Skip to content

Commit 2d9d4d3

Browse files
test: join project E2E 테스트 구현
- 회원이 정상적으로 프로젝트에 참여할때 201 반환 테스트 - 회원이 이미 프로젝트에 참여한 경우 200 반환 테스트 - 토큰이 유효하지 않을경우 401 반환 테스트 - body의 형식이 유효하지 않을 경우 400 반환 테스트 - 프로젝트 링크가 유효하지 않을 경우 404 반환 테스트 Co-Authored-By: Suhjeong Kim <[email protected]>
1 parent d6101e9 commit 2d9d4d3

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import * as request from 'supertest';
2+
import {
3+
app,
4+
appInit,
5+
createMember,
6+
githubApiService,
7+
memberFixture,
8+
memberFixture2,
9+
} from 'test/setup';
10+
import { io } from 'socket.io-client';
11+
12+
describe('Join Project', () => {
13+
let socket;
14+
let projectLinkId;
15+
let projectId;
16+
beforeEach(async () => {
17+
await app.close();
18+
await appInit();
19+
await app.listen(3000);
20+
21+
// projectLinkId를 얻기 위한 사전작업
22+
const { accessToken } = await createMember(memberFixture, app);
23+
await request(app.getHttpServer())
24+
.post('/api/project')
25+
.set('Authorization', `Bearer ${accessToken}`)
26+
.send(projectPayload);
27+
const response = await request(app.getHttpServer())
28+
.get('/api/project')
29+
.set('Authorization', `Bearer ${accessToken}`);
30+
const [project] = response.body.projects;
31+
projectId = project.id;
32+
socket = io(`http://localhost:3000/project-${project.id}`, {
33+
path: '/api/socket.io',
34+
});
35+
await new Promise<void>((resolve) => {
36+
socket.on('connect', () => {
37+
socket.emit('joinLanding');
38+
});
39+
socket.on('landing', (data) => {
40+
const { content } = data;
41+
projectLinkId = content.inviteLinkId;
42+
resolve();
43+
});
44+
});
45+
});
46+
afterEach(async () => {
47+
socket.close();
48+
});
49+
50+
const projectPayload = {
51+
title: 'Lesser1',
52+
subject: '애자일한 프로젝트 관리 툴',
53+
};
54+
55+
it('should return 201', async () => {
56+
jest.spyOn(githubApiService, 'fetchGithubUser').mockResolvedValue({
57+
id: '321',
58+
login: 'username',
59+
avatar_url: 'avatar_url',
60+
});
61+
const { accessToken: newAccessToken } = await createMember(
62+
memberFixture2,
63+
app,
64+
);
65+
const response = await request(app.getHttpServer())
66+
.post('/api/project/join')
67+
.set('Authorization', `Bearer ${newAccessToken}`)
68+
.send({ inviteLinkId: projectLinkId });
69+
expect(response.status).toBe(201);
70+
});
71+
72+
it('should return 200 when already joined member', async () => {
73+
jest.spyOn(githubApiService, 'fetchGithubUser').mockResolvedValue({
74+
id: '321',
75+
login: 'username',
76+
avatar_url: 'avatar_url',
77+
});
78+
const { accessToken: newAccessToken } = await createMember(
79+
memberFixture2,
80+
app,
81+
);
82+
await request(app.getHttpServer())
83+
.post('/api/project/join')
84+
.set('Authorization', `Bearer ${newAccessToken}`)
85+
.send({ inviteLinkId: projectLinkId });
86+
87+
const response = await request(app.getHttpServer())
88+
.post('/api/project/join')
89+
.set('Authorization', `Bearer ${newAccessToken}`)
90+
.send({ inviteLinkId: projectLinkId });
91+
expect(response.status).toBe(200);
92+
expect(response.body.projectId).toBe(projectId);
93+
});
94+
95+
it('should return 400 when given bad request', async () => {
96+
jest.spyOn(githubApiService, 'fetchGithubUser').mockResolvedValue({
97+
id: '321',
98+
login: 'username',
99+
avatar_url: 'avatar_url',
100+
});
101+
const { accessToken: newAccessToken } = await createMember(
102+
memberFixture2,
103+
app,
104+
);
105+
const response = await request(app.getHttpServer())
106+
.post('/api/project/join')
107+
.set('Authorization', `Bearer ${newAccessToken}`)
108+
.send({ invalidProperty: 'invalidProperty' });
109+
110+
expect(response.status).toBe(400);
111+
});
112+
113+
it('should return 401 (Bearer Token is missing)', async () => {
114+
const response = await request(app.getHttpServer())
115+
.post('/api/project/join')
116+
.send({ inviteLinkId: projectLinkId });
117+
118+
expect(response.status).toBe(401);
119+
});
120+
121+
it('should return 401 (Expired:accessToken) when given invalid access token', async () => {
122+
const response = await request(app.getHttpServer())
123+
.post('/api/project/join')
124+
.set('Authorization', `Bearer invalidToken`)
125+
.send({ inviteLinkId: projectLinkId });
126+
127+
expect(response.status).toBe(401);
128+
expect(response.body.message).toBe('Expired:accessToken');
129+
});
130+
131+
it('should return 404 when project link ID is not found', async () => {
132+
const invalidUUID = 'c93a87e8-a0a4-4b55-bdf2-59bf691f5c37';
133+
jest.spyOn(githubApiService, 'fetchGithubUser').mockResolvedValue({
134+
id: '321',
135+
login: 'username',
136+
avatar_url: 'avatar_url',
137+
});
138+
const { accessToken: newAccessToken } = await createMember(
139+
memberFixture2,
140+
app,
141+
);
142+
const response = await request(app.getHttpServer())
143+
.post('/api/project/join')
144+
.set('Authorization', `Bearer ${newAccessToken}`)
145+
.send({ inviteLinkId: invalidUUID });
146+
expect(response.status).toBe(404);
147+
});
148+
});

backend/test/setup.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ export const memberFixture = {
2222
tech_stack: { stacks: ['js', 'ts'] },
2323
};
2424

25+
export const memberFixture2 = {
26+
github_id: 321,
27+
github_username: 'github_username',
28+
github_image_url: 'avatar_url',
29+
username: 'username2',
30+
position: 'position',
31+
tech_stack: { stacks: ['js', 'ts'] },
32+
};
33+
2534
export const githubUserFixture = {
2635
id: '123',
2736
login: 'username',

0 commit comments

Comments
 (0)