diff --git a/src/auth/session.service.ts b/src/auth/session.service.ts index d530135b..ab2e1cbf 100644 --- a/src/auth/session.service.ts +++ b/src/auth/session.service.ts @@ -74,6 +74,21 @@ export class SessionService { ); } + private async getSessionIdByRefreshToken( + refreshToken: string, + ): Promise { + const auth = this.authService.verify(refreshToken); + const permissions = auth.permissions; + if (permissions[0] == null || permissions.length > 1) { + throw new NotRefreshTokenError(); + } + const resouceIds = permissions[0].authorizedResource.resourceIds; + if (resouceIds == null || resouceIds[0] == null || resouceIds.length > 1) { + throw new NotRefreshTokenError(); + } + return resouceIds[0]; + } + // After refreshing the session, the old refresh token is revoked. // Returns: // item1: A new refresh token. @@ -83,15 +98,7 @@ export class SessionService { refreshTokenValidSeconds: number = this.defaultRefreshTokenValidSeconds, accessTokenValidSeconds: number = this.defaultAccessTokenValidSeconds, ): Promise<[string, string]> { - const auth = this.authService.verify(oldRefreshToken); - if ( - auth.permissions.length !== 1 || - auth.permissions[0].authorizedResource.resourceIds == undefined || - auth.permissions[0].authorizedResource.resourceIds.length !== 1 - ) { - throw new NotRefreshTokenError(); - } - const sessionId = auth.permissions[0].authorizedResource.resourceIds[0]; + const sessionId = await this.getSessionIdByRefreshToken(oldRefreshToken); this.authService.audit( oldRefreshToken, AuthorizedAction.other, @@ -157,15 +164,7 @@ export class SessionService { } async revokeSession(refreshToken: string): Promise { - const auth = this.authService.verify(refreshToken); - if ( - auth.permissions.length !== 1 || - auth.permissions[0].authorizedResource.resourceIds == undefined || - auth.permissions[0].authorizedResource.resourceIds.length !== 1 - ) { - throw new NotRefreshTokenError(); - } - const sessionId = auth.permissions[0].authorizedResource.resourceIds[0]; + const sessionId = await this.getSessionIdByRefreshToken(refreshToken); this.authService.audit( refreshToken, AuthorizedAction.other, diff --git a/src/common/helper/page.helper.ts b/src/common/helper/page.helper.ts index af2abfbc..27d8523e 100644 --- a/src/common/helper/page.helper.ts +++ b/src/common/helper/page.helper.ts @@ -110,7 +110,7 @@ export class PageHelper { prevStart: number, idGetter: (item: TData) => number, ): [TData[], PageRespondDto] { - if (data.length == 0 || pageSize < 0) { + if (data[0] == null || pageSize < 0) { return [ [], { diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 44027392..ea9f5ce3 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -159,13 +159,9 @@ export class UsersController { .json(data); } - @Post('/auth/refresh-token') - async refreshToken( - @Headers('cookie') cookieHeader: string, - @Res() res: Response, - @Ip() ip: string, - @Headers('User-Agent') userAgent: string, - ): Promise { + private async getRefreshTokenFromCookieHeader( + cookieHeader: string | undefined, + ): Promise { if (cookieHeader == undefined) { throw new AuthenticationRequiredError(); } @@ -177,6 +173,21 @@ export class UsersController { throw new AuthenticationRequiredError(); } const refreshToken = refreshTokenCookie.split('=')[1]; + if (refreshToken == undefined) { + throw new AuthenticationRequiredError(); + } + return refreshToken; + } + + @Post('/auth/refresh-token') + async refreshToken( + @Headers('cookie') cookieHeader: string | undefined, + @Res() res: Response, + @Ip() ip: string, + @Headers('User-Agent') userAgent: string | undefined, + ): Promise { + const refreshToken = + await this.getRefreshTokenFromCookieHeader(cookieHeader); const [newRefreshToken, accessToken] = await this.sessionService.refreshSession(refreshToken); const newRefreshTokenExpire = new Date( @@ -209,19 +220,10 @@ export class UsersController { @Post('/auth/logout') async logout( - @Headers('cookie') cookieHeader: string, + @Headers('cookie') cookieHeader: string | undefined, ): Promise { - if (cookieHeader == undefined) { - throw new AuthenticationRequiredError(); - } - const cookies = cookieHeader.split(';').map((cookie) => cookie.trim()); - const refreshTokenCookie = cookies.find((cookie) => - cookie.startsWith('REFRESH_TOKEN='), - ); - if (refreshTokenCookie == undefined) { - throw new AuthenticationRequiredError(); - } - const refreshToken = refreshTokenCookie.split('=')[1]; + const refreshToken = + await this.getRefreshTokenFromCookieHeader(cookieHeader); await this.sessionService.revokeSession(refreshToken); return { code: 201, diff --git a/test/answer.e2e-spec.ts b/test/answer.e2e-spec.ts index 6827b762..8dbdd087 100644 --- a/test/answer.e2e-spec.ts +++ b/test/answer.e2e-spec.ts @@ -34,7 +34,7 @@ describe('Answers Module', () => { .send({ email }); expect(respond.status).toBe(201); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.at(-1)[1]; const respond2 = await request(app.getHttpServer()) .post('/users') @@ -60,17 +60,13 @@ describe('Answers Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -88,13 +84,13 @@ describe('Answers Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') diff --git a/test/comment.e2e-spec.ts b/test/comment.e2e-spec.ts index 1f457fc1..afd232cb 100644 --- a/test/comment.e2e-spec.ts +++ b/test/comment.e2e-spec.ts @@ -27,13 +27,12 @@ describe('comments Module', () => { let auxAdminAccessToken: string; // eslint-disable-next-line @typescript-eslint/no-unused-vars let auxAdminUserDto: any; - const CommentIds: number[] = []; - const TopicIds: number[] = []; + const commentIds: number[] = []; + const topicIds: number[] = []; const questionIds: number[] = []; - const TestCommentPrefix = `G${Math.floor(Math.random() * 1000000)}`; + const testCommentPrefix = `G${Math.floor(Math.random() * 1000000)}`; async function createAuxiliaryUser(): Promise<[number, string]> { - // returns [userId, accessToken] const email = `test-${Math.floor(Math.random() * 10000000000)}@ruc.edu.cn`; const respond = await request(app.getHttpServer()) .post('/users/verify/email') @@ -41,7 +40,7 @@ describe('comments Module', () => { .send({ email }); expect(respond.status).toBe(201); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.at(-1)[1]; const respond2 = await request(app.getHttpServer()) .post('/users') @@ -54,7 +53,7 @@ describe('comments Module', () => { emailCode: verificationCode, }); expect(respond2.status).toBe(201); - return [respond2.body.data.user, respond2.body.data.accessToken]; + return [respond2.body.data.user.id, respond2.body.data.accessToken]; } beforeAll(async () => { @@ -67,17 +66,13 @@ describe('comments Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -95,13 +90,13 @@ describe('comments Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -134,7 +129,7 @@ describe('comments Module', () => { expect(respond.body.message).toBe('OK'); expect(respond.status).toBe(201); expect(respond.body.code).toBe(201); - TopicIds.push(respond.body.data.id); + topicIds.push(respond.body.data.id); } await createTopic('数学'); await createTopic('哥德巴赫猜想'); @@ -152,7 +147,7 @@ describe('comments Module', () => { title: `${TestQuestionPrefix} ${title}`, content, type: 0, - topics: [TopicIds[0], TopicIds[1]], + topics: [topicIds[0], topicIds[1]], }); expect(respond.body.message).toBe('Created'); expect(respond.body.code).toBe(201); @@ -183,7 +178,7 @@ describe('comments Module', () => { content: '哥德巴赫猜想又名1+1=2,而显然1+1=2是成立的,所以哥德巴赫猜想是成立的。', type: 0, - topics: [TopicIds[0], TopicIds[1]], + topics: [topicIds[0], topicIds[1]], }); expect(respond.body.message).toMatch(/^AuthenticationRequiredError: /); expect(respond.body.code).toBe(401); @@ -204,28 +199,31 @@ describe('comments Module', () => { }); it('should create some comments', async () => { async function createComment( - commentableId: number, + commentableId: number | undefined, commentableType: 'comment' | 'question' | 'answer', content: string, ) { + if (commentableId == undefined) { + throw new Error('commentableId is undefined'); + } const respond = await request(app.getHttpServer()) .post(`/comments/${commentableType}/${commentableId}`) .set('Authorization', `Bearer ${TestToken}`) .send({ - content: `${TestCommentPrefix} ${content}`, + content: `${testCommentPrefix} ${content}`, }); expect(respond.body.message).toBe('Comment created successfully'); expect(respond.body.code).toBe(201); expect(respond.status).toBe(201); expect(respond.body.data.id).toBeTruthy(); - CommentIds.push(respond.body.data.id); + commentIds.push(respond.body.data.id); } await createComment(questionIds[0], 'question', 'zfgg好帅'); await createComment(questionIds[1], 'question', 'zfggnb'); await createComment(questionIds[2], 'question', 'zfgg???????'); await createComment(questionIds[3], 'question', '宵宫!'); - await createComment(CommentIds[0], 'comment', '啦啦啦德玛西亚'); + await createComment(commentIds[0], 'comment', '啦啦啦德玛西亚'); }, 80000); it('should not create comment due to invalid commentableId', async () => { const content = 'what you gonna to know?'; @@ -233,7 +231,7 @@ describe('comments Module', () => { .post(`/comments/question/114514`) .set('Authorization', `Bearer ${TestToken}`) .send({ - content: `${TestCommentPrefix} ${content}`, + content: `${testCommentPrefix} ${content}`, }); expect(respond.body.message).toMatch(/^CommentableIdNotFoundError: /); @@ -245,7 +243,7 @@ describe('comments Module', () => { const respond = await request(app.getHttpServer()) .post(`/comments/question/${questionIds[0]}/`) .send({ - content: `${TestCommentPrefix} ${content}`, + content: `${testCommentPrefix} ${content}`, }); expect(respond.body.message).toMatch(/^AuthenticationRequiredError: /); expect(respond.body.code).toBe(401); @@ -296,7 +294,7 @@ describe('comments Module', () => { describe('get comment list by id', () => { it('should get comment by id', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[0]}`) + .get(`/comments/${commentIds[0]}`) .set('Authorization', `Bearer ${auxAccessToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); @@ -314,14 +312,14 @@ describe('comments Module', () => { }); it('should get comment by id', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[4]}`) + .get(`/comments/${commentIds[4]}`) .set('Authorization', `Bearer ${auxAccessToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); expect(respond.status).toBe(200); expect(respond.body.code).toBe(200); expect(respond.body.data.comment.id).toBeDefined(); - expect(respond.body.data.comment.commentable_id).toBe(CommentIds[0]); + expect(respond.body.data.comment.commentable_id).toBe(commentIds[0]); expect(respond.body.data.comment.commentable_type).toBe('COMMENT'); expect(respond.body.data.comment.content).toContain('啦啦啦德玛西亚'); expect(respond.body.data.comment.user).toStrictEqual(TestUserDto); @@ -343,7 +341,7 @@ describe('comments Module', () => { describe('AttitudeToComment', () => { it('should agree to a comment', async () => { - const commentId = CommentIds[0]; + const commentId = commentIds[0]; const respond = await request(app.getHttpServer()) .put(`/comments/${commentId}/attitude`) .set('Authorization', `Bearer ${TestToken}`) @@ -355,7 +353,7 @@ describe('comments Module', () => { expect(respond.body.code).toBe(200); }); it('should agree to a comment', async () => { - const commentId = CommentIds[4]; + const commentId = commentIds[4]; const respond = await request(app.getHttpServer()) .put(`/comments/${commentId}/attitude`) .set('Authorization', `Bearer ${TestToken}`) @@ -368,7 +366,7 @@ describe('comments Module', () => { }); it('should get some difference from others', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[0]}`) + .get(`/comments/${commentIds[0]}`) .set('Authorization', `Bearer ${auxAccessToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); @@ -386,7 +384,7 @@ describe('comments Module', () => { }); it('should get some difference from self', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[0]}`) + .get(`/comments/${commentIds[0]}`) .set('Authorization', `Bearer ${TestToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); @@ -403,7 +401,7 @@ describe('comments Module', () => { expect(respond.body.data.comment.attitude_type).toBe('AGREE'); }); it('should disagree to a comment', async () => { - const commentId = CommentIds[0]; + const commentId = commentIds[0]; const respond = await request(app.getHttpServer()) .put(`/comments/${commentId}/attitude`) .set('Authorization', `Bearer ${TestToken}`) @@ -416,7 +414,7 @@ describe('comments Module', () => { }); it('should get some difference from others', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[0]}`) + .get(`/comments/${commentIds[0]}`) .set('Authorization', `Bearer ${auxAccessToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); @@ -434,7 +432,7 @@ describe('comments Module', () => { }); it('should get some difference from self', async () => { const respond = await request(app.getHttpServer()) - .get(`/comments/${CommentIds[0]}`) + .get(`/comments/${commentIds[0]}`) .set('Authorization', `Bearer ${TestToken}`) .send(); expect(respond.body.message).toBe('Details are as follows'); @@ -451,7 +449,7 @@ describe('comments Module', () => { expect(respond.body.data.comment.attitude_type).toBe('DISAGREE'); }); it('should return to InvalidAttitudeTypeError', async () => { - const commentId = CommentIds[1]; + const commentId = commentIds[1]; const respond = await request(app.getHttpServer()) .put(`/comments/${commentId}/attitude`) .set('Authorization', `Bearer ${TestToken}`) @@ -471,7 +469,7 @@ describe('comments Module', () => { expect(respond.body.code).toBe(404); }); it('should return AuthenticationRequiredError', async () => { - const commentId = CommentIds[1]; + const commentId = commentIds[1]; const respond = await request(app.getHttpServer()) .put(`/comments/${commentId}/attitude`) .send({ attitude_type: 'disagree' }); @@ -482,7 +480,7 @@ describe('comments Module', () => { describe('deleteComment', () => { it('should delete a comment', async () => { - const commentId = CommentIds[1]; + const commentId = commentIds[1]; const respond = await request(app.getHttpServer()) .delete(`/comments/${commentId}`) .set('Authorization', `Bearer ${TestToken}`) @@ -492,7 +490,7 @@ describe('comments Module', () => { expect(respond.body.code).toBe(204); }); it('should not delete a comment when the user does not match', async () => { - const commentId = CommentIds[0]; + const commentId = commentIds[0]; const respond = await request(app.getHttpServer()) .delete(`/comments/${commentId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -512,7 +510,7 @@ describe('comments Module', () => { expect(respond.body.code).toBe(404); }); it('should return AuthenticationRequiredError', async () => { - const commentId = CommentIds[0]; + const commentId = commentIds[0]; const respond = await request(app.getHttpServer()) .delete(`/comments/${commentId}`) .send(); @@ -520,7 +518,7 @@ describe('comments Module', () => { expect(respond.body.code).toBe(401); }); it('should delete a comment', async () => { - const commentId = CommentIds[4]; + const commentId = commentIds[4]; const respond = await request(app.getHttpServer()) .delete(`/comments/${commentId}`) .set('Authorization', `Bearer ${TestToken}`) diff --git a/test/groups.e2e-spec.ts b/test/groups.e2e-spec.ts index dbcedb07..e12ae110 100644 --- a/test/groups.e2e-spec.ts +++ b/test/groups.e2e-spec.ts @@ -31,11 +31,12 @@ describe('Groups Module', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars let auxAdminUserDto: any; - const GroupIds: number[] = []; - const TestGroupPrefix = `G${Math.floor(Math.random() * 1000000)}`; + const groupIds: number[] = []; + const testGroupPrefix = `G${Math.floor(Math.random() * 1000000)}`; - async function createAuxiliaryUser(): Promise<[number, string]> { - // returns [userId, accessToken] + // ! This function is not the same as the ones in other test files. + // ! Returns [userDto, accessToken] + async function createAuxiliaryUser(): Promise<[any, string]> { const email = `test-${Math.floor(Math.random() * 10000000000)}@ruc.edu.cn`; const respond = await request(app.getHttpServer()) .post('/users/verify/email') @@ -43,7 +44,7 @@ describe('Groups Module', () => { .send({ email }); expect(respond.status).toBe(201); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.at(-1)[1]; const respond2 = await request(app.getHttpServer()) .post('/users') @@ -69,17 +70,13 @@ describe('Groups Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -97,13 +94,13 @@ describe('Groups Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -129,7 +126,7 @@ describe('Groups Module', () => { const respond = await request(app.getHttpServer()) .post('/groups') .set('Authorization', `Bearer ${TestToken}`) - .send({ name: TestGroupPrefix + name, intro, avatar }); + .send({ name: testGroupPrefix + name, intro, avatar }); expect(respond.body.message).toBe('Group created successfully'); expect(respond.body.code).toBe(201); expect(respond.status).toBe(201); @@ -147,7 +144,7 @@ describe('Groups Module', () => { expect(groupDto.is_owner).toBe(true); expect(groupDto.is_public).toBe(true); expect(groupDto.intro).toBe(intro); - GroupIds.push(groupDto.id); + groupIds.push(groupDto.id); } await createGroup('数学之神膜膜喵', '不如原神', '🥸'); await createGroup('ICS膜膜膜', 'pwb txdy!', '🐂'); @@ -358,7 +355,7 @@ describe('Groups Module', () => { describe('get group', () => { it('should get a group', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${TestToken}`) @@ -382,7 +379,7 @@ describe('Groups Module', () => { }); it('should get a group for another user', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -418,7 +415,10 @@ describe('Groups Module', () => { describe('join group', () => { it('should join a group', async () => { - async function joinGroup(groupId: number) { + async function joinGroup(groupId: number | undefined) { + if (groupId == null) { + throw new Error('groupId is undefined'); + } const respond = await request(app.getHttpServer()) .post(`/groups/${groupId}/members`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -427,11 +427,11 @@ describe('Groups Module', () => { expect(respond.status).toBe(201); expect(respond.body.code).toBe(201); } - await joinGroup(GroupIds[0]); - await joinGroup(GroupIds[1]); + await joinGroup(groupIds[0]); + await joinGroup(groupIds[1]); }); it('should return a group with is_member true', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -463,7 +463,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(404); }); it('should return GroupAlreadyJoinedError when user is already in the group', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .post(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -476,12 +476,12 @@ describe('Groups Module', () => { describe('update group', () => { it('should update a group', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .put(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${TestToken}`) .send({ - name: TestGroupPrefix + '关注幻城谢谢喵', + name: testGroupPrefix + '关注幻城谢谢喵', intro: '湾原审万德', avatar: '🤣', }); @@ -490,7 +490,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(200); }); it('should return a group with updated info from another user', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -517,7 +517,7 @@ describe('Groups Module', () => { .put('/groups/0') .set('Authorization', `Bearer ${TestToken}`) .send({ - name: TestGroupPrefix + '关注幻城谢谢喵', + name: testGroupPrefix + '关注幻城谢谢喵', intro: '湾原审万德', avatar: '🤣', }); @@ -526,12 +526,12 @@ describe('Groups Module', () => { expect(respond.body.message).toMatch(/^GroupIdNotFoundError: /); }); it('should return GroupNameAlreadyUsedError when group name is already used', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .put(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${TestToken}`) .send({ - name: TestGroupPrefix + 'ICS膜膜膜', + name: testGroupPrefix + 'ICS膜膜膜', intro: '湾原审万德', avatar: '🤣', }); @@ -541,12 +541,12 @@ describe('Groups Module', () => { }); // TODO: add permission control it('should return CannotDeleteGroupError when user is not the owner', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .put(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) .send({ - name: TestGroupPrefix + '关注幻城谢谢喵', + name: testGroupPrefix + '关注幻城谢谢喵', intro: '湾原审万德', avatar: '🤣', }); @@ -558,7 +558,7 @@ describe('Groups Module', () => { describe('leave group', () => { it('should leave a group', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .delete(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -568,7 +568,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(200); }); it('should return a group with is_member false', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -600,7 +600,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(404); }, 10000); it('should return GroupNotJoinedError when user is not in the group', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .delete(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -614,7 +614,7 @@ describe('Groups Module', () => { describe('delete group', () => { it('should delete a group', async () => { - const TestGroupId = GroupIds[3]; + const TestGroupId = groupIds[3]; const respond = await request(app.getHttpServer()) .delete(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${TestToken}`) @@ -624,7 +624,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(200); }); it('should return GroupIdNotFoundError after deletion', async () => { - const TestGroupId = GroupIds[3]; + const TestGroupId = groupIds[3]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${TestToken}`) @@ -643,7 +643,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(404); }); it('should return CannotDeleteGroupError when user is not the owner', async () => { - const TestGroupId = GroupIds[1]; + const TestGroupId = groupIds[1]; const respond = await request(app.getHttpServer()) .delete(`/groups/${TestGroupId}`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -656,7 +656,7 @@ describe('Groups Module', () => { describe('get group members', () => { it('should get group members', async () => { - const TestGroupId = GroupIds[1]; + const TestGroupId = groupIds[1]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${TestToken}`) @@ -675,7 +675,7 @@ describe('Groups Module', () => { expect(respond.body.data.page.next_start).toBe(auxUserDto.id); }); it('should get group members from a specific user', async () => { - const TestGroupId = GroupIds[1]; + const TestGroupId = groupIds[1]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${TestToken}`) @@ -694,7 +694,7 @@ describe('Groups Module', () => { expect(respond.body.data.page.next_start).toBeFalsy(); }); it('should get group members from a specific user even quited', async () => { - const TestGroupId = GroupIds[0]; + const TestGroupId = groupIds[0]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${TestToken}`) @@ -712,7 +712,7 @@ describe('Groups Module', () => { expect(respond.body.data.page.next_start).toBeFalsy(); }); it('should get group members for another user', async () => { - const TestGroupId = GroupIds[1]; + const TestGroupId = groupIds[1]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${auxAccessToken}`) @@ -740,7 +740,7 @@ describe('Groups Module', () => { expect(respond.body.code).toBe(404); }); it('should return empty list when page_size is not positive', async () => { - const TestGroupId = GroupIds[1]; + const TestGroupId = groupIds[1]; const respond = await request(app.getHttpServer()) .get(`/groups/${TestGroupId}/members`) .set('Authorization', `Bearer ${TestToken}`) diff --git a/test/question.e2e-spec.ts b/test/question.e2e-spec.ts index 4215211e..a82bde51 100644 --- a/test/question.e2e-spec.ts +++ b/test/question.e2e-spec.ts @@ -32,7 +32,6 @@ describe('Questions Module', () => { let auxAccessToken: string; async function createAuxiliaryUser(): Promise<[number, string]> { - // returns [userId, accessToken] const email = `test-${Math.floor(Math.random() * 10000000000)}@ruc.edu.cn`; const respond = await request(app.getHttpServer()) .post('/users/verify/email') @@ -40,7 +39,7 @@ describe('Questions Module', () => { .send({ email }); expect(respond.status).toBe(201); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.at(-1)[1]; const respond2 = await request(app.getHttpServer()) .post('/users') @@ -66,17 +65,13 @@ describe('Questions Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -94,13 +89,13 @@ describe('Questions Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -585,7 +580,10 @@ describe('Questions Module', () => { expect(respond4.body.data.page.next_start).toBe(0); }); it('should unfollow questions', async () => { - async function unfollow(questionId: number) { + async function unfollow(questionId: number | undefined) { + if (questionId == undefined) { + throw new Error('questionId is undefined'); + } const respond = await request(app.getHttpServer()) .delete(`/questions/${questionId}/followers`) .set('Authorization', `Bearer ${TestToken}`) diff --git a/test/topic.e2e-spec.ts b/test/topic.e2e-spec.ts index 71fede9a..047831e8 100644 --- a/test/topic.e2e-spec.ts +++ b/test/topic.e2e-spec.ts @@ -35,17 +35,13 @@ describe('Topic Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -63,13 +59,13 @@ describe('Topic Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') diff --git a/test/user.e2e-spec.ts b/test/user.e2e-spec.ts index d0373803..39944aea 100644 --- a/test/user.e2e-spec.ts +++ b/test/user.e2e-spec.ts @@ -34,17 +34,13 @@ describe('User Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -115,13 +111,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; jest.advanceTimersByTime(11 * 60 * 1000); @@ -157,13 +153,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; jest.advanceTimersByTime(9 * 60 * 1000); @@ -215,13 +211,13 @@ describe('User Module', () => { }); expect(respond.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith('another-' + TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; return ( request(app.getHttpServer()) @@ -284,13 +280,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith('another-' + TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -324,13 +320,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith('another-' + TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -362,13 +358,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith('another-' + TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -400,13 +396,13 @@ describe('User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith('another-' + TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -443,12 +439,15 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.body.data.user.username).toBe(TestUsername); expect(respond.body.data.user.nickname).toBe('test_user'); - expect(respond.header['set-cookie'][0]).toMatch( + expect(respond.header['set-cookie']?.[0]).toMatch( /^REFRESH_TOKEN=.+; Path=\/users\/auth; Expires=.+; HttpOnly; SameSite=Strict$/, ); - TestRefreshToken = respond.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const TestRefreshToken2 = respond?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(TestRefreshToken2).toBeDefined(); + TestRefreshToken = TestRefreshToken2!; + expect(respond.body.data.accessToken).toBeDefined(); TestToken = respond.body.data.accessToken; }); @@ -465,9 +464,12 @@ describe('User Module', () => { expect(respond2.body.code).toBe(201); expect(respond2.body.data.accessToken).toBeDefined(); TestRefreshTokenOld = TestRefreshToken; - TestRefreshToken = respond2.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const TestRefreshToken2 = respond2?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(TestRefreshToken2).toBeDefined(); + TestRefreshToken = TestRefreshToken2!; + TestToken = respond2.body.data.accessToken; expect(respond2.body.data.user.username).toBe(TestUsername); expect(respond2.body.data.user.nickname).toBe('test_user'); @@ -517,15 +519,17 @@ describe('User Module', () => { expect(respond2.body.data.accessToken).toBeDefined(); expect(respond2.body.data.user.username).toBe(TestUsername); expect(respond2.body.data.user.nickname).toBe('test_user'); - const refreshToken = respond2.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const refreshToken = respond2?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(refreshToken).toBeDefined(); + jest.setSystemTime(Date.now() + 31 * 24 * 60 * 60 * 1000); const respond3 = await request(app.getHttpServer()) .post('/users/auth/refresh-token') .set( 'Cookie', - `some_cookie=12345; REFRESH_TOKEN=${refreshToken}; other_cookie=value`, + `some_cookie=12345; REFRESH_TOKEN=${refreshToken!}; other_cookie=value`, ) .send(); expect(respond3.body.message).toMatch(/^TokenExpiredError: /); @@ -546,12 +550,14 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.body.data.user.username).toBe(TestUsername); expect(respond.body.data.user.nickname).toBe('test_user'); - expect(respond.header['set-cookie'][0]).toMatch( + expect(respond.header?.['set-cookie']?.[0]).toMatch( /^REFRESH_TOKEN=.+; Path=\/users\/auth; Expires=.+; HttpOnly; SameSite=Strict$/, ); - TestRefreshToken = respond.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const TestRefreshToken2 = respond?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(TestRefreshToken2).toBeDefined(); + TestRefreshToken = TestRefreshToken2!; expect(respond.body.data.accessToken).toBeDefined(); TestToken = respond.body.data.accessToken; }); @@ -571,9 +577,12 @@ describe('User Module', () => { expect(respond2.status).toBe(201); expect(respond2.body.code).toBe(201); expect(respond2.body.data.accessToken).toBeDefined(); - refreshToken = respond2.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const refreshToken2 = respond2?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(refreshToken2).toBeDefined(); + refreshToken = refreshToken2!; + expect(respond2.body.data.user.username).toBe(TestUsername); expect(respond2.body.data.user.nickname).toBe('test_user'); } @@ -603,12 +612,15 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.body.data.user.username).toBe(TestUsername); expect(respond.body.data.user.nickname).toBe('test_user'); - expect(respond.header['set-cookie'][0]).toMatch( + expect(respond?.header?.['set-cookie']?.[0]).toMatch( /^REFRESH_TOKEN=.+; Path=\/users\/auth; Expires=.+; HttpOnly; SameSite=Strict$/, ); - TestRefreshToken = respond.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const TestRefreshToken2 = respond?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(TestRefreshToken2).toBeDefined(); + TestRefreshToken = TestRefreshToken2!; + expect(respond.body.data.accessToken).toBeDefined(); TestToken = respond.body.data.accessToken; }); @@ -625,9 +637,12 @@ describe('User Module', () => { expect(respond2.body.code).toBe(201); expect(respond2.body.data.accessToken).toBeDefined(); TestRefreshTokenOld = TestRefreshToken; - TestRefreshToken = respond2.header['set-cookie'][0] - .split(';')[0] - .split('=')[1]; + const TestRefreshToken2 = respond2?.header?.['set-cookie']?.[0] + ?.split(';')?.[0] + ?.split('=')?.[1]; + expect(TestRefreshToken2).toBeDefined(); + TestRefreshToken = TestRefreshToken2!; + TestToken = respond2.body.data.accessToken; expect(respond2.body.data.user.username).toBe(TestUsername); expect(respond2.body.data.user.nickname).toBe('test_user'); @@ -771,13 +786,14 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const token = ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + MockedEmailService.mock.instances[0] + ?.sendPasswordResetEmail as jest.Mock ).mock.calls[0][1]; jest.advanceTimersByTime(9 * 60 * 1000); @@ -834,13 +850,14 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const token = ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + MockedEmailService.mock.instances[0] + ?.sendPasswordResetEmail as jest.Mock ).mock.calls[0][1]; jest.advanceTimersByTime(11 * 60 * 1000); @@ -872,13 +889,14 @@ describe('User Module', () => { expect(respond.body.code).toBe(201); expect(respond.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendPasswordResetEmail, + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const token = ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + MockedEmailService.mock.instances[0] + ?.sendPasswordResetEmail as jest.Mock ).mock.calls[0][1]; jest.advanceTimersByTime(9 * 60 * 1000); diff --git a/test/user.follow.e2e-spec.ts b/test/user.follow.e2e-spec.ts index 6e90478c..52fdf9af 100644 --- a/test/user.follow.e2e-spec.ts +++ b/test/user.follow.e2e-spec.ts @@ -34,7 +34,7 @@ describe('Following Submodule of User Module', () => { .send({ email }); expect(respond.status).toBe(201); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.at(-1)[1]; const respond2 = await request(app.getHttpServer()) .post('/users') @@ -61,16 +61,16 @@ describe('Following Submodule of User Module', () => { beforeEach(() => { ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls.length = 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.results.length = 0; ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail as jest.Mock ).mock.calls.length = 0; ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + MockedEmailService.mock.instances[0]?.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -88,13 +88,13 @@ describe('Following Submodule of User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') @@ -136,6 +136,9 @@ describe('Following Submodule of User Module', () => { }); it('should return UserIdNotFoundError', async () => { + if (tempUserIds[0] == null) { + throw new Error('tempUserIds[0] is undefined.'); + } const respond = await request(app.getHttpServer()) .post(`/users/${tempUserIds[0] + 1000000000}/followers`) //.set('User-Agent', 'PostmanRuntime/7.26.8') diff --git a/test/user.profile.e2e-spec.ts b/test/user.profile.e2e-spec.ts index 66a7c6bf..6e3d6709 100644 --- a/test/user.profile.e2e-spec.ts +++ b/test/user.profile.e2e-spec.ts @@ -33,17 +33,13 @@ describe('Profile Submodule of User Module', () => { }, 20000); beforeEach(() => { + const mockedEmailService = MockedEmailService.mock.instances[0]!; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.calls.length = 0; + (mockedEmailService.sendRegisterCode as jest.Mock).mock.results.length = 0; + (mockedEmailService.sendPasswordResetEmail as jest.Mock).mock.calls.length = + 0; ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock - ).mock.results.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock - ).mock.calls.length = 0; - ( - MockedEmailService.mock.instances[0].sendPasswordResetEmail as jest.Mock + mockedEmailService.sendPasswordResetEmail as jest.Mock ).mock.results.length = 0; }); @@ -61,13 +57,13 @@ describe('Profile Submodule of User Module', () => { }); expect(respond1.status).toBe(201); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveReturnedTimes(1); expect( - MockedEmailService.mock.instances[0].sendRegisterCode, + MockedEmailService.mock.instances[0]?.sendRegisterCode, ).toHaveBeenCalledWith(TestEmail, expect.any(String)); const verificationCode = ( - MockedEmailService.mock.instances[0].sendRegisterCode as jest.Mock + MockedEmailService.mock.instances[0]?.sendRegisterCode as jest.Mock ).mock.calls[0][1]; const req = request(app.getHttpServer()) .post('/users') diff --git a/tsconfig.json b/tsconfig.json index 1110e975..47cdccdf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "strictNullChecks": true, "strictPropertyInitialization": false, "noImplicitAny": true, + "noUncheckedIndexedAccess": true, "strictBindCallApply": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": false,