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

Bugfix/pwa 3377 after login issue on order success page #4354

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
7 changes: 6 additions & 1 deletion packages/peregrine/lib/store/actions/user/actions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { createActions } from 'redux-actions';

const prefix = 'USER';
const actionTypes = ['RESET', 'SET_TOKEN', 'CLEAR_TOKEN'];
const actionTypes = [
'RESET',
'SET_TOKEN',
'CLEAR_TOKEN',
'SET_USER_ON_ORDER_SUCCESS'
];

const actionMap = {
SIGN_IN: {
Expand Down
6 changes: 6 additions & 0 deletions packages/peregrine/lib/store/actions/user/asyncActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,9 @@ export const clearToken = () =>
// Remove from store
dispatch(actions.clearToken());
};

export const setUserOnOrderSuccess = successFlag =>
async function thunk(dispatch) {
// Dispatch the action to update the state
dispatch(actions.setUserOnOrderSuccess(successFlag));
};
9 changes: 8 additions & 1 deletion packages/peregrine/lib/store/reducers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const initialState = {
isResettingPassword: false,
isSignedIn: isSignedIn(),
resetPasswordError: null,
token: getToken()
token: getToken(),
userOnOrderSuccess: false // Add userOnOrderSuccess state
};

const reducerMap = {
Expand All @@ -48,6 +49,12 @@ const reducerMap = {
token: null
};
},
[actions.setUserOnOrderSuccess]: (state, { payload }) => {
return {
...state,
userOnOrderSuccess: payload // Update the state with the new flag value
};
},
[actions.getDetails.request]: state => {
return {
...state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { useLazyQuery } from '@apollo/client';

import { useUserContext } from '../../../../context/user';

import { useDispatch } from 'react-redux'; // Import `connect` and `useDispatch` here

import { setUserOnOrderSuccess } from '../../../../store/actions/user/asyncActions'; // Import `setUserOnOrderSuccess`

jest.mock('../../../../context/user');
useUserContext.mockImplementation(() => {
return [
Expand All @@ -28,6 +32,21 @@ jest.mock('@apollo/client', () => {
};
});

// Mock `react-redux`'s `useDispatch` and `connect` functions

jest.mock('react-redux', () => ({
useDispatch: jest.fn(),
connect: jest.fn().mockReturnValue(Component => Component) // Mock `connect` as an identity function
}));

jest.mock('../../../../store/actions/user/asyncActions', () => ({
setUserOnOrderSuccess: jest.fn(value => ({
type: 'SET_USER_ON_ORDER_SUCCESS',

payload: value
})) // Mock `setUserOnOrderSuccess` to return an action object
}));

const Component = props => {
const talonProps = useOrderConfirmationPage(props);

Expand Down Expand Up @@ -131,6 +150,11 @@ describe('for guest', () => {
}
];
});

const mockDispatch = jest.fn(); // Mock dispatch for this test

useDispatch.mockReturnValue(mockDispatch);

const tree = createTestInstance(<Component {...DEFAULT_PROPS} />);

const { root } = tree;
Expand All @@ -143,6 +167,7 @@ describe('for guest', () => {
describe('for authenticated customers', () => {
it('returns the correct shape', () => {
const mockFetch = jest.fn();
const mockDispatch = jest.fn(); // Mock dispatch for this test

useLazyQuery.mockReturnValueOnce([
mockFetch,
Expand All @@ -153,8 +178,16 @@ describe('for authenticated customers', () => {
}
]);

useDispatch.mockReturnValue(mockDispatch);

const mockOrderNumber = '12345';

// Create a mock dispatch function

//const mockDispatch = jest.fn();

//useDispatch.mockReturnValue(mockDispatch); // Mock useDispatch to return the mock function

const tree = createTestInstance(
<Component orderNumber={mockOrderNumber} />
);
Expand All @@ -164,6 +197,10 @@ describe('for authenticated customers', () => {

expect(talonProps).toMatchSnapshot();

// Check if dispatch was called with the correct action

expect(mockDispatch).toHaveBeenCalledWith(setUserOnOrderSuccess(true));

expect(mockFetch).toHaveBeenCalledWith({
variables: { orderNumber: mockOrderNumber }
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useGoogleReCaptcha } from '../../../hooks/useGoogleReCaptcha';

import DEFAULT_OPERATIONS from './createAccount.gql';
import { useEventingContext } from '../../../context/eventing';
import { useHistory } from 'react-router-dom';

/**
* Returns props necessary to render CreateAccount component. In particular this
Expand Down Expand Up @@ -95,6 +96,7 @@ export const useCreateAccount = props => {
formAction: 'createAccount'
});

const history = useHistory();
const handleSubmit = useCallback(
async formValues => {
setIsSubmitting(true);
Expand Down Expand Up @@ -158,6 +160,8 @@ export const useCreateAccount = props => {
if (onSubmit) {
onSubmit();
}

history.push('/account-information');
} catch (error) {
if (process.env.NODE_ENV !== 'production') {
console.error(error);
Expand All @@ -179,7 +183,8 @@ export const useCreateAccount = props => {
removeCart,
setToken,
signIn,
dispatch
dispatch,
history
]
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useEffect } from 'react';
import { useUserContext } from '../../../context/user';
import { setUserOnOrderSuccess } from '../../../store/actions/user/asyncActions';
import { useLazyQuery } from '@apollo/client';

import mergeOperations from '../../../util/shallowMerge';
import DEFAULT_OPERATIONS from './orderConfirmationPage.gql';
import { useDispatch } from 'react-redux';

export const flattenGuestCartData = data => {
if (!data) {
Expand Down Expand Up @@ -34,8 +36,13 @@ export const flattenCustomerOrderData = data => {
if (!data) {
return;
}

const { customer } = data;
const order = customer.orders.items[0];
const order = customer?.orders?.items?.[0];
if (!order || !order.shipping_address) {
// Return an empty response if no valid order or shipping address exists
return;
}
const { shipping_address: address } = order;

return {
Expand Down Expand Up @@ -65,6 +72,8 @@ export const useOrderConfirmationPage = props => {
const flatData =
flattenGuestCartData(props.data) || flattenCustomerOrderData(queryData);

const dispatch = useDispatch();

useEffect(() => {
if (props.orderNumber && !props.data) {
const orderNumber = props.orderNumber;
Expand All @@ -74,7 +83,19 @@ export const useOrderConfirmationPage = props => {
}
});
}
}, [props.orderNumber, props.data, fetchOrderConfirmationDetails]);

dispatch(setUserOnOrderSuccess(true));

return () => {
// Reset the flag when leaving the page
dispatch(setUserOnOrderSuccess(false));
};
}, [
props.orderNumber,
props.data,
fetchOrderConfirmationDetails,
dispatch
]);

return {
flatData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ import { retrieveCartId } from '../../../store/actions/cart';
import createTestInstance from '../../../util/createTestInstance';
import { useCreateAccount } from '../useCreateAccount';
import { useEventingContext } from '../../../context/eventing';
import { useHistory, useLocation } from 'react-router-dom'; // Added import for useHistory and useLocation

// Mocking useHistory and useLocation

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'), // Keep the other functionality intact

useHistory: jest.fn(),

useLocation: jest.fn()
}));

jest.mock('@apollo/client', () => {
const apolloClient = jest.requireActual('@apollo/client');
Expand Down Expand Up @@ -186,6 +197,22 @@ beforeAll(() => {
});

useApolloClient.mockReturnValue(client);

// Mock useHistory and useLocation here if needed for specific tests

useHistory.mockReturnValue({
push: jest.fn() // You can mock any methods that useHistory would provide
});

useLocation.mockReturnValue({
pathname: '/mock-path',

search: '',

hash: '',

state: null
});
});

test('should return properly', () => {
Expand Down
23 changes: 21 additions & 2 deletions packages/peregrine/lib/talons/CreateAccount/useCreateAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import { useGoogleReCaptcha } from '../../hooks/useGoogleReCaptcha';

import DEFAULT_OPERATIONS from './createAccount.gql';
import { useEventingContext } from '../../context/eventing';
import { useHistory, useLocation } from 'react-router-dom';

/**
* Routes to redirect from if used to create an account.
*/
const REDIRECT_FOR_ROUTES = ['/checkout', '/order-confirmation'];

/**
* Returns props necessary to render CreateAccount component. In particular this
Expand Down Expand Up @@ -47,7 +53,7 @@ export const useCreateAccount = props => {
{ createCart, removeCart, getCartDetails }
] = useCartContext();
const [
{ isGettingDetails },
{ isGettingDetails, userOnOrderSuccess },
{ getUserDetails, setToken }
] = useUserContext();

Expand Down Expand Up @@ -112,6 +118,9 @@ export const useCreateAccount = props => {
};
}, [handleCancel]);

const history = useHistory();
const location = useLocation();

const handleSubmit = useCallback(
async formValues => {
setIsSubmitting(true);
Expand Down Expand Up @@ -188,6 +197,13 @@ export const useCreateAccount = props => {
if (onSubmit) {
onSubmit();
}

if (
userOnOrderSuccess &&
REDIRECT_FOR_ROUTES.includes(location.pathname)
) {
history.push('/account-information');
}
} catch (error) {
if (process.env.NODE_ENV !== 'production') {
console.error(error);
Expand All @@ -213,7 +229,10 @@ export const useCreateAccount = props => {
getCartDetails,
fetchCartDetails,
onSubmit,
dispatch
dispatch,
history,
location.pathname,
userOnOrderSuccess
]
);

Expand Down
24 changes: 24 additions & 0 deletions packages/peregrine/lib/talons/SignIn/__tests__/useSignIn.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ jest.mock('@magento/peregrine/lib/context/eventing', () => ({
useEventingContext: jest.fn().mockReturnValue([{}, { dispatch: jest.fn() }])
}));

jest.mock('react-router-dom', () => ({
useHistory: jest.fn().mockReturnValue({
push: jest.fn(),

replace: jest.fn()
}),

useLocation: jest.fn().mockReturnValue({
pathname: '/checkout',

search: '',

hash: '',

state: null
})
}));

const Component = props => {
const talonProps = useSignIn(props);

Expand Down Expand Up @@ -277,6 +295,12 @@ test('mutation error is returned by talon', async () => {
expect(talonProps.errors).toMatchSnapshot();
});

test('useLocation and useHistory are used correctly', () => {
const { talonProps } = getTalonProps({ ...defaultProps });

expect(talonProps).toBeDefined(); // Placeholder assertion.
});

it('should call handleForgotPassword when Enter key is pressed', () => {
const { talonProps } = getTalonProps({
...defaultProps
Expand Down
Loading