Skip to content

Commit 134e736

Browse files
fix: snowflake 생성 서비스 레이어로 이동
1 parent f44988e commit 134e736

File tree

6 files changed

+79
-58
lines changed

6 files changed

+79
-58
lines changed

apps/backend/src/auth/auth.service.spec.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AuthService } from './auth.service';
33
import { UserRepository } from '../user/user.repository';
44
import { SignUpDto } from './dtos/signUp.dto';
55
import { User } from '../user/user.entity';
6+
import { Snowflake } from '@theinternetfolks/snowflake';
67

78
describe('AuthService', () => {
89
let authService: AuthService;
@@ -65,14 +66,37 @@ describe('AuthService', () => {
6566
provider: 'naver',
6667
6768
};
68-
const user = new User();
69-
jest.spyOn(userRepository, 'create').mockReturnValue(user);
70-
jest.spyOn(userRepository, 'save').mockResolvedValue(user);
69+
const generatedSnowflakeId = Snowflake.generate(); // Snowflake.generate()의 mock 값을 준비
70+
const newDate = new Date();
71+
const createdUser = {
72+
providerId: dto.providerId,
73+
provider: dto.provider,
74+
email: dto.email,
75+
snowflakeId: generatedSnowflakeId,
76+
};
77+
const savedUser = {
78+
providerId: dto.providerId,
79+
provider: dto.provider,
80+
email: dto.email,
81+
snowflakeId: generatedSnowflakeId,
82+
id: 1,
83+
createdAt: newDate,
84+
};
85+
86+
jest.spyOn(Snowflake, 'generate').mockReturnValue(generatedSnowflakeId);
87+
jest.spyOn(userRepository, 'create').mockReturnValue(createdUser as User);
88+
jest.spyOn(userRepository, 'save').mockResolvedValue(savedUser as User);
7189

7290
const result = await authService.signUp(dto);
73-
expect(result).toEqual(user);
74-
expect(userRepository.create).toHaveBeenCalledWith(dto);
75-
expect(userRepository.save).toHaveBeenCalledWith(user);
91+
92+
// Then
93+
expect(result).toEqual(savedUser); // 반환된 값이 예상된 저장된 사용자와 동일
94+
expect(Snowflake.generate).toHaveBeenCalled(); // Snowflake.generate 호출 확인
95+
expect(userRepository.create).toHaveBeenCalledWith({
96+
...dto,
97+
snowflakeId: generatedSnowflakeId,
98+
});
99+
expect(userRepository.save).toHaveBeenCalledWith(createdUser);
76100
});
77101
});
78102
});

apps/backend/src/auth/auth.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
22
import { UserRepository } from '../user/user.repository';
33
import { User } from '../user/user.entity';
44
import { SignUpDto } from './dtos/signUp.dto';
5+
import { Snowflake } from '@theinternetfolks/snowflake';
56

