2023-09-07 09:05:47 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { recordEvent } from '@woocommerce/tracks';
|
2023-09-19 08:41:52 +00:00
|
|
|
import { __experimentalRequestJetpackToken as requestJetpackToken } from '@woocommerce/ai';
|
|
|
|
import apiFetch from '@wordpress/api-fetch';
|
2023-09-07 09:05:47 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
2023-09-19 08:41:52 +00:00
|
|
|
import { getCompletion } from '../services';
|
2023-09-07 09:05:47 +00:00
|
|
|
|
|
|
|
jest.mock( '@woocommerce/tracks', () => ( {
|
|
|
|
recordEvent: jest.fn(),
|
|
|
|
} ) );
|
|
|
|
|
2023-09-19 08:41:52 +00:00
|
|
|
jest.mock( '@woocommerce/ai', () => ( {
|
|
|
|
__experimentalRequestJetpackToken: jest.fn(),
|
|
|
|
} ) );
|
|
|
|
|
|
|
|
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
|
|
|
|
2023-09-21 05:30:57 +00:00
|
|
|
jest.mock(
|
|
|
|
'@wordpress/edit-site/build-module/components/global-styles/global-styles-provider',
|
|
|
|
() => ( {
|
|
|
|
mergeBaseAndUserConfigs: jest.fn(),
|
|
|
|
} )
|
|
|
|
);
|
|
|
|
|
2023-09-19 08:41:52 +00:00
|
|
|
describe( 'getCompletion', () => {
|
2023-09-07 09:05:47 +00:00
|
|
|
beforeEach( () => {
|
2023-09-19 08:41:52 +00:00
|
|
|
jest.clearAllMocks();
|
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'should successfully get completion', async () => {
|
|
|
|
( requestJetpackToken as jest.Mock ).mockResolvedValue( {
|
|
|
|
token: 'fake_token',
|
|
|
|
} );
|
|
|
|
( apiFetch as unknown as jest.Mock ).mockResolvedValue( {
|
|
|
|
completion: JSON.stringify( { key: 'value' } ),
|
|
|
|
} );
|
|
|
|
const responseValidation = jest.fn( ( json ) => json );
|
|
|
|
|
|
|
|
const result = await getCompletion( {
|
|
|
|
queryId: 'query1',
|
|
|
|
prompt: 'test prompt',
|
|
|
|
responseValidation,
|
|
|
|
retryCount: 0,
|
|
|
|
version: '1',
|
|
|
|
} );
|
|
|
|
|
|
|
|
expect( result ).toEqual( { key: 'value' } );
|
|
|
|
expect( responseValidation ).toBeCalledWith( { key: 'value' } );
|
|
|
|
expect( recordEvent ).toBeCalledWith(
|
|
|
|
'customize_your_store_ai_completion_success',
|
|
|
|
{
|
|
|
|
query_id: 'query1',
|
|
|
|
retry_count: 0,
|
|
|
|
version: '1',
|
|
|
|
}
|
|
|
|
);
|
2023-09-07 09:05:47 +00:00
|
|
|
} );
|
|
|
|
|
2023-09-19 08:41:52 +00:00
|
|
|
it( 'should handle API fetch error', async () => {
|
|
|
|
( requestJetpackToken as jest.Mock ).mockResolvedValue( {
|
|
|
|
token: 'fake_token',
|
|
|
|
} );
|
|
|
|
( apiFetch as unknown as jest.Mock ).mockRejectedValue(
|
|
|
|
new Error( 'API error' )
|
|
|
|
);
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
getCompletion( {
|
|
|
|
queryId: 'query1',
|
|
|
|
prompt: 'test prompt',
|
|
|
|
responseValidation: () => {},
|
|
|
|
retryCount: 0,
|
|
|
|
version: '1',
|
|
|
|
} )
|
|
|
|
).rejects.toThrow( 'API error' );
|
|
|
|
|
|
|
|
expect( recordEvent ).toBeCalledWith(
|
|
|
|
'customize_your_store_ai_completion_api_error',
|
|
|
|
{
|
|
|
|
query_id: 'query1',
|
|
|
|
retry_count: 0,
|
|
|
|
error_type: 'api_request_error',
|
|
|
|
version: '1',
|
|
|
|
}
|
|
|
|
);
|
2023-09-07 09:05:47 +00:00
|
|
|
} );
|
|
|
|
|
2023-09-19 08:41:52 +00:00
|
|
|
it( 'should handle JSON parse error', async () => {
|
|
|
|
( requestJetpackToken as jest.Mock ).mockResolvedValue( {
|
|
|
|
token: 'fake_token',
|
|
|
|
} );
|
|
|
|
( apiFetch as unknown as jest.Mock ).mockResolvedValue( {
|
|
|
|
completion: 'invalid json',
|
|
|
|
} );
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
getCompletion( {
|
|
|
|
queryId: 'query1',
|
|
|
|
prompt: 'test prompt',
|
|
|
|
responseValidation: () => {},
|
|
|
|
retryCount: 0,
|
|
|
|
version: '1',
|
|
|
|
} )
|
|
|
|
).rejects.toThrow(
|
|
|
|
`Error validating Jetpack AI text completions response for query1`
|
|
|
|
);
|
|
|
|
|
|
|
|
expect( recordEvent ).toBeCalledWith(
|
|
|
|
'customize_your_store_ai_completion_response_error',
|
2023-09-07 09:05:47 +00:00
|
|
|
{
|
2023-09-19 08:41:52 +00:00
|
|
|
query_id: 'query1',
|
|
|
|
retry_count: 0,
|
2023-09-07 09:05:47 +00:00
|
|
|
error_type: 'json_parse_error',
|
2023-09-19 08:41:52 +00:00
|
|
|
response: 'invalid json',
|
|
|
|
version: '1',
|
2023-09-07 09:05:47 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
|
2023-09-19 08:41:52 +00:00
|
|
|
it( 'should handle validation error', async () => {
|
|
|
|
( requestJetpackToken as jest.Mock ).mockResolvedValue( {
|
|
|
|
token: 'fake_token',
|
|
|
|
} );
|
|
|
|
( apiFetch as unknown as jest.Mock ).mockResolvedValue( {
|
|
|
|
completion: JSON.stringify( { key: 'invalid value' } ),
|
|
|
|
} );
|
|
|
|
const responseValidation = jest.fn( () => {
|
|
|
|
throw new Error( 'Validation error' );
|
|
|
|
} );
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
getCompletion( {
|
|
|
|
queryId: 'query1',
|
|
|
|
prompt: 'test prompt',
|
|
|
|
responseValidation,
|
|
|
|
retryCount: 0,
|
|
|
|
version: '1',
|
|
|
|
} )
|
|
|
|
).rejects.toThrow( 'Validation error' );
|
|
|
|
|
|
|
|
expect( recordEvent ).toBeCalledWith(
|
|
|
|
'customize_your_store_ai_completion_response_error',
|
2023-09-07 09:05:47 +00:00
|
|
|
{
|
2023-09-19 08:41:52 +00:00
|
|
|
query_id: 'query1',
|
|
|
|
retry_count: 0,
|
2023-09-07 09:05:47 +00:00
|
|
|
error_type: 'valid_json_invalid_values',
|
2023-09-19 08:41:52 +00:00
|
|
|
response: JSON.stringify( { key: 'invalid value' } ),
|
|
|
|
version: '1',
|
2023-09-07 09:05:47 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} );
|
|
|
|
} );
|