Skip to content

Commit

Permalink
Merge pull request #490 from project-violet/server-getcomment
Browse files Browse the repository at this point in the history
Implements get comment
  • Loading branch information
violet-dev authored Sep 7, 2024
2 parents 876fc50 + 6f447d9 commit 769a2a4
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 10 deletions.
39 changes: 39 additions & 0 deletions violet-server/src/comment/comment.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('CommentController', () => {
database: ':memory:',
entities: [User, Comment],
synchronize: true,
logging: true,
}),
],
controllers: [CommentController],
Expand Down Expand Up @@ -63,6 +64,44 @@ describe('CommentController', () => {
expect(res.ok).toBe(true);
});

it('get comment', async () => {
await controller.postComment(mockUser, {
where: 'general',
body: 'test',
});
let res = await controller.getComment({
where: 'general',
});
expect(res.elements).not.toHaveLength(0);
});

it('post comment with parent', async () => {
// Post Parent Comment
await controller.postComment(mockUser, {
where: 'general',
body: 'parent',
});

// Get Parent Comment Id
let parentComment = await controller.getComment({
where: 'general',
});
let parentCommentId = parentComment.elements[0].id;

// Post Child Comment
let postChildRes = await controller.postComment(mockUser, {
where: 'general',
body: 'child',
parent: parentCommentId,
});
expect(postChildRes.ok).toBe(true);

let childComment = await controller.getComment({
where: 'general',
});
expect(childComment.elements[0].parent!).toBe(parentCommentId);
});

afterEach(async () => {
await module.close();
});
Expand Down
11 changes: 11 additions & 0 deletions violet-server/src/comment/comment.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Body,
Controller,
Get,
Post,
UseGuards,
UsePipes,
Expand All @@ -13,12 +14,22 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CurrentUser } from 'src/common/decorators/current-user.decorator';
import { User } from 'src/user/entity/user.entity';
import { AccessTokenGuard } from 'src/auth/guards/access-token.guard';
import { CommentGetDto, CommentGetResponseDto } from './dtos/comment-get.dto';

