-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- 컨트롤러, 서비스, 레포지토리에서 초대링크 업데이트 메서드 구현 - 리더인 경우, 리더가 아닌경우 각각에 대한 초대링크 업데이트 E2E 테스트 추가
- Loading branch information
1 parent
c9aa172
commit 3916432
Showing
8 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
backend/src/project/dto/invite-link/InviteLinkUpdateRequest.dto.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { IsNotEmpty, Matches } from 'class-validator'; | ||
|
||
export class InviteLinkUpdateRequestDto { | ||
@Matches(/^update$/) | ||
action: string; | ||
|
||
@IsNotEmpty() | ||
content: Record<string, any>; | ||
} |
23 changes: 23 additions & 0 deletions
23
backend/src/project/dto/invite-link/InviteLinkUpdateResponse.dto.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class inviteLinkDto { | ||
inviteLinkId: string; | ||
|
||
static of(inviteLinkId: string): inviteLinkDto { | ||
const dto = new inviteLinkDto(); | ||
dto.inviteLinkId = inviteLinkId; | ||
return dto; | ||
} | ||
} | ||
|
||
export class InviteLinkUpdateResponseDto { | ||
domain: string; | ||
action: string; | ||
content: inviteLinkDto; | ||
|
||
static of(inviteLinkId: string): InviteLinkUpdateResponseDto { | ||
const dto = new InviteLinkUpdateResponseDto(); | ||
dto.domain = 'inviteLink'; | ||
dto.action = 'update'; | ||
dto.content = inviteLinkDto.of(inviteLinkId); | ||
return dto; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
backend/src/project/ws-controller/ws-project-invite-link.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ProjectService } from '../service/project.service'; | ||
import { ClientSocket } from '../type/ClientSocket.type'; | ||
import { validate } from 'class-validator'; | ||
import { plainToClass } from 'class-transformer'; | ||
import { getRecursiveErrorMsgList } from '../util/validation.util'; | ||
import { InviteLinkUpdateRequestDto } from '../dto/invite-link/InviteLinkUpdateRequest.dto'; | ||
import { InviteLinkUpdateResponseDto } from '../dto/invite-link/InviteLinkUpdateResponse.dto'; | ||
|
||
@Injectable() | ||
export class WsProjectInviteLinkController { | ||
constructor(private readonly projectService: ProjectService) {} | ||
async updateInviteLink(client: ClientSocket, data: any) { | ||
const errors = await validate( | ||
plainToClass(InviteLinkUpdateRequestDto, data), | ||
); | ||
if (errors.length > 0) { | ||
const errorList = getRecursiveErrorMsgList(errors); | ||
client.emit('error', { errorList }); | ||
return; | ||
} | ||
try { | ||
const newInviteLinkId = await this.projectService.updateInviteLink( | ||
client.project.id, | ||
client.member, | ||
); | ||
client.emit('landing', InviteLinkUpdateResponseDto.of(newInviteLinkId)); | ||
} catch (e) { | ||
if (e.message === 'Member is not the project leader') { | ||
client.disconnect(true); | ||
} else throw e; | ||
} | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
backend/test/project/ws-landing-page/ws-invite-link.e2e-spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { | ||
app, | ||
appInit, | ||
connectServer, | ||
createMember, | ||
createProject, | ||
getProjectLinkId, | ||
joinProject, | ||
listenAppAndSetPortEnv, | ||
memberFixture, | ||
memberFixture2, | ||
projectPayload, | ||
} from 'test/setup'; | ||
import { | ||
emitJoinLanding, | ||
handleConnectErrorWithReject, | ||
handleErrorWithReject, | ||
initLanding, | ||
} from '../ws-common'; | ||
|
||
describe('WS invite link', () => { | ||
beforeEach(async () => { | ||
await app.close(); | ||
await appInit(); | ||
await listenAppAndSetPortEnv(app); | ||
}); | ||
describe('update invite link', () => { | ||
it('should return updated invite link data when project leader request', async () => { | ||
let socket; | ||
return new Promise<void>(async (resolve, reject) => { | ||
const accessToken = (await createMember(memberFixture, app)) | ||
.accessToken; | ||
const project = await createProject(accessToken, projectPayload, app); | ||
socket = connectServer(project.id, accessToken); | ||
handleConnectErrorWithReject(socket, reject); | ||
handleErrorWithReject(socket, reject); | ||
await emitJoinLanding(socket); | ||
await initLanding(socket); | ||
const data = { | ||
action: 'update', | ||
content: {}, | ||
}; | ||
socket.emit('inviteLink', data); | ||
await expectUpdateInviteLink(socket); | ||
resolve(); | ||
}).finally(() => { | ||
socket.close(); | ||
}); | ||
}); | ||
const expectUpdateInviteLink = async (socket) => { | ||
return await new Promise<void>((res) => { | ||
socket.once('landing', async (data) => { | ||
const { content, action, domain } = data; | ||
expect(domain).toBe('inviteLink'); | ||
expect(action).toBe('update'); | ||
expect(content.inviteLinkId).toBeDefined(); | ||
expect(typeof content.inviteLinkId).toBe('string'); | ||
res(); | ||
}); | ||
}); | ||
}; | ||
|
||
it('should disconnect if the requester is not the project leader', async () => { | ||
let socket; | ||
return new Promise<void>(async (resolve, reject) => { | ||
const accessToken = (await createMember(memberFixture, app)) | ||
.accessToken; | ||
const project = await createProject(accessToken, projectPayload, app); | ||
const projectLinkId = await getProjectLinkId(accessToken, project.id); | ||
|
||
const accessToken2 = (await createMember(memberFixture2, app)) | ||
.accessToken; | ||
await joinProject(accessToken2, projectLinkId); | ||
|
||
socket = connectServer(project.id, accessToken2); | ||
handleConnectErrorWithReject(socket, reject); | ||
handleErrorWithReject(socket, reject); | ||
await emitJoinLanding(socket); | ||
await initLanding(socket); | ||
const data = { | ||
action: 'update', | ||
content: {}, | ||
}; | ||
socket.emit('inviteLink', data); | ||
socket.on('disconnect', () => { | ||
resolve(); | ||
}); | ||
}).finally(() => { | ||
socket.close(); | ||
}); | ||
}); | ||
}); | ||
}); |