Merge pull request #31010 from woocommerce/add/run-api-tests-on-pr
Run API tests on PR with e2e tests
This commit is contained in:
commit
efe7e4f8ba
|
@ -75,4 +75,9 @@ jobs:
|
|||
WC_E2E_SCREENSHOTS: 1
|
||||
E2E_SLACK_TOKEN: ${{ secrets.E2E_SLACK_TOKEN }}
|
||||
E2E_SLACK_CHANNEL: ${{ secrets.E2E_SLACK_CHANNEL }}
|
||||
run: pnpx wc-e2e test:e2e
|
||||
BASE_URL: ${{ secrets.PR_E2E_TEST_URL }}
|
||||
USER_KEY: ${{ secrets.PR_E2E_TEST_ADMIN_USER }}
|
||||
USER_SECRET: ${{ secrets.PR_E2E_TEST_ADMIN_PASSWORD }}
|
||||
run: |
|
||||
pnpx wc-e2e test:e2e
|
||||
pnpx wc-api-tests test api
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
/**
|
||||
* A basic refund.
|
||||
*
|
||||
* For more details on the order refund properties, see:
|
||||
*
|
||||
* https://woocommerce.github.io/woocommerce-rest-api-docs/#order-refund-properties
|
||||
*
|
||||
*/
|
||||
const refund = {
|
||||
api_refund: false,
|
||||
amount: '1.00',
|
||||
reason: 'Late delivery refund.',
|
||||
line_items: [],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
refund: refund,
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
const {
|
||||
getRequest,
|
||||
postRequest,
|
||||
deleteRequest,
|
||||
} = require( '../utils/request' );
|
||||
|
||||
/**
|
||||
* WooCommerce Refunds endpoints.
|
||||
*
|
||||
* https://woocommerce.github.io/woocommerce-rest-api-docs/#refunds
|
||||
*/
|
||||
const refundsApi = {
|
||||
name: 'Refunds',
|
||||
create: {
|
||||
name: 'Create a refund',
|
||||
method: 'POST',
|
||||
path: 'orders/<id>/refunds',
|
||||
responseCode: 201,
|
||||
refund: async ( orderId, refundDetails ) =>
|
||||
postRequest( `orders/${ orderId }/refunds`, refundDetails ),
|
||||
},
|
||||
retrieve: {
|
||||
name: 'Retrieve a refund',
|
||||
method: 'GET',
|
||||
path: 'orders/<id>/refunds/<refund_id>',
|
||||
responseCode: 200,
|
||||
refund: async ( orderId, refundId ) =>
|
||||
getRequest( `orders/${ orderId }/refunds/${ refundId }` ),
|
||||
},
|
||||
listAll: {
|
||||
name: 'List all refunds',
|
||||
method: 'GET',
|
||||
path: 'orders/<id>/refunds',
|
||||
responseCode: 200,
|
||||
refunds: async ( orderId ) =>
|
||||
getRequest( `orders/${ orderId }/refunds` ),
|
||||
},
|
||||
delete: {
|
||||
name: 'Delete a refund',
|
||||
method: 'DELETE',
|
||||
path: 'orders/<id>/refunds/<refund_id>',
|
||||
responseCode: 200,
|
||||
payload: {
|
||||
force: false,
|
||||
},
|
||||
refund: async ( orderId, refundId, deletePermanently ) =>
|
||||
deleteRequest(
|
||||
`orders/${ orderId }/refunds/${ refundId }`,
|
||||
deletePermanently
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
refundsApi: refundsApi,
|
||||
};
|
|
@ -0,0 +1,122 @@
|
|||
const { refundsApi } = require( '../../endpoints/refunds' );
|
||||
const { ordersApi } = require( '../../endpoints/orders' );
|
||||
const { productsApi } = require( '../../endpoints/products' );
|
||||
const { refund } = require( '../../data' );
|
||||
|
||||
/**
|
||||
* Tests for the WooCommerce Refunds API.
|
||||
*
|
||||
* @group api
|
||||
* @group refunds
|
||||
*
|
||||
*/
|
||||
describe( 'Refunds API tests', () => {
|
||||
let expectedRefund;
|
||||
let orderId;
|
||||
let productId;
|
||||
|
||||
beforeAll( async () => {
|
||||
// Create a product and save its product ID
|
||||
const product = {
|
||||
name: 'Simple Product for Refunds API tests',
|
||||
regular_price: '100',
|
||||
};
|
||||
const createProductResponse = await productsApi.create.product(
|
||||
product
|
||||
);
|
||||
productId = createProductResponse.body.id;
|
||||
|
||||
// Create an order with a product line item, and save its Order ID
|
||||
const order = {
|
||||
status: 'pending',
|
||||
line_items: [
|
||||
{
|
||||
product_id: productId,
|
||||
},
|
||||
],
|
||||
};
|
||||
const createOrderResponse = await ordersApi.create.order( order );
|
||||
orderId = createOrderResponse.body.id;
|
||||
|
||||
// Setup the expected refund object
|
||||
expectedRefund = {
|
||||
...refund,
|
||||
line_items: [
|
||||
{
|
||||
product_id: productId,
|
||||
},
|
||||
],
|
||||
};
|
||||
} );
|
||||
|
||||
afterAll( async () => {
|
||||
// Cleanup the created product and order
|
||||
await productsApi.delete.product( productId, true );
|
||||
await ordersApi.delete.order( orderId, true );
|
||||
} );
|
||||
|
||||
it( 'can create a refund', async () => {
|
||||
const { status, body } = await refundsApi.create.refund(
|
||||
orderId,
|
||||
expectedRefund
|
||||
);
|
||||
expect( status ).toEqual( refundsApi.create.responseCode );
|
||||
expect( body.id ).toBeDefined();
|
||||
|
||||
// Save the refund ID
|
||||
expectedRefund.id = body.id;
|
||||
|
||||
// Verify that the order was refunded.
|
||||
const getOrderResponse = await ordersApi.retrieve.order( orderId );
|
||||
expect( getOrderResponse.body.refunds ).toHaveLength( 1 );
|
||||
expect( getOrderResponse.body.refunds[ 0 ].id ).toEqual(
|
||||
expectedRefund.id
|
||||
);
|
||||
expect( getOrderResponse.body.refunds[ 0 ].reason ).toEqual(
|
||||
expectedRefund.reason
|
||||
);
|
||||
expect( getOrderResponse.body.refunds[ 0 ].total ).toEqual(
|
||||
`-${ expectedRefund.amount }`
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'can retrieve a refund', async () => {
|
||||
const { status, body } = await refundsApi.retrieve.refund(
|
||||
orderId,
|
||||
expectedRefund.id
|
||||
);
|
||||
|
||||
expect( status ).toEqual( refundsApi.retrieve.responseCode );
|
||||
expect( body.id ).toEqual( expectedRefund.id );
|
||||
} );
|
||||
|
||||
it( 'can list all refunds', async () => {
|
||||
const { status, body } = await refundsApi.listAll.refunds( orderId );
|
||||
|
||||
expect( status ).toEqual( refundsApi.listAll.responseCode );
|
||||
expect( body ).toHaveLength( 1 );
|
||||
expect( body[ 0 ].id ).toEqual( expectedRefund.id );
|
||||
} );
|
||||
|
||||
it( 'can delete a refund', async () => {
|
||||
const { status, body } = await refundsApi.delete.refund(
|
||||
orderId,
|
||||
expectedRefund.id,
|
||||
true
|
||||
);
|
||||
|
||||
expect( status ).toEqual( refundsApi.delete.responseCode );
|
||||
expect( body.id ).toEqual( expectedRefund.id );
|
||||
|
||||
// Verify that the refund cannot be retrieved
|
||||
const retrieveRefundResponse = await refundsApi.retrieve.refund(
|
||||
orderId,
|
||||
expectedRefund.id
|
||||
);
|
||||
expect( retrieveRefundResponse.status ).toEqual( 404 );
|
||||
|
||||
// Verify that the order no longer has a refund
|
||||
const retrieveOrderResponse = await ordersApi.retrieve.order( orderId );
|
||||
expect( retrieveOrderResponse.body.refunds ).toHaveLength( 0 );
|
||||
} );
|
||||
} );
|
|
@ -12,7 +12,7 @@ const getCoreTestsRoot = require( '../../core-tests-root' );
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
const { it, describe, beforeAll } = require( '@jest/globals' );
|
||||
const { it, describe, beforeAll, afterAll } = require( '@jest/globals' );
|
||||
|
||||
const path = require( 'path' );
|
||||
const coreTestsPath = getCoreTestsRoot();
|
||||
|
@ -103,6 +103,15 @@ const runImportProductsTest = () => {
|
|||
await merchant.openAllProductsView();
|
||||
await merchant.openImportProducts();
|
||||
} );
|
||||
|
||||
afterAll(async () => {
|
||||
// Delete imported products
|
||||
await withRestApi.deleteAllProducts();
|
||||
await withRestApi.deleteAllProductAttributes();
|
||||
await withRestApi.deleteAllProductCategories();
|
||||
await withRestApi.deleteAllProductTags();
|
||||
});
|
||||
|
||||
it( 'should show error message if you go without providing CSV file', async () => {
|
||||
// Verify the error message if you go without providing CSV file
|
||||
await Promise.all( [
|
||||
|
@ -212,9 +221,6 @@ const runImportProductsTest = () => {
|
|||
expect( productPrices.sort() ).toEqual(
|
||||
productPricesOverride.sort()
|
||||
);
|
||||
|
||||
// Delete imported products
|
||||
await withRestApi.deleteAllProducts();
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
const { merchant } = require('@woocommerce/e2e-utils');
|
||||
const { merchant, withRestApi } = require('@woocommerce/e2e-utils');
|
||||
const { lorem, helpers } = require('faker');
|
||||
|
||||
const runAddShippingClassesTest = () => {
|
||||
|
@ -13,6 +13,10 @@ const runAddShippingClassesTest = () => {
|
|||
await merchant.openSettings('shipping', 'classes');
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await withRestApi.deleteAllShippingClasses();
|
||||
});
|
||||
|
||||
it('can add shipping classes', async () => {
|
||||
const shippingClassSlug = {
|
||||
name: lorem.words(),
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
- `utils.waitForTimeout( delay )` pause processing for `delay` milliseconds
|
||||
- `AdminEdit` class with utility functions for the respective edit screens
|
||||
- Update `shopper.addToCartFromShopPage()` and `.removeFromCart()` to accept product Id or Title
|
||||
- Added `deleteAllProductAttributes()`, `deleteAllProductCategories()`, and `deleteAllProductTags()` to clean up meta data added when products are imported
|
||||
- Added `withRestApi.createProductCategory()` that creates a product category and returns the ID
|
||||
|
||||
# 0.1.6
|
||||
|
|
|
@ -154,6 +154,9 @@ Please note: if you're using a non-SSL environment (such as a Docker container f
|
|||
| `updateSettingOption` | `settingsGroup`, `settingID`, `payload` | Update a settings group |
|
||||
| `updatePaymentGateway`| `paymentGatewayId`, `payload` | Update a payment gateway |
|
||||
| `getSystemEnvironment` | | Get the current environment from the WooCommerce system status API. |
|
||||
| `deleteAllProductAttributes` | | Permanently delete all product attributes. |
|
||||
| `deleteAllProductCategories` | | Permanently delete all product categories. |
|
||||
| `deleteAllProductTags` | | Permanently delete all product tags. |
|
||||
| `createProductCategory` | `categoryName` | Create a product category with the provided name. |
|
||||
|
||||
### Classes
|
||||
|
|
|
@ -8,6 +8,7 @@ const shippingZoneEndpoint = '/wc/v3/shipping/zones';
|
|||
const shippingClassesEndpoint = '/wc/v3/products/shipping_classes';
|
||||
const userEndpoint = '/wp/v2/users';
|
||||
const systemStatusEndpoint = '/wc/v3/system_status';
|
||||
const productsEndpoint = '/wc/v3/products';
|
||||
const productCategoriesEndpoint = '/wc/v3/products/categories';
|
||||
|
||||
/**
|
||||
|
@ -85,6 +86,55 @@ export const withRestApi = {
|
|||
const repository = SimpleProduct.restRepository( client );
|
||||
await deleteAllRepositoryObjects( repository );
|
||||
},
|
||||
/**
|
||||
* Use the API to delete all product attributes.
|
||||
*
|
||||
* @return {Promise} Promise resolving once attributes have been deleted.
|
||||
*/
|
||||
deleteAllProductAttributes: async () => {
|
||||
const productAttributesPath = productsEndpoint + '/attributes';
|
||||
const productAttributes = await client.get( productAttributesPath );
|
||||
if ( productAttributes.data && productAttributes.data.length ) {
|
||||
for ( let a = 0; a < productAttributes.data.length; a++ ) {
|
||||
const response = await client.delete( productAttributesPath + `/${productAttributes.data[a].id}?force=true` );
|
||||
expect( response.status ).toBe( 200 );
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Use the API to delete all product categories.
|
||||
*
|
||||
* @return {Promise} Promise resolving once categories have been deleted.
|
||||
*/
|
||||
deleteAllProductCategories: async () => {
|
||||
const productCategoriesPath = productsEndpoint + '/categories';
|
||||
const productCategories = await client.get( productCategoriesPath );
|
||||
if ( productCategories.data && productCategories.data.length ) {
|
||||
for ( let c = 0; c < productCategories.data.length; c++ ) {
|
||||
// The default `uncategorized` category can't be deleted
|
||||
if ( productCategories.data[c].id == 0 ) {
|
||||
continue;
|
||||
}
|
||||
const response = await client.delete( productCategoriesPath + `/${productCategories.data[c].id}?force=true` );
|
||||
expect( response.status ).toBe( 200 );
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Use the API to delete all product tags.
|
||||
*
|
||||
* @return {Promise} Promise resolving once tags have been deleted.
|
||||
*/
|
||||
deleteAllProductTags: async () => {
|
||||
const productTagsPath = productsEndpoint + '/tags';
|
||||
const productTags = await client.get( productTagsPath );
|
||||
if ( productTags.data && productTags.data.length ) {
|
||||
for ( let t = 0; t < productTags.data.length; t++ ) {
|
||||
const response = await client.delete( productTagsPath + `/${productTags.data[t].id}?force=true` );
|
||||
expect( response.status ).toBe( 200 );
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Use api package to delete all orders.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue