Skip to content

Commit ec3f183

Browse files
committed
✅ test: user 도메인 테스트 코드 최종 리팩토링
1 parent 508b428 commit ec3f183

File tree

10 files changed

+155
-37
lines changed

10 files changed

+155
-37
lines changed

server/src/user/service/user.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
UnauthorizedException,
77
} from '@nestjs/common';
88
import { RegisterUserRequestDto } from '../dto/request/registerUser.dto';
9-
import { v4 as uuidv4 } from 'uuid';
9+
import * as uuid from 'uuid';
1010
import { RedisService } from '../../common/redis/redis.service';
1111
import { REFRESH_TOKEN_TTL, SALT_ROUNDS } from '../constant/user.constants';
1212
import { EmailService } from '../../common/email/email.service';
@@ -64,15 +64,15 @@ export class UserService {
6464
const newUser = registerDto.toEntity();
6565
newUser.password = await this.createHashedPassword(registerDto.password);
6666

67-
const uuid = uuidv4();
67+
const registerCode = uuid.v4();
6868
await this.redisService.set(
69-
`${REDIS_KEYS.USER_AUTH_KEY}:${uuid}`,
69+
`${REDIS_KEYS.USER_AUTH_KEY}:${registerCode}`,
7070
JSON.stringify(newUser),
7171
'EX',
7272
600,
7373
);
7474

75-
this.emailService.sendUserCertificationMail(newUser, uuid);
75+
this.emailService.sendUserCertificationMail(newUser, registerCode);
7676
}
7777

7878
async certificateUser(uuid: string): Promise<void> {
@@ -202,15 +202,15 @@ export class UserService {
202202
return;
203203
}
204204

205-
const uuid = uuidv4();
205+
const forgotPasswordUUID = uuid.v4();
206206
await this.redisService.set(
207-
`${REDIS_KEYS.USER_RESET_PASSWORD_KEY}:${uuid}`,
207+
`${REDIS_KEYS.USER_RESET_PASSWORD_KEY}:${forgotPasswordUUID}`,
208208
JSON.stringify(user.id),
209209
'EX',
210210
600,
211211
);
212212

213-
this.emailService.sendPasswordResetEmail(user, uuid);
213+
this.emailService.sendPasswordResetEmail(user, forgotPasswordUUID);
214214
}
215215

