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
101 changes: 72 additions & 29 deletions __tests__/components/leaderboard/LeaderboardCardsCollected.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { render, screen } from '@testing-library/react';
import LeaderboardCardsCollectedComponent from '@/components/leaderboard/LeaderboardCardsCollected';
import { Content, Collector } from '@/components/leaderboard/Leaderboard';
import { render, screen } from "@testing-library/react";
import LeaderboardCardsCollectedComponent from "@/components/leaderboard/LeaderboardCardsCollected";
import { Content, Collector } from "@/components/leaderboard/Leaderboard";

jest.mock('@/components/leaderboard/leaderboard_helpers', () => {
const original = jest.requireActual('../../../components/leaderboard/leaderboard_helpers');
jest.mock("@/components/leaderboard/leaderboard_helpers", () => {
const original = jest.requireActual(
"../../../components/leaderboard/leaderboard_helpers"
);
return {
...original,
useFetchLeaderboard: jest.fn(),
};
});

const useFetchLeaderboard = require('@/components/leaderboard/leaderboard_helpers').useFetchLeaderboard as jest.Mock;
const useFetchLeaderboard =
require("@/components/leaderboard/leaderboard_helpers")
.useFetchLeaderboard as jest.Mock;

const baseProps = {
block: 1,
Expand All @@ -25,7 +29,7 @@ const baseProps = {

function renderComponent(data: any, loading = false, globalChange?: number) {
useFetchLeaderboard.mockReturnValue({
myFetchUrl: '/api',
myFetchUrl: "/api",
totalResults: data ? data.length : 0,
leaderboard: data,
});
Expand All @@ -38,28 +42,30 @@ function renderComponent(data: any, loading = false, globalChange?: number) {
);
}

describe('LeaderboardCardsCollectedComponent', () => {
describe("LeaderboardCardsCollectedComponent", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders no content when leaderboard is undefined', () => {
it("renders no content when leaderboard is undefined", () => {
renderComponent(undefined, false);
expect(screen.queryByRole('table')).toBeNull();
expect(screen.queryByRole("table")).toBeNull();
});

it('shows message when no results and not loading', () => {
it("shows message when no results and not loading", () => {
renderComponent([], false);
expect(screen.getByText('No results found. Change filters and try again.')).toBeInTheDocument();
expect(
screen.getByText("No results found. Change filters and try again.")
).toBeInTheDocument();
});

it('renders leaderboard rows with calculated values', () => {
it("renders leaderboard rows with calculated values", () => {
const leaderboard = [
{
consolidation_key: '0x1',
handle: 'alice',
consolidation_display: 'Alice',
pfp_url: '',
consolidation_key: "0x1",
handle: "alice",
consolidation_display: "Alice",
pfp_url: "",
cic_type: undefined,
level: 2,
balance: 5,
Expand All @@ -71,10 +77,10 @@ describe('LeaderboardCardsCollectedComponent', () => {
total_tdh: 100,
},
{
consolidation_key: '0x2',
handle: 'bob',
consolidation_display: 'Bob',
pfp_url: '',
consolidation_key: "0x2",
handle: "bob",
consolidation_display: "Bob",
pfp_url: "",
cic_type: undefined,
level: 1,
balance: 1,
Expand All @@ -85,23 +91,60 @@ describe('LeaderboardCardsCollectedComponent', () => {
day_change: 0,
total_tdh: 50,
},
{
consolidation_key: "0x3",
handle: "carol",
consolidation_display: "Carol",
pfp_url: "",
cic_type: undefined,
level: 3,
balance: 468,
unique_memes: 468,
unique_memes_total: 469,
memes_cards_sets: 12,
boosted_tdh: 99,
day_change: 5,
total_tdh: 250,
},
{
consolidation_key: "0x4",
handle: "dave",
consolidation_display: "Dave",
pfp_url: "",
cic_type: undefined,
level: 4,
balance: 1999,
unique_memes: 1999,
unique_memes_total: 2000,
memes_cards_sets: 20,
boosted_tdh: 101,
day_change: 2,
total_tdh: 400,
},
];
renderComponent(leaderboard, false, 20);

const rows = screen.getAllByRole('row');
const rows = screen.getAllByRole("row");
// First row corresponds to table header, others to data
expect(rows).toHaveLength(3);
expect(rows).toHaveLength(5);

// check rank numbering
expect(rows[1]).toHaveTextContent('1');
expect(rows[2]).toHaveTextContent('2');
expect(rows[1]).toHaveTextContent("1");
expect(rows[2]).toHaveTextContent("2");
expect(rows[3]).toHaveTextContent("3");
expect(rows[4]).toHaveTextContent("4");

expect(rows[1]).toHaveTextContent(/3\s*\/\s*10\s*\(30%\)/);
expect(rows[2]).toHaveTextContent(/0\s*\/\s*5\s*\(0%\)/);
expect(rows[3]).toHaveTextContent(/468\s*\/\s*469\s*\(99\.8%\)/);
expect(rows[4]).toHaveTextContent(/1,999\s*\/\s*2,000\s*\(99\.9%\)/);

// tdh change with percentage and vs network
expect(rows[1]).toHaveTextContent('+10');
expect(rows[1]).toHaveTextContent('(10.00%)');
expect(rows[1]).toHaveTextContent('0.50x');
expect(rows[1]).toHaveTextContent("+10");
expect(rows[1]).toHaveTextContent("(10.00%)");
expect(rows[1]).toHaveTextContent("0.50x");

// second row with zero change shows dash and dash vs network
expect(rows[2]).toHaveTextContent('-');
expect(rows[2]).toHaveTextContent("-");
});
});
11 changes: 6 additions & 5 deletions components/leaderboard/LeaderboardCardsCollected.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { useState } from "react";
import { Col, Container, Row, Table } from "react-bootstrap";
import type { Collector, Content } from "./Leaderboard";
import styles from "./Leaderboard.module.scss";
import type {
LeaderboardMetrics} from "./leaderboard_helpers";
import type { LeaderboardMetrics } from "./leaderboard_helpers";
import {
formatPercentageFromCounts,
LeaderboardCardsCollectedSort,
useFetchLeaderboard,
} from "./leaderboard_helpers";
Expand Down Expand Up @@ -200,10 +200,11 @@ export default function LeaderboardCardsCollectedComponent(
? numberWithCommas(lead.unique_memes)
: 0}{" "}
/ {numberWithCommas(lead.unique_memes_total)} (
{Math.round(
(lead.unique_memes / lead.unique_memes_total) * 100
{formatPercentageFromCounts(
lead.unique_memes,
lead.unique_memes_total
)}
%)
)
</td>
<td className={styles["tdhSub"]}>
{numberWithCommas(lead.memes_cards_sets)}
Expand Down
17 changes: 17 additions & 0 deletions components/leaderboard/leaderboard_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ export interface LeaderboardInteractions {
cic_type?: CICType | undefined;
}

export function formatPercentageFromCounts(count: number, total: number) {
const safeCount = Number.isFinite(count) ? Math.max(0, count) : 0;
const safeTotal = Number.isFinite(total) ? Math.max(0, total) : 0;

if (safeTotal === 0 || safeCount === 0) {
return "0%";
}

if (safeCount >= safeTotal) {
return "100%";
}

const percent = (safeCount / safeTotal) * 100;
const rounded = Number(percent.toFixed(1));
return rounded < 100 ? `${rounded}%` : "99.9%";
}

export function getLeaderboardDownloadFileName(
title: string,
block: number,
Expand Down
Loading