2021-11-30 20:18:40 +00:00
|
|
|
const { couponsApi } = require( '../../endpoints/coupons' );
|
|
|
|
const { ordersApi } = require( '../../endpoints/orders' );
|
|
|
|
const { coupon, order } = require( '../../data' );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests for the WooCommerce Coupons API.
|
|
|
|
*
|
|
|
|
* @group api
|
|
|
|
* @group coupons
|
|
|
|
*
|
|
|
|
*/
|
2021-11-30 20:18:40 +00:00
|
|
|
describe( 'Coupons API tests', () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
let couponId;
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can create a coupon', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const testCoupon = {
|
|
|
|
...coupon,
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `${ coupon.code }-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
};
|
2021-11-30 20:18:40 +00:00
|
|
|
const response = await couponsApi.create.coupon( testCoupon );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( response.statusCode ).toEqual( couponsApi.create.responseCode );
|
|
|
|
expect( response.body.id ).toBeDefined();
|
2021-10-19 07:09:48 +00:00
|
|
|
couponId = response.body.id;
|
|
|
|
|
|
|
|
// Validate the created coupon object has the correct code, amount, and discount type
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( response.body ).toEqual(
|
|
|
|
expect.objectContaining( {
|
2021-10-19 07:09:48 +00:00
|
|
|
code: testCoupon.code,
|
2021-11-30 20:18:40 +00:00
|
|
|
amount: Number( coupon.amount ).toFixed( 2 ),
|
2021-10-19 07:09:48 +00:00
|
|
|
discount_type: coupon.discount_type,
|
2021-11-30 20:18:40 +00:00
|
|
|
} )
|
2021-10-19 07:09:48 +00:00
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can retrieve a coupon', async () => {
|
|
|
|
const response = await couponsApi.retrieve.coupon( couponId );
|
|
|
|
expect( response.statusCode ).toEqual(
|
|
|
|
couponsApi.retrieve.responseCode
|
|
|
|
);
|
|
|
|
expect( response.body.id ).toEqual( couponId );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can update a coupon', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const updatedCouponDetails = {
|
|
|
|
description: '10% off storewide',
|
|
|
|
maximum_amount: '500.00',
|
|
|
|
usage_limit_per_user: 1,
|
|
|
|
free_shipping: true,
|
|
|
|
};
|
|
|
|
const response = await couponsApi.update.coupon(
|
|
|
|
couponId,
|
|
|
|
updatedCouponDetails
|
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( response.statusCode ).toEqual( couponsApi.update.responseCode );
|
|
|
|
expect( response.body ).toEqual(
|
|
|
|
expect.objectContaining( updatedCouponDetails )
|
2021-10-19 07:09:48 +00:00
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can permanently delete a coupon', async () => {
|
|
|
|
const response = await couponsApi.delete.coupon( couponId, true );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( response.statusCode ).toEqual( couponsApi.delete.responseCode );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
const getCouponResponse = await couponsApi.retrieve.coupon( couponId );
|
|
|
|
expect( getCouponResponse.statusCode ).toEqual( 404 );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
describe( 'Batch update coupons', () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
/**
|
|
|
|
* Coupons to be created, updated, and deleted.
|
|
|
|
*/
|
|
|
|
const expectedCoupons = [
|
|
|
|
{
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `batchcoupon-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
discount_type: 'percent',
|
|
|
|
amount: '10',
|
|
|
|
free_shipping: false,
|
|
|
|
},
|
|
|
|
{
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `batchcoupon-${ Date.now() + 1 }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
discount_type: 'percent',
|
|
|
|
amount: '20',
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can batch create coupons', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Batch create 2 new coupons.
|
|
|
|
const batchCreatePayload = {
|
|
|
|
create: expectedCoupons,
|
|
|
|
};
|
|
|
|
const batchCreateResponse = await couponsApi.batch.coupons(
|
|
|
|
batchCreatePayload
|
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( batchCreateResponse.status ).toEqual(
|
2021-10-19 07:09:48 +00:00
|
|
|
couponsApi.batch.responseCode
|
|
|
|
);
|
|
|
|
|
|
|
|
// Verify that the 2 new coupons were created
|
|
|
|
const actualCoupons = batchCreateResponse.body.create;
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( actualCoupons ).toHaveLength( expectedCoupons.length );
|
|
|
|
for ( let i = 0; i < actualCoupons.length; i++ ) {
|
|
|
|
const { id, code } = actualCoupons[ i ];
|
|
|
|
const expectedCouponCode = expectedCoupons[ i ].code;
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( id ).toBeDefined();
|
|
|
|
expect( code ).toEqual( expectedCouponCode );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
// Save the coupon id
|
2021-11-30 20:18:40 +00:00
|
|
|
expectedCoupons[ i ].id = id;
|
2021-10-19 07:09:48 +00:00
|
|
|
}
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can batch update coupons', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Update the 1st coupon to free shipping.
|
|
|
|
// Update the amount of the 2nd coupon to 25.
|
|
|
|
const batchUpdatePayload = {
|
|
|
|
update: [
|
|
|
|
{
|
2021-11-30 20:18:40 +00:00
|
|
|
id: expectedCoupons[ 0 ].id,
|
2021-10-19 07:09:48 +00:00
|
|
|
free_shipping: true,
|
|
|
|
},
|
|
|
|
{
|
2021-11-30 20:18:40 +00:00
|
|
|
id: expectedCoupons[ 1 ].id,
|
2021-10-19 07:09:48 +00:00
|
|
|
amount: '25.00',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
const batchUpdateResponse = await couponsApi.batch.coupons(
|
|
|
|
batchUpdatePayload
|
|
|
|
);
|
|
|
|
|
|
|
|
// Verify the response code and the number of coupons that were updated.
|
|
|
|
const updatedCoupons = batchUpdateResponse.body.update;
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( batchUpdateResponse.status ).toEqual(
|
2021-10-19 07:09:48 +00:00
|
|
|
couponsApi.batch.responseCode
|
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( updatedCoupons ).toHaveLength( expectedCoupons.length );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
// Verify that the 1st coupon was updated to free shipping.
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( updatedCoupons[ 0 ].id ).toEqual( expectedCoupons[ 0 ].id );
|
|
|
|
expect( updatedCoupons[ 0 ].free_shipping ).toEqual( true );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
// Verify that the amount of the 2nd coupon was updated to 25.
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( updatedCoupons[ 1 ].id ).toEqual( expectedCoupons[ 1 ].id );
|
|
|
|
expect( updatedCoupons[ 1 ].amount ).toEqual( '25.00' );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can batch delete coupons', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Batch delete the 2 coupons.
|
2021-11-30 20:18:40 +00:00
|
|
|
const couponIdsToDelete = expectedCoupons.map( ( { id } ) => id );
|
2021-10-19 07:09:48 +00:00
|
|
|
const batchDeletePayload = {
|
|
|
|
delete: couponIdsToDelete,
|
|
|
|
};
|
|
|
|
const batchDeleteResponse = await couponsApi.batch.coupons(
|
|
|
|
batchDeletePayload
|
|
|
|
);
|
|
|
|
|
|
|
|
// Verify that the response shows the 2 coupons.
|
|
|
|
const deletedCouponIds = batchDeleteResponse.body.delete.map(
|
2021-11-30 20:18:40 +00:00
|
|
|
( { id } ) => id
|
2021-10-19 07:09:48 +00:00
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( batchDeleteResponse.status ).toEqual(
|
2021-10-19 07:09:48 +00:00
|
|
|
couponsApi.batch.responseCode
|
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( deletedCouponIds ).toEqual( couponIdsToDelete );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
// Verify that the 2 deleted coupons cannot be retrieved.
|
2021-11-30 20:18:40 +00:00
|
|
|
for ( const couponId of couponIdsToDelete ) {
|
|
|
|
const { status } = await couponsApi.retrieve.coupon( couponId );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( status ).toEqual( 404 );
|
2021-10-19 07:09:48 +00:00
|
|
|
}
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
describe( 'List coupons', () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const allCoupons = [
|
|
|
|
{
|
|
|
|
...coupon,
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `listcoupons-01-${ Date.now() }`,
|
|
|
|
description: `description-01-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
...coupon,
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `listcoupons-02-${ Date.now() }`,
|
|
|
|
description: `description-02-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
...coupon,
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `listcoupons-03-${ Date.now() }`,
|
|
|
|
description: `description-03-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
beforeAll( async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Create list of coupons for testing.
|
2021-11-30 20:18:40 +00:00
|
|
|
const response = await couponsApi.batch.coupons( {
|
2021-10-19 07:09:48 +00:00
|
|
|
create: allCoupons,
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
const actualCreatedCoupons = response.body.create;
|
|
|
|
|
|
|
|
// Save their coupon ID's
|
2021-11-30 20:18:40 +00:00
|
|
|
for ( const coupon of allCoupons ) {
|
2021-10-19 07:09:48 +00:00
|
|
|
const { id } = actualCreatedCoupons.find(
|
2021-11-30 20:18:40 +00:00
|
|
|
( { code } ) => coupon.code === code
|
2021-10-19 07:09:48 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
coupon.id = id;
|
|
|
|
}
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
afterAll( async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Clean up created coupons
|
|
|
|
const batchDeletePayload = {
|
2021-11-30 20:18:40 +00:00
|
|
|
delete: allCoupons.map( ( { id } ) => id ),
|
2021-10-19 07:09:48 +00:00
|
|
|
};
|
2021-11-30 20:18:40 +00:00
|
|
|
await couponsApi.batch.coupons( batchDeletePayload );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can list all coupons by default', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const response = await couponsApi.listAll.coupons();
|
|
|
|
const listedCoupons = response.body;
|
2021-11-30 20:18:40 +00:00
|
|
|
const actualCouponIdsList = listedCoupons.map( ( { id } ) => id );
|
|
|
|
const expectedCouponIdsList = allCoupons.map( ( { id } ) => id );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( response.status ).toEqual(
|
|
|
|
couponsApi.listAll.responseCode
|
|
|
|
);
|
|
|
|
expect( actualCouponIdsList ).toEqual(
|
|
|
|
expect.arrayContaining( expectedCouponIdsList )
|
2021-10-19 07:09:48 +00:00
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can limit result set to matching code', async () => {
|
|
|
|
const matchingCoupon = allCoupons[ 1 ];
|
2021-10-19 07:09:48 +00:00
|
|
|
const payload = { code: matchingCoupon.code };
|
2021-11-30 20:18:40 +00:00
|
|
|
const { status, body } = await couponsApi.listAll.coupons(
|
|
|
|
payload
|
|
|
|
);
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
|
|
|
expect( body ).toHaveLength( 1 );
|
|
|
|
expect( body[ 0 ].id ).toEqual( matchingCoupon.id );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can paginate results', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const pageSize = 2;
|
|
|
|
const payload = {
|
|
|
|
page: 1,
|
|
|
|
per_page: pageSize,
|
|
|
|
};
|
2021-11-30 20:18:40 +00:00
|
|
|
const { status, body } = await couponsApi.listAll.coupons(
|
|
|
|
payload
|
|
|
|
);
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
|
|
|
expect( body ).toHaveLength( pageSize );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can limit results to matching string', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Search by description
|
2021-11-30 20:18:40 +00:00
|
|
|
const matchingCoupon = allCoupons[ 2 ];
|
2021-10-19 07:09:48 +00:00
|
|
|
const matchingString = matchingCoupon.description;
|
|
|
|
const payload = {
|
|
|
|
search: matchingString,
|
|
|
|
};
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
const { status, body } = await couponsApi.listAll.coupons(
|
|
|
|
payload
|
|
|
|
);
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
|
|
|
expect( body ).toHaveLength( 1 );
|
|
|
|
expect( body[ 0 ].id ).toEqual( matchingCoupon.id );
|
|
|
|
} );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
describe( 'Add coupon to order', () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const testCoupon = {
|
2021-11-30 20:18:40 +00:00
|
|
|
code: `coupon-${ Date.now() }`,
|
2021-10-19 07:09:48 +00:00
|
|
|
discount_type: 'percent',
|
|
|
|
amount: '10',
|
|
|
|
};
|
|
|
|
let orderId;
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
beforeAll( async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
// Create a coupon
|
|
|
|
const createCouponResponse = await couponsApi.create.coupon(
|
|
|
|
testCoupon
|
|
|
|
);
|
|
|
|
testCoupon.id = createCouponResponse.body.id;
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
|
|
|
// Clean up created coupon and order
|
2021-11-30 20:18:40 +00:00
|
|
|
afterAll( async () => {
|
|
|
|
await couponsApi.delete.coupon( testCoupon.id, true );
|
|
|
|
await ordersApi.delete.order( orderId, true );
|
|
|
|
} );
|
2021-10-19 07:09:48 +00:00
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
it( 'can add coupon to an order', async () => {
|
2021-10-19 07:09:48 +00:00
|
|
|
const orderWithCoupon = {
|
|
|
|
...order,
|
2021-11-30 20:18:40 +00:00
|
|
|
coupon_lines: [ { code: testCoupon.code } ],
|
2021-10-19 07:09:48 +00:00
|
|
|
};
|
|
|
|
const { status, body } = await ordersApi.create.order(
|
|
|
|
orderWithCoupon
|
|
|
|
);
|
|
|
|
orderId = body.id;
|
|
|
|
|
2021-11-30 20:18:40 +00:00
|
|
|
expect( status ).toEqual( ordersApi.create.responseCode );
|
|
|
|
expect( body.coupon_lines ).toHaveLength( 1 );
|
|
|
|
expect( body.coupon_lines[ 0 ].code ).toEqual( testCoupon.code );
|
2021-11-30 20:19:01 +00:00
|
|
|
// Test that the coupon meta data exists.
|
|
|
|
// See: https://github.com/woocommerce/woocommerce/issues/28166.
|
|
|
|
expect( body.coupon_lines[ 0 ].meta_data ).toEqual(
|
|
|
|
expect.arrayContaining( [
|
|
|
|
expect.objectContaining( {
|
|
|
|
key: 'coupon_data',
|
|
|
|
value: expect.objectContaining( {
|
|
|
|
code: testCoupon.code,
|
|
|
|
} ),
|
|
|
|
} ),
|
|
|
|
] )
|
|
|
|
);
|
2021-11-30 20:18:40 +00:00
|
|
|
} );
|
|
|
|
} );
|
|
|
|
} );
|