Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/competition/competition.controller.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { GetCompetitionResponseDto } from "./dto/response/getCompetition.respons
import { GetCompetitionListResponseDto } from "./dto/response/getCompetitionList.response.dto";
import { GetNonVoterListResponseDto } from "./dto/response/getNonVoterList.response.dto";
import { GetRecentCompetitionsResponseDto } from "./dto/response/getRecentCompetitions.response.dto";
import { GetVotingPrefectureResponseDto } from "./dto/response/getVotingPrefecture.response.dto";
import { GetVotePerResponseDto } from "./dto/response/getVotePer.response.dto";
import { PatchCompetitionResponseDto } from "./dto/response/patchCompetition.response.dto";
import { PostAwardsResponseDto } from "./dto/response/postAwards.response.dto";
import { PostCompetitionResponseDto } from "./dto/response/postCompetition.response.dto";
Expand All @@ -24,10 +24,12 @@ export interface ICompetitionController {
getCompetitionList(page: string): Promise<Res<GetCompetitionListResponseDto>>;
getRecentCompetitions(): Promise<Res<GetRecentCompetitionsResponseDto>>;
getCompetition(id: string): Promise<Res<GetCompetitionResponseDto>>;
getVotingPrefecture(id: string): Promise<Res<GetVotingPrefectureResponseDto>>;
getNonVoterList(
request: GetNonVoterListRequestDto,
): Promise<Res<GetNonVoterListResponseDto>>;
getVotePer(
id: string
): Promise<Res<GetVotePerResponseDto>>;
patchCompetition(
id: string,
request: PatchCompetitionRequestDto,
Expand Down
25 changes: 17 additions & 8 deletions src/competition/competition.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Get,
Inject,
Logger,
NotFoundException,
Param,
ParseUUIDPipe,
Patch,
Expand All @@ -22,12 +23,12 @@ import { GetCompetitionResponseDto } from "./dto/response/getCompetition.respons
import { GetCompetitionListResponseDto } from "./dto/response/getCompetitionList.response.dto";
import { GetNonVoterListResponseDto } from "./dto/response/getNonVoterList.response.dto";
import { GetRecentCompetitionsResponseDto } from "./dto/response/getRecentCompetitions.response.dto";
import { GetVotingPrefectureResponseDto } from "./dto/response/getVotingPrefecture.response.dto";
import { PatchCompetitionResponseDto } from "./dto/response/patchCompetition.response.dto";
import { PostAwardsResponseDto } from "./dto/response/postAwards.response.dto";
import { PostCompetitionResponseDto } from "./dto/response/postCompetition.response.dto";
import { CompetitionService } from "./competition.service";
import { DeleteCompetitionResponseDto } from "./dto/response/deleteCompetition.response.dto";
import { GetVotePerResponseDto } from "./dto/response/getVotePer.response.dto";

@Controller("competition")
export class CompetitionController implements ICompetitionController {
Expand Down Expand Up @@ -91,13 +92,6 @@ export class CompetitionController implements ICompetitionController {
};
}

@Get("per/:id")
async getVotingPrefecture(
@Param("id") id: string,
): Promise<Res<GetVotingPrefectureResponseDto>> {
throw new Error("Method not implemented.");
}

@Get("list")
async getNonVoterList(
@Query() request: GetNonVoterListRequestDto,
Expand All @@ -111,6 +105,21 @@ export class CompetitionController implements ICompetitionController {
};
}

@Get("per/:id")
async getVotePer(
@Param("id") id: string,
): Promise<Res<GetVotePerResponseDto>> {
if (!id) throw new BadRequestException();

const data = await this.service.getVotePer(id);

return {
data,
statusCode: 200,
statusMsg: "",
};
}

@Get(":page")
async getCompetitionList(
@Param("page") page: string,
Expand Down
8 changes: 3 additions & 5 deletions src/competition/competition.service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GetCompetitionResponseDto } from "./dto/response/getCompetition.respons
import { GetCompetitionListResponseDto } from "./dto/response/getCompetitionList.response.dto";
import { GetNonVoterListResponseDto } from "./dto/response/getNonVoterList.response.dto";
import { GetRecentCompetitionsResponseDto } from "./dto/response/getRecentCompetitions.response.dto";
import { GetVotingPrefectureResponseDto } from "./dto/response/getVotingPrefecture.response.dto";
import { GetVotePerResponseDto } from "./dto/response/getVotePer.response.dto";
import { PatchCompetitionResponseDto } from "./dto/response/patchCompetition.response.dto";
import { PostAwardsResponseDto } from "./dto/response/postAwards.response.dto";
import { PostCompetitionResponseDto } from "./dto/response/postCompetition.response.dto";
Expand All @@ -23,15 +23,13 @@ export interface ICompetitionService {
getCompetitionList(page: string): Promise<GetCompetitionListResponseDto>;
getRecentCompetitions(): Promise<GetRecentCompetitionsResponseDto>;
getCompetition(id: string): Promise<GetCompetitionResponseDto>;
getVotingPrefecture(id: string): Promise<GetVotingPrefectureResponseDto>;
getNonVoterList(
request: GetNonVoterListRequestDto,
): Promise<GetNonVoterListResponseDto>;
getVotePer(id: string): Promise<GetVotePerResponseDto>;
patchCompetition(
id: string,
request: PatchCompetitionRequestDto,
): Promise<PatchCompetitionResponseDto>;
deleteCompetition(
id: string,
): Promise<DeleteCompetitionResponseDto>;
deleteCompetition(id: string): Promise<DeleteCompetitionResponseDto>;
}
33 changes: 28 additions & 5 deletions src/competition/competition.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import {
List,
} from "./dto/response/getNonVoterList.response.dto";
import { GetRecentCompetitionsResponseDto } from "./dto/response/getRecentCompetitions.response.dto";
import { GetVotingPrefectureResponseDto } from "./dto/response/getVotingPrefecture.response.dto";
import { PatchCompetitionResponseDto } from "./dto/response/patchCompetition.response.dto";
import { PostAwardsResponseDto } from "./dto/response/postAwards.response.dto";
import { PostCompetitionResponseDto } from "./dto/response/postCompetition.response.dto";
import { PrismaService } from "../prisma/prisma.service";
import { DeleteCompetitionResponseDto } from "./dto/response/deleteCompetition.response.dto";
import { GetVotePerResponseDto } from "./dto/response/getVotePer.response.dto";

@Injectable()
export class CompetitionService implements ICompetitionService {
Expand Down Expand Up @@ -128,10 +128,33 @@ export class CompetitionService implements ICompetitionService {
};
}

async getVotingPrefecture(
id: string,
): Promise<GetVotingPrefectureResponseDto> {
throw new Error("Method not implemented.");
async getVotePer(id: string): Promise<GetVotePerResponseDto> {
const competition = await this.prisma.findCompetitionById(id);
if (!competition) {
throw new NotFoundException();
}

const voteStats = await this.prisma.findCountVoterPer(id);
const studentStats = voteStats?.filter(
(stat) => stat.user_role === "Student",
)[0] ?? { user_role: "Student", total_count: 1, voted_count: 0 };
const teacherStats = voteStats?.filter(
(stat) => stat.user_role === "Teacher",
)[0] ?? { user_role: "Teacher", total_count: 1, voted_count: 0 };

const student =
studentStats.total_count === 0
? 0
: studentStats.voted_count / studentStats.total_count;
const teacher =
teacherStats.total_count === 0
? 0
: teacherStats.voted_count / teacherStats.total_count;

return {
student,
teacher,
};
}

async getNonVoterList(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { IsNumber } from "class-validator";

export class GetVotingPrefectureResponseDto {
export class GetVotePerResponseDto {
@IsNumber()
student: number;

@IsNumber()
teacher: number;
}
}
43 changes: 37 additions & 6 deletions src/competition/test/competition.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CompetitionController } from "../competition.controller";
import { JwtService } from "@nestjs/jwt";
import { PrismaService } from "../../prisma/prisma.service";
import { CompetitionService } from "../competition.service";
import { BadRequestException, Logger } from "@nestjs/common";
import { BadRequestException, Logger, NotFoundException } from "@nestjs/common";
import { PostCompetitionRequestDto } from "../dto/request/postCompetition.request.dto";
import { PostAwardsRequestDto } from "../dto/request/postAwards.request.dto";
import { COMPETITION_STATUS } from "../../prisma/client";
Expand Down Expand Up @@ -87,6 +87,12 @@ describe("CompetitionController", () => {
],
};
}),
getVotePer: jest.fn(() => {
return {
student: 26,
teacher: 3,
};
}),
patchCompetition: jest.fn(() => {
return {
id: "1",
Expand All @@ -110,11 +116,7 @@ describe("CompetitionController", () => {

controller = module.get<CompetitionController>(CompetitionController);

serviceMock.postCompetition.mockClear();
serviceMock.postAwards.mockClear();
serviceMock.getCompetitionList.mockClear();
serviceMock.getCompetition.mockClear();
serviceMock.getNonVoterList.mockClear();
jest.clearAllMocks();
});

describe("PostCompetition", () => {
Expand Down Expand Up @@ -317,6 +319,35 @@ describe("CompetitionController", () => {
});
});

describe("GetVotePer", () => {
const id = "b6ee2cd2-4596-47ee-b332-de87e1p39e80";

it("[200]", async () => {
const res = await controller.getVotePer(id);

expect(serviceMock.getVotePer).toHaveBeenCalledTimes(1);
expect(serviceMock.getVotePer).toHaveBeenCalledWith(id);
expect(res).toEqual({
data: {
student: 26,
teacher: 3,
},
statusCode: 200,
statusMsg: "",
});
});

it("[400] empty id", async () => {
const id = undefined;

await expect(async () => await controller.getVotePer(id)).rejects.toThrow(
new BadRequestException(),
);
expect(serviceMock.getVotePer).toHaveBeenCalledTimes(0);
expect(serviceMock.getCompetition).toHaveBeenCalledTimes(0);
});
});

describe("PatchCompetition", () => {
const id = "1";
const request: PatchCompetitionRequestDto = {
Expand Down
108 changes: 107 additions & 1 deletion src/competition/test/competition.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,36 @@ describe("CompetitionService", () => {

return nonVoter;
}),
findCountVoterPer: jest.fn(async (id: string) => {
const allStudents = Object.values(foreignUserDatabase).filter(
(user) => user.userRole == "Student",
);
const voteStudents = allStudents.map((user) =>
Object.values(voteDatabase).filter((e) => e.userId == user.userId),
);
const allTeachers = Object.values(foreignUserDatabase).filter(
(user) => user.userRole == "Teacher",
);
const voteTeachers = allTeachers.map((user) =>
Object.values(voteDatabase).filter((e) => (e.userId = user.userId)),
);

console.log(allStudents, voteStudents)
console.log(allTeachers, voteTeachers)

return [
{
user_role: "Student",
total_count: allStudents.length,
voted_count: voteStudents.length,
},
{
user_role: "Teacher",
total_count: allTeachers.length,
voted_count: voteTeachers.length,
},
];
}),
patchCompetition: jest.fn(
async (
id: string,
Expand Down Expand Up @@ -503,7 +533,9 @@ describe("CompetitionService", () => {

const res = await service.getRecentCompetitions();

expect(prismaMock.findManyCompetitionPendingAward).toHaveBeenCalledTimes(1);
expect(prismaMock.findManyCompetitionPendingAward).toHaveBeenCalledTimes(
1,
);
expect(prismaMock.findManyCompetitionPendingAward).toHaveBeenCalledWith();
expect(res).toEqual({
list: [
Expand Down Expand Up @@ -610,6 +642,80 @@ describe("CompetitionService", () => {
});
});

// describe("GetVotePer", () => {
// const id = "1";

// it("[200]", async () => {
// foreignUserDatabase = {
// "95d1e209-0337-40f4-a852-3c16f3a9a2df": {
// userId: "95d1e209-0337-40f4-a852-3c16f3a9a2df",
// userName: "청도서",
// userRole: "Teacher",
// userStringId: "r0adwest",
// userStudentNumber: null,
// },
// "95d1e209-0337-40f4-a842-3c16f3a9a2df": {
// userId: "95d1e209-0337-40f4-a842-3c16f3a9a2df",
// userName: "청희도",
// userRole: "Teacher",
// userStringId: "ziio",
// userStudentNumber: null,
// },
// "5fe187b2-cf86-4bda-b1f8-d638f2c53324": {
// userId: "5fe187b2-cf86-4bda-b1f8-d638f2c53324",
// userName: "홍길동",
// userRole: "Student",
// userStringId: "hongi1d0ng",
// userStudentNumber: 2345,
// },
// "5fe187b2-ctfx-4bda-b1f8-d638f2c53324": {
// userId: "5fe187b2-ctfx-4bda-b1f8-d638f2c53324",
// userName: "홍이삭",
// userRole: "Student",
// userStringId: "binding0f1ssac",
// userStudentNumber: 2468,
// },
// };

// voteDatabase = {
// "1": {
// userId: "95d1e209-0337-40f4-a852-3c16f3a9a2df",
// contestId: "1",
// projectId: "1",
// },
// "2": {
// userId: "5fe187b2-cf86-4bda-b1f8-d638f2c53324",
// contestId: "1",
// projectId: "4",
// },
// };

// competitionDatabase = {
// "1": {
// id: "1",
// name: "competition-test",
// startDate: new Date("2024-10-10"),
// endDate: new Date("2024-10-20"),
// purpose: "TESTING",
// audience: "members",
// place: "Github",
// status: COMPETITION_STATUS.IN_PROGRESS,
// },
// };

// const res = await service.getVotePer(id);

// expect(prismaMock.findCompetitionById).toHaveBeenCalledTimes(1);
// expect(prismaMock.findCompetitionById).toHaveBeenCalledWith(id);
// expect(prismaMock.findCountVoterPer).toHaveBeenCalledTimes(1);
// expect(prismaMock.findCountVoterPer).toHaveBeenCalledWith(id);
// expect(res).toEqual({
// student: 0.5,
// teacher: 0.5,
// });
// });
// });

describe("PatchCompetition", () => {
const id = "0";
const request: PatchCompetitionRequestDto = {};
Expand Down
3 changes: 0 additions & 3 deletions src/guard/adminValidator/adminValidator.guard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ describe("AdminValidatorGuard", () => {
};
const userPrismaMock = {
findUserByStrId: (userId: string) => {
console.log(userId, "findUserByStrId");
return true;
},
findUserById: (id: string) => {
console.log(id, "findUserById");
return true;
},
findUserByNumber: (number?: number) => {
console.log(number, "findUserByNumber");
return true;
},
};
Expand Down
Loading