Skip to content
Open
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
63 changes: 63 additions & 0 deletions js/src/__mock__/leaderboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ const currentMetadata = ApiURL.create("/api/leaderboard/current/metadata", {
method: "GET",
});

const currentLeaderboardUsers = ApiURL.create(
"/api/leaderboard/current/user/all",
{
method: "GET",
},
);

export const MOCK_LEADERBOARD_ID = uuid();
const metadataById = ApiURL.create(
"/api/leaderboard/{leaderboardId}/metadata",
Expand Down Expand Up @@ -107,3 +114,59 @@ export const catastrophicLeaderboardHandlers = [
return HttpResponse.error();
}),
];

export const currentLeaderboardUsersHandler = http.get(
currentLeaderboardUsers.url.toString(),
() => {
return HttpResponse.json({
success: true,
message: "Leaderboard users loaded!",
payload: {
hasNextPage: false,
pages: 1,
pageSize: 20,
items: [
{
index: 1,
id: "user-1",
discordId: "discord-1",
discordName: "aphrodite",
leetcodeUsername: "aphrodite",
nickname: null,
admin: false,
profileUrl: null,
tags: [],
achievements: [],
totalScore: 120,
},
{
index: 2,
id: "user-2",
discordId: "discord-2",
discordName: "poseidon",
leetcodeUsername: "poseidon",
nickname: null,
admin: false,
profileUrl: null,
tags: [],
achievements: [],
totalScore: 110,
},
{
index: 3,
id: "user-3",
discordId: "discord-3",
discordName: "hermes",
leetcodeUsername: "hermes",
nickname: null,
admin: false,
profileUrl: null,
tags: [],
achievements: [],
totalScore: 100,
},
],
},
} satisfies ReturnType<typeof currentLeaderboardUsers.res>);
},
);
80 changes: 80 additions & 0 deletions js/src/app/embed/leaderboard/_components/OrgEmbedView.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
currentLeaderboardUsersHandler,
failedLeaderboardHandlers,
successfulLeaderboardHandlers,
} from "@/__mock__/leaderboard";
import OrgEmbedView from "@/app/embed/leaderboard/_components/OrgEmbedView";
import { TestUtils, TestUtilTypes } from "@/lib/test";
import { screen, waitFor } from "@testing-library/react";
import { setupServer } from "msw/node";

describe("OrgEmbedView with date range", () => {
const server = setupServer(
currentLeaderboardUsersHandler,
...successfulLeaderboardHandlers,
);

beforeAll(() => server.listen());
afterEach(() => {
server.resetHandlers();
});
afterAll(() => server.close());

let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null;
beforeEach(() => {
renderProviderFn = TestUtils.getRenderWithAllProvidersFn();
});

it("should include startDate and endDate when metadata is available", async () => {
renderProviderFn?.(<OrgEmbedView />);

await waitFor(() => {
const aphrodite = screen.getByText("aphrodite");
expect(aphrodite).toBeInTheDocument();
});

const aphroditeLink = screen.getByText("aphrodite").closest("a");

expect(aphroditeLink).toBeInTheDocument();
expect(aphroditeLink).toHaveAttribute(
"href",
expect.stringContaining("/user/user-1/submissions?startDate="),
);
expect(aphroditeLink).toHaveAttribute(
"href",
expect.stringContaining("endDate="),
);
});
});

describe("OrgEmbedView without date range", () => {
const server = setupServer(
currentLeaderboardUsersHandler,
...failedLeaderboardHandlers,
);

beforeAll(() => server.listen());
afterEach(() => {
server.resetHandlers();
});
afterAll(() => server.close());

let renderProviderFn: TestUtilTypes.RenderWithAllProvidersFn | null = null;
beforeEach(() => {
renderProviderFn = TestUtils.getRenderWithAllProvidersFn();
});

it("should omit date range when metadata is unavailable", async () => {
renderProviderFn?.(<OrgEmbedView />);

await waitFor(() => {
const aphrodite = screen.getByText("aphrodite");
expect(aphrodite).toBeInTheDocument();
});

const aphroditeLink = screen.getByText("aphrodite").closest("a");

expect(aphroditeLink).toBeInTheDocument();
expect(aphroditeLink).toHaveAttribute("href", "/user/user-1/submissions");
});
});
45 changes: 32 additions & 13 deletions js/src/app/embed/leaderboard/_components/OrgEmbedView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import LeaderboardCard from "@/components/ui/LeaderboardCard";
import CustomPagination from "@/components/ui/table/CustomPagination";
import SearchBox from "@/components/ui/table/SearchBox";
import Toast from "@/components/ui/toast/Toast";
import { useCurrentLeaderboardUsersQuery } from "@/lib/api/queries/leaderboard";
import {
useCurrentLeaderboardMetadataQuery,
useCurrentLeaderboardUsersQuery,
} from "@/lib/api/queries/leaderboard";
import { formatLeaderboardDateRange } from "@/lib/helper/leaderboardDateRange";
import getOrdinal from "@/lib/helper/ordinal";
import { theme } from "@/lib/theme";
import {
Expand Down Expand Up @@ -45,6 +49,13 @@ export default function OrgLeaderboardEmbed() {
onFilterReset,
} = useCurrentLeaderboardUsersQuery({ pageSize });

const metadataQuery = useCurrentLeaderboardMetadataQuery();

const dateRange =
metadataQuery.data?.success ?
formatLeaderboardDateRange(metadataQuery.data.payload)
: undefined;

const activeFilter = useMemo(() => {
const active = Object.typedEntries(filters).filter(
([, enabled]) => enabled,
Expand Down Expand Up @@ -106,22 +117,28 @@ export default function OrgLeaderboardEmbed() {
mb="md"
>
{page === 1 && second && !debouncedQuery && (
<LeaderboardCard
placeString={getOrdinal(second.index)}
sizeOrder={2}
discordName={second.discordName}
leetcodeUsername={second.leetcodeUsername}
totalScore={second.totalScore}
nickname={second.nickname}
width={"200px"}
userId={second.id as string}
isLoading={isPlaceholderData}
embedded
/>
<Box>
<LeaderboardCard
placeString={getOrdinal(second.index)}
sizeOrder={2}
discordName={second.discordName}
startDate={dateRange?.startDate}
endDate={dateRange?.endDate}
leetcodeUsername={second.leetcodeUsername}
totalScore={second.totalScore}
nickname={second.nickname}
width={"200px"}
userId={second.id as string}
isLoading={isPlaceholderData}
embedded
/>
</Box>
)}
{page === 1 && first && !debouncedQuery && (
<LeaderboardCard
placeString={getOrdinal(first.index)}
startDate={dateRange?.startDate}
endDate={dateRange?.endDate}
sizeOrder={1}
discordName={first.discordName}
leetcodeUsername={first.leetcodeUsername}
Expand All @@ -141,6 +158,8 @@ export default function OrgLeaderboardEmbed() {
leetcodeUsername={third.leetcodeUsername}
totalScore={third.totalScore}
nickname={third.nickname}
startDate={dateRange?.startDate}
endDate={dateRange?.endDate}
width={"200px"}
userId={third.id as string}
isLoading={isPlaceholderData}
Expand Down
Loading