Skip to content

Commit

Permalink
feat(platforms): adding isDeprecated option to providers, reject veri…
Browse files Browse the repository at this point in the history
…fication (#3087)

* feat(platforms): adding isDeprecated option to providers, reject verification

* feat(app): hiding deprecated credentials

* chore: fixed existing tests

* chore: adding tests

* feat: refactored provider filtering, added tests

* chore: changed local export path

* cleanup

* feat: adding 1 comment for an exported var

---------

Co-authored-by: Gerald Iakobinyi-Pich <[email protected]>
  • Loading branch information
lucianHymer and nutrina authored Dec 4, 2024
1 parent 07c2110 commit b18d319
Show file tree
Hide file tree
Showing 11 changed files with 419 additions and 45 deletions.
151 changes: 151 additions & 0 deletions app/__tests__/components/CardList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { PlatformCard } from "../../components/PlatformCard";
import { PlatformScoreSpec, ScorerContextState } from "../../context/scorerContext";
import { DEFAULT_CUSTOMIZATION, useCustomization } from "../../hooks/useCustomization";
import { platforms } from "@gitcoin/passport-platforms";
import { PLATFORM_ID } from "@gitcoin/passport-types";
import { usePlatforms } from "../../hooks/usePlatforms";

vi.mock("@didtools/cacao", () => ({
Cacao: {
Expand All @@ -29,6 +31,14 @@ vi.mock("next/router", () => ({

vi.mock("../../hooks/useCustomization");

vi.mock("../../hooks/usePlatforms", async (importActual) => {
const actual = (await importActual()) as any;
return {
...actual,
usePlatforms: vi.fn().mockImplementation(actual.usePlatforms),
};
});

const mockCeramicContext: CeramicContextState = makeTestCeramicContext();

let cardListProps: CardListProps = {};
Expand Down Expand Up @@ -203,6 +213,147 @@ test("renders Category component", () => {
});

describe("show/hide tests", () => {
beforeEach(async () => {
const actualUsePlatforms = await vi.importActual("../../hooks/usePlatforms");
vi.mocked(usePlatforms).mockImplementation((actualUsePlatforms as any).usePlatforms);
});

it("should hide platform when all providers are deprecated and no points earned", () => {
vi.mocked(useCustomization).mockReturnValue({} as any);

// Mock a platform with all deprecated providers
const mockPlatforms = new Map();
mockPlatforms.set("TestPlatform", {
platFormGroupSpec: [
{
providers: [{ isDeprecated: true }, { isDeprecated: true }],
},
],
});

vi.mocked(usePlatforms).mockReturnValue({
platformProviderIds: {},
platforms: mockPlatforms,
platformCatagories: [],
} as any);

const scorerContext: Partial<ScorerContextState> = {
scoredPlatforms: [
{
possiblePoints: 10,
earnedPoints: 0,
platform: "TestPlatform" as PLATFORM_ID,
name: "Test Platform",
description: "Test Description",
connectMessage: "Connect",
},
],
};

renderWithContext(mockCeramicContext, <CardList {...cardListProps} />, {}, scorerContext);

// Platform should be hidden
expect(screen.queryByText("Test Platform")).not.toBeInTheDocument();
});

it("should show platform when all providers are deprecated but points were earned", () => {
vi.mocked(useCustomization).mockReturnValue({} as any);

// Mock a platform with all deprecated providers
const mockPlatforms = new Map();
mockPlatforms.set("TestPlatform", {
platFormGroupSpec: [
{
providers: [{ isDeprecated: true }, { isDeprecated: true }],
},
],
});

vi.mocked(usePlatforms).mockReturnValue({
platformProviderIds: {},
platforms: mockPlatforms,
platformCatagories: [
{
name: "Test Category",
description: "Test Description",
platforms: ["TestPlatform"],
},
],
} as any);

const scorerContext: Partial<ScorerContextState> = {
scoredPlatforms: [
{
possiblePoints: 10,
earnedPoints: 5,
platform: "TestPlatform" as PLATFORM_ID,
name: "Test Platform",
description: "Test Description",
connectMessage: "Connect",
},
],
};

renderWithContext(mockCeramicContext, <CardList {...cardListProps} />, {}, scorerContext);

// Platform should be visible because points were earned
expect(screen.getByText("Test Platform")).toBeInTheDocument();
});

it("should show platform when some providers are not deprecated", () => {
vi.mocked(useCustomization).mockReturnValue({} as any);

// Mock a platform with mixed deprecated and active providers
const mockPlatforms = new Map();
mockPlatforms.set("NFT", {
platFormGroupSpec: [
{
providers: [
{
name: "NFTScore#50",
isDeprecated: true,
},
{
name: "NFTScore#75",
isDeprecated: false,
},
],
},
],
});

// Mock the usePlatforms hook
vi.mocked(usePlatforms).mockReturnValue({
platformProviderIds: { NFT: ["NFTScore#50", "NFTScore#75"] },
platforms: mockPlatforms,
platformCatagories: [
{
name: "Bla",
description: "Test Description",
platforms: ["NFT"],
},
],
platformSpecs: { NFT: { platform: "NFT", name: "NFT", description: "NFT", connectMessage: "NFT" } },
} as any);

const scorerContext: Partial<ScorerContextState> = {
scoredPlatforms: [
{
possiblePoints: 10,
earnedPoints: 0,
platform: "NFT" as PLATFORM_ID,
name: "NFT",
description: "NFT",
connectMessage: "Connect",
},
],
};

renderWithContext(mockCeramicContext, <CardList {...cardListProps} />, {}, scorerContext);

// Platform should be visible because not all providers are deprecated
expect(screen.getByTestId("platform-name")).toHaveTextContent("NFT");
});
it("should show allow list stamp if user has points", () => {
vi.mocked(useCustomization).mockReturnValue({
partnerName: "TestPartner",
Expand Down
118 changes: 113 additions & 5 deletions app/__tests__/components/StampSelector.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { vi, describe, it, expect, Mock } from "vitest";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, screen } from "@testing-library/react";
import { screen } from "@testing-library/react";
import { PROVIDER_ID } from "@gitcoin/passport-types";
import { useCustomization } from "../../hooks/useCustomization";
import { platforms } from "@gitcoin/passport-platforms";
Expand All @@ -20,7 +19,7 @@ describe("<StampSelector />", () => {
});

describe("exclusion tests", () => {
const renderTestComponent = (customization: any) => {
const renderTestComponent = (customization: any, stampScores = {}) => {
(useCustomization as Mock).mockReturnValue(customization);
renderWithContext(
testCeramicContext,
Expand All @@ -30,7 +29,19 @@ describe("<StampSelector />", () => {
selectedProviders={[] as PROVIDER_ID[]}
verifiedProviders={[] as PROVIDER_ID[]}
setSelectedProviders={() => {}}
/>
/>,
undefined,
{
stampScores: {
SelfStakingBronze: "1",
SelfStakingSilver: "1",
SelfStakingGold: "1",
BeginnerCommunityStaker: "1",
ExperiencedCommunityStaker: "1",
TrustedCitizen: "1",
...stampScores,
},
}
);
};

Expand Down Expand Up @@ -81,8 +92,105 @@ describe("<StampSelector />", () => {
},
},
});
expect(screen.queryByTestId("checkbox-SelfStakingBronze")).not.toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingBronze")).not.toBeInTheDocument();
expect(screen.queryByText("Self GTC Staking")).not.toBeInTheDocument();
});

it("should hide deprecated stamps with zero score", () => {
const customization = {
useCustomDashboard: true,
dashboardPanel: {},
scorer: {
weights: {
SelfStakingBronze: "1",
SelfStakingSilver: "1",
},
},
};

// Mock a deprecated provider
const originalProviders = GtcStaking.ProviderConfig[0].providers;
GtcStaking.ProviderConfig[0].providers = [
{ ...originalProviders[0], isDeprecated: true, name: "SelfStakingBronze" },
{ ...originalProviders[1], isDeprecated: false, name: "SelfStakingSilver" },
];

renderTestComponent(customization, {
SelfStakingBronze: "0",
SelfStakingSilver: "1",
});

// The group header should be present
expect(screen.queryByText("Self GTC Staking")).toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingBronze")).not.toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingSilver")).toBeInTheDocument();

// Restore original providers
GtcStaking.ProviderConfig[0].providers = originalProviders;
});

it("should hide group when all stamps are deprecated with zero scores", () => {
const customization = {
useCustomDashboard: true,
dashboardPanel: {},
scorer: {
weights: {
SelfStakingBronze: "1",
SelfStakingSilver: "1",
},
},
};

// Mock all providers in a group as deprecated
const originalProviders = GtcStaking.ProviderConfig[0].providers;
GtcStaking.ProviderConfig[0].providers = [
{ ...originalProviders[0], isDeprecated: true, name: "SelfStakingBronze" },
{ ...originalProviders[1], isDeprecated: true, name: "SelfStakingSilver" },
];

renderTestComponent(customization, {
SelfStakingBronze: "0",
SelfStakingSilver: "0",
});

// The group header should not be present
expect(screen.queryByText("Self GTC Staking")).not.toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingBronze")).not.toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingSilver")).not.toBeInTheDocument();

// Restore original providers
GtcStaking.ProviderConfig[0].providers = originalProviders;
});

it("should show deprecated stamps with non-zero score", () => {
const customization = {
useCustomDashboard: true,
dashboardPanel: {},
scorer: {
weights: {
SelfStakingBronze: "1",
SelfStakingSilver: "1",
},
},
};

// Mock a deprecated provider
const originalProviders = GtcStaking.ProviderConfig[0].providers;
GtcStaking.ProviderConfig[0].providers = [
{ ...originalProviders[0], isDeprecated: true, name: "SelfStakingBronze" },
{ ...originalProviders[1], isDeprecated: false, name: "SelfStakingSilver" },
];

renderTestComponent(customization, {
SelfStakingBronze: "1",
SelfStakingSilver: "1",
});

expect(screen.queryByTestId("indicator-SelfStakingBronze")).toBeInTheDocument();
expect(screen.queryByTestId("indicator-SelfStakingSilver")).toBeInTheDocument();

// Restore original providers
GtcStaking.ProviderConfig[0].providers = originalProviders;
});

it("include platform if customization doesn't specify custom weights", () => {
Expand Down
19 changes: 15 additions & 4 deletions app/components/CardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type SelectedProviders = Record<PLATFORM_ID, PROVIDER_ID[]>;

const useShouldDisplayPlatform = () => {
const customization = useCustomization();
const { platformProviderIds } = usePlatforms();
const { platformProviderIds, platforms } = usePlatforms();

const shouldDisplayPlatform = useCallback(
(platform: PlatformScoreSpec): boolean => {
Expand All @@ -33,6 +33,17 @@ const useShouldDisplayPlatform = () => {
return false;
}

const platformGroupSpec = platforms.get(platform.platform)?.platFormGroupSpec;

const allProvidersDeprecated = platformGroupSpec?.every((group) =>
group.providers.every((provider) => provider.isDeprecated)
);

// Hide if all providers are deprecated for this platform and no points were earned
if (platform.earnedPoints <= 0 && allProvidersDeprecated) {
return false;
}

// Hide allow list if no points were earned when onboarding
if (platform.platform.startsWith("AllowList") && platform.earnedPoints === 0) {
return false;
Expand Down Expand Up @@ -70,10 +81,10 @@ const useShouldDisplayPlatform = () => {
};

export const CardList = ({ className, isLoading = false, initialOpen = true }: CardListProps): JSX.Element => {
const { allProvidersState, allPlatforms } = useContext(CeramicContext);
const { allProvidersState } = useContext(CeramicContext);
const { scoredPlatforms } = useContext(ScorerContext);
const { platformProviderIds, platforms, platformCatagories } = usePlatforms();
const { isOpen, onOpen, onClose } = useDisclosure();
const { isOpen, onClose } = useDisclosure();
const [currentPlatform, setCurrentPlatform] = useState<PlatformScoreSpec | undefined>();
const { shouldDisplayPlatform } = useShouldDisplayPlatform();

Expand Down Expand Up @@ -129,7 +140,7 @@ export const CardList = ({ className, isLoading = false, initialOpen = true }: C
});
});

const platformProps = currentPlatform?.platform && allPlatforms.get(currentPlatform.platform);
const platformProps = currentPlatform?.platform && platforms.get(currentPlatform.platform);

return (
<>
Expand Down
Loading

0 comments on commit b18d319

Please sign in to comment.