Skip to content

Commit

Permalink
chore(be): remove group from contest (#2354)
Browse files Browse the repository at this point in the history
* feat(be): modify contest and group schema

* feat(be): remove group from contest client code

* feat(be): remove group from contest admin code

* feat(be): remove group from contest announcement

* fix(be): fix typecheck conflict with main

* chore(be): fix typecheck conflict missed just before with main
  • Loading branch information
02hyeok authored Feb 14, 2025
1 parent a7e8f2e commit 17dcd35
Show file tree
Hide file tree
Showing 18 changed files with 140 additions and 300 deletions.
52 changes: 10 additions & 42 deletions apps/backend/apps/admin/src/contest/contest.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import { ParseBoolPipe } from '@nestjs/common'
import { Args, Context, Int, Mutation, Query, Resolver } from '@nestjs/graphql'
import { Contest, ContestProblem } from '@generated'
import { AuthenticatedRequest, UseRolesGuard } from '@libs/auth'
import { OPEN_SPACE_ID } from '@libs/constants'
import {
CursorValidationPipe,
GroupIDPipe,
IDValidationPipe,
RequiredIntPipe
} from '@libs/pipe'
Expand Down Expand Up @@ -33,16 +31,10 @@ export class ContestResolver {
new RequiredIntPipe('take')
)
take: number,
@Args(
'groupId',
{ defaultValue: OPEN_SPACE_ID, type: () => Int },
GroupIDPipe
)
groupId: number,
@Args('cursor', { nullable: true, type: () => Int }, CursorValidationPipe)
cursor: number | null
) {
return await this.contestService.getContests(take, groupId, cursor)
return await this.contestService.getContests(take, cursor)
}

@Query(() => ContestWithParticipants)
Expand All @@ -56,35 +48,25 @@ export class ContestResolver {
@Mutation(() => Contest)
async createContest(
@Args('input') input: CreateContestInput,
@Args(
'groupId',
{ defaultValue: OPEN_SPACE_ID, type: () => Int },
GroupIDPipe
)
groupId: number,
@Context('req') req: AuthenticatedRequest
) {
return await this.contestService.createContest(groupId, req.user.id, input)
return await this.contestService.createContest(req.user.id, input)
}

@Mutation(() => Contest)
async updateContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('input') input: UpdateContestInput
) {
return await this.contestService.updateContest(groupId, input)
async updateContest(@Args('input') input: UpdateContestInput) {
return await this.contestService.updateContest(input)
}

@Mutation(() => Contest)
async deleteContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int }) contestId: number
) {
return await this.contestService.deleteContest(groupId, contestId)
return await this.contestService.deleteContest(contestId)
}

/**
* Contest의 소속 Group을 Open Space(groupId === 1)로 이동시키기 위한 요청(Publicizing Requests)들을 불러옵니다.
* Contest를 공개(Open Space)로 이동시키기 위한 요청(Publicizing Requests)들을 불러옵니다.
* @returns Publicizing Request 배열
*/
@Query(() => [PublicizingRequest])
Expand All @@ -94,24 +76,19 @@ export class ContestResolver {
}

/**
* Contest의 소속 Group을 Open Space(groupId === 1)로 이동시키기 위한 요청(Publicizing Request)를 생성합니다.
* @param groupId Contest가 속한 Group의 ID. 이미 Open Space(groupId === 1)이 아니어야 합니다.
* Contest를 공개(Open Space)로 이동시키기 위한 요청(Publicizing Request)을 생성합니다.
* @param contestId Contest의 ID
* @returns 생성된 Publicizing Request
*/
@Mutation(() => PublicizingRequest)
async createPublicizingRequest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int }) contestId: number
) {
return await this.contestService.createPublicizingRequest(
groupId,
contestId
)
return await this.contestService.createPublicizingRequest(contestId)
}

