diff --git a/app/__tests__/components/GenericPlatform.test.tsx b/app/__tests__/components/GenericPlatform.test.tsx index 633073e2c..a23af9c01 100644 --- a/app/__tests__/components/GenericPlatform.test.tsx +++ b/app/__tests__/components/GenericPlatform.test.tsx @@ -7,11 +7,7 @@ const { Ens } = platforms; import { CeramicContextState } from "../../context/ceramicContext"; import { mockAddress } from "../../__test-fixtures__/onboardHookValues"; -import { - UN_SUCCESSFUL_ENS_RESULT, - SUCCESFUL_ENS_RESULTS, - credential, -} from "../../__test-fixtures__/verifiableCredentialResults"; +import { UN_SUCCESSFUL_ENS_RESULT, SUCCESFUL_ENS_RESULTS } from "../../__test-fixtures__/verifiableCredentialResults"; import { fetchVerifiableCredential } from "@gitcoin/passport-identity"; import { makeTestCeramicContext, renderWithContext } from "../../__test-fixtures__/contextTestHelpers"; import { JsonRpcSigner } from "@ethersproject/providers"; @@ -158,7 +154,7 @@ describe("when user has previously verified with EnsProvider", () => { beforeEach(async () => { await closeAllToasts(); (fetchVerifiableCredential as jest.Mock).mockResolvedValue({ - credentials: [SUCCESFUL_ENS_RESULTS], + credentials: [UN_SUCCESSFUL_ENS_RESULT], }); }); @@ -193,15 +189,58 @@ describe("when user has previously verified with EnsProvider", () => { const initialVerifyButton = screen.queryByTestId("button-verify-Ens"); fireEvent.click(initialVerifyButton as HTMLElement); + // Wait to see the done toast + await waitFor(() => { + // Empty b/c don't qualify for any stamps but also don't want to delete any stamps + expect(handlePatchStampsMock).toHaveBeenCalledWith([]); + + expect(screen.getByText("Successfully re-verified Ens data point.")).toBeInTheDocument(); + expect(fetchVerifiableCredential).toHaveBeenCalled(); + }); + }); + it("should remove expired stamps if the no longer qualify", async () => { + (fetchVerifiableCredential as jest.Mock).mockResolvedValue({ + credentials: [UN_SUCCESSFUL_ENS_RESULT], + }); + const drawer = () => ( + + {}} + /> + + ); + + const handlePatchStampsMock = jest.fn(); + renderWithContext( + { + ...mockCeramicContext, + verifiedProviderIds: ["Ens"], + expiredProviders: ["Ens"], + handlePatchStamps: handlePatchStampsMock, + }, + drawer() + ); + const initialVerifyButton = screen.queryByTestId("button-verify-Ens"); + fireEvent.click(initialVerifyButton as HTMLElement); + // Wait to see the done toast await waitFor(() => { // extraProvider should be empty but ens should be there to delete expired stamp you no longer qualify for expect(handlePatchStampsMock).toHaveBeenCalledWith([ - { provider: "Ens", credential }, - { provider: extraProvider }, + { + provider: "Ens", + }, ]); - expect(screen.getByText("Successfully re-verified Ens data point.")).toBeInTheDocument(); expect(fetchVerifiableCredential).toHaveBeenCalled(); }); }); diff --git a/app/components/GenericPlatform.tsx b/app/components/GenericPlatform.tsx index 74d72d8a0..362bc2bad 100644 --- a/app/components/GenericPlatform.tsx +++ b/app/components/GenericPlatform.tsx @@ -220,14 +220,18 @@ export const GenericPlatform = ({ // If the stamp was not selected, return {provider} to delete the stamp // If the stamp was selected but cannot be claimed, return null to do nothing and // therefore keep any existing valid stamp if it exists - const stampPatches = platformProviderIds.map((provider: PROVIDER_ID) => { - const cred = verifiedCredentials.find((cred: any) => cred.record?.type === provider); - if (cred) { - return { provider, credential: cred.credential }; - } else { - return { provider }; - } - }) as StampPatch[]; + const stampPatches = platformProviderIds + .map((provider: PROVIDER_ID) => { + const cred = verifiedCredentials.find((cred: any) => cred.record?.type === provider); + if (cred) { + return { provider, credential: cred.credential }; + } else if (expiredProviders.includes(provider)) { + return { provider }; + } else { + return null; + } + }) + .filter((patch): patch is StampPatch => Boolean(patch)); await handlePatchStamps(stampPatches); @@ -238,6 +242,19 @@ export const GenericPlatform = ({ !!stampPatches.find((stampPatch) => stampPatch?.credential?.credentialSubject?.provider === providerId) ); + // `verifiedProviders` still holds the previously verified providers. If the user + // can no longer claim the credential, but they still have a valid credential that + // was previously verified, AND they had selected it, we want to keep it + verifiedProviders.forEach((provider) => { + if ( + !actualVerifiedProviders.includes(provider) && + selectedProviders.includes(provider) && + !expiredProviders.includes(provider) + ) { + actualVerifiedProviders.push(provider); + } + }); + // both verified and selected should look the same after save setVerifiedProviders([...actualVerifiedProviders]); @@ -328,6 +345,8 @@ export const GenericPlatform = ({ // dbl check below } else if (initialMinusUpdated.size > 0 && updatedMinusInitial.size === 0 && platformProviderIds.length === 0) { return VerificationStatuses.AllRemoved; + } else if (initialMinusUpdated.size > 0 && updatedMinusInitial.size === 0) { + return VerificationStatuses.PartiallyRemoved; } else if (updatedMinusInitial.size > 0 && initialMinusUpdated.size > 0) { return VerificationStatuses.PartiallyRemovedAndVerified; } else { diff --git a/app/components/Notifications.tsx b/app/components/Notifications.tsx index e241b1b25..1d23d41de 100644 --- a/app/components/Notifications.tsx +++ b/app/components/Notifications.tsx @@ -37,7 +37,11 @@ const ExpiryAction = ({ const message = useMemo(() => { const refreshStamp = async (stamp: StampClaimForPlatform) => { - await claimCredentials(async () => await Promise.resolve(), [stamp]); + await claimCredentials( + async () => await Promise.resolve(), + () => {}, + [stamp] + ); deleteMutation.mutate(); }; const claim: StampClaimForPlatform = {