From baefb8d6e9203d9e175f8b7106817c90e0fdb65d Mon Sep 17 00:00:00 2001 From: Seghir Nadir Date: Fri, 5 Jun 2020 17:49:07 +0100 Subject: [PATCH] Add fixtures data for all entities. (https://github.com/woocommerce/woocommerce-blocks/pull/2548) * change entrypoint setup and install wc-rest-api * enable pretty links in docker * create fixtures functions * create and load global setup and teardown files * support multiple shipping zones * use env values * refactor command * fix typo in command * more to import instead of require * add docs * refactor test data to its own file and refactor shipping methods * revert to commonJS require * rename function name * rename global variable * update fixture functions to accept fixture as param * document fixture data * pin wc rest api * update package-lock * remove forgetten test line --- plugins/woocommerce-blocks/.env | 1 + .../bin/docker/wordpress/Dockerfile | 2 +- .../bin/docker/wp-cli/entrypoint.sh | 7 +- plugins/woocommerce-blocks/package-lock.json | 124 ++++++++- plugins/woocommerce-blocks/package.json | 1 + .../tests/e2e-tests/config/default.json | 120 ++++---- .../tests/e2e-tests/config/jest.config.js | 3 +- .../tests/e2e-tests/config/setup.js | 51 ++++ .../tests/e2e-tests/config/teardown.js | 26 ++ .../tests/e2e-tests/fixtures/fixture-data.js | 232 +++++++++++++++ .../e2e-tests/fixtures/fixture-loaders.js | 263 ++++++++++++++++++ 11 files changed, 751 insertions(+), 79 deletions(-) create mode 100644 plugins/woocommerce-blocks/tests/e2e-tests/config/setup.js create mode 100644 plugins/woocommerce-blocks/tests/e2e-tests/config/teardown.js create mode 100644 plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-data.js create mode 100644 plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-loaders.js diff --git a/plugins/woocommerce-blocks/.env b/plugins/woocommerce-blocks/.env index d07e146cfe9..82c1d404e75 100644 --- a/plugins/woocommerce-blocks/.env +++ b/plugins/woocommerce-blocks/.env @@ -6,6 +6,7 @@ WORDPRESS_DB_PASSWORD=wordpress # WordPress CLI environment WORDPRESS_PORT=8084 +WORDPRESS_BASE_URL=http://localhost WORDPRESS_HOST=wordpress-www:80 WORDPRESS_TITLE=WooCommerce Core E2E Test Suite WORDPRESS_LOGIN=admin diff --git a/plugins/woocommerce-blocks/bin/docker/wordpress/Dockerfile b/plugins/woocommerce-blocks/bin/docker/wordpress/Dockerfile index 199065d2013..8d927f52ee7 100644 --- a/plugins/woocommerce-blocks/bin/docker/wordpress/Dockerfile +++ b/plugins/woocommerce-blocks/bin/docker/wordpress/Dockerfile @@ -1 +1 @@ -FROM wordpress:5.3 +FROM wordpress:5.4 diff --git a/plugins/woocommerce-blocks/bin/docker/wp-cli/entrypoint.sh b/plugins/woocommerce-blocks/bin/docker/wp-cli/entrypoint.sh index b2091b3e849..54f65a17ac1 100644 --- a/plugins/woocommerce-blocks/bin/docker/wp-cli/entrypoint.sh +++ b/plugins/woocommerce-blocks/bin/docker/wp-cli/entrypoint.sh @@ -46,10 +46,13 @@ else --admin_email=${WORDPRESS_EMAIL} \ --skip-email fi - +# WC Rest API needs pretty links to work +wp rewrite structure "/%postname%/" --hard +# we cannot create API keys for the API, so we using basic auth, this plugin allows that. +wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate wp plugin install woocommerce --activate wp plugin activate woocommerce-gutenberg-products-block -wp theme install twentynineteen --activate +wp theme install storefront --activate wp user create customer customer@woocommercecoree2etestsuite.com --user_pass=password --role=customer --path=/var/www/html wp post create --post_type=page --post_status=publish --post_title='Ready' --post_content='E2E-tests.' diff --git a/plugins/woocommerce-blocks/package-lock.json b/plugins/woocommerce-blocks/package-lock.json index a5d73dce881..88248195ea9 100644 --- a/plugins/woocommerce-blocks/package-lock.json +++ b/plugins/woocommerce-blocks/package-lock.json @@ -8387,6 +8387,18 @@ "locutus": "2.0.11" } }, + "@woocommerce/woocommerce-rest-api": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@woocommerce/woocommerce-rest-api/-/woocommerce-rest-api-1.0.1.tgz", + "integrity": "sha512-YBk3EEYE0zax/egx6Rhpbu6hcCFyZpYQrjH9JO4NUGU3n3T0W9Edn7oAUbjL/c7Oezcg+UaQluCaKjY/B3zwxg==", + "dev": true, + "requires": { + "axios": "^0.19.0", + "create-hmac": "^1.1.7", + "oauth-1.0a": "^2.2.6", + "url-parse": "^1.4.7" + } + }, "@wordpress/a11y": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.9.0.tgz", @@ -9564,14 +9576,15 @@ } }, "@wordpress/compose": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.15.0.tgz", - "integrity": "sha512-v174JYkPLECIfS5ebaKPengCG5FTyi9Ie6r6Mn2qJYsYXegvEdqCSreLsA3JViPvqC3Shx8MHnXBraz+kqYqQQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.16.0.tgz", + "integrity": "sha512-441spdHY6fBqDq3/MWFnhY8Q2MJTNTNK74mR06X1PXvVoQxuhW8SHJbb7+uHL9JiHAF5MRpqMTrslHC/iBD81A==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", "@wordpress/element": "^2.14.0", "@wordpress/is-shallow-equal": "^2.0.0", + "clipboard": "^2.0.1", "lodash": "^4.17.15", "mousetrap": "^1.6.2", "react-resize-aware": "^3.0.0" @@ -9613,20 +9626,20 @@ } }, "@wordpress/keycodes": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.12.0.tgz", - "integrity": "sha512-7fUwfquRLmE4CvJahZTHdNn31heoDcyZ4acgEQR4iKYsKjX6dF1coZjUe693xbf/4r8GmsOg0/uYDImMdDm+1Q==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.13.0.tgz", + "integrity": "sha512-Bm3N4Qf5qLXds+eflM+JXD15VEW/7IQ7eqWt9/UhsssuDTMTMbXnYjxOAh5zoVi2toAMSMs8EYpV28V+Qv0ZjA==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", - "@wordpress/i18n": "^3.12.0", + "@wordpress/i18n": "^3.13.0", "lodash": "^4.17.15" }, "dependencies": { "@wordpress/i18n": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.12.0.tgz", - "integrity": "sha512-QkdHd2Z2yTFItBnnzzjMW4IXJlofWMivct4BkgwRivrG7kLxE7nd2xMG3+hFkkdYGdzE67u8vmin0gmQ+14yPA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.13.0.tgz", + "integrity": "sha512-eMlOvg2vYKmGV4C1vPrWuOEyskxMeCGoQJ0N3mQ6t7iWKs4bKWAJGlGL5QXMwN7xJJ863h3L7mrbLM3zKVrF1g==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -9652,15 +9665,61 @@ } }, "@wordpress/viewport": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.17.0.tgz", - "integrity": "sha512-dTgYZY8O7S2/Cs5vXT2eTSlCcWMbqJvYcfO+MEGXdD2AoMyMm/8ERNLcaaVEi4TAFCFBLQSWJya6XIY8GGvW9g==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.18.0.tgz", + "integrity": "sha512-uJhcbEtFWYvm/QEVeBUaUzDVOHXzqKP9frunzI/VvwjgduGXY1h+ntPXGD+KKPDtsj9ORgPn9BMrpPNmHI2VjQ==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", - "@wordpress/compose": "^3.15.0", - "@wordpress/data": "^4.18.0", + "@wordpress/compose": "^3.16.0", + "@wordpress/data": "^4.19.0", "lodash": "^4.17.15" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.19.0.tgz", + "integrity": "sha512-WdTBlro46qbkGDGx1ORKmL74KGR1ApKc5g1lJk6jtHVZZ/atw4Kler4eqkkYQZORt8lDJWBEDdonTBzSneUkmg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/compose": "^3.16.0", + "@wordpress/deprecated": "^2.8.0", + "@wordpress/element": "^2.14.0", + "@wordpress/is-shallow-equal": "^2.0.0", + "@wordpress/priority-queue": "^1.6.0", + "@wordpress/redux-routine": "^3.9.0", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/element": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.14.0.tgz", + "integrity": "sha512-msSkGecq2Z8lBoj95D0vxj64lbGx7c7Q8VxsNLA3G813HVybeY5gYeWFokWKfok+tszCwjJI4ZgR4DxRsYNTig==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/escape-html": "^1.8.0", + "lodash": "^4.17.15", + "react": "^16.9.0", + "react-dom": "^16.9.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-2.0.0.tgz", + "integrity": "sha512-Xv8b3Jno/3Td6nyj1J+skW96sbyfX7W4sk0TLwN2C2Pz6iQTSTQyGrXmTZWShITt4SOeA8gKpP6kAwSZ4O0HOQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2" + } + } } }, "uuid": { @@ -12123,6 +12182,15 @@ "integrity": "sha512-HZpLE7xu05+8AbpqXITGdxp1Xwk8ysAXrg7MiKRY27py3DAyEJpoJQo1727pWF3F+O79V3r+cTWhOzfB49P89w==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10" + } + }, "axobject-query": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", @@ -18069,6 +18137,26 @@ "integrity": "sha512-vkHTluRCoq9FcsrldC0ulQHiyBYgVJB2CX53I8r0nTC6KnEij7Of0jpBspjt3/CuNb6fyoj3aOh9J2HgQUM0og==", "dev": true }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -28451,6 +28539,12 @@ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", diff --git a/plugins/woocommerce-blocks/package.json b/plugins/woocommerce-blocks/package.json index e1a2440865d..f034c6f5962 100644 --- a/plugins/woocommerce-blocks/package.json +++ b/plugins/woocommerce-blocks/package.json @@ -83,6 +83,7 @@ "@types/react": "16.9.35", "@types/wordpress__data": "4.6.7", "@types/wordpress__element": "2.4.1", + "@woocommerce/woocommerce-rest-api": "1.0.1", "@wordpress/babel-preset-default": "4.10.0", "@wordpress/base-styles": "1.4.0", "@wordpress/blocks": "6.12.0", diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/config/default.json b/plugins/woocommerce-blocks/tests/e2e-tests/config/default.json index 7ec44329fe5..afca505d450 100644 --- a/plugins/woocommerce-blocks/tests/e2e-tests/config/default.json +++ b/plugins/woocommerce-blocks/tests/e2e-tests/config/default.json @@ -1,62 +1,62 @@ { - "url": "http://localhost:8084/", - "users": { - "admin": { - "username": "admin", - "password": "password" - }, - "customer": { - "username": "customer", - "password": "password" - } - }, - "products": { - "simple": { - "name": "Simple product" - }, - "variable": { - "name": "Variable Product with Three Variations" - } - }, - "addresses": { - "admin": { - "store": { - "firstname": "John", - "lastname": "Doe", - "company": "Automattic", - "country": "United States (US)", - "addressfirstline": "addr 1", - "addresssecondline": "addr 2", - "city": "San Francisco", - "state": "CA", - "postcode": "94107" - } - }, - "customer": { - "billing": { - "firstname": "John", - "lastname": "Doe", - "company": "Automattic", - "country": "United States (US)", - "addressfirstline": "addr 1", - "addresssecondline": "addr 2", - "city": "San Francisco", - "state": "CA", - "postcode": "94107", - "phone": "123456789", - "email": "john.doe@example.com" - }, - "shipping": { - "firstname": "John", - "lastname": "Doe", - "company": "Automattic", - "country": "United States (US)", - "addressfirstline": "addr 1", - "addresssecondline": "addr 2", - "city": "San Francisco", - "state": "CA", - "postcode": "94107" - } - } - } + "url": "http://localhost:8084/", + "users": { + "admin": { + "username": "admin", + "password": "password" + }, + "customer": { + "username": "customer", + "password": "password" + } + }, + "products": { + "simple": { + "name": "Simple product" + }, + "variable": { + "name": "Variable Product with Three Variations" + } + }, + "addresses": { + "admin": { + "store": { + "firstname": "John", + "lastname": "Doe", + "company": "Automattic", + "country": "United States (US)", + "addressfirstline": "addr 1", + "addresssecondline": "addr 2", + "city": "San Francisco", + "state": "CA", + "postcode": "94107" + } + }, + "customer": { + "billing": { + "firstname": "John", + "lastname": "Doe", + "company": "Automattic", + "country": "United States (US)", + "addressfirstline": "addr 1", + "addresssecondline": "addr 2", + "city": "San Francisco", + "state": "CA", + "postcode": "94107", + "phone": "123456789", + "email": "john.doe@example.com" + }, + "shipping": { + "firstname": "John", + "lastname": "Doe", + "company": "Automattic", + "country": "United States (US)", + "addressfirstline": "addr 1", + "addresssecondline": "addr 2", + "city": "San Francisco", + "state": "CA", + "postcode": "94107" + } + } + } } diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/config/jest.config.js b/plugins/woocommerce-blocks/tests/e2e-tests/config/jest.config.js index 64ac4c359e5..cdd94cff8c8 100644 --- a/plugins/woocommerce-blocks/tests/e2e-tests/config/jest.config.js +++ b/plugins/woocommerce-blocks/tests/e2e-tests/config/jest.config.js @@ -14,7 +14,8 @@ module.exports = { // Where to look for test files roots: [ '/tests/e2e-tests/specs' ], - + globalSetup: '/tests/e2e-tests/config/setup.js', + globalTeardown: '/tests/e2e-tests/config/teardown.js', setupFiles: [ '/tests/e2e-tests/config/env.setup.js' ], // A list of paths to modules that run some code to configure or set up the testing framework // before each test diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/config/setup.js b/plugins/woocommerce-blocks/tests/e2e-tests/config/setup.js new file mode 100644 index 00000000000..d9db19cc1ed --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e-tests/config/setup.js @@ -0,0 +1,51 @@ +/* eslint-disable no-console */ +/** + * External dependencies + */ +import { setup as setupPuppeteer } from 'jest-environment-puppeteer'; +/** + * Internal dependencies + */ +import { + setupSettings, + createTaxes, + createCoupons, + createProducts, + createShippingZones, + enablePaymentGateways, +} from '../fixtures/fixture-loaders'; + +module.exports = async ( globalConfig ) => { + // we need to load puppeteer global setup here. + await setupPuppeteer( globalConfig ); + + /** + * Promise.all will return an array of all promises resolved values. + * Some functions like setupSettings and enablePaymentGateways resolve + * to server data so we ignore the values here. + */ + return Promise.all( [ + setupSettings(), + createTaxes(), + createCoupons(), + createProducts(), + createShippingZones(), + enablePaymentGateways(), + ] ) + .then( ( results ) => { + /** + * We save our data in global so we can share it with teardown test. + * It is relativity safe to hold this data in global since the context + * in which setup and teardown run in is separate from the one our + * test use, so there is no risk of data bleeding. + */ + const [ , taxes, coupons, products, shippingZones ] = results; + global.fixtureData = { + taxes, + coupons, + products, + shippingZones, + }; + } ) + .catch( console.log ); +}; diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/config/teardown.js b/plugins/woocommerce-blocks/tests/e2e-tests/config/teardown.js new file mode 100644 index 00000000000..6b30a0f328a --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e-tests/config/teardown.js @@ -0,0 +1,26 @@ +/* eslint-disable no-console */ +/** + * External dependencies + */ +import { teardown as teardownPuppeteer } from 'jest-environment-puppeteer'; + +/** + * Internal dependencies + */ +import { + deleteTaxes, + deleteCoupons, + deleteProducts, + deleteShippingZones, +} from '../fixtures/fixture-loaders'; + +module.exports = async ( globalConfig ) => { + await teardownPuppeteer( globalConfig ); + const { taxes, coupons, products, shippingZones } = global.fixtureData; + return Promise.all( [ + deleteTaxes( taxes ), + deleteCoupons( coupons ), + deleteProducts( products ), + deleteShippingZones( shippingZones ), + ] ).catch( console.log ); +}; diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-data.js b/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-data.js new file mode 100644 index 00000000000..6cd71f9a97b --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-data.js @@ -0,0 +1,232 @@ +/** + * The default fixtures data is shaped according to WC REST API + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs|WooCommerce REST API} + */ + +/** + * Coupons fixture data, using the create batch endpoint + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-coupons|Batch update coupons} + */ +const Coupons = () => [ + { + code: 'coupon', + discount_type: 'fixed_cart', + amount: '5', + }, + { + code: 'oldcoupon', + discount_type: 'fixed_cart', + amount: '5', + date_expires: '2020-01-01', + }, + { + code: 'below100', + discount_type: 'percent', + amount: '20', + maximum_amount: '100.00', + }, + { + code: 'above50', + discount_type: 'percent', + amount: '20', + minimum_amount: '50.00', + }, + { + code: 'a12s', + discount_type: 'percent', + amount: '100', + individual_use: true, + email_restrictions: '*@automattic.com%2C *@a8c.com', + }, + { + code: 'freeshipping', + discount_type: 'percent', + amount: '0', + free_shipping: true, + }, +]; + +/** + * Reviews fixture data, using the create batch endpoint + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-product-reviews|Batch update product reviews} + * @param {number} id Product ID to add reviews to. + */ +const ReviewsInProduct = ( id ) => [ + { + product_id: id, + review: 'Looks fine', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + rating: 4, + }, + { + product_id: id, + review: 'I love this album', + reviewer: 'John Doe', + reviewer_email: 'john.doe@example.com', + rating: 5, + }, + { + product_id: id, + review: 'a fine review', + reviewer: "John Doe' niece", + reviewer_email: 'john.doe@example.com', + rating: 5, + }, +]; + +/** + * Product fixture data, using the create batch endpoint + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-products|Batch update products} + */ +const Products = () => [ + { + name: 'Woo Single #1', + type: 'simple', + regular_price: '21.99', + virtual: true, + downloadable: true, + downloads: [ + { + name: 'Woo Single', + file: + 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_4_angle.jpg', + }, + ], + images: [ + { + src: + 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_4_angle.jpg', + }, + ], + }, +]; + +/** + * Settings fixture data, using the update batch endpoint. + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-setting-options|Batch update setting options} + */ +const Settings = () => [ + { + id: 'woocommerce_store_address', + value: '60 29th Street #343', + }, + { + id: 'woocommerce_store_city', + value: 'San Francisco', + }, + { + id: 'woocommerce_store_country', + value: 'US:CA', + }, + { + id: 'woocommerce_store_postcode', + value: '94110', + }, + { + id: 'woocommerce_allowed_countries', + value: 'specific', + }, + { + id: 'woocommerce_specific_allowed_countries', + value: [ 'DZ', 'CA', 'NZ', 'ES', 'GB', 'US' ], + }, + { + id: 'woocommerce_ship_to_countries', + value: 'specific', + }, + { + id: 'woocommerce_specific_ship_to_countries', + value: [ 'DZ', 'CA', 'NZ', 'ES', 'GB', 'US' ], + }, + { + id: 'woocommerce_enable_coupons', + value: 'yes', + }, + { + id: 'woocommerce_calc_taxes', + value: 'yes', + }, + { + id: 'woocommerce_currency', + value: 'USD', + }, +]; + +/** + * Shipping Zones fixture data, using the shipping zone endpoint, shipping + * location, and shipping method endpoint. + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#create-a-shipping-zone|Create a shipping zone} + * * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#update-a-locations-of-a-shipping-zone|Update a locations of a shipping zone} + * * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#include-a-shipping-method-to-a-shipping-zone|Include a shipping method to a shipping zone} + */ +const Shipping = () => [ + { + name: 'UK', + locations: [ + { + code: 'UK', + }, + ], + methods: [ + { + method_id: 'flat_rate', + settings: { + title: 'Normal Shipping', + cost: '20.00', + }, + }, + { + method_id: 'free_shipping', + settings: { + title: 'Free Shipping', + cost: '00.00', + requires: 'coupon', + }, + }, + ], + }, +]; + +/** + * Taxes rates fixture data, using the create batch endpoint. + * + * @see {@link https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-tax-rates|Batch update tax rates} + */ +const Taxes = () => [ + { + country: 'US', + rate: '5.0000', + name: 'State Tax', + shipping: false, + priority: 1, + }, + { + country: 'US', + rate: '10.000', + name: 'Sale Tax', + shipping: false, + priority: 2, + }, + { + country: 'UK', + rate: '20.000', + name: 'VAT', + shipping: false, + }, +]; + +module.exports = { + Coupons, + ReviewsInProduct, + Products, + Settings, + Shipping, + Taxes, +}; diff --git a/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-loaders.js b/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-loaders.js new file mode 100644 index 00000000000..89a4b59f276 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e-tests/fixtures/fixture-loaders.js @@ -0,0 +1,263 @@ +/** + * External dependencies + */ +const WooCommerceRestApi = require( '@woocommerce/woocommerce-rest-api' ) + .default; + +require( 'dotenv' ).config(); + +/** + * Internal dependencies + */ + +const fixtures = require( './fixture-data' ); + +/** + * ConsumerKey and ConsumerSecret are not used, we use basic auth, but + * not providing them will throw an error. + */ +const WooCommerce = new WooCommerceRestApi( { + url: `${ process.env.WORDPRESS_BASE_URL }:${ process.env.WORDPRESS_PORT }/`, + consumerKey: 'consumer_key', // Your consumer key + consumerSecret: 'consumer_secret', // Your consumer secret + version: 'wc/v3', + axiosConfig: { + auth: { + username: process.env.WORDPRESS_LOGIN, + password: process.env.WORDPRESS_PASSWORD, + }, + }, +} ); + +/** + * prepare some store settings. + * + * @param {Object[]} fixture An array of objects describing our data, defaults + * to our fixture. + * @return {Promise} return a promise that resolves to the created data or + * reject if the request failed. + */ +const setupSettings = ( fixture = fixtures.Settings() ) => + WooCommerce.post( 'settings/general/batch', { + update: fixture, + } ); + +/** + * Create taxes. + * + * @param {Object[]} fixture An array of objects describing our data, defaults + * to our fixture. + * @return {Promise} a promise that resolves to an array of newly created taxes, + * or rejects if the request failed. + */ +const createTaxes = ( fixture = fixtures.Taxes() ) => + WooCommerce.post( 'taxes/batch', { + create: fixture, + } ).then( ( response ) => + response.data.create.map( ( taxes ) => taxes.id ) + ); +/** + * Delete taxes. + * + * @param {number[]} ids an array of taxes IDs to delete. + * + * @return {Promise} return a promise that resolves to the deleted data or + * reject if the request failed. + */ +const deleteTaxes = ( ids ) => + WooCommerce.post( 'taxes/batch', { + delete: ids, + } ); + +/** + * Create Coupons. + * + * @param {Object[]} fixture An array of objects describing our data, defaults + * to our fixture. + * @return {Promise} a promise that resolves to an array of newly created coupons, + * or rejects if the request failed. + */ +const createCoupons = ( fixture = fixtures.Coupons() ) => + WooCommerce.post( 'coupons/batch', { + create: fixture, + } ).then( ( response ) => + response.data.create.map( ( coupon ) => coupon.id ) + ); + +/** + * Delete coupons. + * + * @param {number[]} ids an array of coupons IDs to delete. + * + * @return {Promise} return a promise that resolves to the deleted data or + * reject if the request failed. + */ +const deleteCoupons = ( ids ) => + WooCommerce.post( 'coupons/batch', { + delete: ids, + } ); +/** + * Create Products and call createReviews. + * + * @param {Object[]} fixture An array of objects describing our data, defaults + * to our fixture. + * @return {Promise} a promise that resolves to an array of newly created products, + * or rejects if the request failed. + * + * currently this only creates a single product for the sake of reviews. + * @todo: add more products to e2e fixtures data. + */ +const createProducts = ( fixture = fixtures.Products() ) => + WooCommerce.post( 'products/batch', { + create: fixture, + } ).then( ( products ) => { + createReviews( products.data.create[ 0 ].id ); + return products.data.create.map( ( product ) => product.id ); + } ); + +/** + * Delete products. + * + * Deleting products will also delete review. + * + * @param {number[]} ids an array of products IDs to delete. + * + * @return {Promise} return a promise that resolves to the deleted data or + * reject if the request failed. + */ +const deleteProducts = ( ids ) => + WooCommerce.post( 'products/batch', { + delete: ids, + } ); + +/** + * Create Reviews. + +This is not called directly but is called within createProducts. + * + * @param {number} id product id to assign reviews to. + * @param {Object[]} fixture An array of objects describing our reviews, defaults + * to our fixture. + * @return {Promise} a promise that resolves to an server response data, or + * rejects if the request failed. + */ +const createReviews = ( id, fixture = fixtures.ReviewsInProduct( id ) ) => + WooCommerce.post( 'products/reviews/batch', { + create: fixture, + } ); + +/** + * Enable Cheque payments. + * + * This is not called directly but is called within enablePaymentGateways. + * + * @return {Promise} a promise that resolves to an server response data, or + * rejects if the request failed. + */ +const enableCheque = () => + WooCommerce.post( 'payment_gateways/cheque', { + enabled: true, + } ); + +/** + * Enable Paypal payments. + * + * This is not called directly but is called within enablePaymentGateways. + * + * @return {Promise} a promise that resolves to an server response data, or + * rejects if the request failed. + */ +const enablePaypal = () => + WooCommerce.post( 'payment_gateways/paypal', { + enabled: true, + } ); + +/** + * Enable payment gateways. + * + * It calls other individual payment gateway functions. + * + * @return {Promise} a promise that resolves to an array of server response + * data, or rejects if the request failed. + */ +const enablePaymentGateways = () => + Promise.all( [ enableCheque(), enablePaypal() ] ); + +/** + * Create shipping zones. + +Shipping locations need to be assigned to a zone, and shipping methods need +to be assigned to a shipping location, this create a shipping zone and location +and methods. + * + * @param {Object[]} fixture An array of objects describing our data, defaults + * to our fixture. + * @return {Promise} a promise that resolves to an array of newly created shipping + * zones IDs, or rejects if the request failed. + + */ +const createShippingZones = ( fixture = fixtures.Shipping() ) => { + return Promise.all( + fixture.map( ( { name, locations, methods } ) => { + return WooCommerce.post( 'shipping/zones', { name } ) + .then( ( response ) => { + return response.data.id; + } ) + .then( ( zoneId ) => { + const locationsPromise = WooCommerce.put( + `shipping/zones/${ zoneId }/locations`, + locations + ); + + return [ zoneId, locationsPromise ]; + } ) + .then( ( [ zoneId, locationsPromise ] ) => { + const methodPromise = Promise.all( + methods.map( ( method ) => + WooCommerce.post( + `shipping/zones/${ zoneId }/methods`, + method + ) + ) + ); + return [ zoneId, methodPromise, locationsPromise ]; + } ) + .then( ( [ zoneId, methodPromise, locationsPromise ] ) => + Promise.all( [ methodPromise, locationsPromise ] ).then( + () => zoneId + ) + ); + } ) + ); +}; + +/** + * Delete Shipping zones. + * + * Deleting a shipping will also delete location and methods defined within it. + * + * @param {number[]} ids an array of shipping zones IDs to delete. + * + * @return {Promise} return a promise that resolves to an array of deleted data or + * reject if the request failed. + */ +const deleteShippingZones = ( ids ) => { + const deleteZone = ( id ) => + WooCommerce.delete( `shipping/zones/${ id }`, { + force: true, + } ); + return Promise.all( ids.map( deleteZone ) ); +}; + +module.exports = { + setupSettings, + createTaxes, + deleteTaxes, + createCoupons, + deleteCoupons, + createProducts, + deleteProducts, + enablePaymentGateways, + createShippingZones, + deleteShippingZones, +};