Skip to content

Commit 36ece5b

Browse files
authored
Merge branch 'develop' into feature-be-#312
2 parents a30f235 + 8ce0fd5 commit 36ece5b

File tree

56 files changed

+1025
-165
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1025
-165
lines changed

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

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,39 @@ describe('AuthService', () => {
6868
provider: 'naver',
6969
7070
};
71-
const user = new User();
72-
jest.spyOn(userRepository, 'create').mockReturnValue(user);
73-
jest.spyOn(userRepository, 'save').mockResolvedValue(user);
71+
const generated
72+
73+
flakeId = Snowflake.generate(); // Snowflake.generate()의 mock 값을 준비
74+
const newDate = new Date();
75+
const createdUser = {
76+
providerId: dto.providerId,
77+
provider: dto.provider,
78+
email: dto.email,
79+
snowflakeId: generatedSnowflakeId,
80+
};
81+
const savedUser = {
82+
providerId: dto.providerId,
83+
provider: dto.provider,
84+
email: dto.email,
85+
snowflakeId: generatedSnowflakeId,
86+
id: 1,
87+
createdAt: newDate,
88+
};
89+
90+
jest.spyOn(Snowflake, 'generate').mockReturnValue(generatedSnowflakeId);
91+
jest.spyOn(userRepository, 'create').mockReturnValue(createdUser as User);
92+
jest.spyOn(userRepository, 'save').mockResolvedValue(savedUser as User);
7493

7594
const result = await authService.signUp(dto);
76-
expect(result).toEqual(user);
77-
expect(userRepository.create).toHaveBeenCalledWith(dto);
78-
expect(userRepository.save).toHaveBeenCalledWith(user);
95+
96+
// Then
97+
expect(result).toEqual(savedUser); // 반환된 값이 예상된 저장된 사용자와 동일
98+
expect(Snowflake.generate).toHaveBeenCalled(); // Snowflake.generate 호출 확인
99+
expect(userRepository.create).toHaveBeenCalledWith({
100+
...dto,
101+
snowflakeId: generatedSnowflakeId,
102+
});
103+
expect(userRepository.save).toHaveBeenCalledWith(createdUser);
79104
});
80105
});
81106

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { SignUpDto } from './dtos/signUp.dto';
55
import { UpdateUserDto } from './dtos/UpdateUser.dto';
66
import { UserNotFoundException } from '../exception/user.exception';
77

8+
89
@Injectable()
910
export class AuthService {
1011
constructor(private readonly userRepository: UserRepository) {}
@@ -20,7 +21,10 @@ export class AuthService {
2021
}
2122

2223
async signUp(dto: SignUpDto): Promise<User> {
23-
const user = this.userRepository.create(dto);
24+
const user = this.userRepository.create({
25+
...dto,
26+
snowflakeId: Snowflake.generate(),
27+
});
2428
return this.userRepository.save(user);
2529
}
2630

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Injectable } from '@nestjs/common';
22
import { JwtService } from '@nestjs/jwt';
33
import { Response } from 'express';
4-
import { InvalidTokenException } from '../../exception/invalid.exception';
54

65
const HOUR = 60 * 60;
76
const DAY = 24 * 60 * 60;
@@ -34,13 +33,9 @@ export class TokenService {
3433
}
3534

3635
verifyInviteToken(token: string): { workspaceId: string; role: string } {
37-
try {
38-
return this.jwtService.verify(token, {
39-
secret: process.env.JWT_SECRET,
40-
});
41-
} catch (error) {
42-
throw new InvalidTokenException();
43-
}
36+
return this.jwtService.verify(token, {
37+
secret: process.env.JWT_SECRET,
38+
});
4439
}
4540