@ApiTags('comment')
@Controller('comment')
export class CommentController {
constructor(private readonly commentService: CommentService) {}

@Get('/')
@UsePipes(new ValidationPipe({ transform: true }))
@ApiOperation({ summary: 'Get Comment' })
@UseGuards(HmacAuthGuard)
@UseGuards(AccessTokenGuard)
async getComment(@Body() dto: CommentGetDto): Promise<CommentGetResponseDto> {
return await this.commentService.getComment(dto);
}

@Post('/')
@UsePipes(new ValidationPipe({ transform: true }))
@ApiOperation({ summary: 'Post Comment' })
Expand Down
34 changes: 31 additions & 3 deletions violet-server/src/comment/comment.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,46 @@ import { DataSource, Repository } from 'typeorm';
import { CommentPostDto } from './dtos/comment-post.dto';
import { User } from 'src/user/entity/user.entity';
import { Comment } from './entity/comment.entity';
import { CommentGetDto } from './dtos/comment-get.dto';

const DEFAULT_GET_COMMENT_TAKE = 100;

@Injectable()
export class CommentRepository extends Repository<Comment> {
constructor(private dataSource: DataSource) {
super(Comment, dataSource.createEntityManager());
}

async getComment(dto: CommentGetDto): Promise<Comment[]> {
return await this.find({
select: {
id: true,
user: {
userAppId: true,
},
body: true,
createdAt: true,
parent: {
id: true,
},
},
where: {
where: dto.where,
},
take: DEFAULT_GET_COMMENT_TAKE,
order: {
id: 'DESC',
},
relations: {
user: true,
parent: true,
},
});
}

async createComment(user: User, dto: CommentPostDto): Promise<Comment> {
const { parent, where, body } = dto;
// CHECK: 그냥 parent id를 넣는 방법은 없나?
const parentComment = await this.findOneBy({ id: parent });
const comment = this.create({ parent: parentComment, user, where, body });
const comment = this.create({ parent: { id: parent }, user, where, body });
try {
await this.save(comment);
return comment;
Expand Down
16 changes: 16 additions & 0 deletions violet-server/src/comment/comment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@ import { Injectable, Logger } from '@nestjs/common';
import { CommentPostDto } from './dtos/comment-post.dto';
import { User } from 'src/user/entity/user.entity';
import { CommentRepository } from './comment.repository';
import {
CommentGetDto,
CommentGetResponseDto,
CommentGetResponseDtoElement,
} from './dtos/comment-get.dto';

@Injectable()
export class CommentService {
constructor(private repository: CommentRepository) {}

async getComment(dto: CommentGetDto): Promise<CommentGetResponseDto> {
try {
const comments = await this.repository.getComment(dto);
return { elements: comments.map(CommentGetResponseDtoElement.from) };
} catch (e) {
Logger.error(e);

throw e;
}
}

async postComment(
user: User,
dto: CommentPostDto,
Expand Down
78 changes: 78 additions & 0 deletions violet-server/src/comment/dtos/comment-get.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { Comment } from 'src/comment/entity/comment.entity';
import {
IsArray,
IsNumber,
IsOptional,
IsString,
Matches,
} from 'class-validator';

export class CommentGetDto {
@IsString()
@ApiProperty({
description: 'Where to get',
required: true,
})
@Type(() => String)
@Matches(`^(general|\d+)$`, 'i')
where: string;
}

export class CommentGetResponseDtoElement {
@IsNumber()
@ApiProperty({
description: 'Comment Id',
required: true,
})
id: number;

@IsString()
@ApiProperty({
description: 'Body',
required: true,
})
userAppId: string;

@IsString()
@ApiProperty({
description: 'Body',
required: true,
})
body: string;

@IsString()
@ApiProperty({
description: 'Write DateTime',
required: true,
})
dateTime: Date;

@IsString()
@IsOptional()
@ApiProperty({
description: 'Parent Comment',
required: false,
})
parent?: number;

static from(comment: Comment): CommentGetResponseDtoElement {
return {
id: comment.id,
userAppId: comment.user.userAppId,
body: comment.body,
dateTime: comment.createdAt,
parent: comment.parent?.id,
};
}
}

export class CommentGetResponseDto {
@IsArray()
@ApiProperty({
description: 'Comment Elements',
required: true,
})
elements: CommentGetResponseDtoElement[];
}
4 changes: 3 additions & 1 deletion violet-server/src/comment/dtos/comment-post.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsString, Matches } from 'class-validator';
import { IsString, Matches, MaxLength } from 'class-validator';

export class CommentPostDto {
@IsString()
Expand All @@ -10,6 +10,7 @@ export class CommentPostDto {
})
@Type(() => String)
@Matches(`^(general|\d+)$`, 'i')
@MaxLength(20)
where: string;

@IsString()
Expand All @@ -18,6 +19,7 @@ export class CommentPostDto {
required: true,
})
@Type(() => String)
@MaxLength(500)
body: string;

@IsString()
Expand Down
11 changes: 5 additions & 6 deletions violet-server/src/comment/entity/comment.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ import {

@Entity()
export class Comment extends CoreEntity {
@PrimaryGeneratedColumn()
id: number;

@ApiProperty({
description: 'User Id',
required: true,
})
@ManyToOne(() => User, (user) => user.userAppId)
@JoinColumn({ name: 'userAppId' })
user: User;

@Column()
Expand All @@ -29,9 +28,9 @@ export class Comment extends CoreEntity {
@Column()
body: string;

@ManyToOne(() => Comment, (comment) => comment.id)
@JoinColumn({ name: 'childs' })
parent: Comment;
@ManyToOne(() => Comment, (comment) => comment.childs)
@JoinColumn({ name: 'parentId' })
parent?: Comment;

@OneToMany(() => Comment, (comment) => comment.id)
childs: Comment[];
Expand Down

0 comments on commit 769a2a4

Please sign in to comment.