diff --git a/blocks/identity-block/features/login/default.test.jsx b/blocks/identity-block/features/login/default.test.jsx index 3aac18b2e..5f280229c 100644 --- a/blocks/identity-block/features/login/default.test.jsx +++ b/blocks/identity-block/features/login/default.test.jsx @@ -68,7 +68,7 @@ describe("Identity Login Feature", () => { }); }); -describe("Identity Login Feature - rejected Login", () => { +describe("Identity Login Feature - rejected Login, general message", () => { beforeEach(() => { mockLogin.mockImplementation(() => Promise.reject({ code: 0 })); global.grecaptcha = { @@ -101,6 +101,39 @@ describe("Identity Login Feature - rejected Login", () => { }); }); +describe("Identity Login Feature - rejected Login, error code 130001", () => { + beforeEach(() => { + mockLogin.mockImplementation(() => Promise.reject({ code: 130001})); + global.grecaptcha = { + reset: jest.fn() + } + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("rejects the login", async () => { + render(); + + await waitFor(() => expect(screen.getByLabelText("identity-block.email-label"))); + fireEvent.change(screen.getByLabelText("identity-block.email-label"), { + target: { value: "email@test.com" }, + }); + + await waitFor(() => expect(screen.getByLabelText("identity-block.password"))); + fireEvent.change(screen.getByLabelText("identity-block.password"), { + target: { value: "thisNotIsMyPassword" }, + }); + + await waitFor(() => expect(screen.getByRole("button"))); + fireEvent.click(screen.getByRole("button")); + + await waitFor(() => expect(mockLogin).toHaveBeenCalled()); + await screen.findByText("identity-block.login-form-error.captcha-token-invalid"); + }); +}); + describe("Identity Login Feature - unInitialized", () => { beforeEach(() => { useIdentity.mockImplementation(() => ({ diff --git a/blocks/identity-block/utils/useRecaptcha.js b/blocks/identity-block/utils/useRecaptcha.js index bab44e003..6e2c7602b 100644 --- a/blocks/identity-block/utils/useRecaptcha.js +++ b/blocks/identity-block/utils/useRecaptcha.js @@ -18,7 +18,7 @@ const useRecaptcha = (challengeIn) => { const [isRecaptchaEnabled, setIsRecaptchaEnabled] = useState(false); const setRecaptchaInfo = (isCaptchaEnabled, recaptchaSiteKey, recaptchaScore) => { - if (isCaptchaEnabled && recaptchaSiteKey && recaptchaScore) { + if (isCaptchaEnabled && recaptchaSiteKey && !!String(recaptchaScore)) { if (recaptchaScore === "-1") { setSiteKey(recaptchaSiteKey); setRecaptchaVersion(RECAPTCHA_V2); @@ -34,12 +34,12 @@ const useRecaptcha = (challengeIn) => { const checkCaptcha = async () => { const identityConfig = await Identity.getConfig(); const { recaptchaSiteKey, recaptchaScore } = identityConfig; - if (["signup", "signin", "magicLink"].includes(challengeIn)) { + if ([RECAPTCHA_LOGIN, RECAPTCHA_SIGNUP, RECAPTCHA_MAGICLINK].includes(challengeIn)) { const isIdentityCaptchaEnabled = identityConfig?.[`${challengeIn}Recaptcha`]; setRecaptchaInfo(isIdentityCaptchaEnabled, recaptchaSiteKey, recaptchaScore); } - if (challengeIn === "checkout") { + if (challengeIn === RECAPTCHA_CHECKOUT) { const salesConfig = await Sales.getConfig(); const isSalesCaptchaEnabled = salesConfig?.checkoutRecaptchaEnabled; setRecaptchaInfo(isSalesCaptchaEnabled, recaptchaSiteKey, recaptchaScore); diff --git a/blocks/identity-block/utils/useRecaptcha.test.js b/blocks/identity-block/utils/useRecaptcha.test.js new file mode 100644 index 000000000..2fbb95cee --- /dev/null +++ b/blocks/identity-block/utils/useRecaptcha.test.js @@ -0,0 +1,170 @@ +import React from "react"; +import { waitFor, renderHook } from "@testing-library/react"; +import useRecaptcha from "./useRecaptcha"; +import { useIdentity } from "@wpmedia/arc-themes-components"; + +// Mock setTimeout and clearTimeout +jest.useFakeTimers(); + +jest.mock("@arc-publishing/sdk-identity", () => ({ + __esModule: true, + default: { + apiOrigin: "", + options: jest.fn(), + }, +})); + +jest.mock("fusion:properties", () => + jest.fn(() => ({ + api: { + identity: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + }, + retail: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + endpoint: "/retail/public/v1/offer/live/", + }, + }, + })), +); + +jest.mock("fusion:context", () => ({ + __esModule: true, + useFusionContext: () => ({ + arcSite: "Test Site", + }), +})); + +const mockIdentity = { + getConfig: jest.fn(() => + Promise.resolve({ + signupRecaptcha: true, + signinRecaptcha: true, + magicLinkRecaptcha: true, + recaptchaScore: "-1", + recaptchaSiteKey: "6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C", + }), + ), +}; + +const mockSales = { + getConfig: jest.fn(() => + Promise.resolve({ + checkoutRecaptchaEnabled: false, + }), + ), +}; + +jest.mock("@wpmedia/arc-themes-components", () => ({ + ...jest.requireActual("@wpmedia/arc-themes-components"), + useIdentity: jest.fn(() => ({ + isInitialized: true, + Identity: { + ...mockIdentity, + }, + })), + useSales: jest.fn(() => ({ + isInitialized: true, + Sales: { + ...mockSales, + }, + })), +})); + +describe("useRecaptcha", () => { + it("reCaptcha v2 enabled for signIn", async () => { + const { result } = renderHook(() => useRecaptcha("signin")); + + expect(result.current.recaptchaVersion).toBe(undefined); + expect(result.current.siteKey).toBe(undefined); + expect(result.current.isRecaptchaEnabled).toBe(false); + + await waitFor(() => expect(result.current.recaptchaVersion).toEqual("V2")); + + await waitFor(() => expect(result.current.isRecaptchaEnabled).toEqual(true)); + + await waitFor(() => + expect(result.current.siteKey).toEqual("6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C"), + ); + }); + + it("reCaptcha v2 enabled for signUp", async () => { + const { result } = renderHook(() => useRecaptcha("signup")); + + expect(result.current.recaptchaVersion).toBe(undefined); + expect(result.current.siteKey).toBe(undefined); + expect(result.current.isRecaptchaEnabled).toBe(false); + + await waitFor(() => expect(result.current.recaptchaVersion).toEqual("V2")); + + await waitFor(() => expect(result.current.isRecaptchaEnabled).toEqual(true)); + + await waitFor(() => + expect(result.current.siteKey).toEqual("6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C"), + ); + }); + + it("reCaptcha v2 enabled for magicLink", async () => { + const { result } = renderHook(() => useRecaptcha("magicLink")); + + expect(result.current.recaptchaVersion).toBe(undefined); + expect(result.current.siteKey).toBe(undefined); + expect(result.current.isRecaptchaEnabled).toBe(false); + + await waitFor(() => expect(result.current.recaptchaVersion).toEqual("V2")); + + await waitFor(() => expect(result.current.isRecaptchaEnabled).toEqual(true)); + + await waitFor(() => + expect(result.current.siteKey).toEqual("6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C"), + ); + }); + + it("reCaptcha v2 enabled for magicLink", async () => { + const { result } = renderHook(() => useRecaptcha("magicLink")); + + expect(result.current.recaptchaVersion).toBe(undefined); + expect(result.current.siteKey).toBe(undefined); + expect(result.current.isRecaptchaEnabled).toBe(false); + + await waitFor(() => expect(result.current.recaptchaVersion).toEqual("V2")); + + await waitFor(() => expect(result.current.isRecaptchaEnabled).toEqual(true)); + + await waitFor(() => + expect(result.current.siteKey).toEqual("6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C"), + ); + }); + + it("reCaptcha v2 disabled for signIn", async () => { + + useIdentity.mockReturnValueOnce({ + isInitialized: true, + Identity: { + getConfig: jest.fn(() => + Promise.resolve({ + signupRecaptcha: false, // Change the mocked data here + signinRecaptcha: false, + magicLinkRecaptcha: false, + recaptchaScore: "-1", + recaptchaSiteKey: "6LemcOMhAAAAAEGptytQEAMK_SfH4ZAGJ_e4652C", + }), + ), + }, + }); + + const { result } = renderHook(() => useRecaptcha("signin")); + + expect(result.current.recaptchaVersion).toBe(undefined); + expect(result.current.siteKey).toBe(undefined); + expect(result.current.isRecaptchaEnabled).toBe(false); + + await waitFor(() => expect(result.current.recaptchaVersion).toEqual(undefined)); + + await waitFor(() => expect(result.current.isRecaptchaEnabled).toEqual(false)); + + await waitFor(() => + expect(result.current.siteKey).toEqual(undefined), + ); + }); +});