Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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
7 changes: 4 additions & 3 deletions __mocks__/fixtures/reward.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ export const reward = {
community: "community",
token: "token",
stable: false,
fiatCurrency: "USD",
amount: 10,
timestamp: 10,
distribution: {
first: 1,
second: 2,
third: 3
}
}
third: 3,
},
};
20 changes: 20 additions & 0 deletions __tests__/components/sections/challenges/Header.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ChallengeHeader from "@/components/sections/challenges/Header";
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import { challenge, submission } from "@__mocks__/fixtures/challenge";

describe("ChallengeHeader", () => {
it("should render the ChallengeHeader", () => {
renderWithRedux(<ChallengeHeader testId="challengeHeaderId" />);
const challengeheader = screen.getByTestId("challengeHeaderId");
expect(challengeheader).toBeInTheDocument();
});

it("should render the challenge header with section", () => {
renderWithRedux(<ChallengeHeader />, { challenges: { current: challenge, list: [challenge], loading: false, submission: submission } });
expect(screen.getByText("communities.challenge.title")).toBeInTheDocument();
expect(screen.getByText(challenge.name)).toBeInTheDocument();
expect(screen.getByText(challenge.description)).toBeInTheDocument();
});
});
44 changes: 44 additions & 0 deletions __tests__/components/sections/challenges/Learning.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Learning from "@/components/sections/challenges/Learning";
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import { challenge, submission } from "@__mocks__/fixtures/challenge";
import { mockCourse, mockLearningModule } from "@__mocks__/fixtures/course";
import { mockCommunity } from "@__mocks__/fixtures/community";

describe("Learning", () => {
it("should render Learning", () => {
renderWithRedux(<Learning testId="learningId" courses={[]} learningModules={[]} community={mockCommunity} />);
const learning = screen.getByTestId("learningId");
expect(learning).toBeInTheDocument();
expect(screen.getByText("communities.overview.challenge.learning.title")).toBeInTheDocument();
});

it("should render with courses", () => {
const coursesArray = [mockCourse];
renderWithRedux(<Learning courses={[mockCourse]} learningModules={[mockLearningModule]} community={mockCommunity} />, {
challenges: { current: challenge, list: [challenge], loading: false, submission: submission },
});
coursesArray.forEach((course) => {
const courseNameElement = screen.getByText(course.name);
const courseDescriptionElement = screen.getByText(course.description);
expect(courseNameElement).toBeInTheDocument();
expect(courseNameElement).toHaveTextContent(course.name);
expect(courseDescriptionElement).toBeInTheDocument();
expect(courseDescriptionElement).toHaveTextContent(course.description);
});
});

it("should render with learning", () => {
const learningArray = [mockLearningModule];
renderWithRedux(<Learning courses={[mockCourse]} learningModules={[mockLearningModule]} community={mockCommunity} />);
learningArray.forEach((learningModule) => {
const learningTitleElement = screen.getByText(learningModule.title);
const learningDescriptionElement = screen.getByText(learningModule.description);
expect(learningTitleElement).toBeInTheDocument();
expect(learningTitleElement).toHaveTextContent(learningModule.title);
expect(learningDescriptionElement).toBeInTheDocument();
expect(learningDescriptionElement).toHaveTextContent(learningModule.description);
});
});
});
49 changes: 49 additions & 0 deletions __tests__/components/sections/challenges/Objectives.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Objectives from "@/components/sections/challenges/Objectives";
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import DateManager from "@/utilities/DateManager";
import { challenge, submission } from "@__mocks__/fixtures/challenge";