216216
async resetPassword(uuid: string, password: string): Promise<void> {
@@ -238,7 +238,7 @@ export class UserService {
238238
async requestDeleteAccount(userId: number): Promise<void> {
239239
const user = await this.getUser(userId);
240240

241-
const token = uuidv4();
241+
const token = uuid.v4();
242242
await this.redisService.set(
243243
`${REDIS_KEYS.USER_DELETE_ACCOUNT_KEY}:${token}`,
244244
user.id.toString(),

server/test/user/e2e/certificate.e2e-spec.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ describe(`POST ${URL} E2E Test`, () => {
1515
let agent: TestAgent;
1616
let redisService: RedisService;
1717
let userRepository: UserRepository;
18+
const userRegisterCode = 'user-register-certificate';
19+
const redisKeyMake = (data: string) => `${REDIS_KEYS.USER_AUTH_KEY}:${data}`;
1820

1921
beforeAll(async () => {
2022
app = global.testApp;
@@ -26,7 +28,7 @@ describe(`POST ${URL} E2E Test`, () => {
2628
it('[404] 존재하지 않거나 만료된 UUID로 인증을 요청할 경우 회원 가입 인증을 실패한다.', async () => {
2729
// given
2830
const requestDto = new CertificateUserRequestDto({
29-
uuid: 'non-existent-or-expired-uuid',
31+
uuid: `Wrong${userRegisterCode}`,
3032
});
3133

3234
// Http when
@@ -38,13 +40,16 @@ describe(`POST ${URL} E2E Test`, () => {
3840
expect(data).toBeUndefined();
3941
});
4042

41-
it('[200] 올바른 UUID로 인증을 요청할 경우 회원 가입 인증을 성공한다.', async () => {
43+
it('[200] 올바른 인증 코드로 인증을 요청할 경우 회원 가입 인증을 성공한다.', async () => {
4244
// given
43-
const uuid = 'test-certificate-uuid';
4445
const userEntity = await UserFixture.createUserCryptFixture();
45-
const redisKey = `${REDIS_KEYS.USER_AUTH_KEY}:${uuid}`;
46-
const requestDto = new CertificateUserRequestDto({ uuid });
47-
await redisService.set(redisKey, JSON.stringify(userEntity));
46+
const requestDto = new CertificateUserRequestDto({
47+
uuid: userRegisterCode,
48+
});
49+
await redisService.set(
50+
redisKeyMake(userRegisterCode),
51+
JSON.stringify(userEntity),
52+
);
4853

4954
// Http when
5055
const response = await agent.post(URL).send(requestDto);
@@ -59,10 +64,12 @@ describe(`POST ${URL} E2E Test`, () => {
5964
email: userEntity.email,
6065
userName: userEntity.userName,
6166
});
62-
const savedUUID = await redisService.get(redisKey);
67+
const savedRegisterCode = await redisService.get(
68+
redisKeyMake(userRegisterCode),
69+
);
6370

6471
// DB, Redis then
65-
expect(savedUUID).toBeNull();
72+
expect(savedRegisterCode).toBeNull();
6673
expect(savedUser).not.toBeUndefined();
6774
expect(
6875
await bcrypt.compare(

server/test/user/e2e/delete-account/confirm.e2e-spec.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ describe(`POST ${URL} E2E Test`, () => {
2222
let likeRepository: LikeRepository;
2323
let activityRepository: ActivityRepository;
2424
let fileRepository: FileRepository;
25+
const userDeleteCode = 'user-delete-confirm';
26+
const redisKeyMake = (data: string) =>
27+
`${REDIS_KEYS.USER_DELETE_ACCOUNT_KEY}:${data}`;
2528

2629
beforeAll(async () => {
2730
app = global.testApp;
@@ -36,7 +39,9 @@ describe(`POST ${URL} E2E Test`, () => {
3639

3740
it('[404] 회원 탈퇴 인증 코드가 만료되었거나 잘 못된 경우 회원 탈퇴를 실패한다.', async () => {
3841
// given
39-
const requestDto = new ConfirmDeleteAccountDto({ token: 'invalid-token' });
42+
const requestDto = new ConfirmDeleteAccountDto({
43+
token: `Wrong${userDeleteCode}`,
44+
});
4045

4146
// Http when
4247
const response = await agent.post(URL).send(requestDto);
@@ -49,14 +54,12 @@ describe(`POST ${URL} E2E Test`, () => {
4954

5055
it('[200] 회원 탈퇴 인증 코드가 있을 경우 회원 탈퇴를 성공한다.', async () => {
5156
// given
52-
const token = 'test-delete-account-token';
53-
const redisKey = `${REDIS_KEYS.USER_DELETE_ACCOUNT_KEY}:${token}`;
54-
const requestDto = new ConfirmDeleteAccountDto({ token });
57+
const requestDto = new ConfirmDeleteAccountDto({ token: userDeleteCode });
5558
const user = await userRepository.save(
5659
await UserFixture.createUserCryptFixture(),
5760
);
5861

59-
await redisService.set(redisKey, user.id, 'EX', 600);
62+
await redisService.set(redisKeyMake(userDeleteCode), user.id);
6063

6164
// Http when
6265
const response = await agent.post(URL).send(requestDto);
@@ -68,18 +71,22 @@ describe(`POST ${URL} E2E Test`, () => {
6871

6972
// DB, Redis when
7073
const savedComment = await commentRepository.findBy({
71-
user,
74+
user: { id: user.id },
75+
});
76+
const savedLike = await likeRepository.findBy({ user: { id: user.id } });
77+
const savedActivity = await activityRepository.findBy({
78+
user: { id: user.id },
7279
});
73-
const savedLike = await likeRepository.findBy({ user });
74-
const savedActivity = await activityRepository.findBy({ user });
75-
const savedFile = await fileRepository.findBy({ user });
76-
const savedUUID = await redisService.get(redisKey);
80+
const savedFile = await fileRepository.findBy({ user: { id: user.id } });
81+
const savedRssDeleteCode = await redisService.get(
82+
redisKeyMake(userDeleteCode),
83+
);
7784

7885
// DB, Redis then
7986
expect(savedComment.length).toBe(0);
8087
expect(savedLike.length).toBe(0);
8188
expect(savedActivity.length).toBe(0);
8289
expect(savedFile.length).toBe(0);
83-
expect(savedUUID).toBeNull;
90+
expect(savedRssDeleteCode).toBeNull;
8491
});
8592
});

server/test/user/e2e/delete-account/request.e2e-spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,35 @@ import { UserFixture } from '../../../fixture/user.fixture';
55
import TestAgent from 'supertest/lib/agent';
66
import { User } from '../../../../src/user/entity/user.entity';
77
import { createAccessToken } from '../../../jest.setup';
8+
import { REDIS_KEYS } from '../../../../src/common/redis/redis.constant';
9+
import * as uuid from 'uuid';
10+
import { RedisService } from '../../../../src/common/redis/redis.service';
811

912
const URL = '/api/user/delete-account/request';
1013

1114
describe(`POST ${URL} E2E Test`, () => {
1215
let app: INestApplication;
1316
let agent: TestAgent;
1417
let user: User;
18+
let redisService: RedisService;
19+
const userDeleteCode = 'user-delete-request';
20+
const redisKeyMake = (data: string) =>
21+
`${REDIS_KEYS.USER_DELETE_ACCOUNT_KEY}:${data}`;
1522

1623
beforeAll(async () => {
1724
app = global.testApp;
1825
agent = supertest(app.getHttpServer());
26+
redisService = app.get(RedisService);
1927
const userRepository = app.get(UserRepository);
2028
user = await userRepository.save(
2129
await UserFixture.createUserCryptFixture(),
2230
);
2331
});
2432

33+
beforeEach(() => {
34+
jest.spyOn(uuid, 'v4').mockReturnValue(userDeleteCode as any);
35+
});
36+
2537
it('[401] 로그인 되지 않은 유저가 회원 탈퇴를 신청할 경우 회원 탈퇴 신청을 실패한다.', async () => {
2638
// Http when
2739
const response = await agent.post(URL);
@@ -30,6 +42,14 @@ describe(`POST ${URL} E2E Test`, () => {
3042
const { data } = response.body;
3143
expect(response.status).toBe(HttpStatus.UNAUTHORIZED);
3244
expect(data).toBeUndefined();
45+
46+
// DB, Redis when
47+
const savedDeleteCode = await redisService.get(
48+
redisKeyMake(userDeleteCode),
49+
);
50+
51+
// DB, Redis then
52+
expect(savedDeleteCode).toBeNull();
3353
});
3454

3555
it('[200] 회원 탈퇴 신청을 받을 경우 회원 탈퇴 신청을 성공한다.', async () => {
@@ -45,5 +65,13 @@ describe(`POST ${URL} E2E Test`, () => {
4565
const { data } = response.body;
4666
expect(response.status).toBe(HttpStatus.OK);
4767
expect(data).toBeUndefined();
68+
69+
// DB, Redis when
70+
const savedDeleteCode = await redisService.get(
71+
redisKeyMake(userDeleteCode),
72+
);
73+
74+
// DB, Redis then
75+
expect(savedDeleteCode).toBe(user.id.toString());
4876
});
4977
});

server/test/user/e2e/email-check.e2e-spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe(`GET ${URL} E2E Test`, () => {
2323
it('[200] 중복 이메일이 존재하지 않을 경우 이메일 중복 검사를 성공한다.', async () => {
2424
// given
2525
const requestDto = new CheckEmailDuplicationRequestDto({
26-
email: `${user.email}invalid`,
26+
email: `Invalid${user.email}`,
2727
});
2828

2929
// Http when

server/test/user/e2e/login.e2e-spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe(`POST ${URL} E2E Test`, () => {
1515
app = global.testApp;
1616
agent = supertest(app.getHttpServer());
1717
const userRepository = app.get(UserRepository);
18-
await userRepository.save(await UserFixture.createUserCryptFixture());
18+
await userRepository.insert(await UserFixture.createUserCryptFixture());
1919
});
2020

2121
it('[401] 아이디가 틀렸을 경우 로그인을 실패한다.', async () => {

server/test/user/e2e/password-confirm.e2e-spec.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ describe(`PATCH ${URL} E2E Test`, () => {
1515
let agent: TestAgent;
1616
let redisService: RedisService;
1717
let userRepository: UserRepository;
18+
const passwordPatchCode = 'user-password-confirm';
19+
const redisKeyMake = (data: string) =>
20+
`${REDIS_KEYS.USER_RESET_PASSWORD_KEY}:${data}`;
1821

1922
beforeAll(async () => {
2023
app = global.testApp;
@@ -26,7 +29,7 @@ describe(`PATCH ${URL} E2E Test`, () => {
2629
it('[404] 존재하지 않는 비밀번호 세션 ID를 통해 비밀번호 변경 요청을 할 경우 비밀번호 변경을 실패한다.', async () => {
2730
// given
2831
const requestDto = new ResetPasswordRequestDto({
29-
uuid: 'non-existent-or-expired-uuid',
32+
uuid: `Wrong${passwordPatchCode}`,
3033
password: 'test1234@',
3134
});
3235

@@ -37,19 +40,28 @@ describe(`PATCH ${URL} E2E Test`, () => {
3740
const { data } = response.body;
3841
expect(response.status).toBe(HttpStatus.NOT_FOUND);
3942
expect(data).toBeUndefined();
43+
44+
// DB, Redis when
45+
const savedPasswordCode = await redisService.get(
46+
redisKeyMake(passwordPatchCode),
47+
);
48+
49+
// DB, Redis then
50+
expect(savedPasswordCode).toBeNull();
4051
});
4152

4253
it('[200] 존재하는 비밀번호 세션 ID를 통해 비밀번호 변경 요청을 할 경우 비밀번호 변경을 성공한다.', async () => {
4354
// given
44-
const uuid = 'test-reset-password-uuid';
45-
const redisKey = `${REDIS_KEYS.USER_RESET_PASSWORD_KEY}:${uuid}`;
4655
const user = await userRepository.save(UserFixture.createUserFixture());
4756
const updatedPassword = 'test1234@';
4857
const requestDto = new ResetPasswordRequestDto({
49-
uuid,
58+
uuid: passwordPatchCode,
5059
password: updatedPassword,
5160
});
52-
await redisService.set(redisKey, JSON.stringify(user.id));
61+
await redisService.set(
62+
redisKeyMake(passwordPatchCode),
63+
JSON.stringify(user.id),
64+
);
5365

5466
// Http when
5567
const response = await agent.patch(URL).send(requestDto);
@@ -61,12 +73,14 @@ describe(`PATCH ${URL} E2E Test`, () => {
6173

6274
// DB, Redis when
6375
const savedUser = await userRepository.findOneBy({ id: user.id });
64-
const savedUUID = await redisService.get(redisKey);
76+
const savedPasswordCode = await redisService.get(
77+
redisKeyMake(passwordPatchCode),
78+
);
6579

6680
// DB, Redis then
6781
expect(
6882
await bcrypt.compare(updatedPassword, savedUser.password),
6983
).toBeTruthy();
70-
expect(savedUUID).toBeNull();
84+
expect(savedPasswordCode).toBeNull();
7185
});
7286
});

server/test/user/e2e/password-request.e2e-spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,33 @@ import { UserRepository } from '../../../src/user/repository/user.repository';
55
import TestAgent from 'supertest/lib/agent';
66
import { UserFixture } from '../../fixture/user.fixture';
77
import { User } from '../../../src/user/entity/user.entity';
8+
import { REDIS_KEYS } from '../../../src/common/redis/redis.constant';
9+
import { RedisService } from '../../../src/common/redis/redis.service';
10+
import * as uuid from 'uuid';
811

912
const URL = '/api/user/password-reset';
1013

1114
describe(`POST ${URL} E2E Test`, () => {
1215
let app: INestApplication;
1316
let agent: TestAgent;
1417
let user: User;
18+
let redisService: RedisService;
19+
const passwordPatchCode = 'user-password-request';
20+
const redisKeyMake = (data: string) =>
21+
`${REDIS_KEYS.USER_RESET_PASSWORD_KEY}:${data}`;
1522

1623
beforeAll(async () => {
1724
app = global.testApp;
1825
agent = supertest(app.getHttpServer());
26+
redisService = app.get(RedisService);
1927
const userRepository = app.get(UserRepository);
2028
user = await userRepository.save(UserFixture.createUserFixture());
2129
});
2230

31+
beforeEach(() => {
32+
jest.spyOn(uuid, 'v4').mockReturnValue(passwordPatchCode as any);
33+
});
34+
2335
it('[200] 존재하지 않는 이메일로 요청한 경우 비밀번호 재설정 이메일 요청을 성공한다.', async () => {
2436
// given
2537
const requestDto = new ForgotPasswordRequestDto({
@@ -33,6 +45,14 @@ describe(`POST ${URL} E2E Test`, () => {
3345
const { data } = response.body;
3446
expect(response.status).toBe(HttpStatus.OK);
3547
expect(data).toBeUndefined();
48+
49+
// DB, Redis when
50+
const savedPasswordCode = await redisService.get(
51+
redisKeyMake(passwordPatchCode),
52+
);
53+
54+
// DB, Redis then
55+
expect(savedPasswordCode).toBeNull();
3656
});
3757

3858
it('[200] 존재하는 이메일로 요청한 경우 비밀번호 재설정 이메일 요청을 성공한다.', async () => {
@@ -48,5 +68,13 @@ describe(`POST ${URL} E2E Test`, () => {
4868
const { data } = response.body;
4969
expect(response.status).toBe(HttpStatus.OK);
5070
expect(data).toBeUndefined();
71+
72+
// DB, Redis when
73+
const savedPasswordCode = await redisService.get(
74+
redisKeyMake(passwordPatchCode),
75+
);
76+
77+
// DB, Redis then
78+
expect(savedPasswordCode).toBe(user.id.toString());
5179
});
5280
});

server/test/user/e2e/refresh-token.e2e-spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { HttpStatus, INestApplication } from '@nestjs/common';
2-
import { UserService } from '../../../src/user/service/user.service';
32
import * as supertest from 'supertest';
43
import { UserRepository } from '../../../src/user/repository/user.repository';
54
import { UserFixture } from '../../fixture/user.fixture';

0 commit comments

Comments
 (0)