/**
* Contest의 소속 Group을 Open Space(groupId === 1)로 이동시키기 위한 요청(Publicizing Request)을 처리합니다.
* Contest를 공개(Open Space)로 이동시키기 위한 요청(Publicizing Request)을 처리합니다.
* @param contestId Publicizing Request를 생성한 contest의 Id
* @param isAccepted 요청 수락 여부
* @returns
Expand All @@ -130,27 +107,23 @@ export class ContestResolver {

@Mutation(() => [ContestProblem])
async importProblemsToContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int }) contestId: number,
@Args('problemIdsWithScore', { type: () => [ProblemScoreInput] })
problemIdsWithScore: ProblemScoreInput[]
) {
return await this.contestService.importProblemsToContest(
groupId,
contestId,
problemIdsWithScore
)
}

@Mutation(() => [ContestProblem])
async removeProblemsFromContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int })
contestId: number,
@Args('problemIds', { type: () => [Int] }) problemIds: number[]
) {
return await this.contestService.removeProblemsFromContest(
groupId,
contestId,
problemIds
)
Expand Down Expand Up @@ -188,16 +161,11 @@ export class ContestResolver {

@Mutation(() => DuplicatedContestResponse)
async duplicateContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int })
contestId: number,
@Context('req') req: AuthenticatedRequest
) {
return await this.contestService.duplicateContest(
groupId,
contestId,
req.user.id
)
return await this.contestService.duplicateContest(contestId, req.user.id)
}

/**
Expand Down
52 changes: 11 additions & 41 deletions apps/backend/apps/admin/src/contest/contest.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager'
import { Test, type TestingModule } from '@nestjs/testing'
import { ContestProblem, Group, ContestRecord } from '@generated'
import { ContestProblem, ContestRecord } from '@generated'
import { Problem } from '@generated'
import { Contest } from '@generated'
import { faker } from '@faker-js/faker'
Expand All @@ -20,7 +20,6 @@ import type { PublicizingRequest } from './model/publicizing-request.model'

const contestId = 1
const userId = 1
const groupId = 1
const problemId = 2
const startTime = faker.date.past()
const endTime = faker.date.future()
Expand All @@ -36,7 +35,6 @@ const problemIdsWithScore = {
const contest: Contest = {
id: contestId,
createdById: userId,
groupId,
title: 'title',
description: 'description',
penalty: 20,
Expand All @@ -63,7 +61,6 @@ const contest: Contest = {
const contestWithCount = {
id: contestId,
createdById: userId,
groupId,
title: 'title',
description: 'description',
penalty: 20,
Expand Down Expand Up @@ -93,7 +90,6 @@ const contestWithCount = {
const contestWithParticipants: ContestWithParticipants = {
id: contestId,
createdById: userId,
groupId,
title: 'title',
description: 'description',
penalty: 20,
Expand All @@ -118,20 +114,6 @@ const contestWithParticipants: ContestWithParticipants = {
benefits: 'benefits'
}

const group: Group = {
id: groupId,
groupName: 'groupName',
description: 'description',
config: {
showOnList: true,
allowJoinFromSearch: true,
allowJoinWithURL: false,
requireApprovalBeforeJoin: true
},
createTime: faker.date.past(),
updateTime: faker.date.past()
}

const problem: Problem = {
id: problemId,
createdById: 2,
Expand Down Expand Up @@ -257,9 +239,6 @@ const db = {
updateMany: stub().resolves([Problem]),
findFirstOrThrow: stub().resolves(Problem)
},
group: {
findUnique: stub().resolves(Group)
},
submission: {
findMany: stub().resolves([submissionsWithProblemTitleAndUsername])
},
Expand Down Expand Up @@ -310,7 +289,7 @@ describe('ContestService', () => {
it('should return an array of contests', async () => {
db.contest.findMany.resolves([contestWithCount])

const res = await service.getContests(5, 2, 0)
const res = await service.getContests(5, 0)
expect(res).to.deep.equal([contestWithParticipants])
})
})
Expand All @@ -328,9 +307,8 @@ describe('ContestService', () => {
describe('createContest', () => {
it('should return created contest', async () => {
db.contest.create.resolves(contest)
db.group.findUnique.resolves(group)

const res = await service.createContest(groupId, userId, input)
const res = await service.createContest(userId, input)
expect(res).to.deep.equal(contest)
})
})
Expand All @@ -340,28 +318,22 @@ describe('ContestService', () => {
db.contest.findFirst.resolves(contest)
db.contest.update.resolves(contest)

const res = await service.updateContest(groupId, updateInput)
const res = await service.updateContest(updateInput)
expect(res).to.deep.equal(contest)
})

it('should throw error when groupId or contestId not exist', async () => {
expect(service.updateContest(1000, updateInput)).to.be.rejectedWith(
EntityNotExistException
)
})
})

describe('deleteContest', () => {
it('should return deleted contest', async () => {
db.contest.findFirst.resolves(contest)
db.contest.delete.resolves(contest)

const res = await service.deleteContest(groupId, contestId)
const res = await service.deleteContest(contestId)
expect(res).to.deep.equal(contest)
})

it('should throw error when groupId or contestId not exist', async () => {
expect(service.deleteContest(1000, 1000)).to.be.rejectedWith(
it('should throw error when contestId not exist', async () => {
expect(service.deleteContest(1000)).to.be.rejectedWith(
EntityNotExistException
)
})
Expand All @@ -381,7 +353,7 @@ describe('ContestService', () => {
})
})

it('should throw error when groupId or contestId not exist', async () => {
it('should throw error when contestId not exist', async () => {
expect(service.handlePublicizingRequest(1000, true)).to.be.rejectedWith(
EntityNotExistException
)
Expand All @@ -407,9 +379,7 @@ describe('ContestService', () => {
db.contestProblem.findFirst.resolves(null)

const res = await Promise.all(
await service.importProblemsToContest(groupId, contestId, [
problemIdsWithScore
])
await service.importProblemsToContest(contestId, [problemIdsWithScore])
)

expect(res).to.deep.equal([contestProblem])
Expand All @@ -420,7 +390,7 @@ describe('ContestService', () => {
db.problem.update.resolves(problem)
db.contestProblem.findFirst.resolves(ContestProblem)

const res = await service.importProblemsToContest(groupId, contestId, [
const res = await service.importProblemsToContest(contestId, [
problemIdsWithScore
])

Expand All @@ -429,7 +399,7 @@ describe('ContestService', () => {

it('should throw error when the contestId not exist', async () => {
expect(
service.importProblemsToContest(groupId, 9999, [problemIdsWithScore])
service.importProblemsToContest(9999, [problemIdsWithScore])
).to.be.rejectedWith(EntityNotExistException)
})
})
Expand Down
Loading

0 comments on commit 17dcd35

Please sign in to comment.