Skip to content

Commit 06a413e

Browse files
Merge pull request #1267 from dacadeorg/test/best-submission
Test: add test for BestSubmmission and Evaluation components
2 parents d3c774f + a0490d9 commit 06a413e

File tree

7 files changed

+185
-46
lines changed

7 files changed

+185
-46
lines changed

__mocks__/fixtures/challenge.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { mockFormat, mockCertificateData, mockCourse, mockLearningModule, mockRatingCriteria } from "./course";
22
import { mockCommunity, mockMetadata } from "./community";
33
import { reward } from "./reward";
4-
import { Submission } from "@/types/bounty";
4+
import { Evaluation, Submission } from "@/types/bounty";
55
import { AdditionalInfo, Challenge } from "@/types/course";
6-
import { TEAM_FORMATION } from "@/constants/challengeInfo";
6+
import { GRADING_CRITERIA, TEAM_FORMATION } from "@/constants/challengeInfo";
77
import { Team, TeamMember } from "@/types/challenge";
88
import { Feedback } from "@/types/feedback";
99
import { mockUser } from "./user";
@@ -51,6 +51,22 @@ export const challenge: Challenge = {
5151
type: "teamFormation",
5252
text: "Form your team details here",
5353
},
54+
[GRADING_CRITERIA]: { type: "teamFormation", text: "Sample grading criteria text" },
55+
},
56+
};
57+
export const evaluation: Evaluation = {
58+
evaluator: mockUser,
59+
created_at: new Date("2022-05-01T12:00:00Z"),
60+
comment: "comment",
61+
criteria: [],
62+
metadata: {
63+
language: "language",
64+
},
65+
points: 10,
66+
totalPoints: 1,
67+
reward: {
68+
amount: 10,
69+
token: "token",
5470
},
5571
};
5672

@@ -89,6 +105,7 @@ export const submission: Submission = {
89105
totalPoints: 10,
90106
},
91107
},
108+
evaluation: evaluation,
92109
timestamp: 0,
93110
user: mockUser,
94111
reviewable: false,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import "@testing-library/jest-dom";
2+
import { screen } from "@testing-library/react";
3+
import { challenge, submission } from "@__mocks__/fixtures/challenge";
4+
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
5+
import BestSubmissions from "@/components/sections/submissions/BestSubmissions";
6+
7+
jest.mock("next/router", () => ({
8+
useRouter: () => ({
9+
asPath: "next",
10+
query: { challenge_id: "test-challenge-id", slug: "test-community-slug" },
11+
pathname: "/communities/test-community-slug/challenges/test-challenge-id",
12+
}),
13+
}));
14+
15+
const mockBestSubmissions = {
16+
challenges: {
17+
current: {
18+
...challenge,
19+
bestSubmissions: [submission],
20+
},
21+
list: [challenge],
22+
submission: submission,
23+
loading: true,
24+
},
25+
};
26+
27+
describe("BestSubmissions Component", () => {
28+
it("Should render best submissions when they exist", () => {
29+
renderWithRedux(<BestSubmissions testId="bestSubmissionId" />, mockBestSubmissions);
30+
const bestSubmission = screen.getByTestId("bestSubmissionId");
31+
expect(bestSubmission).toBeInTheDocument();
32+
mockBestSubmissions.challenges.current.bestSubmissions.forEach((submission) => {
33+
expect(screen.getByText(submission.text)).toBeInTheDocument();
34+
});
35+
});
36+
37+
it("Should render the link to submissions path", () => {
38+
renderWithRedux(<BestSubmissions testId="bestSubmissionId" />, mockBestSubmissions);
39+
const link = screen.getByRole("link", { name: /challenge.best-submissions.button/i });
40+
expect(link).toHaveAttribute("href", "/communities/test-community-slug/challenges/test-challenge-id/submissions");
41+
});
42+
});
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Evaluations from "@/components/sections/submissions/Evaluation";
2+
import { challenge, submission } from "@__mocks__/fixtures/challenge";
3+
import { colors } from "@__mocks__/fixtures/colors";
4+
import { renderWithRedux } from "@__mocks__/renderWithRedux";
5+
import "@testing-library/jest-dom";
6+
import { screen } from "@testing-library/react";
7+
8+
jest.mock("next/router", () => ({
9+
useRouter: () => ({
10+
asPath: "next",
11+
}),
12+
}));
13+
14+
const mockEvaluationState = {
15+
ui: { colors: colors, locked: false, showReferralPopup: false, showJobOffersPopup: false },
16+
submissions: {
17+
current: {
18+
...submission,
19+
},
20+
list: [submission],
21+
text: "",
22+
},
23+
challenges: { current: challenge, list: [challenge], submission: submission, loading: false },
24+
};
25+
26+
describe("Evaluations", () => {
27+
it("Should render evaluations", () => {
28+
renderWithRedux(<Evaluations />, mockEvaluationState);
29+
const evaluations = screen.getByTestId("evaluationsId");
30+
expect(evaluations).toBeInTheDocument();
31+
});
32+
33+
it("Should render RatingRubric when the challenge is present", () => {
34+
renderWithRedux(<Evaluations />, mockEvaluationState);
35+
const ratingCriteriaName = challenge.ratingCriteria[0].name;
36+
const ratingRubric = screen.getByText(ratingCriteriaName);
37+
expect(ratingRubric).toBeInTheDocument();
38+
});
39+
40+
it("Should conditionally render reward information when evaluation reward is present and the challenge is not a hackathon", () => {
41+
const nonHackathonState = {
42+
...mockEvaluationState,
43+
challenges: {
44+
...mockEvaluationState.challenges,
45+
current: { ...challenge, isHackathon: false },
46+
},
47+
};
48+
49+
renderWithRedux(<Evaluations />, nonHackathonState);
50+
const token = submission.evaluation?.reward?.token;
51+
if (token) {
52+
expect(screen.getByText(token)).toBeInTheDocument();
53+
}
54+
});
55+
56+
it("Should conditionally render reward information when evaluation.reward is present and challenge is a hackathon", () => {
57+
const hackathonState = {
58+
...mockEvaluationState,
59+
challenges: {
60+
...mockEvaluationState.challenges,
61+
current: { ...challenge, isHackathon: true },
62+
},
63+
};
64+
65+
renderWithRedux(<Evaluations />, hackathonState);
66+
expect(screen.getByText("USD")).toBeInTheDocument();
67+
expect(screen.getByText("communities.challenge.evaluation.message.nominated")).toBeInTheDocument();
68+
});
69+
});

