[e2e] External sites - Include API tests for Pressable and WPCOM (#51284)

* Pressable - run only /api-tests

* Skip on Pressable

* Fix lint errors

* WPCOM - run API only

* Revert "WPCOM - run API only"

This reverts commit 5e59be1663.

* WPCOM - run API only

* Update settings-crud.test.js so they are passing against Pressable

* Skip "can retrieve all tax settings"

* Skip "can view all system status items" on WPCOM

* Several skips in settings-crud.test.js

* Skip "Product review tests: CRUD" on WPCOM

* Skip "List all products > categories" on WPCOM

* Skip "can view all payment gateways" on WPCOM

* Skip "Orders API tests" on WPCOM

* Skip "Customers API tests: CRUD" on WPCOM

* Revert `playwright.config.js` files and include '**/api-tests/**/*.test.js',

* Add changefile(s) from automation for the following project(s): woocommerce

* Skip three more API tests for WPCOM

* Skip two coupons tests

* Update report name for Pressable and WPCOM to ``*-core-e2e-and-api`

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Ivan Stojadinov 2024-09-12 16:01:40 +02:00 committed by GitHub
parent 2433f9f1c4
commit a06c6ba496
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 6488 additions and 6233 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
Include API tests into test suites for Pressable and WPCOM.

View File

@ -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",

View File

@ -16,6 +16,7 @@ config = {
'**/customize-store/**/*.spec.js',
'**/merchant/**/*.spec.js',
'**/shopper/**/*.spec.js',
'**/api-tests/**/*.test.js',
],
grepInvert: /@skip-on-default-pressable/,
},

View File

@ -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/,
},
],

View File

@ -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', () => {

View File

@ -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 );
}
} );
);
} );

View File

@ -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 &quot;Flat rate&quot; method',
},
'Free shipping': {
free_shipping:
'Any &quot;Free shipping&quot; method',
},
'Local pickup': expect.objectContaining( {
[ localPickupKey ]:
'Any &quot;Local pickup&quot; 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 &quot;Flat rate&quot; method',
},
'Free shipping': {
free_shipping:
'Any &quot;Free shipping&quot; method',
},
'Local pickup': expect.objectContaining( {
[ localPickupKey ]:
'Any &quot;Local pickup&quot; 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

View File

@ -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&#8217;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(
'<p>Nice simple product!</p>\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(
'<p>On reflection, I hate this thing!</p>\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&#8217;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(
'<p>Nice simple product!</p>\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(
'<p>On reflection, I hate this thing!</p>\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', () => {