Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be/feature/#598 사용자 api 및 서비스 구현 #599

Merged
merged 18 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/was/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
ignorePatterns: ['.eslintrc.js', 'jest*.config.js'],
rules: {
'no-console': 'warn',
'@typescript-eslint/no-unused-vars': 'off',
Expand Down
3 changes: 3 additions & 0 deletions backend/was/jest-e2e.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const jestConfig = require('./jest.config');

module.exports = jestConfig('e2e');
3 changes: 3 additions & 0 deletions backend/was/jest-unit.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const jestConfig = require('./jest.config');

module.exports = jestConfig('unit');
17 changes: 17 additions & 0 deletions backend/was/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const commonJestConfig = require('./jest.config.json');

module.exports = (target) => {
if (target === 'unit') {
return {
...commonJestConfig,
testRegex: '.*\\.spec\\.ts$',
};
}
if (target === 'e2e') {
return {
...commonJestConfig,
testRegex: '.e2e-spec.ts$',
};
}
return commonJestConfig;
};
16 changes: 9 additions & 7 deletions backend/was/test/jest-e2e.json → backend/was/jest.config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
{
"verbose": true,
"moduleDirectories": ["node_modules", "src"],
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "..",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": ["**/*.(t|j)s"],
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/src/$1",
"src/(.*)": "<rootDir>/src/$1",
"@auth/(.*)$": "<rootDir>/src/auth/$1",
"@chat/(.*)$": "<rootDir>/src/chat/$1",
"@chatbot/(.*)$": "<rootDir>/src/chatbot/$1",
Expand All @@ -15,10 +22,5 @@
"@members/(.*)$": "<rootDir>/src/members/$1",
"@socket/(.*)$": "<rootDir>/src/socket/$1",
"@tarot/(.*)$": "<rootDir>/src/tarot/$1"
},
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
41 changes: 2 additions & 39 deletions backend/was/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest --runInBand",
"test": "jest --config ./jest-unit.config.js --runInBand",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json --runInBand"
"test:e2e": "jest --config ./jest-e2e.config.js --runInBand"
},
"lint-staged": {
"{src,apps,libs,test}/**/*.ts": [
Expand Down Expand Up @@ -77,42 +77,5 @@
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0"
},
"jest": {
"verbose": true,
"moduleDirectories": [
"node_modules",
"src"
],
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"moduleNameMapper": {
"src/(.*)": "<rootDir>/$1",
"@auth/(.*)$": "<rootDir>/auth/$1",
"@chat/(.*)$": "<rootDir>/chat/$1",
"@chatbot/(.*)$": "<rootDir>/chatbot/$1",
"@common/(.*)$": "<rootDir>/common/$1",
"@config/(.*)$": "<rootDir>/common/config/$1",
"@constants/(.*)$": "<rootDir>/common/constants/$1",
"@interceptors/(.*)$": "<rootDir>/common/interceptors/$1",
"@exceptions/(.*)$": "<rootDir>/exceptions/$1",
"@logger/(.*)$": "<rootDir>/logger/$1",
"@members/(.*)$": "<rootDir>/members/$1",
"@socket/(.*)$": "<rootDir>/socket/$1",
"@tarot/(.*)$": "<rootDir>/tarot/$1"
}
}
}
2 changes: 1 addition & 1 deletion backend/was/src/auth/dto/auth-status.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class AuthStatusDto {
@IsBoolean()
Expand Down
5 changes: 1 addition & 4 deletions backend/was/src/auth/service/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,7 @@ describe('AuthService', () => {
await expect(
authService.login(id, providerId, profile, token),
).resolves.not.toThrow();
expect(memberUpdateMock).toHaveBeenCalledWith(
{ id: id },
updateMemberDto,
);
expect(memberUpdateMock).toHaveBeenCalledWith({ id }, updateMemberDto);
});
});
});
Expand Down
5 changes: 1 addition & 4 deletions backend/was/src/auth/service/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,7 @@ export class AuthService {
): Promise<Member | null> {
try {
return await this.membersRepository.findOne({
where: {
email: email,
providerId: providerId,
},
where: { email, providerId },
select: ['id'],
});
} catch (err: unknown) {
Expand Down
15 changes: 3 additions & 12 deletions backend/was/src/chat/chat.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,7 @@ describe('ChatService', () => {
},
];
for (const { memberId, email, providerId, roomId } of testData) {
const member: Member = {
id: memberId,
email: email,
providerId: providerId,
};
const member: Member = { id: memberId, email, providerId };
const room: ChattingRoom = {
id: roomId,
participant: member,
Expand All @@ -125,10 +121,7 @@ describe('ChatService', () => {
result,
userInfo,
);
expect(expectation).toEqual({
memberId: memberId,
roomId: roomId,
});
expect(expectation).toEqual({ memberId, roomId });
expect(transactionMock).toHaveBeenCalled();
}
});
Expand All @@ -149,9 +142,7 @@ describe('ChatService', () => {
},
];
for (const { roomId, memberId, messages } of testData) {
const member: Member = {
id: memberId,
};
const member: Member = { id: memberId };
const room: ChattingRoom = {
id: roomId,
participant: member,
Expand Down
7 changes: 2 additions & 5 deletions backend/was/src/chat/chat.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export class ChatService {
): Promise<ChattingRoom> {
try {
const room: ChattingRoom | null = await manager.findOne(ChattingRoom, {
where: { id: id },
where: { id },
select: ['id', 'participant'],
});
if (!room) {
Expand All @@ -252,10 +252,7 @@ export class ChatService {
): Promise<Member> {
try {
const member: Member | null = await manager.findOne(Member, {
where: {
email: email,
providerId: providerId,
},
where: { email, providerId },
select: ['id'],
});
if (!member) {
Expand Down
2 changes: 1 addition & 1 deletion backend/was/src/chat/dto/chatting-message.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { ChattingMessage } from '../entities';

export class ChattingMessageDto {
Expand Down
2 changes: 1 addition & 1 deletion backend/was/src/chat/dto/chatting-room.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsArray, IsDate, IsString, IsUUID } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { ChattingRoom } from '../entities';

export class ChattingRoomDto {
Expand Down
2 changes: 1 addition & 1 deletion backend/was/src/chat/dto/update-chatting-room.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class UpdateChattingRoomDto {
@IsString()
Expand Down
11 changes: 11 additions & 0 deletions backend/was/src/exceptions/codemap/members-codemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ExceptionCodemap } from './type';

export const MEMBERS_CODEMAP: ExceptionCodemap = {
NOT_FOUND: {
status: 404,
message: '사용자를 찾을 수 없습니다.',
code: 'MME001',
description:
'해당 이메일에 해당하는 사용자가 존재하지 않습니다. 쿠키에 들어있는 email, providerId가 올바른지 확인해주세요.',
},
};
Comment on lines +3 to +11
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍

9 changes: 9 additions & 0 deletions backend/was/src/members/dto/create-member.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
IsString,
IsUrl,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { ProviderIdEnum } from '@constants/etc';
import { ProfileDto } from '@auth/dto';

Expand All @@ -18,10 +19,18 @@ export class CreateMemberDto {
readonly providerId: number;

@IsString()
@ApiProperty({
description: '사용자 닉네임',
required: true,
})
readonly nickname: string;

@IsUrl()
@IsOptional()
@ApiProperty({
description: '사용자 프로필 URL',
required: false,
})
readonly profileUrl?: string;

static fromProfile(providerId: number, profile: ProfileDto): CreateMemberDto {
Expand Down
12 changes: 12 additions & 0 deletions backend/was/src/members/dto/member.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PartialType } from '@nestjs/swagger';
import { Member } from '../entities';
import { CreateMemberDto } from './create-member.dto';

export class MemberDto extends PartialType(CreateMemberDto) {
static fromEntity(entity: Member): MemberDto {
return {
nickname: entity.nickname ?? '',
profileUrl: entity.profileUrl,
};
}
}
22 changes: 22 additions & 0 deletions backend/was/src/members/members.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '@auth/guard';
import { MemberDto } from './dto/member.dto';
import { FindMemberByEmailDecorator } from './members.decorators';
import { MembersService } from './members.service';

@UseGuards(JwtAuthGuard)
@Controller('/members')
@ApiTags('✅ Members API')
export class MembersController {
constructor(private readonly membersService: MembersService) {}

@Get()
@FindMemberByEmailDecorator('사용자 정보', MemberDto)
async findMemberByEmail(@Req() req: any): Promise<MemberDto> {
return await this.membersService.findMemberByEmail(
req.user.email,
req.user.providerId,
);
}
}
6 changes: 6 additions & 0 deletions backend/was/src/members/members.decorators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SwaggerDecoratorBuilder } from '@kimyu0218/swagger-decorator-builder';

export const FindMemberByEmailDecorator = (target: string, returnType: any) =>
new SwaggerDecoratorBuilder(target, 'GET', returnType)
.removeResponse(403)
.build();
4 changes: 4 additions & 0 deletions backend/was/src/members/members.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Member } from './entities';
import { MembersController } from './members.controller';
import { MembersService } from './members.service';

@Module({
imports: [TypeOrmModule.forFeature([Member])],
controllers: [MembersController],
providers: [MembersService],
})
export class MembersModule {}
Loading