describe("Objectives", () => {
const challenges = challenge;
const submissions = submission;
const mockObjectivesStates = { challenges: { current: challenges, list: [challenges], loading: false, submission: submissions } };
it("should render objectives", () => {
renderWithRedux(<Objectives testId="objectiveId" />);
expect(screen.getByTestId("objectiveId")).toBeInTheDocument();
expect(screen.getByText("communities.overview.challenge.objective.title")).toBeInTheDocument();
});

it("should render the objective list", () => {
renderWithRedux(<Objectives />, mockObjectivesStates);
const objectiveValue = challenge.objectives.find((objective) => objective);
expect(screen.getByText(objectiveValue || "objectives 1")).toBeInTheDocument();
});

it("should display expiry date", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it("should display expiry date", () => {
it("should display challenge expiry date, when applicable", () => {

renderWithRedux(<Objectives />, mockObjectivesStates);
const expirationDate = challenge.expiresAt && DateManager.format(challenge.expiresAt, "MMMM d, yyyy", "en");
if (expirationDate) {
const expirationDateElement = screen.getByText(expirationDate);
expect(expirationDateElement).toBeInTheDocument();
expect(expirationDateElement).toHaveTextContent(expirationDate);
}
});

it("should display challenge hint", () => {
renderWithRedux(<Objectives />, { challenges: { current: challenges, list: [challenges], loading: false, submission: submissions } });
const containsLink = new RegExp(/<a.*?>.*?<\/a>/g);
expect(containsLink.test('<a href="http://example.com">Example</a>')).toBe(true);
expect(containsLink.test("This is a test string without a link.")).toBe(false);
expect(containsLink.test('<a href="http://example.com">Example')).toBe(false);
expect(containsLink.test('<a href="http://example.com"><a>Nested</a></a>')).toBe(true);

expect(containsLink.test("<div>Not a link</div>")).toBe(false);
if (containsLink.test(challenge.hint as string)) {
expect(screen.getByText(challenge.hint as string)).toBeInTheDocument();
} else {
expect(screen.getByText(challenge.hint)).toBeInTheDocument();
}
});
});
50 changes: 50 additions & 0 deletions __tests__/components/sections/challenges/Rating.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import RubricRating from "@/components/sections/challenges/Rating";
import type { RubricRatingProps } from "@/components/sections/challenges/Rating";
import { mockCommunity } from "@__mocks__/fixtures/community";
import { mockCourse } from "@__mocks__/fixtures/course";
type MockRubricRating = Pick<RubricRatingProps, "rubricRating">;

const fixtureRubricRating: MockRubricRating = {
rubricRating: {
relevance: 2,
originality: 2,
quality: 8,
total: 12,
available: 2,
reward: 6,
rewardCoin: "ICP",
},
};
describe("RubricRating", () => {
const rubricRatings = fixtureRubricRating.rubricRating;
it("should render ratings with title", () => {
renderWithRedux(<RubricRating testId="rubricRatingId" hideTitle={false} />);
expect(screen.getByTestId("rubricRatingId")).toBeInTheDocument();
expect(screen.getByTestId("coin")).toBeInTheDocument();
expect(screen.getByText("communities.challenge.criteria.title")).toBeInTheDocument();
});

it("should render ratings with rating criterias", () => {
renderWithRedux(<RubricRating rubricRating={rubricRatings} />, {
community: { current: mockCommunity, list: [mockCommunity], courses: [mockCourse], status: "succeeded", error: "error message" },
});

mockCommunity.challenge?.ratingCriteria.forEach((criteria) => {
expect(screen.getByText(criteria.name)).toBeInTheDocument();
expect(screen.getByText(criteria.name).textContent).toBe("rating criteria");
criteria.rubric.forEach((rubric) => {
if (rubricRatings) {
if (rubricRatings[criteria.name] === rubric.points) {
expect(screen.getByText(rubric.points)).toBeInTheDocument();
expect(screen.getByText(rubric.points).textContent).toBe("90");
expect(screen.getByText(rubric.text)).toBeInTheDocument();
expect(screen.getByText(rubric.text).textContent).toBe("Challenge text");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, you should not use hardcoded values, it would be better if they are in a variable for readability of the code.

}
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize loop by replacing forEach with for...of.

Replacing forEach with for...of improves performance and readability.

- mockCommunity.challenge?.ratingCriteria.forEach((criteria) => {
+ for (const criteria of mockCommunity.challenge?.ratingCriteria || []) {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mockCommunity.challenge?.ratingCriteria.forEach((criteria) => {
expect(screen.getByText(criteria.name)).toBeInTheDocument();
expect(screen.getByText(criteria.name).textContent).toBe("rating criteria");
criteria.rubric.forEach((rubric) => {
if (rubricRatings) {
if (rubricRatings[criteria.name] === rubric.points) {
expect(screen.getByText(rubric.points)).toBeInTheDocument();
expect(screen.getByText(rubric.points).textContent).toBe("90");
expect(screen.getByText(rubric.text)).toBeInTheDocument();
expect(screen.getByText(rubric.text).textContent).toBe("Challenge text");
}
}
});
});
for (const criteria of mockCommunity.challenge?.ratingCriteria || []) {
expect(screen.getByText(criteria.name)).toBeInTheDocument();
expect(screen.getByText(criteria.name).textContent).toBe("rating criteria");
criteria.rubric.forEach((rubric) => {
if (rubricRatings) {
if (rubricRatings[criteria.name] === rubric.points) {
expect(screen.getByText(rubric.points)).toBeInTheDocument();
expect(screen.getByText(rubric.points).textContent).toBe("90");
expect(screen.getByText(rubric.text)).toBeInTheDocument();
expect(screen.getByText(rubric.text).textContent).toBe("Challenge text");
}
}
});
}

});
});
33 changes: 33 additions & 0 deletions __tests__/components/sections/challenges/Rewards.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { OverviewRewards } from "@/components/sections/challenges/Rewards";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import { challenge, submission } from "@__mocks__/fixtures/challenge";

jest.mock("next/router", () => ({
useRouter: () => ({
query: "query",
}),
}));

describe("Reward", () => {
it("should render a reward", () => {
renderWithRedux(<OverviewRewards testId="overviewRewardId" />);
expect(screen.getByTestId("overviewRewardId")).toBeInTheDocument();
});

it("should render reward with the challenge", () => {
renderWithRedux(<OverviewRewards testId="overviewRewardId" />, { challenges: { current: challenge, list: [challenge], loading: false, submission: submission } });
if (challenge.rewards) {
challenge.rewards.forEach((reward) => {
expect(screen.getByText(`${reward.amount} ${reward.token}`)).toBeInTheDocument();
expect(screen.getByText(`${reward.amount} ${reward.token}`).textContent).toBe("10 token");
});
}
if (challenge.isHackathon) {
const challengeCertificate = screen.getByText("communities.overview.challenge.participate");
expect(challengeCertificate).toBeInTheDocument();
expect(challengeCertificate.textContent).toContain(challenge.reward?.token || challenge?.rewards[0]?.token || "");
}
});
});
36 changes: 36 additions & 0 deletions __tests__/components/sections/challenges/Rubric.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import RubricHeader from "@/components/sections/challenges/Rubric";
import { challenge, submission } from "@__mocks__/fixtures/challenge";
import { mockRatingCriteria, Rubric } from "@__mocks__/fixtures/course";

describe("Rubric", () => {
it("should render the Rubric header", () => {
renderWithRedux(<RubricHeader testId="rubricId" ratingCriteria={[]} selected={[]} />);
expect(screen.getByTestId("rubricId")).toBeInTheDocument();
});

it("should render the Rubric with ratings", () => {
renderWithRedux(<RubricHeader ratingCriteria={[mockRatingCriteria]} selected={[Rubric]} />, {
challenges: { current: challenge, list: [challenge], loading: false, submission: submission },
});
const rubricHeaderName = screen.getByText(mockRatingCriteria.name);
expect(rubricHeaderName).toBeInTheDocument();

const selectedRubric = (id: string) => [Rubric].find((rubric) => rubric.id === id);

[mockRatingCriteria].forEach((criteria) => {
expect(screen.getByText(criteria.name)).toBeInTheDocument();
criteria.rubric.forEach((rubric) => {
if (selectedRubric(rubric.id)) {
const rubricPoints = selectedRubric(rubric.id)?.points;
expect(screen.getByText(rubricPoints || "id")).toBeInTheDocument();
} else {
expect(screen.getByText(rubric.points)).toBeInTheDocument();
}
expect(screen.getByText(rubric.text)).toBeInTheDocument();
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import SetupTeamChallenge from "@/components/sections/challenges/SetupTeamChallenge";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import { challenge, mockInvite, submission } from "@__mocks__/fixtures/challenge";

describe("SetUpTeamChallenge", () => {
const mockTeamChallengeStates = {
challenges: { current: challenge, list: [challenge], loading: false, submission: submission },
invites: { data: mockInvite },
};
it("renders without crashing", () => {
renderWithRedux(<SetupTeamChallenge testid="challengeId" />);
expect(screen.getByTestId("challengeId")).toBeInTheDocument();
});

it("renders content correctly", () => {
renderWithRedux(<SetupTeamChallenge />, mockTeamChallengeStates);
expect(screen.getByText("Submission")).toBeInTheDocument();
expect(screen.getByText("communities.overview.challenge.team.setup.info")).toBeInTheDocument();
expect(screen.getByText("Form your team")).toBeInTheDocument();
expect(screen.getByText(challenge?.additionalInfo?.TEAM_FORMATION.text || " ") || "communities.overview.challenge.team.organization").toBeInTheDocument();
});

it("renders CreateTeamCard when there is no invitation or comfirmTeamInvitation when there is invitation", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description is not clear enough

renderWithRedux(<SetupTeamChallenge />, mockTeamChallengeStates);
if (!mockInvite) {
expect(screen.getByText("communities.overview.challenge.team.setup.submit-title")).toBeInTheDocument();
expect(screen.getByText("communities.overview.challenge.team.setup.description")).toBeInTheDocument();
} else {
expect(screen.getByText("Submit your team")).toBeInTheDocument();
expect(screen.getByText(`The maximum team members for this challenge is ${challenge?.teamLimit} people`)).toBeInTheDocument();
}
});
});
49 changes: 49 additions & 0 deletions __tests__/components/sections/challenges/Submission.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import "@testing-library/jest-dom";
import { screen } from "@testing-library/react";
import Submission, { FormValues } from "@/components/sections/challenges/Submission";
import { renderWithRedux } from "../../../../__mocks__/renderWithRedux";
import { FieldErrors } from "react-hook-form";
import { challenge, mockTeam, submission } from "@__mocks__/fixtures/challenge";
import { mockUser } from "@__mocks__/fixtures/user";

describe("Submission", () => {
let errors: FieldErrors<FormValues>;
const canSubmit = () => {
if (!challenge?.isTeamChallenge) return true;
return Boolean(!!mockTeam?.organizer);
};
it("renders the submission section", async () => {
renderWithRedux(<Submission />, {
challenges: { current: challenge, list: [challenge], loading: false, submission: submission },
teams: { current: mockTeam, loading: true },
});
const submissionsClosed = challenge?.expiresAt ? Date.parse(challenge?.expiresAt) < Date.now() : false;
if (submissionsClosed) {
expect(screen.getByText("communities.overview.challenge.submissions-closed")).toBeInTheDocument();
} else if (challenge.isTeamChallenge) {
expect(screen.getByText("communities.overview.challenge.submission.description")).toBeInTheDocument();
}
});

it("validates submission form and displays necessary elements", () => {
renderWithRedux(<Submission testId="submission-form" />, {
challenges: { current: challenge, list: [challenge], loading: false, submission: submission },
teams: { current: mockTeam, loading: true },
});
if (!canSubmit()) {
expect(screen.getByText("communities.challenge.submission.hint")).toBeInTheDocument();
} else {
expect(screen.getByTestId("submission-form")).toBeInTheDocument();
if (challenge.format && mockUser && mockUser.avatar && challenge.format.githubLink && errors) {
expect(screen.getByText(mockTeam.organizer?.displayName || mockUser.displayName)).toBeInTheDocument();
expect(screen.getByText(errors.text?.message as string)).toBeInTheDocument();
expect(screen.getByText(errors.githubLink?.message as string)).toBeInTheDocument();
}
expect(screen.getByText("Markdown")).toBeInTheDocument();
if (challenge?.format.disclaimer) {
expect(screen.getByRole("checkbox")).toBeInTheDocument();
}
expect(screen.getByText("submit")).toBeInTheDocument();
}
});
});
Loading