2024-01-16 13:01:31 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { interpret } from 'xstate';
|
|
|
|
import { waitFor } from 'xstate/lib/waitFor';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { designWithNoAiStateMachineDefinition } from '../state-machine';
|
|
|
|
|
|
|
|
const createMockMachine = ( {
|
|
|
|
services,
|
|
|
|
guards,
|
|
|
|
actions,
|
|
|
|
}: Parameters<
|
|
|
|
typeof designWithNoAiStateMachineDefinition.withConfig
|
|
|
|
>[ 0 ] ) => {
|
|
|
|
const machineWithConfig = designWithNoAiStateMachineDefinition.withConfig( {
|
|
|
|
services,
|
|
|
|
guards,
|
|
|
|
actions,
|
|
|
|
} );
|
|
|
|
|
|
|
|
return machineWithConfig;
|
|
|
|
};
|
|
|
|
|
2024-01-17 14:09:12 +00:00
|
|
|
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
2024-02-08 15:08:38 +00:00
|
|
|
jest.mock(
|
|
|
|
'@wordpress/edit-site/build-module/components/global-styles/global-styles-provider',
|
|
|
|
() => jest.fn()
|
|
|
|
);
|
2024-01-17 14:09:12 +00:00
|
|
|
|
2024-01-16 13:01:31 +00:00
|
|
|
describe( 'Design Without AI state machine', () => {
|
|
|
|
beforeEach( () => {
|
|
|
|
jest.clearAllMocks();
|
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'navigate state', () => {
|
|
|
|
it( 'should start with the navigate state', async () => {
|
|
|
|
const expectedValue = 'navigate';
|
|
|
|
|
|
|
|
const actualState =
|
|
|
|
designWithNoAiStateMachineDefinition.initialState;
|
|
|
|
|
|
|
|
expect( actualState.matches( expectedValue ) ).toBeTruthy();
|
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'should check the url', () => {
|
|
|
|
const hasStepInUrl = jest.fn( () => true );
|
|
|
|
const machine = designWithNoAiStateMachineDefinition.withConfig( {
|
|
|
|
guards: {
|
|
|
|
hasStepInUrl,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
2024-01-25 11:04:44 +00:00
|
|
|
const machineInterpret = interpret( machine ).start();
|
2024-01-16 13:01:31 +00:00
|
|
|
|
|
|
|
expect( hasStepInUrl ).toBeCalled();
|
2024-01-25 11:04:44 +00:00
|
|
|
machineInterpret.stop();
|
2024-01-16 13:01:31 +00:00
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
it( 'should transit to preAssembleSite state when the url is /design', () => {
|
2024-01-16 13:01:31 +00:00
|
|
|
const hasStepInUrl = jest.fn( () => true );
|
|
|
|
const machine = designWithNoAiStateMachineDefinition.withConfig( {
|
|
|
|
guards: {
|
|
|
|
hasStepInUrl,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const machineInterpret = interpret( machine ).start();
|
|
|
|
|
|
|
|
expect(
|
2024-01-18 14:52:49 +00:00
|
|
|
machineInterpret.getSnapshot().matches( 'preAssembleSite' )
|
2024-01-16 13:01:31 +00:00
|
|
|
).toBeTruthy();
|
2024-01-25 11:04:44 +00:00
|
|
|
|
|
|
|
machineInterpret.stop();
|
2024-01-16 13:01:31 +00:00
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
it( "should not transit to preAssembleSite state when the url isn't /design", () => {
|
2024-01-16 13:01:31 +00:00
|
|
|
const hasStepInUrl = jest.fn( () => false );
|
|
|
|
const machine = designWithNoAiStateMachineDefinition.withConfig( {
|
|
|
|
guards: {
|
|
|
|
hasStepInUrl,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const machineInterpret = interpret( machine ).start();
|
|
|
|
|
|
|
|
expect(
|
2024-01-18 14:52:49 +00:00
|
|
|
machineInterpret.getSnapshot().matches( 'preAssembleSite' )
|
2024-01-16 13:01:31 +00:00
|
|
|
).toBeFalsy();
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
describe( 'preAssembleSite state', () => {
|
2024-01-25 11:04:44 +00:00
|
|
|
it( 'should invoke `redirectToIntroWithError` when `installAndActivateTheme` service fails', async () => {
|
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme';
|
|
|
|
|
|
|
|
const installAndActivateThemeMock = jest.fn( () =>
|
|
|
|
Promise.reject()
|
|
|
|
);
|
|
|
|
const assembleSiteMock = jest.fn( () => Promise.resolve() );
|
|
|
|
const createProductsMock = jest.fn( () =>
|
|
|
|
Promise.resolve( {
|
|
|
|
success: true,
|
|
|
|
} )
|
|
|
|
);
|
|
|
|
const redirectToIntroWithErrorMock = jest.fn();
|
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
|
|
|
installAndActivateTheme: installAndActivateThemeMock,
|
|
|
|
assembleSite: assembleSiteMock,
|
|
|
|
createProducts: createProductsMock,
|
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
redirectToIntroWithError: redirectToIntroWithErrorMock,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const state = machine.getInitialState( initialState );
|
|
|
|
|
|
|
|
const actor = interpret( machine ).start( state );
|
|
|
|
|
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme.pending'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
expect( installAndActivateThemeMock ).toHaveBeenCalled();
|
|
|
|
expect( redirectToIntroWithErrorMock ).toHaveBeenCalled();
|
|
|
|
} );
|
2024-01-17 14:09:12 +00:00
|
|
|
it( 'should invoke `installAndActivateTheme` service', async () => {
|
2024-01-18 14:52:49 +00:00
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme';
|
2024-01-17 14:09:12 +00:00
|
|
|
const installAndActivateThemeMock = jest.fn( () =>
|
|
|
|
Promise.resolve()
|
|
|
|
);
|
2024-01-25 11:04:44 +00:00
|
|
|
const assembleSiteMock = jest.fn( () => Promise.resolve() );
|
|
|
|
const createProductsMock = jest.fn( () =>
|
|
|
|
Promise.resolve( {
|
|
|
|
success: true,
|
|
|
|
} )
|
|
|
|
);
|
2024-01-17 14:09:12 +00:00
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
|
|
|
installAndActivateTheme: installAndActivateThemeMock,
|
2024-01-25 11:04:44 +00:00
|
|
|
assembleSite: assembleSiteMock,
|
|
|
|
createProducts: createProductsMock,
|
2024-01-17 14:09:12 +00:00
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
const state = machine.getInitialState( initialState );
|
2024-01-17 14:09:12 +00:00
|
|
|
|
|
|
|
const actor = interpret( machine ).start( state );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme.pending'
|
|
|
|
);
|
|
|
|
} );
|
2024-01-17 14:09:12 +00:00
|
|
|
|
|
|
|
expect( installAndActivateThemeMock ).toHaveBeenCalled();
|
2024-01-18 14:52:49 +00:00
|
|
|
|
|
|
|
const finalState = await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme.success'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
2024-01-17 14:09:12 +00:00
|
|
|
expect(
|
2024-01-18 14:52:49 +00:00
|
|
|
finalState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.installAndActivateTheme.success'
|
|
|
|
)
|
2024-01-17 14:09:12 +00:00
|
|
|
).toBeTruthy();
|
|
|
|
} );
|
|
|
|
|
2024-01-25 11:04:44 +00:00
|
|
|
it( 'should invoke `redirectToIntroWithError` when `assembleSite` service fails', async () => {
|
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite';
|
|
|
|
|
|
|
|
const assembleSiteMock = jest.fn( () => Promise.reject() );
|
|
|
|
const createProductsMock = jest.fn( () => {
|
|
|
|
return Promise.resolve( {
|
|
|
|
success: true,
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
const installAndActivateThemeMock = jest.fn( () =>
|
|
|
|
Promise.resolve()
|
|
|
|
);
|
|
|
|
|
|
|
|
const redirectToIntroWithErrorMock = jest.fn();
|
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
|
|
|
assembleSite: assembleSiteMock,
|
|
|
|
createProducts: createProductsMock,
|
|
|
|
installAndActivateTheme: installAndActivateThemeMock,
|
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
redirectToIntroWithError: redirectToIntroWithErrorMock,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const state = machine.getInitialState( initialState );
|
|
|
|
|
|
|
|
const actor = interpret( machine ).start( state );
|
|
|
|
|
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite.pending'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
expect( assembleSiteMock ).toHaveBeenCalled();
|
|
|
|
expect( redirectToIntroWithErrorMock ).toHaveBeenCalled();
|
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
it( 'should invoke `assembleSite` service', async () => {
|
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite';
|
|
|
|
|
|
|
|
const assembleSiteMock = jest.fn( () => Promise.resolve() );
|
2024-01-25 11:04:44 +00:00
|
|
|
const installAndActivateThemeMock = jest.fn( () =>
|
|
|
|
Promise.resolve()
|
|
|
|
);
|
|
|
|
const createProductsMock = jest.fn( () =>
|
|
|
|
Promise.resolve( {
|
|
|
|
success: true,
|
|
|
|
} )
|
|
|
|
);
|
2024-01-18 14:52:49 +00:00
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
|
|
|
assembleSite: assembleSiteMock,
|
2024-01-25 11:04:44 +00:00
|
|
|
createProducts: createProductsMock,
|
|
|
|
installAndActivateTheme: installAndActivateThemeMock,
|
2024-01-18 14:52:49 +00:00
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const state = machine.getInitialState( initialState );
|
|
|
|
|
|
|
|
const actor = interpret( machine ).start( state );
|
|
|
|
|
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite.pending'
|
|
|
|
);
|
|
|
|
} );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
expect( assembleSiteMock ).toHaveBeenCalled();
|
|
|
|
|
|
|
|
const finalState = await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite.success'
|
|
|
|
);
|
|
|
|
} );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
|
|
|
expect(
|
2024-01-18 14:52:49 +00:00
|
|
|
finalState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.assembleSite.success'
|
|
|
|
)
|
2024-01-16 13:01:31 +00:00
|
|
|
).toBeTruthy();
|
|
|
|
} );
|
|
|
|
|
2024-01-25 11:04:44 +00:00
|
|
|
it( 'should invoke `redirectToIntroWithError` when `createProducts` service fails', async () => {
|
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts';
|
|
|
|
|
|
|
|
const createProductsMock = jest.fn( () => Promise.reject() );
|
|
|
|
const assembleSiteMock = jest.fn( () => Promise.resolve() );
|
|
|
|
const installAndActivateThemeMock = jest.fn( () =>
|
|
|
|
Promise.resolve()
|
|
|
|
);
|
|
|
|
|
|
|
|
const redirectToIntroWithErrorMock = jest.fn();
|
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
|
|
|
createProducts: createProductsMock,
|
|
|
|
assembleSite: assembleSiteMock,
|
|
|
|
installAndActivateTheme: installAndActivateThemeMock,
|
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
redirectToIntroWithError: redirectToIntroWithErrorMock,
|
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
|
|
|
const state = machine.getInitialState( initialState );
|
|
|
|
|
|
|
|
const actor = interpret( machine ).start( state );
|
|
|
|
|
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts.pending'
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
|
|
|
expect( createProductsMock ).toHaveBeenCalled();
|
|
|
|
expect( redirectToIntroWithErrorMock ).toHaveBeenCalled();
|
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
it( 'should invoke `createProducts` service', async () => {
|
|
|
|
const initialState =
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts';
|
|
|
|
|
2024-01-25 11:04:44 +00:00
|
|
|
const createProductsMock = jest.fn( () =>
|
|
|
|
Promise.resolve( {
|
|
|
|
success: true,
|
|
|
|
} )
|
|
|
|
);
|
2024-01-16 13:01:31 +00:00
|
|
|
|
|
|
|
const machine = createMockMachine( {
|
|
|
|
services: {
|
2024-01-18 14:52:49 +00:00
|
|
|
createProducts: createProductsMock,
|
2024-01-16 13:01:31 +00:00
|
|
|
},
|
|
|
|
} );
|
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
const state = machine.getInitialState( initialState );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
const actor = interpret( machine ).start( state );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts.pending'
|
|
|
|
);
|
|
|
|
} );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
2024-01-18 14:52:49 +00:00
|
|
|
expect( createProductsMock ).toHaveBeenCalled();
|
|
|
|
|
|
|
|
const finalState = await waitFor( actor, ( currentState ) => {
|
|
|
|
return currentState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts.success'
|
|
|
|
);
|
|
|
|
} );
|
2024-01-16 13:01:31 +00:00
|
|
|
|
|
|
|
expect(
|
2024-01-18 14:52:49 +00:00
|
|
|
finalState.matches(
|
|
|
|
'preAssembleSite.preApiCallLoader.createProducts.success'
|
|
|
|
)
|
2024-01-16 13:01:31 +00:00
|
|
|
).toBeTruthy();
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
} );
|