Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add loadingStatusErrorMessage to state #366

Merged
merged 5 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/components/PayPalScriptProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ describe("<PayPalScriptProvider />", () => {
await waitFor(() => expect(state.isResolved).toBeTruthy());
expect(state.isPending).toBeFalsy();
expect(state.isRejected).toBeFalsy();
expect(state.criticalError).toBeFalsy();
});

test('should set "isRejected" state to "true" after failing to load the script', async () => {
const spyConsoleError = jest
.spyOn(console, "error")
.mockImplementation();
(loadScript as jest.Mock).mockRejectedValue(new Error());
(loadScript as jest.Mock).mockRejectedValue(new Error("test error"));
const { state, TestComponent } = setupTestComponent();
render(
<PayPalScriptProvider options={{ clientId: "test" }}>
Expand All @@ -79,6 +80,9 @@ describe("<PayPalScriptProvider />", () => {
// verify initial loading state
expect(state.isPending).toBeTruthy();
await waitFor(() => expect(state.isRejected).toBeTruthy());
await waitFor(() =>
expect(state.criticalError).toBe("Error: test error")
);
expect(state.isPending).toBeFalsy();
expect(state.isResolved).toBeFalsy();
spyConsoleError.mockRestore();
Expand All @@ -99,6 +103,7 @@ describe("<PayPalScriptProvider />", () => {
unmount();

await waitFor(() => expect(loadScript).toBeCalled());
await waitFor(() => expect(state.criticalError).toBeFalsy());
// verify initial loading state
expect(state.isInitial).toBeFalsy();
expect(state.isPending).toBeTruthy();
Expand Down Expand Up @@ -142,6 +147,7 @@ describe("<PayPalScriptProvider />", () => {

expect(state.isPending).toBe(true);
await waitFor(() => expect(state.isResolved).toBe(true));
expect(state.criticalError).toBeFalsy();
});

test("should remount without reloading the sdk script when the options have not changed", async () => {
Expand Down Expand Up @@ -251,6 +257,7 @@ describe("usePayPalScriptReducer", () => {

function setupTestComponent() {
const state = {
criticalError: "",
options: { "data-react-paypal-script-id": "" },
isInitial: true,
isPending: false,
Expand Down
4 changes: 4 additions & 0 deletions src/components/PayPalScriptProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ export const PayPalScriptProvider: FC<ScriptProviderProps> = ({
type: DISPATCH_ACTION.LOADING_STATUS,
value: SCRIPT_LOADING_STATE.REJECTED,
});
dispatch({
type: DISPATCH_ACTION.CRITICAL_ERROR,
value: String(err),
});
}
});
return () => {
Expand Down
5 changes: 5 additions & 0 deletions src/context/scriptProviderContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
export function getScriptID(options: ReactPayPalScriptOptions): string {
// exclude the data-react-paypal-script-id value from the options hash
const { [SCRIPT_ID]: _scriptId, ...paypalScriptOptions } = options;

Check warning on line 21 in src/context/scriptProviderContext.ts

View workflow job for this annotation

GitHub Actions / main

'_scriptId' is assigned a value but never used

return `react-paypal-js-${hashStr(JSON.stringify(paypalScriptOptions))}`;
}
Expand Down Expand Up @@ -55,6 +55,11 @@
...state,
loadingStatus: action.value as SCRIPT_LOADING_STATE,
};
case DISPATCH_ACTION.CRITICAL_ERROR:
return {
...state,
criticalError: action.value,
};
case DISPATCH_ACTION.RESET_OPTIONS:
// destroy existing script to make sure only one script loads at a time
destroySDKScript(state.options[SCRIPT_ID]);
Expand Down
1 change: 1 addition & 0 deletions src/types/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum SCRIPT_LOADING_STATE {
*/
export enum DISPATCH_ACTION {
LOADING_STATUS = "setLoadingStatus",
CRITICAL_ERROR = "criticalError",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about this name? It may be nice to name it after LOADING_STATUS so it's clearer that this error message is related to a script loading failure.

Suggested change
CRITICAL_ERROR = "criticalError",
LOADING_STATUS_ERROR_MESSAGE = "loadingStatusErrorMessage",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! Renamed

RESET_OPTIONS = "resetOptions",
SET_BRAINTREE_INSTANCE = "braintreeInstance",
}
Expand Down
5 changes: 5 additions & 0 deletions src/types/scriptProviderTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import type { PayPalScriptOptions } from "@paypal/paypal-js";

export interface ReactPayPalScriptOptions extends PayPalScriptOptions {
[key: string]: any;

Check warning on line 8 in src/types/scriptProviderTypes.ts

View workflow job for this annotation

GitHub Actions / main

Unexpected any. Specify a different type
}

export type ScriptReducerAction =
Expand All @@ -13,6 +13,10 @@
type: `${DISPATCH_ACTION.LOADING_STATUS}`;
value: SCRIPT_LOADING_STATE;
}
| {
type: `${DISPATCH_ACTION.CRITICAL_ERROR}`;
value: string;
}
| {
type: `${DISPATCH_ACTION.RESET_OPTIONS}`;
value: ReactPayPalScriptOptions;
Expand All @@ -30,6 +34,7 @@
export interface ScriptContextState {
options: ReactPayPalScriptOptions;
loadingStatus: SCRIPT_LOADING_STATE;
criticalError?: string;
braintreePayPalCheckoutInstance?: BraintreePayPalCheckout;
dispatch?: Dispatch<ScriptReducerAction>;
}
Expand Down