67
@Injectable()
78
export class AuthService {
@@ -18,7 +19,10 @@ export class AuthService {
1819
}
1920

2021
async signUp(dto: SignUpDto): Promise<User> {
21-
const user = this.userRepository.create(dto);
22+
const user = this.userRepository.create({
23+
...dto,
24+
snowflakeId: Snowflake.generate(),
25+
});
2226
return this.userRepository.save(user);
2327
}
2428

apps/backend/src/user/user.entity.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import {
55
Column,
66
CreateDateColumn,
77
Index,
8-
BeforeInsert,
98
} from 'typeorm';
10-
import { Snowflake } from '@theinternetfolks/snowflake';
119

1210
@Entity()
1311
export class User {
@@ -35,9 +33,4 @@ export class User {
3533

3634
@CreateDateColumn()
3735
createdAt: Date;
38-
39-
@BeforeInsert()
40-
generateSnowflakeId() {
41-
this.snowflakeId = Snowflake.generate();
42-
}
4336
}

apps/backend/src/workspace/workspace.entity.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ import {
77
UpdateDateColumn,
88
OneToMany,
99
Index,
10-
BeforeInsert,
1110
} from 'typeorm';
1211
import { User } from '../user/user.entity';
13-
import { Snowflake } from '@theinternetfolks/snowflake';
1412
import { Edge } from '../edge/edge.entity';
1513
import { Page } from '../page/page.entity';
1614
import { Node } from '../node/node.entity';
@@ -53,9 +51,4 @@ export class Workspace {
5351

5452
@OneToMany(() => Node, (node) => node.workspace)
5553
nodes: Node[];
56-
57-
@BeforeInsert()
58-
generateSnowflakeId() {
59-
this.snowflakeId = Snowflake.generate();
60-
}
6154
}

apps/backend/src/workspace/workspace.service.spec.ts

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Role } from '../role/role.entity';
1212
import { User } from '../user/user.entity';
1313
import { TokenService } from '../auth/token/token.service';
1414
import { ForbiddenAccessException } from '../exception/access.exception';
15+
import { Snowflake } from '@theinternetfolks/snowflake';
1516

1617
describe('WorkspaceService', () => {
1718
let service: WorkspaceService;
@@ -72,64 +73,68 @@ describe('WorkspaceService', () => {
7273
});
7374

7475
describe('createWorkspace', () => {
75-
it('워크스페이스를 성공적으로 생성한다.', async () => {
76+
it('성공적으로 워크스페이스를 생성한다.', async () => {
77+
// Mock 데이터
7678
const userId = 1;
7779
const dto: CreateWorkspaceDto = {
7880
title: 'New Workspace',
79-
description: 'A test workspace',
81+
description: 'Description of workspace',
8082
visibility: 'private',
81-
thumbnailUrl: 'http://example.com/thumbnail.png',
83+
thumbnailUrl: 'http://example.com/image.png',
8284
};
8385

84-
const owner = { id: userId } as User;
85-
const newDate = new Date();
86-
const newWorkspace = {
87-
id: 1,
88-
snowflakeId: 'snowflake-id',
89-
owner,
90-
title: dto.title,
91-
description: dto.description,
92-
visibility: dto.visibility,
93-
createdAt: newDate,
94-
updatedAt: newDate,
95-
thumbnailUrl: dto.thumbnailUrl,
96-
edges: [],
97-
pages: [],
98-
nodes: [],
86+
const mockUser = { id: userId } as User;
87+
const generatedSnowflakeId = Snowflake.generate();
88+
const mockWorkspace = {
89+
id: 10,
90+
...dto,
91+
snowflakeId: generatedSnowflakeId,
9992
} as Workspace;
10093

101-
jest.spyOn(userRepository, 'findOneBy').mockResolvedValue(owner);
102-
jest.spyOn(workspaceRepository, 'save').mockResolvedValue(newWorkspace);
94+
// Mocking
95+
jest.spyOn(userRepository, 'findOneBy').mockResolvedValue(mockUser);
96+
jest.spyOn(Snowflake, 'generate').mockReturnValue(generatedSnowflakeId);
97+
jest.spyOn(workspaceRepository, 'save').mockResolvedValue(mockWorkspace);
98+
jest.spyOn(roleRepository, 'save').mockResolvedValue(undefined);
10399

100+
// 실행
104101
const result = await service.createWorkspace(userId, dto);
105102

106-
expect(result).toEqual(newWorkspace);
103+
// 검증
107104
expect(userRepository.findOneBy).toHaveBeenCalledWith({ id: userId });
108105
expect(workspaceRepository.save).toHaveBeenCalledWith({
109-
owner,
110-
...dto,
111-
visibility: 'private',
106+
snowflakeId: generatedSnowflakeId,
107+
owner: mockUser,
108+
title: dto.title,
109+
description: dto.description,
110+
visibility: 'private', // 기본값 확인
111+
thumbnailUrl: dto.thumbnailUrl,
112112
});
113113
expect(roleRepository.save).toHaveBeenCalledWith({
114-
userId: owner.id,
115-
workspaceId: newWorkspace.id,
114+
userId: mockUser.id,
115+
workspaceId: mockWorkspace.id,
116116
role: 'owner',
117117
});
118+
expect(result).toEqual(mockWorkspace);
118119
});
119120

120-
it('사용자가 존재하지 않으면 UserNotFoundException을 throw한다.', async () => {
121+
it('사용자를 찾을 수 없으면 UserNotFoundException을 던진다.', async () => {
122+
// Mocking
121123
jest.spyOn(userRepository, 'findOneBy').mockResolvedValue(null);
122124

123-
const dto: CreateWorkspaceDto = {
124-
title: 'New Workspace',
125-
description: 'A test workspace',
126-
visibility: 'private',
127-
thumbnailUrl: 'http://example.com/thumbnail.png',
128-
};
129-
130-
await expect(service.createWorkspace(1, dto)).rejects.toThrow(
131-
UserNotFoundException,
132-
);
125+
// 실행 및 검증
126+
await expect(
127+
service.createWorkspace(1, {
128+
title: 'New Workspace',
129+
description: 'Description of workspace',
130+
visibility: 'private',
131+
thumbnailUrl: 'http://example.com/image.png',
132+
}),
133+
).rejects.toThrow(UserNotFoundException);
134+
135+
expect(userRepository.findOneBy).toHaveBeenCalledWith({ id: 1 });
136+
expect(workspaceRepository.save).not.toHaveBeenCalled();
137+
expect(roleRepository.save).not.toHaveBeenCalled();
133138
});
134139
});
135140

apps/backend/src/workspace/workspace.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { NotWorkspaceOwnerException } from '../exception/workspace-auth.exceptio
1111
import { TokenService } from '../auth/token/token.service';
1212
import { ForbiddenAccessException } from '../exception/access.exception';
1313
import { UserAlreadyInWorkspaceException } from '../exception/role-duplicate.exception';
14+
import { Snowflake } from '@theinternetfolks/snowflake';
1415

1516
enum MainWorkspace {
1617
OWNER_SNOWFLAKEID = 'admin',
@@ -53,6 +54,7 @@ export class WorkspaceService {
5354

5455
// 워크스페이스 생성 및 저장
5556
const newWorkspace = await this.workspaceRepository.save({
57+
snowflakeId: Snowflake.generate(),
5658
owner,
5759
title,
5860
description,

0 commit comments

Comments
 (0)