Sync with trunk, changelog entry, resolve conflicts
This commit is contained in:
commit
110266fd9b
|
@ -1,3 +1,10 @@
|
|||
# Unreleased
|
||||
|
||||
## Added
|
||||
- Shipping Zones API Tests
|
||||
- Shipping Methods API Tests
|
||||
- Complex Order API Tests
|
||||
|
||||
# 0.1.0
|
||||
|
||||
- Initial/beta release
|
||||
|
|
|
@ -11,6 +11,8 @@ const {
|
|||
groupedProduct,
|
||||
externalProduct,
|
||||
} = require( './products-crud' );
|
||||
const { getShippingZoneExample } = require( './shipping-zone' );
|
||||
const { getShippingMethodExample } = require( './shipping-method' );
|
||||
const shared = require( './shared' );
|
||||
|
||||
module.exports = {
|
||||
|
@ -27,4 +29,6 @@ module.exports = {
|
|||
virtualProduct,
|
||||
groupedProduct,
|
||||
externalProduct,
|
||||
getShippingZoneExample,
|
||||
getShippingMethodExample,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Constructs a shipping method based on the given `methodId` and `cost`.
|
||||
*
|
||||
* `methodId` should be one of the following:
|
||||
* - `free_shipping`
|
||||
* - `flat_rate`
|
||||
* - `local_pickup`
|
||||
*
|
||||
* @returns shipping method object that can serve as a request payload for adding a shipping method to a shipping zone.
|
||||
*/
|
||||
const getShippingMethodExample = ( methodId, cost ) => {
|
||||
const shippingMethodExample = {
|
||||
method_id: methodId,
|
||||
};
|
||||
|
||||
if ( cost !== undefined ) {
|
||||
shippingMethodExample.settings = {
|
||||
cost: cost,
|
||||
};
|
||||
}
|
||||
|
||||
return shippingMethodExample;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getShippingMethodExample,
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Default shipping zone object.
|
||||
*
|
||||
* For more details on shipping zone properties, see:
|
||||
*
|
||||
* https://woocommerce.github.io/woocommerce-rest-api-docs/#shipping-zone-properties
|
||||
*
|
||||
*/
|
||||
const shippingZone = {
|
||||
name: 'US Domestic',
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a default shipping zone object.
|
||||
*
|
||||
* @returns default shipping zone
|
||||
*/
|
||||
const getShippingZoneExample = () => {
|
||||
return shippingZone;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getShippingZoneExample,
|
||||
};
|
|
@ -4,6 +4,8 @@ const { productsApi } = require( './products' );
|
|||
const { refundsApi } = require( './refunds' );
|
||||
const { taxRatesApi } = require( './tax-rates' );
|
||||
const { variationsApi } = require( './variations' );
|
||||
const { shippingZonesApi } = require( './shipping-zones' );
|
||||
const { shippingMethodsApi } = require( './shipping-methods' );
|
||||
|
||||
module.exports = {
|
||||
ordersApi,
|
||||
|
@ -12,4 +14,6 @@ module.exports = {
|
|||
refundsApi,
|
||||
taxRatesApi,
|
||||
variationsApi,
|
||||
shippingZonesApi,
|
||||
shippingMethodsApi,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
const {
|
||||
getRequest,
|
||||
postRequest,
|
||||
putRequest,
|
||||
deleteRequest,
|
||||
} = require( '../utils/request' );
|
||||
|
||||
/**
|
||||
* WooCommerce Shipping method endpoints.
|
||||
*
|
||||
* https://woocommerce.github.io/woocommerce-rest-api-docs/#shipping-methods
|
||||
*/
|
||||
const shippingMethodsApi = {
|
||||
name: 'Shipping methods',
|
||||
create: {
|
||||
name: 'Include a shipping method to a shipping zone',
|
||||
method: 'POST',
|
||||
path: 'shipping/zones/<id>/methods',
|
||||
responseCode: 200,
|
||||
shippingMethod: async ( shippingZoneId, shippingMethod ) =>
|
||||
postRequest(
|
||||
`shipping/zones/${ shippingZoneId }/methods`,
|
||||
shippingMethod
|
||||
),
|
||||
},
|
||||
retrieve: {
|
||||
name: 'Retrieve a shipping method from a shipping zone',
|
||||
method: 'GET',
|
||||
path: 'shipping/zones/<zone_id>/methods/<id>',
|
||||
responseCode: 200,
|
||||
shippingMethod: async ( shippingZoneId, shippingMethodInstanceId ) =>
|
||||
getRequest(
|
||||
`shipping/zones/${ shippingZoneId }/methods/${ shippingMethodInstanceId }`
|
||||
),
|
||||
},
|
||||
listAll: {
|
||||
name: 'List all shipping methods from a shipping zone',
|
||||
method: 'GET',
|
||||
path: 'shipping/zones/<id>/methods',
|
||||
responseCode: 200,
|
||||
shippingMethods: async ( shippingZoneId, params = {} ) =>
|
||||
getRequest( `shipping/zones/${ shippingZoneId }/methods`, params ),
|
||||
},
|
||||
update: {
|
||||
name: 'Update a shipping method of a shipping zone',
|
||||
method: 'PUT',
|
||||
path: 'shipping/zones/<zone_id>/methods/<id>',
|
||||
responseCode: 200,
|
||||
shippingMethod: async (
|
||||
shippingZoneId,
|
||||
shippingMethodInstanceId,
|
||||
updatedShippingMethod
|
||||
) =>
|
||||
putRequest(
|
||||
`shipping/zones/${ shippingZoneId }/methods/${ shippingMethodInstanceId }`,
|
||||
updatedShippingMethod
|
||||
),
|
||||
},
|
||||
delete: {
|
||||
name: 'Delete a shipping method from a shipping zone',
|
||||
method: 'DELETE',
|
||||
path: 'shipping/zones/<zone_id>/methods/<id>>',
|
||||
responseCode: 200,
|
||||
payload: {
|
||||
force: false,
|
||||
},
|
||||
shippingMethod: async (
|
||||
shippingZoneId,
|
||||
shippingMethodInstanceId,
|
||||
deletePermanently
|
||||
) =>
|
||||
deleteRequest(
|
||||
`shipping/zones/${ shippingZoneId }/methods/${ shippingMethodInstanceId }`,
|
||||
deletePermanently
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
shippingMethodsApi,
|
||||
};
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
const {
|
||||
getRequest,
|
||||
postRequest,
|
||||
putRequest,
|
||||
deleteRequest,
|
||||
} = require( '../utils/request' );
|
||||
|
||||
/**
|
||||
* WooCommerce Shipping zone endpoints.
|
||||
*
|
||||
* https://woocommerce.github.io/woocommerce-rest-api-docs/#shipping-zones
|
||||
*/
|
||||
const shippingZonesApi = {
|
||||
name: 'Shipping zones',
|
||||
create: {
|
||||
name: 'Create a shipping zone',
|
||||
method: 'POST',
|
||||
path: 'shipping/zones',
|
||||
responseCode: 201,
|
||||
shippingZone: async ( shippingZone ) =>
|
||||
postRequest( `shipping/zones`, shippingZone ),
|
||||
},
|
||||
retrieve: {
|
||||
name: 'Retrieve a shipping zone',
|
||||
method: 'GET',
|
||||
path: 'shipping/zones/<id>',
|
||||
responseCode: 200,
|
||||
shippingZone: async ( shippingZoneId ) =>
|
||||
getRequest( `shipping/zones/${ shippingZoneId }` ),
|
||||
},
|
||||
listAll: {
|
||||
name: 'List all shipping zones',
|
||||
method: 'GET',
|
||||
path: 'shipping/zones',
|
||||
responseCode: 200,
|
||||
shippingZones: async ( params = {} ) =>
|
||||
getRequest( `shipping/zones`, params ),
|
||||
},
|
||||
update: {
|
||||
name: 'Update a shipping zone',
|
||||
method: 'PUT',
|
||||
path: 'shipping/zones/<id>',
|
||||
responseCode: 200,
|
||||
shippingZone: async ( shippingZoneId, updatedShippingZone ) =>
|
||||
putRequest(
|
||||
`shipping/zones/${ shippingZoneId }`,
|
||||
updatedShippingZone
|
||||
),
|
||||
},
|
||||
delete: {
|
||||
name: 'Delete a shipping zone',
|
||||
method: 'DELETE',
|
||||
path: 'shipping/zones/<id>',
|
||||
responseCode: 200,
|
||||
payload: {
|
||||
force: false,
|
||||
},
|
||||
shippingZone: async ( shippingZoneId, deletePermanently ) =>
|
||||
deleteRequest(
|
||||
`shipping/zones/${ shippingZoneId }`,
|
||||
deletePermanently
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
shippingZonesApi,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
const { couponsApi } = require('../../endpoints/coupons');
|
||||
const { ordersApi } = require('../../endpoints/orders');
|
||||
const { coupon, order } = require('../../data');
|
||||
const { couponsApi } = require( '../../endpoints/coupons' );
|
||||
const { ordersApi } = require( '../../endpoints/orders' );
|
||||
const { coupon, order } = require( '../../data' );
|
||||
|
||||
/**
|
||||
* Tests for the WooCommerce Coupons API.
|
||||
|
@ -9,37 +9,39 @@ const { coupon, order } = require('../../data');
|
|||
* @group coupons
|
||||
*
|
||||
*/
|
||||
describe('Coupons API tests', () => {
|
||||
describe( 'Coupons API tests', () => {
|
||||
let couponId;
|
||||
|
||||
it('can create a coupon', async () => {
|
||||
it( 'can create a coupon', async () => {
|
||||
const testCoupon = {
|
||||
...coupon,
|
||||
code: `${coupon.code}-${Date.now()}`,
|
||||
code: `${ coupon.code }-${ Date.now() }`,
|
||||
};
|
||||
const response = await couponsApi.create.coupon(testCoupon);
|
||||
const response = await couponsApi.create.coupon( testCoupon );
|
||||
|
||||
expect(response.statusCode).toEqual(couponsApi.create.responseCode);
|
||||
expect(response.body.id).toBeDefined();
|
||||
expect( response.statusCode ).toEqual( couponsApi.create.responseCode );
|
||||
expect( response.body.id ).toBeDefined();
|
||||
couponId = response.body.id;
|
||||
|
||||
// Validate the created coupon object has the correct code, amount, and discount type
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
expect( response.body ).toEqual(
|
||||
expect.objectContaining( {
|
||||
code: testCoupon.code,
|
||||
amount: Number(coupon.amount).toFixed(2),
|
||||
amount: Number( coupon.amount ).toFixed( 2 ),
|
||||
discount_type: coupon.discount_type,
|
||||
})
|
||||
} )
|
||||
);
|
||||
});
|
||||
} );
|
||||
|
||||
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);
|
||||
});
|
||||
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 );
|
||||
} );
|
||||
|
||||
it('can update a coupon', async () => {
|
||||
it( 'can update a coupon', async () => {
|
||||
const updatedCouponDetails = {
|
||||
description: '10% off storewide',
|
||||
maximum_amount: '500.00',
|
||||
|
@ -50,40 +52,40 @@ describe('Coupons API tests', () => {
|
|||
couponId,
|
||||
updatedCouponDetails
|
||||
);
|
||||
expect(response.statusCode).toEqual(couponsApi.update.responseCode);
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining(updatedCouponDetails)
|
||||
expect( response.statusCode ).toEqual( couponsApi.update.responseCode );
|
||||
expect( response.body ).toEqual(
|
||||
expect.objectContaining( updatedCouponDetails )
|
||||
);
|
||||
});
|
||||
} );
|
||||
|
||||
it('can permanently delete a coupon', async () => {
|
||||
const response = await couponsApi.delete.coupon(couponId, true);
|
||||
it( 'can permanently delete a coupon', async () => {
|
||||
const response = await couponsApi.delete.coupon( couponId, true );
|
||||
|
||||
expect(response.statusCode).toEqual(couponsApi.delete.responseCode);
|
||||
expect( response.statusCode ).toEqual( couponsApi.delete.responseCode );
|
||||
|
||||
const getCouponResponse = await couponsApi.retrieve.coupon(couponId);
|
||||
expect(getCouponResponse.statusCode).toEqual(404);
|
||||
});
|
||||
const getCouponResponse = await couponsApi.retrieve.coupon( couponId );
|
||||
expect( getCouponResponse.statusCode ).toEqual( 404 );
|
||||
} );
|
||||
|
||||
describe('Batch update coupons', () => {
|
||||
describe( 'Batch update coupons', () => {
|
||||
/**
|
||||
* Coupons to be created, updated, and deleted.
|
||||
*/
|
||||
const expectedCoupons = [
|
||||
{
|
||||
code: `batchcoupon-${Date.now()}`,
|
||||
code: `batchcoupon-${ Date.now() }`,
|
||||
discount_type: 'percent',
|
||||
amount: '10',
|
||||
free_shipping: false,
|
||||
},
|
||||
{
|
||||
code: `batchcoupon-${Date.now() + 1}`,
|
||||
code: `batchcoupon-${ Date.now() + 1 }`,
|
||||
discount_type: 'percent',
|
||||
amount: '20',
|
||||
},
|
||||
];
|
||||
|
||||
it('can batch create coupons', async () => {
|
||||
it( 'can batch create coupons', async () => {
|
||||
// Batch create 2 new coupons.
|
||||
const batchCreatePayload = {
|
||||
create: expectedCoupons,
|
||||
|
@ -91,36 +93,36 @@ describe('Coupons API tests', () => {
|
|||
const batchCreateResponse = await couponsApi.batch.coupons(
|
||||
batchCreatePayload
|
||||
);
|
||||
expect(batchCreateResponse.status).toEqual(
|
||||
expect( batchCreateResponse.status ).toEqual(
|
||||
couponsApi.batch.responseCode
|
||||
);
|
||||
|
||||
// Verify that the 2 new coupons were created
|
||||
const actualCoupons = batchCreateResponse.body.create;
|
||||
expect(actualCoupons).toHaveLength(expectedCoupons.length);
|
||||
for (let i = 0; i < actualCoupons.length; i++) {
|
||||
const { id, code } = actualCoupons[i];
|
||||
const expectedCouponCode = expectedCoupons[i].code;
|
||||
expect( actualCoupons ).toHaveLength( expectedCoupons.length );
|
||||
for ( let i = 0; i < actualCoupons.length; i++ ) {
|
||||
const { id, code } = actualCoupons[ i ];
|
||||
const expectedCouponCode = expectedCoupons[ i ].code;
|
||||
|
||||
expect(id).toBeDefined();
|
||||
expect(code).toEqual(expectedCouponCode);
|
||||
expect( id ).toBeDefined();
|
||||
expect( code ).toEqual( expectedCouponCode );
|
||||
|
||||
// Save the coupon id
|
||||
expectedCoupons[i].id = id;
|
||||
expectedCoupons[ i ].id = id;
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
it('can batch update coupons', async () => {
|
||||
it( 'can batch update coupons', async () => {
|
||||
// Update the 1st coupon to free shipping.
|
||||
// Update the amount of the 2nd coupon to 25.
|
||||
const batchUpdatePayload = {
|
||||
update: [
|
||||
{
|
||||
id: expectedCoupons[0].id,
|
||||
id: expectedCoupons[ 0 ].id,
|
||||
free_shipping: true,
|
||||
},
|
||||
{
|
||||
id: expectedCoupons[1].id,
|
||||
id: expectedCoupons[ 1 ].id,
|
||||
amount: '25.00',
|
||||
},
|
||||
],
|
||||
|
@ -131,23 +133,23 @@ describe('Coupons API tests', () => {
|
|||
|
||||
// Verify the response code and the number of coupons that were updated.
|
||||
const updatedCoupons = batchUpdateResponse.body.update;
|
||||
expect(batchUpdateResponse.status).toEqual(
|
||||
expect( batchUpdateResponse.status ).toEqual(
|
||||
couponsApi.batch.responseCode
|
||||
);
|
||||
expect(updatedCoupons).toHaveLength(expectedCoupons.length);
|
||||
expect( updatedCoupons ).toHaveLength( expectedCoupons.length );
|
||||
|
||||
// Verify that the 1st coupon was updated to free shipping.
|
||||
expect(updatedCoupons[0].id).toEqual(expectedCoupons[0].id);
|
||||
expect(updatedCoupons[0].free_shipping).toEqual(true);
|
||||
expect( updatedCoupons[ 0 ].id ).toEqual( expectedCoupons[ 0 ].id );
|
||||
expect( updatedCoupons[ 0 ].free_shipping ).toEqual( true );
|
||||
|
||||
// Verify that the amount of the 2nd coupon was updated to 25.
|
||||
expect(updatedCoupons[1].id).toEqual(expectedCoupons[1].id);
|
||||
expect(updatedCoupons[1].amount).toEqual('25.00');
|
||||
});
|
||||
expect( updatedCoupons[ 1 ].id ).toEqual( expectedCoupons[ 1 ].id );
|
||||
expect( updatedCoupons[ 1 ].amount ).toEqual( '25.00' );
|
||||
} );
|
||||
|
||||
it('can batch delete coupons', async () => {
|
||||
it( 'can batch delete coupons', async () => {
|
||||
// Batch delete the 2 coupons.
|
||||
const couponIdsToDelete = expectedCoupons.map(({ id }) => id);
|
||||
const couponIdsToDelete = expectedCoupons.map( ( { id } ) => id );
|
||||
const batchDeletePayload = {
|
||||
delete: couponIdsToDelete,
|
||||
};
|
||||
|
@ -157,151 +159,171 @@ describe('Coupons API tests', () => {
|
|||
|
||||
// Verify that the response shows the 2 coupons.
|
||||
const deletedCouponIds = batchDeleteResponse.body.delete.map(
|
||||
({ id }) => id
|
||||
( { id } ) => id
|
||||
);
|
||||
expect(batchDeleteResponse.status).toEqual(
|
||||
expect( batchDeleteResponse.status ).toEqual(
|
||||
couponsApi.batch.responseCode
|
||||
);
|
||||
expect(deletedCouponIds).toEqual(couponIdsToDelete);
|
||||
expect( deletedCouponIds ).toEqual( couponIdsToDelete );
|
||||
|
||||
// Verify that the 2 deleted coupons cannot be retrieved.
|
||||
for (const couponId of couponIdsToDelete) {
|
||||
const { status } = await couponsApi.retrieve.coupon(couponId);
|
||||
for ( const couponId of couponIdsToDelete ) {
|
||||
const { status } = await couponsApi.retrieve.coupon( couponId );
|
||||
|
||||
expect(status).toEqual(404);
|
||||
expect( status ).toEqual( 404 );
|
||||
}
|
||||
});
|
||||
});
|
||||
} );
|
||||
} );
|
||||
|
||||
describe('List coupons', () => {
|
||||
describe( 'List coupons', () => {
|
||||
const allCoupons = [
|
||||
{
|
||||
...coupon,
|
||||
code: `listcoupons-01-${Date.now()}`,
|
||||
description: `description-01-${Date.now()}`,
|
||||
code: `listcoupons-01-${ Date.now() }`,
|
||||
description: `description-01-${ Date.now() }`,
|
||||
},
|
||||
{
|
||||
...coupon,
|
||||
code: `listcoupons-02-${Date.now()}`,
|
||||
description: `description-02-${Date.now()}`,
|
||||
code: `listcoupons-02-${ Date.now() }`,
|
||||
description: `description-02-${ Date.now() }`,
|
||||
},
|
||||
{
|
||||
...coupon,
|
||||
code: `listcoupons-03-${Date.now()}`,
|
||||
description: `description-03-${Date.now()}`,
|
||||
code: `listcoupons-03-${ Date.now() }`,
|
||||
description: `description-03-${ Date.now() }`,
|
||||
},
|
||||
];
|
||||
|
||||
beforeAll(async () => {
|
||||
beforeAll( async () => {
|
||||
// Create list of coupons for testing.
|
||||
const response = await couponsApi.batch.coupons({
|
||||
const response = await couponsApi.batch.coupons( {
|
||||
create: allCoupons,
|
||||
});
|
||||
} );
|
||||
const actualCreatedCoupons = response.body.create;
|
||||
|
||||
// Save their coupon ID's
|
||||
for (const coupon of allCoupons) {
|
||||
for ( const coupon of allCoupons ) {
|
||||
const { id } = actualCreatedCoupons.find(
|
||||
({ code }) => coupon.code === code
|
||||
( { code } ) => coupon.code === code
|
||||
);
|
||||
|
||||
coupon.id = id;
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
afterAll(async () => {
|
||||
afterAll( async () => {
|
||||
// Clean up created coupons
|
||||
const batchDeletePayload = {
|
||||
delete: allCoupons.map(({ id }) => id),
|
||||
delete: allCoupons.map( ( { id } ) => id ),
|
||||
};
|
||||
await couponsApi.batch.coupons(batchDeletePayload);
|
||||
});
|
||||
await couponsApi.batch.coupons( batchDeletePayload );
|
||||
} );
|
||||
|
||||
it('can list all coupons by default', async () => {
|
||||
it( 'can list all coupons by default', async () => {
|
||||
const response = await couponsApi.listAll.coupons();
|
||||
const listedCoupons = response.body;
|
||||
const actualCouponIdsList = listedCoupons.map(({ id }) => id);
|
||||
const expectedCouponIdsList = allCoupons.map(({ id }) => id);
|
||||
const actualCouponIdsList = listedCoupons.map( ( { id } ) => id );
|
||||
const expectedCouponIdsList = allCoupons.map( ( { id } ) => id );
|
||||
|
||||
expect(response.status).toEqual(couponsApi.listAll.responseCode);
|
||||
expect(actualCouponIdsList).toEqual(
|
||||
expect.arrayContaining(expectedCouponIdsList)
|
||||
expect( response.status ).toEqual(
|
||||
couponsApi.listAll.responseCode
|
||||
);
|
||||
});
|
||||
expect( actualCouponIdsList ).toEqual(
|
||||
expect.arrayContaining( expectedCouponIdsList )
|
||||
);
|
||||
} );
|
||||
|
||||
it('can limit result set to matching code', async () => {
|
||||
const matchingCoupon = allCoupons[1];
|
||||
it( 'can limit result set to matching code', async () => {
|
||||
const matchingCoupon = allCoupons[ 1 ];
|
||||
const payload = { code: matchingCoupon.code };
|
||||
const { status, body } = await couponsApi.listAll.coupons(payload);
|
||||
const { status, body } = await couponsApi.listAll.coupons(
|
||||
payload
|
||||
);
|
||||
|
||||
expect(status).toEqual(couponsApi.listAll.responseCode);
|
||||
expect(body).toHaveLength(1);
|
||||
expect(body[0].id).toEqual(matchingCoupon.id);
|
||||
});
|
||||
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
||||
expect( body ).toHaveLength( 1 );
|
||||
expect( body[ 0 ].id ).toEqual( matchingCoupon.id );
|
||||
} );
|
||||
|
||||
it('can paginate results', async () => {
|
||||
it( 'can paginate results', async () => {
|
||||
const pageSize = 2;
|
||||
const payload = {
|
||||
page: 1,
|
||||
per_page: pageSize,
|
||||
};
|
||||
const { status, body } = await couponsApi.listAll.coupons(payload);
|
||||
const { status, body } = await couponsApi.listAll.coupons(
|
||||
payload
|
||||
);
|
||||
|
||||
expect(status).toEqual(couponsApi.listAll.responseCode);
|
||||
expect(body).toHaveLength(pageSize);
|
||||
});
|
||||
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
||||
expect( body ).toHaveLength( pageSize );
|
||||
} );
|
||||
|
||||
it('can limit results to matching string', async () => {
|
||||
it( 'can limit results to matching string', async () => {
|
||||
// Search by description
|
||||
const matchingCoupon = allCoupons[2];
|
||||
const matchingCoupon = allCoupons[ 2 ];
|
||||
const matchingString = matchingCoupon.description;
|
||||
const payload = {
|
||||
search: matchingString,
|
||||
};
|
||||
|
||||
const { status, body } = await couponsApi.listAll.coupons(payload);
|
||||
const { status, body } = await couponsApi.listAll.coupons(
|
||||
payload
|
||||
);
|
||||
|
||||
expect(status).toEqual(couponsApi.listAll.responseCode);
|
||||
expect(body).toHaveLength(1);
|
||||
expect(body[0].id).toEqual(matchingCoupon.id);
|
||||
});
|
||||
});
|
||||
expect( status ).toEqual( couponsApi.listAll.responseCode );
|
||||
expect( body ).toHaveLength( 1 );
|
||||
expect( body[ 0 ].id ).toEqual( matchingCoupon.id );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe('Add coupon to order', () => {
|
||||
describe( 'Add coupon to order', () => {
|
||||
const testCoupon = {
|
||||
code: `coupon-${Date.now()}`,
|
||||
code: `coupon-${ Date.now() }`,
|
||||
discount_type: 'percent',
|
||||
amount: '10',
|
||||
};
|
||||
let orderId;
|
||||
|
||||
beforeAll(async () => {
|
||||
beforeAll( async () => {
|
||||
// Create a coupon
|
||||
const createCouponResponse = await couponsApi.create.coupon(
|
||||
testCoupon
|
||||
);
|
||||
testCoupon.id = createCouponResponse.body.id;
|
||||
});
|
||||
} );
|
||||
|
||||
// Clean up created coupon and order
|
||||
afterAll(async () => {
|
||||
await couponsApi.delete.coupon(testCoupon.id, true);
|
||||
await ordersApi.delete.order(orderId, true);
|
||||
});
|
||||
afterAll( async () => {
|
||||
await couponsApi.delete.coupon( testCoupon.id, true );
|
||||
await ordersApi.delete.order( orderId, true );
|
||||
} );
|
||||
|
||||
it('can add coupon to an order', async () => {
|
||||
it( 'can add coupon to an order', async () => {
|
||||
const orderWithCoupon = {
|
||||
...order,
|
||||
coupon_lines: [{ code: testCoupon.code }],
|
||||
coupon_lines: [ { code: testCoupon.code } ],
|
||||
};
|
||||
const { status, body } = await ordersApi.create.order(
|
||||
orderWithCoupon
|
||||
);
|
||||
orderId = body.id;
|
||||
|
||||
expect(status).toEqual(ordersApi.create.responseCode);
|
||||
expect(body.coupon_lines).toHaveLength(1);
|
||||
expect(body.coupon_lines[0].code).toEqual(testCoupon.code);
|
||||
});
|
||||
});
|
||||
});
|
||||
expect( status ).toEqual( ordersApi.create.responseCode );
|
||||
expect( body.coupon_lines ).toHaveLength( 1 );
|
||||
expect( body.coupon_lines[ 0 ].code ).toEqual( testCoupon.code );
|
||||
// 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,
|
||||
} ),
|
||||
} ),
|
||||
] )
|
||||
);
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
const { shippingMethodsApi } = require( '../../endpoints' );
|
||||
const { getShippingMethodExample } = require( '../../data' );
|
||||
|
||||
/**
|
||||
* Shipping zone id for "Locations not covered by your other zones".
|
||||
*/
|
||||
const shippingZoneId = 0;
|
||||
|
||||
/**
|
||||
* Data table for shipping methods.
|
||||
*/
|
||||
const shippingMethods = [
|
||||
[ 'Flat rate', 'flat_rate', '10' ],
|
||||
[ 'Free shipping', 'free_shipping', undefined ],
|
||||
[ 'Local pickup', 'local_pickup', '30' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests for the WooCommerce Shipping methods API.
|
||||
*
|
||||
* @group api
|
||||
* @group shipping-methods
|
||||
*
|
||||
*/
|
||||
describe( 'Shipping methods API tests', () => {
|
||||
it.each( shippingMethods )(
|
||||
"can add a '%s' shipping method",
|
||||
async ( methodTitle, methodId, cost ) => {
|
||||
const shippingMethod = getShippingMethodExample( methodId, cost );
|
||||
|
||||
const {
|
||||
status,
|
||||
body,
|
||||
} = await shippingMethodsApi.create.shippingMethod(
|
||||
shippingZoneId,
|
||||
shippingMethod
|
||||
);
|
||||
|
||||
expect( status ).toEqual( shippingMethodsApi.create.responseCode );
|
||||
expect( typeof body.id ).toEqual( 'number' );
|
||||
expect( body.method_id ).toEqual( methodId );
|
||||
expect( body.method_title ).toEqual( methodTitle );
|
||||
expect( body.enabled ).toEqual( true );
|
||||
|
||||
if ( [ 'flat_rate', 'local_pickup' ].includes( methodId ) ) {
|
||||
expect( body.settings.cost.value ).toEqual( cost );
|
||||
}
|
||||
|
||||
// Cleanup: Delete the shipping method
|
||||
await shippingMethodsApi.delete.shippingMethod(
|
||||
shippingZoneId,
|
||||
body.id,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
} );
|
|
@ -0,0 +1,124 @@
|
|||
const { shippingZonesApi } = require( '../../endpoints' );
|
||||
const { getShippingZoneExample } = require( '../../data' );
|
||||
|
||||
/**
|
||||
* Shipping zone to be created, retrieved, updated, and deleted by the tests.
|
||||
*/
|
||||
const shippingZone = getShippingZoneExample();
|
||||
|
||||
/**
|
||||
* Tests for the WooCommerce Shipping zones API.
|
||||
*
|
||||
* @group api
|
||||
* @group shipping-zones
|
||||
*
|
||||
*/
|
||||
describe( 'Shipping zones API tests', () => {
|
||||
it( 'cannot delete the default shipping zone "Locations not covered by your other zones"', async () => {
|
||||
// Delete all pre-existing shipping zones
|
||||
const { body } = await shippingZonesApi.listAll.shippingZones( {
|
||||
_fields: 'id',
|
||||
} );
|
||||
const ids = body.map( ( { id } ) => id );
|
||||
|
||||
for ( const id of ids ) {
|
||||
await shippingZonesApi.delete.shippingZone( id, true );
|
||||
}
|
||||
|
||||
// Verify that the default shipping zone remains
|
||||
const {
|
||||
body: remainingZones,
|
||||
} = await shippingZonesApi.listAll.shippingZones( {
|
||||
_fields: 'id',
|
||||
} );
|
||||
|
||||
expect( remainingZones ).toHaveLength( 1 );
|
||||
expect( remainingZones[ 0 ].id ).toEqual( 0 );
|
||||
} );
|
||||
|
||||
it( 'cannot update the default shipping zone', async () => {
|
||||
const newZoneDetails = {
|
||||
name: 'Default shipping zone',
|
||||
};
|
||||
const { status, body } = await shippingZonesApi.update.shippingZone(
|
||||
0,
|
||||
newZoneDetails
|
||||
);
|
||||
|
||||
expect( status ).toEqual( 403 );
|
||||
expect( body.code ).toEqual(
|
||||
'woocommerce_rest_shipping_zone_invalid_zone'
|
||||
);
|
||||
expect( body.message ).toEqual(
|
||||
'The "locations not covered by your other zones" zone cannot be updated.'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'can create a shipping zone', async () => {
|
||||
const { status, body } = await shippingZonesApi.create.shippingZone(
|
||||
shippingZone
|
||||
);
|
||||
|
||||
expect( status ).toEqual( shippingZonesApi.create.responseCode );
|
||||
expect( typeof body.id ).toEqual( 'number' );
|
||||
expect( body.name ).toEqual( shippingZone.name );
|
||||
|
||||
// Save the shipping zone ID. It will be used by other tests.
|
||||
shippingZone.id = body.id;
|
||||
} );
|
||||
|
||||
it( 'can retrieve a shipping zone', async () => {
|
||||
const { status, body } = await shippingZonesApi.retrieve.shippingZone(
|
||||
shippingZone.id
|
||||
);
|
||||
|
||||
expect( status ).toEqual( shippingZonesApi.retrieve.responseCode );
|
||||
expect( body.id ).toEqual( shippingZone.id );
|
||||
} );
|
||||
|
||||
it( 'can list all shipping zones', async () => {
|
||||
const param = {
|
||||
_fields: 'id',
|
||||
};
|
||||
const { status, body } = await shippingZonesApi.listAll.shippingZones(
|
||||
param
|
||||
);
|
||||
|
||||
expect( body ).toHaveLength( 2 ); // the test shipping zone, and the default 'Locations not covered by your other zones'
|
||||
expect( status ).toEqual( shippingZonesApi.listAll.responseCode );
|
||||
expect( body ).toEqual(
|
||||
expect.arrayContaining( [ { id: shippingZone.id } ] )
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'can update a shipping zone', async () => {
|
||||
const updatedShippingZone = {
|
||||
name: 'United States (Domestic)',
|
||||
};
|
||||
|
||||
const { status, body } = await shippingZonesApi.update.shippingZone(
|
||||
shippingZone.id,
|
||||
updatedShippingZone
|
||||
);
|
||||
|
||||
expect( status ).toEqual( shippingZonesApi.retrieve.responseCode );
|
||||
expect( body.id ).toEqual( shippingZone.id );
|
||||
expect( body.name ).toEqual( updatedShippingZone.name );
|
||||
} );
|
||||
|
||||
it( 'can delete a shipping zone', async () => {
|
||||
const { status, body } = await shippingZonesApi.delete.shippingZone(
|
||||
shippingZone.id,
|
||||
true
|
||||
);
|
||||
|
||||
expect( status ).toEqual( shippingZonesApi.delete.responseCode );
|
||||
expect( body.id ).toEqual( shippingZone.id );
|
||||
|
||||
// Verify that the shipping zone can no longer be retrieved
|
||||
const {
|
||||
status: retrieveStatus,
|
||||
} = await shippingZonesApi.retrieve.shippingZone( shippingZone.id );
|
||||
expect( retrieveStatus ).toEqual( 404 );
|
||||
} );
|
||||
} );
|
|
@ -21,7 +21,7 @@
|
|||
"pelago/emogrifier": "3.1.0",
|
||||
"psr/container": "1.0.0",
|
||||
"woocommerce/action-scheduler": "3.4.0",
|
||||
"woocommerce/woocommerce-admin": "2.9.0",
|
||||
"woocommerce/woocommerce-admin": "2.9.1",
|
||||
"woocommerce/woocommerce-blocks": "6.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ec7987721f51ed5c0faf6251128ba110",
|
||||
"content-hash": "20885acd22c0a58cff8852e7cf4ebf20",
|
||||
"packages": [
|
||||
{
|
||||
"name": "automattic/jetpack-autoloader",
|
||||
|
@ -51,6 +51,9 @@
|
|||
"GPL-2.0-or-later"
|
||||
],
|
||||
"description": "Creates a custom autoloader for a plugin or theme.",
|
||||
"support": {
|
||||
"source": "https://github.com/Automattic/jetpack-autoloader/tree/2.10.1"
|
||||
},
|
||||
"time": "2021-03-30T15:15:59+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -82,6 +85,9 @@
|
|||
"GPL-2.0-or-later"
|
||||
],
|
||||
"description": "A wrapper for defining constants in a more testable way.",
|
||||
"support": {
|
||||
"source": "https://github.com/Automattic/jetpack-constants/tree/v1.5.1"
|
||||
},
|
||||
"time": "2020-10-28T19:00:31+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -215,6 +221,10 @@
|
|||
"zend",
|
||||
"zikula"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/installers/issues",
|
||||
"source": "https://github.com/composer/installers/tree/v1.12.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
|
@ -289,6 +299,10 @@
|
|||
"geolocation",
|
||||
"maxmind"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
|
||||
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.6.0"
|
||||
},
|
||||
"time": "2019-12-19T22:59:03+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -363,6 +377,10 @@
|
|||
"email",
|
||||
"pre-processing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/emogrifier/issues",
|
||||
"source": "https://github.com/MyIntervals/emogrifier"
|
||||
},
|
||||
"time": "2019-12-26T19:37:31+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -412,6 +430,10 @@
|
|||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/container/issues",
|
||||
"source": "https://github.com/php-fig/container/tree/master"
|
||||
},
|
||||
"time": "2017-02-14T16:28:37+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -460,6 +482,9 @@
|
|||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/css-selector/tree/v3.4.47"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -510,20 +535,24 @@
|
|||
],
|
||||
"description": "Action Scheduler for WordPress and WooCommerce",
|
||||
"homepage": "https://actionscheduler.org/",
|
||||
"support": {
|
||||
"issues": "https://github.com/woocommerce/action-scheduler/issues",
|
||||
"source": "https://github.com/woocommerce/action-scheduler/tree/3.4.0"
|
||||
},
|
||||
"time": "2021-10-28T17:09:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "woocommerce/woocommerce-admin",
|
||||
"version": "2.9.0",
|
||||
"version": "2.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/woocommerce/woocommerce-admin.git",
|
||||
"reference": "8040a6ac2af1b217324ae83a4137b0bfe3edbc23"
|
||||
"reference": "fdffbfef084c65a3e2141f0aff41cef3bad27553"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/8040a6ac2af1b217324ae83a4137b0bfe3edbc23",
|
||||
"reference": "8040a6ac2af1b217324ae83a4137b0bfe3edbc23",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/fdffbfef084c65a3e2141f0aff41cef3bad27553",
|
||||
"reference": "fdffbfef084c65a3e2141f0aff41cef3bad27553",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -577,7 +606,11 @@
|
|||
],
|
||||
"description": "A modern, javascript-driven WooCommerce Admin experience.",
|
||||
"homepage": "https://github.com/woocommerce/woocommerce-admin",
|
||||
"time": "2021-11-29T23:28:44+00:00"
|
||||
"support": {
|
||||
"issues": "https://github.com/woocommerce/woocommerce-admin/issues",
|
||||
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.9.1"
|
||||
},
|
||||
"time": "2021-12-08T02:59:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "woocommerce/woocommerce-blocks",
|
||||
|
@ -687,6 +720,9 @@
|
|||
"GPL-2.0-or-later"
|
||||
],
|
||||
"description": "Jetpack Changelogger tool. Allows for managing changelogs by dropping change files into a changelog directory with each PR.",
|
||||
"support": {
|
||||
"source": "https://github.com/Automattic/jetpack-changelogger/tree/v3.0.2"
|
||||
},
|
||||
"time": "2021-11-02T14:06:49+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -733,6 +769,10 @@
|
|||
"isolation",
|
||||
"tool"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/bamarni/composer-bin-plugin/issues",
|
||||
"source": "https://github.com/bamarni/composer-bin-plugin/tree/master"
|
||||
},
|
||||
"time": "2020-05-03T08:27:20+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -787,6 +827,10 @@
|
|||
"constructor",
|
||||
"instantiate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/instantiator/issues",
|
||||
"source": "https://github.com/doctrine/instantiator/tree/master"
|
||||
},
|
||||
"time": "2015-06-14T21:17:01+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -832,6 +876,10 @@
|
|||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.x"
|
||||
},
|
||||
"time": "2017-10-19T19:58:43+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -887,6 +935,10 @@
|
|||
}
|
||||
],
|
||||
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/manifest/issues",
|
||||
"source": "https://github.com/phar-io/manifest/tree/master"
|
||||
},
|
||||
"time": "2017-03-05T18:14:27+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -934,6 +986,10 @@
|
|||
}
|
||||
],
|
||||
"description": "Library for handling version information and constraints",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/version/issues",
|
||||
"source": "https://github.com/phar-io/version/tree/master"
|
||||
},
|
||||
"time": "2017-03-05T17:38:23+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -988,6 +1044,10 @@
|
|||
"reflection",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
|
||||
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
|
||||
},
|
||||
"time": "2017-09-11T18:02:19+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1040,6 +1100,10 @@
|
|||
}
|
||||
],
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
|
||||
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
|
||||
},
|
||||
"time": "2019-12-28T18:55:12+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1085,6 +1149,10 @@
|
|||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
|
||||
},
|
||||
"time": "2017-12-30T13:23:38+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1148,6 +1216,10 @@
|
|||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpspec/prophecy/issues",
|
||||
"source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
|
||||
},
|
||||
"time": "2020-03-05T15:02:03+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1211,6 +1283,10 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/5.3"
|
||||
},
|
||||
"time": "2018-04-06T15:36:58+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1258,6 +1334,11 @@
|
|||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.net/phpunit",
|
||||
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5"
|
||||
},
|
||||
"time": "2017-11-27T13:52:08+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1299,6 +1380,10 @@
|
|||
"keywords": [
|
||||
"template"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
|
||||
},
|
||||
"time": "2015-06-21T13:50:34+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1348,6 +1433,10 @@
|
|||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-timer/tree/master"
|
||||
},
|
||||
"time": "2017-02-26T11:10:40+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1397,6 +1486,10 @@
|
|||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2017-11-27T05:48:46+00:00"
|
||||
},
|
||||
|
@ -1482,6 +1575,10 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/6.5.14"
|
||||
},
|
||||
"time": "2019-02-01T05:22:47+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1541,6 +1638,10 @@
|
|||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/5.0.10"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2018-08-09T05:50:03+00:00"
|
||||
},
|
||||
|
@ -1589,6 +1690,9 @@
|
|||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/1.1.4"
|
||||
},
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1634,6 +1738,10 @@
|
|||
],
|
||||
"description": "Looks up which function or method a line of code belongs to",
|
||||
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
|
||||
"source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
|
@ -1704,6 +1812,10 @@
|
|||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/comparator/issues",
|
||||
"source": "https://github.com/sebastianbergmann/comparator/tree/master"
|
||||
},
|
||||
"time": "2018-02-01T13:46:46+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1756,6 +1868,10 @@
|
|||
"keywords": [
|
||||
"diff"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/master"
|
||||
},
|
||||
"time": "2017-08-03T08:09:46+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1806,6 +1922,10 @@
|
|||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/environment/issues",
|
||||
"source": "https://github.com/sebastianbergmann/environment/tree/master"
|
||||
},
|
||||
"time": "2017-07-01T08:51:00+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1873,6 +1993,10 @@
|
|||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/exporter/issues",
|
||||
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
|
@ -1930,6 +2054,10 @@
|
|||
"keywords": [
|
||||
"global state"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
|
||||
},
|
||||
"time": "2017-04-27T15:39:26+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -1977,6 +2105,10 @@
|
|||
],
|
||||
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
|
||||
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
|
||||
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
|
@ -2028,6 +2160,10 @@
|
|||
],
|
||||
"description": "Allows reflection of object attributes, including inherited and non-public ones",
|
||||
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
|
||||
"source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
|
@ -2087,6 +2223,10 @@
|
|||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
|
||||
"source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sebastianbergmann",
|
||||
|
@ -2135,6 +2275,10 @@
|
|||
],
|
||||
"description": "Provides a list of PHP built-in functions that operate on resources",
|
||||
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
|
||||
"source": "https://github.com/sebastianbergmann/resource-operations/tree/master"
|
||||
},
|
||||
"time": "2015-07-28T20:34:47+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -2178,6 +2322,10 @@
|
|||
],
|
||||
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
||||
"homepage": "https://github.com/sebastianbergmann/version",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/version/issues",
|
||||
"source": "https://github.com/sebastianbergmann/version/tree/master"
|
||||
},
|
||||
"time": "2016-10-03T07:35:21+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -2245,6 +2393,9 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v3.4.47"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -2310,6 +2461,9 @@
|
|||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/debug/tree/v3.4.47"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -2386,6 +2540,9 @@
|
|||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -2463,6 +2620,9 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -2521,6 +2681,9 @@
|
|||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v3.4.47"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
|
@ -2575,6 +2738,10 @@
|
|||
}
|
||||
],
|
||||
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
||||
"support": {
|
||||
"issues": "https://github.com/theseer/tokenizer/issues",
|
||||
"source": "https://github.com/theseer/tokenizer/tree/master"
|
||||
},
|
||||
"time": "2019-06-13T22:48:21+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -2624,6 +2791,10 @@
|
|||
"check",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.9.1"
|
||||
},
|
||||
"time": "2020-07-08T17:02:28+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -2676,6 +2847,9 @@
|
|||
],
|
||||
"description": "Safe replacement to @ for suppressing warnings.",
|
||||
"homepage": "https://www.mediawiki.org/wiki/at-ease",
|
||||
"support": {
|
||||
"source": "https://github.com/wikimedia/at-ease/tree/master"
|
||||
},
|
||||
"time": "2018-10-10T15:39:06+00:00"
|
||||
},
|
||||
{
|
||||
|
@ -2733,6 +2907,10 @@
|
|||
"polyfill",
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues",
|
||||
"source": "https://github.com/Yoast/PHPUnit-Polyfills"
|
||||
},
|
||||
"time": "2021-11-23T01:37:03+00:00"
|
||||
}
|
||||
],
|
||||
|
@ -2748,5 +2926,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "7.0.33"
|
||||
},
|
||||
"plugin-api-version": "2.1.0"
|
||||
"plugin-api-version": "2.0.0"
|
||||
}
|
||||
|
|
|
@ -1323,6 +1323,16 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
if ( ! $item_id ) {
|
||||
$coupon_item = new WC_Order_Item_Coupon();
|
||||
$coupon_item->set_code( $coupon_code );
|
||||
|
||||
// Add coupon data.
|
||||
$coupon_id = wc_get_coupon_id_by_code( $coupon_code );
|
||||
$coupon = new WC_Coupon( $coupon_id );
|
||||
|
||||
// Avoid storing used_by - it's not needed and can get large.
|
||||
$coupon_data = $coupon->get_data();
|
||||
unset( $coupon_data['used_by'] );
|
||||
|
||||
$coupon_item->add_meta_data( 'coupon_data', $coupon_data );
|
||||
} else {
|
||||
$coupon_item = $this->get_item( $item_id, false );
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ class WC_Admin {
|
|||
public function prevent_admin_access() {
|
||||
$prevent_access = false;
|
||||
|
||||
if ( apply_filters( 'woocommerce_disable_admin_bar', true ) && ! is_ajax() && isset( $_SERVER['SCRIPT_FILENAME'] ) && basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_FILENAME'] ) ) ) !== 'admin-post.php' ) {
|
||||
if ( apply_filters( 'woocommerce_disable_admin_bar', true ) && ! wp_doing_ajax() && isset( $_SERVER['SCRIPT_FILENAME'] ) && basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_FILENAME'] ) ) ) !== 'admin-post.php' ) {
|
||||
$has_cap = false;
|
||||
$access_caps = array( 'edit_posts', 'manage_woocommerce', 'view_admin_dashboard' );
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ class WC_Settings_General extends WC_Settings_Page {
|
|||
'class' => 'wc-enhanced-select',
|
||||
'options' => array(
|
||||
'' => __( 'No location by default', 'woocommerce' ),
|
||||
'base' => __( 'Shop base address', 'woocommerce' ),
|
||||
'base' => __( 'Shop country/region', 'woocommerce' ),
|
||||
'geolocation' => __( 'Geolocate', 'woocommerce' ),
|
||||
'geolocation_ajax' => __( 'Geolocate (with page caching support)', 'woocommerce' ),
|
||||
),
|
||||
|
|
|
@ -186,7 +186,7 @@ class WC_Cache_Helper {
|
|||
* This prevents caching of the wrong data for this request.
|
||||
*/
|
||||
public static function geolocation_ajax_redirect() {
|
||||
if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) && ! is_checkout() && ! is_cart() && ! is_account_page() && ! is_ajax() && empty( $_POST ) ) { // WPCS: CSRF ok, input var ok.
|
||||
if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) && ! is_checkout() && ! is_cart() && ! is_account_page() && ! wp_doing_ajax() && empty( $_POST ) ) { // WPCS: CSRF ok, input var ok.
|
||||
$location_hash = self::geolocation_ajax_get_location_hash();
|
||||
$current_hash = isset( $_GET['v'] ) ? wc_clean( wp_unslash( $_GET['v'] ) ) : ''; // WPCS: sanitization ok, input var ok, CSRF ok.
|
||||
if ( empty( $current_hash ) || $current_hash !== $location_hash ) {
|
||||
|
|
|
@ -985,7 +985,7 @@ class WC_Checkout {
|
|||
|
||||
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
|
||||
|
||||
if ( ! is_ajax() ) {
|
||||
if ( ! wp_doing_ajax() ) {
|
||||
// phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
|
||||
wp_redirect( $result['redirect'] );
|
||||
exit;
|
||||
|
@ -1006,7 +1006,7 @@ class WC_Checkout {
|
|||
$order->payment_complete();
|
||||
wc_empty_cart();
|
||||
|
||||
if ( ! is_ajax() ) {
|
||||
if ( ! wp_doing_ajax() ) {
|
||||
wp_safe_redirect(
|
||||
apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $order->get_checkout_order_received_url(), $order )
|
||||
);
|
||||
|
@ -1106,7 +1106,7 @@ class WC_Checkout {
|
|||
* If checkout failed during an AJAX call, send failure response.
|
||||
*/
|
||||
protected function send_ajax_failure_response() {
|
||||
if ( is_ajax() ) {
|
||||
if ( wp_doing_ajax() ) {
|
||||
// Only print notices if not reloading the checkout, otherwise they're lost in the page reload.
|
||||
if ( ! isset( WC()->session->reload_checkout ) ) {
|
||||
$messages = wc_print_notices( true );
|
||||
|
|
|
@ -106,7 +106,7 @@ class WC_HTTPS {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( ! wc_site_is_https() && is_ssl() && $_SERVER['REQUEST_URI'] && ! is_checkout() && ! is_ajax() && ! is_account_page() && apply_filters( 'woocommerce_unforce_ssl_checkout', true ) ) {
|
||||
if ( ! wc_site_is_https() && is_ssl() && $_SERVER['REQUEST_URI'] && ! is_checkout() && ! wp_doing_ajax() && ! is_account_page() && apply_filters( 'woocommerce_unforce_ssl_checkout', true ) ) {
|
||||
|
||||
if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
|
||||
wp_safe_redirect( preg_replace( '|^https://|', 'http://', $_SERVER['REQUEST_URI'] ) );
|
||||
|
|
|
@ -168,7 +168,7 @@ class WC_Order_Item_Meta {
|
|||
* @return array
|
||||
*/
|
||||
public function get_formatted_legacy( $hideprefix = '_' ) {
|
||||
if ( ! is_ajax() ) {
|
||||
if ( ! wp_doing_ajax() ) {
|
||||
wc_deprecated_argument( 'WC_Order_Item_Meta::get_formatted', '2.4', 'Item Meta Data is being called with legacy arguments' );
|
||||
}
|
||||
|
||||
|
|
|
@ -256,18 +256,6 @@ if ( ! function_exists( 'is_lost_password_page' ) ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'is_ajax' ) ) {
|
||||
|
||||
/**
|
||||
* Is_ajax - Returns true when the page is loaded via ajax.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_ajax() {
|
||||
return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : Constants::is_defined( 'DOING_AJAX' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'is_store_notice_showing' ) ) {
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,7 @@ function wc_do_deprecated_action( $tag, $args, $version, $replacement = null, $m
|
|||
*/
|
||||
function wc_deprecated_function( $function, $version, $replacement = null ) {
|
||||
// @codingStandardsIgnoreStart
|
||||
if ( is_ajax() || WC()->is_rest_api_request() ) {
|
||||
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
|
||||
do_action( 'deprecated_function_run', $function, $replacement, $version );
|
||||
$log_string = "The {$function} function is deprecated since version {$version}.";
|
||||
$log_string .= $replacement ? " Replace with {$replacement}." : '';
|
||||
|
@ -67,7 +67,7 @@ function wc_deprecated_function( $function, $version, $replacement = null ) {
|
|||
*/
|
||||
function wc_deprecated_hook( $hook, $version, $replacement = null, $message = null ) {
|
||||
// @codingStandardsIgnoreStart
|
||||
if ( is_ajax() || WC()->is_rest_api_request() ) {
|
||||
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
|
||||
do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message );
|
||||
|
||||
$message = empty( $message ) ? '' : ' ' . $message;
|
||||
|
@ -111,7 +111,7 @@ function wc_doing_it_wrong( $function, $message, $version ) {
|
|||
// @codingStandardsIgnoreStart
|
||||
$message .= ' Backtrace: ' . wp_debug_backtrace_summary();
|
||||
|
||||
if ( is_ajax() || WC()->is_rest_api_request() ) {
|
||||
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
|
||||
do_action( 'doing_it_wrong_run', $function, $message, $version );
|
||||
error_log( "{$function} was called incorrectly. {$message}. This message was added in version {$version}." );
|
||||
} else {
|
||||
|
@ -129,7 +129,7 @@ function wc_doing_it_wrong( $function, $message, $version ) {
|
|||
* @param string $replacement
|
||||
*/
|
||||
function wc_deprecated_argument( $argument, $version, $message = null ) {
|
||||
if ( is_ajax() || WC()->is_rest_api_request() ) {
|
||||
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
|
||||
do_action( 'deprecated_argument_run', $argument, $message, $version );
|
||||
error_log( "The {$argument} argument is deprecated since version {$version}. {$message}" );
|
||||
} else {
|
||||
|
@ -1123,3 +1123,17 @@ function get_woocommerce_term_meta( $term_id, $key, $single = true ) {
|
|||
wc_deprecated_function( 'get_woocommerce_term_meta', '3.6', 'get_term_meta' );
|
||||
return function_exists( 'get_term_meta' ) ? get_term_meta( $term_id, $key, $single ) : get_metadata( 'woocommerce_term', $term_id, $key, $single );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'is_ajax' ) ) {
|
||||
|
||||
/**
|
||||
* Is_ajax - Returns true when the page is loaded via ajax.
|
||||
*
|
||||
* @deprecated 6.1.0
|
||||
* @return bool
|
||||
*/
|
||||
function is_ajax() {
|
||||
wc_deprecated_function( 'is_ajax', '6.1.0', 'wp_doing_ajax' );
|
||||
return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : Constants::is_defined( 'DOING_AJAX' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@ add_action( 'woocommerce_product_set_stock_status', 'wc_recount_after_stock_chan
|
|||
* @return array
|
||||
*/
|
||||
function wc_change_term_counts( $terms, $taxonomies ) {
|
||||
if ( is_admin() || is_ajax() ) {
|
||||
if ( is_admin() || wp_doing_ajax() ) {
|
||||
return $terms;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! is_ajax() ) {
|
||||
if ( ! wp_doing_ajax() ) {
|
||||
do_action( 'woocommerce_review_order_before_payment' );
|
||||
}
|
||||
?>
|
||||
|
@ -56,6 +56,6 @@ if ( ! is_ajax() ) {
|
|||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ( ! is_ajax() ) {
|
||||
if ( ! wp_doing_ajax() ) {
|
||||
do_action( 'woocommerce_review_order_after_payment' );
|
||||
}
|
||||
|
|
|
@ -246,4 +246,27 @@ class WC_Abstract_Order_Test extends WC_Unit_Test_Case {
|
|||
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code_2 ) )->get_usage_count() );
|
||||
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code_3 ) )->get_usage_count() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test apply_coupon() stores coupon meta data.
|
||||
* See: https://github.com/woocommerce/woocommerce/issues/28166.
|
||||
*/
|
||||
public function test_apply_coupon_stores_meta_data() {
|
||||
$coupon_code = 'coupon_test_meta_data';
|
||||
$coupon = WC_Helper_Coupon::create_coupon( $coupon_code );
|
||||
$order = WC_Helper_Order::create_order();
|
||||
$order->set_status( 'processing' );
|
||||
$order->save();
|
||||
$order->apply_coupon( $coupon_code );
|
||||
|
||||
$coupon_items = $order->get_items( 'coupon' );
|
||||
$this->assertCount( 1, $coupon_items );
|
||||
|
||||
$coupon_data = ( current( $coupon_items ) )->get_meta( 'coupon_data' );
|
||||
$this->assertNotEmpty( $coupon_data, 'WC_Order_Item_Coupon missing `coupon_data` meta.' );
|
||||
$this->assertArrayHasKey( 'id', $coupon_data );
|
||||
$this->assertArrayHasKey( 'code', $coupon_data );
|
||||
$this->assertEquals( $coupon->get_id(), $coupon_data['id'] );
|
||||
$this->assertEquals( $coupon_code, $coupon_data['code'] );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue