diff --git a/plugins/woocommerce/changelog/51284-e2e-external-pressable-include-api-tests b/plugins/woocommerce/changelog/51284-e2e-external-pressable-include-api-tests new file mode 100644 index 00000000000..0351b91c1d8 --- /dev/null +++ b/plugins/woocommerce/changelog/51284-e2e-external-pressable-include-api-tests @@ -0,0 +1,4 @@ +Significance: patch +Type: update + +Include API tests into test suites for Pressable and WPCOM. \ No newline at end of file diff --git a/plugins/woocommerce/package.json b/plugins/woocommerce/package.json index a01cd250ffc..8ec41d6cfda 100644 --- a/plugins/woocommerce/package.json +++ b/plugins/woocommerce/package.json @@ -556,7 +556,7 @@ "on-demand" ], "report": { - "resultsBlobName": "default-pressable-core-e2e", + "resultsBlobName": "default-pressable-core-e2e-and-api", "resultsPath": "tests/e2e-pw/test-results", "allure": true } @@ -572,7 +572,7 @@ "on-demand" ], "report": { - "resultsBlobName": "default-wpcom-core-e2e", + "resultsBlobName": "default-wpcom-core-e2e-and-api", "resultsPath": "tests/e2e-pw/test-results", "allure": true } @@ -681,7 +681,6 @@ "node_modules/@woocommerce/e2e-core-tests/CHANGELOG.md", "node_modules/@woocommerce/api/dist/", "node_modules/@woocommerce/admin-e2e-tests/build", - "node_modules/@woocommerce/classic-assets/build", "node_modules/@woocommerce/block-library/build", "node_modules/@woocommerce/block-library/blocks.ini", "node_modules/@woocommerce/admin-library/build", diff --git a/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js b/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js index 259c06b7fc6..4de1709668c 100644 --- a/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js +++ b/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js @@ -16,6 +16,7 @@ config = { '**/customize-store/**/*.spec.js', '**/merchant/**/*.spec.js', '**/shopper/**/*.spec.js', + '**/api-tests/**/*.test.js', ], grepInvert: /@skip-on-default-pressable/, }, diff --git a/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js b/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js index 62169c1d0dc..08977a04e71 100644 --- a/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js +++ b/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js @@ -7,7 +7,11 @@ config = { { name: 'default wpcom', use: { ...devices[ 'Desktop Chrome' ] }, - testMatch: [ '**/basic.spec.js', '**/shopper/**/*.spec.js' ], + testMatch: [ + '**/basic.spec.js', + '**/shopper/**/*.spec.js', + '**/api-tests/**/*.test.js', + ], grepInvert: /@skip-on-default-wpcom/, }, ], diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/coupons/coupons.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/coupons/coupons.test.js index 7c9a8a06565..a4a7cc9abe9 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/coupons/coupons.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/coupons/coupons.test.js @@ -69,26 +69,30 @@ test.describe( 'Coupons API tests', () => { ); } ); - test( 'can permanently delete a coupon', async ( { request } ) => { - //call API to delete previously created coupon - const response = await request.delete( - `/wp-json/wc/v3/coupons/${ couponId }`, - { - data: { force: true }, - } - ); + test( + 'can permanently delete a coupon', + { tag: '@skip-on-default-wpcom' }, + async ( { request } ) => { + //call API to delete previously created coupon + const response = await request.delete( + `/wp-json/wc/v3/coupons/${ couponId }`, + { + data: { force: true }, + } + ); - //validate response - expect( response.status() ).toEqual( 200 ); + //validate response + expect( response.status() ).toEqual( 200 ); - //call API to retrieve previously deleted coupon - const getCouponResponse = await request.get( - `/wp-json/wc/v3/coupons/${ couponId }` - ); + //call API to retrieve previously deleted coupon + const getCouponResponse = await request.get( + `/wp-json/wc/v3/coupons/${ couponId }` + ); - //validate response - expect( getCouponResponse.status() ).toEqual( 404 ); - } ); + //validate response + expect( getCouponResponse.status() ).toEqual( 404 ); + } + ); } ); test.describe( 'Batch update coupons', () => { @@ -180,38 +184,42 @@ test.describe( 'Batch update coupons', () => { expect( updatedCoupons[ 1 ].amount ).toEqual( '25.00' ); } ); - test( 'can batch delete coupons', async ( { request } ) => { - // Batch delete the 2 coupons. - const couponIdsToDelete = expectedCoupons.map( ( { id } ) => id ); - const batchDeletePayload = { - delete: couponIdsToDelete, - }; + test( + 'can batch delete coupons', + { tag: '@skip-on-default-wpcom' }, + async ( { request } ) => { + // Batch delete the 2 coupons. + const couponIdsToDelete = expectedCoupons.map( ( { id } ) => id ); + const batchDeletePayload = { + delete: couponIdsToDelete, + }; - //Call API to batch delete the coupons - const batchDeleteResponse = await request.post( - 'wp-json/wc/v3/coupons/batch', - { - data: batchDeletePayload, - } - ); - const batchDeletePayloadJSON = await batchDeleteResponse.json(); - - // Verify that the response shows the 2 coupons. - const deletedCouponIds = batchDeletePayloadJSON.delete.map( - ( { id } ) => id - ); - expect( batchDeleteResponse.status() ).toEqual( 200 ); - expect( deletedCouponIds ).toEqual( couponIdsToDelete ); - - // Verify that the 2 deleted coupons cannot be retrieved. - for ( const couponId of couponIdsToDelete ) { - //Call the API to attempte to retrieve the coupons - const response = await request.get( - `wp-json/wc/v3/coupons/${ couponId }` + //Call API to batch delete the coupons + const batchDeleteResponse = await request.post( + 'wp-json/wc/v3/coupons/batch', + { + data: batchDeletePayload, + } ); - expect( response.status() ).toEqual( 404 ); + const batchDeletePayloadJSON = await batchDeleteResponse.json(); + + // Verify that the response shows the 2 coupons. + const deletedCouponIds = batchDeletePayloadJSON.delete.map( + ( { id } ) => id + ); + expect( batchDeleteResponse.status() ).toEqual( 200 ); + expect( deletedCouponIds ).toEqual( couponIdsToDelete ); + + // Verify that the 2 deleted coupons cannot be retrieved. + for ( const couponId of couponIdsToDelete ) { + //Call the API to attempte to retrieve the coupons + const response = await request.get( + `wp-json/wc/v3/coupons/${ couponId }` + ); + expect( response.status() ).toEqual( 404 ); + } } - } ); + ); } ); test.describe( 'List coupons', () => { diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/customers/customers-crud.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/customers/customers-crud.test.js index 17be7e0a3bc..a93fef4198a 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/customers/customers-crud.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/customers/customers-crud.test.js @@ -2,500 +2,537 @@ const { test, expect } = require( '../../../fixtures/api-tests-fixtures' ); const { admin } = require( '../../../test-data/data' ); const { customer } = require( '../../../data' ); -test.describe( 'Customers API tests: CRUD', () => { - let customerId; - let subscriberUserId; - let subscriberUserCreatedDuringTests = false; +test.describe( + 'Customers API tests: CRUD', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + () => { + let customerId; + let subscriberUserId; + let subscriberUserCreatedDuringTests = false; - test.beforeAll( async ( { request } ) => { - // Call the API to return all users and determine if a - // subscriber user has been created - const customersResponse = await request.get( - '/wp-json/wc/v3/customers', - { - params: { - role: 'all', - }, - } - ); - const customersResponseJSON = await customersResponse.json(); - - for ( const element of customersResponseJSON ) { - if ( element.role === 'subscriber' ) { - subscriberUserId = element.id; - break; - } - } - - // If a subscriber user has not been created then create one - if ( ! subscriberUserId ) { - const now = Date.now(); - const userResponse = await request.post( '/wp-json/wp/v2/users', { - data: { - username: `customer_${ now }`, - email: `customer_${ now }@woocommercecoretestsuite.com`, - first_name: 'Jane', - last_name: 'Smith', - roles: [ 'subscriber' ], - password: 'password', - name: 'Jane', - }, - } ); - const userResponseJSON = await userResponse.json(); - // set subscriber user id to newly created user - subscriberUserId = userResponseJSON.id; - subscriberUserCreatedDuringTests = true; - } - - // Verify the subscriber user has been created - const response = await request.get( - `/wp-json/wc/v3/customers/${ subscriberUserId }` - ); - const responseJSON = await response.json(); - // eslint-disable-next-line jest/no-standalone-expect - expect( response.status() ).toEqual( 200 ); - // eslint-disable-next-line jest/no-standalone-expect - expect( responseJSON.role ).toEqual( 'subscriber' ); - } ); - - test.afterAll( async ( { request } ) => { - // delete subscriber user if one was created during the execution of these tests - if ( subscriberUserCreatedDuringTests ) { - await request.delete( - `/wp-json/wc/v3/customers/${ subscriberUserId }`, + test.beforeAll( async ( { request } ) => { + // Call the API to return all users and determine if a + // subscriber user has been created + const customersResponse = await request.get( + '/wp-json/wc/v3/customers', { - data: { - force: true, + params: { + role: 'all', }, } ); - } - } ); + const customersResponseJSON = await customersResponse.json(); - test.describe( 'Retrieve after env setup', () => { - /** - * when the environment is created, - * (https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/tests/e2e-pw#woocommerce-playwright-end-to-end-tests), - * we have an admin user and a subscriber user that can both be - * accessed through their ids - * admin user will have id 1 and subscriber user will have id 2 - * neither of these are returned as part of the get all customers call - * unless the role 'all' is passed as a search param - * but they can be accessed by specific id reference - */ - test( 'can retrieve admin user', async ( { request } ) => { - // call API to retrieve the previously saved customer - const response = await request.get( '/wp-json/wc/v3/customers/1' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.is_paying_customer ).toEqual( false ); - expect( responseJSON.role ).toEqual( 'administrator' ); - // this test was updated to allow for local test setup and other test sites. - expect( responseJSON.username ).toEqual( admin.username ); - } ); + for ( const element of customersResponseJSON ) { + if ( element.role === 'subscriber' ) { + subscriberUserId = element.id; + break; + } + } - test( 'can retrieve subscriber user', async ( { request } ) => { - // if environment was created with subscriber user - // call API to retrieve the customer with id 2 + // If a subscriber user has not been created then create one + if ( ! subscriberUserId ) { + const now = Date.now(); + const userResponse = await request.post( + '/wp-json/wp/v2/users', + { + data: { + username: `customer_${ now }`, + email: `customer_${ now }@woocommercecoretestsuite.com`, + first_name: 'Jane', + last_name: 'Smith', + roles: [ 'subscriber' ], + password: 'password', + name: 'Jane', + }, + } + ); + const userResponseJSON = await userResponse.json(); + // set subscriber user id to newly created user + subscriberUserId = userResponseJSON.id; + subscriberUserCreatedDuringTests = true; + } + + // Verify the subscriber user has been created const response = await request.get( `/wp-json/wc/v3/customers/${ subscriberUserId }` ); const responseJSON = await response.json(); + // eslint-disable-next-line jest/no-standalone-expect expect( response.status() ).toEqual( 200 ); - expect( responseJSON.is_paying_customer ).toEqual( false ); + // eslint-disable-next-line jest/no-standalone-expect expect( responseJSON.role ).toEqual( 'subscriber' ); } ); - test( 'retrieve user with id 0 is invalid', async ( { request } ) => { - // call API to retrieve the previously saved customer - const response = await request.get( '/wp-json/wc/v3/customers/0' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 404 ); - expect( responseJSON.code ).toEqual( - 'woocommerce_rest_invalid_id' - ); - expect( responseJSON.message ).toEqual( 'Invalid resource ID.' ); + test.afterAll( async ( { request } ) => { + // delete subscriber user if one was created during the execution of these tests + if ( subscriberUserCreatedDuringTests ) { + await request.delete( + `/wp-json/wc/v3/customers/${ subscriberUserId }`, + { + data: { + force: true, + }, + } + ); + } } ); - test( 'can retrieve customers', async ( { request } ) => { - // call API to retrieve all customers should initially return empty array - const response = await request.get( '/wp-json/wc/v3/customers' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON.length ).toEqual( 1 ); - } ); - - // however, if we pass in the search string for role 'all' then all users are returned - test( 'can retrieve all customers', async ( { request } ) => { - // call API to retrieve all customers should initially return empty array - // unless the role 'all' is passed as a search string, in which case the admin - // and subscriber users will be returned - const response = await request.get( '/wp-json/wc/v3/customers', { - params: { - role: 'all', - }, - } ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON.length ).toBeGreaterThanOrEqual( 3 ); - } ); - } ); - - test.describe( 'Create a customer', () => { - test( 'can create a customer', async ( { request } ) => { - // call API to create a customer - const response = await request.post( '/wp-json/wc/v3/customers', { - data: customer, - } ); - const responseJSON = await response.json(); - - // Save the customer ID. It will be used by the retrieve, update, and delete tests. - customerId = responseJSON.id; - - expect( response.status() ).toEqual( 201 ); - expect( typeof responseJSON.id ).toEqual( 'number' ); - // Verify that the customer role is 'customer' - expect( responseJSON.role ).toEqual( 'customer' ); - } ); - } ); - - test.describe( 'Retrieve after create', () => { - test( 'can retrieve a customer', async ( { request } ) => { - // call API to retrieve the previously saved customer - const response = await request.get( - `/wp-json/wc/v3/customers/${ customerId }` - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.id ).toEqual( customerId ); - expect( responseJSON.is_paying_customer ).toEqual( false ); - expect( responseJSON.role ).toEqual( 'customer' ); - } ); - - test( 'can retrieve all customers after create', async ( { - request, - } ) => { - // call API to retrieve all customers - const response = await request.get( '/wp-json/wc/v3/customers' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON.length ).toBeGreaterThan( 0 ); - } ); - } ); - - test.describe( 'Update a customer', () => { - test( `can update the admin user/customer`, async ( { request } ) => { + test.describe( 'Retrieve after env setup', () => { /** - * update customer names (regular, billing and shipping) to admin - * (these were initialised blank when the environment is created, - * (https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/tests/e2e-pw#woocommerce-playwright-end-to-end-tests + * when the environment is created, + * (https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/tests/e2e-pw#woocommerce-playwright-end-to-end-tests), + * we have an admin user and a subscriber user that can both be + * accessed through their ids + * admin user will have id 1 and subscriber user will have id 2 + * neither of these are returned as part of the get all customers call + * unless the role 'all' is passed as a search param + * but they can be accessed by specific id reference */ - const response = await request.put( `/wp-json/wc/v3/customers/1`, { - data: { - first_name: 'admin', + test( 'can retrieve admin user', async ( { request } ) => { + // call API to retrieve the previously saved customer + const response = await request.get( + '/wp-json/wc/v3/customers/1' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.is_paying_customer ).toEqual( false ); + expect( responseJSON.role ).toEqual( 'administrator' ); + // this test was updated to allow for local test setup and other test sites. + expect( responseJSON.username ).toEqual( admin.username ); + } ); + + test( 'can retrieve subscriber user', async ( { request } ) => { + // if environment was created with subscriber user + // call API to retrieve the customer with id 2 + const response = await request.get( + `/wp-json/wc/v3/customers/${ subscriberUserId }` + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.is_paying_customer ).toEqual( false ); + expect( responseJSON.role ).toEqual( 'subscriber' ); + } ); + + test( 'retrieve user with id 0 is invalid', async ( { + request, + } ) => { + // call API to retrieve the previously saved customer + const response = await request.get( + '/wp-json/wc/v3/customers/0' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 404 ); + expect( responseJSON.code ).toEqual( + 'woocommerce_rest_invalid_id' + ); + expect( responseJSON.message ).toEqual( + 'Invalid resource ID.' + ); + } ); + + test( 'can retrieve customers', async ( { request } ) => { + // call API to retrieve all customers should initially return empty array + const response = await request.get( + '/wp-json/wc/v3/customers' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON.length ).toEqual( 1 ); + } ); + + // however, if we pass in the search string for role 'all' then all users are returned + test( 'can retrieve all customers', async ( { request } ) => { + // call API to retrieve all customers should initially return empty array + // unless the role 'all' is passed as a search string, in which case the admin + // and subscriber users will be returned + const response = await request.get( + '/wp-json/wc/v3/customers', + { + params: { + role: 'all', + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON.length ).toBeGreaterThanOrEqual( 3 ); + } ); + } ); + + test.describe( 'Create a customer', () => { + test( 'can create a customer', async ( { request } ) => { + // call API to create a customer + const response = await request.post( + '/wp-json/wc/v3/customers', + { + data: customer, + } + ); + const responseJSON = await response.json(); + + // Save the customer ID. It will be used by the retrieve, update, and delete tests. + customerId = responseJSON.id; + + expect( response.status() ).toEqual( 201 ); + expect( typeof responseJSON.id ).toEqual( 'number' ); + // Verify that the customer role is 'customer' + expect( responseJSON.role ).toEqual( 'customer' ); + } ); + } ); + + test.describe( 'Retrieve after create', () => { + test( 'can retrieve a customer', async ( { request } ) => { + // call API to retrieve the previously saved customer + const response = await request.get( + `/wp-json/wc/v3/customers/${ customerId }` + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.id ).toEqual( customerId ); + expect( responseJSON.is_paying_customer ).toEqual( false ); + expect( responseJSON.role ).toEqual( 'customer' ); + } ); + + test( 'can retrieve all customers after create', async ( { + request, + } ) => { + // call API to retrieve all customers + const response = await request.get( + '/wp-json/wc/v3/customers' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON.length ).toBeGreaterThan( 0 ); + } ); + } ); + + test.describe( 'Update a customer', () => { + test( `can update the admin user/customer`, async ( { + request, + } ) => { + /** + * update customer names (regular, billing and shipping) to admin + * (these were initialised blank when the environment is created, + * (https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/tests/e2e-pw#woocommerce-playwright-end-to-end-tests + */ + const response = await request.put( + `/wp-json/wc/v3/customers/1`, + { + data: { + first_name: 'admin', + billing: { + first_name: 'admin', + }, + shipping: { + first_name: 'admin', + }, + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'admin' ); + expect( responseJSON.billing.first_name ).toEqual( 'admin' ); + expect( responseJSON.shipping.first_name ).toEqual( 'admin' ); + } ); + + test( 'retrieve after update admin', async ( { request } ) => { + // call API to retrieve the admin customer we updated above + const response = await request.get( + '/wp-json/wc/v3/customers/1' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'admin' ); + expect( responseJSON.billing.first_name ).toEqual( 'admin' ); + expect( responseJSON.shipping.first_name ).toEqual( 'admin' ); + } ); + + test( `can update the subscriber user/customer`, async ( { + request, + } ) => { + // update customer names (billing and shipping) to Jane + // (these were initialised blank, only regular first_name was populated) + const response = await request.put( + `/wp-json/wc/v3/customers/${ subscriberUserId }`, + { + data: { + billing: { + first_name: 'Jane', + }, + shipping: { + first_name: 'Jane', + }, + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'Jane' ); + expect( responseJSON.billing.first_name ).toEqual( 'Jane' ); + expect( responseJSON.shipping.first_name ).toEqual( 'Jane' ); + } ); + + test( 'retrieve after update subscriber', async ( { request } ) => { + // call API to retrieve the subscriber customer we updated above + const response = await request.get( + `/wp-json/wc/v3/customers/${ subscriberUserId }` + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'Jane' ); + expect( responseJSON.billing.first_name ).toEqual( 'Jane' ); + expect( responseJSON.shipping.first_name ).toEqual( 'Jane' ); + } ); + + test( `can update a customer`, async ( { request } ) => { + // update customer names (regular, billing and shipping) from John to Jack + const response = await request.put( + `/wp-json/wc/v3/customers/${ customerId }`, + { + data: { + first_name: 'Jack', + billing: { + first_name: 'Jack', + }, + shipping: { + first_name: 'Jack', + }, + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'Jack' ); + expect( responseJSON.billing.first_name ).toEqual( 'Jack' ); + expect( responseJSON.shipping.first_name ).toEqual( 'Jack' ); + } ); + + test( 'retrieve after update customer', async ( { request } ) => { + // call API to retrieve the updated customer we created above + const response = await request.get( + `/wp-json/wc/v3/customers/${ customerId }` + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.first_name ).toEqual( 'Jack' ); + expect( responseJSON.billing.first_name ).toEqual( 'Jack' ); + expect( responseJSON.shipping.first_name ).toEqual( 'Jack' ); + } ); + } ); + + test.describe( 'Delete a customer', () => { + test( 'can permanently delete an customer', async ( { + request, + } ) => { + // Delete the customer. + const response = await request.delete( + `/wp-json/wc/v3/customers/${ customerId }`, + { + data: { + force: true, + }, + } + ); + expect( response.status() ).toEqual( 200 ); + + // Verify that the customer can no longer be retrieved. + const getDeletedCustomerResponse = await request.get( + `/wp-json/wc/v3/customers/${ customer }` + ); + expect( getDeletedCustomerResponse.status() ).toEqual( 404 ); + } ); + } ); + + test.describe( 'Batch update customers', () => { + /** + * 2 Customers to be created in one batch. + */ + const expectedCustomers = [ + { + email: 'john.doe2@example.com', + first_name: 'John', + last_name: 'Doe', + username: 'john.doe2', billing: { - first_name: 'admin', + first_name: 'John', + last_name: 'Doe', + company: '', + address_1: '969 Market', + address_2: '', + city: 'San Francisco', + state: 'CA', + postcode: '94103', + country: 'US', + email: 'john.doe2@example.com', + phone: '(555) 555-5555', }, shipping: { - first_name: 'admin', + first_name: 'John', + last_name: 'Doe', + company: '', + address_1: '969 Market', + address_2: '', + city: 'San Francisco', + state: 'CA', + postcode: '94103', + country: 'US', }, }, - } ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'admin' ); - expect( responseJSON.billing.first_name ).toEqual( 'admin' ); - expect( responseJSON.shipping.first_name ).toEqual( 'admin' ); - } ); - - test( 'retrieve after update admin', async ( { request } ) => { - // call API to retrieve the admin customer we updated above - const response = await request.get( '/wp-json/wc/v3/customers/1' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'admin' ); - expect( responseJSON.billing.first_name ).toEqual( 'admin' ); - expect( responseJSON.shipping.first_name ).toEqual( 'admin' ); - } ); - - test( `can update the subscriber user/customer`, async ( { - request, - } ) => { - // update customer names (billing and shipping) to Jane - // (these were initialised blank, only regular first_name was populated) - const response = await request.put( - `/wp-json/wc/v3/customers/${ subscriberUserId }`, { - data: { - billing: { - first_name: 'Jane', - }, - shipping: { - first_name: 'Jane', - }, - }, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'Jane' ); - expect( responseJSON.billing.first_name ).toEqual( 'Jane' ); - expect( responseJSON.shipping.first_name ).toEqual( 'Jane' ); - } ); - - test( 'retrieve after update subscriber', async ( { request } ) => { - // call API to retrieve the subscriber customer we updated above - const response = await request.get( - `/wp-json/wc/v3/customers/${ subscriberUserId }` - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'Jane' ); - expect( responseJSON.billing.first_name ).toEqual( 'Jane' ); - expect( responseJSON.shipping.first_name ).toEqual( 'Jane' ); - } ); - - test( `can update a customer`, async ( { request } ) => { - // update customer names (regular, billing and shipping) from John to Jack - const response = await request.put( - `/wp-json/wc/v3/customers/${ customerId }`, - { - data: { - first_name: 'Jack', - billing: { - first_name: 'Jack', - }, - shipping: { - first_name: 'Jack', - }, - }, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'Jack' ); - expect( responseJSON.billing.first_name ).toEqual( 'Jack' ); - expect( responseJSON.shipping.first_name ).toEqual( 'Jack' ); - } ); - - test( 'retrieve after update customer', async ( { request } ) => { - // call API to retrieve the updated customer we created above - const response = await request.get( - `/wp-json/wc/v3/customers/${ customerId }` - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.first_name ).toEqual( 'Jack' ); - expect( responseJSON.billing.first_name ).toEqual( 'Jack' ); - expect( responseJSON.shipping.first_name ).toEqual( 'Jack' ); - } ); - } ); - - test.describe( 'Delete a customer', () => { - test( 'can permanently delete an customer', async ( { request } ) => { - // Delete the customer. - const response = await request.delete( - `/wp-json/wc/v3/customers/${ customerId }`, - { - data: { - force: true, - }, - } - ); - expect( response.status() ).toEqual( 200 ); - - // Verify that the customer can no longer be retrieved. - const getDeletedCustomerResponse = await request.get( - `/wp-json/wc/v3/customers/${ customer }` - ); - expect( getDeletedCustomerResponse.status() ).toEqual( 404 ); - } ); - } ); - - test.describe( 'Batch update customers', () => { - /** - * 2 Customers to be created in one batch. - */ - const expectedCustomers = [ - { - email: 'john.doe2@example.com', - first_name: 'John', - last_name: 'Doe', - username: 'john.doe2', - billing: { - first_name: 'John', - last_name: 'Doe', - company: '', - address_1: '969 Market', - address_2: '', - city: 'San Francisco', - state: 'CA', - postcode: '94103', - country: 'US', - email: 'john.doe2@example.com', - phone: '(555) 555-5555', - }, - shipping: { - first_name: 'John', - last_name: 'Doe', - company: '', - address_1: '969 Market', - address_2: '', - city: 'San Francisco', - state: 'CA', - postcode: '94103', - country: 'US', - }, - }, - { - email: 'joao.silva2@example.com', - first_name: 'João', - last_name: 'Silva', - username: 'joao.silva2', - billing: { - first_name: 'João', - last_name: 'Silva', - company: '', - address_1: 'Av. Brasil, 432', - address_2: '', - city: 'Rio de Janeiro', - state: 'RJ', - postcode: '12345-000', - country: 'BR', email: 'joao.silva2@example.com', - phone: '(55) 5555-5555', - }, - shipping: { first_name: 'João', last_name: 'Silva', - company: '', - address_1: 'Av. Brasil, 432', - address_2: '', - city: 'Rio de Janeiro', - state: 'RJ', - postcode: '12345-000', - country: 'BR', + username: 'joao.silva2', + billing: { + first_name: 'João', + last_name: 'Silva', + company: '', + address_1: 'Av. Brasil, 432', + address_2: '', + city: 'Rio de Janeiro', + state: 'RJ', + postcode: '12345-000', + country: 'BR', + email: 'joao.silva2@example.com', + phone: '(55) 5555-5555', + }, + shipping: { + first_name: 'João', + last_name: 'Silva', + company: '', + address_1: 'Av. Brasil, 432', + address_2: '', + city: 'Rio de Janeiro', + state: 'RJ', + postcode: '12345-000', + country: 'BR', + }, }, - }, - ]; + ]; - // set payload to use batch create: action - const batchCreate2CustomersPayload = { - create: expectedCustomers, - }; - - test( 'can batch create customers', async ( { request } ) => { - // Batch create 2 new customers. - // call API to batch create customers - const response = await request.post( - 'wp-json/wc/v3/customers/batch', - { - data: batchCreate2CustomersPayload, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - - // Verify that the 2 new customers were created - const actualCustomers = responseJSON.create; - expect( actualCustomers ).toHaveLength( expectedCustomers.length ); - - for ( let i = 0; i < actualCustomers.length; i++ ) { - const { id, first_name } = actualCustomers[ i ]; - const expectedCustomerName = expectedCustomers[ i ].first_name; - - expect( id ).toBeDefined(); - expect( first_name ).toEqual( expectedCustomerName ); - - // Save the customer id - expectedCustomers[ i ].id = id; - } - } ); - - test( 'can batch update customers', async ( { request } ) => { - // set payload to use batch update: action - const batchUpdatePayload = { - update: [ - { - id: expectedCustomers[ 0 ].id, - email: 'emailupdated@example.com', - }, - { - id: expectedCustomers[ 1 ].id, - billing: { - address_1: '123 Addressupdate Street', - }, - }, - ], + // set payload to use batch create: action + const batchCreate2CustomersPayload = { + create: expectedCustomers, }; - // Call API to update the customers - const response = await request.post( - 'wp-json/wc/v3/customers/batch', - { - data: batchUpdatePayload, - } - ); - const responseJSON = await response.json(); - - // Verify the response code and the number of customers that were updated. - const updatedCustomers = responseJSON.update; - expect( response.status() ).toEqual( 200 ); - expect( updatedCustomers ).toHaveLength( 2 ); - - // Verify that the 1st customer was updated to have a new email address. - expect( updatedCustomers[ 0 ].id ).toEqual( - expectedCustomers[ 0 ].id - ); - expect( updatedCustomers[ 0 ].email ).toEqual( - 'emailupdated@example.com' - ); - - // Verify that the amount of the 2nd customer was updated to have a new billing address. - expect( updatedCustomers[ 1 ].id ).toEqual( - expectedCustomers[ 1 ].id - ); - expect( updatedCustomers[ 1 ].billing.address_1 ).toEqual( - '123 Addressupdate Street' - ); - } ); - - test( 'can batch delete customers', async ( { request } ) => { - // Batch delete the 2 customers. - const customerIdsToDelete = expectedCustomers.map( - ( { id } ) => id - ); - const batchDeletePayload = { - delete: customerIdsToDelete, - }; - - //Call API to batch delete the customers - const response = await request.post( - 'wp-json/wc/v3/customers/batch', - { - data: batchDeletePayload, - } - ); - const responseJSON = await response.json(); - - // Verify that the response shows the 2 customers. - const deletedCustomerIds = responseJSON.delete.map( - ( { id } ) => id - ); - expect( response.status() ).toEqual( 200 ); - expect( deletedCustomerIds ).toEqual( customerIdsToDelete ); - - // Verify that the 2 deleted customers cannot be retrieved. - for ( const id of customerIdsToDelete ) { - //Call the API to attempte to retrieve the customers - const r = await request.get( - `wp-json/wc/v3/customers/${ id }` + test( 'can batch create customers', async ( { request } ) => { + // Batch create 2 new customers. + // call API to batch create customers + const response = await request.post( + 'wp-json/wc/v3/customers/batch', + { + data: batchCreate2CustomersPayload, + } ); - expect( r.status() ).toEqual( 404 ); - } + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + + // Verify that the 2 new customers were created + const actualCustomers = responseJSON.create; + expect( actualCustomers ).toHaveLength( + expectedCustomers.length + ); + + for ( let i = 0; i < actualCustomers.length; i++ ) { + const { id, first_name } = actualCustomers[ i ]; + const expectedCustomerName = + expectedCustomers[ i ].first_name; + + expect( id ).toBeDefined(); + expect( first_name ).toEqual( expectedCustomerName ); + + // Save the customer id + expectedCustomers[ i ].id = id; + } + } ); + + test( 'can batch update customers', async ( { request } ) => { + // set payload to use batch update: action + const batchUpdatePayload = { + update: [ + { + id: expectedCustomers[ 0 ].id, + email: 'emailupdated@example.com', + }, + { + id: expectedCustomers[ 1 ].id, + billing: { + address_1: '123 Addressupdate Street', + }, + }, + ], + }; + + // Call API to update the customers + const response = await request.post( + 'wp-json/wc/v3/customers/batch', + { + data: batchUpdatePayload, + } + ); + const responseJSON = await response.json(); + + // Verify the response code and the number of customers that were updated. + const updatedCustomers = responseJSON.update; + expect( response.status() ).toEqual( 200 ); + expect( updatedCustomers ).toHaveLength( 2 ); + + // Verify that the 1st customer was updated to have a new email address. + expect( updatedCustomers[ 0 ].id ).toEqual( + expectedCustomers[ 0 ].id + ); + expect( updatedCustomers[ 0 ].email ).toEqual( + 'emailupdated@example.com' + ); + + // Verify that the amount of the 2nd customer was updated to have a new billing address. + expect( updatedCustomers[ 1 ].id ).toEqual( + expectedCustomers[ 1 ].id + ); + expect( updatedCustomers[ 1 ].billing.address_1 ).toEqual( + '123 Addressupdate Street' + ); + } ); + + test( 'can batch delete customers', async ( { request } ) => { + // Batch delete the 2 customers. + const customerIdsToDelete = expectedCustomers.map( + ( { id } ) => id + ); + const batchDeletePayload = { + delete: customerIdsToDelete, + }; + + //Call API to batch delete the customers + const response = await request.post( + 'wp-json/wc/v3/customers/batch', + { + data: batchDeletePayload, + } + ); + const responseJSON = await response.json(); + + // Verify that the response shows the 2 customers. + const deletedCustomerIds = responseJSON.delete.map( + ( { id } ) => id + ); + expect( response.status() ).toEqual( 200 ); + expect( deletedCustomerIds ).toEqual( customerIdsToDelete ); + + // Verify that the 2 deleted customers cannot be retrieved. + for ( const id of customerIdsToDelete ) { + //Call the API to attempte to retrieve the customers + const r = await request.get( + `wp-json/wc/v3/customers/${ id }` + ); + expect( r.status() ).toEqual( 404 ); + } + } ); } ); - } ); -} ); + } +); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/order-complex.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/order-complex.test.js index 5308ecdcfa1..90df59a1b9c 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/order-complex.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/order-complex.test.js @@ -208,48 +208,52 @@ test.describe( 'Orders API test', () => { } ); } ); - test( 'can add complex order', async ( { request } ) => { - //ensure tax calculations are enabled - await request.put( - '/wp-json/wc/v3/settings/general/woocommerce_calc_taxes', - { - data: { - value: 'yes', - }, + test( + 'can add complex order', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + async ( { request } ) => { + //ensure tax calculations are enabled + await request.put( + '/wp-json/wc/v3/settings/general/woocommerce_calc_taxes', + { + data: { + value: 'yes', + }, + } + ); + + // Create the complex order and save its ID. + const response = await request.post( '/wp-json/wc/v3/orders', { + data: order, + } ); + const responseJSON = await response.json(); + + order.id = responseJSON.id; + + expect( response.status() ).toEqual( 201 ); + + // Verify order and tax totals + expect( responseJSON.total ).toEqual( expectedOrderTotal ); + expect( responseJSON.total_tax ).toEqual( expectedTaxTotal ); + + // Verify total tax of each product line item + const expectedTaxTotalsPerLineItem = [ + [ simpleProduct, expectedSimpleProductTaxTotal ], + [ variableProduct, expectedVariableProductTaxTotal ], + [ groupedProduct, expectedSimpleProductTaxTotal ], + [ externalProduct, expectedExternalProductTaxTotal ], + ]; + for ( const [ + product, + expectedLineTaxTotal, + ] of expectedTaxTotalsPerLineItem ) { + const { total_tax: actualLineTaxTotal } = + responseJSON.line_items.find( + ( { product_id } ) => product_id === product.id + ); + + expect( actualLineTaxTotal ).toEqual( expectedLineTaxTotal ); } - ); - - // Create the complex order and save its ID. - const response = await request.post( '/wp-json/wc/v3/orders', { - data: order, - } ); - const responseJSON = await response.json(); - - order.id = responseJSON.id; - - expect( response.status() ).toEqual( 201 ); - - // Verify order and tax totals - expect( responseJSON.total ).toEqual( expectedOrderTotal ); - expect( responseJSON.total_tax ).toEqual( expectedTaxTotal ); - - // Verify total tax of each product line item - const expectedTaxTotalsPerLineItem = [ - [ simpleProduct, expectedSimpleProductTaxTotal ], - [ variableProduct, expectedVariableProductTaxTotal ], - [ groupedProduct, expectedSimpleProductTaxTotal ], - [ externalProduct, expectedExternalProductTaxTotal ], - ]; - for ( const [ - product, - expectedLineTaxTotal, - ] of expectedTaxTotalsPerLineItem ) { - const { total_tax: actualLineTaxTotal } = - responseJSON.line_items.find( - ( { product_id } ) => product_id === product.id - ); - - expect( actualLineTaxTotal ).toEqual( expectedLineTaxTotal ); } - } ); + ); } ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/orders.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/orders.test.js index f0164b40982..b6a556ce2de 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/orders.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/orders/orders.test.js @@ -34,3232 +34,3274 @@ const updatedCustomerShipping = { phone: '123456789', }; -test.describe.serial( 'Orders API tests', () => { - let orderId, sampleData; +test.describe.serial( + 'Orders API tests', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + () => { + let orderId, sampleData; - test.beforeAll( async ( { request } ) => { - const createSampleCategories = async () => { - const clothing = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Clothing', - }, - } - ); - const clothingJSON = await clothing.json(); - - const accessories = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Accessories', - parent: clothingJSON.id, - }, - } - ); - const accessoriesJSON = await accessories.json(); - - const hoodies = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Hoodies', - parent: clothingJSON.id, - }, - } - ); - const hoodiesJSON = await hoodies.json(); - - const tshirts = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Tshirts', - parent: clothingJSON.id, - }, - } - ); - const tshirtsJSON = await tshirts.json(); - - const decor = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Decor', - }, - } - ); - const decorJSON = await decor.json(); - - const music = await request.post( - '/wp-json/wc/v3/products/categories', - { - data: { - name: 'Music', - }, - } - ); - const musicJSON = await music.json(); - - return { - clothingJSON, - accessoriesJSON, - hoodiesJSON, - tshirtsJSON, - decorJSON, - musicJSON, - }; - }; - - const createSampleAttributes = async () => { - const color = await request.post( - '/wp-json/wc/v3/products/attributes', - { - data: { - name: 'Color', - }, - } - ); - const colorJSON = await color.json(); - - const size = await request.post( - '/wp-json/wc/v3/products/attributes', - { - data: { - name: 'Size', - }, - } - ); - const sizeJSON = await size.json(); - - const colorNames = [ 'Blue', 'Gray', 'Green', 'Red', 'Yellow' ]; - - const colorNamesObjectArray = colorNames.map( ( name ) => ( { - name, - } ) ); - - const colors = await request.post( - `/wp-json/wc/v3/products/attributes/${ colorJSON.id }/terms/batch`, - { - data: { - create: colorNamesObjectArray, - }, - } - ); - - const colorsJSON = await colors.json(); - - const sizeNames = [ 'Large', 'Medium', 'Small' ]; - - const sizeNamesObjectArray = sizeNames.map( ( name ) => ( { - name, - } ) ); - - const sizes = await request.post( - `/wp-json/wc/v3/products/attributes/${ sizeJSON.id }/terms/batch`, - { - data: { - create: sizeNamesObjectArray, - }, - } - ); - const sizesJSON = await sizes.json(); - - return { - colorJSON, - colors: colorsJSON.create, - sizeJSON, - sizes: sizesJSON.create, - }; - }; - - const createSampleTags = async () => { - const cool = await request.post( '/wp-json/wc/v3/products/tags', { - data: { - name: 'Cool', - }, - } ); - const coolJSON = await cool.json(); - - return { - coolJSON, - }; - }; - - const createSampleShippingClasses = async () => { - const freight = await request.post( - '/wp-json/wc/v3/products/shipping_classes', - { - data: { - name: 'Freight', - }, - } - ); - const freightJSON = await freight.json(); - - return { - freightJSON, - }; - }; - - const createSampleTaxClasses = async () => { - //check to see if Reduced Rate tax class exists - if not, create it - let reducedRate = await request.get( - '/wp-json/wc/v3/taxes/classes/reduced-rate' - ); - let reducedRateJSON = await reducedRate.json(); - expect( Array.isArray( reducedRateJSON ) ).toBe( true ); - - //if tax class does not exist then create it - if ( reducedRateJSON.length < 1 ) { - reducedRate = await request.post( - '/wp-json/wc/v3/taxes/classes', + test.beforeAll( async ( { request } ) => { + const createSampleCategories = async () => { + const clothing = await request.post( + '/wp-json/wc/v3/products/categories', { data: { - name: 'Reduced Rate', + name: 'Clothing', }, } ); - reducedRateJSON = await reducedRate.json(); - return { reducedRateJSON }; - } + const clothingJSON = await clothing.json(); - // return an empty object as nothing new was created so nothing will - // need deleted during cleanup - return {}; - }; - - const createSampleSimpleProducts = async ( - categories, - attributes, - tags - ) => { - const description = - '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + - 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. ' + - 'Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n'; - - const simpleProducts = await request.post( - '/wp-json/wc/v3/products/batch', - { - data: { - create: [ - { - name: 'Beanie with Logo oxo', - date_created_gmt: '2021-09-01T15:50:20', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'Woo-beanie-logo', - price: '18', - regular_price: '20', - sale_price: '18', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.2', - dimensions: { - length: '6', - width: '4', - height: '1', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.accessoriesJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Red' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 62, 63, 61, 60 ], - stock_status: 'instock', - }, - { - name: 'T-Shirt with Logo oxo', - date_created_gmt: '2021-09-02T15:50:20', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'Woo-tshirt-logo', - price: '18', - regular_price: '18', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.5', - dimensions: { - length: '10', - width: '12', - height: '0.5', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.tshirtsJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Gray' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 59, 67, 66, 56 ], - stock_status: 'instock', - }, - { - name: 'Single oxo', - date_created_gmt: '2021-09-03T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple, virtual product.

\n', - sku: 'woo-single', - price: '2', - regular_price: '3', - sale_price: '2', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: true, - downloadable: true, - downloads: [ - { - id: '2579cf07-8b08-4c25-888a-b6258dd1f035', - name: 'Single', - file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg', - }, - ], - download_limit: 1, - download_expiry: 1, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '', - dimensions: { - length: '', - width: '', - height: '', - }, - shipping_required: false, - shipping_taxable: false, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.musicJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 68 ], - stock_status: 'instock', - }, - { - name: 'Album oxo', - date_created_gmt: '2021-09-04T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple, virtual product.

\n', - sku: 'woo-album', - price: '15', - regular_price: '15', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: true, - downloadable: true, - downloads: [ - { - id: 'cc10249f-1de2-44d4-93d3-9f88ae629f76', - name: 'Single 1', - file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg', - }, - { - id: 'aea8ef69-ccdc-4d83-8e21-3c395ebb9411', - name: 'Single 2', - file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg', - }, - ], - download_limit: 1, - download_expiry: 1, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '', - dimensions: { - length: '', - width: '', - height: '', - }, - shipping_required: false, - shipping_taxable: false, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.musicJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 69 ], - stock_status: 'instock', - }, - { - name: 'Polo oxo', - date_created_gmt: '2021-09-05T15:50:19', - type: 'simple', - status: 'pending', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-polo', - price: '20', - regular_price: '20', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.8', - dimensions: { - length: '6', - width: '5', - height: '1', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.tshirtsJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Blue' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 59, 56, 66, 76 ], - stock_status: 'instock', - }, - { - name: 'Long Sleeve Tee oxo', - date_created_gmt: '2021-09-06T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-long-sleeve-tee', - price: '25', - regular_price: '25', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '1', - dimensions: { - length: '7', - width: '5', - height: '1', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: 'freight', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.tshirtsJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Green' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 59, 56, 76, 67 ], - stock_status: 'instock', - }, - { - name: 'Hoodie with Zipper oxo', - date_created_gmt: '2021-09-07T15:50:19', - type: 'simple', - status: 'publish', - featured: true, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-hoodie-with-zipper', - price: '45', - regular_price: '45', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '2', - dimensions: { - length: '8', - width: '6', - height: '2', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.hoodiesJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 57, 58 ], - stock_status: 'instock', - }, - { - name: 'Hoodie with Pocket oxo', - date_created_gmt: '2021-09-08T15:50:19', - type: 'simple', - status: 'publish', - featured: true, - catalog_visibility: 'hidden', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-hoodie-with-pocket', - price: '35', - regular_price: '45', - sale_price: '35', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '3', - dimensions: { - length: '10', - width: '8', - height: '2', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.hoodiesJSON.id, - }, - ], - tags: [ - { - id: tags.coolJSON.id, - }, - ], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Gray' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 65, 57, 58 ], - stock_status: 'instock', - }, - { - name: 'Sunglasses oxo', - date_created_gmt: '2021-09-09T15:50:19', - type: 'simple', - status: 'publish', - featured: true, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-sunglasses', - price: '90', - regular_price: '90', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: 'reduced-rate', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.2', - dimensions: { - length: '4', - width: '1.4', - height: '1', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.accessoriesJSON.id, - }, - ], - tags: [ - { - id: tags.coolJSON.id, - }, - ], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 60, 62, 77, 61 ], - stock_status: 'instock', - }, - { - name: 'Cap oxo', - date_created_gmt: '2021-09-10T15:50:19', - type: 'simple', - status: 'publish', - featured: true, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-cap', - price: '16', - regular_price: '18', - sale_price: '16', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.6', - dimensions: { - length: '8', - width: '6.5', - height: '4', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.accessoriesJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Yellow' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 60, 77, 61, 63 ], - stock_status: 'instock', - }, - { - name: 'Belt oxo', - date_created_gmt: '2021-09-12T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-belt', - price: '55', - regular_price: '65', - sale_price: '55', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '1.2', - dimensions: { - length: '12', - width: '2', - height: '1.5', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.accessoriesJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 63, 77, 62, 60 ], - stock_status: 'instock', - }, - { - name: 'Beanie oxo', - date_created_gmt: '2021-09-13T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-beanie', - price: '18', - regular_price: '20', - sale_price: '18', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.2', - dimensions: { - length: '4', - width: '5', - height: '0.5', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.accessoriesJSON.id, - }, - ], - tags: [ - { - id: tags.coolJSON.id, - }, - ], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Red' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 63, 62, 61, 77 ], - stock_status: 'instock', - }, - { - name: 'T-Shirt oxo', - date_created_gmt: '2021-09-14T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-tshirt', - price: '18', - regular_price: '18', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.8', - dimensions: { - length: '8', - width: '6', - height: '1', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.tshirtsJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Gray' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 67, 76, 56, 66 ], - stock_status: 'onbackorder', - }, - { - name: 'Hoodie with Logo oxo', - date_created_gmt: '2021-09-15T15:50:19', - type: 'simple', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: - '

This is a simple product.

\n', - sku: 'woo-hoodie-with-logo', - price: '45', - regular_price: '45', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '2', - dimensions: { - length: '10', - width: '6', - height: '3', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.hoodiesJSON.id, - }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: false, - options: [ 'Blue' ], - }, - ], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [ 57, 65 ], - stock_status: 'instock', - }, - ], - }, - } - ); - const simpleProductsJSON = await simpleProducts.json(); - - return simpleProductsJSON.create; - }; - - const createSampleExternalProducts = async ( categories ) => { - const externalProducts = await request.post( - '/wp-json/wc/v3/products/batch', - { - data: { - create: [ - { - name: 'WordPress Pennant oxo', - date_created_gmt: '2021-09-16T15:50:20', - type: 'external', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description: - '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + - 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + - 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n', - short_description: - '

This is an external product.

\n', - sku: 'wp-pennant', - price: '11.05', - regular_price: '11.05', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: false, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: - 'https://mercantile.wordpress.org/product/wordpress-pennant/', - button_text: 'Buy on the WordPress swag store!', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '', - dimensions: { - length: '', - width: '', - height: '', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.decorJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: [], - menu_order: 0, - related_ids: [], - stock_status: 'instock', - }, - ], - }, - } - ); - const externalProductsJSON = await externalProducts.json(); - - return externalProductsJSON.create; - }; - - const createSampleGroupedProduct = async ( categories ) => { - const logoProducts = await request.get( '/wp-json/wc/v3/products', { - params: { - search: 'logo', - _fields: [ 'id' ], - }, - } ); - const logoProductsJSON = await logoProducts.json(); - - const groupedProducts = await request.post( - '/wp-json/wc/v3/products/batch', - { - data: { - create: [ - { - name: 'Logo Collection oxo', - date_created_gmt: '2021-09-17T15:50:20', - type: 'grouped', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description: - '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + - 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + - 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n', - short_description: - '

This is a grouped product.

\n', - sku: 'logo-collection', - price: '18', - regular_price: '', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: false, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '', - dimensions: { - length: '', - width: '', - height: '', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.clothingJSON.id, - }, - ], - tags: [], - attributes: [], - default_attributes: [], - variations: [], - grouped_products: logoProductsJSON.map( - ( p ) => p.id - ), - menu_order: 0, - related_ids: [], - stock_status: 'instock', - }, - ], - }, - } - ); - const groupedProductsJSON = await groupedProducts.json(); - - return groupedProductsJSON.create; - }; - - const createSampleVariableProducts = async ( - categories, - attributes - ) => { - const description = - '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + - 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + - 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n'; - - const hoodie = await request.post( '/wp-json/wc/v3/products', { - data: { - name: 'Hoodie oxo', - date_created_gmt: '2021-09-18T15:50:19', - type: 'variable', - status: 'publish', - featured: false, - catalog_visibility: 'visible', - description, - short_description: '

This is a variable product.

\n', - sku: 'woo-hoodie', - price: '42', - regular_price: '', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '1.5', - dimensions: { - length: '10', - width: '8', - height: '3', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.hoodiesJSON.id, + const accessories = await request.post( + '/wp-json/wc/v3/products/categories', + { + data: { + name: 'Accessories', + parent: clothingJSON.id, }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: true, - options: [ 'Blue', 'Green', 'Red' ], - }, - { - id: 0, - name: 'Logo', - position: 1, - visible: true, - variation: true, - options: [ 'Yes', 'No' ], - }, - ], - default_attributes: [], - grouped_products: [], - menu_order: 0, - stock_status: 'instock', - }, - } ); - const hoodieJSON = await hoodie.json(); + } + ); + const accessoriesJSON = await accessories.json(); - const variationDescription = - '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. ' + - 'Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. ' + - 'Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. ' + - 'Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. ' + - 'Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. ' + - 'Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.

\n'; - - const hoodieVariations = await request.post( - `/wp-json/wc/v3/products/${ hoodieJSON.id }/variations/batch`, - { - data: { - create: [ - { - date_created_gmt: '2021-09-19T15:50:20', - description: variationDescription, - sku: 'woo-hoodie-blue-logo', - price: '45', - regular_price: '45', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '1.5', - dimensions: { - length: '10', - width: '8', - height: '3', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Blue', - }, - { - id: 0, - name: 'Logo', - option: 'Yes', - }, - ], - menu_order: 0, - }, - { - date_created_gmt: '2021-09-20T15:50:20', - description: variationDescription, - sku: 'woo-hoodie-blue', - price: '45', - regular_price: '45', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '1.5', - dimensions: { - length: '10', - width: '8', - height: '3', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Blue', - }, - { - id: 0, - name: 'Logo', - option: 'No', - }, - ], - menu_order: 3, - }, - { - date_created_gmt: '2021-09-21T15:50:20', - description: variationDescription, - sku: 'woo-hoodie-green', - price: '45', - regular_price: '45', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '1.5', - dimensions: { - length: '10', - width: '8', - height: '3', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Green', - }, - { - id: 0, - name: 'Logo', - option: 'No', - }, - ], - menu_order: 2, - }, - { - date_created_gmt: '2021-09-22T15:50:19', - description: variationDescription, - sku: 'woo-hoodie-red', - price: '42', - regular_price: '45', - sale_price: '42', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: true, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '1.5', - dimensions: { - length: '10', - width: '8', - height: '3', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Red', - }, - { - id: 0, - name: 'Logo', - option: 'No', - }, - ], - menu_order: 1, - }, - ], - }, - } - ); - const hoodieVariationsJSON = await hoodieVariations.json(); - - const vneck = await request.post( '/wp-json/wc/v3/products', { - data: { - name: 'V-Neck T-Shirt oxo', - date_created_gmt: '2021-09-23T15:50:19', - type: 'variable', - status: 'publish', - featured: true, - catalog_visibility: 'visible', - description, - short_description: '

This is a variable product.

\n', - sku: 'woo-vneck-tee', - price: '15', - regular_price: '', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - purchasable: true, - total_sales: 0, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - external_url: '', - button_text: '', - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - sold_individually: false, - weight: '0.5', - dimensions: { - length: '24', - width: '1', - height: '2', - }, - shipping_required: true, - shipping_taxable: true, - shipping_class: '', - reviews_allowed: true, - average_rating: '0.00', - rating_count: 0, - upsell_ids: [], - cross_sell_ids: [], - parent_id: 0, - purchase_note: '', - categories: [ - { - id: categories.tshirtsJSON.id, + const hoodies = await request.post( + '/wp-json/wc/v3/products/categories', + { + data: { + name: 'Hoodies', + parent: clothingJSON.id, }, - ], - tags: [], - attributes: [ - { - id: attributes.colorJSON.id, - position: 0, - visible: true, - variation: true, - options: [ 'Blue', 'Green', 'Red' ], - }, - { - id: attributes.sizeJSON.id, - position: 1, - visible: true, - variation: true, - options: [ 'Large', 'Medium', 'Small' ], - }, - ], - default_attributes: [], - grouped_products: [], - menu_order: 0, - stock_status: 'instock', - }, - } ); - const vneckJSON = await vneck.json(); + } + ); + const hoodiesJSON = await hoodies.json(); - const vneckVariations = await request.post( - `/wp-json/wc/v3/products/${ vneckJSON.id }/variations/batch`, - { - data: { - create: [ - { - date_created_gmt: '2021-09-24T15:50:19', - description: variationDescription, - sku: 'woo-vneck-tee-blue', - price: '15', - regular_price: '15', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '0.5', - dimensions: { - length: '24', - width: '1', - height: '2', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Blue', - }, - ], - menu_order: 0, - }, - { - date_created_gmt: '2021-09-25T15:50:19', - description: variationDescription, - sku: 'woo-vneck-tee-green', - price: '20', - regular_price: '20', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '0.5', - dimensions: { - length: '24', - width: '1', - height: '2', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Green', - }, - ], - menu_order: 0, - }, - { - date_created_gmt: '2021-09-26T15:50:19', - description: variationDescription, - sku: 'woo-vneck-tee-red', - price: '20', - regular_price: '20', - sale_price: '', - date_on_sale_from_gmt: null, - date_on_sale_to_gmt: null, - on_sale: false, - status: 'publish', - purchasable: true, - virtual: false, - downloadable: false, - downloads: [], - download_limit: 0, - download_expiry: 0, - tax_status: 'taxable', - tax_class: '', - manage_stock: false, - stock_quantity: null, - stock_status: 'instock', - backorders: 'no', - backorders_allowed: false, - backordered: false, - low_stock_amount: null, - weight: '0.5', - dimensions: { - length: '24', - width: '1', - height: '2', - }, - shipping_class: '', - attributes: [ - { - id: attributes.colorJSON.id, - option: 'Red', - }, - ], - menu_order: 0, - }, - ], - }, - } - ); - const vneckVariationsJSON = await vneckVariations.json(); + const tshirts = await request.post( + '/wp-json/wc/v3/products/categories', + { + data: { + name: 'Tshirts', + parent: clothingJSON.id, + }, + } + ); + const tshirtsJSON = await tshirts.json(); - return { - hoodieJSON, - hoodieVariations: hoodieVariationsJSON.create, - vneckJSON, - vneckVariations: vneckVariationsJSON.create, + const decor = await request.post( + '/wp-json/wc/v3/products/categories', + { + data: { + name: 'Decor', + }, + } + ); + const decorJSON = await decor.json(); + + const music = await request.post( + '/wp-json/wc/v3/products/categories', + { + data: { + name: 'Music', + }, + } + ); + const musicJSON = await music.json(); + + return { + clothingJSON, + accessoriesJSON, + hoodiesJSON, + tshirtsJSON, + decorJSON, + musicJSON, + }; }; - }; - const createSampleHierarchicalProducts = async () => { - const parent = await request.post( '/wp-json/wc/v3/products', { - data: { - name: 'Parent Product oxo', - date_created_gmt: '2021-09-27T15:50:19', - }, - } ); - const parentJSON = await parent.json(); + const createSampleAttributes = async () => { + const color = await request.post( + '/wp-json/wc/v3/products/attributes', + { + data: { + name: 'Color', + }, + } + ); + const colorJSON = await color.json(); - const child = await request.post( '/wp-json/wc/v3/products', { - data: { - name: 'Child Product oxo', - parent_id: parentJSON.id, - date_created_gmt: '2021-09-28T15:50:19', - }, - } ); - const childJSON = await child.json(); + const size = await request.post( + '/wp-json/wc/v3/products/attributes', + { + data: { + name: 'Size', + }, + } + ); + const sizeJSON = await size.json(); - return { - parentJSON, - childJSON, + const colorNames = [ 'Blue', 'Gray', 'Green', 'Red', 'Yellow' ]; + + const colorNamesObjectArray = colorNames.map( ( name ) => ( { + name, + } ) ); + + const colors = await request.post( + `/wp-json/wc/v3/products/attributes/${ colorJSON.id }/terms/batch`, + { + data: { + create: colorNamesObjectArray, + }, + } + ); + + const colorsJSON = await colors.json(); + + const sizeNames = [ 'Large', 'Medium', 'Small' ]; + + const sizeNamesObjectArray = sizeNames.map( ( name ) => ( { + name, + } ) ); + + const sizes = await request.post( + `/wp-json/wc/v3/products/attributes/${ sizeJSON.id }/terms/batch`, + { + data: { + create: sizeNamesObjectArray, + }, + } + ); + const sizesJSON = await sizes.json(); + + return { + colorJSON, + colors: colorsJSON.create, + sizeJSON, + sizes: sizesJSON.create, + }; }; - }; - const createSampleProductReviews = async ( simpleProducts ) => { - const cap = simpleProducts.find( ( p ) => p.name === 'Cap oxo' ); - - const shirt = simpleProducts.find( - ( p ) => p.name === 'T-Shirt oxo' - ); - - const sunglasses = simpleProducts.find( - ( p ) => p.name === 'Sunglasses oxo' - ); - - const review1 = await request.post( - '/wp-json/wc/v3/products/reviews', - { - data: { - product_id: cap.id, - rating: 3, - review: 'Decent cap.', - reviewer: 'John Doe', - reviewer_email: 'john.doe@example.com', - }, - } - ); - const review1JSON = await review1.json(); - - // We need to update the review in order for the product's - // average_rating to be recalculated. - // See: https://github.com/woocommerce/woocommerce/issues/29906. - //await updateProductReview(review1.id); - await request.post( - `/wp-json/wc/v3/products/reviews/${ review1JSON.id }`, - { - data: {}, - } - ); - - const review2 = await request.post( - '/wp-json/wc/v3/products/reviews', - { - data: { - product_id: shirt.id, - rating: 5, - review: 'The BEST shirt ever!!', - reviewer: 'Shannon Smith', - reviewer_email: 'shannon.smith@example.com', - }, - } - ); - const review2JSON = await review2.json(); - - //await updateProductReview(review2.id); - await request.post( - `/wp-json/wc/v3/products/reviews/${ review2JSON.id }`, - { - data: {}, - } - ); - - const review3 = await request.post( - '/wp-json/wc/v3/products/reviews', - { - data: { - product_id: sunglasses.id, - rating: 1, - review: 'These are way too expensive.', - reviewer: 'Tim Frugalman', - reviewer_email: 'timmyfrufru@example.com', - }, - } - ); - const review3JSON = await review3.json(); - - await request.post( - `/wp-json/wc/v3/products/reviews/${ review3JSON.id }`, - { - data: {}, - } - ); - - return [ review1JSON.id, review2JSON.id, review3JSON.id ]; - }; - - const createSampleProductOrders = async ( simpleProducts ) => { - const single = simpleProducts.find( - ( p ) => p.name === 'Single oxo' - ); - const beanie = simpleProducts.find( - ( p ) => p.name === 'Beanie with Logo oxo' - ); - const shirt = simpleProducts.find( - ( p ) => p.name === 'T-Shirt oxo' - ); - - const order1 = await request.post( '/wp-json/wc/v3/orders', { - data: { - set_paid: true, - status: 'completed', - line_items: [ - { - product_id: single.id, - quantity: 2, + const createSampleTags = async () => { + const cool = await request.post( + '/wp-json/wc/v3/products/tags', + { + data: { + name: 'Cool', }, - { - product_id: beanie.id, - quantity: 3, + } + ); + const coolJSON = await cool.json(); + + return { + coolJSON, + }; + }; + + const createSampleShippingClasses = async () => { + const freight = await request.post( + '/wp-json/wc/v3/products/shipping_classes', + { + data: { + name: 'Freight', }, + } + ); + const freightJSON = await freight.json(); + + return { + freightJSON, + }; + }; + + const createSampleTaxClasses = async () => { + //check to see if Reduced Rate tax class exists - if not, create it + let reducedRate = await request.get( + '/wp-json/wc/v3/taxes/classes/reduced-rate' + ); + let reducedRateJSON = await reducedRate.json(); + expect( Array.isArray( reducedRateJSON ) ).toBe( true ); + + //if tax class does not exist then create it + if ( reducedRateJSON.length < 1 ) { + reducedRate = await request.post( + '/wp-json/wc/v3/taxes/classes', { - product_id: shirt.id, - quantity: 1, - }, - ], - }, - } ); - const orderJSON = await order1.json(); + data: { + name: 'Reduced Rate', + }, + } + ); + reducedRateJSON = await reducedRate.json(); + return { reducedRateJSON }; + } - return [ orderJSON ]; - }; + // return an empty object as nothing new was created so nothing will + // need deleted during cleanup + return {}; + }; - const productsTestSetupCreateSampleData = async () => { - const categories = await createSampleCategories(); - - const attributes = await createSampleAttributes(); - - const tags = await createSampleTags(); - - const shippingClasses = await createSampleShippingClasses(); - - const taxClasses = await createSampleTaxClasses(); - - const simpleProducts = await createSampleSimpleProducts( + const createSampleSimpleProducts = async ( categories, attributes, tags - ); + ) => { + const description = + '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + + 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. ' + + 'Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n'; - const externalProducts = await createSampleExternalProducts( - categories - ); + const simpleProducts = await request.post( + '/wp-json/wc/v3/products/batch', + { + data: { + create: [ + { + name: 'Beanie with Logo oxo', + date_created_gmt: '2021-09-01T15:50:20', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'Woo-beanie-logo', + price: '18', + regular_price: '20', + sale_price: '18', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.2', + dimensions: { + length: '6', + width: '4', + height: '1', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.accessoriesJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Red' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 62, 63, 61, 60 ], + stock_status: 'instock', + }, + { + name: 'T-Shirt with Logo oxo', + date_created_gmt: '2021-09-02T15:50:20', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'Woo-tshirt-logo', + price: '18', + regular_price: '18', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.5', + dimensions: { + length: '10', + width: '12', + height: '0.5', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.tshirtsJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Gray' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 59, 67, 66, 56 ], + stock_status: 'instock', + }, + { + name: 'Single oxo', + date_created_gmt: '2021-09-03T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple, virtual product.

\n', + sku: 'woo-single', + price: '2', + regular_price: '3', + sale_price: '2', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: true, + downloadable: true, + downloads: [ + { + id: '2579cf07-8b08-4c25-888a-b6258dd1f035', + name: 'Single', + file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg', + }, + ], + download_limit: 1, + download_expiry: 1, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '', + dimensions: { + length: '', + width: '', + height: '', + }, + shipping_required: false, + shipping_taxable: false, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.musicJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 68 ], + stock_status: 'instock', + }, + { + name: 'Album oxo', + date_created_gmt: '2021-09-04T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple, virtual product.

\n', + sku: 'woo-album', + price: '15', + regular_price: '15', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: true, + downloadable: true, + downloads: [ + { + id: 'cc10249f-1de2-44d4-93d3-9f88ae629f76', + name: 'Single 1', + file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg', + }, + { + id: 'aea8ef69-ccdc-4d83-8e21-3c395ebb9411', + name: 'Single 2', + file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg', + }, + ], + download_limit: 1, + download_expiry: 1, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '', + dimensions: { + length: '', + width: '', + height: '', + }, + shipping_required: false, + shipping_taxable: false, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.musicJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 69 ], + stock_status: 'instock', + }, + { + name: 'Polo oxo', + date_created_gmt: '2021-09-05T15:50:19', + type: 'simple', + status: 'pending', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-polo', + price: '20', + regular_price: '20', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.8', + dimensions: { + length: '6', + width: '5', + height: '1', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.tshirtsJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Blue' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 59, 56, 66, 76 ], + stock_status: 'instock', + }, + { + name: 'Long Sleeve Tee oxo', + date_created_gmt: '2021-09-06T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-long-sleeve-tee', + price: '25', + regular_price: '25', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '1', + dimensions: { + length: '7', + width: '5', + height: '1', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: 'freight', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.tshirtsJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Green' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 59, 56, 76, 67 ], + stock_status: 'instock', + }, + { + name: 'Hoodie with Zipper oxo', + date_created_gmt: '2021-09-07T15:50:19', + type: 'simple', + status: 'publish', + featured: true, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-hoodie-with-zipper', + price: '45', + regular_price: '45', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '2', + dimensions: { + length: '8', + width: '6', + height: '2', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.hoodiesJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 57, 58 ], + stock_status: 'instock', + }, + { + name: 'Hoodie with Pocket oxo', + date_created_gmt: '2021-09-08T15:50:19', + type: 'simple', + status: 'publish', + featured: true, + catalog_visibility: 'hidden', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-hoodie-with-pocket', + price: '35', + regular_price: '45', + sale_price: '35', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '3', + dimensions: { + length: '10', + width: '8', + height: '2', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.hoodiesJSON.id, + }, + ], + tags: [ + { + id: tags.coolJSON.id, + }, + ], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Gray' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 65, 57, 58 ], + stock_status: 'instock', + }, + { + name: 'Sunglasses oxo', + date_created_gmt: '2021-09-09T15:50:19', + type: 'simple', + status: 'publish', + featured: true, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-sunglasses', + price: '90', + regular_price: '90', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: 'reduced-rate', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.2', + dimensions: { + length: '4', + width: '1.4', + height: '1', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.accessoriesJSON.id, + }, + ], + tags: [ + { + id: tags.coolJSON.id, + }, + ], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 60, 62, 77, 61 ], + stock_status: 'instock', + }, + { + name: 'Cap oxo', + date_created_gmt: '2021-09-10T15:50:19', + type: 'simple', + status: 'publish', + featured: true, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-cap', + price: '16', + regular_price: '18', + sale_price: '16', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.6', + dimensions: { + length: '8', + width: '6.5', + height: '4', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.accessoriesJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Yellow' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 60, 77, 61, 63 ], + stock_status: 'instock', + }, + { + name: 'Belt oxo', + date_created_gmt: '2021-09-12T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-belt', + price: '55', + regular_price: '65', + sale_price: '55', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '1.2', + dimensions: { + length: '12', + width: '2', + height: '1.5', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.accessoriesJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 63, 77, 62, 60 ], + stock_status: 'instock', + }, + { + name: 'Beanie oxo', + date_created_gmt: '2021-09-13T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-beanie', + price: '18', + regular_price: '20', + sale_price: '18', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.2', + dimensions: { + length: '4', + width: '5', + height: '0.5', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.accessoriesJSON.id, + }, + ], + tags: [ + { + id: tags.coolJSON.id, + }, + ], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Red' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 63, 62, 61, 77 ], + stock_status: 'instock', + }, + { + name: 'T-Shirt oxo', + date_created_gmt: '2021-09-14T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-tshirt', + price: '18', + regular_price: '18', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.8', + dimensions: { + length: '8', + width: '6', + height: '1', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.tshirtsJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Gray' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 67, 76, 56, 66 ], + stock_status: 'onbackorder', + }, + { + name: 'Hoodie with Logo oxo', + date_created_gmt: '2021-09-15T15:50:19', + type: 'simple', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a simple product.

\n', + sku: 'woo-hoodie-with-logo', + price: '45', + regular_price: '45', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '2', + dimensions: { + length: '10', + width: '6', + height: '3', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.hoodiesJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: false, + options: [ 'Blue' ], + }, + ], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [ 57, 65 ], + stock_status: 'instock', + }, + ], + }, + } + ); + const simpleProductsJSON = await simpleProducts.json(); - const groupedProducts = await createSampleGroupedProduct( - categories - ); + return simpleProductsJSON.create; + }; - const variableProducts = await createSampleVariableProducts( + const createSampleExternalProducts = async ( categories ) => { + const externalProducts = await request.post( + '/wp-json/wc/v3/products/batch', + { + data: { + create: [ + { + name: 'WordPress Pennant oxo', + date_created_gmt: '2021-09-16T15:50:20', + type: 'external', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description: + '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + + 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + + 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n', + short_description: + '

This is an external product.

\n', + sku: 'wp-pennant', + price: '11.05', + regular_price: '11.05', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: false, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: + 'https://mercantile.wordpress.org/product/wordpress-pennant/', + button_text: + 'Buy on the WordPress swag store!', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '', + dimensions: { + length: '', + width: '', + height: '', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.decorJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: [], + menu_order: 0, + related_ids: [], + stock_status: 'instock', + }, + ], + }, + } + ); + const externalProductsJSON = await externalProducts.json(); + + return externalProductsJSON.create; + }; + + const createSampleGroupedProduct = async ( categories ) => { + const logoProducts = await request.get( + '/wp-json/wc/v3/products', + { + params: { + search: 'logo', + _fields: [ 'id' ], + }, + } + ); + const logoProductsJSON = await logoProducts.json(); + + const groupedProducts = await request.post( + '/wp-json/wc/v3/products/batch', + { + data: { + create: [ + { + name: 'Logo Collection oxo', + date_created_gmt: '2021-09-17T15:50:20', + type: 'grouped', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description: + '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + + 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + + 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n', + short_description: + '

This is a grouped product.

\n', + sku: 'logo-collection', + price: '18', + regular_price: '', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: false, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '', + dimensions: { + length: '', + width: '', + height: '', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.clothingJSON.id, + }, + ], + tags: [], + attributes: [], + default_attributes: [], + variations: [], + grouped_products: logoProductsJSON.map( + ( p ) => p.id + ), + menu_order: 0, + related_ids: [], + stock_status: 'instock', + }, + ], + }, + } + ); + const groupedProductsJSON = await groupedProducts.json(); + + return groupedProductsJSON.create; + }; + + const createSampleVariableProducts = async ( categories, attributes - ); + ) => { + const description = + '

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' + + 'Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. ' + + 'Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

\n'; - const hierarchicalProducts = - await createSampleHierarchicalProducts(); + const hoodie = await request.post( '/wp-json/wc/v3/products', { + data: { + name: 'Hoodie oxo', + date_created_gmt: '2021-09-18T15:50:19', + type: 'variable', + status: 'publish', + featured: false, + catalog_visibility: 'visible', + description, + short_description: + '

This is a variable product.

\n', + sku: 'woo-hoodie', + price: '42', + regular_price: '', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '1.5', + dimensions: { + length: '10', + width: '8', + height: '3', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.hoodiesJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: true, + options: [ 'Blue', 'Green', 'Red' ], + }, + { + id: 0, + name: 'Logo', + position: 1, + visible: true, + variation: true, + options: [ 'Yes', 'No' ], + }, + ], + default_attributes: [], + grouped_products: [], + menu_order: 0, + stock_status: 'instock', + }, + } ); + const hoodieJSON = await hoodie.json(); - const reviewIds = await createSampleProductReviews( - simpleProducts - ); + const variationDescription = + '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. ' + + 'Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. ' + + 'Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. ' + + 'Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. ' + + 'Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. ' + + 'Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.

\n'; - const orders = await createSampleProductOrders( simpleProducts ); + const hoodieVariations = await request.post( + `/wp-json/wc/v3/products/${ hoodieJSON.id }/variations/batch`, + { + data: { + create: [ + { + date_created_gmt: '2021-09-19T15:50:20', + description: variationDescription, + sku: 'woo-hoodie-blue-logo', + price: '45', + regular_price: '45', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '1.5', + dimensions: { + length: '10', + width: '8', + height: '3', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Blue', + }, + { + id: 0, + name: 'Logo', + option: 'Yes', + }, + ], + menu_order: 0, + }, + { + date_created_gmt: '2021-09-20T15:50:20', + description: variationDescription, + sku: 'woo-hoodie-blue', + price: '45', + regular_price: '45', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '1.5', + dimensions: { + length: '10', + width: '8', + height: '3', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Blue', + }, + { + id: 0, + name: 'Logo', + option: 'No', + }, + ], + menu_order: 3, + }, + { + date_created_gmt: '2021-09-21T15:50:20', + description: variationDescription, + sku: 'woo-hoodie-green', + price: '45', + regular_price: '45', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '1.5', + dimensions: { + length: '10', + width: '8', + height: '3', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Green', + }, + { + id: 0, + name: 'Logo', + option: 'No', + }, + ], + menu_order: 2, + }, + { + date_created_gmt: '2021-09-22T15:50:19', + description: variationDescription, + sku: 'woo-hoodie-red', + price: '42', + regular_price: '45', + sale_price: '42', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: true, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '1.5', + dimensions: { + length: '10', + width: '8', + height: '3', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Red', + }, + { + id: 0, + name: 'Logo', + option: 'No', + }, + ], + menu_order: 1, + }, + ], + }, + } + ); + const hoodieVariationsJSON = await hoodieVariations.json(); - return { - categories, - attributes, - tags, - shippingClasses, - taxClasses, - simpleProducts, - externalProducts, - groupedProducts, - variableProducts, - hierarchicalProducts, - reviewIds, - orders, + const vneck = await request.post( '/wp-json/wc/v3/products', { + data: { + name: 'V-Neck T-Shirt oxo', + date_created_gmt: '2021-09-23T15:50:19', + type: 'variable', + status: 'publish', + featured: true, + catalog_visibility: 'visible', + description, + short_description: + '

This is a variable product.

\n', + sku: 'woo-vneck-tee', + price: '15', + regular_price: '', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + purchasable: true, + total_sales: 0, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + external_url: '', + button_text: '', + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + sold_individually: false, + weight: '0.5', + dimensions: { + length: '24', + width: '1', + height: '2', + }, + shipping_required: true, + shipping_taxable: true, + shipping_class: '', + reviews_allowed: true, + average_rating: '0.00', + rating_count: 0, + upsell_ids: [], + cross_sell_ids: [], + parent_id: 0, + purchase_note: '', + categories: [ + { + id: categories.tshirtsJSON.id, + }, + ], + tags: [], + attributes: [ + { + id: attributes.colorJSON.id, + position: 0, + visible: true, + variation: true, + options: [ 'Blue', 'Green', 'Red' ], + }, + { + id: attributes.sizeJSON.id, + position: 1, + visible: true, + variation: true, + options: [ 'Large', 'Medium', 'Small' ], + }, + ], + default_attributes: [], + grouped_products: [], + menu_order: 0, + stock_status: 'instock', + }, + } ); + const vneckJSON = await vneck.json(); + + const vneckVariations = await request.post( + `/wp-json/wc/v3/products/${ vneckJSON.id }/variations/batch`, + { + data: { + create: [ + { + date_created_gmt: '2021-09-24T15:50:19', + description: variationDescription, + sku: 'woo-vneck-tee-blue', + price: '15', + regular_price: '15', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '0.5', + dimensions: { + length: '24', + width: '1', + height: '2', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Blue', + }, + ], + menu_order: 0, + }, + { + date_created_gmt: '2021-09-25T15:50:19', + description: variationDescription, + sku: 'woo-vneck-tee-green', + price: '20', + regular_price: '20', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '0.5', + dimensions: { + length: '24', + width: '1', + height: '2', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Green', + }, + ], + menu_order: 0, + }, + { + date_created_gmt: '2021-09-26T15:50:19', + description: variationDescription, + sku: 'woo-vneck-tee-red', + price: '20', + regular_price: '20', + sale_price: '', + date_on_sale_from_gmt: null, + date_on_sale_to_gmt: null, + on_sale: false, + status: 'publish', + purchasable: true, + virtual: false, + downloadable: false, + downloads: [], + download_limit: 0, + download_expiry: 0, + tax_status: 'taxable', + tax_class: '', + manage_stock: false, + stock_quantity: null, + stock_status: 'instock', + backorders: 'no', + backorders_allowed: false, + backordered: false, + low_stock_amount: null, + weight: '0.5', + dimensions: { + length: '24', + width: '1', + height: '2', + }, + shipping_class: '', + attributes: [ + { + id: attributes.colorJSON.id, + option: 'Red', + }, + ], + menu_order: 0, + }, + ], + }, + } + ); + const vneckVariationsJSON = await vneckVariations.json(); + + return { + hoodieJSON, + hoodieVariations: hoodieVariationsJSON.create, + vneckJSON, + vneckVariations: vneckVariationsJSON.create, + }; }; - }; - // create Sample Data function - const createSampleData = async () => { - const testProductData = await productsTestSetupCreateSampleData(); - const orderedProducts = { - pocketHoodie: testProductData.simpleProducts.find( - ( p ) => p.name === 'Hoodie with Pocket oxo' - ), - sunglasses: testProductData.simpleProducts.find( + const createSampleHierarchicalProducts = async () => { + const parent = await request.post( '/wp-json/wc/v3/products', { + data: { + name: 'Parent Product oxo', + date_created_gmt: '2021-09-27T15:50:19', + }, + } ); + const parentJSON = await parent.json(); + + const child = await request.post( '/wp-json/wc/v3/products', { + data: { + name: 'Child Product oxo', + parent_id: parentJSON.id, + date_created_gmt: '2021-09-28T15:50:19', + }, + } ); + const childJSON = await child.json(); + + return { + parentJSON, + childJSON, + }; + }; + + const createSampleProductReviews = async ( simpleProducts ) => { + const cap = simpleProducts.find( + ( p ) => p.name === 'Cap oxo' + ); + + const shirt = simpleProducts.find( + ( p ) => p.name === 'T-Shirt oxo' + ); + + const sunglasses = simpleProducts.find( ( p ) => p.name === 'Sunglasses oxo' - ), - beanie: testProductData.simpleProducts.find( - ( p ) => p.name === 'Beanie oxo' - ), - blueVneck: - testProductData.variableProducts.vneckVariations.find( - ( p ) => p.sku === 'woo-vneck-tee-blue' + ); + + const review1 = await request.post( + '/wp-json/wc/v3/products/reviews', + { + data: { + product_id: cap.id, + rating: 3, + review: 'Decent cap.', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + }, + } + ); + const review1JSON = await review1.json(); + + // We need to update the review in order for the product's + // average_rating to be recalculated. + // See: https://github.com/woocommerce/woocommerce/issues/29906. + //await updateProductReview(review1.id); + await request.post( + `/wp-json/wc/v3/products/reviews/${ review1JSON.id }`, + { + data: {}, + } + ); + + const review2 = await request.post( + '/wp-json/wc/v3/products/reviews', + { + data: { + product_id: shirt.id, + rating: 5, + review: 'The BEST shirt ever!!', + reviewer: 'Shannon Smith', + reviewer_email: 'shannon.smith@example.com', + }, + } + ); + const review2JSON = await review2.json(); + + //await updateProductReview(review2.id); + await request.post( + `/wp-json/wc/v3/products/reviews/${ review2JSON.id }`, + { + data: {}, + } + ); + + const review3 = await request.post( + '/wp-json/wc/v3/products/reviews', + { + data: { + product_id: sunglasses.id, + rating: 1, + review: 'These are way too expensive.', + reviewer: 'Tim Frugalman', + reviewer_email: 'timmyfrufru@example.com', + }, + } + ); + const review3JSON = await review3.json(); + + await request.post( + `/wp-json/wc/v3/products/reviews/${ review3JSON.id }`, + { + data: {}, + } + ); + + return [ review1JSON.id, review2JSON.id, review3JSON.id ]; + }; + + const createSampleProductOrders = async ( simpleProducts ) => { + const single = simpleProducts.find( + ( p ) => p.name === 'Single oxo' + ); + const beanie = simpleProducts.find( + ( p ) => p.name === 'Beanie with Logo oxo' + ); + const shirt = simpleProducts.find( + ( p ) => p.name === 'T-Shirt oxo' + ); + + const order1 = await request.post( '/wp-json/wc/v3/orders', { + data: { + set_paid: true, + status: 'completed', + line_items: [ + { + product_id: single.id, + quantity: 2, + }, + { + product_id: beanie.id, + quantity: 3, + }, + { + product_id: shirt.id, + quantity: 1, + }, + ], + }, + } ); + const orderJSON = await order1.json(); + + return [ orderJSON ]; + }; + + const productsTestSetupCreateSampleData = async () => { + const categories = await createSampleCategories(); + + const attributes = await createSampleAttributes(); + + const tags = await createSampleTags(); + + const shippingClasses = await createSampleShippingClasses(); + + const taxClasses = await createSampleTaxClasses(); + + const simpleProducts = await createSampleSimpleProducts( + categories, + attributes, + tags + ); + + const externalProducts = await createSampleExternalProducts( + categories + ); + + const groupedProducts = await createSampleGroupedProduct( + categories + ); + + const variableProducts = await createSampleVariableProducts( + categories, + attributes + ); + + const hierarchicalProducts = + await createSampleHierarchicalProducts(); + + const reviewIds = await createSampleProductReviews( + simpleProducts + ); + + const orders = await createSampleProductOrders( + simpleProducts + ); + + return { + categories, + attributes, + tags, + shippingClasses, + taxClasses, + simpleProducts, + externalProducts, + groupedProducts, + variableProducts, + hierarchicalProducts, + reviewIds, + orders, + }; + }; + + // create Sample Data function + const createSampleData = async () => { + const testProductData = + await productsTestSetupCreateSampleData(); + const orderedProducts = { + pocketHoodie: testProductData.simpleProducts.find( + ( p ) => p.name === 'Hoodie with Pocket oxo' ), - pennant: testProductData.externalProducts[ 0 ], - }; + sunglasses: testProductData.simpleProducts.find( + ( p ) => p.name === 'Sunglasses oxo' + ), + beanie: testProductData.simpleProducts.find( + ( p ) => p.name === 'Beanie oxo' + ), + blueVneck: + testProductData.variableProducts.vneckVariations.find( + ( p ) => p.sku === 'woo-vneck-tee-blue' + ), + pennant: testProductData.externalProducts[ 0 ], + }; - const johnAddress = { - first_name: 'John', - last_name: 'Doe', - company: 'Automattic', - country: 'US', - address_1: '60 29th Street', - address_2: '#343', - city: 'San Francisco', - state: 'CA', - postcode: '94110', - phone: '123456789', - }; - const tinaAddress = { - first_name: 'Tina', - last_name: 'Clark', - company: 'Automattic', - country: 'US', - address_1: 'Oxford Ave', - address_2: '', - city: 'Buffalo', - state: 'NY', - postcode: '14201', - phone: '123456789', - }; - const guestShippingAddress = { - first_name: 'Ano', - last_name: 'Nymous', - company: '', - country: 'US', - address_1: '0 Incognito St', - address_2: '', - city: 'Erie', - state: 'PA', - postcode: '16515', - phone: '123456789', - }; - const guestBillingAddress = { - first_name: 'Ben', - last_name: 'Efactor', - company: '', - country: 'US', - address_1: '200 W University Avenue', - address_2: '', - city: 'Gainesville', - state: 'FL', - postcode: '32601', - phone: '123456789', - email: 'ben.efactor@email.net', - }; - - const john = await request.post( '/wp-json/wc/v3/customers', { - data: { + const johnAddress = { first_name: 'John', last_name: 'Doe', - username: 'john.doe', - email: 'john.doe@example.com', - billing: { - ...johnAddress, - email: 'john.doe@example.com', - }, - shipping: johnAddress, - }, - } ); - const johnJSON = await john.json(); - - const tina = await request.post( '/wp-json/wc/v3/customers', { - data: { + company: 'Automattic', + country: 'US', + address_1: '60 29th Street', + address_2: '#343', + city: 'San Francisco', + state: 'CA', + postcode: '94110', + phone: '123456789', + }; + const tinaAddress = { first_name: 'Tina', last_name: 'Clark', - username: 'tina.clark', - email: 'tina.clark@example.com', - billing: { - ...tinaAddress, - email: 'tina.clark@example.com', - }, - shipping: tinaAddress, - }, - } ); - const tinaJSON = await tina.json(); + company: 'Automattic', + country: 'US', + address_1: 'Oxford Ave', + address_2: '', + city: 'Buffalo', + state: 'NY', + postcode: '14201', + phone: '123456789', + }; + const guestShippingAddress = { + first_name: 'Ano', + last_name: 'Nymous', + company: '', + country: 'US', + address_1: '0 Incognito St', + address_2: '', + city: 'Erie', + state: 'PA', + postcode: '16515', + phone: '123456789', + }; + const guestBillingAddress = { + first_name: 'Ben', + last_name: 'Efactor', + company: '', + country: 'US', + address_1: '200 W University Avenue', + address_2: '', + city: 'Gainesville', + state: 'FL', + postcode: '32601', + phone: '123456789', + email: 'ben.efactor@email.net', + }; - const orderBaseData = { - payment_method: 'cod', - payment_method_title: 'Cash on Delivery', - status: 'processing', - set_paid: false, - currency: 'USD', - customer_id: 0, - }; - - const orders = []; - // Have "John" order all products. - Object.values( orderedProducts ).forEach( async ( product ) => { - const order2 = await request.post( '/wp-json/wc/v3/orders', { + const john = await request.post( '/wp-json/wc/v3/customers', { data: { - ...orderBaseData, - customer_id: johnJSON.id, + first_name: 'John', + last_name: 'Doe', + username: 'john.doe', + email: 'john.doe@example.com', billing: { ...johnAddress, email: 'john.doe@example.com', }, shipping: johnAddress, - line_items: [ - { - product_id: product.id, - quantity: 1, - }, - ], }, } ); - const orderJSON = await order2.json(); + const johnJSON = await john.json(); - orders.push( orderJSON ); - } ); - - // Have "Tina" order some sunglasses and make a child order. - // This somewhat resembles a subscription renewal, but we're just testing the `parent` field. - const order2 = await request.post( '/wp-json/wc/v3/orders', { - data: { - ...orderBaseData, - status: 'completed', - set_paid: true, - customer_id: tinaJSON.id, - billing: { - ...tinaAddress, - email: 'tina.clark@example.com', - }, - shipping: tinaAddress, - line_items: [ - { - product_id: orderedProducts.sunglasses.id, - quantity: 1, - }, - ], - }, - } ); - const order2JSON = await order2.json(); - - orders.push( order2JSON ); - - // create child order by referencing a parent_id - const order3 = await request.post( '/wp-json/wc/v3/orders', { - data: { - ...orderBaseData, - parent_id: order2JSON.id, - customer_id: tinaJSON.id, - billing: { - ...tinaAddress, - email: 'tina.clark@example.com', - }, - shipping: tinaAddress, - line_items: [ - { - product_id: orderedProducts.sunglasses.id, - quantity: 1, - }, - ], - }, - } ); - const order3JSON = await order3.json(); - - orders.push( order3JSON ); - - // Guest order. - const guestOrder = await request.post( '/wp-json/wc/v3/orders', { - data: { - ...orderBaseData, - billing: guestBillingAddress, - shipping: guestShippingAddress, - line_items: [ - { - product_id: orderedProducts.pennant.id, - quantity: 2, - }, - { - product_id: orderedProducts.beanie.id, - quantity: 1, - }, - ], - }, - } ); - const guestOrderJSON = await guestOrder.json(); - - // Create an order with all possible numerical fields (taxes, fees, refunds, etc). - await request.put( - '/wp-json/wc/v3/settings/general/woocommerce_calc_taxes', - { + const tina = await request.post( '/wp-json/wc/v3/customers', { data: { - value: 'yes', + first_name: 'Tina', + last_name: 'Clark', + username: 'tina.clark', + email: 'tina.clark@example.com', + billing: { + ...tinaAddress, + email: 'tina.clark@example.com', + }, + shipping: tinaAddress, }, - } - ); + } ); + const tinaJSON = await tina.json(); - await request.post( '/wp-json/wc/v3/taxes', { - data: { - country: '*', - state: '*', - postcode: '*', - city: '*', - name: 'Tax', - rate: '5.5', - shipping: true, - }, - } ); + const orderBaseData = { + payment_method: 'cod', + payment_method_title: 'Cash on Delivery', + status: 'processing', + set_paid: false, + currency: 'USD', + customer_id: 0, + }; - const coupon = await request.post( '/wp-json/wc/v3/coupons', { - data: { - code: 'save5', - amount: '5', - }, - } ); - const couponJSON = await coupon.json(); - - const order4 = await request.post( '/wp-json/wc/v3/orders', { - data: { - ...orderBaseData, - line_items: [ + const orders = []; + // Have "John" order all products. + Object.values( orderedProducts ).forEach( async ( product ) => { + const order2 = await request.post( + '/wp-json/wc/v3/orders', { - product_id: orderedProducts.blueVneck.id, - quantity: 1, - }, - ], - coupon_lines: [ - { - code: 'save5', - }, - ], - shipping_lines: [ - { - method_id: 'flat_rate', - total: '5.00', - }, - ], - fee_lines: [ - { - total: '1.00', - name: 'Test Fee', - }, - ], - }, - } ); - const order4JSON = await order4.json(); - - await request.post( - `/wp-json/wc/v3/orders/${ order4JSON.id }/refunds`, - { - data: { - api_refund: false, // Prevent an actual refund request (fails with CoD), - line_items: [ - { - id: order4JSON.line_items[ 0 ].id, - quantity: 1, - refund_total: order4JSON.line_items[ 0 ].total, - refund_tax: [ + data: { + ...orderBaseData, + customer_id: johnJSON.id, + billing: { + ...johnAddress, + email: 'john.doe@example.com', + }, + shipping: johnAddress, + line_items: [ { - id: order4JSON.line_items[ 0 ] - .taxes[ 0 ].id, - refund_total: - order4JSON.line_items[ 0 ] - .total_tax, + product_id: product.id, + quantity: 1, }, ], }, + } + ); + const orderJSON = await order2.json(); + + orders.push( orderJSON ); + } ); + + // Have "Tina" order some sunglasses and make a child order. + // This somewhat resembles a subscription renewal, but we're just testing the `parent` field. + const order2 = await request.post( '/wp-json/wc/v3/orders', { + data: { + ...orderBaseData, + status: 'completed', + set_paid: true, + customer_id: tinaJSON.id, + billing: { + ...tinaAddress, + email: 'tina.clark@example.com', + }, + shipping: tinaAddress, + line_items: [ + { + product_id: orderedProducts.sunglasses.id, + quantity: 1, + }, ], }, - } - ); - orders.push( order4JSON ); + } ); + const order2JSON = await order2.json(); - return { - customers: { - johnJSON, - tinaJSON, - }, - orders, - precisionOrder: order4JSON, - hierarchicalOrders: { - parent: order2JSON, - child: order3JSON, - }, - guestOrderJSON, - testProductData, - couponJSON, + orders.push( order2JSON ); + + // create child order by referencing a parent_id + const order3 = await request.post( '/wp-json/wc/v3/orders', { + data: { + ...orderBaseData, + parent_id: order2JSON.id, + customer_id: tinaJSON.id, + billing: { + ...tinaAddress, + email: 'tina.clark@example.com', + }, + shipping: tinaAddress, + line_items: [ + { + product_id: orderedProducts.sunglasses.id, + quantity: 1, + }, + ], + }, + } ); + const order3JSON = await order3.json(); + + orders.push( order3JSON ); + + // Guest order. + const guestOrder = await request.post( + '/wp-json/wc/v3/orders', + { + data: { + ...orderBaseData, + billing: guestBillingAddress, + shipping: guestShippingAddress, + line_items: [ + { + product_id: orderedProducts.pennant.id, + quantity: 2, + }, + { + product_id: orderedProducts.beanie.id, + quantity: 1, + }, + ], + }, + } + ); + const guestOrderJSON = await guestOrder.json(); + + // Create an order with all possible numerical fields (taxes, fees, refunds, etc). + await request.put( + '/wp-json/wc/v3/settings/general/woocommerce_calc_taxes', + { + data: { + value: 'yes', + }, + } + ); + + await request.post( '/wp-json/wc/v3/taxes', { + data: { + country: '*', + state: '*', + postcode: '*', + city: '*', + name: 'Tax', + rate: '5.5', + shipping: true, + }, + } ); + + const coupon = await request.post( '/wp-json/wc/v3/coupons', { + data: { + code: 'save5', + amount: '5', + }, + } ); + const couponJSON = await coupon.json(); + + const order4 = await request.post( '/wp-json/wc/v3/orders', { + data: { + ...orderBaseData, + line_items: [ + { + product_id: orderedProducts.blueVneck.id, + quantity: 1, + }, + ], + coupon_lines: [ + { + code: 'save5', + }, + ], + shipping_lines: [ + { + method_id: 'flat_rate', + total: '5.00', + }, + ], + fee_lines: [ + { + total: '1.00', + name: 'Test Fee', + }, + ], + }, + } ); + const order4JSON = await order4.json(); + + await request.post( + `/wp-json/wc/v3/orders/${ order4JSON.id }/refunds`, + { + data: { + api_refund: false, // Prevent an actual refund request (fails with CoD), + line_items: [ + { + id: order4JSON.line_items[ 0 ].id, + quantity: 1, + refund_total: + order4JSON.line_items[ 0 ].total, + refund_tax: [ + { + id: order4JSON.line_items[ 0 ] + .taxes[ 0 ].id, + refund_total: + order4JSON.line_items[ 0 ] + .total_tax, + }, + ], + }, + ], + }, + } + ); + orders.push( order4JSON ); + + return { + customers: { + johnJSON, + tinaJSON, + }, + orders, + precisionOrder: order4JSON, + hierarchicalOrders: { + parent: order2JSON, + child: order3JSON, + }, + guestOrderJSON, + testProductData, + couponJSON, + }; }; - }; - sampleData = await createSampleData(); - }, 100000 ); + sampleData = await createSampleData(); + }, 100000 ); - test.afterAll( async ( { request } ) => { - const productsTestSetupDeleteSampleData = async ( _sampleData ) => { - const { - categories, - attributes, - tags, - shippingClasses, - taxClasses, - simpleProducts, - externalProducts, - groupedProducts, - variableProducts, - hierarchicalProducts, - orders, - } = _sampleData; + test.afterAll( async ( { request } ) => { + const productsTestSetupDeleteSampleData = async ( _sampleData ) => { + const { + categories, + attributes, + tags, + shippingClasses, + taxClasses, + simpleProducts, + externalProducts, + groupedProducts, + variableProducts, + hierarchicalProducts, + orders, + } = _sampleData; - const productIds = [] - .concat( simpleProducts.map( ( p ) => p.id ) ) - .concat( externalProducts.map( ( p ) => p.id ) ) - .concat( groupedProducts.map( ( p ) => p.id ) ) - .concat( [ - variableProducts.hoodieJSON.id, - variableProducts.vneckJSON.id, - ] ) - .concat( [ - hierarchicalProducts.parentJSON.id, - hierarchicalProducts.childJSON.id, - ] ); + const productIds = [] + .concat( simpleProducts.map( ( p ) => p.id ) ) + .concat( externalProducts.map( ( p ) => p.id ) ) + .concat( groupedProducts.map( ( p ) => p.id ) ) + .concat( [ + variableProducts.hoodieJSON.id, + variableProducts.vneckJSON.id, + ] ) + .concat( [ + hierarchicalProducts.parentJSON.id, + hierarchicalProducts.childJSON.id, + ] ); - for ( const _order of orders ) { - await request.delete( `/wp-json/wc/v3/orders/${ _order.id }`, { - data: { - force: true, - }, - } ); - } - - for ( const productId of productIds ) { - await request.delete( - `/wp-json/wc/v3/products/${ productId }`, - { - data: { - force: true, - }, - } - ); - } - - await request.delete( - `/wp-json/wc/v3/products/attributes/${ attributes.colorJSON.id }`, - { - data: { - force: true, - }, + for ( const _order of orders ) { + await request.delete( + `/wp-json/wc/v3/orders/${ _order.id }`, + { + data: { + force: true, + }, + } + ); } - ); - await request.delete( - `/wp-json/wc/v3/products/attributes/${ attributes.sizeJSON.id }`, - { - data: { - force: true, - }, + for ( const productId of productIds ) { + await request.delete( + `/wp-json/wc/v3/products/${ productId }`, + { + data: { + force: true, + }, + } + ); } - ); - for ( const category of Object.values( categories ) ) { await request.delete( - `/wp-json/wc/v3/products/categories/${ category.id }`, + `/wp-json/wc/v3/products/attributes/${ attributes.colorJSON.id }`, { data: { force: true, }, } ); - } - for ( const tag of Object.values( tags ) ) { await request.delete( - `/wp-json/wc/v3/products/tags/${ tag.id }`, + `/wp-json/wc/v3/products/attributes/${ attributes.sizeJSON.id }`, { data: { force: true, }, } ); - } - for ( const shippingClass of Object.values( shippingClasses ) ) { - await request.delete( - `/wp-json/wc/v3/products/shipping_classes/${ shippingClass.id }`, - { - data: { - force: true, - }, - } + for ( const category of Object.values( categories ) ) { + await request.delete( + `/wp-json/wc/v3/products/categories/${ category.id }`, + { + data: { + force: true, + }, + } + ); + } + + for ( const tag of Object.values( tags ) ) { + await request.delete( + `/wp-json/wc/v3/products/tags/${ tag.id }`, + { + data: { + force: true, + }, + } + ); + } + + for ( const shippingClass of Object.values( + shippingClasses + ) ) { + await request.delete( + `/wp-json/wc/v3/products/shipping_classes/${ shippingClass.id }`, + { + data: { + force: true, + }, + } + ); + } + + for ( const taxClass of Object.values( taxClasses ) ) { + await request.delete( + `/wp-json/wc/v3/taxes/classes/${ taxClass.slug }`, + { + data: { + force: true, + }, + } + ); + } + }; + + const deleteSampleData = async ( _sampleData ) => { + await productsTestSetupDeleteSampleData( + _sampleData.testProductData ); - } - for ( const taxClass of Object.values( taxClasses ) ) { - await request.delete( - `/wp-json/wc/v3/taxes/classes/${ taxClass.slug }`, - { - data: { - force: true, - }, - } - ); - } - }; + for ( const _order of _sampleData.orders.concat( [ + _sampleData.guestOrderJSON, + ] ) ) { + await request.delete( + `/wp-json/wc/v3/orders/${ _order.id }`, + { + data: { + force: true, + }, + } + ); + } - const deleteSampleData = async ( _sampleData ) => { - await productsTestSetupDeleteSampleData( - _sampleData.testProductData - ); + for ( const customer of Object.values( + _sampleData.customers + ) ) { + await request.delete( + `/wp-json/wc/v3/customers/${ customer.id }`, + { + data: { + force: true, + }, + } + ); + } + }; - for ( const _order of _sampleData.orders.concat( [ - _sampleData.guestOrderJSON, - ] ) ) { - await request.delete( `/wp-json/wc/v3/orders/${ _order.id }`, { - data: { - force: true, - }, - } ); - } + await deleteSampleData( sampleData ); + }, 10000 ); - for ( const customer of Object.values( _sampleData.customers ) ) { - await request.delete( - `/wp-json/wc/v3/customers/${ customer.id }`, - { - data: { - force: true, - }, - } - ); - } - }; - - await deleteSampleData( sampleData ); - }, 10000 ); - - test( 'can create an order', async ( { request } ) => { - const response = await request.post( '/wp-json/wc/v3/orders', { - data: order, - } ); - const responseJSON = await response.json(); - - expect( response.status() ).toEqual( 201 ); - expect( responseJSON.id ).toBeDefined(); - orderId = responseJSON.id; - - // Validate the data type and verify the order is in a pending state - expect( typeof responseJSON.status ).toBe( 'string' ); - expect( responseJSON.status ).toEqual( 'pending' ); - } ); - - test( 'can retrieve an order', async ( { request } ) => { - const response = await request.get( - `/wp-json/wc/v3/orders/${ orderId }` - ); - const responseJSON = await response.json(); - - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.id ).toEqual( orderId ); - } ); - - test( 'can add shipping and billing contacts to an order', async ( { - request, - } ) => { - // Update the billing and shipping fields on the order - order.billing = updatedCustomerBilling; - order.shipping = updatedCustomerShipping; - - const response = await request.put( - `/wp-json/wc/v3/orders/${ orderId }`, - { + test( 'can create an order', async ( { request } ) => { + const response = await request.post( '/wp-json/wc/v3/orders', { data: order, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - - expect( responseJSON.billing ).toEqual( updatedCustomerBilling ); - expect( responseJSON.shipping ).toEqual( updatedCustomerShipping ); - } ); - - test( 'can permanently delete an order', async ( { request } ) => { - const response = await request.delete( - `/wp-json/wc/v3/orders/${ orderId }`, - { - data: { - force: true, - }, - } - ); - expect( response.status() ).toEqual( 200 ); - - const getOrderResponse = await request.get( - `/wp-json/wc/v3/orders/${ orderId }` - ); - expect( getOrderResponse.status() ).toEqual( 404 ); - } ); - - test.describe( 'List all orders', () => { - const ORDERS_COUNT = 10; - - test( 'pagination', async ( { request } ) => { - const pageSize = 4; - const page1 = await request.get( '/wp-json/wc/v3/orders', { - params: { - per_page: pageSize, - search: 'oxo', - }, } ); - const page1JSON = await page1.json(); + const responseJSON = await response.json(); - const page2 = await request.get( '/wp-json/wc/v3/orders', { - params: { - per_page: pageSize, - page: 2, - search: 'oxo', - }, - } ); - const page2JSON = await page2.json(); + expect( response.status() ).toEqual( 201 ); + expect( responseJSON.id ).toBeDefined(); + orderId = responseJSON.id; - expect( page1.status() ).toEqual( 200 ); - expect( page2.status() ).toEqual( 200 ); - - // Verify total page count. - expect( page1.headers()[ 'x-wp-total' ] ).toEqual( - ORDERS_COUNT.toString() - ); - expect( page1.headers()[ 'x-wp-totalpages' ] ).toEqual( '3' ); - - // Verify we get pageSize'd arrays. - expect( Array.isArray( page1JSON ) ).toBe( true ); - expect( Array.isArray( page2JSON ) ).toBe( true ); - expect( page1JSON ).toHaveLength( pageSize ); - expect( page2JSON ).toHaveLength( pageSize ); - - // Ensure all of the order IDs are unique (no page overlap). - const allOrderIds = page1JSON - .concat( page2JSON ) - .reduce( ( acc, { id } ) => { - acc[ id ] = 1; - return acc; - }, {} ); - expect( Object.keys( allOrderIds ) ).toHaveLength( pageSize * 2 ); - - // Verify that offset takes precedent over page number. - const page2Offset = await request.get( 'wp-json/wc/v3/orders', { - params: { - per_page: pageSize, - page: 2, - offset: pageSize + 1, - search: 'oxo', - }, - } ); - const page2OffsetJSON = await page2Offset.json(); - - // The offset pushes the result set 1 order past the start of page 2. - expect( page2OffsetJSON ).toEqual( - expect.not.arrayContaining( [ - expect.objectContaining( { - id: page2JSON[ 0 ].id, - } ), - ] ) - ); - expect( page2OffsetJSON[ 0 ].id ).toEqual( page2JSON[ 1 ].id ); - - // Verify the last page only has 1 order as we expect. - const lastPage = await request.get( 'wp-json/wc/v3/orders', { - params: { - per_page: pageSize, - page: 3, - search: 'oxo', - }, - } ); - const lastPageJSON = await lastPage.json(); - - expect( Array.isArray( lastPageJSON ) ).toBe( true ); - expect( lastPageJSON ).toHaveLength( 2 ); - - // Verify a page outside the total page count is empty. - const page6 = await request.get( 'wp-json/wc/v3/orders', { - params: { - page: 6, - search: 'oxo', - }, - } ); - const page6JSON = await page6.json(); - - expect( Array.isArray( page6JSON ) ).toBe( true ); - expect( page6JSON ).toHaveLength( 0 ); + // Validate the data type and verify the order is in a pending state + expect( typeof responseJSON.status ).toBe( 'string' ); + expect( responseJSON.status ).toEqual( 'pending' ); } ); - test( 'inclusion / exclusion', async ( { request } ) => { - const allOrders = await request.get( 'wp-json/wc/v3/orders', { - params: { - per_page: 10, - search: 'oxo', - }, - } ); - const allOrdersJSON = await allOrders.json(); - - expect( allOrders.status() ).toEqual( 200 ); - const allOrdersIds = allOrdersJSON.map( ( _order ) => _order.id ); - expect( allOrdersIds ).toHaveLength( ORDERS_COUNT ); - - const ordersToFilter = [ - allOrdersIds[ 0 ], - allOrdersIds[ 2 ], - allOrdersIds[ 4 ], - allOrdersIds[ 7 ], - ]; - - const included = await request.get( 'wp-json/wc/v3/orders', { - params: { - per_page: 20, - include: ordersToFilter.join( ',' ), - }, - } ); - const includedJSON = await included.json(); - - expect( included.status() ).toEqual( 200 ); - expect( includedJSON ).toHaveLength( ordersToFilter.length ); - expect( includedJSON ).toEqual( - expect.arrayContaining( - ordersToFilter.map( ( id ) => - expect.objectContaining( { - id, - } ) - ) - ) + test( 'can retrieve an order', async ( { request } ) => { + const response = await request.get( + `/wp-json/wc/v3/orders/${ orderId }` ); + const responseJSON = await response.json(); - const excluded = await request.get( 'wp-json/wc/v3/orders', { - params: { - per_page: 20, - exclude: ordersToFilter.join( ',' ), - }, - } ); - const excludedJSON = await excluded.json(); - - expect( excluded.status() ).toEqual( 200 ); - expect( excludedJSON.length ).toBeGreaterThanOrEqual( - Number( ORDERS_COUNT - ordersToFilter.length ) - ); - expect( excludedJSON ).toEqual( - expect.not.arrayContaining( - ordersToFilter.map( ( id ) => - expect.objectContaining( { - id, - } ) - ) - ) - ); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.id ).toEqual( orderId ); } ); - test( 'parent', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - parent: sampleData.hierarchicalOrders.parent.id, - }, - } ); - const result1JSON = await result1.json(); + test( 'can add shipping and billing contacts to an order', async ( { + request, + } ) => { + // Update the billing and shipping fields on the order + order.billing = updatedCustomerBilling; + order.shipping = updatedCustomerShipping; - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].id ).toBe( - sampleData.hierarchicalOrders.child.id + const response = await request.put( + `/wp-json/wc/v3/orders/${ orderId }`, + { + data: order, + } ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - parent_exclude: sampleData.hierarchicalOrders.parent.id, - }, - } ); - const result2JSON = await result2.json(); - - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( [ - expect.objectContaining( { - id: sampleData.hierarchicalOrders.child.id, - } ), - ] ) - ); + expect( responseJSON.billing ).toEqual( updatedCustomerBilling ); + expect( responseJSON.shipping ).toEqual( updatedCustomerShipping ); } ); - test( 'status', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - status: 'completed', - search: 'oxo', - }, - } ); - const result1JSON = await result1.json(); - - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 2 ); - expect( result1JSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - status: 'completed', - customer_id: 0, - line_items: expect.arrayContaining( [ - expect.objectContaining( { - name: 'Single oxo', - quantity: 2, - } ), - expect.objectContaining( { - name: 'Beanie with Logo oxo', - quantity: 3, - } ), - expect.objectContaining( { - name: 'T-Shirt oxo', - quantity: 1, - } ), - ] ), - } ), - expect.objectContaining( { - status: 'completed', - customer_id: sampleData.customers.tinaJSON.id, - line_items: expect.arrayContaining( [ - expect.objectContaining( { - name: 'Sunglasses oxo', - quantity: 1, - } ), - ] ), - } ), - ] ) + test( 'can permanently delete an order', async ( { request } ) => { + const response = await request.delete( + `/wp-json/wc/v3/orders/${ orderId }`, + { + data: { + force: true, + }, + } ); + expect( response.status() ).toEqual( 200 ); - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - status: 'processing', - search: 'oxo', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 8 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( - result1JSON.map( ( { id } ) => - expect.objectContaining( { - id, - } ) - ) - ) + const getOrderResponse = await request.get( + `/wp-json/wc/v3/orders/${ orderId }` ); + expect( getOrderResponse.status() ).toEqual( 404 ); } ); - test( 'customer', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - customer: sampleData.customers.johnJSON.id, - }, - } ); - const result1JSON = await result1.json(); + test.describe( 'List all orders', () => { + const ORDERS_COUNT = 10; - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 5 ); - result1JSON.forEach( ( _order ) => - expect( _order ).toEqual( - expect.objectContaining( { - customer_id: sampleData.customers.johnJSON.id, - } ) - ) - ); + test( 'pagination', async ( { request } ) => { + const pageSize = 4; + const page1 = await request.get( '/wp-json/wc/v3/orders', { + params: { + per_page: pageSize, + search: 'oxo', + }, + } ); + const page1JSON = await page1.json(); - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - customer: 0, - search: 'oxo', - }, - } ); - const result2JSON = await result2.json(); + const page2 = await request.get( '/wp-json/wc/v3/orders', { + params: { + per_page: pageSize, + page: 2, + search: 'oxo', + }, + } ); + const page2JSON = await page2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 3 ); - result2JSON.forEach( ( _order ) => - expect( _order ).toEqual( - expect.objectContaining( { - customer_id: 0, - } ) - ) - ); - } ); + expect( page1.status() ).toEqual( 200 ); + expect( page2.status() ).toEqual( 200 ); - test( 'product', async ( { request } ) => { - const beanie = sampleData.testProductData.simpleProducts.find( - ( p ) => p.name === 'Beanie oxo' - ); - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - product: beanie.id, - }, - } ); - const result1JSON = await result1.json(); - - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 2 ); - result1JSON.forEach( ( _order ) => - expect( _order ).toEqual( - expect.objectContaining( { - line_items: expect.arrayContaining( [ - expect.objectContaining( { - name: 'Beanie oxo', - } ), - ] ), - } ) - ) - ); - } ); - - // NOTE: This does not verify the `taxes` array nested in line items. - // While the precision parameter doesn't affect those values, after some - // discussion it seems `dp` may not be supported in v4 of the API. - test( 'dp (precision)', async ( { request } ) => { - const expectPrecisionToMatch = ( value, dp ) => { - expect( value ).toEqual( - Number.parseFloat( value ).toFixed( dp ) + // Verify total page count. + expect( page1.headers()[ 'x-wp-total' ] ).toEqual( + ORDERS_COUNT.toString() ); - }; + expect( page1.headers()[ 'x-wp-totalpages' ] ).toEqual( '3' ); - const verifyOrderPrecision = ( _order, dp ) => { - expectPrecisionToMatch( _order.discount_total, dp ); - expectPrecisionToMatch( _order.discount_tax, dp ); - expectPrecisionToMatch( _order.shipping_total, dp ); - expectPrecisionToMatch( _order.shipping_tax, dp ); - expectPrecisionToMatch( _order.cart_tax, dp ); - expectPrecisionToMatch( _order.total, dp ); - expectPrecisionToMatch( _order.total_tax, dp ); + // Verify we get pageSize'd arrays. + expect( Array.isArray( page1JSON ) ).toBe( true ); + expect( Array.isArray( page2JSON ) ).toBe( true ); + expect( page1JSON ).toHaveLength( pageSize ); + expect( page2JSON ).toHaveLength( pageSize ); - _order.line_items.forEach( ( lineItem ) => { - expectPrecisionToMatch( lineItem.total, dp ); - expectPrecisionToMatch( lineItem.total_tax, dp ); - } ); + // Ensure all of the order IDs are unique (no page overlap). + const allOrderIds = page1JSON + .concat( page2JSON ) + .reduce( ( acc, { id } ) => { + acc[ id ] = 1; + return acc; + }, {} ); + expect( Object.keys( allOrderIds ) ).toHaveLength( + pageSize * 2 + ); - _order.tax_lines.forEach( ( taxLine ) => { - expectPrecisionToMatch( taxLine.tax_total, dp ); - expectPrecisionToMatch( taxLine.shipping_tax_total, dp ); - } ); - - _order.shipping_lines.forEach( ( shippingLine ) => { - expectPrecisionToMatch( shippingLine.total, dp ); - expectPrecisionToMatch( shippingLine.total_tax, dp ); - } ); - - _order.fee_lines.forEach( ( feeLine ) => { - expectPrecisionToMatch( feeLine.total, dp ); - expectPrecisionToMatch( feeLine.total_tax, dp ); - } ); - - _order.refunds.forEach( ( refund ) => { - expectPrecisionToMatch( refund.total, dp ); - } ); - }; - - const result1 = await request.get( - `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }`, - { + // Verify that offset takes precedent over page number. + const page2Offset = await request.get( 'wp-json/wc/v3/orders', { params: { - dp: 1, + per_page: pageSize, + page: 2, + offset: pageSize + 1, + search: 'oxo', }, - } - ); - const result1JSON = await result1.json(); + } ); + const page2OffsetJSON = await page2Offset.json(); - expect( result1.status() ).toEqual( 200 ); - verifyOrderPrecision( result1JSON, 1 ); + // The offset pushes the result set 1 order past the start of page 2. + expect( page2OffsetJSON ).toEqual( + expect.not.arrayContaining( [ + expect.objectContaining( { + id: page2JSON[ 0 ].id, + } ), + ] ) + ); + expect( page2OffsetJSON[ 0 ].id ).toEqual( page2JSON[ 1 ].id ); - const result2 = await request.get( - `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }`, - { + // Verify the last page only has 1 order as we expect. + const lastPage = await request.get( 'wp-json/wc/v3/orders', { params: { - dp: 3, + per_page: pageSize, + page: 3, + search: 'oxo', }, - } - ); - const result2JSON = await result2.json(); + } ); + const lastPageJSON = await lastPage.json(); - expect( result2.status() ).toEqual( 200 ); - verifyOrderPrecision( result2JSON, 3 ); + expect( Array.isArray( lastPageJSON ) ).toBe( true ); + expect( lastPageJSON ).toHaveLength( 2 ); - const result3 = await request.get( - `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }` - ); - const result3JSON = await result3.json(); + // Verify a page outside the total page count is empty. + const page6 = await request.get( 'wp-json/wc/v3/orders', { + params: { + page: 6, + search: 'oxo', + }, + } ); + const page6JSON = await page6.json(); - expect( result3.status() ).toEqual( 200 ); - verifyOrderPrecision( result3JSON, 2 ); // The default value for 'dp' is 2. - } ); - - test( 'search', async ( { request } ) => { - // By default, 'search' looks in: - // - _billing_address_index - // - _shipping_address_index - // - _billing_last_name - // - _billing_email - // - order_item_name - - // Test billing email. - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - search: 'example.com', - }, + expect( Array.isArray( page6JSON ) ).toBe( true ); + expect( page6JSON ).toHaveLength( 0 ); } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON.length ).toBeGreaterThanOrEqual( 1 ); - result1JSON.forEach( ( _order ) => - expect( _order.billing.email ).toContain( 'example.com' ) - ); + test( 'inclusion / exclusion', async ( { request } ) => { + const allOrders = await request.get( 'wp-json/wc/v3/orders', { + params: { + per_page: 10, + search: 'oxo', + }, + } ); + const allOrdersJSON = await allOrders.json(); - // Test billing address. - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - search: 'gainesville', - }, - } ); - const result2JSON = await result2.json(); + expect( allOrders.status() ).toEqual( 200 ); + const allOrdersIds = allOrdersJSON.map( + ( _order ) => _order.id + ); + expect( allOrdersIds ).toHaveLength( ORDERS_COUNT ); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 1 ); - expect( result2JSON[ 0 ].id ).toEqual( - sampleData.guestOrderJSON.id - ); + const ordersToFilter = [ + allOrdersIds[ 0 ], + allOrdersIds[ 2 ], + allOrdersIds[ 4 ], + allOrdersIds[ 7 ], + ]; - // Test shipping address. - const result3 = await request.get( 'wp-json/wc/v3/orders', { - params: { - search: 'Incognito', - }, - } ); - const result3JSON = await result3.json(); + const included = await request.get( 'wp-json/wc/v3/orders', { + params: { + per_page: 20, + include: ordersToFilter.join( ',' ), + }, + } ); + const includedJSON = await included.json(); - expect( result3.status() ).toEqual( 200 ); - expect( result3JSON ).toHaveLength( 1 ); - expect( result3JSON[ 0 ].id ).toEqual( - sampleData.guestOrderJSON.id - ); - - // Test billing last name. - const result4 = await request.get( 'wp-json/wc/v3/orders', { - params: { - search: 'Doe', - }, - } ); - const result4JSON = await result4.json(); - - expect( result4.status() ).toEqual( 200 ); - expect( result4JSON.length ).toBeGreaterThanOrEqual( 1 ); - result4JSON.forEach( ( _order ) => - expect( _order.billing.last_name ).toEqual( 'Doe' ) - ); - - // Test order item name. - const result5 = await request.get( 'wp-json/wc/v3/orders', { - params: { - search: 'Pennant oxo', - }, - } ); - const result5JSON = await result5.json(); - - expect( result5.status() ).toEqual( 200 ); - expect( result5JSON ).toHaveLength( 2 ); - result5JSON.forEach( ( _order ) => - expect( _order ).toEqual( - expect.objectContaining( { - line_items: expect.arrayContaining( [ + expect( included.status() ).toEqual( 200 ); + expect( includedJSON ).toHaveLength( ordersToFilter.length ); + expect( includedJSON ).toEqual( + expect.arrayContaining( + ordersToFilter.map( ( id ) => expect.objectContaining( { - name: 'WordPress Pennant oxo', - } ), - ] ), - } ) - ) - ); - } ); - } ); + id, + } ) + ) + ) + ); - test.describe( 'orderby', () => { - // The orders endpoint `orderby` parameter uses WP_Query, so our tests won't - // include slug and title, since they are programmatically generated. - test( 'default', async ( { request } ) => { - // Default = date desc. - const result = await request.get( 'wp-json/wc/v3/orders' ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); + const excluded = await request.get( 'wp-json/wc/v3/orders', { + params: { + per_page: 20, + exclude: ordersToFilter.join( ',' ), + }, + } ); + const excludedJSON = await excluded.json(); - // Verify all dates are in descending order. - let lastDate = Date.now(); - resultJSON.forEach( ( { date_created } ) => { - const created = Date.parse( date_created + '.000Z' ); - expect( lastDate ).toBeGreaterThanOrEqual( created ); - lastDate = created; + expect( excluded.status() ).toEqual( 200 ); + expect( excludedJSON.length ).toBeGreaterThanOrEqual( + Number( ORDERS_COUNT - ordersToFilter.length ) + ); + expect( excludedJSON ).toEqual( + expect.not.arrayContaining( + ordersToFilter.map( ( id ) => + expect.objectContaining( { + id, + } ) + ) + ) + ); + } ); + + test( 'parent', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + parent: sampleData.hierarchicalOrders.parent.id, + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].id ).toBe( + sampleData.hierarchicalOrders.child.id + ); + + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + parent_exclude: sampleData.hierarchicalOrders.parent.id, + }, + } ); + const result2JSON = await result2.json(); + + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( [ + expect.objectContaining( { + id: sampleData.hierarchicalOrders.child.id, + } ), + ] ) + ); + } ); + + test( 'status', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + status: 'completed', + search: 'oxo', + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 2 ); + expect( result1JSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + status: 'completed', + customer_id: 0, + line_items: expect.arrayContaining( [ + expect.objectContaining( { + name: 'Single oxo', + quantity: 2, + } ), + expect.objectContaining( { + name: 'Beanie with Logo oxo', + quantity: 3, + } ), + expect.objectContaining( { + name: 'T-Shirt oxo', + quantity: 1, + } ), + ] ), + } ), + expect.objectContaining( { + status: 'completed', + customer_id: sampleData.customers.tinaJSON.id, + line_items: expect.arrayContaining( [ + expect.objectContaining( { + name: 'Sunglasses oxo', + quantity: 1, + } ), + ] ), + } ), + ] ) + ); + + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + status: 'processing', + search: 'oxo', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 8 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( + result1JSON.map( ( { id } ) => + expect.objectContaining( { + id, + } ) + ) + ) + ); + } ); + + test( 'customer', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + customer: sampleData.customers.johnJSON.id, + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 5 ); + result1JSON.forEach( ( _order ) => + expect( _order ).toEqual( + expect.objectContaining( { + customer_id: sampleData.customers.johnJSON.id, + } ) + ) + ); + + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + customer: 0, + search: 'oxo', + }, + } ); + const result2JSON = await result2.json(); + + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 3 ); + result2JSON.forEach( ( _order ) => + expect( _order ).toEqual( + expect.objectContaining( { + customer_id: 0, + } ) + ) + ); + } ); + + test( 'product', async ( { request } ) => { + const beanie = sampleData.testProductData.simpleProducts.find( + ( p ) => p.name === 'Beanie oxo' + ); + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + product: beanie.id, + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 2 ); + result1JSON.forEach( ( _order ) => + expect( _order ).toEqual( + expect.objectContaining( { + line_items: expect.arrayContaining( [ + expect.objectContaining( { + name: 'Beanie oxo', + } ), + ] ), + } ) + ) + ); + } ); + + // NOTE: This does not verify the `taxes` array nested in line items. + // While the precision parameter doesn't affect those values, after some + // discussion it seems `dp` may not be supported in v4 of the API. + test( 'dp (precision)', async ( { request } ) => { + const expectPrecisionToMatch = ( value, dp ) => { + expect( value ).toEqual( + Number.parseFloat( value ).toFixed( dp ) + ); + }; + + const verifyOrderPrecision = ( _order, dp ) => { + expectPrecisionToMatch( _order.discount_total, dp ); + expectPrecisionToMatch( _order.discount_tax, dp ); + expectPrecisionToMatch( _order.shipping_total, dp ); + expectPrecisionToMatch( _order.shipping_tax, dp ); + expectPrecisionToMatch( _order.cart_tax, dp ); + expectPrecisionToMatch( _order.total, dp ); + expectPrecisionToMatch( _order.total_tax, dp ); + + _order.line_items.forEach( ( lineItem ) => { + expectPrecisionToMatch( lineItem.total, dp ); + expectPrecisionToMatch( lineItem.total_tax, dp ); + } ); + + _order.tax_lines.forEach( ( taxLine ) => { + expectPrecisionToMatch( taxLine.tax_total, dp ); + expectPrecisionToMatch( + taxLine.shipping_tax_total, + dp + ); + } ); + + _order.shipping_lines.forEach( ( shippingLine ) => { + expectPrecisionToMatch( shippingLine.total, dp ); + expectPrecisionToMatch( shippingLine.total_tax, dp ); + } ); + + _order.fee_lines.forEach( ( feeLine ) => { + expectPrecisionToMatch( feeLine.total, dp ); + expectPrecisionToMatch( feeLine.total_tax, dp ); + } ); + + _order.refunds.forEach( ( refund ) => { + expectPrecisionToMatch( refund.total, dp ); + } ); + }; + + const result1 = await request.get( + `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }`, + { + params: { + dp: 1, + }, + } + ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + verifyOrderPrecision( result1JSON, 1 ); + + const result2 = await request.get( + `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }`, + { + params: { + dp: 3, + }, + } + ); + const result2JSON = await result2.json(); + + expect( result2.status() ).toEqual( 200 ); + verifyOrderPrecision( result2JSON, 3 ); + + const result3 = await request.get( + `wp-json/wc/v3/orders/${ sampleData.precisionOrder.id }` + ); + const result3JSON = await result3.json(); + + expect( result3.status() ).toEqual( 200 ); + verifyOrderPrecision( result3JSON, 2 ); // The default value for 'dp' is 2. + } ); + + test( 'search', async ( { request } ) => { + // By default, 'search' looks in: + // - _billing_address_index + // - _shipping_address_index + // - _billing_last_name + // - _billing_email + // - order_item_name + + // Test billing email. + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + search: 'example.com', + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON.length ).toBeGreaterThanOrEqual( 1 ); + result1JSON.forEach( ( _order ) => + expect( _order.billing.email ).toContain( 'example.com' ) + ); + + // Test billing address. + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + search: 'gainesville', + }, + } ); + const result2JSON = await result2.json(); + + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 1 ); + expect( result2JSON[ 0 ].id ).toEqual( + sampleData.guestOrderJSON.id + ); + + // Test shipping address. + const result3 = await request.get( 'wp-json/wc/v3/orders', { + params: { + search: 'Incognito', + }, + } ); + const result3JSON = await result3.json(); + + expect( result3.status() ).toEqual( 200 ); + expect( result3JSON ).toHaveLength( 1 ); + expect( result3JSON[ 0 ].id ).toEqual( + sampleData.guestOrderJSON.id + ); + + // Test billing last name. + const result4 = await request.get( 'wp-json/wc/v3/orders', { + params: { + search: 'Doe', + }, + } ); + const result4JSON = await result4.json(); + + expect( result4.status() ).toEqual( 200 ); + expect( result4JSON.length ).toBeGreaterThanOrEqual( 1 ); + result4JSON.forEach( ( _order ) => + expect( _order.billing.last_name ).toEqual( 'Doe' ) + ); + + // Test order item name. + const result5 = await request.get( 'wp-json/wc/v3/orders', { + params: { + search: 'Pennant oxo', + }, + } ); + const result5JSON = await result5.json(); + + expect( result5.status() ).toEqual( 200 ); + expect( result5JSON ).toHaveLength( 2 ); + result5JSON.forEach( ( _order ) => + expect( _order ).toEqual( + expect.objectContaining( { + line_items: expect.arrayContaining( [ + expect.objectContaining( { + name: 'WordPress Pennant oxo', + } ), + ] ), + } ) + ) + ); } ); } ); - test( 'date', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/orders', { - params: { - order: 'asc', - orderby: 'date', - }, + test.describe( 'orderby', () => { + // The orders endpoint `orderby` parameter uses WP_Query, so our tests won't + // include slug and title, since they are programmatically generated. + test( 'default', async ( { request } ) => { + // Default = date desc. + const result = await request.get( 'wp-json/wc/v3/orders' ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); + + // Verify all dates are in descending order. + let lastDate = Date.now(); + resultJSON.forEach( ( { date_created } ) => { + const created = Date.parse( date_created + '.000Z' ); + expect( lastDate ).toBeGreaterThanOrEqual( created ); + lastDate = created; + } ); } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); + test( 'date', async ( { request } ) => { + const result = await request.get( 'wp-json/wc/v3/orders', { + params: { + order: 'asc', + orderby: 'date', + }, + } ); + const resultJSON = await result.json(); - // Verify all dates are in ascending order. - let lastDate = 0; - resultJSON.forEach( ( { date_created } ) => { - const created = Date.parse( date_created + '.000Z' ); - expect( created ).toBeGreaterThanOrEqual( lastDate ); - lastDate = created; + expect( result.status() ).toEqual( 200 ); + + // Verify all dates are in ascending order. + let lastDate = 0; + resultJSON.forEach( ( { date_created } ) => { + const created = Date.parse( date_created + '.000Z' ); + expect( created ).toBeGreaterThanOrEqual( lastDate ); + lastDate = created; + } ); + } ); + + test( 'id', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + order: 'asc', + orderby: 'id', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + + // Verify all results are in ascending order. + let lastId = 0; + result1JSON.forEach( ( { id } ) => { + expect( id ).toBeGreaterThan( lastId ); + lastId = id; + } ); + + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + order: 'desc', + orderby: 'id', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + lastId = Number.MAX_SAFE_INTEGER; + result2JSON.forEach( ( { id } ) => { + expect( lastId ).toBeGreaterThan( id ); + lastId = id; + } ); + } ); + + test( 'include', async ( { request } ) => { + const includeIds = [ + sampleData.precisionOrder.id, + sampleData.hierarchicalOrders.parent.id, + sampleData.guestOrderJSON.id, + ]; + + const result1 = await request.get( 'wp-json/wc/v3/orders', { + params: { + order: 'asc', + orderby: 'include', + include: includeIds.join( ',' ), + }, + } ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( includeIds.length ); + + // Verify all results are in proper order. + result1JSON.forEach( ( { id }, idx ) => { + expect( id ).toBe( includeIds[ idx ] ); + } ); + + const result2 = await request.get( 'wp-json/wc/v3/orders', { + params: { + order: 'desc', + orderby: 'include', + include: includeIds.join( ',' ), + }, + } ); + const result2JSON = await result2.json(); + + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( includeIds.length ); + + // Verify all results are in proper order. + result2JSON.forEach( ( { id }, idx ) => { + expect( id ).toBe( includeIds[ idx ] ); + } ); } ); } ); - - test( 'id', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - order: 'asc', - orderby: 'id', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - - // Verify all results are in ascending order. - let lastId = 0; - result1JSON.forEach( ( { id } ) => { - expect( id ).toBeGreaterThan( lastId ); - lastId = id; - } ); - - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - order: 'desc', - orderby: 'id', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - - // Verify all results are in descending order. - lastId = Number.MAX_SAFE_INTEGER; - result2JSON.forEach( ( { id } ) => { - expect( lastId ).toBeGreaterThan( id ); - lastId = id; - } ); - } ); - - test( 'include', async ( { request } ) => { - const includeIds = [ - sampleData.precisionOrder.id, - sampleData.hierarchicalOrders.parent.id, - sampleData.guestOrderJSON.id, - ]; - - const result1 = await request.get( 'wp-json/wc/v3/orders', { - params: { - order: 'asc', - orderby: 'include', - include: includeIds.join( ',' ), - }, - } ); - const result1JSON = await result1.json(); - - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( includeIds.length ); - - // Verify all results are in proper order. - result1JSON.forEach( ( { id }, idx ) => { - expect( id ).toBe( includeIds[ idx ] ); - } ); - - const result2 = await request.get( 'wp-json/wc/v3/orders', { - params: { - order: 'desc', - orderby: 'include', - include: includeIds.join( ',' ), - }, - } ); - const result2JSON = await result2.json(); - - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( includeIds.length ); - - // Verify all results are in proper order. - result2JSON.forEach( ( { id }, idx ) => { - expect( id ).toBe( includeIds[ idx ] ); - } ); - } ); - } ); -} ); + } +); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/payment-gateways/payment-gateways-crud.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/payment-gateways/payment-gateways-crud.test.js index c4d021c65f5..a0cd439f3e4 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/payment-gateways/payment-gateways-crud.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/payment-gateways/payment-gateways-crud.test.js @@ -1,170 +1,176 @@ const { test, expect } = require( '../../../fixtures/api-tests-fixtures' ); test.describe( 'Payment Gateways API tests', () => { - test( 'can view all payment gateways', async ( { request } ) => { - // call API to retrieve the payment gateways - const response = await request.get( '/wp-json/wc/v3/payment_gateways' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); + test( + 'can view all payment gateways', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + async ( { request } ) => { + // call API to retrieve the payment gateways + const response = await request.get( + '/wp-json/wc/v3/payment_gateways' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); - const localPickupKey = - // eslint-disable-next-line playwright/no-conditional-in-test - process.env.BASE_URL && - ! process.env.BASE_URL.includes( 'localhost' ) - ? 'pickup_location' - : 'local_pickup'; - console.log( 'localPickupKey=', localPickupKey ); + const localPickupKey = + // eslint-disable-next-line playwright/no-conditional-in-test + process.env.BASE_URL && + ! process.env.BASE_URL.includes( 'localhost' ) + ? 'pickup_location' + : 'local_pickup'; + console.log( 'localPickupKey=', localPickupKey ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'bacs', - title: 'Direct bank transfer', - description: - 'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.', - order: '', - enabled: false, - method_title: 'Direct bank transfer', - method_description: - 'Take payments in person via BACS. More commonly known as direct bank/wire transfer.', - method_supports: [ 'products' ], - settings: { - title: { - id: 'title', - label: 'Title', - description: - 'This controls the title which the user sees during checkout.', - type: 'safe_text', - value: 'Direct bank transfer', - default: 'Direct bank transfer', - tip: 'This controls the title which the user sees during checkout.', - placeholder: '', + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'bacs', + title: 'Direct bank transfer', + description: + 'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.', + order: '', + enabled: false, + method_title: 'Direct bank transfer', + method_description: + 'Take payments in person via BACS. More commonly known as direct bank/wire transfer.', + method_supports: [ 'products' ], + settings: { + title: { + id: 'title', + label: 'Title', + description: + 'This controls the title which the user sees during checkout.', + type: 'safe_text', + value: 'Direct bank transfer', + default: 'Direct bank transfer', + tip: 'This controls the title which the user sees during checkout.', + placeholder: '', + }, + instructions: { + id: 'instructions', + label: 'Instructions', + description: + 'Instructions that will be added to the thank you page and emails.', + type: 'textarea', + value: '', + default: '', + tip: 'Instructions that will be added to the thank you page and emails.', + placeholder: '', + }, }, - instructions: { - id: 'instructions', - label: 'Instructions', - description: - 'Instructions that will be added to the thank you page and emails.', - type: 'textarea', - value: '', - default: '', - tip: 'Instructions that will be added to the thank you page and emails.', - placeholder: '', - }, - }, - } ), + } ), - expect.objectContaining( { - id: 'cheque', - title: 'Check payments', - description: - 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', - order: '', - enabled: false, - method_title: 'Check payments', - method_description: - 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', - method_supports: [ 'products' ], - settings: { - title: { - id: 'title', - label: 'Title', - description: - 'This controls the title which the user sees during checkout.', - type: 'safe_text', - value: 'Check payments', - default: 'Check payments', - tip: 'This controls the title which the user sees during checkout.', - placeholder: '', + expect.objectContaining( { + id: 'cheque', + title: 'Check payments', + description: + 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', + order: '', + enabled: false, + method_title: 'Check payments', + method_description: + 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', + method_supports: [ 'products' ], + settings: { + title: { + id: 'title', + label: 'Title', + description: + 'This controls the title which the user sees during checkout.', + type: 'safe_text', + value: 'Check payments', + default: 'Check payments', + tip: 'This controls the title which the user sees during checkout.', + placeholder: '', + }, + instructions: { + id: 'instructions', + label: 'Instructions', + description: + 'Instructions that will be added to the thank you page and emails.', + type: 'textarea', + value: '', + default: '', + tip: 'Instructions that will be added to the thank you page and emails.', + placeholder: '', + }, }, - instructions: { - id: 'instructions', - label: 'Instructions', - description: - 'Instructions that will be added to the thank you page and emails.', - type: 'textarea', - value: '', - default: '', - tip: 'Instructions that will be added to the thank you page and emails.', - placeholder: '', - }, - }, - } ), + } ), - expect.objectContaining( { - id: 'cod', - title: 'Cash on delivery', - description: 'Pay with cash upon delivery.', - order: '', - enabled: false, - method_title: 'Cash on delivery', - method_description: - 'Have your customers pay with cash (or by other means) upon delivery.', - method_supports: [ 'products' ], - settings: { - title: { - id: 'title', - label: 'Title', - description: - 'Payment method description that the customer will see on your checkout.', - type: 'safe_text', - value: 'Cash on delivery', - default: 'Cash on delivery', - tip: 'Payment method description that the customer will see on your checkout.', - placeholder: '', - }, - instructions: { - id: 'instructions', - label: 'Instructions', - description: - 'Instructions that will be added to the thank you page.', - type: 'textarea', - value: 'Pay with cash upon delivery.', - default: 'Pay with cash upon delivery.', - tip: 'Instructions that will be added to the thank you page.', - placeholder: '', - }, - enable_for_methods: { - id: 'enable_for_methods', - label: 'Enable for shipping methods', - description: - 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', - type: 'multiselect', - value: '', - default: '', - tip: 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', - placeholder: '', - options: expect.objectContaining( { - 'Flat rate': { - flat_rate: - 'Any "Flat rate" method', - }, - 'Free shipping': { - free_shipping: - 'Any "Free shipping" method', - }, - 'Local pickup': expect.objectContaining( { - [ localPickupKey ]: - 'Any "Local pickup" method', + expect.objectContaining( { + id: 'cod', + title: 'Cash on delivery', + description: 'Pay with cash upon delivery.', + order: '', + enabled: false, + method_title: 'Cash on delivery', + method_description: + 'Have your customers pay with cash (or by other means) upon delivery.', + method_supports: [ 'products' ], + settings: { + title: { + id: 'title', + label: 'Title', + description: + 'Payment method description that the customer will see on your checkout.', + type: 'safe_text', + value: 'Cash on delivery', + default: 'Cash on delivery', + tip: 'Payment method description that the customer will see on your checkout.', + placeholder: '', + }, + instructions: { + id: 'instructions', + label: 'Instructions', + description: + 'Instructions that will be added to the thank you page.', + type: 'textarea', + value: 'Pay with cash upon delivery.', + default: 'Pay with cash upon delivery.', + tip: 'Instructions that will be added to the thank you page.', + placeholder: '', + }, + enable_for_methods: { + id: 'enable_for_methods', + label: 'Enable for shipping methods', + description: + 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', + type: 'multiselect', + value: '', + default: '', + tip: 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', + placeholder: '', + options: expect.objectContaining( { + 'Flat rate': { + flat_rate: + 'Any "Flat rate" method', + }, + 'Free shipping': { + free_shipping: + 'Any "Free shipping" method', + }, + 'Local pickup': expect.objectContaining( { + [ localPickupKey ]: + 'Any "Local pickup" method', + } ), } ), - } ), + }, + enable_for_virtual: { + id: 'enable_for_virtual', + label: 'Accept COD if the order is virtual', + description: '', + type: 'checkbox', + value: 'yes', + default: 'yes', + tip: '', + placeholder: '', + }, }, - enable_for_virtual: { - id: 'enable_for_virtual', - label: 'Accept COD if the order is virtual', - description: '', - type: 'checkbox', - value: 'yes', - default: 'yes', - tip: '', - placeholder: '', - }, - }, - } ), - ] ) - ); - } ); + } ), + ] ) + ); + } + ); test( 'can view a payment gateway', async ( { request } ) => { // call API to retrieve a single payment gateway diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/product-list.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/product-list.test.js index 03f51112b37..d9faf15633c 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/product-list.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/product-list.test.js @@ -2230,1077 +2230,1170 @@ test.describe( 'Products API tests: List All Products', () => { await deleteSampleData( sampleData ); }, 10000 ); - test.describe( 'List all products', () => { - test( 'defaults', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - search: 'xxx', - }, + test.describe( + 'List all products', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + () => { + test( 'defaults', async ( { request } ) => { + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + search: 'xxx', + }, + } ); + + expect( result.status() ).toEqual( 200 ); + expect( result.headers()[ 'x-wp-total' ] ).toEqual( + PRODUCTS_COUNT.toString() + ); + expect( result.headers()[ 'x-wp-totalpages' ] ).toEqual( '2' ); } ); - expect( result.status() ).toEqual( 200 ); - expect( result.headers()[ 'x-wp-total' ] ).toEqual( - PRODUCTS_COUNT.toString() - ); - expect( result.headers()[ 'x-wp-totalpages' ] ).toEqual( '2' ); - } ); + test( 'pagination', async ( { request } ) => { + const pageSize = 6; + const page1 = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: pageSize, + search: 'xxx', + }, + } ); + const page1JSON = await page1.json(); + const page2 = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: pageSize, + page: 2, + search: 'xxx', + }, + } ); + const page2JSON = await page2.json(); + expect( page1.status() ).toEqual( 200 ); + expect( page2.status() ).toEqual( 200 ); - test( 'pagination', async ( { request } ) => { - const pageSize = 6; - const page1 = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: pageSize, - search: 'xxx', - }, - } ); - const page1JSON = await page1.json(); - const page2 = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: pageSize, - page: 2, - search: 'xxx', - }, - } ); - const page2JSON = await page2.json(); - expect( page1.status() ).toEqual( 200 ); - expect( page2.status() ).toEqual( 200 ); + // Verify total page count. + expect( page1.headers()[ 'x-wp-total' ] ).toEqual( + PRODUCTS_COUNT.toString() + ); + expect( page1.headers()[ 'x-wp-totalpages' ] ).toEqual( '4' ); - // Verify total page count. - expect( page1.headers()[ 'x-wp-total' ] ).toEqual( - PRODUCTS_COUNT.toString() - ); - expect( page1.headers()[ 'x-wp-totalpages' ] ).toEqual( '4' ); + // Verify we get pageSize'd arrays. + expect( Array.isArray( page1JSON ) ).toBe( true ); + expect( Array.isArray( page2JSON ) ).toBe( true ); + expect( page1JSON ).toHaveLength( pageSize ); + expect( page2JSON ).toHaveLength( pageSize ); - // Verify we get pageSize'd arrays. - expect( Array.isArray( page1JSON ) ).toBe( true ); - expect( Array.isArray( page2JSON ) ).toBe( true ); - expect( page1JSON ).toHaveLength( pageSize ); - expect( page2JSON ).toHaveLength( pageSize ); + // Ensure all of the product IDs are unique (no page overlap). + const allProductIds = page1JSON + .concat( page2JSON ) + .reduce( ( acc, product ) => { + acc[ product.id ] = 1; + return acc; + }, {} ); + expect( Object.keys( allProductIds ) ).toHaveLength( + pageSize * 2 + ); - // Ensure all of the product IDs are unique (no page overlap). - const allProductIds = page1JSON - .concat( page2JSON ) - .reduce( ( acc, product ) => { - acc[ product.id ] = 1; - return acc; - }, {} ); - expect( Object.keys( allProductIds ) ).toHaveLength( pageSize * 2 ); - - // Verify that offset takes precedent over page number. - const page2Offset = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: pageSize, - page: 2, - offset: pageSize + 1, - search: 'xxx', - }, - } ); - const page2OffsetJSON = await page2Offset.json(); - // The offset pushes the result set 1 product past the start of page 2. - expect( page2OffsetJSON ).toEqual( - expect.not.arrayContaining( [ - expect.objectContaining( { - id: page2JSON[ 0 ].id, - } ), - ] ) - ); - expect( page2OffsetJSON[ 0 ].id ).toEqual( page2JSON[ 1 ].id ); - - // Verify the last page only has 2 products as we expect. - const lastPage = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: pageSize, - page: 4, - search: 'xxx', - }, - } ); - const lastPageJSON = await lastPage.json(); - expect( Array.isArray( lastPageJSON ) ).toBe( true ); - expect( lastPageJSON ).toHaveLength( 2 ); - - // Verify a page outside the total page count is empty. - const page6 = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: pageSize, - page: 6, - search: 'xxx', - }, - } ); - const page6JSON = await page6.json(); - expect( Array.isArray( page6JSON ) ).toBe( true ); - expect( page6JSON ).toHaveLength( 0 ); - } ); - - test( 'search', async ( { request } ) => { - // Match in the short description. - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - search: 'external', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON.length ).toBeGreaterThanOrEqual( 1 ); - expect( result1JSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - name: 'WordPress Pennant xxx', - } ), - ] ) - ); - - // Match in the product name. - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - search: 'pocket xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 1 ); - expect( result2JSON[ 0 ].name ).toBe( 'Hoodie with Pocket xxx' ); - } ); - - test( 'inclusion / exclusion', async ( { request } ) => { - const allProducts = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: 20, - search: 'xxx', - }, - } ); - const allProductsJSON = await allProducts.json(); - expect( allProducts.status() ).toEqual( 200 ); - const allProductIds = allProductsJSON.map( - ( product ) => product.id - ); - expect( allProductIds ).toHaveLength( PRODUCTS_COUNT ); - - const productsToFilter = [ - allProductIds[ 2 ], - allProductIds[ 4 ], - allProductIds[ 7 ], - allProductIds[ 13 ], - ]; - - const included = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: 20, - include: productsToFilter.join( ',' ), - }, - } ); - const includedJSON = await included.json(); - expect( included.status() ).toEqual( 200 ); - expect( includedJSON ).toHaveLength( productsToFilter.length ); - expect( includedJSON ).toEqual( - expect.arrayContaining( - productsToFilter.map( ( id ) => + // Verify that offset takes precedent over page number. + const page2Offset = await request.get( + 'wp-json/wc/v3/products', + { + params: { + per_page: pageSize, + page: 2, + offset: pageSize + 1, + search: 'xxx', + }, + } + ); + const page2OffsetJSON = await page2Offset.json(); + // The offset pushes the result set 1 product past the start of page 2. + expect( page2OffsetJSON ).toEqual( + expect.not.arrayContaining( [ expect.objectContaining( { - id, - } ) - ) - ) - ); + id: page2JSON[ 0 ].id, + } ), + ] ) + ); + expect( page2OffsetJSON[ 0 ].id ).toEqual( page2JSON[ 1 ].id ); - const excluded = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: 20, - exclude: productsToFilter.join( ',' ), - }, + // Verify the last page only has 2 products as we expect. + const lastPage = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: pageSize, + page: 4, + search: 'xxx', + }, + } ); + const lastPageJSON = await lastPage.json(); + expect( Array.isArray( lastPageJSON ) ).toBe( true ); + expect( lastPageJSON ).toHaveLength( 2 ); + + // Verify a page outside the total page count is empty. + const page6 = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: pageSize, + page: 6, + search: 'xxx', + }, + } ); + const page6JSON = await page6.json(); + expect( Array.isArray( page6JSON ) ).toBe( true ); + expect( page6JSON ).toHaveLength( 0 ); } ); - const excludedJSON = await excluded.json(); - expect( excluded.status() ).toEqual( 200 ); - expect( excludedJSON.length ).toBeGreaterThanOrEqual( - Number( PRODUCTS_COUNT - productsToFilter.length ) - ); - expect( excludedJSON ).toEqual( - expect.not.arrayContaining( - productsToFilter.map( ( id ) => + + test( 'search', async ( { request } ) => { + // Match in the short description. + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + search: 'external', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON.length ).toBeGreaterThanOrEqual( 1 ); + expect( result1JSON ).toEqual( + expect.arrayContaining( [ expect.objectContaining( { - id, - } ) + name: 'WordPress Pennant xxx', + } ), + ] ) + ); + + // Match in the product name. + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + search: 'pocket xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 1 ); + expect( result2JSON[ 0 ].name ).toBe( + 'Hoodie with Pocket xxx' + ); + } ); + + test( 'inclusion / exclusion', async ( { request } ) => { + const allProducts = await request.get( + 'wp-json/wc/v3/products', + { + params: { + per_page: 20, + search: 'xxx', + }, + } + ); + const allProductsJSON = await allProducts.json(); + expect( allProducts.status() ).toEqual( 200 ); + const allProductIds = allProductsJSON.map( + ( product ) => product.id + ); + expect( allProductIds ).toHaveLength( PRODUCTS_COUNT ); + + const productsToFilter = [ + allProductIds[ 2 ], + allProductIds[ 4 ], + allProductIds[ 7 ], + allProductIds[ 13 ], + ]; + + const included = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: 20, + include: productsToFilter.join( ',' ), + }, + } ); + const includedJSON = await included.json(); + expect( included.status() ).toEqual( 200 ); + expect( includedJSON ).toHaveLength( productsToFilter.length ); + expect( includedJSON ).toEqual( + expect.arrayContaining( + productsToFilter.map( ( id ) => + expect.objectContaining( { + id, + } ) + ) ) - ) + ); + + const excluded = await request.get( 'wp-json/wc/v3/products', { + params: { + per_page: 20, + exclude: productsToFilter.join( ',' ), + }, + } ); + const excludedJSON = await excluded.json(); + expect( excluded.status() ).toEqual( 200 ); + expect( excludedJSON.length ).toBeGreaterThanOrEqual( + Number( PRODUCTS_COUNT - productsToFilter.length ) + ); + expect( excludedJSON ).toEqual( + expect.not.arrayContaining( + productsToFilter.map( ( id ) => + expect.objectContaining( { + id, + } ) + ) + ) + ); + } ); + + test( 'slug', async ( { request } ) => { + // Match by slug. + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + slug: 't-shirt-with-logo-xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].slug ).toBe( 't-shirt-with-logo-xxx' ); + + // No matches + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + slug: 'no-product-with-this-slug', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 0 ); + } ); + + test( 'sku', async ( { request } ) => { + // Match by SKU. + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + sku: 'woo-sunglasses-product', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].sku ).toBe( 'woo-sunglasses-product' ); + + // No matches + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + sku: 'no-product-with-this-sku', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 0 ); + } ); + + test( 'type', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + type: 'simple', + search: 'xxx', + }, + } ); + expect( result1.status() ).toEqual( 200 ); + expect( result1.headers()[ 'x-wp-total' ] ).toEqual( '16' ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + type: 'external', + search: 'xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 1 ); + expect( result2JSON[ 0 ].name ).toBe( 'WordPress Pennant xxx' ); + + const result3 = await request.get( 'wp-json/wc/v3/products', { + params: { + type: 'variable', + search: 'xxx', + }, + } ); + const result3JSON = await result3.json(); + expect( result3.status() ).toEqual( 200 ); + expect( result3JSON ).toHaveLength( 2 ); + + const result4 = await request.get( 'wp-json/wc/v3/products', { + params: { + type: 'grouped', + search: 'xxx', + }, + } ); + const result4JSON = await result4.json(); + expect( result4.status() ).toEqual( 200 ); + expect( result4JSON ).toHaveLength( 1 ); + expect( result4JSON[ 0 ].name ).toBe( 'Logo Collection xxx' ); + } ); + + test( 'featured', async ( { request } ) => { + const featured = [ + expect.objectContaining( { + name: 'Hoodie with Zipper xxx', + } ), + expect.objectContaining( { + name: 'Hoodie with Pocket xxx', + } ), + expect.objectContaining( { + name: 'Sunglasses xxx', + } ), + expect.objectContaining( { + name: 'Cap xxx', + } ), + expect.objectContaining( { + name: 'V-Neck T-Shirt xxx', + } ), + ]; + + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + featured: true, + search: 'xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( featured.length ); + expect( result1JSON ).toEqual( + expect.arrayContaining( featured ) + ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + featured: false, + search: 'xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( featured ) + ); + } ); + + test( + 'categories', + { tag: '@skip-on-default-wpcom' }, + async ( { request } ) => { + const accessory = [ + expect.objectContaining( { + name: 'Beanie xxx', + } ), + ]; + const hoodies = [ + expect.objectContaining( { + name: 'Hoodie with Zipper xxx', + } ), + expect.objectContaining( { + name: 'Hoodie with Pocket xxx', + } ), + expect.objectContaining( { + name: 'Hoodie with Logo xxx', + } ), + expect.objectContaining( { + name: 'Hoodie xxx', + } ), + ]; + + // Verify that subcategories are included. + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + per_page: 20, + category: sampleData.categories.clothingJSON.id, + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toEqual( + expect.arrayContaining( accessory ) + ); + expect( result1JSON ).toEqual( + expect.arrayContaining( hoodies ) + ); + + // Verify sibling categories are not. + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + category: sampleData.categories.hoodiesJSON.id, + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( accessory ) + ); + expect( result2JSON ).toEqual( + expect.arrayContaining( hoodies ) + ); + } ); - } ); - test( 'slug', async ( { request } ) => { - // Match by slug. - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - slug: 't-shirt-with-logo-xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].slug ).toBe( 't-shirt-with-logo-xxx' ); - - // No matches - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - slug: 'no-product-with-this-slug', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 0 ); - } ); - - test( 'sku', async ( { request } ) => { - // Match by SKU. - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - sku: 'woo-sunglasses-product', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].sku ).toBe( 'woo-sunglasses-product' ); - - // No matches - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - sku: 'no-product-with-this-sku', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 0 ); - } ); - - test( 'type', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - type: 'simple', - search: 'xxx', - }, - } ); - expect( result1.status() ).toEqual( 200 ); - expect( result1.headers()[ 'x-wp-total' ] ).toEqual( '16' ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - type: 'external', - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 1 ); - expect( result2JSON[ 0 ].name ).toBe( 'WordPress Pennant xxx' ); - - const result3 = await request.get( 'wp-json/wc/v3/products', { - params: { - type: 'variable', - search: 'xxx', - }, - } ); - const result3JSON = await result3.json(); - expect( result3.status() ).toEqual( 200 ); - expect( result3JSON ).toHaveLength( 2 ); - - const result4 = await request.get( 'wp-json/wc/v3/products', { - params: { - type: 'grouped', - search: 'xxx', - }, - } ); - const result4JSON = await result4.json(); - expect( result4.status() ).toEqual( 200 ); - expect( result4JSON ).toHaveLength( 1 ); - expect( result4JSON[ 0 ].name ).toBe( 'Logo Collection xxx' ); - } ); - - test( 'featured', async ( { request } ) => { - const featured = [ - expect.objectContaining( { - name: 'Hoodie with Zipper xxx', - } ), - expect.objectContaining( { - name: 'Hoodie with Pocket xxx', - } ), - expect.objectContaining( { - name: 'Sunglasses xxx', - } ), - expect.objectContaining( { - name: 'Cap xxx', - } ), - expect.objectContaining( { - name: 'V-Neck T-Shirt xxx', - } ), - ]; - - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - featured: true, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( featured.length ); - expect( result1JSON ).toEqual( expect.arrayContaining( featured ) ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - featured: false, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( featured ) - ); - } ); - - test( 'categories', async ( { request } ) => { - const accessory = [ - expect.objectContaining( { - name: 'Beanie xxx', - } ), - ]; - const hoodies = [ - expect.objectContaining( { - name: 'Hoodie with Zipper xxx', - } ), - expect.objectContaining( { - name: 'Hoodie with Pocket xxx', - } ), - expect.objectContaining( { - name: 'Hoodie with Logo xxx', - } ), - expect.objectContaining( { - name: 'Hoodie xxx', - } ), - ]; - - // Verify that subcategories are included. - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - per_page: 20, - category: sampleData.categories.clothingJSON.id, - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toEqual( - expect.arrayContaining( accessory ) - ); - expect( result1JSON ).toEqual( expect.arrayContaining( hoodies ) ); - - // Verify sibling categories are not. - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - category: sampleData.categories.hoodiesJSON.id, - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( accessory ) - ); - expect( result2JSON ).toEqual( expect.arrayContaining( hoodies ) ); - } ); - - test( 'on sale', async ( { request } ) => { - const onSale = [ - expect.objectContaining( { - name: 'Beanie with Logo xxx', - } ), - expect.objectContaining( { - name: 'Hoodie with Pocket xxx', - } ), - expect.objectContaining( { - name: 'Single xxx', - } ), - expect.objectContaining( { - name: 'Cap xxx', - } ), - expect.objectContaining( { - name: 'Belt xxx', - } ), - expect.objectContaining( { - name: 'Beanie xxx', - } ), - expect.objectContaining( { - name: 'Hoodie xxx', - } ), - ]; - - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - on_sale: true, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( onSale.length ); - expect( result1JSON ).toEqual( expect.arrayContaining( onSale ) ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - on_sale: false, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( onSale ) - ); - } ); - - test( 'price', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - min_price: 21, - max_price: 28, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].name ).toBe( 'Long Sleeve Tee xxx' ); - expect( result1JSON[ 0 ].price ).toBe( '25' ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - max_price: 5, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 1 ); - expect( result2JSON[ 0 ].name ).toBe( 'Single xxx' ); - expect( result2JSON[ 0 ].price ).toBe( '2' ); - - const result3 = await request.get( 'wp-json/wc/v3/products', { - params: { - min_price: 5, - order: 'asc', - orderby: 'price', - search: 'xxx', - }, - } ); - const result3JSON = await result3.json(); - expect( result3.status() ).toEqual( 200 ); - expect( result3JSON ).toEqual( - expect.not.arrayContaining( [ + test( 'on sale', async ( { request } ) => { + const onSale = [ + expect.objectContaining( { + name: 'Beanie with Logo xxx', + } ), + expect.objectContaining( { + name: 'Hoodie with Pocket xxx', + } ), expect.objectContaining( { name: 'Single xxx', } ), - ] ) - ); - } ); + expect.objectContaining( { + name: 'Cap xxx', + } ), + expect.objectContaining( { + name: 'Belt xxx', + } ), + expect.objectContaining( { + name: 'Beanie xxx', + } ), + expect.objectContaining( { + name: 'Hoodie xxx', + } ), + ]; - test( 'before / after', async ( { request } ) => { - const before = [ - expect.objectContaining( { - name: 'Album xxx', - } ), - expect.objectContaining( { - name: 'Single xxx', - } ), - expect.objectContaining( { - name: 'T-Shirt with Logo xxx', - } ), - expect.objectContaining( { - name: 'Beanie with Logo xxx', - } ), - ]; - const after = [ - expect.objectContaining( { - name: 'Hoodie xxx', - } ), - expect.objectContaining( { - name: 'V-Neck T-Shirt xxx', - } ), - expect.objectContaining( { - name: 'Parent Product xxx', - } ), - expect.objectContaining( { - name: 'Child Product xxx', - } ), - ]; + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + on_sale: true, + search: 'xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( onSale.length ); + expect( result1JSON ).toEqual( + expect.arrayContaining( onSale ) + ); - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - before: '2021-09-05T15:50:19', - search: 'xxx', - }, + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + on_sale: false, + search: 'xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( onSale ) + ); } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( before.length ); - expect( result1JSON ).toEqual( expect.arrayContaining( before ) ); - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - after: '2021-09-18T15:50:18', - search: 'xxx', - }, + test( 'price', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + min_price: 21, + max_price: 28, + search: 'xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].name ).toBe( 'Long Sleeve Tee xxx' ); + expect( result1JSON[ 0 ].price ).toBe( '25' ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + max_price: 5, + search: 'xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 1 ); + expect( result2JSON[ 0 ].name ).toBe( 'Single xxx' ); + expect( result2JSON[ 0 ].price ).toBe( '2' ); + + const result3 = await request.get( 'wp-json/wc/v3/products', { + params: { + min_price: 5, + order: 'asc', + orderby: 'price', + search: 'xxx', + }, + } ); + const result3JSON = await result3.json(); + expect( result3.status() ).toEqual( 200 ); + expect( result3JSON ).toEqual( + expect.not.arrayContaining( [ + expect.objectContaining( { + name: 'Single xxx', + } ), + ] ) + ); } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( before ) - ); - expect( result2JSON ).toHaveLength( after.length ); - expect( result2JSON ).toEqual( expect.arrayContaining( after ) ); - } ); - test( 'attributes', async ( { request } ) => { - const red = sampleData.attributes.colors.find( - ( term ) => term.name === 'Red' - ); - - const redProducts = [ - expect.objectContaining( { - name: 'V-Neck T-Shirt xxx', - } ), - expect.objectContaining( { - name: 'Hoodie xxx', - } ), - expect.objectContaining( { - name: 'Beanie xxx', - } ), - expect.objectContaining( { - name: 'Beanie with Logo xxx', - } ), - ]; - - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - attribute: 'pa_colorxxx', - attribute_term: red.id, - }, - } ); - const resultJSON = await result.json(); - - expect( result.status() ).toEqual( 200 ); - expect( resultJSON ).toHaveLength( redProducts.length ); - expect( resultJSON ).toEqual( - expect.arrayContaining( redProducts ) - ); - } ); - - test( 'status', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - status: 'pending', - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].name ).toBe( 'Polo xxx' ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - status: 'draft', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( 0 ); - } ); - - test( 'shipping class', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - shipping_class: sampleData.shippingClasses.freightJSON.id, - }, - } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); - expect( resultJSON ).toHaveLength( 1 ); - expect( resultJSON[ 0 ].name ).toBe( 'Long Sleeve Tee xxx' ); - } ); - - test( 'tax class', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - tax_class: 'reduced-rate', - search: 'xxx', - }, - } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); - expect( resultJSON ).toHaveLength( 1 ); - expect( resultJSON[ 0 ].name ).toBe( 'Sunglasses xxx' ); - } ); - - test( 'stock status', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - stock_status: 'onbackorder', - search: 'xxx', - }, - } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); - expect( resultJSON ).toHaveLength( 1 ); - expect( resultJSON[ 0 ].name ).toBe( 'T-Shirt xxx' ); - } ); - - test( 'tags', async ( { request } ) => { - const coolProducts = [ - expect.objectContaining( { - name: 'Sunglasses xxx', - } ), - expect.objectContaining( { - name: 'Hoodie with Pocket xxx', - } ), - expect.objectContaining( { - name: 'Beanie xxx', - } ), - ]; - - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - tag: sampleData.tags.coolJSON.id, - }, - } ); - const resultJSON = await result.json(); - - expect( result.status() ).toEqual( 200 ); - expect( resultJSON ).toHaveLength( coolProducts.length ); - expect( resultJSON ).toEqual( - expect.arrayContaining( coolProducts ) - ); - } ); - - test( 'parent', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - parent: sampleData.hierarchicalProducts.parentJSON.id, - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( 1 ); - expect( result1JSON[ 0 ].name ).toBe( 'Child Product xxx' ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - parent_exclude: - sampleData.hierarchicalProducts.parentJSON.id, - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toEqual( - expect.not.arrayContaining( [ + test( 'before / after', async ( { request } ) => { + const before = [ + expect.objectContaining( { + name: 'Album xxx', + } ), + expect.objectContaining( { + name: 'Single xxx', + } ), + expect.objectContaining( { + name: 'T-Shirt with Logo xxx', + } ), + expect.objectContaining( { + name: 'Beanie with Logo xxx', + } ), + ]; + const after = [ + expect.objectContaining( { + name: 'Hoodie xxx', + } ), + expect.objectContaining( { + name: 'V-Neck T-Shirt xxx', + } ), + expect.objectContaining( { + name: 'Parent Product xxx', + } ), expect.objectContaining( { name: 'Child Product xxx', } ), - ] ) - ); - } ); - - test.describe( 'orderby', () => { - const productNamesAsc = [ - 'Album xxx', - 'Beanie with Logo xxx', - 'Beanie xxx', - 'Belt xxx', - 'Cap xxx', - 'Child Product xxx', - 'Hoodie with Logo xxx', - 'Hoodie with Pocket xxx', - 'Hoodie with Zipper xxx', - 'Hoodie xxx', - 'Logo Collection xxx', - 'Long Sleeve Tee xxx', - 'Parent Product xxx', - 'Polo xxx', - 'Single xxx', - 'Sunglasses xxx', - 'T-Shirt with Logo xxx', - 'T-Shirt xxx', - 'V-Neck T-Shirt xxx', - 'WordPress Pennant xxx', - ]; - const productNamesDesc = [ ...productNamesAsc ].reverse(); - const productNamesByRatingAsc = [ - 'Sunglasses xxx', - 'Cap xxx', - 'T-Shirt xxx', - ]; - const productNamesByRatingDesc = [ - ...productNamesByRatingAsc, - ].reverse(); - const productNamesByPopularityDesc = [ - 'Beanie with Logo xxx', - 'Single xxx', - 'T-Shirt xxx', - ]; - const productNamesByPopularityAsc = [ - ...productNamesByPopularityDesc, - ].reverse(); - - test( 'default', async ( { request } ) => { - // Default = date desc. - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - search: 'xxx', - }, - } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); - - // Verify all dates are in descending order. - let lastDate = Date.now(); - resultJSON.forEach( ( { date_created_gmt } ) => { - const created = Date.parse( date_created_gmt + '.000Z' ); - expect( lastDate ).toBeGreaterThan( created ); - lastDate = created; - } ); - } ); - - test( 'date', async ( { request } ) => { - const result = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'date', - search: 'xxx', - }, - } ); - const resultJSON = await result.json(); - expect( result.status() ).toEqual( 200 ); - - // Verify all dates are in ascending order. - let lastDate = 0; - resultJSON.forEach( ( { date_created_gmt } ) => { - const created = Date.parse( date_created_gmt + '.000Z' ); - expect( created ).toBeGreaterThan( lastDate ); - lastDate = created; - } ); - } ); - - test( 'id', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'id', - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - - // Verify all results are in ascending order. - let lastId = 0; - result1JSON.forEach( ( { id } ) => { - expect( id ).toBeGreaterThan( lastId ); - lastId = id; - } ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'id', - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - - // Verify all results are in descending order. - lastId = Number.MAX_SAFE_INTEGER; - result2JSON.forEach( ( { id } ) => { - expect( lastId ).toBeGreaterThan( id ); - lastId = id; - } ); - } ); - - test( 'title', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'title', - per_page: productNamesAsc.length, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - - // Verify all results are in ascending order. - result1JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesAsc[ idx ] ); - } ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'title', - per_page: productNamesDesc.length, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - - // Verify all results are in descending order. - result2JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesDesc[ idx ] ); - } ); - } ); - - test( 'slug orderby', async ( { request } ) => { - const productNamesBySlugAsc = [ - 'Polo xxx', // The Polo isn't published so it has an empty slug. - ...productNamesAsc.filter( ( p ) => p !== 'Polo xxx' ), ]; - const productNamesBySlugDesc = [ - ...productNamesBySlugAsc, + + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + before: '2021-09-05T15:50:19', + search: 'xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( before.length ); + expect( result1JSON ).toEqual( + expect.arrayContaining( before ) + ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + after: '2021-09-18T15:50:18', + search: 'xxx', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( before ) + ); + expect( result2JSON ).toHaveLength( after.length ); + expect( result2JSON ).toEqual( + expect.arrayContaining( after ) + ); + } ); + + test( 'attributes', async ( { request } ) => { + const red = sampleData.attributes.colors.find( + ( term ) => term.name === 'Red' + ); + + const redProducts = [ + expect.objectContaining( { + name: 'V-Neck T-Shirt xxx', + } ), + expect.objectContaining( { + name: 'Hoodie xxx', + } ), + expect.objectContaining( { + name: 'Beanie xxx', + } ), + expect.objectContaining( { + name: 'Beanie with Logo xxx', + } ), + ]; + + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + attribute: 'pa_colorxxx', + attribute_term: red.id, + }, + } ); + const resultJSON = await result.json(); + + expect( result.status() ).toEqual( 200 ); + expect( resultJSON ).toHaveLength( redProducts.length ); + expect( resultJSON ).toEqual( + expect.arrayContaining( redProducts ) + ); + } ); + + test( 'status', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + status: 'pending', + search: 'xxx', + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].name ).toBe( 'Polo xxx' ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + status: 'draft', + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( 0 ); + } ); + + test( 'shipping class', async ( { request } ) => { + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + shipping_class: + sampleData.shippingClasses.freightJSON.id, + }, + } ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); + expect( resultJSON ).toHaveLength( 1 ); + expect( resultJSON[ 0 ].name ).toBe( 'Long Sleeve Tee xxx' ); + } ); + + test( 'tax class', async ( { request } ) => { + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + tax_class: 'reduced-rate', + search: 'xxx', + }, + } ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); + expect( resultJSON ).toHaveLength( 1 ); + expect( resultJSON[ 0 ].name ).toBe( 'Sunglasses xxx' ); + } ); + + test( 'stock status', async ( { request } ) => { + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + stock_status: 'onbackorder', + search: 'xxx', + }, + } ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); + expect( resultJSON ).toHaveLength( 1 ); + expect( resultJSON[ 0 ].name ).toBe( 'T-Shirt xxx' ); + } ); + + test( 'tags', async ( { request } ) => { + const coolProducts = [ + expect.objectContaining( { + name: 'Sunglasses xxx', + } ), + expect.objectContaining( { + name: 'Hoodie with Pocket xxx', + } ), + expect.objectContaining( { + name: 'Beanie xxx', + } ), + ]; + + const result = await request.get( 'wp-json/wc/v3/products', { + params: { + tag: sampleData.tags.coolJSON.id, + }, + } ); + const resultJSON = await result.json(); + + expect( result.status() ).toEqual( 200 ); + expect( resultJSON ).toHaveLength( coolProducts.length ); + expect( resultJSON ).toEqual( + expect.arrayContaining( coolProducts ) + ); + } ); + + test( 'parent', async ( { request } ) => { + const result1 = await request.get( 'wp-json/wc/v3/products', { + params: { + parent: sampleData.hierarchicalProducts.parentJSON.id, + }, + } ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( 1 ); + expect( result1JSON[ 0 ].name ).toBe( 'Child Product xxx' ); + + const result2 = await request.get( 'wp-json/wc/v3/products', { + params: { + parent_exclude: + sampleData.hierarchicalProducts.parentJSON.id, + }, + } ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toEqual( + expect.not.arrayContaining( [ + expect.objectContaining( { + name: 'Child Product xxx', + } ), + ] ) + ); + } ); + + test.describe( 'orderby', () => { + const productNamesAsc = [ + 'Album xxx', + 'Beanie with Logo xxx', + 'Beanie xxx', + 'Belt xxx', + 'Cap xxx', + 'Child Product xxx', + 'Hoodie with Logo xxx', + 'Hoodie with Pocket xxx', + 'Hoodie with Zipper xxx', + 'Hoodie xxx', + 'Logo Collection xxx', + 'Long Sleeve Tee xxx', + 'Parent Product xxx', + 'Polo xxx', + 'Single xxx', + 'Sunglasses xxx', + 'T-Shirt with Logo xxx', + 'T-Shirt xxx', + 'V-Neck T-Shirt xxx', + 'WordPress Pennant xxx', + ]; + const productNamesDesc = [ ...productNamesAsc ].reverse(); + const productNamesByRatingAsc = [ + 'Sunglasses xxx', + 'Cap xxx', + 'T-Shirt xxx', + ]; + const productNamesByRatingDesc = [ + ...productNamesByRatingAsc, + ].reverse(); + const productNamesByPopularityDesc = [ + 'Beanie with Logo xxx', + 'Single xxx', + 'T-Shirt xxx', + ]; + const productNamesByPopularityAsc = [ + ...productNamesByPopularityDesc, ].reverse(); - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'slug', - per_page: productNamesBySlugAsc.length, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); + test( 'default', async ( { request } ) => { + // Default = date desc. + const result = await request.get( + 'wp-json/wc/v3/products', + { + params: { + search: 'xxx', + }, + } + ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); - // Verify all results are in ascending order. - result1JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesBySlugAsc[ idx ] ); + // Verify all dates are in descending order. + let lastDate = Date.now(); + resultJSON.forEach( ( { date_created_gmt } ) => { + const created = Date.parse( + date_created_gmt + '.000Z' + ); + expect( lastDate ).toBeGreaterThan( created ); + lastDate = created; + } ); } ); - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'slug', - per_page: productNamesBySlugDesc.length, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); + test( 'date', async ( { request } ) => { + const result = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'date', + search: 'xxx', + }, + } + ); + const resultJSON = await result.json(); + expect( result.status() ).toEqual( 200 ); - // Verify all results are in descending order. - result2JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesBySlugDesc[ idx ] ); + // Verify all dates are in ascending order. + let lastDate = 0; + resultJSON.forEach( ( { date_created_gmt } ) => { + const created = Date.parse( + date_created_gmt + '.000Z' + ); + expect( created ).toBeGreaterThan( lastDate ); + lastDate = created; + } ); + } ); + + test( 'id', async ( { request } ) => { + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'id', + search: 'xxx', + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + + // Verify all results are in ascending order. + let lastId = 0; + result1JSON.forEach( ( { id } ) => { + expect( id ).toBeGreaterThan( lastId ); + lastId = id; + } ); + + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'id', + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + lastId = Number.MAX_SAFE_INTEGER; + result2JSON.forEach( ( { id } ) => { + expect( lastId ).toBeGreaterThan( id ); + lastId = id; + } ); + } ); + + test( 'title', async ( { request } ) => { + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'title', + per_page: productNamesAsc.length, + search: 'xxx', + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + + // Verify all results are in ascending order. + result1JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesAsc[ idx ] ); + } ); + + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'title', + per_page: productNamesDesc.length, + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + result2JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesDesc[ idx ] ); + } ); + } ); + + test( 'slug orderby', async ( { request } ) => { + const productNamesBySlugAsc = [ + 'Polo xxx', // The Polo isn't published so it has an empty slug. + ...productNamesAsc.filter( ( p ) => p !== 'Polo xxx' ), + ]; + const productNamesBySlugDesc = [ + ...productNamesBySlugAsc, + ].reverse(); + + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'slug', + per_page: productNamesBySlugAsc.length, + search: 'xxx', + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + + // Verify all results are in ascending order. + result1JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesBySlugAsc[ idx ] ); + } ); + + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'slug', + per_page: productNamesBySlugDesc.length, + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + result2JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesBySlugDesc[ idx ] ); + } ); + } ); + + test( 'price orderby', async ( { request } ) => { + const productNamesMinPriceAsc = [ + 'Parent Product xxx', + 'Child Product xxx', + 'Single xxx', + 'WordPress Pennant xxx', + 'Album xxx', + 'V-Neck T-Shirt xxx', + 'Cap xxx', + 'Beanie with Logo xxx', + 'T-Shirt with Logo xxx', + 'Beanie xxx', + 'T-Shirt xxx', + 'Logo Collection xxx', + 'Polo xxx', + 'Long Sleeve Tee xxx', + 'Hoodie with Pocket xxx', + 'Hoodie xxx', + 'Hoodie with Zipper xxx', + 'Hoodie with Logo xxx', + 'Belt xxx', + 'Sunglasses xxx', + ]; + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'price', + per_page: productNamesMinPriceAsc.length, + search: 'xxx', + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( + productNamesMinPriceAsc.length + ); + + // Verify all results are in ascending order. + // The query uses the min price calculated in the product meta lookup table, + // so we can't just check the price property of the response. + result1JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesMinPriceAsc[ idx ] ); + } ); + + const productNamesMaxPriceDesc = [ + 'Sunglasses xxx', + 'Belt xxx', + 'Hoodie xxx', + 'Logo Collection xxx', + 'Hoodie with Logo xxx', + 'Hoodie with Zipper xxx', + 'Hoodie with Pocket xxx', + 'Long Sleeve Tee xxx', + 'V-Neck T-Shirt xxx', + 'Polo xxx', + 'T-Shirt xxx', + 'Beanie xxx', + 'T-Shirt with Logo xxx', + 'Beanie with Logo xxx', + 'Cap xxx', + 'Album xxx', + 'WordPress Pennant xxx', + 'Single xxx', + 'Child Product xxx', + 'Parent Product xxx', + ]; + + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'price', + per_page: productNamesMaxPriceDesc.length, + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( + productNamesMaxPriceDesc.length + ); + + // Verify all results are in descending order. + // The query uses the max price calculated in the product meta lookup table, + // so we can't just check the price property of the response. + result2JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesMaxPriceDesc[ idx ] ); + } ); + } ); + + test( 'include', async ( { request } ) => { + const includeIds = [ + sampleData.groupedProducts[ 0 ].id, + sampleData.simpleProducts[ 3 ].id, + sampleData.hierarchicalProducts.parentJSON.id, + ]; + + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'include', + include: includeIds.join( ',' ), + }, + } + ); + const result1JSON = await result1.json(); + + expect( result1.status() ).toEqual( 200 ); + expect( result1JSON ).toHaveLength( includeIds.length ); + + // Verify all results are in proper order. + result1JSON.forEach( ( { id }, idx ) => { + expect( id ).toBe( includeIds[ idx ] ); + } ); + + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'include', + include: includeIds.join( ',' ), + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + expect( result2JSON ).toHaveLength( includeIds.length ); + + // Verify all results are in proper order. + result2JSON.forEach( ( { id }, idx ) => { + expect( id ).toBe( includeIds[ idx ] ); + } ); + } ); + + test( 'rating (desc)', async ( { request } ) => { + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'rating', + per_page: productNamesByRatingDesc.length, + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + result2JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesByRatingDesc[ idx ] ); + } ); + } ); + + // This case will remain skipped until ratings can be sorted ascending. + // See: https://github.com/woocommerce/woocommerce/issues/30354#issuecomment-925955099. + test.skip( 'rating (asc)', async ( { request } ) => { + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'rating', + per_page: productNamesByRatingAsc.length, + search: 'xxx', + }, + } + ); + expect( result1.status() ).toEqual( 200 ); + const result1JSON = await result1.json(); + + // Verify all results are in ascending order. + result1JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( productNamesByRatingAsc[ idx ] ); + } ); + } ); + + // This case will remain skipped until popularity can be sorted ascending. + // See: https://github.com/woocommerce/woocommerce/issues/30354#issuecomment-925955099. + test.skip( 'popularity (asc)', async ( { request } ) => { + const result1 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'asc', + orderby: 'popularity', + per_page: productNamesByPopularityAsc.length, + search: 'xxx', + }, + } + ); + const result1JSON = await result1.json(); + expect( result1.status() ).toEqual( 200 ); + + // Verify all results are in ascending order. + result1JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( + productNamesByPopularityAsc[ idx ] + ); + } ); + } ); + + test( 'popularity (desc)', async ( { request } ) => { + const result2 = await request.get( + 'wp-json/wc/v3/products', + { + params: { + order: 'desc', + orderby: 'popularity', + per_page: productNamesByPopularityDesc.length, + search: 'xxx', + }, + } + ); + const result2JSON = await result2.json(); + expect( result2.status() ).toEqual( 200 ); + + // Verify all results are in descending order. + result2JSON.forEach( ( { name }, idx ) => { + expect( name ).toBe( + productNamesByPopularityDesc[ idx ] + ); + } ); } ); } ); - - test( 'price orderby', async ( { request } ) => { - const productNamesMinPriceAsc = [ - 'Parent Product xxx', - 'Child Product xxx', - 'Single xxx', - 'WordPress Pennant xxx', - 'Album xxx', - 'V-Neck T-Shirt xxx', - 'Cap xxx', - 'Beanie with Logo xxx', - 'T-Shirt with Logo xxx', - 'Beanie xxx', - 'T-Shirt xxx', - 'Logo Collection xxx', - 'Polo xxx', - 'Long Sleeve Tee xxx', - 'Hoodie with Pocket xxx', - 'Hoodie xxx', - 'Hoodie with Zipper xxx', - 'Hoodie with Logo xxx', - 'Belt xxx', - 'Sunglasses xxx', - ]; - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'price', - per_page: productNamesMinPriceAsc.length, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( - productNamesMinPriceAsc.length - ); - - // Verify all results are in ascending order. - // The query uses the min price calculated in the product meta lookup table, - // so we can't just check the price property of the response. - result1JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesMinPriceAsc[ idx ] ); - } ); - - const productNamesMaxPriceDesc = [ - 'Sunglasses xxx', - 'Belt xxx', - 'Hoodie xxx', - 'Logo Collection xxx', - 'Hoodie with Logo xxx', - 'Hoodie with Zipper xxx', - 'Hoodie with Pocket xxx', - 'Long Sleeve Tee xxx', - 'V-Neck T-Shirt xxx', - 'Polo xxx', - 'T-Shirt xxx', - 'Beanie xxx', - 'T-Shirt with Logo xxx', - 'Beanie with Logo xxx', - 'Cap xxx', - 'Album xxx', - 'WordPress Pennant xxx', - 'Single xxx', - 'Child Product xxx', - 'Parent Product xxx', - ]; - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'price', - per_page: productNamesMaxPriceDesc.length, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( - productNamesMaxPriceDesc.length - ); - - // Verify all results are in descending order. - // The query uses the max price calculated in the product meta lookup table, - // so we can't just check the price property of the response. - result2JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesMaxPriceDesc[ idx ] ); - } ); - } ); - - test( 'include', async ( { request } ) => { - const includeIds = [ - sampleData.groupedProducts[ 0 ].id, - sampleData.simpleProducts[ 3 ].id, - sampleData.hierarchicalProducts.parentJSON.id, - ]; - - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'include', - include: includeIds.join( ',' ), - }, - } ); - const result1JSON = await result1.json(); - - expect( result1.status() ).toEqual( 200 ); - expect( result1JSON ).toHaveLength( includeIds.length ); - - // Verify all results are in proper order. - result1JSON.forEach( ( { id }, idx ) => { - expect( id ).toBe( includeIds[ idx ] ); - } ); - - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'include', - include: includeIds.join( ',' ), - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - expect( result2JSON ).toHaveLength( includeIds.length ); - - // Verify all results are in proper order. - result2JSON.forEach( ( { id }, idx ) => { - expect( id ).toBe( includeIds[ idx ] ); - } ); - } ); - - test( 'rating (desc)', async ( { request } ) => { - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'rating', - per_page: productNamesByRatingDesc.length, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - - // Verify all results are in descending order. - result2JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesByRatingDesc[ idx ] ); - } ); - } ); - - // This case will remain skipped until ratings can be sorted ascending. - // See: https://github.com/woocommerce/woocommerce/issues/30354#issuecomment-925955099. - test.skip( 'rating (asc)', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'rating', - per_page: productNamesByRatingAsc.length, - search: 'xxx', - }, - } ); - expect( result1.status() ).toEqual( 200 ); - const result1JSON = await result1.json(); - - // Verify all results are in ascending order. - result1JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesByRatingAsc[ idx ] ); - } ); - } ); - - // This case will remain skipped until popularity can be sorted ascending. - // See: https://github.com/woocommerce/woocommerce/issues/30354#issuecomment-925955099. - test.skip( 'popularity (asc)', async ( { request } ) => { - const result1 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'asc', - orderby: 'popularity', - per_page: productNamesByPopularityAsc.length, - search: 'xxx', - }, - } ); - const result1JSON = await result1.json(); - expect( result1.status() ).toEqual( 200 ); - - // Verify all results are in ascending order. - result1JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesByPopularityAsc[ idx ] ); - } ); - } ); - - test( 'popularity (desc)', async ( { request } ) => { - const result2 = await request.get( 'wp-json/wc/v3/products', { - params: { - order: 'desc', - orderby: 'popularity', - per_page: productNamesByPopularityDesc.length, - search: 'xxx', - }, - } ); - const result2JSON = await result2.json(); - expect( result2.status() ).toEqual( 200 ); - - // Verify all results are in descending order. - result2JSON.forEach( ( { name }, idx ) => { - expect( name ).toBe( productNamesByPopularityDesc[ idx ] ); - } ); - } ); - } ); - } ); + } + ); } ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/products-crud.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/products-crud.test.js index 64bf5072cfd..cbb39c3aed7 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/products-crud.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/products/products-crud.test.js @@ -589,278 +589,301 @@ test.describe( 'Products API tests: CRUD', () => { } ); } ); - test.describe( 'Product review tests: CRUD', () => { - let productReviewId; - let reviewsTestProduct; + test.describe( + 'Product review tests: CRUD', + { tag: '@skip-on-default-wpcom' }, + () => { + let productReviewId; + let reviewsTestProduct; - test.beforeAll( async ( { simpleTestProduct } ) => { - reviewsTestProduct = simpleTestProduct; - } ); - - test( 'can add a product review', async ( { request } ) => { - const response = await request.post( - 'wp-json/wc/v3/products/reviews', - { - data: { - product_id: reviewsTestProduct.id, - review: 'Nice simple product!', - reviewer: 'John Doe', - reviewer_email: 'john.doe@example.com', - rating: 5, - }, - } - ); - const responseJSON = await response.json(); - productReviewId = responseJSON.id; - - expect( response.status() ).toEqual( 201 ); - expect( typeof productReviewId ).toEqual( 'number' ); - expect( responseJSON.id ).toEqual( productReviewId ); - expect( responseJSON.product_name ).toEqual( 'A Simple Product' ); - expect( responseJSON.status ).toEqual( 'approved' ); - expect( responseJSON.reviewer ).toEqual( 'John Doe' ); - expect( responseJSON.reviewer_email ).toEqual( - 'john.doe@example.com' - ); - expect( responseJSON.review ).toEqual( 'Nice simple product!' ); - expect( responseJSON.rating ).toEqual( 5 ); - expect( responseJSON.verified ).toEqual( false ); - } ); - - test( 'cannot add a product review with invalid product_id', async ( { - request, - } ) => { - const response = await request.post( - 'wp-json/wc/v3/products/reviews', - { - data: { - product_id: 999, - review: 'A non existent product!', - reviewer: 'John Do Not', - reviewer_email: 'john.do.not@example.com', - rating: 5, - }, - } - ); - const responseJSON = await response.json(); - - expect( response.status() ).toEqual( 404 ); - expect( responseJSON.code ).toEqual( - 'woocommerce_rest_product_invalid_id' - ); - expect( responseJSON.message ).toEqual( 'Invalid product ID.' ); - } ); - - test( 'cannot add a duplicate product review', async ( { - request, - } ) => { - const response = await request.post( - 'wp-json/wc/v3/products/reviews', - { - data: { - product_id: reviewsTestProduct.id, - review: 'Nice simple product!', - reviewer: 'John Doe', - reviewer_email: 'john.doe@example.com', - rating: 5, - }, - } - ); - const responseJSON = await response.json(); - - expect( response.status() ).toEqual( 409 ); - expect( responseJSON.code ).toEqual( - 'woocommerce_rest_comment_duplicate' - ); - expect( responseJSON.message ).toEqual( - 'Duplicate comment detected; it looks as though you’ve already said that!' - ); - } ); - - test( 'can retrieve a product review', async ( { request } ) => { - const response = await request.get( - `wp-json/wc/v3/products/reviews/${ productReviewId }` - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.id ).toEqual( productReviewId ); - expect( responseJSON.product_id ).toEqual( reviewsTestProduct.id ); - expect( responseJSON.product_name ).toEqual( 'A Simple Product' ); - expect( responseJSON.status ).toEqual( 'approved' ); - expect( responseJSON.reviewer ).toEqual( 'John Doe' ); - expect( responseJSON.reviewer_email ).toEqual( - 'john.doe@example.com' - ); - expect( responseJSON.review ).toEqual( - '

Nice simple product!

\n' - ); - expect( responseJSON.rating ).toEqual( 5 ); - expect( responseJSON.verified ).toEqual( false ); - } ); - - test( 'can retrieve all product reviews', async ( { request } ) => { - // call API to retrieve all product reviews - const response = await request.get( - '/wp-json/wc/v3/products/reviews' - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON.length ).toBeGreaterThan( 0 ); - } ); - - test( 'can update a product review', async ( { request } ) => { - // call API to retrieve all product reviews - const response = await request.put( - `wp-json/wc/v3/products/reviews/${ productReviewId }`, - { - data: { - rating: 1, - }, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.id ).toEqual( productReviewId ); - expect( responseJSON.product_id ).toEqual( reviewsTestProduct.id ); - expect( responseJSON.product_name ).toEqual( 'A Simple Product' ); - expect( responseJSON.status ).toEqual( 'approved' ); - expect( responseJSON.reviewer ).toEqual( 'John Doe' ); - expect( responseJSON.reviewer_email ).toEqual( - 'john.doe@example.com' - ); - expect( responseJSON.review ).toEqual( 'Nice simple product!' ); - expect( responseJSON.rating ).toEqual( 1 ); - expect( responseJSON.verified ).toEqual( false ); - } ); - - test( 'can permanently delete a product review', async ( { - request, - } ) => { - // Delete the product review. - const response = await request.delete( - `wp-json/wc/v3/products/reviews/${ productReviewId }`, - { - data: { - force: true, - }, - } - ); - expect( response.status() ).toEqual( 200 ); - - // Verify that the product review can no longer be retrieved. - const getDeletedProductReviewResponse = await request.get( - `wp-json/wc/v3/products/reviews/${ productReviewId }` - ); - expect( getDeletedProductReviewResponse.status() ).toEqual( 404 ); - } ); - - test( 'can batch update product reviews', async ( { request } ) => { - // Batch create product reviews. - const response = await request.post( - `wp-json/wc/v3/products/reviews/batch`, - { - data: { - create: [ - { - product_id: reviewsTestProduct.id, - review: 'Nice product!', - reviewer: 'John Doe', - reviewer_email: 'john.doe@example.com', - rating: 4, - }, - { - product_id: reviewsTestProduct.id, - review: 'I love this thing!', - reviewer: 'Jane Doe', - reviewer_email: 'Jane.doe@example.com', - rating: 5, - }, - ], - }, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.create[ 0 ].product_id ).toEqual( - reviewsTestProduct.id - ); - expect( responseJSON.create[ 0 ].review ).toEqual( - 'Nice product!' - ); - expect( responseJSON.create[ 0 ].reviewer ).toEqual( 'John Doe' ); - expect( responseJSON.create[ 0 ].reviewer_email ).toEqual( - 'john.doe@example.com' - ); - expect( responseJSON.create[ 0 ].rating ).toEqual( 4 ); - - expect( responseJSON.create[ 1 ].product_id ).toEqual( - reviewsTestProduct.id - ); - expect( responseJSON.create[ 1 ].review ).toEqual( - 'I love this thing!' - ); - expect( responseJSON.create[ 1 ].reviewer ).toEqual( 'Jane Doe' ); - expect( responseJSON.create[ 1 ].reviewer_email ).toEqual( - 'Jane.doe@example.com' - ); - expect( responseJSON.create[ 1 ].rating ).toEqual( 5 ); - const review1Id = responseJSON.create[ 0 ].id; - const review2Id = responseJSON.create[ 1 ].id; - - // Batch create a new review, update a review and delete another. - const responseBatchUpdate = await request.post( - `wp-json/wc/v3/products/reviews/batch`, - { - data: { - create: [ - { - product_id: reviewsTestProduct.id, - review: 'Ok product.', - reviewer: 'Jack Doe', - reviewer_email: 'jack.doe@example.com', - rating: 3, - }, - ], - update: [ - { - id: review1Id, - review: 'On reflection, I hate this thing!', - rating: 1, - }, - ], - delete: [ review2Id ], - }, - } - ); - const responseBatchUpdateJSON = await responseBatchUpdate.json(); - const review3Id = responseBatchUpdateJSON.create[ 0 ].id; - expect( response.status() ).toEqual( 200 ); - - const responseUpdatedReview = await request.get( - `wp-json/wc/v3/products/reviews/${ review1Id }` - ); - const responseUpdatedReviewJSON = - await responseUpdatedReview.json(); - expect( responseUpdatedReviewJSON.review ).toEqual( - '

On reflection, I hate this thing!

\n' - ); - expect( responseUpdatedReviewJSON.rating ).toEqual( 1 ); - - // Verify that the deleted review can no longer be retrieved. - const getDeletedProductReviewResponse = await request.get( - `wp-json/wc/v3/products/reviews/${ review2Id }` - ); - expect( getDeletedProductReviewResponse.status() ).toEqual( 404 ); - - // Batch delete the created tags - await request.post( `wp-json/wc/v3/products/reviews/batch`, { - data: { - delete: [ review1Id, review3Id ], - }, + test.beforeAll( async ( { simpleTestProduct } ) => { + reviewsTestProduct = simpleTestProduct; } ); - } ); - } ); + + test( 'can add a product review', async ( { request } ) => { + const response = await request.post( + 'wp-json/wc/v3/products/reviews', + { + data: { + product_id: reviewsTestProduct.id, + review: 'Nice simple product!', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + rating: 5, + }, + } + ); + const responseJSON = await response.json(); + productReviewId = responseJSON.id; + + expect( response.status() ).toEqual( 201 ); + expect( typeof productReviewId ).toEqual( 'number' ); + expect( responseJSON.id ).toEqual( productReviewId ); + expect( responseJSON.product_name ).toEqual( + 'A Simple Product' + ); + expect( responseJSON.status ).toEqual( 'approved' ); + expect( responseJSON.reviewer ).toEqual( 'John Doe' ); + expect( responseJSON.reviewer_email ).toEqual( + 'john.doe@example.com' + ); + expect( responseJSON.review ).toEqual( 'Nice simple product!' ); + expect( responseJSON.rating ).toEqual( 5 ); + expect( responseJSON.verified ).toEqual( false ); + } ); + + test( 'cannot add a product review with invalid product_id', async ( { + request, + } ) => { + const response = await request.post( + 'wp-json/wc/v3/products/reviews', + { + data: { + product_id: 999, + review: 'A non existent product!', + reviewer: 'John Do Not', + reviewer_email: 'john.do.not@example.com', + rating: 5, + }, + } + ); + const responseJSON = await response.json(); + + expect( response.status() ).toEqual( 404 ); + expect( responseJSON.code ).toEqual( + 'woocommerce_rest_product_invalid_id' + ); + expect( responseJSON.message ).toEqual( 'Invalid product ID.' ); + } ); + + test( 'cannot add a duplicate product review', async ( { + request, + } ) => { + const response = await request.post( + 'wp-json/wc/v3/products/reviews', + { + data: { + product_id: reviewsTestProduct.id, + review: 'Nice simple product!', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + rating: 5, + }, + } + ); + const responseJSON = await response.json(); + + expect( response.status() ).toEqual( 409 ); + expect( responseJSON.code ).toEqual( + 'woocommerce_rest_comment_duplicate' + ); + expect( responseJSON.message ).toEqual( + 'Duplicate comment detected; it looks as though you’ve already said that!' + ); + } ); + + test( 'can retrieve a product review', async ( { request } ) => { + const response = await request.get( + `wp-json/wc/v3/products/reviews/${ productReviewId }` + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.id ).toEqual( productReviewId ); + expect( responseJSON.product_id ).toEqual( + reviewsTestProduct.id + ); + expect( responseJSON.product_name ).toEqual( + 'A Simple Product' + ); + expect( responseJSON.status ).toEqual( 'approved' ); + expect( responseJSON.reviewer ).toEqual( 'John Doe' ); + expect( responseJSON.reviewer_email ).toEqual( + 'john.doe@example.com' + ); + expect( responseJSON.review ).toEqual( + '

Nice simple product!

\n' + ); + expect( responseJSON.rating ).toEqual( 5 ); + expect( responseJSON.verified ).toEqual( false ); + } ); + + test( 'can retrieve all product reviews', async ( { request } ) => { + // call API to retrieve all product reviews + const response = await request.get( + '/wp-json/wc/v3/products/reviews' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON.length ).toBeGreaterThan( 0 ); + } ); + + test( 'can update a product review', async ( { request } ) => { + // call API to retrieve all product reviews + const response = await request.put( + `wp-json/wc/v3/products/reviews/${ productReviewId }`, + { + data: { + rating: 1, + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.id ).toEqual( productReviewId ); + expect( responseJSON.product_id ).toEqual( + reviewsTestProduct.id + ); + expect( responseJSON.product_name ).toEqual( + 'A Simple Product' + ); + expect( responseJSON.status ).toEqual( 'approved' ); + expect( responseJSON.reviewer ).toEqual( 'John Doe' ); + expect( responseJSON.reviewer_email ).toEqual( + 'john.doe@example.com' + ); + expect( responseJSON.review ).toEqual( 'Nice simple product!' ); + expect( responseJSON.rating ).toEqual( 1 ); + expect( responseJSON.verified ).toEqual( false ); + } ); + + test( 'can permanently delete a product review', async ( { + request, + } ) => { + // Delete the product review. + const response = await request.delete( + `wp-json/wc/v3/products/reviews/${ productReviewId }`, + { + data: { + force: true, + }, + } + ); + expect( response.status() ).toEqual( 200 ); + + // Verify that the product review can no longer be retrieved. + const getDeletedProductReviewResponse = await request.get( + `wp-json/wc/v3/products/reviews/${ productReviewId }` + ); + expect( getDeletedProductReviewResponse.status() ).toEqual( + 404 + ); + } ); + + test( 'can batch update product reviews', async ( { request } ) => { + // Batch create product reviews. + const response = await request.post( + `wp-json/wc/v3/products/reviews/batch`, + { + data: { + create: [ + { + product_id: reviewsTestProduct.id, + review: 'Nice product!', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + rating: 4, + }, + { + product_id: reviewsTestProduct.id, + review: 'I love this thing!', + reviewer: 'Jane Doe', + reviewer_email: 'Jane.doe@example.com', + rating: 5, + }, + ], + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.create[ 0 ].product_id ).toEqual( + reviewsTestProduct.id + ); + expect( responseJSON.create[ 0 ].review ).toEqual( + 'Nice product!' + ); + expect( responseJSON.create[ 0 ].reviewer ).toEqual( + 'John Doe' + ); + expect( responseJSON.create[ 0 ].reviewer_email ).toEqual( + 'john.doe@example.com' + ); + expect( responseJSON.create[ 0 ].rating ).toEqual( 4 ); + + expect( responseJSON.create[ 1 ].product_id ).toEqual( + reviewsTestProduct.id + ); + expect( responseJSON.create[ 1 ].review ).toEqual( + 'I love this thing!' + ); + expect( responseJSON.create[ 1 ].reviewer ).toEqual( + 'Jane Doe' + ); + expect( responseJSON.create[ 1 ].reviewer_email ).toEqual( + 'Jane.doe@example.com' + ); + expect( responseJSON.create[ 1 ].rating ).toEqual( 5 ); + const review1Id = responseJSON.create[ 0 ].id; + const review2Id = responseJSON.create[ 1 ].id; + + // Batch create a new review, update a review and delete another. + const responseBatchUpdate = await request.post( + `wp-json/wc/v3/products/reviews/batch`, + { + data: { + create: [ + { + product_id: reviewsTestProduct.id, + review: 'Ok product.', + reviewer: 'Jack Doe', + reviewer_email: 'jack.doe@example.com', + rating: 3, + }, + ], + update: [ + { + id: review1Id, + review: 'On reflection, I hate this thing!', + rating: 1, + }, + ], + delete: [ review2Id ], + }, + } + ); + const responseBatchUpdateJSON = + await responseBatchUpdate.json(); + const review3Id = responseBatchUpdateJSON.create[ 0 ].id; + expect( response.status() ).toEqual( 200 ); + + const responseUpdatedReview = await request.get( + `wp-json/wc/v3/products/reviews/${ review1Id }` + ); + const responseUpdatedReviewJSON = + await responseUpdatedReview.json(); + expect( responseUpdatedReviewJSON.review ).toEqual( + '

On reflection, I hate this thing!

\n' + ); + expect( responseUpdatedReviewJSON.rating ).toEqual( 1 ); + + // Verify that the deleted review can no longer be retrieved. + const getDeletedProductReviewResponse = await request.get( + `wp-json/wc/v3/products/reviews/${ review2Id }` + ); + expect( getDeletedProductReviewResponse.status() ).toEqual( + 404 + ); + + // Batch delete the created tags + await request.post( `wp-json/wc/v3/products/reviews/batch`, { + data: { + delete: [ review1Id, review3Id ], + }, + } ); + } ); + } + ); test.describe( 'Product shipping classes tests: CRUD', () => { let productShippingClassId; @@ -958,83 +981,91 @@ test.describe( 'Products API tests: CRUD', () => { ); } ); - test( 'can batch update product shipping classes', async ( { - request, - } ) => { - // Batch create product shipping classes. - const response = await request.post( - `wp-json/wc/v3/products/shipping_classes/batch`, - { - data: { - create: [ - { - name: 'Small Items', - }, - { - name: 'Large Items', - }, - ], - }, - } - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( responseJSON.create[ 0 ].name ).toEqual( 'Small Items' ); - expect( responseJSON.create[ 1 ].name ).toEqual( 'Large Items' ); - const shippingClass1Id = responseJSON.create[ 0 ].id; - const shippingClass2Id = responseJSON.create[ 1 ].id; + test( + 'can batch update product shipping classes', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + async ( { request } ) => { + // Batch create product shipping classes. + const response = await request.post( + `wp-json/wc/v3/products/shipping_classes/batch`, + { + data: { + create: [ + { + name: 'Small Items', + }, + { + name: 'Large Items', + }, + ], + }, + } + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( responseJSON.create[ 0 ].name ).toEqual( + 'Small Items' + ); + expect( responseJSON.create[ 1 ].name ).toEqual( + 'Large Items' + ); + const shippingClass1Id = responseJSON.create[ 0 ].id; + const shippingClass2Id = responseJSON.create[ 1 ].id; - // Batch create a new shipping class, update a shipping class and delete another. - const responseBatchUpdate = await request.post( - `wp-json/wc/v3/products/shipping_classes/batch`, - { - data: { - create: [ - { - name: 'Express', - }, - ], - update: [ - { - id: shippingClass1Id, - description: 'Priority shipping.', - }, - ], - delete: [ shippingClass2Id ], - }, - } - ); - const responseBatchUpdateJSON = await responseBatchUpdate.json(); - const shippingClass3Id = responseBatchUpdateJSON.create[ 0 ].id; - expect( response.status() ).toEqual( 200 ); + // Batch create a new shipping class, update a shipping class and delete another. + const responseBatchUpdate = await request.post( + `wp-json/wc/v3/products/shipping_classes/batch`, + { + data: { + create: [ + { + name: 'Express', + }, + ], + update: [ + { + id: shippingClass1Id, + description: 'Priority shipping.', + }, + ], + delete: [ shippingClass2Id ], + }, + } + ); + const responseBatchUpdateJSON = + await responseBatchUpdate.json(); + const shippingClass3Id = responseBatchUpdateJSON.create[ 0 ].id; + expect( response.status() ).toEqual( 200 ); - const responseUpdatedShippingClass = await request.get( - `wp-json/wc/v3/products/shipping_classes/${ shippingClass1Id }` - ); - const responseUpdatedShippingClassJSON = - await responseUpdatedShippingClass.json(); - expect( responseUpdatedShippingClassJSON.description ).toEqual( - 'Priority shipping.' - ); + const responseUpdatedShippingClass = await request.get( + `wp-json/wc/v3/products/shipping_classes/${ shippingClass1Id }` + ); + const responseUpdatedShippingClassJSON = + await responseUpdatedShippingClass.json(); + expect( responseUpdatedShippingClassJSON.description ).toEqual( + 'Priority shipping.' + ); - // Verify that the product tag can no longer be retrieved. - const getDeletedProductShippingClassResponse = await request.get( - `wp-json/wc/v3/products/shipping_classes/${ shippingClass2Id }` - ); - expect( getDeletedProductShippingClassResponse.status() ).toEqual( - 404 - ); + // Verify that the product tag can no longer be retrieved. + const getDeletedProductShippingClassResponse = + await request.get( + `wp-json/wc/v3/products/shipping_classes/${ shippingClass2Id }` + ); + expect( + getDeletedProductShippingClassResponse.status() + ).toEqual( 404 ); - // Batch delete the created tags - await request.post( - `wp-json/wc/v3/products/shipping_classes/batch`, - { - data: { - delete: [ shippingClass1Id, shippingClass3Id ], - }, - } - ); - } ); + // Batch delete the created tags + await request.post( + `wp-json/wc/v3/products/shipping_classes/batch`, + { + data: { + delete: [ shippingClass1Id, shippingClass3Id ], + }, + } + ); + } + ); } ); test.describe( 'Product tags tests: CRUD', () => { diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/settings/settings-crud.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/settings/settings-crud.test.js index 376d606c745..e7caee7e0b4 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/settings/settings-crud.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/settings/settings-crud.test.js @@ -280,7 +280,7 @@ test.describe.serial( 'Settings API tests: CRUD', () => { type: 'text', default: '', tip: 'The street address for your business location.', - value: '', + value: expect.any( String ), } ), ] ) ); @@ -310,7 +310,7 @@ test.describe.serial( 'Settings API tests: CRUD', () => { type: 'text', default: '', tip: 'The city in which your business is located.', - value: '', + value: expect.any( String ), } ), ] ) ); @@ -341,7 +341,7 @@ test.describe.serial( 'Settings API tests: CRUD', () => { type: 'text', default: '', tip: 'The postal code, if any, in which your business is located.', - value: '', + value: expect.any( String ), } ), ] ) ); @@ -1019,157 +1019,164 @@ test.describe.serial( 'Settings API tests: CRUD', () => { } ); test.describe( 'List all Tax settings options', () => { - test( 'can retrieve all tax settings', async ( { request } ) => { - // call API to retrieve all settings options - const response = await request.get( '/wp-json/wc/v3/settings/tax' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON.length ).toBeGreaterThan( 0 ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_prices_include_tax', - label: 'Prices entered with tax', - description: '', - type: 'radio', - default: 'no', - options: { - yes: 'Yes, I will enter prices inclusive of tax', - no: 'No, I will enter prices exclusive of tax', - }, - tip: 'This option is important as it will affect how you input prices. Changing it will not update existing products.', - value: 'no', - } ), - ] ) - ); + test( + 'can retrieve all tax settings', + { tag: [ '@skip-on-default-pressable', '@skip-on-default-wpcom' ] }, + async ( { request } ) => { + // call API to retrieve all settings options + const response = await request.get( + '/wp-json/wc/v3/settings/tax' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON.length ).toBeGreaterThan( 0 ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_prices_include_tax', + label: 'Prices entered with tax', + description: '', + type: 'radio', + default: 'no', + options: { + yes: 'Yes, I will enter prices inclusive of tax', + no: 'No, I will enter prices exclusive of tax', + }, + tip: 'This option is important as it will affect how you input prices. Changing it will not update existing products.', + value: 'no', + } ), + ] ) + ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_based_on', - label: 'Calculate tax based on', - description: '', - type: 'select', - default: 'shipping', - options: { - shipping: 'Customer shipping address', - billing: 'Customer billing address', - base: 'Shop base address', - }, - tip: 'This option determines which address is used to calculate tax.', - value: 'shipping', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_shipping_tax_class', - label: 'Shipping tax class', - description: - 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', - type: 'select', - default: 'inherit', - options: { - inherit: 'Shipping tax class based on cart items', - '': 'Standard', - 'reduced-rate': 'Reduced rate', - 'zero-rate': 'Zero rate', - }, - tip: 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', - value: 'inherit', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_round_at_subtotal', - label: 'Rounding', - description: - 'Round tax at subtotal level, instead of rounding per line', - type: 'checkbox', - default: 'no', - value: 'no', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_classes', - label: 'Additional tax classes', - description: '', - type: 'textarea', - default: '', - tip: 'List additional tax classes you need below (1 per line, e.g. Reduced Rates). These are in addition to "Standard rate" which exists by default.', - value: '', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_display_shop', - label: 'Display prices in the shop', - description: '', - type: 'select', - default: 'excl', - options: { - incl: 'Including tax', - excl: 'Excluding tax', - }, - value: 'excl', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_display_cart', - label: 'Display prices during cart and checkout', - description: '', - type: 'select', - default: 'excl', - options: { - incl: 'Including tax', - excl: 'Excluding tax', - }, - value: 'excl', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_price_display_suffix', - label: 'Price display suffix', - description: '', - type: 'text', - default: '', - tip: 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', - value: '', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_tax_total_display', - label: 'Display tax totals', - description: '', - type: 'select', - default: 'itemized', - options: { - single: 'As a single total', - itemized: 'Itemized', - }, - value: 'itemized', - } ), - ] ) - ); - } ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_based_on', + label: 'Calculate tax based on', + description: '', + type: 'select', + default: 'shipping', + options: { + shipping: 'Customer shipping address', + billing: 'Customer billing address', + base: 'Shop base address', + }, + tip: 'This option determines which address is used to calculate tax.', + value: 'shipping', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_shipping_tax_class', + label: 'Shipping tax class', + description: + 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', + type: 'select', + default: 'inherit', + options: { + inherit: + 'Shipping tax class based on cart items', + '': 'Standard', + 'reduced-rate': 'Reduced rate', + 'zero-rate': 'Zero rate', + }, + tip: 'Optionally control which tax class shipping gets, or leave it so shipping tax is based on the cart items themselves.', + value: 'inherit', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_round_at_subtotal', + label: 'Rounding', + description: + 'Round tax at subtotal level, instead of rounding per line', + type: 'checkbox', + default: 'no', + value: 'no', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_classes', + label: 'Additional tax classes', + description: '', + type: 'textarea', + default: '', + tip: 'List additional tax classes you need below (1 per line, e.g. Reduced Rates). These are in addition to "Standard rate" which exists by default.', + value: '', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_display_shop', + label: 'Display prices in the shop', + description: '', + type: 'select', + default: 'excl', + options: { + incl: 'Including tax', + excl: 'Excluding tax', + }, + value: 'excl', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_display_cart', + label: 'Display prices during cart and checkout', + description: '', + type: 'select', + default: 'excl', + options: { + incl: 'Including tax', + excl: 'Excluding tax', + }, + value: 'excl', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_price_display_suffix', + label: 'Price display suffix', + description: '', + type: 'text', + default: '', + tip: 'Define text to show after your product prices. This could be, for example, "inc. Vat" to explain your pricing. You can also have prices substituted here using one of the following: {price_including_tax}, {price_excluding_tax}.', + value: '', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_tax_total_display', + label: 'Display tax totals', + description: '', + type: 'select', + default: 'itemized', + options: { + single: 'As a single total', + itemized: 'Itemized', + }, + value: 'itemized', + } ), + ] ) + ); + } + ); } ); test.describe( 'List all Shipping settings options', () => { @@ -1613,286 +1620,294 @@ test.describe.serial( 'Settings API tests: CRUD', () => { } ); } ); - test.describe( 'List all Advanced settings options', () => { - test( 'can retrieve all advanced settings', async ( { request } ) => { - // call API to retrieve all settings options - const response = await request.get( - '/wp-json/wc/v3/settings/advanced' - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); + test.describe( + 'List all Advanced settings options', + { tag: '@skip-on-default-wpcom' }, + () => { + test( 'can retrieve all advanced settings', async ( { + request, + } ) => { + // call API to retrieve all settings options + const response = await request.get( + '/wp-json/wc/v3/settings/advanced' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + + // not present in external host + // eslint-disable-next-line playwright/no-conditional-in-test + if ( ! shouldSkip ) { + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_cart_page_id', + label: 'Cart page', + description: + 'Page where shoppers review their shopping cart', + type: 'select', + default: '', + tip: 'Page where shoppers review their shopping cart', + value: expect.any( String ), + options: expect.any( Object ), + } ), + ] ) + ); + } + + // not present in external host + // eslint-disable-next-line playwright/no-conditional-in-test + if ( ! shouldSkip ) { + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_checkout_page_id', + label: 'Checkout page', + description: + 'Page where shoppers go to finalize their purchase', + type: 'select', + default: expect.any( Number ), + tip: 'Page where shoppers go to finalize their purchase', + value: expect.any( String ), + options: expect.any( Object ), + } ), + ] ) + ); + } - // not present in external host - // eslint-disable-next-line playwright/no-conditional-in-test - if ( ! shouldSkip ) { expect( responseJSON ).toEqual( expect.arrayContaining( [ expect.objectContaining( { - id: 'woocommerce_cart_page_id', - label: 'Cart page', + id: 'woocommerce_myaccount_page_id', + label: 'My account page', description: - 'Page where shoppers review their shopping cart', + 'Page contents: [woocommerce_my_account]', type: 'select', default: '', - tip: 'Page where shoppers review their shopping cart', + tip: 'Page contents: [woocommerce_my_account]', value: expect.any( String ), options: expect.any( Object ), } ), ] ) ); - } - - // not present in external host - // eslint-disable-next-line playwright/no-conditional-in-test - if ( ! shouldSkip ) { expect( responseJSON ).toEqual( expect.arrayContaining( [ expect.objectContaining( { - id: 'woocommerce_checkout_page_id', - label: 'Checkout page', + id: 'woocommerce_checkout_pay_endpoint', + label: 'Pay', description: - 'Page where shoppers go to finalize their purchase', - type: 'select', - default: expect.any( Number ), - tip: 'Page where shoppers go to finalize their purchase', - value: expect.any( String ), - options: expect.any( Object ), + 'Endpoint for the "Checkout → Pay" page.', + type: 'text', + default: 'order-pay', + tip: 'Endpoint for the "Checkout → Pay" page.', + value: 'order-pay', } ), ] ) ); - } - - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_page_id', - label: 'My account page', - description: 'Page contents: [woocommerce_my_account]', - type: 'select', - default: '', - tip: 'Page contents: [woocommerce_my_account]', - value: expect.any( String ), - options: expect.any( Object ), - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_checkout_pay_endpoint', - label: 'Pay', - description: - 'Endpoint for the "Checkout → Pay" page.', - type: 'text', - default: 'order-pay', - tip: 'Endpoint for the "Checkout → Pay" page.', - value: 'order-pay', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_checkout_order_received_endpoint', - label: 'Order received', - description: - 'Endpoint for the "Checkout → Order received" page.', - type: 'text', - default: 'order-received', - tip: 'Endpoint for the "Checkout → Order received" page.', - value: 'order-received', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_add_payment_method_endpoint', - label: 'Add payment method', - description: - 'Endpoint for the "Checkout → Add payment method" page.', - type: 'text', - default: 'add-payment-method', - tip: 'Endpoint for the "Checkout → Add payment method" page.', - value: 'add-payment-method', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_delete_payment_method_endpoint', - label: 'Delete payment method', - description: - 'Endpoint for the delete payment method page.', - type: 'text', - default: 'delete-payment-method', - tip: 'Endpoint for the delete payment method page.', - value: 'delete-payment-method', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_orders_endpoint', - label: 'Orders', - description: - 'Endpoint for the "My account → Orders" page.', - type: 'text', - default: 'orders', - tip: 'Endpoint for the "My account → Orders" page.', - value: 'orders', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_view_order_endpoint', - label: 'View order', - description: - 'Endpoint for the "My account → View order" page.', - type: 'text', - default: 'view-order', - tip: 'Endpoint for the "My account → View order" page.', - value: 'view-order', - } ), - ] ) - ); - - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_downloads_endpoint', - label: 'Downloads', - description: - 'Endpoint for the "My account → Downloads" page.', - type: 'text', - default: 'downloads', - tip: 'Endpoint for the "My account → Downloads" page.', - value: 'downloads', - } ), - ] ) - ); - - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_edit_account_endpoint', - label: 'Edit account', - description: - 'Endpoint for the "My account → Edit account" page.', - type: 'text', - default: 'edit-account', - tip: 'Endpoint for the "My account → Edit account" page.', - value: 'edit-account', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_edit_address_endpoint', - label: 'Addresses', - description: - 'Endpoint for the "My account → Addresses" page.', - type: 'text', - default: 'edit-address', - tip: 'Endpoint for the "My account → Addresses" page.', - value: 'edit-address', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_payment_methods_endpoint', - label: 'Payment methods', - description: - 'Endpoint for the "My account → Payment methods" page.', - type: 'text', - default: 'payment-methods', - tip: 'Endpoint for the "My account → Payment methods" page.', - value: 'payment-methods', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_myaccount_lost_password_endpoint', - label: 'Lost password', - description: - 'Endpoint for the "My account → Lost password" page.', - type: 'text', - default: 'lost-password', - tip: 'Endpoint for the "My account → Lost password" page.', - value: 'lost-password', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_logout_endpoint', - label: 'Logout', - description: - 'Endpoint for the triggering logout. You can add this to your menus via a custom link: yoursite.com/?customer-logout=true', - type: 'text', - default: 'customer-logout', - tip: 'Endpoint for the triggering logout. You can add this to your menus via a custom link: yoursite.com/?customer-logout=true', - value: 'customer-logout', - } ), - ] ) - ); - // eslint-disable-next-line playwright/no-conditional-in-test - if ( ! shouldSkip ) { expect( responseJSON ).toEqual( expect.arrayContaining( [ expect.objectContaining( { - id: 'woocommerce_allow_tracking', - label: 'Enable tracking', + id: 'woocommerce_checkout_order_received_endpoint', + label: 'Order received', description: - 'Allow usage of WooCommerce to be tracked', + 'Endpoint for the "Checkout → Order received" page.', + type: 'text', + default: 'order-received', + tip: 'Endpoint for the "Checkout → Order received" page.', + value: 'order-received', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_add_payment_method_endpoint', + label: 'Add payment method', + description: + 'Endpoint for the "Checkout → Add payment method" page.', + type: 'text', + default: 'add-payment-method', + tip: 'Endpoint for the "Checkout → Add payment method" page.', + value: 'add-payment-method', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_delete_payment_method_endpoint', + label: 'Delete payment method', + description: + 'Endpoint for the delete payment method page.', + type: 'text', + default: 'delete-payment-method', + tip: 'Endpoint for the delete payment method page.', + value: 'delete-payment-method', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_orders_endpoint', + label: 'Orders', + description: + 'Endpoint for the "My account → Orders" page.', + type: 'text', + default: 'orders', + tip: 'Endpoint for the "My account → Orders" page.', + value: 'orders', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_view_order_endpoint', + label: 'View order', + description: + 'Endpoint for the "My account → View order" page.', + type: 'text', + default: 'view-order', + tip: 'Endpoint for the "My account → View order" page.', + value: 'view-order', + } ), + ] ) + ); + + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_downloads_endpoint', + label: 'Downloads', + description: + 'Endpoint for the "My account → Downloads" page.', + type: 'text', + default: 'downloads', + tip: 'Endpoint for the "My account → Downloads" page.', + value: 'downloads', + } ), + ] ) + ); + + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_edit_account_endpoint', + label: 'Edit account', + description: + 'Endpoint for the "My account → Edit account" page.', + type: 'text', + default: 'edit-account', + tip: 'Endpoint for the "My account → Edit account" page.', + value: 'edit-account', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_edit_address_endpoint', + label: 'Addresses', + description: + 'Endpoint for the "My account → Addresses" page.', + type: 'text', + default: 'edit-address', + tip: 'Endpoint for the "My account → Addresses" page.', + value: 'edit-address', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_payment_methods_endpoint', + label: 'Payment methods', + description: + 'Endpoint for the "My account → Payment methods" page.', + type: 'text', + default: 'payment-methods', + tip: 'Endpoint for the "My account → Payment methods" page.', + value: 'payment-methods', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_myaccount_lost_password_endpoint', + label: 'Lost password', + description: + 'Endpoint for the "My account → Lost password" page.', + type: 'text', + default: 'lost-password', + tip: 'Endpoint for the "My account → Lost password" page.', + value: 'lost-password', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_logout_endpoint', + label: 'Logout', + description: + 'Endpoint for the triggering logout. You can add this to your menus via a custom link: yoursite.com/?customer-logout=true', + type: 'text', + default: 'customer-logout', + tip: 'Endpoint for the triggering logout. You can add this to your menus via a custom link: yoursite.com/?customer-logout=true', + value: 'customer-logout', + } ), + ] ) + ); + // eslint-disable-next-line playwright/no-conditional-in-test + if ( ! shouldSkip ) { + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_allow_tracking', + label: 'Enable tracking', + description: + 'Allow usage of WooCommerce to be tracked', + type: 'checkbox', + default: 'no', + tip: 'To opt out, leave this box unticked. Your store remains untracked, and no data will be collected. Read about what usage data is tracked at: WooCommerce.com Usage Tracking Documentation.', + value: 'no', + } ), + ] ) + ); + } else { + // Test is failing on external hosts + } + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_show_marketplace_suggestions', + label: 'Show Suggestions', + description: + 'Display suggestions within WooCommerce', type: 'checkbox', - default: 'no', - tip: 'To opt out, leave this box unticked. Your store remains untracked, and no data will be collected. Read about what usage data is tracked at: WooCommerce.com Usage Tracking Documentation.', - value: 'no', + default: 'yes', + tip: 'Leave this box unchecked if you do not want to pull suggested extensions from WooCommerce.com. You will see a static list of extensions instead.', + value: 'yes', } ), ] ) ); - } else { - // Test is failing on external hosts - } - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_show_marketplace_suggestions', - label: 'Show Suggestions', - description: 'Display suggestions within WooCommerce', - type: 'checkbox', - default: 'yes', - tip: 'Leave this box unchecked if you do not want to pull suggested extensions from WooCommerce.com. You will see a static list of extensions instead.', - value: 'yes', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'woocommerce_analytics_enabled', - label: 'Analytics', - description: 'Enable WooCommerce Analytics', - type: 'checkbox', - default: 'yes', - value: 'yes', - } ), - ] ) - ); - } ); - } ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'woocommerce_analytics_enabled', + label: 'Analytics', + description: 'Enable WooCommerce Analytics', + type: 'checkbox', + default: 'yes', + value: 'yes', + } ), + ] ) + ); + } ); + } + ); test.describe( 'List all Email New Order settings', () => { test( 'can retrieve all email new order settings', async ( { @@ -1930,7 +1945,7 @@ test.describe.serial( 'Settings API tests: CRUD', () => { tip: expect.stringContaining( 'Enter recipients (comma separated) for this email. Defaults to' ), - value: '', + value: expect.any( String ), } ), ] ) ); @@ -1998,107 +2013,110 @@ test.describe.serial( 'Settings API tests: CRUD', () => { } ); test.describe( 'List all Email Failed Order settings', () => { - test( 'can retrieve all email failed order settings', async ( { - request, - } ) => { - // call API to retrieve all settings options - const response = await request.get( - '/wp-json/wc/v3/settings/email_failed_order' - ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); - expect( Array.isArray( responseJSON ) ).toBe( true ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'enabled', - label: 'Enable/Disable', - description: '', - type: 'checkbox', - default: 'yes', - value: 'yes', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'recipient', - label: 'Recipient(s)', - description: expect.stringContaining( - 'Enter recipients (comma separated) for this email. Defaults to' - ), - type: 'text', - default: '', - tip: expect.stringContaining( - 'Enter recipients (comma separated) for this email. Defaults to' - ), - value: '', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'subject', - label: 'Subject', - description: - 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - type: 'text', - default: '', - tip: 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - value: '', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'heading', - label: 'Email heading', - description: - 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - type: 'text', - default: '', - tip: 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - value: '', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'additional_content', - label: 'Additional content', - description: - 'Text to appear below the main email content. Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - type: 'textarea', - default: - 'Hopefully they’ll be back. Read more about troubleshooting failed payments.', - tip: 'Text to appear below the main email content. Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', - value: 'Hopefully they’ll be back. Read more about troubleshooting failed payments.', - } ), - ] ) - ); - expect( responseJSON ).toEqual( - expect.arrayContaining( [ - expect.objectContaining( { - id: 'email_type', - label: 'Email type', - description: 'Choose which format of email to send.', - type: 'select', - default: 'html', - options: { - plain: 'Plain text', - html: 'HTML', - multipart: 'Multipart', - }, - tip: 'Choose which format of email to send.', - value: 'html', - } ), - ] ) - ); - } ); + test( + 'can retrieve all email failed order settings', + { tag: '@skip-on-default-pressable' }, + async ( { request } ) => { + // call API to retrieve all settings options + const response = await request.get( + '/wp-json/wc/v3/settings/email_failed_order' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + expect( Array.isArray( responseJSON ) ).toBe( true ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'enabled', + label: 'Enable/Disable', + description: '', + type: 'checkbox', + default: 'yes', + value: 'yes', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'recipient', + label: 'Recipient(s)', + description: expect.stringContaining( + 'Enter recipients (comma separated) for this email. Defaults to' + ), + type: 'text', + default: '', + tip: expect.stringContaining( + 'Enter recipients (comma separated) for this email. Defaults to' + ), + value: '', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'subject', + label: 'Subject', + description: + 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + type: 'text', + default: '', + tip: 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + value: '', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'heading', + label: 'Email heading', + description: + 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + type: 'text', + default: '', + tip: 'Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + value: '', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'additional_content', + label: 'Additional content', + description: + 'Text to appear below the main email content. Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + type: 'textarea', + default: + 'Hopefully they’ll be back. Read more about troubleshooting failed payments.', + tip: 'Text to appear below the main email content. Available placeholders: {site_title}</code>, <code>{site_address}</code>, <code>{site_url}</code>, <code>{order_date}</code>, <code>{order_number}', + value: 'Hopefully they’ll be back. Read more about troubleshooting failed payments.', + } ), + ] ) + ); + expect( responseJSON ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + id: 'email_type', + label: 'Email type', + description: + 'Choose which format of email to send.', + type: 'select', + default: 'html', + options: { + plain: 'Plain text', + html: 'HTML', + multipart: 'Multipart', + }, + tip: 'Choose which format of email to send.', + value: 'html', + } ), + ] ) + ); + } + ); } ); test.describe( 'List all Email Customer On Hold Order settings', () => { diff --git a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/system-status/system-status-crud.test.js b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/system-status/system-status-crud.test.js index 65d56a07196..005c48a99cd 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/api-tests/system-status/system-status-crud.test.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/api-tests/system-status/system-status-crud.test.js @@ -3,582 +3,590 @@ const { BASE_URL } = process.env; const shouldSkip = BASE_URL !== undefined && ! BASE_URL.includes( 'localhost' ); test.describe( 'System Status API tests', () => { - test( 'can view all system status items', async ( { request } ) => { - // call API to view all system status items - const response = await request.get( '/wp-json/wc/v3/system_status' ); - const responseJSON = await response.json(); - expect( response.status() ).toEqual( 200 ); + test( + 'can view all system status items', + { tag: '@skip-on-default-wpcom' }, + async ( { request } ) => { + // call API to view all system status items + const response = await request.get( + '/wp-json/wc/v3/system_status' + ); + const responseJSON = await response.json(); + expect( response.status() ).toEqual( 200 ); + + // local environment differs from external hosts. Local listed first. + // eslint-disable-next-line playwright/no-conditional-in-test + if ( ! shouldSkip ) { + expect( responseJSON ).toEqual( + expect.objectContaining( { + environment: expect.objectContaining( { + home_url: expect.any( String ), + site_url: expect.any( String ), + version: expect.any( String ), + log_directory: expect.any( String ), + log_directory_writable: expect.any( Boolean ), + wp_version: expect.any( String ), + wp_multisite: expect.any( Boolean ), + wp_memory_limit: expect.any( Number ), + wp_debug_mode: expect.any( Boolean ), + wp_cron: expect.any( Boolean ), + language: expect.any( String ), + external_object_cache: null, + server_info: expect.any( String ), + php_version: expect.any( String ), + php_post_max_size: expect.any( Number ), + php_max_execution_time: expect.any( Number ), + php_max_input_vars: expect.any( Number ), + curl_version: expect.any( String ), + suhosin_installed: expect.any( Boolean ), + max_upload_size: expect.any( Number ), + mysql_version: expect.any( String ), + mysql_version_string: expect.any( String ), + default_timezone: expect.any( String ), + fsockopen_or_curl_enabled: expect.any( Boolean ), + soapclient_enabled: expect.any( Boolean ), + domdocument_enabled: expect.any( Boolean ), + gzip_enabled: expect.any( Boolean ), + mbstring_enabled: expect.any( Boolean ), + remote_post_successful: expect.any( Boolean ), + remote_post_response: expect.any( String ), + remote_get_successful: expect.any( Boolean ), + remote_get_response: expect.any( String ), + } ), + } ) + ); + } else { + expect( responseJSON ).toEqual( + expect.objectContaining( { + environment: expect.objectContaining( { + home_url: expect.any( String ), + site_url: expect.any( String ), + version: expect.any( String ), + log_directory: expect.any( String ), + log_directory_writable: expect.any( Boolean ), + wp_version: expect.any( String ), + wp_multisite: expect.any( Boolean ), + wp_memory_limit: expect.any( Number ), + wp_debug_mode: expect.any( Boolean ), + wp_cron: expect.any( Boolean ), + language: expect.any( String ), + external_object_cache: expect.any( Boolean ), + server_info: expect.any( String ), + php_version: expect.any( String ), + php_post_max_size: expect.any( Number ), + php_max_execution_time: expect.any( Number ), + php_max_input_vars: expect.any( Number ), + curl_version: expect.any( String ), + suhosin_installed: expect.any( Boolean ), + max_upload_size: expect.any( Number ), + mysql_version: expect.any( String ), + mysql_version_string: expect.any( String ), + default_timezone: expect.any( String ), + fsockopen_or_curl_enabled: expect.any( Boolean ), + soapclient_enabled: expect.any( Boolean ), + domdocument_enabled: expect.any( Boolean ), + gzip_enabled: expect.any( Boolean ), + mbstring_enabled: expect.any( Boolean ), + remote_post_successful: expect.any( Boolean ), + remote_post_response: expect.any( Number ), + remote_get_successful: expect.any( Boolean ), + remote_get_response: expect.any( Number ), + } ), + } ) + ); + } - // local environment differs from external hosts. Local listed first. - // eslint-disable-next-line playwright/no-conditional-in-test - if ( ! shouldSkip ) { expect( responseJSON ).toEqual( expect.objectContaining( { - environment: expect.objectContaining( { - home_url: expect.any( String ), - site_url: expect.any( String ), - version: expect.any( String ), - log_directory: expect.any( String ), - log_directory_writable: expect.any( Boolean ), - wp_version: expect.any( String ), - wp_multisite: expect.any( Boolean ), - wp_memory_limit: expect.any( Number ), - wp_debug_mode: expect.any( Boolean ), - wp_cron: expect.any( Boolean ), - language: expect.any( String ), - external_object_cache: null, - server_info: expect.any( String ), - php_version: expect.any( String ), - php_post_max_size: expect.any( Number ), - php_max_execution_time: expect.any( Number ), - php_max_input_vars: expect.any( Number ), - curl_version: expect.any( String ), - suhosin_installed: expect.any( Boolean ), - max_upload_size: expect.any( Number ), - mysql_version: expect.any( String ), - mysql_version_string: expect.any( String ), - default_timezone: expect.any( String ), - fsockopen_or_curl_enabled: expect.any( Boolean ), - soapclient_enabled: expect.any( Boolean ), - domdocument_enabled: expect.any( Boolean ), - gzip_enabled: expect.any( Boolean ), - mbstring_enabled: expect.any( Boolean ), - remote_post_successful: expect.any( Boolean ), - remote_post_response: expect.any( String ), - remote_get_successful: expect.any( Boolean ), - remote_get_response: expect.any( String ), - } ), - } ) - ); - } else { - expect( responseJSON ).toEqual( - expect.objectContaining( { - environment: expect.objectContaining( { - home_url: expect.any( String ), - site_url: expect.any( String ), - version: expect.any( String ), - log_directory: expect.any( String ), - log_directory_writable: expect.any( Boolean ), - wp_version: expect.any( String ), - wp_multisite: expect.any( Boolean ), - wp_memory_limit: expect.any( Number ), - wp_debug_mode: expect.any( Boolean ), - wp_cron: expect.any( Boolean ), - language: expect.any( String ), - external_object_cache: expect.any( Boolean ), - server_info: expect.any( String ), - php_version: expect.any( String ), - php_post_max_size: expect.any( Number ), - php_max_execution_time: expect.any( Number ), - php_max_input_vars: expect.any( Number ), - curl_version: expect.any( String ), - suhosin_installed: expect.any( Boolean ), - max_upload_size: expect.any( Number ), - mysql_version: expect.any( String ), - mysql_version_string: expect.any( String ), - default_timezone: expect.any( String ), - fsockopen_or_curl_enabled: expect.any( Boolean ), - soapclient_enabled: expect.any( Boolean ), - domdocument_enabled: expect.any( Boolean ), - gzip_enabled: expect.any( Boolean ), - mbstring_enabled: expect.any( Boolean ), - remote_post_successful: expect.any( Boolean ), - remote_post_response: expect.any( Number ), - remote_get_successful: expect.any( Boolean ), - remote_get_response: expect.any( Number ), - } ), - } ) - ); - } - - expect( responseJSON ).toEqual( - expect.objectContaining( { - database: expect.objectContaining( { - wc_database_version: expect.any( String ), - database_prefix: expect.any( String ), - maxmind_geoip_database: expect.any( String ), - database_tables: expect.objectContaining( { - woocommerce: expect.objectContaining( { - wp_woocommerce_sessions: expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_api_keys: expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_attribute_taxonomies: - expect.objectContaining( { + database: expect.objectContaining( { + wc_database_version: expect.any( String ), + database_prefix: expect.any( String ), + maxmind_geoip_database: expect.any( String ), + database_tables: expect.objectContaining( { + woocommerce: expect.objectContaining( { + wp_woocommerce_sessions: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_api_keys: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_attribute_taxonomies: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_downloadable_product_permissions: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_order_items: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_order_itemmeta: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_tax_rates: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_tax_rate_locations: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_shipping_zones: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_shipping_zone_locations: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_shipping_zone_methods: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_payment_tokens: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_payment_tokenmeta: + expect.objectContaining( { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + } ), + wp_woocommerce_log: expect.objectContaining( { data: expect.any( String ), index: expect.any( String ), engine: expect.any( String ), } ), - wp_woocommerce_downloadable_product_permissions: - expect.objectContaining( { + } ), + other: expect.objectContaining( { + wp_actionscheduler_actions: { data: expect.any( String ), index: expect.any( String ), engine: expect.any( String ), - } ), - wp_woocommerce_order_items: expect.objectContaining( + }, + wp_actionscheduler_claims: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_actionscheduler_groups: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_actionscheduler_logs: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_commentmeta: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_comments: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_links: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_options: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_postmeta: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_posts: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_termmeta: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_terms: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_term_relationships: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_term_taxonomy: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_usermeta: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_users: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_admin_notes: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_admin_note_actions: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_category_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_customer_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_download_log: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_order_coupon_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_order_product_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_order_stats: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_order_tax_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_product_attributes_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_product_download_directories: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_product_meta_lookup: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_rate_limits: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_reserved_stock: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_tax_rate_classes: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + wp_wc_webhooks: { + data: expect.any( String ), + index: expect.any( String ), + engine: expect.any( String ), + }, + } ), + } ), + database_size: { + data: expect.any( Number ), + index: expect.any( Number ), + }, + } ), + } ) + ); + + expect( responseJSON ).toEqual( + expect.objectContaining( { + active_plugins: expect.arrayContaining( [ + { + plugin: expect.any( String ), + name: expect.any( String ), + version: expect.any( String ), + version_latest: expect.any( String ), + url: expect.any( String ), + author_name: expect.any( String ), + author_url: expect.any( String ), + network_activated: expect.any( Boolean ), + }, + { + plugin: expect.any( String ), + name: expect.any( String ), + version: expect.any( String ), + version_latest: expect.any( String ), + url: expect.any( String ), + author_name: expect.any( String ), + author_url: expect.any( String ), + network_activated: expect.any( Boolean ), + }, + { + plugin: expect.any( String ), + name: expect.any( String ), + version: expect.any( String ), + version_latest: expect.any( String ), + url: expect.any( String ), + author_name: expect.any( String ), + author_url: expect.any( String ), + network_activated: expect.any( Boolean ), + }, + { + plugin: expect.any( String ), + name: expect.any( String ), + version: expect.any( String ), + version_latest: expect.any( String ), + url: expect.any( String ), + author_name: expect.any( String ), + author_url: expect.any( String ), + network_activated: expect.any( Boolean ), + }, + ] ), + } ) + ); + + // local environment differs from external hosts. Local listed first. + // eslint-disable-next-line playwright/no-conditional-in-test + if ( ! shouldSkip ) { + expect( responseJSON ).toEqual( + expect.objectContaining( { + dropins_mu_plugins: expect.objectContaining( { + dropins: expect.arrayContaining( [] ), + mu_plugins: expect.arrayContaining( [] ), + } ), + } ) + ); + } else { + expect( responseJSON ).toEqual( + expect.objectContaining( { + dropins_mu_plugins: expect.objectContaining( { + dropins: expect.arrayContaining( [ { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } - ), - wp_woocommerce_order_itemmeta: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_tax_rates: expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_tax_rate_locations: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_shipping_zones: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_shipping_zone_locations: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_shipping_zone_methods: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_payment_tokens: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_payment_tokenmeta: - expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), - wp_woocommerce_log: expect.objectContaining( { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - } ), + name: expect.any( String ), + plugin: expect.any( String ), + }, + { + name: expect.any( String ), + plugin: expect.any( String ), + }, + ] ), + mu_plugins: [], } ), - other: expect.objectContaining( { - wp_actionscheduler_actions: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_actionscheduler_claims: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_actionscheduler_groups: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_actionscheduler_logs: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_commentmeta: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_comments: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_links: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_options: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_postmeta: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_posts: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_termmeta: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_terms: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_term_relationships: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_term_taxonomy: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_usermeta: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_users: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_admin_notes: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_admin_note_actions: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_category_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_customer_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_download_log: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_order_coupon_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_order_product_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_order_stats: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_order_tax_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_product_attributes_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_product_download_directories: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_product_meta_lookup: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_rate_limits: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_reserved_stock: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_tax_rate_classes: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - wp_wc_webhooks: { - data: expect.any( String ), - index: expect.any( String ), - engine: expect.any( String ), - }, - } ), - } ), - database_size: { - data: expect.any( Number ), - index: expect.any( Number ), - }, - } ), - } ) - ); - - expect( responseJSON ).toEqual( - expect.objectContaining( { - active_plugins: expect.arrayContaining( [ - { - plugin: expect.any( String ), - name: expect.any( String ), - version: expect.any( String ), - version_latest: expect.any( String ), - url: expect.any( String ), - author_name: expect.any( String ), - author_url: expect.any( String ), - network_activated: expect.any( Boolean ), - }, - { - plugin: expect.any( String ), - name: expect.any( String ), - version: expect.any( String ), - version_latest: expect.any( String ), - url: expect.any( String ), - author_name: expect.any( String ), - author_url: expect.any( String ), - network_activated: expect.any( Boolean ), - }, - { - plugin: expect.any( String ), - name: expect.any( String ), - version: expect.any( String ), - version_latest: expect.any( String ), - url: expect.any( String ), - author_name: expect.any( String ), - author_url: expect.any( String ), - network_activated: expect.any( Boolean ), - }, - { - plugin: expect.any( String ), - name: expect.any( String ), - version: expect.any( String ), - version_latest: expect.any( String ), - url: expect.any( String ), - author_name: expect.any( String ), - author_url: expect.any( String ), - network_activated: expect.any( Boolean ), - }, - ] ), - } ) - ); - - // local environment differs from external hosts. Local listed first. - // eslint-disable-next-line playwright/no-conditional-in-test - if ( ! shouldSkip ) { + } ) + ); + } expect( responseJSON ).toEqual( expect.objectContaining( { - dropins_mu_plugins: expect.objectContaining( { - dropins: expect.arrayContaining( [] ), - mu_plugins: expect.arrayContaining( [] ), + theme: expect.objectContaining( { + name: expect.any( String ), + version: expect.any( String ), + version_latest: expect.any( String ), + author_url: expect.any( String ), + is_child_theme: expect.any( Boolean ), + has_woocommerce_support: expect.any( Boolean ), + has_woocommerce_file: expect.any( Boolean ), + has_outdated_templates: expect.any( Boolean ), + overrides: expect.any( Array ), + parent_name: expect.any( String ), + parent_version: expect.any( String ), + parent_version_latest: expect.any( String ), + parent_author_url: expect.any( String ), } ), } ) ); - } else { expect( responseJSON ).toEqual( expect.objectContaining( { - dropins_mu_plugins: expect.objectContaining( { - dropins: expect.arrayContaining( [ - { - name: expect.any( String ), - plugin: expect.any( String ), - }, - { - name: expect.any( String ), - plugin: expect.any( String ), - }, - ] ), - mu_plugins: [], + settings: expect.objectContaining( { + api_enabled: expect.any( Boolean ), + force_ssl: expect.any( Boolean ), + currency: expect.any( String ), + currency_symbol: expect.any( String ), + currency_position: expect.any( String ), + thousand_separator: expect.any( String ), + decimal_separator: expect.any( String ), + number_of_decimals: expect.any( Number ), + geolocation_enabled: expect.any( Boolean ), + taxonomies: { + external: expect.any( String ), + grouped: expect.any( String ), + simple: expect.any( String ), + variable: expect.any( String ), + }, + product_visibility_terms: { + 'exclude-from-catalog': expect.any( String ), + 'exclude-from-search': expect.any( String ), + featured: expect.any( String ), + outofstock: expect.any( String ), + 'rated-1': expect.any( String ), + 'rated-2': expect.any( String ), + 'rated-3': expect.any( String ), + 'rated-4': expect.any( String ), + 'rated-5': expect.any( String ), + }, + woocommerce_com_connected: expect.any( String ), } ), } ) ); + expect( responseJSON ).toEqual( + expect.objectContaining( { + security: expect.objectContaining( { + secure_connection: expect.any( Boolean ), + hide_errors: expect.any( Boolean ), + } ), + } ) + ); + expect( responseJSON ).toEqual( + expect.objectContaining( { + pages: expect.arrayContaining( [ + { + page_name: expect.any( String ), + page_id: expect.any( String ), + page_set: expect.any( Boolean ), + page_exists: expect.any( Boolean ), + page_visible: expect.any( Boolean ), + shortcode: expect.any( String ), + block: expect.any( String ), + shortcode_required: expect.any( Boolean ), + shortcode_present: expect.any( Boolean ), + block_present: expect.any( Boolean ), + block_required: expect.any( Boolean ), + }, + { + page_name: expect.any( String ), + page_id: expect.any( String ), + page_set: expect.any( Boolean ), + page_exists: expect.any( Boolean ), + page_visible: expect.any( Boolean ), + shortcode: expect.any( String ), + block: expect.any( String ), + shortcode_required: expect.any( Boolean ), + shortcode_present: expect.any( Boolean ), + block_present: expect.any( Boolean ), + block_required: expect.any( Boolean ), + }, + { + page_name: expect.any( String ), + page_id: expect.any( String ), + page_set: expect.any( Boolean ), + page_exists: expect.any( Boolean ), + page_visible: expect.any( Boolean ), + shortcode: expect.any( String ), + block: expect.any( String ), + shortcode_required: expect.any( Boolean ), + shortcode_present: expect.any( Boolean ), + block_present: expect.any( Boolean ), + block_required: expect.any( Boolean ), + }, + { + page_name: expect.any( String ), + page_id: expect.any( String ), + page_set: expect.any( Boolean ), + page_exists: expect.any( Boolean ), + page_visible: expect.any( Boolean ), + shortcode: expect.any( String ), + block: expect.any( String ), + shortcode_required: expect.any( Boolean ), + shortcode_present: expect.any( Boolean ), + block_present: expect.any( Boolean ), + block_required: expect.any( Boolean ), + }, + { + page_name: expect.any( String ), + page_id: expect.any( String ), + page_set: expect.any( Boolean ), + page_exists: expect.any( Boolean ), + page_visible: expect.any( Boolean ), + shortcode: expect.any( String ), + block: expect.any( String ), + shortcode_required: expect.any( Boolean ), + shortcode_present: expect.any( Boolean ), + block_present: expect.any( Boolean ), + block_required: expect.any( Boolean ), + }, + ] ), + } ) + ); + expect( responseJSON ).toEqual( + expect.objectContaining( { + post_type_counts: expect.arrayContaining( [ + { + type: expect.any( String ), + count: expect.any( String ), + }, + { + type: expect.any( String ), + count: expect.any( String ), + }, + { + type: expect.any( String ), + count: expect.any( String ), + }, + ] ), + } ) + ); } - expect( responseJSON ).toEqual( - expect.objectContaining( { - theme: expect.objectContaining( { - name: expect.any( String ), - version: expect.any( String ), - version_latest: expect.any( String ), - author_url: expect.any( String ), - is_child_theme: expect.any( Boolean ), - has_woocommerce_support: expect.any( Boolean ), - has_woocommerce_file: expect.any( Boolean ), - has_outdated_templates: expect.any( Boolean ), - overrides: expect.any( Array ), - parent_name: expect.any( String ), - parent_version: expect.any( String ), - parent_version_latest: expect.any( String ), - parent_author_url: expect.any( String ), - } ), - } ) - ); - expect( responseJSON ).toEqual( - expect.objectContaining( { - settings: expect.objectContaining( { - api_enabled: expect.any( Boolean ), - force_ssl: expect.any( Boolean ), - currency: expect.any( String ), - currency_symbol: expect.any( String ), - currency_position: expect.any( String ), - thousand_separator: expect.any( String ), - decimal_separator: expect.any( String ), - number_of_decimals: expect.any( Number ), - geolocation_enabled: expect.any( Boolean ), - taxonomies: { - external: expect.any( String ), - grouped: expect.any( String ), - simple: expect.any( String ), - variable: expect.any( String ), - }, - product_visibility_terms: { - 'exclude-from-catalog': expect.any( String ), - 'exclude-from-search': expect.any( String ), - featured: expect.any( String ), - outofstock: expect.any( String ), - 'rated-1': expect.any( String ), - 'rated-2': expect.any( String ), - 'rated-3': expect.any( String ), - 'rated-4': expect.any( String ), - 'rated-5': expect.any( String ), - }, - woocommerce_com_connected: expect.any( String ), - } ), - } ) - ); - expect( responseJSON ).toEqual( - expect.objectContaining( { - security: expect.objectContaining( { - secure_connection: expect.any( Boolean ), - hide_errors: expect.any( Boolean ), - } ), - } ) - ); - expect( responseJSON ).toEqual( - expect.objectContaining( { - pages: expect.arrayContaining( [ - { - page_name: expect.any( String ), - page_id: expect.any( String ), - page_set: expect.any( Boolean ), - page_exists: expect.any( Boolean ), - page_visible: expect.any( Boolean ), - shortcode: expect.any( String ), - block: expect.any( String ), - shortcode_required: expect.any( Boolean ), - shortcode_present: expect.any( Boolean ), - block_present: expect.any( Boolean ), - block_required: expect.any( Boolean ), - }, - { - page_name: expect.any( String ), - page_id: expect.any( String ), - page_set: expect.any( Boolean ), - page_exists: expect.any( Boolean ), - page_visible: expect.any( Boolean ), - shortcode: expect.any( String ), - block: expect.any( String ), - shortcode_required: expect.any( Boolean ), - shortcode_present: expect.any( Boolean ), - block_present: expect.any( Boolean ), - block_required: expect.any( Boolean ), - }, - { - page_name: expect.any( String ), - page_id: expect.any( String ), - page_set: expect.any( Boolean ), - page_exists: expect.any( Boolean ), - page_visible: expect.any( Boolean ), - shortcode: expect.any( String ), - block: expect.any( String ), - shortcode_required: expect.any( Boolean ), - shortcode_present: expect.any( Boolean ), - block_present: expect.any( Boolean ), - block_required: expect.any( Boolean ), - }, - { - page_name: expect.any( String ), - page_id: expect.any( String ), - page_set: expect.any( Boolean ), - page_exists: expect.any( Boolean ), - page_visible: expect.any( Boolean ), - shortcode: expect.any( String ), - block: expect.any( String ), - shortcode_required: expect.any( Boolean ), - shortcode_present: expect.any( Boolean ), - block_present: expect.any( Boolean ), - block_required: expect.any( Boolean ), - }, - { - page_name: expect.any( String ), - page_id: expect.any( String ), - page_set: expect.any( Boolean ), - page_exists: expect.any( Boolean ), - page_visible: expect.any( Boolean ), - shortcode: expect.any( String ), - block: expect.any( String ), - shortcode_required: expect.any( Boolean ), - shortcode_present: expect.any( Boolean ), - block_present: expect.any( Boolean ), - block_required: expect.any( Boolean ), - }, - ] ), - } ) - ); - expect( responseJSON ).toEqual( - expect.objectContaining( { - post_type_counts: expect.arrayContaining( [ - { - type: expect.any( String ), - count: expect.any( String ), - }, - { - type: expect.any( String ), - count: expect.any( String ), - }, - { - type: expect.any( String ), - count: expect.any( String ), - }, - ] ), - } ) - ); - } ); + ); test( 'can view all system status tools', async ( { request } ) => { // call API to view system status tools