src/components/sections/submissions/BestSubmissions.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ import ArrowButton from "@/components/ui/button/Arrow";
99
import { useSelector } from "@/hooks/useTypedSelector";
1010
import Accordion from "@/components/ui/accordion/Accordion";
1111

12+
interface BestSubmissionsProps {
13+
testId?: string;
14+
}
15+
1216
/**
1317
* BestSubmissions Component
1418
* @date 4/25/2023 - 2:21:45 PM
1519
*
1620
* @export
1721
* @returns {ReactElement}
1822
*/
19-
export default function BestSubmissions(): ReactElement {
23+
export default function BestSubmissions({ testId }: BestSubmissionsProps): ReactElement {
2024
const { t } = useTranslation();
2125
const router = useRouter();
2226
const navigation = new CommunityNavigation(router);
@@ -29,7 +33,7 @@ export default function BestSubmissions(): ReactElement {
2933
subtitle=""
3034
isExpanded
3135
content={
32-
<div>
36+
<div data-testid={testId}>
3337
<p className="leading-normal text-sm capitalize md:w-full w-64 pt-6">{t("communities.challenge.best-submissions.description")}</p>
3438
<div className="text-xl md:text-.5xl px-0">
3539
<div className="md:grid grid-cols-2 gap-5 pt-6 flex-wrap">

src/components/sections/submissions/Evaluation.tsx

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { Colors } from "@/types/community";
99
import { Challenge } from "@/types/course";
1010
import { IRootState } from "@/store";
1111

12+
interface EvaluationsProps {
13+
testId?: string;
14+
}
15+
1216
/**
1317
* interface for Evaluations multiSelector
1418
* @date 9/13/2023 - 9:21:32 AM
@@ -29,7 +33,7 @@ interface EvaluationsMultiSelector {
2933
* @export
3034
* @returns {ReactElement}
3135
*/
32-
export default function Evaluations(): ReactElement {
36+
export default function Evaluations({testId = "evaluationsId" }: EvaluationsProps): ReactElement {
3337
const { t } = useTranslation();
3438
const { colors, submission, challenge } = useMultiSelector<unknown, EvaluationsMultiSelector>({
3539
colors: (state: IRootState) => state.ui.colors,
@@ -39,45 +43,47 @@ export default function Evaluations(): ReactElement {
3943
const evaluation = submission?.evaluation as Evaluation;
4044

4145
return (
42-
<EvaluationCard evaluation={evaluation}>
43-
<>
44-
{challenge && <RatingRubric hideTitle ratingCriteria={challenge.ratingCriteria} selected={evaluation.criteria} />}
45-
<div className="grid grid-cols-1 mt-3 space-y-4 md:space-y-0 md:grid-cols-2 lg:grid-cols-4 gap-y-5 gap-x-5">
46-
<div className="text-sm">
47-
<span className="block font-medium">{t("communities.challenge.evaluation.total")}</span>
48-
<span className="text-xl" style={{ color: colors?.textAccent }}>
49-
{evaluation.points}
50-
</span>
51-
<span style={{ color: colors?.textAccent }}>
52-
/{evaluation.totalPoints}
53-
{t("communities.challenge.evaluation.points")}
54-
</span>
55-
</div>
56-
{evaluation.reward && (
57-
<div className="relative text-sm">
58-
{challenge?.isHackathon ? (
59-
<>
60-
<div>{t("communities.challenge.evaluation.message.nominated", { threshold: challenge.threshold })}</div>
61-
<div className="inline-block font-medium" style={{ color: colors?.textAccent }}>
62-
<span className="text-xl">{evaluation.reward.amount}</span> USD
63-
</div>
64-
</>
65-
) : (
66-
<>
67-
<span className="block font-medium">{t("communities.challenge.evaluation.total")}</span>
68-
<div className="absolute -left-5 top-7">
69-
<Coin token={evaluation.reward.token} size="small" />
70-
</div>
71-
<div className="inline-block font-medium" style={{ color: colors?.textAccent }}>
72-
<span className="text-xl">{evaluation.reward.amount}</span> <span>{evaluation.reward.token}</span>
73-
</div>
74-
<div>{t("communities.challenge.evaluation.message")}</div>
75-
</>
76-
)}
46+
<div data-testid={testId}>
47+
<EvaluationCard evaluation={evaluation}>
48+
<>
49+
{challenge && <RatingRubric hideTitle ratingCriteria={challenge.ratingCriteria} selected={evaluation?.criteria} />}
50+
<div className="grid grid-cols-1 mt-3 space-y-4 md:space-y-0 md:grid-cols-2 lg:grid-cols-4 gap-y-5 gap-x-5">
51+
<div className="text-sm">
52+
<span className="block font-medium">{t("communities.challenge.evaluation.total")}</span>
53+
<span className="text-xl" style={{ color: colors?.textAccent }}>
54+
{evaluation?.points}
55+
</span>
56+
<span style={{ color: colors?.textAccent }}>
57+
/{evaluation?.totalPoints}
58+
{t("communities.challenge.evaluation.points")}
59+
</span>
7760
</div>
78-
)}
79-
</div>
80-
</>
81-
</EvaluationCard>
61+
{evaluation?.reward && (
62+
<div className="relative text-sm">
63+
{challenge?.isHackathon ? (
64+
<>
65+
<div>{t("communities.challenge.evaluation.message.nominated", { threshold: challenge.threshold })}</div>
66+
<div className="inline-block font-medium" style={{ color: colors?.textAccent }}>
67+
<span className="text-xl">{evaluation.reward.amount}</span> USD
68+
</div>
69+
</>
70+
) : (
71+
<>
72+
<span className="block font-medium">{t("communities.challenge.evaluation.total")}</span>
73+
<div className="absolute -left-5 top-7">
74+
<Coin token={evaluation.reward.token} size="small" />
75+
</div>
76+
<div className="inline-block font-medium" style={{ color: colors?.textAccent }}>
77+
<span className="text-xl">{evaluation.reward.amount}</span> <span>{evaluation.reward.token}</span>
78+
</div>
79+
<div>{t("communities.challenge.evaluation.message")}</div>
80+
</>
81+
)}
82+
</div>
83+
)}
84+
</div>
85+
</>
86+
</EvaluationCard>
87+
</div>
8288
);
8389
}

src/types/course.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type Course = {
2323
learningModules: LearningModule[];
2424
challenge?: Challenge;
2525
challenges?: Challenge[];
26-
translations: any[];
26+
translations?: any[];
2727
trailer: Trailer;
2828
disclaimer: string;
2929
items?: string[];

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"incremental": true,
1717
"paths": {
1818
"@/*": ["./src/*"],
19-
"react": ["./node_modules/@types/react"]
19+
"react": ["./node_modules/@types/react"],
20+
"@__mocks__/*": ["./__mocks__/*"]
2021
}
2122
},
2223
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "src/components/sections/learning-modules/_partials/MarkDown.jsx", "jest.config.js"],

0 commit comments

Comments
 (0)