4641
// 후에 DB 로직 (지금은 refreshToken이 DB로 관리 X)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ describe('EdgeService', () => {
125125
describe('findEdgesByWorkspace', () => {
126126
it('특정 워크스페이스에 존재하는 모든 엣지를 반환한다.', async () => {
127127
const workspaceId = '123456789012345678'; // Snowflake ID
128-
const workspace: Workspace = {
128+
const workspace = {
129129
id: 1,
130130
snowflakeId: workspaceId,
131131
owner: null,
@@ -138,7 +138,7 @@ describe('EdgeService', () => {
138138
edges: [],
139139
pages: [],
140140
nodes: [],
141-
};
141+
} as Workspace;
142142
const node3 = {
143143
id: 3,
144144
x: 0,

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe('PageService', () => {
6161
describe('createPage', () => {
6262
it('페이지를 성공적으로 생성한다.', async () => {
6363
const newDate1 = new Date();
64-
const workspace1: Workspace = {
64+
const workspace1 = {
6565
id: 1,
6666
snowflakeId: 'snowflake-id-1',
6767
owner: null,
@@ -74,7 +74,7 @@ describe('PageService', () => {
7474
edges: [],
7575
pages: [],
7676
nodes: [],
77-
};
77+
} as Workspace;
7878

7979
// 페이지 dto
8080
const newPageDto: CreatePageDto = {
@@ -254,7 +254,7 @@ describe('PageService', () => {
254254
describe('findPagesByWorkspace', () => {
255255
it('특정 워크스페이스에 존재하는 페이지들을 content 없이 반환한다.', async () => {
256256
const workspaceId = '123456789012345678'; // Snowflake ID
257-
const workspace: Workspace = {
257+
const workspace = {
258258
id: 1,
259259
snowflakeId: workspaceId,
260260
owner: null,
@@ -267,7 +267,7 @@ describe('PageService', () => {
267267
edges: [],
268268
pages: [],
269269
nodes: [],
270-
};
270+
} as Workspace;
271271

272272
const page1: Page = {
273273
id: 1,

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
CreateDateColumn,
77
Index,
88
} from 'typeorm';
9-
import { Snowflake } from '@theinternetfolks/snowflake';
109

1110
@Entity()
1211
export class User {
@@ -15,7 +14,7 @@ export class User {
1514

1615
@Column({ unique: true })
1716
@Index()
18-
snowflakeId: string = Snowflake.generate();
17+
snowflakeId: string;
1918

2019
@Column({ unique: true })
2120
providerId: string; // 네이버/카카오 ID

apps/backend/src/workspace/dtos/getUserWorkspacesResponse.dto.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ export class GetUserWorkspacesResponseDto {
1717
title: 'naver-boostcamp-9th',
1818
description: '네이버 부스트캠프 9기 워크스페이스입니다',
1919
thumbnailUrl: 'https://example.com/image1.png',
20-
role: 'owner',
20+
role: 'guest',
21+
visibility: 'private',
2122
},
2223
{
2324
workspaceId: 'snowflake-id-2',
2425
title: '2024-fall-컴퓨터구조',
2526
description: null,
2627
thumbnailUrl: null,
27-
role: 'guest',
28+
role: 'owner',
29+
visibility: 'public',
2830
},
2931
],
3032
description: '사용자가 속한 모든 워크스페이스 배열',

apps/backend/src/workspace/dtos/userWorkspace.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export class UserWorkspaceDto {
44
description: string | null;
55
thumbnailUrl: string | null;
66
role: 'owner' | 'guest';
7+
visibility: 'public' | 'private';
78
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ describe('WorkspaceController', () => {
2727
generateInviteUrl: jest.fn(),
2828
processInviteUrl: jest.fn(),
2929
checkAccess: jest.fn(),
30+
updateVisibility: jest.fn(),
3031
},
3132
},
3233
{

apps/backend/src/workspace/workspace.controller.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Post,
44
Delete,
55
Get,
6+
Patch,
67
UseGuards,
78
Request,
89
Body,
@@ -27,6 +28,8 @@ export enum WorkspaceResponseMessage {
2728
WORKSPACE_INVITED = '워크스페이스 게스트 초대 링크가 생성되었습니다.',
2829
WORKSPACE_JOINED = '워크스페이스에 게스트로 등록되었습니다.',
2930
WORKSPACE_ACCESS_CHECKED = '워크스페이스에 대한 사용자의 접근 권한이 확인되었습니다.',
31+
WORKSPACE_UPDATED_TO_PUBLIC = '워크스페이스가 공개로 설정되었습니다.',
32+
WORKSPACE_UPDATED_TO_PRIVATE = '워크스페이스가 비공개로 설정되었습니다.',
3033
}
3134

3235
@Controller('workspace')
@@ -152,4 +155,34 @@ export class WorkspaceController {
152155
message: WorkspaceResponseMessage.WORKSPACE_ACCESS_CHECKED,
153156
};
154157
}
158+
159+
@ApiResponse({
160+
type: MessageResponseDto,
161+
})
162+
@ApiOperation({
163+
summary: '워크스페이스를 비공개에서 공개로 설정합니다.',
164+
})
165+
@Patch('/:id/public')
166+
@UseGuards(JwtAuthGuard) // 로그인 인증
167+
@HttpCode(HttpStatus.OK)
168+
async makeWorkspacePublic(@Request() req, @Param('id') id: string) {
169+
const userId = req.user.sub; // 인증된 사용자 ID
170+
await this.workspaceService.updateVisibility(userId, id, 'public');
171+
return { message: WorkspaceResponseMessage.WORKSPACE_UPDATED_TO_PUBLIC };
172+
}
173+
174+
@ApiResponse({
175+
type: MessageResponseDto,
176+
})
177+
@ApiOperation({
178+
summary: '워크스페이스를 공개에서 비공개로 설정합니다.',
179+
})
180+
@Patch('/:id/private')
181+
@UseGuards(JwtAuthGuard) // 로그인 인증
182+
@HttpCode(HttpStatus.OK)
183+
async makeWorkspacePrivate(@Request() req, @Param('id') id: string) {
184+
const userId = req.user.sub; // 인증된 사용자 ID
185+
await this.workspaceService.updateVisibility(userId, id, 'private');
186+
return { message: WorkspaceResponseMessage.WORKSPACE_UPDATED_TO_PRIVATE };
187+
}
155188
}

0 commit comments

Comments
 (0)