access-token-parser.integ.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import { faker } from '@faker-js/faker';
  2. import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
  3. import type { Response } from 'express';
  4. import { mock } from 'vitest-mock-extended';
  5. import type Crowi from '~/server/crowi';
  6. import type UserEvent from '~/server/events/user';
  7. import type { AccessTokenParserReq } from './interfaces';
  8. import { accessTokenParser } from '.';
  9. vi.mock('@growi/core/dist/models/serializers', { spy: true });
  10. describe('access-token-parser middleware', () => {
  11. let User;
  12. beforeAll(async() => {
  13. const crowiMock = mock<Crowi>({
  14. event: vi.fn().mockImplementation((eventName) => {
  15. if (eventName === 'user') {
  16. return mock<UserEvent>({
  17. on: vi.fn(),
  18. });
  19. }
  20. }),
  21. });
  22. const userModelFactory = (await import('../../models/user')).default;
  23. User = userModelFactory(crowiMock);
  24. });
  25. it('should call next if no access token is provided', async() => {
  26. // arrange
  27. const reqMock = mock<AccessTokenParserReq>({
  28. user: undefined,
  29. });
  30. const resMock = mock<Response>();
  31. const nextMock = vi.fn();
  32. expect(reqMock.user).toBeUndefined();
  33. // act
  34. await accessTokenParser(reqMock, resMock, nextMock);
  35. // assert
  36. expect(reqMock.user).toBeUndefined();
  37. expect(serializeUserSecurely).not.toHaveBeenCalled();
  38. expect(nextMock).toHaveBeenCalled();
  39. });
  40. it('should call next if the given access token is invalid', async() => {
  41. // arrange
  42. const reqMock = mock<AccessTokenParserReq>({
  43. user: undefined,
  44. });
  45. const resMock = mock<Response>();
  46. const nextMock = vi.fn();
  47. expect(reqMock.user).toBeUndefined();
  48. // act
  49. reqMock.query.access_token = 'invalidToken';
  50. await accessTokenParser(reqMock, resMock, nextMock);
  51. // assert
  52. expect(reqMock.user).toBeUndefined();
  53. expect(serializeUserSecurely).not.toHaveBeenCalled();
  54. expect(nextMock).toHaveBeenCalled();
  55. });
  56. it('should set req.user with a valid access token in query', async() => {
  57. // arrange
  58. const reqMock = mock<AccessTokenParserReq>({
  59. user: undefined,
  60. });
  61. const resMock = mock<Response>();
  62. const nextMock = vi.fn();
  63. expect(reqMock.user).toBeUndefined();
  64. // prepare a user with an access token
  65. const targetUser = await User.create({
  66. name: faker.person.fullName(),
  67. username: faker.string.uuid(),
  68. password: faker.internet.password(),
  69. lang: 'en_US',
  70. apiToken: faker.internet.password(),
  71. });
  72. // act
  73. reqMock.query.access_token = targetUser.apiToken;
  74. await accessTokenParser(reqMock, resMock, nextMock);
  75. // assert
  76. expect(reqMock.user).toBeDefined();
  77. expect(reqMock.user?._id).toStrictEqual(targetUser._id);
  78. expect(serializeUserSecurely).toHaveBeenCalledOnce();
  79. expect(nextMock).toHaveBeenCalled();
  80. });
  81. it('should set req.user with a valid access token in body', async() => {
  82. // arrange
  83. const reqMock = mock<AccessTokenParserReq>({
  84. user: undefined,
  85. });
  86. const resMock = mock<Response>();
  87. const nextMock = vi.fn();
  88. expect(reqMock.user).toBeUndefined();
  89. // prepare a user with an access token
  90. const targetUser = await User.create({
  91. name: faker.person.fullName(),
  92. username: faker.string.uuid(),
  93. password: faker.internet.password(),
  94. lang: 'en_US',
  95. apiToken: faker.internet.password(),
  96. });
  97. // act
  98. reqMock.body.access_token = targetUser.apiToken;
  99. await accessTokenParser(reqMock, resMock, nextMock);
  100. // assert
  101. expect(reqMock.user).toBeDefined();
  102. expect(reqMock.user?._id).toStrictEqual(targetUser._id);
  103. expect(serializeUserSecurely).toHaveBeenCalledOnce();
  104. expect(nextMock).toHaveBeenCalled();
  105. });
  106. });