From 2897d81e6ede04334c1dea1e027bf105c43c50d7 Mon Sep 17 00:00:00 2001 From: won2283 Date: Mon, 22 Jan 2024 02:13:04 +0000 Subject: [PATCH 01/23] feat(be): implement admin annoouncement create and read --- .devcontainer/devcontainer.json | 3 +- .../src/announcement/announcement.resolver.ts | 4 +-- .../src/announcement/announcement.service.ts | 31 +++++++++++++++---- .../dto/create-announcement.input.ts | 7 +++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6ab7508763..8435ca9461 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -32,5 +32,6 @@ "source=${localEnv:HOME}/.aws,target=/home/node/.aws,type=bind,consistency=cached" ], // Connect as non-root user (https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user) - "remoteUser": "node" + "remoteUser": "node", + "initializeCommand": "echo 'Hello World!'" } diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 46cf477f0d..57896581ea 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -17,8 +17,8 @@ export class AnnouncementResolver { } @Query(() => [Announcement], { name: 'announcement' }) - findAll() { - return this.announcementService.findAll() + findAll(@Args('problemId', { type: () => Int }) problemId: number) { + return this.announcementService.findAll(problemId) } @Query(() => Announcement, { name: 'announcement' }) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index bf014c9fab..d92ae96a39 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -1,19 +1,38 @@ import { Injectable } from '@nestjs/common' +import { PrismaService } from '@libs/prisma' import type { CreateAnnouncementInput } from './dto/create-announcement.input' import type { UpdateAnnouncementInput } from './dto/update-announcement.input' @Injectable() export class AnnouncementService { - create(createAnnouncementInput: CreateAnnouncementInput) { - return createAnnouncementInput + constructor(private readonly prisma: PrismaService) {} + + async create( + announcement: CreateAnnouncementInput + ): Promise { + await this.prisma.announcement.create({ + data: { + problemId: announcement.problemId, + content: announcement.content + } + }) + return announcement } - findAll() { - return `This action returns all announcement` + async findAll(problemId: number) { + return await this.prisma.announcement.findMany({ + where: { + problemId + } + }) } - findOne(id: number) { - return `This action returns a #${id} announcement` + async findOne(id: number) { + return await this.prisma.announcement.findFirstOrThrow({ + where: { + id + } + }) } update(id: number, updateAnnouncementInput: UpdateAnnouncementInput) { diff --git a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts index 5d59f6ca53..5000d6d4dc 100644 --- a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts +++ b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts @@ -2,6 +2,9 @@ import { InputType, Int, Field } from '@nestjs/graphql' @InputType() export class CreateAnnouncementInput { - @Field(() => Int, { description: 'Example field (placeholder)' }) - exampleField: number + @Field(() => Int, { description: 'problemId field' }) + problemId: number + + @Field(() => String, { description: 'content field' }) + content: string } From 10b70efc2ba7aac215a4220b36ae1a436d74cab8 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 22 Jan 2024 02:28:36 +0000 Subject: [PATCH 02/23] feat(be): implement admin annoouncement create and read --- .devcontainer/devcontainer.json | 3 +- .../src/announcement/announcement.resolver.ts | 4 +-- .../src/announcement/announcement.service.ts | 31 ++++--------------- .../dto/create-announcement.input.ts | 7 ++--- 4 files changed, 11 insertions(+), 34 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8435ca9461..6ab7508763 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -32,6 +32,5 @@ "source=${localEnv:HOME}/.aws,target=/home/node/.aws,type=bind,consistency=cached" ], // Connect as non-root user (https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user) - "remoteUser": "node", - "initializeCommand": "echo 'Hello World!'" + "remoteUser": "node" } diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 57896581ea..46cf477f0d 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -17,8 +17,8 @@ export class AnnouncementResolver { } @Query(() => [Announcement], { name: 'announcement' }) - findAll(@Args('problemId', { type: () => Int }) problemId: number) { - return this.announcementService.findAll(problemId) + findAll() { + return this.announcementService.findAll() } @Query(() => Announcement, { name: 'announcement' }) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index d92ae96a39..bf014c9fab 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -1,38 +1,19 @@ import { Injectable } from '@nestjs/common' -import { PrismaService } from '@libs/prisma' import type { CreateAnnouncementInput } from './dto/create-announcement.input' import type { UpdateAnnouncementInput } from './dto/update-announcement.input' @Injectable() export class AnnouncementService { - constructor(private readonly prisma: PrismaService) {} - - async create( - announcement: CreateAnnouncementInput - ): Promise { - await this.prisma.announcement.create({ - data: { - problemId: announcement.problemId, - content: announcement.content - } - }) - return announcement + create(createAnnouncementInput: CreateAnnouncementInput) { + return createAnnouncementInput } - async findAll(problemId: number) { - return await this.prisma.announcement.findMany({ - where: { - problemId - } - }) + findAll() { + return `This action returns all announcement` } - async findOne(id: number) { - return await this.prisma.announcement.findFirstOrThrow({ - where: { - id - } - }) + findOne(id: number) { + return `This action returns a #${id} announcement` } update(id: number, updateAnnouncementInput: UpdateAnnouncementInput) { diff --git a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts index 5000d6d4dc..5d59f6ca53 100644 --- a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts +++ b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts @@ -2,9 +2,6 @@ import { InputType, Int, Field } from '@nestjs/graphql' @InputType() export class CreateAnnouncementInput { - @Field(() => Int, { description: 'problemId field' }) - problemId: number - - @Field(() => String, { description: 'content field' }) - content: string + @Field(() => Int, { description: 'Example field (placeholder)' }) + exampleField: number } From a1e231f41f79871935b72a4236f045b442159a84 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 22 Jan 2024 02:31:28 +0000 Subject: [PATCH 03/23] feat(be): implement admin annoouncement create and read --- .../src/announcement/announcement.resolver.ts | 4 +-- .../src/announcement/announcement.service.ts | 31 +++++++++++++++---- .../dto/create-announcement.input.ts | 7 +++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 46cf477f0d..57896581ea 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -17,8 +17,8 @@ export class AnnouncementResolver { } @Query(() => [Announcement], { name: 'announcement' }) - findAll() { - return this.announcementService.findAll() + findAll(@Args('problemId', { type: () => Int }) problemId: number) { + return this.announcementService.findAll(problemId) } @Query(() => Announcement, { name: 'announcement' }) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index bf014c9fab..d92ae96a39 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -1,19 +1,38 @@ import { Injectable } from '@nestjs/common' +import { PrismaService } from '@libs/prisma' import type { CreateAnnouncementInput } from './dto/create-announcement.input' import type { UpdateAnnouncementInput } from './dto/update-announcement.input' @Injectable() export class AnnouncementService { - create(createAnnouncementInput: CreateAnnouncementInput) { - return createAnnouncementInput + constructor(private readonly prisma: PrismaService) {} + + async create( + announcement: CreateAnnouncementInput + ): Promise { + await this.prisma.announcement.create({ + data: { + problemId: announcement.problemId, + content: announcement.content + } + }) + return announcement } - findAll() { - return `This action returns all announcement` + async findAll(problemId: number) { + return await this.prisma.announcement.findMany({ + where: { + problemId + } + }) } - findOne(id: number) { - return `This action returns a #${id} announcement` + async findOne(id: number) { + return await this.prisma.announcement.findFirstOrThrow({ + where: { + id + } + }) } update(id: number, updateAnnouncementInput: UpdateAnnouncementInput) { diff --git a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts index 5d59f6ca53..5000d6d4dc 100644 --- a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts +++ b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts @@ -2,6 +2,9 @@ import { InputType, Int, Field } from '@nestjs/graphql' @InputType() export class CreateAnnouncementInput { - @Field(() => Int, { description: 'Example field (placeholder)' }) - exampleField: number + @Field(() => Int, { description: 'problemId field' }) + problemId: number + + @Field(() => String, { description: 'content field' }) + content: string } From 4d2cc7b07cc88651d2caa11aa1d053fcccec8659 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 25 Jan 2024 07:31:50 +0000 Subject: [PATCH 04/23] feat: implement admin announcement update and delete --- .../announcement.resolver.spec.ts | 23 ++++++++ .../src/announcement/announcement.resolver.ts | 38 ++++++------- .../announcement/announcement.service.spec.ts | 0 .../src/announcement/announcement.service.ts | 56 ++++++++++++++----- .../announcement/dto/announcement.input.ts | 10 ++++ .../dto/create-announcement.input.ts | 10 ---- .../dto/update-announcement.input.ts | 10 ---- .../Create Announcement/Succeed.bru | 28 ++++++++++ .../Delete Announcement/Succeed.bru | 23 ++++++++ .../Announcement/Get Announcement/Succeed.bru | 24 ++++++++ .../Get Announcements/Succeed.bru | 25 +++++++++ .../Update Announcement/Succeed.bru | 29 ++++++++++ 12 files changed, 222 insertions(+), 54 deletions(-) create mode 100644 backend/apps/admin/src/announcement/announcement.resolver.spec.ts create mode 100644 backend/apps/admin/src/announcement/announcement.service.spec.ts create mode 100644 backend/apps/admin/src/announcement/dto/announcement.input.ts delete mode 100644 backend/apps/admin/src/announcement/dto/create-announcement.input.ts delete mode 100644 backend/apps/admin/src/announcement/dto/update-announcement.input.ts create mode 100644 collection/admin/Announcement/Create Announcement/Succeed.bru create mode 100644 collection/admin/Announcement/Delete Announcement/Succeed.bru create mode 100644 collection/admin/Announcement/Get Announcement/Succeed.bru create mode 100644 collection/admin/Announcement/Get Announcements/Succeed.bru create mode 100644 collection/admin/Announcement/Update Announcement/Succeed.bru diff --git a/backend/apps/admin/src/announcement/announcement.resolver.spec.ts b/backend/apps/admin/src/announcement/announcement.resolver.spec.ts new file mode 100644 index 0000000000..f885afb384 --- /dev/null +++ b/backend/apps/admin/src/announcement/announcement.resolver.spec.ts @@ -0,0 +1,23 @@ +import { Test, type TestingModule } from '@nestjs/testing' +import { expect } from 'chai' +import { AnnouncementResolver } from './announcement.resolver' +import { AnnouncementService } from './announcement.service' + +describe('AnnouncementResolver', () => { + let resolver: AnnouncementResolver + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + AnnouncementResolver, + { provide: AnnouncementService, useValue: {} } + ] + }).compile() + + resolver = module.get(AnnouncementResolver) + }) + + it('shoulld be defined', () => { + expect(resolver).to.be.ok + }) +}) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 57896581ea..28642433b7 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -1,44 +1,42 @@ import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql' import { Announcement } from '@admin/@generated' import { AnnouncementService } from './announcement.service' -import { CreateAnnouncementInput } from './dto/create-announcement.input' -import { UpdateAnnouncementInput } from './dto/update-announcement.input' +import { AnnouncementInput } from './dto/announcement.input' @Resolver(() => Announcement) export class AnnouncementResolver { constructor(private readonly announcementService: AnnouncementService) {} @Mutation(() => Announcement) - createAnnouncement( + async createAnnouncement( @Args('createAnnouncementInput') - createAnnouncementInput: CreateAnnouncementInput + announcementInput: AnnouncementInput ) { - return this.announcementService.create(createAnnouncementInput) + return await this.announcementService.create(announcementInput) } - @Query(() => [Announcement], { name: 'announcement' }) - findAll(@Args('problemId', { type: () => Int }) problemId: number) { - return this.announcementService.findAll(problemId) + @Query(() => [Announcement], { name: 'getAnnouncementsByProblemId' }) + async getAnnouncementsByProblemId( + @Args('problemId', { type: () => Int }) problemId: number + ) { + return await this.announcementService.findAll(problemId) } - @Query(() => Announcement, { name: 'announcement' }) - findOne(@Args('id', { type: () => Int }) id: number) { - return this.announcementService.findOne(id) + @Query(() => Announcement, { name: 'getAnnouncement' }) + async getAnnouncement(@Args('id', { type: () => Int }) id: number) { + return await this.announcementService.findOne(id) } @Mutation(() => Announcement) - updateAnnouncement( - @Args('updateAnnouncementInput') - updateAnnouncementInput: UpdateAnnouncementInput + async updateAnnouncement( + @Args('id', { type: () => Int }) id: number, + @Args('announcementInput') announcementInput: AnnouncementInput ) { - return this.announcementService.update( - updateAnnouncementInput.id, - updateAnnouncementInput - ) + return await this.announcementService.update(id, announcementInput) } @Mutation(() => Announcement) - removeAnnouncement(@Args('id', { type: () => Int }) id: number) { - return this.announcementService.remove(id) + async removeAnnouncement(@Args('id', { type: () => Int }) id: number) { + return await this.announcementService.delete(id) } } diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index d92ae96a39..268f352e31 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -1,22 +1,31 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, Logger } from '@nestjs/common' +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' +import { EntityNotExistException } from '@libs/exception' import { PrismaService } from '@libs/prisma' -import type { CreateAnnouncementInput } from './dto/create-announcement.input' -import type { UpdateAnnouncementInput } from './dto/update-announcement.input' +import type { AnnouncementInput } from './dto/announcement.input' @Injectable() export class AnnouncementService { + private readonly logger = new Logger(AnnouncementService.name) + constructor(private readonly prisma: PrismaService) {} async create( - announcement: CreateAnnouncementInput - ): Promise { - await this.prisma.announcement.create({ + announcementInput: AnnouncementInput + ): Promise { + const announcement = await this.prisma.announcement.findFirst({ + where: { + problemId: announcementInput.problemId, + content: announcementInput.content + } + }) + if (announcement) throw new Error('Announcement already exist') + return await this.prisma.announcement.create({ data: { - problemId: announcement.problemId, - content: announcement.content + problemId: announcementInput.problemId, + content: announcementInput.content } }) - return announcement } async findAll(problemId: number) { @@ -28,18 +37,37 @@ export class AnnouncementService { } async findOne(id: number) { - return await this.prisma.announcement.findFirstOrThrow({ + const announcement = await this.prisma.announcement.findFirst({ where: { id } }) + if (!announcement) throw new EntityNotExistException('announcement') + return announcement } - update(id: number, updateAnnouncementInput: UpdateAnnouncementInput) { - return updateAnnouncementInput + async update(id: number, announcementInput: AnnouncementInput) { + try { + return await this.prisma.announcement.update({ + where: { id }, + data: announcementInput + }) + } catch (error) { + if (error instanceof PrismaClientKnownRequestError) { + throw new EntityNotExistException('announcement') + } + } } - remove(id: number) { - return `This action removes a #${id} announcement` + async delete(id: number) { + try { + return await this.prisma.announcement.delete({ + where: { id } + }) + } catch (error) { + if (error instanceof PrismaClientKnownRequestError) { + throw new EntityNotExistException('announcement') + } + } } } diff --git a/backend/apps/admin/src/announcement/dto/announcement.input.ts b/backend/apps/admin/src/announcement/dto/announcement.input.ts new file mode 100644 index 0000000000..e36924c869 --- /dev/null +++ b/backend/apps/admin/src/announcement/dto/announcement.input.ts @@ -0,0 +1,10 @@ +import { InputType, Int, Field } from '@nestjs/graphql' + +@InputType() +export class AnnouncementInput { + @Field(() => Int) + problemId: number + + @Field(() => String) + content: string +} diff --git a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts b/backend/apps/admin/src/announcement/dto/create-announcement.input.ts deleted file mode 100644 index 5000d6d4dc..0000000000 --- a/backend/apps/admin/src/announcement/dto/create-announcement.input.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InputType, Int, Field } from '@nestjs/graphql' - -@InputType() -export class CreateAnnouncementInput { - @Field(() => Int, { description: 'problemId field' }) - problemId: number - - @Field(() => String, { description: 'content field' }) - content: string -} diff --git a/backend/apps/admin/src/announcement/dto/update-announcement.input.ts b/backend/apps/admin/src/announcement/dto/update-announcement.input.ts deleted file mode 100644 index 748bdb4acb..0000000000 --- a/backend/apps/admin/src/announcement/dto/update-announcement.input.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InputType, Field, Int, PartialType } from '@nestjs/graphql' -import { CreateAnnouncementInput } from './create-announcement.input' - -@InputType() -export class UpdateAnnouncementInput extends PartialType( - CreateAnnouncementInput -) { - @Field(() => Int) - id: number -} diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru new file mode 100644 index 0000000000..46c471cdfb --- /dev/null +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -0,0 +1,28 @@ +meta { + name: Succeed + type: graphql + seq: 1 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + createAnnouncement( + createAnnouncementInput: { + problemId: 1 + content: "this is new announcement1" + } + ) { + id + problemId + content + } + } + + +} diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru new file mode 100644 index 0000000000..0ad671045f --- /dev/null +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -0,0 +1,23 @@ +meta { + name: Succeed + type: graphql + seq: 1 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + removeAnnouncement( + id: 3 + ) { + id + problemId + content + } + } +} diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru new file mode 100644 index 0000000000..2867c22d9b --- /dev/null +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -0,0 +1,24 @@ +meta { + name: Succeed + type: graphql + seq: 1 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + query { + getAnnouncement( + id: 4 + ) { + id + problemId + content + } + } + +} diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru new file mode 100644 index 0000000000..8b532265d4 --- /dev/null +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -0,0 +1,25 @@ +meta { + name: Succeed + type: graphql + seq: 1 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + query { + getAnnouncementsByProblemId( + problemId: 3 + ) { + id + problemId + content + } + } + + +} diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru new file mode 100644 index 0000000000..b3fdd2e0b7 --- /dev/null +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -0,0 +1,29 @@ +meta { + name: Succeed + type: graphql + seq: 1 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + updateAnnouncement( + id: 2 + announcementInput: { + problemId: 3 + content: "updated announcement" + } + ) { + id + problemId + content + } + } + + +} From 485b8a209edc80d875f38c455982e9cad43a940c Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 29 Jan 2024 08:12:59 +0000 Subject: [PATCH 05/23] feat: add test code and additional error handler --- .../announcement/announcement.service.spec.ts | 138 ++++++++++++++++++ .../src/announcement/announcement.service.ts | 15 +- 2 files changed, 151 insertions(+), 2 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index e69de29bb2..e2a7316717 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -0,0 +1,138 @@ +import { Test, type TestingModule } from '@nestjs/testing' +import { faker } from '@faker-js/faker' +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' +import { expect } from 'chai' +import { stub } from 'sinon' +import { + DuplicateFoundException, + EntityNotExistException +} from '@libs/exception' +import { PrismaService } from '@libs/prisma' +import { AnnouncementService } from './announcement.service' + +const problemId = faker.number.int() +const id = faker.number.int() +const announcementInput = { + problemId, + content: faker.string.sample() +} + +const announcement = { + ...announcementInput, + id +} + +const problem = { + problemId +} + +const db = { + announcement: { + findFirst: stub(), + findMany: stub().resolves([announcement]), + update: stub(), + delete: stub(), + create: stub().resolves(announcement) + }, + problem: { + findFirst: stub() + } +} + +const PrismaErrorInstance = new PrismaClientKnownRequestError('error', { + code: '4xx', + clientVersion: 'x.x.x' +}) + +describe('AnnouncementService', () => { + let service: AnnouncementService + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AnnouncementService, { provide: PrismaService, useValue: db }] + }).compile() + + service = module.get(AnnouncementService) + }) + + it('should be defined', () => { + expect(service).to.be.ok + }) + + describe('create', () => { + it('should return created announcement', async () => { + db.announcement.findFirst.resolves(null) + db.problem.findFirst.resolves(problem) + + const res = await service.create(announcementInput) + expect(res).to.deep.equal(announcement) + }) + + it('should throw error when given announcement already exists', async () => { + db.announcement.findFirst.resolves(announcement) + + await expect(service.create(announcementInput)).to.be.rejectedWith( + DuplicateFoundException + ) + }) + + it('should throw error when given problemId is invalid', async () => { + db.announcement.findFirst.resolves(null) + db.problem.findFirst.resolves(null) + + await expect(service.create(announcementInput)).to.be.rejectedWith( + EntityNotExistException + ) + }) + }) + + describe('findAll', () => { + it('should return all announcements', async () => { + db.announcement.findMany() + const res = await service.findAll(problemId) + expect(res).to.deep.equal([announcement]) + }) + }) + + describe('findOne', () => { + it('should throw error when given id is invalid', async () => { + db.announcement.findFirst.resolves(null) + await expect(service.findOne(id)).to.be.rejectedWith( + EntityNotExistException + ) + }) + it('should return an announcement', async () => { + db.announcement.findFirst.resolves(announcement) + const res = await service.findOne(id) + expect(res).to.deep.equal(announcement) + }) + }) + + describe('update', () => { + it('should return updated announcement', async () => { + db.announcement.update.resolves(announcement) + const res = await service.update(id, announcementInput) + expect(res).to.deep.equal(announcement) + }) + it('should throw error when given id is invalid', async () => { + db.announcement.update.rejects(PrismaErrorInstance) + await expect(service.update(id, announcementInput)).to.be.rejectedWith( + EntityNotExistException + ) + }) + }) + + describe('delete', () => { + it('should return deleted announcement', async () => { + db.announcement.delete.resolves(announcement) + const res = await service.delete(id) + expect(res).to.deep.equal(announcement) + }) + it('should throw error when given id is invalid', async () => { + db.announcement.delete.rejects(PrismaErrorInstance) + await expect(service.delete(id)).to.be.rejectedWith( + EntityNotExistException + ) + }) + }) +}) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index 268f352e31..efa2bff1b4 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -1,6 +1,9 @@ import { Injectable, Logger } from '@nestjs/common' import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' -import { EntityNotExistException } from '@libs/exception' +import { + EntityNotExistException, + DuplicateFoundException +} from '@libs/exception' import { PrismaService } from '@libs/prisma' import type { AnnouncementInput } from './dto/announcement.input' @@ -19,7 +22,15 @@ export class AnnouncementService { content: announcementInput.content } }) - if (announcement) throw new Error('Announcement already exist') + if (announcement) throw new DuplicateFoundException('announcement') + + const problem = await this.prisma.problem.findFirst({ + where: { + id: announcementInput.problemId + } + }) + if (!problem) throw new EntityNotExistException('problem') + return await this.prisma.announcement.create({ data: { problemId: announcementInput.problemId, From 2b2cbb6357c2a870081de215110e0aabb99429ba Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 29 Jan 2024 08:37:59 +0000 Subject: [PATCH 06/23] docs: add bruno announcement requests --- .../Error: Duplicated Announcement.bru | 26 +++++++++++++++++ .../Error: Invalid Problem ID.bru | 28 +++++++++++++++++++ .../Create Announcement/Succeed.bru | 6 ++-- .../Error: Invalid Announcement ID.bru | 23 +++++++++++++++ .../Delete Announcement/Succeed.bru | 2 +- .../Error: Invalid Announcement ID.bru | 24 ++++++++++++++++ .../Announcement/Get Announcement/Succeed.bru | 2 +- .../Get Announcements/Succeed.bru | 6 ++-- .../Error: Invalid Announcement ID.bru | 28 +++++++++++++++++++ .../Update Announcement/Succeed.bru | 4 +-- 10 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru create mode 100644 collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru create mode 100644 collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru create mode 100644 collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru create mode 100644 collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru diff --git a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru new file mode 100644 index 0000000000..15374403d7 --- /dev/null +++ b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru @@ -0,0 +1,26 @@ +meta { + name: Error: Duplicated Announcement + type: graphql + seq: 2 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + createAnnouncement( + createAnnouncementInput: { + problemId: 1 + content: "Announcement_1_0" + } + ) { + id + problemId + content + } + } +} diff --git a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru new file mode 100644 index 0000000000..6e33c96803 --- /dev/null +++ b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru @@ -0,0 +1,28 @@ +meta { + name: Error: Invalid Problem ID + type: graphql + seq: 3 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + createAnnouncement( + createAnnouncementInput: { + problemId: -9999999 + content: "this is new announcment!" + } + ) { + id + problemId + content + } + } + + +} diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 46c471cdfb..9cd2a291b4 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -15,7 +15,7 @@ body:graphql { createAnnouncement( createAnnouncementInput: { problemId: 1 - content: "this is new announcement1" + content: "this is new announcement" } ) { id @@ -23,6 +23,6 @@ body:graphql { content } } - - + + } diff --git a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru new file mode 100644 index 0000000000..7a6fad6cca --- /dev/null +++ b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru @@ -0,0 +1,23 @@ +meta { + name: Error: Invalid Announcement ID + type: graphql + seq: 2 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + removeAnnouncement( + id: -9999999 + ) { + id + problemId + content + } + } +} diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 0ad671045f..60e059eb29 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -13,7 +13,7 @@ post { body:graphql { mutation { removeAnnouncement( - id: 3 + id: 1 ) { id problemId diff --git a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru new file mode 100644 index 0000000000..aae74aada5 --- /dev/null +++ b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru @@ -0,0 +1,24 @@ +meta { + name: Error: Invalid Announcement ID + type: graphql + seq: 2 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + query { + getAnnouncement( + id: -99999 + ) { + id + problemId + content + } + } + +} diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index 2867c22d9b..6f2ada3ba2 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -13,7 +13,7 @@ post { body:graphql { query { getAnnouncement( - id: 4 + id: 1 ) { id problemId diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index 8b532265d4..ba364e752c 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -13,13 +13,13 @@ post { body:graphql { query { getAnnouncementsByProblemId( - problemId: 3 + problemId: 1 ) { id problemId content } } - - + + } diff --git a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru new file mode 100644 index 0000000000..7528d2a55b --- /dev/null +++ b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru @@ -0,0 +1,28 @@ +meta { + name: Error: Invalid Announcement ID + type: graphql + seq: 2 +} + +post { + url: {{gqlUrl}} + body: graphql + auth: none +} + +body:graphql { + mutation { + updateAnnouncement( + id: -99999 + announcementInput: { + problemId: 2 + content: "updated announcement" + } + ) { + id + problemId + content + } + } + +} diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index b3fdd2e0b7..4b67c73af4 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -13,9 +13,9 @@ post { body:graphql { mutation { updateAnnouncement( - id: 2 + id: 1 announcementInput: { - problemId: 3 + problemId: 2 content: "updated announcement" } ) { From 06be8aaff7a16465dfd1892bbe5f31e44f6fd76c Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Tue, 13 Feb 2024 06:23:19 +0000 Subject: [PATCH 07/23] feat: change business exception handling --- .../src/announcement/announcement.resolver.ts | 40 +++++++++++++++++-- .../src/announcement/announcement.service.ts | 6 +-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 28642433b7..2fafd57883 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -1,10 +1,16 @@ +import { InternalServerErrorException, Logger } from '@nestjs/common' import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql' +import { + DuplicateFoundException, + EntityNotExistException +} from '@libs/exception' import { Announcement } from '@admin/@generated' import { AnnouncementService } from './announcement.service' import { AnnouncementInput } from './dto/announcement.input' @Resolver(() => Announcement) export class AnnouncementResolver { + private readonly logger = new Logger(AnnouncementResolver.name) constructor(private readonly announcementService: AnnouncementService) {} @Mutation(() => Announcement) @@ -12,19 +18,40 @@ export class AnnouncementResolver { @Args('createAnnouncementInput') announcementInput: AnnouncementInput ) { - return await this.announcementService.create(announcementInput) + try { + return await this.announcementService.create(announcementInput) + } catch (error) { + if (error instanceof DuplicateFoundException) { + throw error.convert2HTTPException() + } + this.logger.error(error) + throw new InternalServerErrorException() + } } @Query(() => [Announcement], { name: 'getAnnouncementsByProblemId' }) async getAnnouncementsByProblemId( @Args('problemId', { type: () => Int }) problemId: number ) { - return await this.announcementService.findAll(problemId) + try { + return await this.announcementService.findAll(problemId) + } catch (error) { + this.logger.error(error) + throw new InternalServerErrorException() + } } @Query(() => Announcement, { name: 'getAnnouncement' }) async getAnnouncement(@Args('id', { type: () => Int }) id: number) { - return await this.announcementService.findOne(id) + try { + return await this.announcementService.findOne(id) + } catch (error) { + if (error instanceof EntityNotExistException) { + throw error.convert2HTTPException() + } + this.logger.error(error) + throw new InternalServerErrorException() + } } @Mutation(() => Announcement) @@ -32,7 +59,12 @@ export class AnnouncementResolver { @Args('id', { type: () => Int }) id: number, @Args('announcementInput') announcementInput: AnnouncementInput ) { - return await this.announcementService.update(id, announcementInput) + try { + return await this.announcementService.update(id, announcementInput) + } catch (error) { + this.logger.error(error) + throw new InternalServerErrorException() + } } @Mutation(() => Announcement) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index efa2bff1b4..c96424e8f9 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -24,12 +24,11 @@ export class AnnouncementService { }) if (announcement) throw new DuplicateFoundException('announcement') - const problem = await this.prisma.problem.findFirst({ + await this.prisma.problem.findFirstOrThrow({ where: { id: announcementInput.problemId } }) - if (!problem) throw new EntityNotExistException('problem') return await this.prisma.announcement.create({ data: { @@ -48,12 +47,11 @@ export class AnnouncementService { } async findOne(id: number) { - const announcement = await this.prisma.announcement.findFirst({ + const announcement = await this.prisma.announcement.findFirstOrThrow({ where: { id } }) - if (!announcement) throw new EntityNotExistException('announcement') return announcement } From 7cd01eed2d283235f09cf65e02b5cddc9501c25d Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Tue, 13 Feb 2024 06:37:52 +0000 Subject: [PATCH 08/23] chore: change business exception handling --- .../src/announcement/announcement.resolver.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 2fafd57883..64e41df58a 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -46,9 +46,6 @@ export class AnnouncementResolver { try { return await this.announcementService.findOne(id) } catch (error) { - if (error instanceof EntityNotExistException) { - throw error.convert2HTTPException() - } this.logger.error(error) throw new InternalServerErrorException() } @@ -62,6 +59,9 @@ export class AnnouncementResolver { try { return await this.announcementService.update(id, announcementInput) } catch (error) { + if (error instanceof EntityNotExistException) { + throw error.convert2HTTPException() + } this.logger.error(error) throw new InternalServerErrorException() } @@ -69,6 +69,14 @@ export class AnnouncementResolver { @Mutation(() => Announcement) async removeAnnouncement(@Args('id', { type: () => Int }) id: number) { - return await this.announcementService.delete(id) + try { + return await this.announcementService.delete(id) + } catch (error) { + if (error instanceof EntityNotExistException) { + throw error.convert2HTTPException() + } + this.logger.error(error) + throw new InternalServerErrorException() + } } } From 6c1cf38e51a12c27596acca4bd7c56e5c5c261ac Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Tue, 13 Feb 2024 07:11:19 +0000 Subject: [PATCH 09/23] docs: bruno collection docs --- .../src/announcement/announcement.resolver.ts | 19 ++++++++++++++++++- .../Create Announcement/Succeed.bru | 17 +++++++++++++++++ .../Delete Announcement/Succeed.bru | 14 ++++++++++++++ .../Announcement/Get Announcement/Succeed.bru | 14 ++++++++++++++ .../Get Announcements/Succeed.bru | 10 ++++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 64e41df58a..ad53ee7723 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -1,5 +1,10 @@ -import { InternalServerErrorException, Logger } from '@nestjs/common' +import { + InternalServerErrorException, + Logger, + NotFoundException +} from '@nestjs/common' import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql' +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' import { DuplicateFoundException, EntityNotExistException @@ -24,6 +29,12 @@ export class AnnouncementResolver { if (error instanceof DuplicateFoundException) { throw error.convert2HTTPException() } + if ( + error instanceof PrismaClientKnownRequestError && + error.name == 'NotFoundError' + ) { + throw new NotFoundException(error.message) + } this.logger.error(error) throw new InternalServerErrorException() } @@ -46,6 +57,12 @@ export class AnnouncementResolver { try { return await this.announcementService.findOne(id) } catch (error) { + if ( + error instanceof PrismaClientKnownRequestError && + error.name == 'NotFoundError' + ) { + throw new NotFoundException(error.message) + } this.logger.error(error) throw new InternalServerErrorException() } diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 9cd2a291b4..b6936ed4ba 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -26,3 +26,20 @@ body:graphql { } + +docs { + ## Create Announcment + 새로운 Announement를 생성합니다. + + ### Args + | 이름 | 타입 | 설명| + |--|--|--| + |problemId|int|Announment를 추가할 문제의 id| + |content|string|추가할 Announement의 내용| + + ### Error Case + #### CONFLICT + 추가하려는 것과 problemId, content가 모두 일치하는 Announement가 이미 존재 + #### NOT_FOUND + 존재하지 않는 problemId +} diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 60e059eb29..3f74ac22ae 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -21,3 +21,17 @@ body:graphql { } } } + +docs { + ## Delete Announcment + Announement를 제거합니다. + + ### Args + | 이름 | 타입 | 설명| + |--|--|--| + |id|int|제거할 Annoucement id| + + ### Error Case + #### NOT_FOUND + 존재하지 않는 id +} diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index 6f2ada3ba2..ef1f00c2f6 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -22,3 +22,17 @@ body:graphql { } } + +docs { + ## Get Announcment + Announcement의 정보를 조회합니다. + + ### Args + | 이름 | 타입 | 설명| + |--|--|--| + |id|int|조회할 Announment의 id| + + ### Error Case + #### NOT_FOUND + 존재하지 않는 id +} diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index ba364e752c..09e4a51285 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -23,3 +23,13 @@ body:graphql { } + +docs { + ## Get Announcments + 해당 문제에 등록된 모든 Announcement를 조회합니다. + + ### Args + | 이름 | 타입 | 설명| + |--|--|--| + |problemId|int|Announment를 조회할 문제의 id| +} From 1ed30acde9f948ac8d2448392f010aa26beb61ad Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Tue, 13 Feb 2024 07:44:05 +0000 Subject: [PATCH 10/23] chore: change prisma exception handler --- .../src/announcement/announcement.resolver.ts | 22 +++---------- .../src/announcement/announcement.service.ts | 32 +++++++++++++------ 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index ad53ee7723..7d4ba66da3 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -1,10 +1,5 @@ -import { - InternalServerErrorException, - Logger, - NotFoundException -} from '@nestjs/common' +import { InternalServerErrorException, Logger } from '@nestjs/common' import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql' -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' import { DuplicateFoundException, EntityNotExistException @@ -26,15 +21,9 @@ export class AnnouncementResolver { try { return await this.announcementService.create(announcementInput) } catch (error) { - if (error instanceof DuplicateFoundException) { + if (error instanceof DuplicateFoundException || EntityNotExistException) { throw error.convert2HTTPException() } - if ( - error instanceof PrismaClientKnownRequestError && - error.name == 'NotFoundError' - ) { - throw new NotFoundException(error.message) - } this.logger.error(error) throw new InternalServerErrorException() } @@ -57,11 +46,8 @@ export class AnnouncementResolver { try { return await this.announcementService.findOne(id) } catch (error) { - if ( - error instanceof PrismaClientKnownRequestError && - error.name == 'NotFoundError' - ) { - throw new NotFoundException(error.message) + if (error instanceof EntityNotExistException) { + throw error.convert2HTTPException() } this.logger.error(error) throw new InternalServerErrorException() diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index c96424e8f9..467cfb5220 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -24,11 +24,17 @@ export class AnnouncementService { }) if (announcement) throw new DuplicateFoundException('announcement') - await this.prisma.problem.findFirstOrThrow({ - where: { - id: announcementInput.problemId - } - }) + await this.prisma.problem + .findFirstOrThrow({ + where: { + id: announcementInput.problemId + } + }) + .catch((error) => { + if (error.name == 'NotFoundError') { + throw new EntityNotExistException('prolem') + } + }) return await this.prisma.announcement.create({ data: { @@ -47,11 +53,17 @@ export class AnnouncementService { } async findOne(id: number) { - const announcement = await this.prisma.announcement.findFirstOrThrow({ - where: { - id - } - }) + const announcement = await this.prisma.announcement + .findFirstOrThrow({ + where: { + id + } + }) + .catch((error) => { + if (error.name == 'NotFoundError') { + throw new EntityNotExistException('announcement') + } + }) return announcement } From 966f4378c9bcf7f9c6c2983c22040d5e7ec2fa89 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Tue, 13 Feb 2024 09:01:03 +0000 Subject: [PATCH 11/23] fix: update test code --- .../src/announcement/announcement.service.spec.ts | 10 ++++++---- .../admin/src/announcement/announcement.service.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index e2a7316717..10c875d247 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -29,13 +29,15 @@ const problem = { const db = { announcement: { findFirst: stub(), + findFirstOrThrow: stub(), findMany: stub().resolves([announcement]), update: stub(), delete: stub(), create: stub().resolves(announcement) }, problem: { - findFirst: stub() + findFirst: stub(), + findFirstOrThrow: stub() } } @@ -62,7 +64,7 @@ describe('AnnouncementService', () => { describe('create', () => { it('should return created announcement', async () => { db.announcement.findFirst.resolves(null) - db.problem.findFirst.resolves(problem) + db.problem.findFirstOrThrow.resolves(problem) const res = await service.create(announcementInput) expect(res).to.deep.equal(announcement) @@ -78,7 +80,7 @@ describe('AnnouncementService', () => { it('should throw error when given problemId is invalid', async () => { db.announcement.findFirst.resolves(null) - db.problem.findFirst.resolves(null) + db.problem.findFirstOrThrow.rejects(PrismaErrorInstance) await expect(service.create(announcementInput)).to.be.rejectedWith( EntityNotExistException @@ -96,7 +98,7 @@ describe('AnnouncementService', () => { describe('findOne', () => { it('should throw error when given id is invalid', async () => { - db.announcement.findFirst.resolves(null) + db.announcement.findFirstOrThrow.rejects(PrismaErrorInstance) await expect(service.findOne(id)).to.be.rejectedWith( EntityNotExistException ) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index 467cfb5220..08b12a66d8 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -32,7 +32,7 @@ export class AnnouncementService { }) .catch((error) => { if (error.name == 'NotFoundError') { - throw new EntityNotExistException('prolem') + throw new EntityNotExistException('problem') } }) From 8f81940ca80f784b98d6ed50a81dfc05a3d62644 Mon Sep 17 00:00:00 2001 From: won2283 Date: Thu, 15 Feb 2024 07:50:23 +0000 Subject: [PATCH 12/23] feat: match service and resolver function name --- .../src/announcement/announcement.resolver.ts | 17 ++++++--- .../announcement/announcement.service.spec.ts | 36 ++++++++++--------- .../src/announcement/announcement.service.ts | 10 +++--- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 7d4ba66da3..89ad6cc422 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -19,7 +19,9 @@ export class AnnouncementResolver { announcementInput: AnnouncementInput ) { try { - return await this.announcementService.create(announcementInput) + return await this.announcementService.createAnnouncement( + announcementInput + ) } catch (error) { if (error instanceof DuplicateFoundException || EntityNotExistException) { throw error.convert2HTTPException() @@ -34,7 +36,9 @@ export class AnnouncementResolver { @Args('problemId', { type: () => Int }) problemId: number ) { try { - return await this.announcementService.findAll(problemId) + return await this.announcementService.getAnnouncementsByProblemId( + problemId + ) } catch (error) { this.logger.error(error) throw new InternalServerErrorException() @@ -44,7 +48,7 @@ export class AnnouncementResolver { @Query(() => Announcement, { name: 'getAnnouncement' }) async getAnnouncement(@Args('id', { type: () => Int }) id: number) { try { - return await this.announcementService.findOne(id) + return await this.announcementService.getAnnouncement(id) } catch (error) { if (error instanceof EntityNotExistException) { throw error.convert2HTTPException() @@ -60,7 +64,10 @@ export class AnnouncementResolver { @Args('announcementInput') announcementInput: AnnouncementInput ) { try { - return await this.announcementService.update(id, announcementInput) + return await this.announcementService.updateAnnouncement( + id, + announcementInput + ) } catch (error) { if (error instanceof EntityNotExistException) { throw error.convert2HTTPException() @@ -73,7 +80,7 @@ export class AnnouncementResolver { @Mutation(() => Announcement) async removeAnnouncement(@Args('id', { type: () => Int }) id: number) { try { - return await this.announcementService.delete(id) + return await this.announcementService.removeAnnouncement(id) } catch (error) { if (error instanceof EntityNotExistException) { throw error.convert2HTTPException() diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index 10c875d247..e1b1888a27 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -46,6 +46,8 @@ const PrismaErrorInstance = new PrismaClientKnownRequestError('error', { clientVersion: 'x.x.x' }) +PrismaErrorInstance.name = 'NotFoundError' + describe('AnnouncementService', () => { let service: AnnouncementService @@ -66,32 +68,32 @@ describe('AnnouncementService', () => { db.announcement.findFirst.resolves(null) db.problem.findFirstOrThrow.resolves(problem) - const res = await service.create(announcementInput) + const res = await service.createAnnouncement(announcementInput) expect(res).to.deep.equal(announcement) }) it('should throw error when given announcement already exists', async () => { db.announcement.findFirst.resolves(announcement) - await expect(service.create(announcementInput)).to.be.rejectedWith( - DuplicateFoundException - ) + await expect( + service.createAnnouncement(announcementInput) + ).to.be.rejectedWith(DuplicateFoundException) }) it('should throw error when given problemId is invalid', async () => { db.announcement.findFirst.resolves(null) db.problem.findFirstOrThrow.rejects(PrismaErrorInstance) - await expect(service.create(announcementInput)).to.be.rejectedWith( - EntityNotExistException - ) + await expect( + service.createAnnouncement(announcementInput) + ).to.be.rejectedWith(EntityNotExistException) }) }) describe('findAll', () => { it('should return all announcements', async () => { db.announcement.findMany() - const res = await service.findAll(problemId) + const res = await service.getAnnouncementsByProblemId(problemId) expect(res).to.deep.equal([announcement]) }) }) @@ -99,13 +101,13 @@ describe('AnnouncementService', () => { describe('findOne', () => { it('should throw error when given id is invalid', async () => { db.announcement.findFirstOrThrow.rejects(PrismaErrorInstance) - await expect(service.findOne(id)).to.be.rejectedWith( + await expect(service.getAnnouncement(id)).to.be.rejectedWith( EntityNotExistException ) }) it('should return an announcement', async () => { - db.announcement.findFirst.resolves(announcement) - const res = await service.findOne(id) + db.announcement.findFirstOrThrow.resolves(announcement) + const res = await service.getAnnouncement(id) expect(res).to.deep.equal(announcement) }) }) @@ -113,26 +115,26 @@ describe('AnnouncementService', () => { describe('update', () => { it('should return updated announcement', async () => { db.announcement.update.resolves(announcement) - const res = await service.update(id, announcementInput) + const res = await service.updateAnnouncement(id, announcementInput) expect(res).to.deep.equal(announcement) }) it('should throw error when given id is invalid', async () => { db.announcement.update.rejects(PrismaErrorInstance) - await expect(service.update(id, announcementInput)).to.be.rejectedWith( - EntityNotExistException - ) + await expect( + service.updateAnnouncement(id, announcementInput) + ).to.be.rejectedWith(EntityNotExistException) }) }) describe('delete', () => { it('should return deleted announcement', async () => { db.announcement.delete.resolves(announcement) - const res = await service.delete(id) + const res = await service.removeAnnouncement(id) expect(res).to.deep.equal(announcement) }) it('should throw error when given id is invalid', async () => { db.announcement.delete.rejects(PrismaErrorInstance) - await expect(service.delete(id)).to.be.rejectedWith( + await expect(service.removeAnnouncement(id)).to.be.rejectedWith( EntityNotExistException ) }) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index 08b12a66d8..cf787aeec7 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -13,7 +13,7 @@ export class AnnouncementService { constructor(private readonly prisma: PrismaService) {} - async create( + async createAnnouncement( announcementInput: AnnouncementInput ): Promise { const announcement = await this.prisma.announcement.findFirst({ @@ -44,7 +44,7 @@ export class AnnouncementService { }) } - async findAll(problemId: number) { + async getAnnouncementsByProblemId(problemId: number) { return await this.prisma.announcement.findMany({ where: { problemId @@ -52,7 +52,7 @@ export class AnnouncementService { }) } - async findOne(id: number) { + async getAnnouncement(id: number) { const announcement = await this.prisma.announcement .findFirstOrThrow({ where: { @@ -67,7 +67,7 @@ export class AnnouncementService { return announcement } - async update(id: number, announcementInput: AnnouncementInput) { + async updateAnnouncement(id: number, announcementInput: AnnouncementInput) { try { return await this.prisma.announcement.update({ where: { id }, @@ -80,7 +80,7 @@ export class AnnouncementService { } } - async delete(id: number) { + async removeAnnouncement(id: number) { try { return await this.prisma.announcement.delete({ where: { id } From 95a6e4c1fccb4564ecf7b135f6ab3f3f3bdada26 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 15 Feb 2024 08:08:34 +0000 Subject: [PATCH 13/23] chore: fix test code --- .../src/announcement/announcement.service.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index e1b1888a27..dd1b9625d2 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -63,7 +63,7 @@ describe('AnnouncementService', () => { expect(service).to.be.ok }) - describe('create', () => { + describe('createAnnouncement', () => { it('should return created announcement', async () => { db.announcement.findFirst.resolves(null) db.problem.findFirstOrThrow.resolves(problem) @@ -90,7 +90,7 @@ describe('AnnouncementService', () => { }) }) - describe('findAll', () => { + describe('getAnnouncementsByProblemId', () => { it('should return all announcements', async () => { db.announcement.findMany() const res = await service.getAnnouncementsByProblemId(problemId) @@ -98,7 +98,7 @@ describe('AnnouncementService', () => { }) }) - describe('findOne', () => { + describe('getAnnouncement', () => { it('should throw error when given id is invalid', async () => { db.announcement.findFirstOrThrow.rejects(PrismaErrorInstance) await expect(service.getAnnouncement(id)).to.be.rejectedWith( @@ -112,7 +112,7 @@ describe('AnnouncementService', () => { }) }) - describe('update', () => { + describe('updateAnnouncement', () => { it('should return updated announcement', async () => { db.announcement.update.resolves(announcement) const res = await service.updateAnnouncement(id, announcementInput) @@ -126,7 +126,7 @@ describe('AnnouncementService', () => { }) }) - describe('delete', () => { + describe('removeAnnouncement', () => { it('should return deleted announcement', async () => { db.announcement.delete.resolves(announcement) const res = await service.removeAnnouncement(id) From 63ad162b194fff01d01924c04512a51728ddd5e8 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 15 Feb 2024 08:29:42 +0000 Subject: [PATCH 14/23] chore: fix ts issue --- backend/apps/admin/src/announcement/announcement.service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index cf787aeec7..1d3ff6a20b 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -13,9 +13,7 @@ export class AnnouncementService { constructor(private readonly prisma: PrismaService) {} - async createAnnouncement( - announcementInput: AnnouncementInput - ): Promise { + async createAnnouncement(announcementInput: AnnouncementInput) { const announcement = await this.prisma.announcement.findFirst({ where: { problemId: announcementInput.problemId, From 2c4a95005d6e54fb90f5de29869a910c774395b6 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 19 Feb 2024 07:58:17 +0000 Subject: [PATCH 15/23] feat: fix create & update logic --- .../src/announcement/announcement.resolver.ts | 11 ++++--- .../announcement/announcement.service.spec.ts | 2 ++ .../src/announcement/announcement.service.ts | 30 +++++++++++++------ .../announcement/dto/announcement.input.ts | 5 +++- .../admin/src/contest/contest.resolver.ts | 4 +-- .../admin/src/contest/contest.service.spec.ts | 6 ++-- .../apps/admin/src/contest/contest.service.ts | 2 +- .../apps/admin/src/group/group.resolver.ts | 2 +- .../admin/src/group/group.service.spec.ts | 4 +-- .../apps/admin/src/group/model/group.input.ts | 2 +- .../admin/src/group/model/group.output.ts | 2 +- .../admin/src/notice/model/notice.input.ts | 2 +- .../apps/admin/src/notice/notice.resolver.ts | 2 +- .../admin/src/notice/notice.service.spec.ts | 2 +- backend/apps/admin/src/problem/mock/mock.ts | 4 +-- .../admin/src/problem/model/problem.input.ts | 2 +- .../admin/src/problem/model/template.input.ts | 2 +- .../admin/src/problem/problem.resolver.ts | 7 ++++- .../admin/src/problem/problem.service.spec.ts | 14 ++++----- .../apps/admin/src/problem/problem.service.ts | 8 ++--- backend/apps/admin/src/user/user.resolver.ts | 4 +-- backend/apps/admin/src/user/user.service.ts | 2 +- .../client/src/problem/problem.repository.ts | 2 +- backend/tsconfig.json | 2 +- 24 files changed, 72 insertions(+), 51 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index 89ad6cc422..d23a665f6c 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -33,10 +33,12 @@ export class AnnouncementResolver { @Query(() => [Announcement], { name: 'getAnnouncementsByProblemId' }) async getAnnouncementsByProblemId( - @Args('problemId', { type: () => Int }) problemId: number + @Args('contestId', { type: () => Int }) contestId: number, + @Args('problemId', { type: () => Int, nullable: true }) problemId?: number ) { try { return await this.announcementService.getAnnouncementsByProblemId( + contestId, problemId ) } catch (error) { @@ -61,13 +63,10 @@ export class AnnouncementResolver { @Mutation(() => Announcement) async updateAnnouncement( @Args('id', { type: () => Int }) id: number, - @Args('announcementInput') announcementInput: AnnouncementInput + @Args('content', { type: () => String }) content: string ) { try { - return await this.announcementService.updateAnnouncement( - id, - announcementInput - ) + return await this.announcementService.updateAnnouncement(id, content) } catch (error) { if (error instanceof EntityNotExistException) { throw error.convert2HTTPException() diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index dd1b9625d2..7ab0d52164 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -11,9 +11,11 @@ import { PrismaService } from '@libs/prisma' import { AnnouncementService } from './announcement.service' const problemId = faker.number.int() +const contestId = faker.number.int() const id = faker.number.int() const announcementInput = { problemId, + contestId, content: faker.string.sample() } diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index 1d3ff6a20b..a025b47731 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -16,40 +16,52 @@ export class AnnouncementService { async createAnnouncement(announcementInput: AnnouncementInput) { const announcement = await this.prisma.announcement.findFirst({ where: { - problemId: announcementInput.problemId, + ...(announcementInput.problemId && { + problemId: announcementInput.problemId + }), + contestId: announcementInput.contestId, content: announcementInput.content } }) if (announcement) throw new DuplicateFoundException('announcement') - await this.prisma.problem + await this.prisma.contestProblem .findFirstOrThrow({ where: { - id: announcementInput.problemId + contestId: announcementInput.contestId, + ...(announcementInput.problemId && { + problemId: announcementInput.problemId + }) } }) .catch((error) => { if (error.name == 'NotFoundError') { - throw new EntityNotExistException('problem') + throw new EntityNotExistException('contestProblem') } }) return await this.prisma.announcement.create({ data: { - problemId: announcementInput.problemId, + ...(announcementInput.problemId && { + problemId: announcementInput.problemId + }), + contestId: announcementInput.contestId, content: announcementInput.content } }) } - async getAnnouncementsByProblemId(problemId: number) { + //getAnnouncements + async getAnnouncementsByProblemId(contestId: number, problemId?: number) { return await this.prisma.announcement.findMany({ where: { - problemId + ...(problemId && { problemId }), + contestId } }) } + //getAnnouncementById async getAnnouncement(id: number) { const announcement = await this.prisma.announcement .findFirstOrThrow({ @@ -65,11 +77,11 @@ export class AnnouncementService { return announcement } - async updateAnnouncement(id: number, announcementInput: AnnouncementInput) { + async updateAnnouncement(id: number, content: string) { try { return await this.prisma.announcement.update({ where: { id }, - data: announcementInput + data: { content } }) } catch (error) { if (error instanceof PrismaClientKnownRequestError) { diff --git a/backend/apps/admin/src/announcement/dto/announcement.input.ts b/backend/apps/admin/src/announcement/dto/announcement.input.ts index e36924c869..650431212a 100644 --- a/backend/apps/admin/src/announcement/dto/announcement.input.ts +++ b/backend/apps/admin/src/announcement/dto/announcement.input.ts @@ -2,8 +2,11 @@ import { InputType, Int, Field } from '@nestjs/graphql' @InputType() export class AnnouncementInput { + @Field({ nullable: true }) + problemId?: number + @Field(() => Int) - problemId: number + contestId: number @Field(() => String) content: string diff --git a/backend/apps/admin/src/contest/contest.resolver.ts b/backend/apps/admin/src/contest/contest.resolver.ts index 6dbc9338ce..f4e2516eaa 100644 --- a/backend/apps/admin/src/contest/contest.resolver.ts +++ b/backend/apps/admin/src/contest/contest.resolver.ts @@ -5,8 +5,6 @@ import { ParseBoolPipe } from '@nestjs/common' import { Args, Context, Int, Mutation, Query, Resolver } from '@nestjs/graphql' -import { ContestProblem } from '@generated' -import { Contest } from '@generated' import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' import { AuthenticatedRequest, UseRolesGuard } from '@libs/auth' import { OPEN_SPACE_ID } from '@libs/constants' @@ -16,6 +14,8 @@ import { UnprocessableDataException } from '@libs/exception' import { CursorValidationPipe, GroupIDPipe, RequiredIntPipe } from '@libs/pipe' +import { ContestProblem } from '@admin/@generated' +import { Contest } from '@admin/@generated' import { ContestService } from './contest.service' import { ContestWithParticipants } from './model/contest-with-participants.model' import { CreateContestInput } from './model/contest.input' diff --git a/backend/apps/admin/src/contest/contest.service.spec.ts b/backend/apps/admin/src/contest/contest.service.spec.ts index 4b6f0f4ca9..e90ec0aa82 100644 --- a/backend/apps/admin/src/contest/contest.service.spec.ts +++ b/backend/apps/admin/src/contest/contest.service.spec.ts @@ -1,8 +1,5 @@ import { CACHE_MANAGER } from '@nestjs/cache-manager' import { Test, type TestingModule } from '@nestjs/testing' -import { ContestProblem, Group } from '@generated' -import { Problem } from '@generated' -import { Contest } from '@generated' import { faker } from '@faker-js/faker' import { Prisma } from '@prisma/client' import type { Cache } from 'cache-manager' @@ -10,6 +7,9 @@ import { expect } from 'chai' import { stub } from 'sinon' import { EntityNotExistException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import { ContestProblem, Group } from '@admin/@generated' +import { Problem } from '@admin/@generated' +import { Contest } from '@admin/@generated' import { ContestService } from './contest.service' import type { ContestWithParticipants } from './model/contest-with-participants.model' import type { diff --git a/backend/apps/admin/src/contest/contest.service.ts b/backend/apps/admin/src/contest/contest.service.ts index d0b1e86bab..1f27db61aa 100644 --- a/backend/apps/admin/src/contest/contest.service.ts +++ b/backend/apps/admin/src/contest/contest.service.ts @@ -4,7 +4,6 @@ import { Injectable, UnprocessableEntityException } from '@nestjs/common' -import type { Contest } from '@generated' import type { ContestProblem } from '@prisma/client' import { Cache } from 'cache-manager' import { @@ -18,6 +17,7 @@ import { UnprocessableDataException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import type { Contest } from '@admin/@generated' import type { CreateContestInput } from './model/contest.input' import type { UpdateContestInput } from './model/contest.input' import type { PublicizingRequest } from './model/publicizing-request.model' diff --git a/backend/apps/admin/src/group/group.resolver.ts b/backend/apps/admin/src/group/group.resolver.ts index b1eadf30be..ca0a829d73 100644 --- a/backend/apps/admin/src/group/group.resolver.ts +++ b/backend/apps/admin/src/group/group.resolver.ts @@ -1,6 +1,5 @@ import { InternalServerErrorException, Logger } from '@nestjs/common' import { Args, Int, Query, Mutation, Resolver, Context } from '@nestjs/graphql' -import { Group } from '@generated' import { Role } from '@prisma/client' import { AuthenticatedRequest, UseRolesGuard } from '@libs/auth' import { @@ -9,6 +8,7 @@ import { ForbiddenAccessException } from '@libs/exception' import { CursorValidationPipe, GroupIDPipe } from '@libs/pipe' +import { Group } from '@admin/@generated' import { GroupService } from './group.service' import { CreateGroupInput, UpdateGroupInput } from './model/group.input' import { DeletedUserGroup, FindGroup } from './model/group.output' diff --git a/backend/apps/admin/src/group/group.service.spec.ts b/backend/apps/admin/src/group/group.service.spec.ts index 35e35d9cb8..8af848f534 100644 --- a/backend/apps/admin/src/group/group.service.spec.ts +++ b/backend/apps/admin/src/group/group.service.spec.ts @@ -1,7 +1,5 @@ import { CACHE_MANAGER } from '@nestjs/cache-manager' import { Test, type TestingModule } from '@nestjs/testing' -import type { Group } from '@generated' -import type { User } from '@generated' import { faker } from '@faker-js/faker' import { Role } from '@prisma/client' import type { Cache } from 'cache-manager' @@ -15,6 +13,8 @@ import { ForbiddenAccessException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import type { Group } from '@admin/@generated' +import type { User } from '@admin/@generated' import { GroupService } from './group.service' const userId = faker.number.int() diff --git a/backend/apps/admin/src/group/model/group.input.ts b/backend/apps/admin/src/group/model/group.input.ts index d3cda6a923..a1783c1795 100644 --- a/backend/apps/admin/src/group/model/group.input.ts +++ b/backend/apps/admin/src/group/model/group.input.ts @@ -1,6 +1,6 @@ import { Field } from '@nestjs/graphql' import { InputType } from '@nestjs/graphql' -import { GroupCreateInput, GroupUpdateInput } from '@generated' +import { GroupCreateInput, GroupUpdateInput } from '@admin/@generated' @InputType() class Config { diff --git a/backend/apps/admin/src/group/model/group.output.ts b/backend/apps/admin/src/group/model/group.output.ts index 7016da3465..c539c5cfe4 100644 --- a/backend/apps/admin/src/group/model/group.output.ts +++ b/backend/apps/admin/src/group/model/group.output.ts @@ -1,6 +1,6 @@ import { Field, Int } from '@nestjs/graphql' import { ObjectType } from '@nestjs/graphql' -import { Group } from '@generated' +import { Group } from '@admin/@generated' @ObjectType() export class FindGroup extends Group { diff --git a/backend/apps/admin/src/notice/model/notice.input.ts b/backend/apps/admin/src/notice/model/notice.input.ts index d80cf33f82..f0333401f3 100644 --- a/backend/apps/admin/src/notice/model/notice.input.ts +++ b/backend/apps/admin/src/notice/model/notice.input.ts @@ -1,5 +1,5 @@ import { InputType, PartialType, PickType } from '@nestjs/graphql' -import { NoticeCreateInput } from '@generated' +import { NoticeCreateInput } from '@admin/@generated' @InputType() export class CreateNoticeInput extends PickType(NoticeCreateInput, [ diff --git a/backend/apps/admin/src/notice/notice.resolver.ts b/backend/apps/admin/src/notice/notice.resolver.ts index 49be1822fa..99a9aee6df 100644 --- a/backend/apps/admin/src/notice/notice.resolver.ts +++ b/backend/apps/admin/src/notice/notice.resolver.ts @@ -13,10 +13,10 @@ import { ResolveField, Parent } from '@nestjs/graphql' -import { Group, Notice, User } from '@generated' import { AuthenticatedRequest } from '@libs/auth' import { EntityNotExistException } from '@libs/exception' import { CursorValidationPipe, GroupIDPipe, IDValidationPipe } from '@libs/pipe' +import { Group, Notice, User } from '@admin/@generated' import { GroupService } from '@admin/group/group.service' import { UserService } from '@admin/user/user.service' import { CreateNoticeInput, UpdateNoticeInput } from './model/notice.input' diff --git a/backend/apps/admin/src/notice/notice.service.spec.ts b/backend/apps/admin/src/notice/notice.service.spec.ts index e9b689adbf..047b9a7fb7 100644 --- a/backend/apps/admin/src/notice/notice.service.spec.ts +++ b/backend/apps/admin/src/notice/notice.service.spec.ts @@ -1,11 +1,11 @@ import { Test, type TestingModule } from '@nestjs/testing' -import type { Notice } from '@generated' import { faker } from '@faker-js/faker' import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' import { expect } from 'chai' import { stub } from 'sinon' import { EntityNotExistException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import type { Notice } from '@admin/@generated' import type { CreateNoticeInput, UpdateNoticeInput } from './model/notice.input' import { NoticeService } from './notice.service' diff --git a/backend/apps/admin/src/problem/mock/mock.ts b/backend/apps/admin/src/problem/mock/mock.ts index 12974ba5a4..cb7a737879 100644 --- a/backend/apps/admin/src/problem/mock/mock.ts +++ b/backend/apps/admin/src/problem/mock/mock.ts @@ -1,7 +1,7 @@ -import { Language, Level } from '@generated' -import type { Problem } from '@generated' import { faker } from '@faker-js/faker' import { createReadStream } from 'fs' +import { Language, Level } from '@admin/@generated' +import type { Problem } from '@admin/@generated' import type { FileUploadDto } from '../dto/file-upload.dto' import type { UploadFileInput } from '../model/problem.input' import type { Template } from '../model/template.input' diff --git a/backend/apps/admin/src/problem/model/problem.input.ts b/backend/apps/admin/src/problem/model/problem.input.ts index b227ed7340..a063bdf018 100644 --- a/backend/apps/admin/src/problem/model/problem.input.ts +++ b/backend/apps/admin/src/problem/model/problem.input.ts @@ -1,7 +1,7 @@ import { Field, InputType, Int } from '@nestjs/graphql' -import { Language, Level } from '@generated' import { ValidatePromise } from 'class-validator' import { GraphQLUpload } from 'graphql-upload' +import { Language, Level } from '@admin/@generated' import type { FileUploadDto } from '../dto/file-upload.dto' import { Template } from './template.input' import { Testcase } from './testcase.input' diff --git a/backend/apps/admin/src/problem/model/template.input.ts b/backend/apps/admin/src/problem/model/template.input.ts index e19a5ede98..c20b976eff 100644 --- a/backend/apps/admin/src/problem/model/template.input.ts +++ b/backend/apps/admin/src/problem/model/template.input.ts @@ -1,5 +1,5 @@ import { Field, InputType, Int } from '@nestjs/graphql' -import { Language } from '@generated' +import { Language } from '@admin/@generated' @InputType() class Snippet { diff --git a/backend/apps/admin/src/problem/problem.resolver.ts b/backend/apps/admin/src/problem/problem.resolver.ts index a3273986ca..c9cc50ee9d 100644 --- a/backend/apps/admin/src/problem/problem.resolver.ts +++ b/backend/apps/admin/src/problem/problem.resolver.ts @@ -8,7 +8,6 @@ import { ValidationPipe } from '@nestjs/common' import { Args, Context, Query, Int, Mutation, Resolver } from '@nestjs/graphql' -import { ContestProblem, Problem, Tag, WorkbookProblem } from '@generated' import { Prisma } from '@prisma/client' import { AuthenticatedRequest } from '@libs/auth' import { OPEN_SPACE_ID } from '@libs/constants' @@ -18,6 +17,12 @@ import { UnprocessableDataException } from '@libs/exception' import { CursorValidationPipe, GroupIDPipe, RequiredIntPipe } from '@libs/pipe' +import { + ContestProblem, + Problem, + Tag, + WorkbookProblem +} from '@admin/@generated' import { CreateProblemInput, UploadFileInput, diff --git a/backend/apps/admin/src/problem/problem.service.spec.ts b/backend/apps/admin/src/problem/problem.service.spec.ts index 7ee800308e..7a1eb6acb8 100644 --- a/backend/apps/admin/src/problem/problem.service.spec.ts +++ b/backend/apps/admin/src/problem/problem.service.spec.ts @@ -1,12 +1,5 @@ import { ConfigService } from '@nestjs/config' import { Test, type TestingModule } from '@nestjs/testing' -import type { - Workbook, - WorkbookProblem, - Contest, - ContestProblem -} from '@generated' -import { Level } from '@generated' import { expect } from 'chai' import { spy, stub } from 'sinon' import { @@ -14,6 +7,13 @@ import { UnprocessableDataException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import type { + Workbook, + WorkbookProblem, + Contest, + ContestProblem +} from '@admin/@generated' +import { Level } from '@admin/@generated' import { S3Provider } from '@admin/storage/s3.provider' import { StorageService } from '@admin/storage/storage.service' import { diff --git a/backend/apps/admin/src/problem/problem.service.ts b/backend/apps/admin/src/problem/problem.service.ts index 71feeafac5..5546a7e31f 100644 --- a/backend/apps/admin/src/problem/problem.service.ts +++ b/backend/apps/admin/src/problem/problem.service.ts @@ -1,8 +1,4 @@ import { Injectable } from '@nestjs/common' -import { Language } from '@generated' -import type { ContestProblem, Tag, WorkbookProblem } from '@generated' -import { Level } from '@generated' -import type { ProblemWhereInput } from '@generated' import { Workbook } from 'exceljs' import { DuplicateFoundException, @@ -10,6 +6,10 @@ import { UnprocessableFileDataException } from '@libs/exception' import { PrismaService } from '@libs/prisma' +import { Language } from '@admin/@generated' +import type { ContestProblem, Tag, WorkbookProblem } from '@admin/@generated' +import { Level } from '@admin/@generated' +import type { ProblemWhereInput } from '@admin/@generated' import { StorageService } from '@admin/storage/storage.service' import { ImportedProblemHeader } from './model/problem.constants' import type { diff --git a/backend/apps/admin/src/user/user.resolver.ts b/backend/apps/admin/src/user/user.resolver.ts index 45ca9465b3..c437cfbe24 100644 --- a/backend/apps/admin/src/user/user.resolver.ts +++ b/backend/apps/admin/src/user/user.resolver.ts @@ -6,10 +6,10 @@ import { NotFoundException } from '@nestjs/common' import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql' -import { UserGroup } from '@generated' -import { User } from '@generated' import { OPEN_SPACE_ID } from '@libs/constants' import { CursorValidationPipe, GroupIDPipe, RequiredIntPipe } from '@libs/pipe' +import { UserGroup } from '@admin/@generated' +import { User } from '@admin/@generated' import { GroupMember } from './model/groupMember.model' import { UserService } from './user.service' diff --git a/backend/apps/admin/src/user/user.service.ts b/backend/apps/admin/src/user/user.service.ts index 173e0363c2..0ddc65ba7f 100644 --- a/backend/apps/admin/src/user/user.service.ts +++ b/backend/apps/admin/src/user/user.service.ts @@ -6,7 +6,6 @@ import { Injectable, NotFoundException } from '@nestjs/common' -import type { UserGroup } from '@generated' import { Role } from '@prisma/client' import { Cache } from 'cache-manager' import { joinGroupCacheKey } from '@libs/cache' @@ -14,6 +13,7 @@ import { JOIN_GROUP_REQUEST_EXPIRE_TIME } from '@libs/constants' import { EntityNotExistException } from '@libs/exception' import { PrismaService } from '@libs/prisma' import type { GroupJoinRequest } from '@libs/types' +import type { UserGroup } from '@admin/@generated' @Injectable() export class UserService { diff --git a/backend/apps/client/src/problem/problem.repository.ts b/backend/apps/client/src/problem/problem.repository.ts index a7b1c52c5a..b16f52f15d 100644 --- a/backend/apps/client/src/problem/problem.repository.ts +++ b/backend/apps/client/src/problem/problem.repository.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Injectable } from '@nestjs/common' -import type { CodeDraftUpdateInput } from '@generated' import type { Problem, Tag, CodeDraft, Prisma } from '@prisma/client' import { PrismaService } from '@libs/prisma' +import type { CodeDraftUpdateInput } from '@admin/@generated' import type { CreateTemplateDto } from './dto/create-code-draft.dto' import type { ProblemOrder } from './schema/problem-order.schema' diff --git a/backend/tsconfig.json b/backend/tsconfig.json index f54c34e134..38d0ce4995 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -20,7 +20,7 @@ "paths": { "@admin/*": ["./apps/admin/src/*"], "@client/*": ["./apps/client/src/*"], - "@generated": ["./apps/admin/src/@generated"], + "@generated": ["apps/admin/src/@generated"], "@libs/prisma": ["./libs/prisma/src/index.ts"], "@libs/cache": ["./libs/cache/src/index.ts"], "@libs/auth": ["./libs/auth/src/index.ts"], From 710f50cf993fd45ac68162a7184a8fa8667fff25 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 19 Feb 2024 12:33:45 +0000 Subject: [PATCH 16/23] docs: submission bruno docs & rename API --- .../admin/src/announcement/announcement.resolver.ts | 12 ++++++------ .../admin/src/announcement/announcement.service.ts | 6 ++---- .../Error: Invalid Problem ID.bru | 1 + .../Announcement/Create Announcement/Succeed.bru | 1 + .../admin/Announcement/Get Announcement/Succeed.bru | 1 + .../admin/Announcement/Get Announcements/Succeed.bru | 5 ++++- .../Error: Invalid Announcement ID.bru | 5 +---- .../Announcement/Update Announcement/Succeed.bru | 5 +---- 8 files changed, 17 insertions(+), 19 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.resolver.ts b/backend/apps/admin/src/announcement/announcement.resolver.ts index d23a665f6c..390ca650e0 100644 --- a/backend/apps/admin/src/announcement/announcement.resolver.ts +++ b/backend/apps/admin/src/announcement/announcement.resolver.ts @@ -31,13 +31,13 @@ export class AnnouncementResolver { } } - @Query(() => [Announcement], { name: 'getAnnouncementsByProblemId' }) - async getAnnouncementsByProblemId( + @Query(() => [Announcement], { name: 'getAnnouncements' }) + async getAnnouncements( @Args('contestId', { type: () => Int }) contestId: number, @Args('problemId', { type: () => Int, nullable: true }) problemId?: number ) { try { - return await this.announcementService.getAnnouncementsByProblemId( + return await this.announcementService.getAnnouncements( contestId, problemId ) @@ -47,10 +47,10 @@ export class AnnouncementResolver { } } - @Query(() => Announcement, { name: 'getAnnouncement' }) - async getAnnouncement(@Args('id', { type: () => Int }) id: number) { + @Query(() => Announcement, { name: 'getAnnouncementById' }) + async getAnnouncementById(@Args('id', { type: () => Int }) id: number) { try { - return await this.announcementService.getAnnouncement(id) + return await this.announcementService.getAnnouncementById(id) } catch (error) { if (error instanceof EntityNotExistException) { throw error.convert2HTTPException() diff --git a/backend/apps/admin/src/announcement/announcement.service.ts b/backend/apps/admin/src/announcement/announcement.service.ts index a025b47731..a473509c96 100644 --- a/backend/apps/admin/src/announcement/announcement.service.ts +++ b/backend/apps/admin/src/announcement/announcement.service.ts @@ -51,8 +51,7 @@ export class AnnouncementService { }) } - //getAnnouncements - async getAnnouncementsByProblemId(contestId: number, problemId?: number) { + async getAnnouncements(contestId: number, problemId?: number) { return await this.prisma.announcement.findMany({ where: { ...(problemId && { problemId }), @@ -61,8 +60,7 @@ export class AnnouncementService { }) } - //getAnnouncementById - async getAnnouncement(id: number) { + async getAnnouncementById(id: number) { const announcement = await this.prisma.announcement .findFirstOrThrow({ where: { diff --git a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru index 6e33c96803..940c743d1d 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru @@ -15,6 +15,7 @@ body:graphql { createAnnouncement( createAnnouncementInput: { problemId: -9999999 + contestId: -9999999 content: "this is new announcment!" } ) { diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index b6936ed4ba..52de5f4f64 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -15,6 +15,7 @@ body:graphql { createAnnouncement( createAnnouncementInput: { problemId: 1 + contestId: 1 content: "this is new announcement" } ) { diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index ef1f00c2f6..46a97f8b6a 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -17,6 +17,7 @@ body:graphql { ) { id problemId + contestId content } } diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index 09e4a51285..bcf89eacb8 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -13,10 +13,12 @@ post { body:graphql { query { getAnnouncementsByProblemId( + contestId: 1 problemId: 1 ) { id problemId + contestId content } } @@ -31,5 +33,6 @@ docs { ### Args | 이름 | 타입 | 설명| |--|--|--| - |problemId|int|Announment를 조회할 문제의 id| + |contestId|int|Announment를 조회할 contest의 id| + |problemId|int|Announment를 조회할 문제의 id (optional)| } diff --git a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru index 7528d2a55b..0bf9f6a19e 100644 --- a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru @@ -14,10 +14,7 @@ body:graphql { mutation { updateAnnouncement( id: -99999 - announcementInput: { - problemId: 2 - content: "updated announcement" - } + content: "updated announcement" ) { id problemId diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index 4b67c73af4..0d1c89eb24 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -14,10 +14,7 @@ body:graphql { mutation { updateAnnouncement( id: 1 - announcementInput: { - problemId: 2 - content: "updated announcement" - } + content: "updated announcement" ) { id problemId From dacd6cfb680fe5b1e7dc8960381c7abf95ef2cce Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 22 Feb 2024 06:50:28 +0000 Subject: [PATCH 17/23] feat: update announcement test code --- .../announcement/announcement.service.spec.ts | 25 +++++++++++-------- backend/apps/admin/src/problem/mock/mock.ts | 12 +++++++-- .../admin/src/problem/problem.resolver.ts | 6 ----- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/backend/apps/admin/src/announcement/announcement.service.spec.ts b/backend/apps/admin/src/announcement/announcement.service.spec.ts index 7ab0d52164..4806b7f3b6 100644 --- a/backend/apps/admin/src/announcement/announcement.service.spec.ts +++ b/backend/apps/admin/src/announcement/announcement.service.spec.ts @@ -24,7 +24,7 @@ const announcement = { id } -const problem = { +const contestProblem = { problemId } @@ -37,7 +37,7 @@ const db = { delete: stub(), create: stub().resolves(announcement) }, - problem: { + contestProblem: { findFirst: stub(), findFirstOrThrow: stub() } @@ -68,7 +68,7 @@ describe('AnnouncementService', () => { describe('createAnnouncement', () => { it('should return created announcement', async () => { db.announcement.findFirst.resolves(null) - db.problem.findFirstOrThrow.resolves(problem) + db.contestProblem.findFirstOrThrow.resolves(contestProblem) const res = await service.createAnnouncement(announcementInput) expect(res).to.deep.equal(announcement) @@ -84,7 +84,7 @@ describe('AnnouncementService', () => { it('should throw error when given problemId is invalid', async () => { db.announcement.findFirst.resolves(null) - db.problem.findFirstOrThrow.rejects(PrismaErrorInstance) + db.contestProblem.findFirstOrThrow.rejects(PrismaErrorInstance) await expect( service.createAnnouncement(announcementInput) @@ -92,24 +92,24 @@ describe('AnnouncementService', () => { }) }) - describe('getAnnouncementsByProblemId', () => { + describe('getAnnouncements', () => { it('should return all announcements', async () => { db.announcement.findMany() - const res = await service.getAnnouncementsByProblemId(problemId) + const res = await service.getAnnouncements(problemId) expect(res).to.deep.equal([announcement]) }) }) - describe('getAnnouncement', () => { + describe('getAnnouncementById', () => { it('should throw error when given id is invalid', async () => { db.announcement.findFirstOrThrow.rejects(PrismaErrorInstance) - await expect(service.getAnnouncement(id)).to.be.rejectedWith( + await expect(service.getAnnouncementById(id)).to.be.rejectedWith( EntityNotExistException ) }) it('should return an announcement', async () => { db.announcement.findFirstOrThrow.resolves(announcement) - const res = await service.getAnnouncement(id) + const res = await service.getAnnouncementById(id) expect(res).to.deep.equal(announcement) }) }) @@ -117,13 +117,16 @@ describe('AnnouncementService', () => { describe('updateAnnouncement', () => { it('should return updated announcement', async () => { db.announcement.update.resolves(announcement) - const res = await service.updateAnnouncement(id, announcementInput) + const res = await service.updateAnnouncement( + id, + announcementInput.content + ) expect(res).to.deep.equal(announcement) }) it('should throw error when given id is invalid', async () => { db.announcement.update.rejects(PrismaErrorInstance) await expect( - service.updateAnnouncement(id, announcementInput) + service.updateAnnouncement(id, announcementInput.content) ).to.be.rejectedWith(EntityNotExistException) }) }) diff --git a/backend/apps/admin/src/problem/mock/mock.ts b/backend/apps/admin/src/problem/mock/mock.ts index 5d0eb3f958..1eb1a9bb9b 100644 --- a/backend/apps/admin/src/problem/mock/mock.ts +++ b/backend/apps/admin/src/problem/mock/mock.ts @@ -1,7 +1,15 @@ +import { Language, Level } from '@generated' +import type { + Problem, + Workbook, + WorkbookProblem, + Contest, + ContestProblem, + ProblemTag, + Tag +} from '@generated' import { faker } from '@faker-js/faker' import { createReadStream } from 'fs' -import { Language, Level } from '@admin/@generated' -import type { Problem } from '@admin/@generated' import type { FileUploadDto } from '../dto/file-upload.dto' import type { UploadFileInput } from '../model/problem.input' import type { Template } from '../model/template.input' diff --git a/backend/apps/admin/src/problem/problem.resolver.ts b/backend/apps/admin/src/problem/problem.resolver.ts index c53e183dac..3f2dfa55e5 100644 --- a/backend/apps/admin/src/problem/problem.resolver.ts +++ b/backend/apps/admin/src/problem/problem.resolver.ts @@ -33,12 +33,6 @@ import { UnprocessableDataException } from '@libs/exception' import { CursorValidationPipe, GroupIDPipe, RequiredIntPipe } from '@libs/pipe' -import { - ContestProblem, - Problem, - Tag, - WorkbookProblem -} from '@admin/@generated' import { CreateProblemInput, UploadFileInput, From 961ac1d2dad060ff9c30c1af0f3f649ea50f6bbd Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 22 Feb 2024 07:09:42 +0000 Subject: [PATCH 18/23] docs: update bruno --- .../apps/admin/src/problem/problem.service.spec.ts | 7 ------- .../Announcement/Create Announcement/Succeed.bru | 11 ++++++----- .../Announcement/Delete Announcement/Succeed.bru | 6 +++--- .../Error: Invalid Announcement ID.bru | 3 ++- .../admin/Announcement/Get Announcement/Succeed.bru | 6 +++--- .../admin/Announcement/Get Announcements/Succeed.bru | 8 ++++---- .../Announcement/Update Announcement/Succeed.bru | 11 +++++++++++ 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/backend/apps/admin/src/problem/problem.service.spec.ts b/backend/apps/admin/src/problem/problem.service.spec.ts index 78e4b4d4b6..be230b88eb 100644 --- a/backend/apps/admin/src/problem/problem.service.spec.ts +++ b/backend/apps/admin/src/problem/problem.service.spec.ts @@ -8,13 +8,6 @@ import { UnprocessableDataException } from '@libs/exception' import { PrismaService } from '@libs/prisma' -import type { - Workbook, - WorkbookProblem, - Contest, - ContestProblem -} from '@admin/@generated' -import { Level } from '@admin/@generated' import { S3Provider } from '@admin/storage/s3.provider' import { StorageService } from '@admin/storage/storage.service' import { diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 52de5f4f64..33fcdd8d97 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -29,18 +29,19 @@ body:graphql { } docs { - ## Create Announcment - 새로운 Announement를 생성합니다. + ## Create Announcement + 새로운 Announcement를 생성합니다. ### Args | 이름 | 타입 | 설명| |--|--|--| - |problemId|int|Announment를 추가할 문제의 id| - |content|string|추가할 Announement의 내용| + |problemId|int(optional)|Announcement를 추가할 문제의 id| + |contestId|int|Announcement를 추가할 contest의 id| + |content|string|추가할 Announcement의 내용| ### Error Case #### CONFLICT - 추가하려는 것과 problemId, content가 모두 일치하는 Announement가 이미 존재 + 추가하려는 것과 problemId, content가 모두 일치하는 Announcement가 이미 존재 #### NOT_FOUND 존재하지 않는 problemId } diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 3f74ac22ae..8c4fcab7b3 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -23,13 +23,13 @@ body:graphql { } docs { - ## Delete Announcment - Announement를 제거합니다. + ## Delete Announcement + Announcement를 제거합니다. ### Args | 이름 | 타입 | 설명| |--|--|--| - |id|int|제거할 Annoucement id| + |id|int|제거할 Announcement id| ### Error Case #### NOT_FOUND diff --git a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru index aae74aada5..a934132213 100644 --- a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru @@ -12,11 +12,12 @@ post { body:graphql { query { - getAnnouncement( + getAnnouncementById( id: -99999 ) { id problemId + contestId content } } diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index 46a97f8b6a..7f42addbc2 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -12,7 +12,7 @@ post { body:graphql { query { - getAnnouncement( + getAnnouncementById( id: 1 ) { id @@ -25,13 +25,13 @@ body:graphql { } docs { - ## Get Announcment + ## Get Announcement Announcement의 정보를 조회합니다. ### Args | 이름 | 타입 | 설명| |--|--|--| - |id|int|조회할 Announment의 id| + |id|int|조회할 Announcement의 id| ### Error Case #### NOT_FOUND diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index bcf89eacb8..1556427413 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -12,7 +12,7 @@ post { body:graphql { query { - getAnnouncementsByProblemId( + getAnnouncements( contestId: 1 problemId: 1 ) { @@ -27,12 +27,12 @@ body:graphql { } docs { - ## Get Announcments + ## Get Announcements 해당 문제에 등록된 모든 Announcement를 조회합니다. ### Args | 이름 | 타입 | 설명| |--|--|--| - |contestId|int|Announment를 조회할 contest의 id| - |problemId|int|Announment를 조회할 문제의 id (optional)| + |contestId|int|Announcement를 조회할 contest의 id| + |problemId|int(optional)|Announcement를 조회할 문제의 id| } diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index 0d1c89eb24..dfe9819d9b 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -24,3 +24,14 @@ body:graphql { } + +docs { + ## Update Announcment + Announcement의 내용을 업데이트합니다. + + ### Args + | 이름 | 타입 | 설명| + |--|--|--| + |Id|int|Announcement의 id| + |content|string|수정할 Announcement의 내용| +} From 79a97dd23a795dd722414b58b9e1c19542bcb18e Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 29 Feb 2024 07:55:10 +0000 Subject: [PATCH 19/23] docs: bruno assert --- .../Create Announcement/Error: Duplicated Announcement.bru | 4 ++++ .../Create Announcement/Error: Invalid Problem ID.bru | 4 ++++ collection/admin/Announcement/Create Announcement/Succeed.bru | 4 ++++ .../Delete Announcement/Error: Invalid Announcement ID.bru | 4 ++++ collection/admin/Announcement/Delete Announcement/Succeed.bru | 4 ++++ .../Get Announcement/Error: Invalid Announcement ID.bru | 4 ++++ collection/admin/Announcement/Get Announcement/Succeed.bru | 4 ++++ collection/admin/Announcement/Get Announcements/Succeed.bru | 4 ++++ .../Update Announcement/Error: Invalid Announcement ID.bru | 4 ++++ collection/admin/Announcement/Update Announcement/Succeed.bru | 4 ++++ 10 files changed, 40 insertions(+) diff --git a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru index 15374403d7..ae315b3174 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru @@ -24,3 +24,7 @@ body:graphql { } } } + +assert { + res.body.errors: isDefined +} diff --git a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru index 940c743d1d..59edd30e56 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru @@ -27,3 +27,7 @@ body:graphql { } + +assert { + res.body.errors: isDefined +} diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 33fcdd8d97..9f25843130 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -28,6 +28,10 @@ body:graphql { } +assert { + res.body.data.createAnnouncement: isDefined +} + docs { ## Create Announcement 새로운 Announcement를 생성합니다. diff --git a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru index 7a6fad6cca..7bc5608911 100644 --- a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru @@ -21,3 +21,7 @@ body:graphql { } } } + +assert { + res.body.errors: isDefined +} diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 8c4fcab7b3..8003a05a84 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -22,6 +22,10 @@ body:graphql { } } +assert { + res.body.data.removeAnnouncement: isDefined +} + docs { ## Delete Announcement Announcement를 제거합니다. diff --git a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru index a934132213..1b329f8e47 100644 --- a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru @@ -23,3 +23,7 @@ body:graphql { } } + +assert { + res.body.errors: isDefined +} diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index 7f42addbc2..c72b1d7d6e 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -24,6 +24,10 @@ body:graphql { } +assert { + res.body.data.getAnnouncementById: isDefined +} + docs { ## Get Announcement Announcement의 정보를 조회합니다. diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index 1556427413..a7b4f78918 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -26,6 +26,10 @@ body:graphql { } +assert { + res.body.data.getAnnouncements: isDefined +} + docs { ## Get Announcements 해당 문제에 등록된 모든 Announcement를 조회합니다. diff --git a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru index 0bf9f6a19e..3e0caa5846 100644 --- a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru @@ -23,3 +23,7 @@ body:graphql { } } + +assert { + res.body.errors: isDefined +} diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index dfe9819d9b..922a138e05 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -25,6 +25,10 @@ body:graphql { } +assert { + res.body.data.updateAnnouncement: isDefined +} + docs { ## Update Announcment Announcement의 내용을 업데이트합니다. From 0c967476f4f3873b567c89727dc8c43605033b31 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Thu, 29 Feb 2024 08:40:42 +0000 Subject: [PATCH 20/23] docs: write bruno docs --- .../Error: Duplicated Announcement.bru | 14 +++++++++++--- .../Error: Invalid Problem ID.bru | 16 ++++++++++++---- .../Announcement/Create Announcement/Succeed.bru | 16 ++++++++++++---- .../Error: Invalid Announcement ID.bru | 10 ++++++++-- .../Announcement/Delete Announcement/Succeed.bru | 8 +++++++- .../Error: Invalid Announcement ID.bru | 10 ++++++++-- .../Announcement/Get Announcement/Succeed.bru | 8 +++++++- .../Announcement/Get Announcements/Succeed.bru | 13 ++++++++++--- .../Error: Invalid Announcement ID.bru | 13 ++++++++++--- .../Announcement/Update Announcement/Succeed.bru | 13 ++++++++++--- 10 files changed, 95 insertions(+), 26 deletions(-) diff --git a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru index ae315b3174..fa6a709218 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru @@ -14,8 +14,8 @@ body:graphql { mutation { createAnnouncement( createAnnouncementInput: { - problemId: 1 - content: "Announcement_1_0" + problemId: $problemId + content: $content } ) { id @@ -25,6 +25,14 @@ body:graphql { } } +body:graphql:vars { + { + "problemId": 1, + "contestId": 1, + "content": "this is new announcement" + } +} + assert { - res.body.errors: isDefined + res.body.errors: isDefined } diff --git a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru index 59edd30e56..96d26fdeee 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru @@ -14,9 +14,9 @@ body:graphql { mutation { createAnnouncement( createAnnouncementInput: { - problemId: -9999999 - contestId: -9999999 - content: "this is new announcment!" + problemId: $problemId + contestId: $contestId + content: $content } ) { id @@ -28,6 +28,14 @@ body:graphql { } +body:graphql:vars { + { + "problemId": -9999999, + "contestId": -9999999, + "content": "this is new announcement" + } +} + assert { - res.body.errors: isDefined + res.body.errors: isDefined } diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 9f25843130..948eb3b28d 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -14,9 +14,9 @@ body:graphql { mutation { createAnnouncement( createAnnouncementInput: { - problemId: 1 - contestId: 1 - content: "this is new announcement" + problemId: $problemId + contestId: $contestId + content: $content } ) { id @@ -28,8 +28,16 @@ body:graphql { } +body:graphql:vars { + { + "problemId": 1, + "contestId": 1, + "content": "this is new announcement" + } +} + assert { - res.body.data.createAnnouncement: isDefined + res.body.data.createAnnouncement: isDefined } docs { diff --git a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru index 7bc5608911..9e3011f90b 100644 --- a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru @@ -13,7 +13,7 @@ post { body:graphql { mutation { removeAnnouncement( - id: -9999999 + id: $id ) { id problemId @@ -22,6 +22,12 @@ body:graphql { } } +body:graphql:vars { + { + "id": -999999 + } +} + assert { - res.body.errors: isDefined + res.body.errors: isDefined } diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 8003a05a84..831109c536 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -13,7 +13,7 @@ post { body:graphql { mutation { removeAnnouncement( - id: 1 + id: $id ) { id problemId @@ -22,6 +22,12 @@ body:graphql { } } +body:graphql:vars { + { + "id": 1 + } +} + assert { res.body.data.removeAnnouncement: isDefined } diff --git a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru index 1b329f8e47..0813a47094 100644 --- a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru @@ -13,7 +13,7 @@ post { body:graphql { query { getAnnouncementById( - id: -99999 + id: $id ) { id problemId @@ -24,6 +24,12 @@ body:graphql { } +body:graphql:vars { + { + "id": -999999 + } +} + assert { - res.body.errors: isDefined + res.body.errors: isDefined } diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index c72b1d7d6e..f7562b3736 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -13,7 +13,7 @@ post { body:graphql { query { getAnnouncementById( - id: 1 + id: $id ) { id problemId @@ -24,6 +24,12 @@ body:graphql { } +body:graphql:vars { + { + "id": 1 + } +} + assert { res.body.data.getAnnouncementById: isDefined } diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index a7b4f78918..2151cd187f 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -13,8 +13,8 @@ post { body:graphql { query { getAnnouncements( - contestId: 1 - problemId: 1 + contestId: $contestId + problemId: $problemId ) { id problemId @@ -26,8 +26,15 @@ body:graphql { } +body:graphql:vars { + { + "problemId": 1, + "contestId": 1 + } +} + assert { - res.body.data.getAnnouncements: isDefined + res.body.data.getAnnouncements: isDefined } docs { diff --git a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru index 3e0caa5846..9075e647a0 100644 --- a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru @@ -13,8 +13,8 @@ post { body:graphql { mutation { updateAnnouncement( - id: -99999 - content: "updated announcement" + id: $id + content: $content ) { id problemId @@ -24,6 +24,13 @@ body:graphql { } +body:graphql:vars { + { + "id": -99999, + "content": "updated announcement" + } +} + assert { - res.body.errors: isDefined + res.body.errors: isDefined } diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index 922a138e05..58f401eafb 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -13,8 +13,8 @@ post { body:graphql { mutation { updateAnnouncement( - id: 1 - content: "updated announcement" + id: $id + content: $content ) { id problemId @@ -25,8 +25,15 @@ body:graphql { } +body:graphql:vars { + { + "id": 1, + "content": "updated announcement" + } +} + assert { - res.body.data.updateAnnouncement: isDefined + res.body.data.updateAnnouncement: isDefined } docs { From e9d485f1ae61bc3cb80975d6ed472dace5b755d9 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 1 Apr 2024 07:47:33 +0000 Subject: [PATCH 21/23] chore: remove unused dto --- .../apps/admin/src/announcement/dto/create-announcement.input.ts | 0 .../apps/admin/src/announcement/dto/update-announcement.input.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/backend/apps/admin/src/announcement/dto/create-announcement.input.ts delete mode 100644 apps/backend/apps/admin/src/announcement/dto/update-announcement.input.ts diff --git a/apps/backend/apps/admin/src/announcement/dto/create-announcement.input.ts b/apps/backend/apps/admin/src/announcement/dto/create-announcement.input.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/apps/backend/apps/admin/src/announcement/dto/update-announcement.input.ts b/apps/backend/apps/admin/src/announcement/dto/update-announcement.input.ts deleted file mode 100644 index e69de29bb2..0000000000 From 826f1291b5289cadb057c7ae27290c8dcb7391b3 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 1 Apr 2024 12:51:16 +0000 Subject: [PATCH 22/23] docs: update bruno docs --- .../apps/admin/src/announcement/dto/announcement.input.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/backend/apps/admin/src/announcement/dto/announcement.input.ts b/apps/backend/apps/admin/src/announcement/dto/announcement.input.ts index 650431212a..9ed50c9ff3 100644 --- a/apps/backend/apps/admin/src/announcement/dto/announcement.input.ts +++ b/apps/backend/apps/admin/src/announcement/dto/announcement.input.ts @@ -2,7 +2,7 @@ import { InputType, Int, Field } from '@nestjs/graphql' @InputType() export class AnnouncementInput { - @Field({ nullable: true }) + @Field(() => Int, { nullable: true }) problemId?: number @Field(() => Int) From 81c2f1733a68edcc7e323737700f3e405abe1558 Mon Sep 17 00:00:00 2001 From: Lee-won-hyeok Date: Mon, 29 Apr 2024 12:04:21 +0000 Subject: [PATCH 23/23] docs: update bruno docs --- .../Create Announcement/Error: Duplicated Announcement.bru | 2 +- .../Create Announcement/Error: Invalid Problem ID.bru | 2 +- collection/admin/Announcement/Create Announcement/Succeed.bru | 2 +- .../Delete Announcement/Error: Invalid Announcement ID.bru | 2 +- collection/admin/Announcement/Delete Announcement/Succeed.bru | 2 +- .../Get Announcement/Error: Invalid Announcement ID.bru | 2 +- collection/admin/Announcement/Get Announcement/Succeed.bru | 2 +- collection/admin/Announcement/Get Announcements/Succeed.bru | 2 +- .../Update Announcement/Error: Invalid Announcement ID.bru | 2 +- collection/admin/Announcement/Update Announcement/Succeed.bru | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru index fa6a709218..9b917e6463 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Duplicated Announcement.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($problemId: Int, $content: String!) { createAnnouncement( createAnnouncementInput: { problemId: $problemId diff --git a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru index 96d26fdeee..f30162a931 100644 --- a/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru +++ b/collection/admin/Announcement/Create Announcement/Error: Invalid Problem ID.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($problemId: Int, $contestId: Int!, $content: String!) { createAnnouncement( createAnnouncementInput: { problemId: $problemId diff --git a/collection/admin/Announcement/Create Announcement/Succeed.bru b/collection/admin/Announcement/Create Announcement/Succeed.bru index 948eb3b28d..fcb54fa064 100644 --- a/collection/admin/Announcement/Create Announcement/Succeed.bru +++ b/collection/admin/Announcement/Create Announcement/Succeed.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($problemId: Int, $contestId: Int!, $content: String!) { createAnnouncement( createAnnouncementInput: { problemId: $problemId diff --git a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru index 9e3011f90b..e962e89ef8 100644 --- a/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Delete Announcement/Error: Invalid Announcement ID.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($id: Int!) { removeAnnouncement( id: $id ) { diff --git a/collection/admin/Announcement/Delete Announcement/Succeed.bru b/collection/admin/Announcement/Delete Announcement/Succeed.bru index 831109c536..c15ebb727b 100644 --- a/collection/admin/Announcement/Delete Announcement/Succeed.bru +++ b/collection/admin/Announcement/Delete Announcement/Succeed.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($id: Int!) { removeAnnouncement( id: $id ) { diff --git a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru index 0813a47094..62252b00bc 100644 --- a/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Get Announcement/Error: Invalid Announcement ID.bru @@ -11,7 +11,7 @@ post { } body:graphql { - query { + query($id: Int!) { getAnnouncementById( id: $id ) { diff --git a/collection/admin/Announcement/Get Announcement/Succeed.bru b/collection/admin/Announcement/Get Announcement/Succeed.bru index f7562b3736..48b87b80e5 100644 --- a/collection/admin/Announcement/Get Announcement/Succeed.bru +++ b/collection/admin/Announcement/Get Announcement/Succeed.bru @@ -11,7 +11,7 @@ post { } body:graphql { - query { + query($id: Int!) { getAnnouncementById( id: $id ) { diff --git a/collection/admin/Announcement/Get Announcements/Succeed.bru b/collection/admin/Announcement/Get Announcements/Succeed.bru index 2151cd187f..bbedaac785 100644 --- a/collection/admin/Announcement/Get Announcements/Succeed.bru +++ b/collection/admin/Announcement/Get Announcements/Succeed.bru @@ -11,7 +11,7 @@ post { } body:graphql { - query { + query($contestId: Int!, $problemId: Int) { getAnnouncements( contestId: $contestId problemId: $problemId diff --git a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru index 9075e647a0..7dc21dccdb 100644 --- a/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru +++ b/collection/admin/Announcement/Update Announcement/Error: Invalid Announcement ID.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($id: Int!, $content: String!) { updateAnnouncement( id: $id content: $content diff --git a/collection/admin/Announcement/Update Announcement/Succeed.bru b/collection/admin/Announcement/Update Announcement/Succeed.bru index 58f401eafb..148011ea34 100644 --- a/collection/admin/Announcement/Update Announcement/Succeed.bru +++ b/collection/admin/Announcement/Update Announcement/Succeed.bru @@ -11,7 +11,7 @@ post { } body:graphql { - mutation { + mutation($id: Int!, $content: String!) { updateAnnouncement( id: $id content: $content