Merge branch 'master' of github.com:woocommerce/woocommerce into add/e2e-merchant-product-views

# Conflicts:
#	tests/e2e/core-tests/CHANGELOG.md
#	tests/e2e/utils/README.md
This commit is contained in:
zhongruige 2021-02-10 09:19:14 -07:00
commit 642c3aa40f
99 changed files with 1385 additions and 506 deletions

View File

@ -1,5 +1,6 @@
/** @format */
const { useE2EEsLintConfig } = require( '@woocommerce/e2e-environment' );
const { useE2EEsLintConfig } = require( './tests/e2e/env/config/use-config' );
module.exports = useE2EEsLintConfig( {
root: true,

View File

@ -0,0 +1,121 @@
name: Build zip for PR
on:
pull_request
jobs:
build:
name: Build zip for PR
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build
id: build
uses: woocommerce/action-build@v2
- name: Upload PR zip
uses: actions/upload-artifact@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: woocommerce
path: ${{ steps.build.outputs.zip_path }}
retention-days: 7
- name: Add comment
uses: actions/github-script@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: ':package: Artifacts ready for [download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})!'
})
e2e-tests-cache:
name: Set e2e caches for running tests
runs-on: ubuntu-latest
steps:
- name: Checkout code.
uses: actions/checkout@v2
- name: Load Node.js.
uses: actions/setup-node@v2
with:
node-version: '12'
# From https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#using-the-cache-action
- name: Cache node modules
uses: actions/cache@v2
id: cache_node_modules
env:
cache-name: cache-node-modules
with:
path: ./node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
- name: Run npm install, and cache if they aren't.
run: npm install
e2e-tests-run:
name: Runs E2E tests.
runs-on: ubuntu-latest
needs: [ build, e2e-tests-cache ]
steps:
- name: Create dirs.
run: |
mkdir -p code/woocommerce
mkdir -p package/woocommerce
mkdir -p tmp/woocommerce
mkdir -p node_modules
- name: Checkout code.
uses: actions/checkout@v2
with:
path: package/woocommerce
# From https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#using-the-cache-action
- name: Cache node modules
uses: actions/cache@v2
id: cache_node_modules
env:
cache-name: cache-node-modules
with:
path: ./node_modules
key: ${{ runner.os }}-build-${{ hashFiles('package-lock.json') }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-
- name: Restore node modules from cache, if available.
run: mv ./node_modules package/woocommerce/node_modules
- name: Run npm install.
working-directory: package/woocommerce
run: npm install
- name: Load docker images and start containers.
working-directory: package/woocommerce
run: npx wc-e2e docker:up
- name: Move current directory to code. We will install zip file in this dir later.
run: mv ./package/woocommerce/* ./code/woocommerce
- name: Download WooCommerce ZIP.
uses: actions/download-artifact@v2
with:
name: woocommerce
path: tmp
- name: Extract and replace WooCommerce zip.
working-directory: tmp
run: |
unzip woocommerce.zip -d woocommerce
mv woocommerce/woocommerce/* ../package/woocommerce/
- name: Run tests command.
working-directory: code/woocommerce
run: npx wc-e2e test:e2e

View File

@ -1,21 +0,0 @@
name: Build zip for PR
on:
pull_request
jobs:
build:
name: Build zip for PR
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build
id: build
uses: woocommerce/action-build@v2
- name: Upload PR zip
uses: actions/upload-artifact@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: woocommerce.zip
path: ${{ steps.build.outputs.zip_path }}
retention-days: 7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -1 +1 @@
<svg viewBox="0 0 998 810" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M160.7 331.2h199.1c12.6 0 22.8 10.2 22.8 22.8v76c0 12.6-10.2 22.8-22.8 22.8h-71.4l9.8 24-43.1-24h-94.3c-12.6 0-22.8-10.2-22.8-22.8v-76c-.1-12.5 10.1-22.8 22.7-22.8z" fill="#9b5c8f" fill-rule="evenodd"/><path d="M150.2 351.9c1.4-1.9 3.5-2.9 6.3-3.1 5.1-.4 8 2 8.7 7.2 3.1 20.9 6.5 38.6 10.1 53.1l21.9-41.7c2-3.8 4.5-5.8 7.5-6 4.4-.3 7.1 2.5 8.2 8.4 2.5 13.3 5.7 24.6 9.5 34.2 2.6-25.4 7-43.7 13.2-55 1.5-2.8 3.7-4.2 6.6-4.4 2.3-.2 4.4.5 6.3 2s2.9 3.4 3.1 5.7c.1 1.8-.2 3.3-1 4.8-3.9 7.2-7.1 19.3-9.7 36.1-2.5 16.3-3.4 29-2.8 38.1.2 2.5-.2 4.7-1.2 6.6-1.2 2.2-3 3.4-5.3 3.6-2.6.2-5.3-1-7.9-3.7-9.3-9.5-16.7-23.7-22.1-42.6-6.5 12.8-11.3 22.4-14.4 28.8-5.9 11.3-10.9 17.1-15.1 17.4-2.7.2-5-2.1-7-6.9-5.1-13.1-10.6-38.4-16.5-75.9-.3-2.6.2-4.9 1.6-6.7zm215 15.7c-3.6-6.3-8.9-10.1-16-11.6-1.9-.4-3.7-.6-5.4-.6-9.6 0-17.4 5-23.5 15-5.2 8.5-7.8 17.9-7.8 28.2 0 7.7 1.6 14.3 4.8 19.8 3.6 6.3 8.9 10.1 16 11.6 1.9.4 3.7.6 5.4.6 9.7 0 17.5-5 23.5-15 5.2-8.6 7.8-18 7.8-28.3 0-7.8-1.6-14.3-4.8-19.7zm-12.6 27.7c-1.4 6.6-3.9 11.5-7.6 14.8-2.9 2.6-5.6 3.7-8.1 3.2-2.4-.5-4.4-2.6-5.9-6.5-1.2-3.1-1.8-6.2-1.8-9.1 0-2.5.2-5 .7-7.3.9-4.1 2.6-8.1 5.3-11.9 3.3-4.9 6.8-6.9 10.4-6.2 2.4.5 4.4 2.6 5.9 6.5 1.2 3.1 1.8 6.2 1.8 9.1 0 2.6-.3 5.1-.7 7.4zm-50.1-27.7c-3.6-6.3-9-10.1-16-11.6-1.9-.4-3.7-.6-5.4-.6-9.6 0-17.4 5-23.5 15-5.2 8.5-7.8 17.9-7.8 28.2 0 7.7 1.6 14.3 4.8 19.8 3.6 6.3 8.9 10.1 16 11.6 1.9.4 3.7.6 5.4.6 9.7 0 17.5-5 23.5-15 5.2-8.6 7.8-18 7.8-28.3 0-7.8-1.6-14.3-4.8-19.7zm-12.6 27.7c-1.4 6.6-3.9 11.5-7.6 14.8-2.9 2.6-5.6 3.7-8.1 3.2-2.4-.5-4.4-2.6-5.9-6.5-1.2-3.1-1.8-6.2-1.8-9.1 0-2.5.2-5 .7-7.3.9-4.1 2.6-8.1 5.3-11.9 3.3-4.9 6.8-6.9 10.4-6.2 2.4.5 4.4 2.6 5.9 6.5 1.2 3.1 1.8 6.2 1.8 9.1 0 2.6-.2 5.1-.7 7.4z" fill="#fff"/><path d="M407.9 366.7c-6.7 6.6-10 15-10 25.2 0 10.9 3.3 19.8 9.9 26.5s15.2 10.1 25.9 10.1c3.1 0 6.6-.5 10.4-1.6v-16.2c-3.5 1-6.5 1.5-9.1 1.5-5.3 0-9.5-1.8-12.7-5.3-3.2-3.6-4.8-8.4-4.8-14.5 0-5.7 1.6-10.4 4.7-14 3.2-3.7 7.1-5.5 11.9-5.5 3.1 0 6.4.5 10 1.5v-16.2c-3.3-.9-7-1.3-10.9-1.3-10.2-.1-18.6 3.2-25.3 9.8zm69.4-9.9c-9.2 0-16.4 3.1-21.6 9.2s-7.7 14.7-7.7 25.7c0 11.9 2.6 21 7.7 27.3s12.6 9.5 22.4 9.5c9.5 0 16.8-3.2 21.9-9.5s7.7-15.2 7.7-26.6-2.6-20.2-7.8-26.4c-5.3-6.1-12.8-9.2-22.6-9.2zm7.9 52c-1.8 2.8-4.5 4.2-7.9 4.2-3.2 0-5.6-1.4-7.3-4.2s-2.5-8.4-2.5-16.9c0-13.1 3.3-19.6 10-19.6 7 0 10.6 6.6 10.6 19.9-.1 8.2-1.1 13.8-2.9 16.6zm71.9-50.1l-3.6 15.3c-.9 3.9-1.8 7.9-2.6 12l-2 10.6c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7 68.1h17.4l4.7-46.9 11.9 46.9h12.4L567 380l4.9 46.8h18.2l-9.2-68.1zm83.3 0l-3.6 15.3c-.9 3.9-1.8 7.9-2.6 12l-2 10.6c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7 68.1h17.4l4.7-46.9 11.9 46.9h12.4l11.3-46.8 4.9 46.8h18.2l-9.2-68.1zm56.6 41.2h16.3v-14.1H697v-12.5h18.8v-14.5h-37.2v68.1h37.3v-14.5H697zm70.7-10.8c1.9-3.1 2.9-6.3 2.9-9.6 0-6.4-2.5-11.5-7.5-15.2s-11.9-5.6-20.5-5.6h-21.4v68.1h18.4v-31h.3l14.9 31h19.4l-14.7-30.7c3.5-1.6 6.3-3.9 8.2-7zm-28.2-1.1v-16.2c4.4.1 7.5.8 9.4 2.2s2.8 3.6 2.8 6.8c0 4.7-4.1 7.1-12.2 7.2zm41.9-21.3c-6.7 6.6-10 15-10 25.2 0 10.9 3.3 19.8 9.9 26.5s15.2 10.1 25.9 10.1c3.1 0 6.6-.5 10.4-1.6v-16.2c-3.5 1-6.5 1.5-9.1 1.5-5.3 0-9.5-1.8-12.7-5.3-3.2-3.6-4.8-8.4-4.8-14.5 0-5.7 1.6-10.4 4.7-14 3.2-3.7 7.1-5.5 11.9-5.5 3.1 0 6.4.5 10 1.5v-16.2c-3.3-.9-7-1.3-10.9-1.3-10.1-.1-18.6 3.2-25.3 9.8zm59.7 45.5v-12.4h16.3v-14.1h-16.3v-12.5H860v-14.5h-37.2v68.1h37.3v-14.5h-19z"/></svg>
<svg viewBox="0 0 998 810" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M160.7 331.2h199.1c12.6 0 22.8 10.2 22.8 22.8v76c0 12.6-10.2 22.8-22.8 22.8h-71.4l9.8 24-43.1-24h-94.3c-12.6 0-22.8-10.2-22.8-22.8v-76c-.1-12.5 10.1-22.8 22.7-22.8z" fill="#7f54b3" fill-rule="evenodd"/><path d="M150.2 351.9c1.4-1.9 3.5-2.9 6.3-3.1 5.1-.4 8 2 8.7 7.2 3.1 20.9 6.5 38.6 10.1 53.1l21.9-41.7c2-3.8 4.5-5.8 7.5-6 4.4-.3 7.1 2.5 8.2 8.4 2.5 13.3 5.7 24.6 9.5 34.2 2.6-25.4 7-43.7 13.2-55 1.5-2.8 3.7-4.2 6.6-4.4 2.3-.2 4.4.5 6.3 2s2.9 3.4 3.1 5.7c.1 1.8-.2 3.3-1 4.8-3.9 7.2-7.1 19.3-9.7 36.1-2.5 16.3-3.4 29-2.8 38.1.2 2.5-.2 4.7-1.2 6.6-1.2 2.2-3 3.4-5.3 3.6-2.6.2-5.3-1-7.9-3.7-9.3-9.5-16.7-23.7-22.1-42.6-6.5 12.8-11.3 22.4-14.4 28.8-5.9 11.3-10.9 17.1-15.1 17.4-2.7.2-5-2.1-7-6.9-5.1-13.1-10.6-38.4-16.5-75.9-.3-2.6.2-4.9 1.6-6.7zm215 15.7c-3.6-6.3-8.9-10.1-16-11.6-1.9-.4-3.7-.6-5.4-.6-9.6 0-17.4 5-23.5 15-5.2 8.5-7.8 17.9-7.8 28.2 0 7.7 1.6 14.3 4.8 19.8 3.6 6.3 8.9 10.1 16 11.6 1.9.4 3.7.6 5.4.6 9.7 0 17.5-5 23.5-15 5.2-8.6 7.8-18 7.8-28.3 0-7.8-1.6-14.3-4.8-19.7zm-12.6 27.7c-1.4 6.6-3.9 11.5-7.6 14.8-2.9 2.6-5.6 3.7-8.1 3.2-2.4-.5-4.4-2.6-5.9-6.5-1.2-3.1-1.8-6.2-1.8-9.1 0-2.5.2-5 .7-7.3.9-4.1 2.6-8.1 5.3-11.9 3.3-4.9 6.8-6.9 10.4-6.2 2.4.5 4.4 2.6 5.9 6.5 1.2 3.1 1.8 6.2 1.8 9.1 0 2.6-.3 5.1-.7 7.4zm-50.1-27.7c-3.6-6.3-9-10.1-16-11.6-1.9-.4-3.7-.6-5.4-.6-9.6 0-17.4 5-23.5 15-5.2 8.5-7.8 17.9-7.8 28.2 0 7.7 1.6 14.3 4.8 19.8 3.6 6.3 8.9 10.1 16 11.6 1.9.4 3.7.6 5.4.6 9.7 0 17.5-5 23.5-15 5.2-8.6 7.8-18 7.8-28.3 0-7.8-1.6-14.3-4.8-19.7zm-12.6 27.7c-1.4 6.6-3.9 11.5-7.6 14.8-2.9 2.6-5.6 3.7-8.1 3.2-2.4-.5-4.4-2.6-5.9-6.5-1.2-3.1-1.8-6.2-1.8-9.1 0-2.5.2-5 .7-7.3.9-4.1 2.6-8.1 5.3-11.9 3.3-4.9 6.8-6.9 10.4-6.2 2.4.5 4.4 2.6 5.9 6.5 1.2 3.1 1.8 6.2 1.8 9.1 0 2.6-.2 5.1-.7 7.4z" fill="#fff"/><path d="M407.9 366.7c-6.7 6.6-10 15-10 25.2 0 10.9 3.3 19.8 9.9 26.5s15.2 10.1 25.9 10.1c3.1 0 6.6-.5 10.4-1.6v-16.2c-3.5 1-6.5 1.5-9.1 1.5-5.3 0-9.5-1.8-12.7-5.3-3.2-3.6-4.8-8.4-4.8-14.5 0-5.7 1.6-10.4 4.7-14 3.2-3.7 7.1-5.5 11.9-5.5 3.1 0 6.4.5 10 1.5v-16.2c-3.3-.9-7-1.3-10.9-1.3-10.2-.1-18.6 3.2-25.3 9.8zm69.4-9.9c-9.2 0-16.4 3.1-21.6 9.2s-7.7 14.7-7.7 25.7c0 11.9 2.6 21 7.7 27.3s12.6 9.5 22.4 9.5c9.5 0 16.8-3.2 21.9-9.5s7.7-15.2 7.7-26.6-2.6-20.2-7.8-26.4c-5.3-6.1-12.8-9.2-22.6-9.2zm7.9 52c-1.8 2.8-4.5 4.2-7.9 4.2-3.2 0-5.6-1.4-7.3-4.2s-2.5-8.4-2.5-16.9c0-13.1 3.3-19.6 10-19.6 7 0 10.6 6.6 10.6 19.9-.1 8.2-1.1 13.8-2.9 16.6zm71.9-50.1l-3.6 15.3c-.9 3.9-1.8 7.9-2.6 12l-2 10.6c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7 68.1h17.4l4.7-46.9 11.9 46.9h12.4L567 380l4.9 46.8h18.2l-9.2-68.1zm83.3 0l-3.6 15.3c-.9 3.9-1.8 7.9-2.6 12l-2 10.6c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7 68.1h17.4l4.7-46.9 11.9 46.9h12.4l11.3-46.8 4.9 46.8h18.2l-9.2-68.1zm56.6 41.2h16.3v-14.1H697v-12.5h18.8v-14.5h-37.2v68.1h37.3v-14.5H697zm70.7-10.8c1.9-3.1 2.9-6.3 2.9-9.6 0-6.4-2.5-11.5-7.5-15.2s-11.9-5.6-20.5-5.6h-21.4v68.1h18.4v-31h.3l14.9 31h19.4l-14.7-30.7c3.5-1.6 6.3-3.9 8.2-7zm-28.2-1.1v-16.2c4.4.1 7.5.8 9.4 2.2s2.8 3.6 2.8 6.8c0 4.7-4.1 7.1-12.2 7.2zm41.9-21.3c-6.7 6.6-10 15-10 25.2 0 10.9 3.3 19.8 9.9 26.5s15.2 10.1 25.9 10.1c3.1 0 6.6-.5 10.4-1.6v-16.2c-3.5 1-6.5 1.5-9.1 1.5-5.3 0-9.5-1.8-12.7-5.3-3.2-3.6-4.8-8.4-4.8-14.5 0-5.7 1.6-10.4 4.7-14 3.2-3.7 7.1-5.5 11.9-5.5 3.1 0 6.4.5 10 1.5v-16.2c-3.3-.9-7-1.3-10.9-1.3-10.1-.1-18.6 3.2-25.3 9.8zm59.7 45.5v-12.4h16.3v-14.1h-16.3v-12.5H860v-14.5h-37.2v68.1h37.3v-14.5h-19z"/></svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -58,7 +58,7 @@
} else {
$( '#copy-error' ).text( '' );
wcClearClipboard();
wcSetClipboard( $.trim( $( this ).prev( 'input' ).val() ), $( css_class ) );
wcSetClipboard( $( this ).prev( 'input' ).val().trim(), $( css_class ) );
}
} )
.on( 'aftercopy', css_class, function() {

View File

@ -12,7 +12,7 @@ jQuery(function( $ ) {
init: function() {
$( 'select#discount_type' )
.on( 'change', this.type_options )
.change();
.trigger( 'change' );
this.insert_generate_coupon_code_button();
$( '.button.generate-coupon-code' ).on( 'click', this.generate_coupon_code );

View File

@ -90,7 +90,7 @@ jQuery( function ( $ ) {
$state.replaceWith( $newstate );
$newstate.show().selectWoo().hide().change();
$newstate.show().selectWoo().hide().trigger( 'change' );
} else {
$newstate = $( '<input type="text" />' )
.prop( 'id', input_id )
@ -143,8 +143,8 @@ jQuery( function ( $ ) {
$this.parent().find( 'a' ).toggle();
if ( ! $country_input.val() ) {
$country_input.val( woocommerce_admin_meta_boxes_order.default_country ).change();
$state_input.val( woocommerce_admin_meta_boxes_order.default_state ).change();
$country_input.val( woocommerce_admin_meta_boxes_order.default_country ).trigger( 'change' );
$state_input.val( woocommerce_admin_meta_boxes_order.default_state ).trigger( 'change' );
}
$edit_address.show();
@ -158,7 +158,7 @@ jQuery( function ( $ ) {
change_customer_user: function() {
if ( ! $( '#_billing_country' ).val() ) {
$( 'a.edit_address' ).click();
$( 'a.edit_address' ).trigger( 'click' );
wc_meta_boxes_order.load_billing( true );
wc_meta_boxes_order.load_shipping( true );
}
@ -196,7 +196,7 @@ jQuery( function ( $ ) {
success: function( response ) {
if ( response && response.billing ) {
$.each( response.billing, function( key, data ) {
$( ':input#_billing_' + key ).val( data ).change();
$( ':input#_billing_' + key ).val( data ).trigger( 'change' );
});
}
$( 'div.edit_address' ).unblock();
@ -238,7 +238,7 @@ jQuery( function ( $ ) {
success: function( response ) {
if ( response && response.billing ) {
$.each( response.shipping, function( key, data ) {
$( ':input#_shipping_' + key ).val( data ).change();
$( ':input#_shipping_' + key ).val( data ).trigger( 'change' );
});
}
$( 'div.edit_address' ).unblock();
@ -253,7 +253,7 @@ jQuery( function ( $ ) {
$('.order_data_column :input[name^="_billing_"]').each( function() {
var input_name = $(this).attr('name');
input_name = input_name.replace( '_billing_', '_shipping_' );
$( ':input#' + input_name ).val( $(this).val() ).change();
$( ':input#' + input_name ).val( $(this).val() ).trigger( 'change' );
});
}
return false;
@ -643,7 +643,7 @@ jQuery( function ( $ ) {
$( this ).closest( 'tr' ).find( '.view' ).hide();
$( this ).closest( 'tr' ).find( '.edit' ).show();
$( this ).hide();
$( 'button.add-line-item' ).click();
$( 'button.add-line-item' ).trigger( 'click' );
$( 'button.cancel-action' ).attr( 'data-reload', true );
window.wcTracks.recordEvent( 'order_edit_edit_item_click', {
order_id: woocommerce_admin_meta_boxes.post_id,
@ -1002,7 +1002,7 @@ jQuery( function ( $ ) {
'',
woocommerce_admin.mon_decimal_point
) )
.change();
.trigger( 'change' );
},
amount_changed: function() {
@ -1032,7 +1032,7 @@ jQuery( function ( $ ) {
parseFloat( accounting.formatNumber( unit_total * refund_qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
.toString()
.replace( '.', woocommerce_admin.mon_decimal_point )
).change();
).trigger( 'change' );
// Taxes
$( '.refund_line_tax', $row ).each( function() {
@ -1054,9 +1054,9 @@ jQuery( function ( $ ) {
parseFloat( accounting.formatNumber( unit_total_tax * refund_qty, precision, '' ) )
.toString()
.replace( '.', woocommerce_admin.mon_decimal_point )
).change();
).trigger( 'change' );
} else {
$refund_line_total_tax.val( 0 ).change();
$refund_line_total_tax.val( 0 ).trigger( 'change' );
}
});
@ -1401,7 +1401,7 @@ jQuery( function ( $ ) {
}
$( document.body ).trigger( 'wc-init-datepickers' );
$( '#grant_access_id' ).val( '' ).change();
$( '#grant_access_id' ).val( '' ).trigger( 'change' );
$( '.order_download_permissions' ).unblock();
});

View File

@ -19,7 +19,7 @@ jQuery( function( $ ) {
.on( 'click', 'h3 .sort', this.set_menu_order )
.on( 'reload', this.reload );
$( 'input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock' ).change();
$( 'input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock' ).trigger( 'change' );
$( '#woocommerce-product-data' ).on( 'woocommerce_variations_loaded', this.variations_loaded );
$( document.body ).on( 'woocommerce_variations_added', this.variation_added );
},
@ -95,7 +95,7 @@ jQuery( function( $ ) {
if ( ! needsUpdate ) {
// Show/hide downloadable, virtual and stock fields
$( 'input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock', wrapper ).change();
$( 'input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock', wrapper ).trigger( 'change' );
// Open sale schedule fields when have some sale price date
$( '.woocommerce_variation', wrapper ).each( function( index, el ) {
@ -104,7 +104,7 @@ jQuery( function( $ ) {
date_to = $( '.sale_price_dates_to', $el ).val();
if ( '' !== date_from || '' !== date_to ) {
$( 'a.sale_schedule', $el ).click();
$( 'a.sale_schedule', $el ).trigger( 'click' );
}
});
@ -138,7 +138,7 @@ jQuery( function( $ ) {
date = $( this ).datepicker( 'getDate' );
dates.not( this ).datepicker( 'option', option, date );
$( this ).change();
$( this ).trigger( 'change' );
}
});
@ -182,7 +182,7 @@ jQuery( function( $ ) {
if ( value != null ) {
// Set value, save changes and reload view
$menu_order.val( parseInt( value, 10 ) ).change();
$menu_order.val( parseInt( value, 10 ) ).trigger( 'change' );
wc_meta_boxes_product_variations_ajax.save_variations();
}
},
@ -199,7 +199,7 @@ jQuery( function( $ ) {
$( '.variation_menu_order', el )
.val( parseInt( $( el )
.index( '.woocommerce_variations .woocommerce_variation' ), 10 ) + 1 + offset )
.change();
.trigger( 'change' );
});
}
};
@ -262,7 +262,7 @@ jQuery( function( $ ) {
if ( $button.is( '.remove' ) ) {
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( '' ).change();
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( '' ).trigger( 'change' );
wc_meta_boxes_product_variations_media.setting_variation_image.find( 'img' ).eq( 0 )
.attr( 'src', woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src );
wc_meta_boxes_product_variations_media.setting_variation_image.find( '.upload_image_button' ).removeClass( 'remove' );
@ -301,7 +301,8 @@ jQuery( function( $ ) {
.get( 'selection' ).first().toJSON(),
url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( attachment.id ).change();
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( attachment.id )
.trigger( 'change' );
wc_meta_boxes_product_variations_media.setting_variation_image.find( '.upload_image_button' ).addClass( 'remove' );
wc_meta_boxes_product_variations_media.setting_variation_image.find( 'img' ).eq( 0 ).attr( 'src', url );
@ -346,7 +347,7 @@ jQuery( function( $ ) {
postForm.on( 'submit', this.save_on_submit );
$( 'input:submit', postForm ).bind( 'click keypress', function() {
$( 'input:submit', postForm ).on( 'click keypress', function() {
postForm.data( 'callerid', this.id );
});
@ -547,9 +548,9 @@ jQuery( function( $ ) {
callerid = postForm.data( 'callerid' );
if ( 'publish' === callerid ) {
postForm.append('<input type="hidden" name="publish" value="1" />').submit();
postForm.append('<input type="hidden" name="publish" value="1" />').trigger( 'submit' );
} else {
postForm.append('<input type="hidden" name="save-post" value="1" />').submit();
postForm.append('<input type="hidden" name="save-post" value="1" />').trigger( 'submit' );
}
},
@ -977,7 +978,7 @@ jQuery( function( $ ) {
* Set page
*/
set_page: function( page ) {
$( '.variations-pagenav .page-selector' ).val( page ).first().change();
$( '.variations-pagenav .page-selector' ).val( page ).first().trigger( 'change' );
},
/**

View File

@ -20,7 +20,7 @@ jQuery( function( $ ) {
});
// Prevent enter submitting post form.
$( '#upsell_product_data' ).bind( 'keypress', function( e ) {
$( '#upsell_product_data' ).on( 'keypress', function( e ) {
if ( e.keyCode === 13 ) {
return false;
}
@ -100,7 +100,7 @@ jQuery( function( $ ) {
var select_val = $( this ).val();
if ( 'variable' === select_val ) {
$( 'input#_manage_stock' ).change();
$( 'input#_manage_stock' ).trigger( 'change' );
$( 'input#_downloadable' ).prop( 'checked', false );
$( 'input#_virtual' ).removeAttr( 'checked' );
} else if ( 'grouped' === select_val ) {
@ -113,11 +113,11 @@ jQuery( function( $ ) {
show_and_hide_panels();
$( 'ul.wc-tabs li:visible' ).eq( 0 ).find( 'a' ).click();
$( 'ul.wc-tabs li:visible' ).eq( 0 ).find( 'a' ).trigger( 'click' );
$( document.body ).trigger( 'woocommerce-product-type-change', select_val, $( this ) );
}).change();
}).trigger( 'change' );
$( 'input#_downloadable, input#_virtual' ).change( function() {
show_and_hide_panels();
@ -165,7 +165,7 @@ jQuery( function( $ ) {
$( '.hide_if_' + product_type ).hide();
$( 'input#_manage_stock' ).change();
$( 'input#_manage_stock' ).trigger( 'change' );
// Hide empty panels/tabs after display.
$( '.woocommerce_options_panel' ).each( function() {
@ -250,8 +250,8 @@ jQuery( function( $ ) {
$( 'p.stock_status_field:not( .hide_if_' + product_type + ' )' ).show();
}
$( 'input.variable_manage_stock' ).change();
}).change();
$( 'input.variable_manage_stock' ).trigger( 'change' );
}).trigger( 'change' );
// Date picker fields.
function date_picker_select( datepicker ) {
@ -260,7 +260,7 @@ jQuery( function( $ ) {
date = $( datepicker ).datepicker( 'getDate' );
$( otherDateField ).datepicker( 'option', option, date );
$( datepicker ).change();
$( datepicker ).trigger( 'change' );
}
$( '.sale_price_dates_fields' ).each( function() {
@ -335,7 +335,7 @@ jQuery( function( $ ) {
attribute_row_indexes();
$attributes.find( '.woocommerce_attribute' ).last().find( 'h3' ).click();
$attributes.find( '.woocommerce_attribute' ).last().find( 'h3' ).trigger( 'click' );
$wrapper.unblock();
@ -356,13 +356,13 @@ jQuery( function( $ ) {
$( '.product_attributes' ).on( 'click', 'button.select_all_attributes', function() {
$( this ).closest( 'td' ).find( 'select option' ).prop( 'selected', 'selected' );
$( this ).closest( 'td' ).find( 'select' ).change();
$( this ).closest( 'td' ).find( 'select' ).trigger( 'change' );
return false;
});
$( '.product_attributes' ).on( 'click', 'button.select_no_attributes', function() {
$( this ).closest( 'td' ).find( 'select option' ).removeAttr( 'selected' );
$( this ).closest( 'td' ).find( 'select' ).change();
$( this ).closest( 'td' ).find( 'select' ).trigger( 'change' );
return false;
});
@ -436,7 +436,7 @@ jQuery( function( $ ) {
// Success.
$wrapper.find( 'select.attribute_values' )
.append( '<option value="' + response.term_id + '" selected="selected">' + response.name + '</option>' );
$wrapper.find( 'select.attribute_values' ).change();
$wrapper.find( 'select.attribute_values' ).trigger( 'change' );
}
$( '.product_attributes' ).unblock();
@ -556,7 +556,7 @@ jQuery( function( $ ) {
}
});
file_path_field.val( file_path ).change();
file_path_field.val( file_path ).trigger( 'change' );
});
// Set post to 0 and set our custom type.

View File

@ -32,7 +32,7 @@ jQuery( function ( $ ) {
$( $( this ).attr( 'href' ) ).show();
});
$( 'div.panel-wrap' ).each( function() {
$( this ).find( 'ul.wc-tabs li' ).eq( 0 ).find( 'a' ).click();
$( this ).find( 'ul.wc-tabs li' ).eq( 0 ).find( 'a' ).trigger( 'click' );
});
}).trigger( 'wc-init-tabbed-panels' );

View File

@ -44,8 +44,9 @@ jQuery(
$( 'input[name="_width"]', '.inline-edit-row' ).val( width );
$( 'input[name="_height"]', '.inline-edit-row' ).val( height );
$( 'select[name="_shipping_class"] option:selected', '.inline-edit-row' ).attr( 'selected', false ).change();
$( 'select[name="_shipping_class"] option[value="' + shipping_class + '"]' ).attr( 'selected', 'selected' ).change();
$( 'select[name="_shipping_class"] option:selected', '.inline-edit-row' ).attr( 'selected', false ).trigger( 'change' );
$( 'select[name="_shipping_class"] option[value="' + shipping_class + '"]' ).attr( 'selected', 'selected' )
.trigger( 'change' );
$( 'input[name="_stock"]', '.inline-edit-row' ).val( stock );
$( 'input[name="menu_order"]', '.inline-edit-row' ).val( menu_order );

View File

@ -10,7 +10,7 @@ jQuery(function( $ ) {
var prev_data_index = null;
var prev_series_index = null;
$( '.chart-placeholder' ).bind( 'plothover', function ( event, pos, item ) {
$( '.chart-placeholder' ).on( 'plothover', function ( event, pos, item ) {
if ( item ) {
if ( prev_data_index !== item.dataIndex || prev_series_index !== item.seriesIndex ) {
prev_data_index = item.dataIndex;

View File

@ -13,7 +13,7 @@
$( this ).closest('tr').next( 'tr' ).hide();
$( this ).closest('tr').next().next( 'tr' ).hide();
}
}).change();
}).trigger( 'change' );
// Ship Countries
$( 'select#woocommerce_ship_to_countries' ).change( function() {
@ -22,7 +22,7 @@
} else {
$( this ).closest('tr').next( 'tr' ).hide();
}
}).change();
}).trigger( 'change' );
// Stock management
$( 'input#woocommerce_manage_stock' ).change( function() {
@ -31,7 +31,7 @@
} else {
$( this ).closest('tbody').find( '.manage_stock_field' ).closest( 'tr' ).hide();
}
}).change();
}).trigger( 'change' );
// Color picker
$( '.colorpick' )
@ -56,9 +56,9 @@
var original_value = $( this ).data( 'original-value' );
if ( original_value.match( /^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ ) ) {
$( this ).val( $( this ).data( 'original-value' ) ).change();
$( this ).val( $( this ).data( 'original-value' ) ).trigger( 'change' );
} else {
$( this ).val( '' ).change();
$( this ).val( '' ).trigger( 'change' );
}
}
});

View File

@ -34,11 +34,11 @@ jQuery( function ( $ ) {
$( '.wc_status_table thead, .wc_status_table tbody' ).each( function() {
if ( $( this ).is( 'thead' ) ) {
var label = $( this ).find( 'th:eq(0)' ).data( 'export-label' ) || $( this ).text();
report = report + '\n### ' + $.trim( label ) + ' ###\n\n';
report = report + '\n### ' + label.trim() + ' ###\n\n';
} else {
$( 'tr', $( this ) ).each( function() {
var label = $( this ).find( 'td:eq(0)' ).data( 'export-label' ) || $( this ).find( 'td:eq(0)' ).text();
var the_name = $.trim( label ).replace( /(<([^>]+)>)/ig, '' ); // Remove HTML.
var the_name = label.trim().replace( /(<([^>]+)>)/ig, '' ); // Remove HTML.
// Find value
var $value_html = $( this ).find( 'td:eq(2)' ).clone();
@ -47,7 +47,7 @@ jQuery( function ( $ ) {
$value_html.find( '.dashicons-no-alt, .dashicons-warning' ).replaceWith( '&#10060;' );
// Format value
var the_value = $.trim( $value_html.text() );
var the_value = $value_html.text().trim();
var value_array = the_value.split( ', ' );
if ( value_array.length > 1 ) {

View File

@ -71,7 +71,7 @@ jQuery( function ( $ ) {
$state.replaceWith( $newstate );
$newstate.show().selectWoo().hide().change();
$newstate.show().selectWoo().hide().trigger( 'change' );
} else {
$newstate = $( '<input type="text" />' )
.prop( 'id', input_id )

View File

@ -93,7 +93,7 @@
if ( -1 !== $.inArray( 'variation', $( this ).val() ) ) {
exportCategory.closest( 'tr' ).hide();
exportCategory.val( '' ).change(); // Reset WooSelect selected value.
exportCategory.val( '' ).trigger( 'change' ); // Reset WooSelect selected value.
} else {
exportCategory.closest( 'tr' ).show();
}

View File

@ -37,7 +37,7 @@ jQuery( function( $ ) {
} );
$( document.body ).on( 'wc_backbone_modal_response', function() {
form.unbind( 'submit' ).submit();
form.unbind( 'submit' ).trigger( 'submit' );
} );
$( '#wc_tracker_checkbox_dialog' ).on( 'change', function( e ) {
@ -46,7 +46,7 @@ jQuery( function( $ ) {
} );
$( '#wc_tracker_submit' ).on( 'click', function () {
form.unbind( 'submit' ).submit();
form.unbind( 'submit' ).trigger( 'submit' );
} );
return true;
@ -72,13 +72,13 @@ jQuery( function( $ ) {
} );
$( '.store-state-container' ).show();
$state_select.selectWoo().val( wc_base_state ).change().prop( 'required', true );
$state_select.selectWoo().val( wc_base_state ).trigger( 'change' ).prop( 'required', true );
} else {
$( '.store-state-container' ).hide();
$state_select.empty().val( '' ).change().prop( 'required', false );
$state_select.empty().val( '' ).trigger( 'change' ).prop( 'required', false );
}
$( '#currency_code' ).val( wc_setup_currencies[ country ] ).change();
$( '#currency_code' ).val( wc_setup_currencies[ country ] ).trigger( 'change' );
} );
/* Setup postcode field and validations */
@ -100,7 +100,7 @@ jQuery( function( $ ) {
}
} );
$( '#store_country' ).change();
$( '#store_country' ).trigger( 'change' );
$( '.wc-wizard-services' ).on( 'change', '.wc-wizard-service-enable input', function() {
if ( $( this ).is( ':checked' ) ) {
@ -121,7 +121,7 @@ jQuery( function( $ ) {
$focused = $( document.activeElement );
if ( $focused.is( '.wc-wizard-service-toggle, .wc-wizard-service-enable' ) && ( 13 === code || 32 === code ) ) {
$focused.find( ':input' ).click();
$focused.find( ':input' ).trigger( 'click' );
}
} );
@ -135,7 +135,7 @@ jQuery( function( $ ) {
var $checkbox = $( this ).find( 'input[type="checkbox"]' );
$checkbox.prop( 'checked', ! $checkbox.prop( 'checked' ) ).change();
$checkbox.prop( 'checked', ! $checkbox.prop( 'checked' ) ).trigger( 'change' );
} );
$( '.wc-wizard-services-list-toggle' ).on( 'click', function() {
@ -165,7 +165,7 @@ jQuery( function( $ ) {
.removeClass( 'hide' )
.find( '.shipping-method-required-field' )
.prop( 'required', $checkbox.prop( 'checked' ) );
} ).find( '.wc-wizard-shipping-method-select .method' ).change();
} ).find( '.wc-wizard-shipping-method-select .method' ).trigger( 'change' );
$( '.wc-wizard-services' ).on( 'change', '.wc-wizard-shipping-method-enable', function() {
var checked = $( this ).is( ':checked' );
@ -182,7 +182,7 @@ jQuery( function( $ ) {
} );
function submitActivateForm() {
$( 'form.activate-jetpack' ).submit();
$( 'form.activate-jetpack' ).trigger( 'submit' );
}
function waitForJetpackInstall() {
@ -239,7 +239,7 @@ jQuery( function( $ ) {
.prop( 'disabled', true )
.prop( 'required', false );
}
} ).find( 'input#stripe_create_account, input#ppec_paypal_reroute_requests' ).change();
} ).find( 'input#stripe_create_account, input#ppec_paypal_reroute_requests' ).trigger( 'change' );
function addPlugins( bySlug, $el, hover ) {
var plugins = $el.data( 'plugins' );

View File

@ -354,7 +354,7 @@
}
});
$( '.wc-shipping-zone-method-selector select' ).change();
$( '.wc-shipping-zone-method-selector select' ).trigger( 'change' );
},
onAddShippingMethodSubmitted: function( event, target, posted_data ) {
if ( 'wc-modal-add-shipping-method' === target ) {

View File

@ -250,7 +250,7 @@
var shifted = false;
var hasFocus = false;
$( document.body ).bind( 'keyup keydown', function( e ) {
$( document.body ).on( 'keyup keydown', function( e ) {
shifted = e.shiftKey;
controlled = e.ctrlKey || e.metaKey;
});
@ -315,7 +315,7 @@
} else {
$( this ).closest( 'tr' ).next( 'tr' ).show();
}
}).change();
}).trigger( 'change' );
// Hidden options
$( '.hide_options_if_checked' ).each( function() {
@ -331,7 +331,7 @@
.nextUntil( '.hide_options_if_checked, .show_options_if_checked', '.hidden_option' )
.show();
}
}).change();
}).trigger( 'change' );
});
$( '.show_options_if_checked' ).each( function() {
@ -347,7 +347,7 @@
.nextUntil( '.hide_options_if_checked, .show_options_if_checked', '.hidden_option' )
.hide();
}
}).change();
}).trigger( 'change' );
});
// Reviews.
@ -357,7 +357,7 @@
} else {
$( '#woocommerce_enable_review_rating' ).closest( 'tr' ).hide();
}
}).change();
}).trigger( 'change' );
// Attribute term table
$( 'table.attributes-table tbody tr:nth-child(odd)' ).addClass( 'alternate' );

View File

@ -24,7 +24,7 @@ jQuery( function( $ ) {
})
// Trigger initial click
.find( 'input[name=payment_method]:checked' ).click();
.find( 'input[name=payment_method]:checked' ).trigger( 'click' );
$( '#add_payment_method' ).submit( function() {
$( '#add_payment_method' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });

View File

@ -53,7 +53,7 @@
*/
VariationForm.prototype.onReset = function( event ) {
event.preventDefault();
event.data.variationForm.$attributeFields.val( '' ).change();
event.data.variationForm.$attributeFields.val( '' ).trigger( 'change' );
event.data.variationForm.$form.trigger( 'reset_data' );
};
@ -286,11 +286,11 @@
$template_html = $template_html.replace( '/*]]>*/', '' );
form.$singleVariation.html( $template_html );
form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( variation.variation_id ).change();
form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( variation.variation_id ).trigger( 'change' );
// Hide or show qty input
if ( variation.is_sold_individually === 'yes' ) {
$qty.find( 'input.qty' ).val( '1' ).attr( 'min', '1' ).attr( 'max', '' ).change();
$qty.find( 'input.qty' ).val( '1' ).attr( 'min', '1' ).attr( 'max', '' ).trigger( 'change' );
$qty.hide();
} else {
@ -304,7 +304,7 @@
qty_val = qty_val < parseFloat( variation.min_qty ) ? variation.min_qty : qty_val;
}
$qty_input.attr( 'min', variation.min_qty ).attr( 'max', variation.max_qty ).val( qty_val ).change();
$qty_input.attr( 'min', variation.min_qty ).attr( 'max', variation.max_qty ).val( qty_val ).trigger( 'change' );
$qty.show();
}
@ -314,7 +314,7 @@
}
// Reveal
if ( $.trim( form.$singleVariation.text() ) ) {
if ( form.$singleVariation.text().trim() ) {
form.$singleVariation.slideDown( 200 ).trigger( 'show_variation', [ variation, purchasable ] );
} else {
form.$singleVariation.show().trigger( 'show_variation', [ variation, purchasable ] );
@ -327,7 +327,7 @@
VariationForm.prototype.onChange = function( event ) {
var form = event.data.variationForm;
form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( '' ).change();
form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( '' ).trigger( 'change' );
form.$form.find( '.wc-no-matching-variations' ).remove();
if ( form.useAjax ) {
@ -379,7 +379,7 @@
if ( ! current_attr_select.data( 'attribute_html' ) ) {
var refSelect = current_attr_select.clone();
refSelect.find( 'option' ).removeAttr( 'disabled attached' ).removeAttr( 'selected' );
refSelect.find( 'option' ).prop( 'disabled attached', false ).prop( 'selected', false );
// Legacy data attribute.
current_attr_select.data(
@ -484,7 +484,7 @@
if ( selected_attr_val_valid ) {
current_attr_select.val( selected_attr_val );
} else {
current_attr_select.val( '' ).change();
current_attr_select.val( '' ).trigger( 'change' );
}
} else {
current_attr_select.val( '' ); // No change event to prevent infinite loop.

View File

@ -32,7 +32,7 @@ jQuery( function( $ ) {
// Handle locale
$( document.body )
.bind( 'country_to_state_changing', function( event, country, wrapper ) {
.on( 'country_to_state_changing', function( event, country, wrapper ) {
var thisform = wrapper, thislocale;
if ( typeof locale[ country ] !== 'undefined' ) {

View File

@ -16,8 +16,8 @@ jQuery( function( $ ) {
$order_review: $( '#order_review' ),
$checkout_form: $( 'form.checkout' ),
init: function() {
$( document.body ).bind( 'update_checkout', this.update_checkout );
$( document.body ).bind( 'init_checkout', this.init_checkout );
$( document.body ).on( 'update_checkout', this.update_checkout );
$( document.body ).on( 'init_checkout', this.init_checkout );
// Payment methods
this.$checkout_form.on( 'click', 'input[name="payment_method"]', this.payment_method_selected );
@ -50,7 +50,7 @@ jQuery( function( $ ) {
this.$checkout_form.on( 'change', '#ship-to-different-address input', this.ship_to_different_address );
// Trigger events
this.$checkout_form.find( '#ship-to-different-address input' ).change();
this.$checkout_form.find( '#ship-to-different-address input' ).trigger( 'change' );
this.init_payment_methods();
// Update on page load
@ -58,7 +58,7 @@ jQuery( function( $ ) {
$( document.body ).trigger( 'init_checkout' );
}
if ( wc_checkout_params.option_guest_checkout === 'yes' ) {
$( 'input#createaccount' ).change( this.toggle_create_account ).change();
$( 'input#createaccount' ).change( this.toggle_create_account ).trigger( 'change' );
}
},
init_payment_methods: function() {
@ -130,7 +130,7 @@ jQuery( function( $ ) {
if ( $( this ).is( ':checked' ) ) {
// Ensure password is not pre-populated.
$( '#account_password' ).val( '' ).change();
$( '#account_password' ).val( '' ).trigger( 'change' );
$( 'div.create-account' ).slideDown();
}
},
@ -380,11 +380,11 @@ jQuery( function( $ ) {
var ID = $( this ).attr( 'id' );
if ( ID ) {
if ( $.inArray( $( this ).attr( 'type' ), [ 'checkbox', 'radio' ] ) !== -1 ) {
$( this ).prop( 'checked', paymentDetails[ ID ] ).change();
$( this ).prop( 'checked', paymentDetails[ ID ] ).trigger( 'change' );
} else if ( $.inArray( $( this ).attr( 'type' ), [ 'select' ] ) !== -1 ) {
$( this ).val( paymentDetails[ ID ] ).change();
$( this ).val( paymentDetails[ ID ] ).trigger( 'change' );
} else if ( null !== $( this ).val() && 0 === $( this ).val().length ) {
$( this ).val( paymentDetails[ ID ] ).change();
$( this ).val( paymentDetails[ ID ] ).trigger( 'change' );
}
}
});
@ -406,7 +406,7 @@ jQuery( function( $ ) {
}
// Lose focus for all fields
$form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
$form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).trigger( 'blur' );
wc_checkout_form.scroll_to_notices();
}
@ -560,7 +560,7 @@ jQuery( function( $ ) {
$( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove();
wc_checkout_form.$checkout_form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' ); // eslint-disable-line max-len
wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock();
wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).trigger( 'blur' );
wc_checkout_form.scroll_to_notices();
$( document.body ).trigger( 'checkout_error' , [ error_message ] );
},

View File

@ -70,7 +70,7 @@ jQuery( function( $ ) {
wc_country_select_select2();
$( document.body ).bind( 'country_to_state_changed', function() {
$( document.body ).on( 'country_to_state_changed', function() {
wc_country_select_select2();
});
}
@ -142,7 +142,7 @@ jQuery( function( $ ) {
$statebox.append( $option );
} );
$statebox.val( value ).change();
$statebox.val( value ).trigger( 'change' );
$( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] );
}

View File

@ -17,7 +17,7 @@
'form.edit-account #password_1, form.lost_reset_password #password_1',
this.strengthMeter
);
$( 'form.checkout #createaccount' ).change();
$( 'form.checkout #createaccount' ).trigger( 'change' );
},
/**

View File

@ -76,7 +76,7 @@ jQuery( function( $ ) {
wp.customize.widgetsPreview.WidgetPartial
);
if ( hasSelectiveRefresh ) {
wp.customize.selectiveRefresh.on( 'partial-content-rendered', function() {
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
init_price_filter();
} );
}

View File

@ -16,13 +16,13 @@ jQuery( function( $ ) {
var $tabs = $( this ).find( '.wc-tabs, ul.tabs' ).first();
if ( hash.toLowerCase().indexOf( 'comment-' ) >= 0 || hash === '#reviews' || hash === '#tab-reviews' ) {
$tabs.find( 'li.reviews_tab a' ).click();
$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
} else if ( url.indexOf( 'comment-page-' ) > 0 || url.indexOf( 'cpage=' ) > 0 ) {
$tabs.find( 'li.reviews_tab a' ).click();
$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
} else if ( hash === '#tab-additional_information' ) {
$tabs.find( 'li.additional_information_tab a' ).click();
$tabs.find( 'li.additional_information_tab a' ).trigger( 'click' );
} else {
$tabs.find( 'li:first a' ).click();
$tabs.find( 'li:first a' ).trigger( 'click' );
}
} )
.on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) {
@ -39,7 +39,7 @@ jQuery( function( $ ) {
} )
// Review link
.on( 'click', 'a.woocommerce-review-link', function() {
$( '.reviews_tab a' ).click();
$( '.reviews_tab a' ).trigger( 'click' );
return true;
} )
// Star ratings for comments
@ -101,8 +101,8 @@ jQuery( function( $ ) {
$target.data( 'product_gallery', this );
// Pick functionality to initialize...
this.flexslider_enabled = $.isFunction( $.fn.flexslider ) && wc_single_product_params.flexslider_enabled;
this.zoom_enabled = $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled;
this.flexslider_enabled = 'function' === typeof $.fn.flexslider && wc_single_product_params.flexslider_enabled;
this.zoom_enabled = 'function' === typeof $.fn.zoom && wc_single_product_params.zoom_enabled;
this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled;
// ...also taking args into account.

View File

@ -2,7 +2,7 @@
jQuery( function( $ ) {
// Orderby
$( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() {
$( this ).closest( 'form' ).submit();
$( this ).closest( 'form' ).trigger( 'submit' );
});
// Target quantity inputs on product pages

View File

@ -10,7 +10,7 @@ rm -rf "$BUILD_PATH"
mkdir -p "$DEST_PATH"
echo "Installing PHP and JS dependencies..."
npm install
npm run install:no-e2e
composer install || exit "$?"
echo "Running JS Build..."
npm run build:core || exit "$?"

View File

@ -4,7 +4,7 @@
},
"config": {
"platform": {
"php": "7.2"
"php": "7.3"
}
}
}

View File

@ -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": "cbcce1648bdb890ae805e1afb7396e3c",
"content-hash": "53c40e5764ce9bbe304e6aee0508ccb7",
"packages": [],
"packages-dev": [
{
@ -13,26 +13,26 @@
"source": {
"type": "git",
"url": "https://github.com/coenjacobs/mozart.git",
"reference": "5d8041fdefc94ff57edcbe83ab468a9988c4fc11"
"reference": "782a9282a7097ae38ddb7600388885059de10ea1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/coenjacobs/mozart/zipball/5d8041fdefc94ff57edcbe83ab468a9988c4fc11",
"reference": "5d8041fdefc94ff57edcbe83ab468a9988c4fc11",
"url": "https://api.github.com/repos/coenjacobs/mozart/zipball/782a9282a7097ae38ddb7600388885059de10ea1",
"reference": "782a9282a7097ae38ddb7600388885059de10ea1",
"shasum": ""
},
"require": {
"league/flysystem": "^1.0",
"php": "^7.2",
"php": "^7.3|^8.0",
"symfony/console": "^4|^5",
"symfony/finder": "^4|^5"
},
"require-dev": {
"mheap/phpunit-github-actions-printer": "^1.4",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "^3.5"
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.4"
},
"default-branch": true,
"bin": [
"bin/mozart"
],
@ -53,42 +53,39 @@
}
],
"description": "Composes all dependencies as a package inside a WordPress plugin",
"support": {
"issues": "https://github.com/coenjacobs/mozart/issues",
"source": "https://github.com/coenjacobs/mozart/tree/master"
},
"funding": [
{
"url": "https://github.com/coenjacobs",
"type": "github"
}
],
"time": "2020-11-23T21:03:43+00:00"
"time": "2021-02-03T20:37:56+00:00"
},
{
"name": "league/flysystem",
"version": "1.0.70",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "585824702f534f8d3cf7fab7225e8466cc4b7493"
"reference": "9be3b16c877d477357c015cec057548cf9b2a14a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/585824702f534f8d3cf7fab7225e8466cc4b7493",
"reference": "585824702f534f8d3cf7fab7225e8466cc4b7493",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/9be3b16c877d477357c015cec057548cf9b2a14a",
"reference": "9be3b16c877d477357c015cec057548cf9b2a14a",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": ">=5.5.9"
"league/mime-type-detection": "^1.3",
"php": "^7.2.5 || ^8.0"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"phpunit/phpunit": "^5.7.26"
"phpspec/prophecy": "^1.11.1",
"phpunit/phpunit": "^8.5.8"
},
"suggest": {
"ext-fileinfo": "Required for MimeType",
@ -147,17 +144,65 @@
"sftp",
"storage"
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.0.70"
},
"funding": [
{
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"time": "2020-07-26T07:20:36+00:00"
"time": "2020-08-23T07:39:11+00:00"
},
{
"name": "league/mime-type-detection",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": "^7.2 || ^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.18",
"phpstan/phpstan": "^0.12.68",
"phpunit/phpunit": "^8.5.8 || ^9.3"
},
"type": "library",
"autoload": {
"psr-4": {
"League\\MimeTypeDetection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
}
],
"description": "Mime-type detection for Flysystem",
"funding": [
{
"url": "https://github.com/frankdejonge",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/flysystem",
"type": "tidelift"
}
],
"time": "2021-01-18T20:58:21+00:00"
},
{
"name": "psr/container",
@ -214,42 +259,44 @@
},
{
"name": "symfony/console",
"version": "v4.4.18",
"version": "v5.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "12e071278e396cc3e1c149857337e9e192deca0b"
"reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/12e071278e396cc3e1c149857337e9e192deca0b",
"reference": "12e071278e396cc3e1c149857337e9e192deca0b",
"url": "https://api.github.com/repos/symfony/console/zipball/89d4b176d12a2946a1ae4e34906a025b7b6b135a",
"reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"php": ">=7.2.5",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15",
"symfony/service-contracts": "^1.1|^2"
"symfony/service-contracts": "^1.1|^2",
"symfony/string": "^5.1"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
"symfony/event-dispatcher": "<4.3|>=5",
"symfony/dependency-injection": "<4.4",
"symfony/dotenv": "<5.1",
"symfony/event-dispatcher": "<4.4",
"symfony/lock": "<4.4",
"symfony/process": "<3.3"
"symfony/process": "<4.4"
},
"provide": {
"psr/log-implementation": "1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "^3.4|^4.0|^5.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0",
"symfony/event-dispatcher": "^4.3",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/event-dispatcher": "^4.4|^5.0",
"symfony/lock": "^4.4|^5.0",
"symfony/process": "^3.4|^4.0|^5.0",
"symfony/var-dumper": "^4.3|^5.0"
"symfony/process": "^4.4|^5.0",
"symfony/var-dumper": "^4.4|^5.0"
},
"suggest": {
"psr/log": "For using the console logger",
@ -280,11 +327,14 @@
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/console/tree/v4.4.18"
},
"keywords": [
"cli",
"command line",
"console",
"terminal"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -299,24 +349,24 @@
"type": "tidelift"
}
],
"time": "2020-12-18T07:41:31+00:00"
"time": "2021-01-28T22:06:19+00:00"
},
{
"name": "symfony/finder",
"version": "v4.4.18",
"version": "v5.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "ebd0965f2dc2d4e0f11487c16fbb041e50b5c09b"
"reference": "4adc8d172d602008c204c2e16956f99257248e03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/ebd0965f2dc2d4e0f11487c16fbb041e50b5c09b",
"reference": "ebd0965f2dc2d4e0f11487c16fbb041e50b5c09b",
"url": "https://api.github.com/repos/symfony/finder/zipball/4adc8d172d602008c204c2e16956f99257248e03",
"reference": "4adc8d172d602008c204c2e16956f99257248e03",
"shasum": ""
},
"require": {
"php": ">=7.1.3"
"php": ">=7.2.5"
},
"type": "library",
"autoload": {
@ -341,11 +391,8 @@
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v4.4.18"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -360,20 +407,255 @@
"type": "tidelift"
}
],
"time": "2020-12-08T16:59:59+00:00"
"time": "2021-01-28T22:06:19+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.20.0",
"name": "symfony/polyfill-ctype",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531"
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af",
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Grapheme\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's grapheme_* functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"grapheme",
"intl",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "6e971c891537eb617a00bb07a43d182a6915faba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba",
"reference": "6e971c891537eb617a00bb07a43d182a6915faba",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-07T17:09:11+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"shasum": ""
},
"require": {
@ -385,7 +667,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -423,9 +705,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -440,20 +719,20 @@
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-php73",
"version": "v1.20.0",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed"
"reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed",
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
"reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
"shasum": ""
},
"require": {
@ -462,7 +741,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -502,9 +781,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -519,20 +795,20 @@
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.20.0",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de"
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
"shasum": ""
},
"require": {
@ -541,7 +817,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -585,9 +861,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -602,24 +875,24 @@
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v1.1.9",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "b776d18b303a39f56c63747bcb977ad4b27aca26"
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26",
"reference": "b776d18b303a39f56c63747bcb977ad4b27aca26",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"php": ">=7.2.5",
"psr/container": "^1.0"
},
"suggest": {
@ -628,7 +901,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -664,9 +937,6 @@
"interoperability",
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v1.1.9"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -681,7 +951,87 @@
"type": "tidelift"
}
],
"time": "2020-07-06T13:19:58+00:00"
"time": "2020-09-07T11:33:47+00:00"
},
{
"name": "symfony/string",
"version": "v5.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "c95468897f408dd0aca2ff582074423dd0455122"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122",
"reference": "c95468897f408dd0aca2ff582074423dd0455122",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "~1.15"
},
"require-dev": {
"symfony/error-handler": "^4.4|^5.0",
"symfony/http-client": "^4.4|^5.0",
"symfony/translation-contracts": "^1.1|^2",
"symfony/var-exporter": "^4.4|^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\String\\": ""
},
"files": [
"Resources/functions.php"
],
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
"homepage": "https://symfony.com",
"keywords": [
"grapheme",
"i18n",
"string",
"unicode",
"utf-8",
"utf8"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-25T15:14:59+00:00"
}
],
"aliases": [],
@ -694,7 +1044,7 @@
"platform": [],
"platform-dev": [],
"platform-overrides": {
"php": "7.2"
"php": "7.3"
},
"plugin-api-version": "2.0.0"
"plugin-api-version": "1.1.0"
}

View File

@ -282,11 +282,6 @@
"phpcs",
"standards"
],
"support": {
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
},
"time": "2020-10-23T02:01:07+00:00"
},
{

View File

@ -1614,12 +1614,12 @@
"version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
"shasum": ""
},

View File

@ -382,6 +382,10 @@
],
"description": "Provides internationalization tools for WordPress projects.",
"homepage": "https://github.com/wp-cli/i18n-command",
"support": {
"issues": "https://github.com/wp-cli/i18n-command/issues",
"source": "https://github.com/wp-cli/i18n-command/tree/v2.2.6"
},
"time": "2020-12-07T19:28:27+00:00"
},
{

View File

@ -25,17 +25,19 @@ output 3 "Updating autoloader classmaps..."
composer dump-autoload
output 2 "Done"
# Convert textdomains
output 3 "Updating package PHP textdomains..."
if [ -z "$SKIP_UPDATE_TEXTDOMAINS" ]; then
# Convert textdomains
output 3 "Updating package PHP textdomains..."
# Replace text domains within packages with woocommerce
npm run packages:fix:textdomain
output 2 "Done!"
# Replace text domains within packages with woocommerce
npm run packages:fix:textdomain
output 2 "Done!"
output 3 "Updating package JS textdomains..."
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-admin -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
output 3 "Updating package JS textdomains..."
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-admin -iname '*.js' -exec sed -i.bak -e "s/'woocommerce-admin'/'woocommerce'/g" -e "s/\"woocommerce-admin\"/'woocommerce'/g" {} \;
fi
# Cleanup backup files
find ./packages -name "*.bak" -type f -delete

View File

@ -9,5 +9,5 @@ runOnChange() {
fi
}
runOnChange "package-lock.json" "npm install"
runOnChange "composer.lock" "composer install"
runOnChange "package-lock.json" "npm run install:no-e2e"
runOnChange "composer.lock" "SKIP_UPDATE_TEXTDOMAINS=true composer install"

View File

@ -14,14 +14,14 @@
],
"require": {
"php": ">=7.0",
"automattic/jetpack-autoloader": "2.7.1",
"automattic/jetpack-autoloader": "2.9.1",
"automattic/jetpack-constants": "1.5.1",
"composer/installers": "~1.7",
"maxmind-db/reader": "1.6.0",
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.1.6",
"woocommerce/woocommerce-admin": "1.9.0-rc.3",
"woocommerce/woocommerce-admin": "1.9.0",
"woocommerce/woocommerce-blocks": "4.0.0"
},
"require-dev": {

45
composer.lock generated
View File

@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5fac5fbdbcff552de109cd95d469e975",
"content-hash": "c5ebe496c9f97d9748856d33070681e0",
"packages": [
{
"name": "automattic/jetpack-autoloader",
"version": "v2.7.1",
"version": "v2.9.1",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-autoloader.git",
"reference": "5437697a56aefbdf707849b9833e1b36093d7a73"
"reference": "d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/5437697a56aefbdf707849b9833e1b36093d7a73",
"reference": "5437697a56aefbdf707849b9833e1b36093d7a73",
"url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88",
"reference": "d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88",
"shasum": ""
},
"require": {
@ -28,7 +28,8 @@
},
"type": "composer-plugin",
"extra": {
"class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin"
"class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin",
"mirror-repo": "Automattic/jetpack-autoloader"
},
"autoload": {
"classmap": [
@ -44,9 +45,9 @@
],
"description": "Creates a custom autoloader for a plugin or theme.",
"support": {
"source": "https://github.com/Automattic/jetpack-autoloader/tree/v2.7.1"
"source": "https://github.com/Automattic/jetpack-autoloader/tree/v2.9.1"
},
"time": "2020-12-18T22:33:59+00:00"
"time": "2021-02-05T19:07:06+00:00"
},
{
"name": "automattic/jetpack-constants",
@ -281,6 +282,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"
},
{
@ -355,6 +360,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"
},
{
@ -404,6 +413,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"
},
{
@ -495,20 +508,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/master"
},
"time": "2020-05-12T16:22:33+00:00"
},
{
"name": "woocommerce/woocommerce-admin",
"version": "1.9.0-rc.3",
"version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "8c5b20cb6347959daf5403ee30e47061f335240b"
"reference": "cb2fa7ad034200acba6ee3ef0f332453d2533144"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/8c5b20cb6347959daf5403ee30e47061f335240b",
"reference": "8c5b20cb6347959daf5403ee30e47061f335240b",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/cb2fa7ad034200acba6ee3ef0f332453d2533144",
"reference": "cb2fa7ad034200acba6ee3ef0f332453d2533144",
"shasum": ""
},
"require": {
@ -540,7 +557,7 @@
],
"description": "A modern, javascript-driven WooCommerce Admin experience.",
"homepage": "https://github.com/woocommerce/woocommerce-admin",
"time": "2021-01-22T10:23:29+00:00"
"time": "2021-01-28T00:59:01+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
@ -654,5 +671,5 @@
"platform-overrides": {
"php": "7.0"
},
"plugin-api-version": "1.1.0"
"plugin-api-version": "2.0.0"
}

View File

@ -1270,6 +1270,8 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
*/
protected function set_item_discount_amounts( $discounts ) {
$item_discounts = $discounts->get_discounts_by_item();
$tax_location = $this->get_tax_location();
$tax_location = array( $tax_location['country'], $tax_location['state'], $tax_location['postcode'], $tax_location['city'] );
if ( $item_discounts ) {
foreach ( $item_discounts as $item_id => $amount ) {
@ -1277,7 +1279,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
// If the prices include tax, discounts should be taken off the tax inclusive prices like in the cart.
if ( $this->get_prices_include_tax() && wc_tax_enabled() && 'taxable' === $item->get_tax_status() ) {
$taxes = WC_Tax::calc_tax( $amount, WC_Tax::get_rates( $item->get_tax_class() ), true );
$taxes = WC_Tax::calc_tax( $amount, $this->get_tax_rates( $item->get_tax_class(), $tax_location ), true );
// Use unrounded taxes so totals will be re-calculated accurately, like in cart.
$amount = $amount - array_sum( $taxes );
@ -1299,6 +1301,13 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$coupon_code_to_id = wc_list_pluck( $coupons, 'get_id', 'get_code' );
$all_discounts = $discounts->get_discounts();
$coupon_discounts = $discounts->get_discounts_by_coupon();
$tax_location = $this->get_tax_location();
$tax_location = array(
$tax_location['country'],
$tax_location['state'],
$tax_location['postcode'],
$tax_location['city'],
);
if ( $coupon_discounts ) {
foreach ( $coupon_discounts as $coupon_code => $amount ) {
@ -1321,7 +1330,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
continue;
}
$taxes = array_sum( WC_Tax::calc_tax( $item_discount_amount, WC_Tax::get_rates( $item->get_tax_class() ), $this->get_prices_include_tax() ) );
$taxes = array_sum( WC_Tax::calc_tax( $item_discount_amount, $this->get_tax_rates( $item->get_tax_class(), $tax_location ), $this->get_prices_include_tax() ) );
if ( 'yes' !== get_option( 'woocommerce_tax_round_at_subtotal' ) ) {
$taxes = wc_round_tax_total( $taxes );
}
@ -1514,6 +1523,21 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
return apply_filters( 'woocommerce_order_get_tax_location', $args, $this );
}
/**
* Get tax rates for an order. Use order's shipping or billing address, defaults to base location.
*
* @param string $tax_class Tax class to get rates for.
* @param array $location_args Location to compute rates for. Should be in form: array( country, state, postcode, city).
* @param object $customer Only used to maintain backward compatibility for filter `woocommerce-matched_rates`.
*
* @return mixed|void Tax rates.
*/
protected function get_tax_rates( $tax_class, $location_args = array(), $customer = null ) {
$tax_location = $this->get_tax_location( $location_args );
$tax_location = array( $tax_location['country'], $tax_location['state'], $tax_location['postcode'], $tax_location['city'] );
return WC_Tax::get_rates_from_location( $tax_class, $tax_location, $customer );
}
/**
* Calculate taxes for all line items and shipping, and store the totals and tax rows.
*
@ -1610,6 +1634,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
}
$saved_rate_ids[] = $tax->get_rate_id();
$tax->set_tax_total( isset( $cart_taxes[ $tax->get_rate_id() ] ) ? $cart_taxes[ $tax->get_rate_id() ] : 0 );
$tax->set_label( WC_Tax::get_rate_label( $tax->get_rate_id() ) );
$tax->set_shipping_tax_total( ! empty( $shipping_taxes[ $tax->get_rate_id() ] ) ? $shipping_taxes[ $tax->get_rate_id() ] : 0 );
$tax->save();
}

View File

@ -64,6 +64,10 @@ class WC_Settings_Products extends WC_Settings_Page {
$settings = $this->get_settings( $current_section );
WC_Admin_Settings::save_fields( $settings );
// Any time we update the product settings, we should flush the term count cache.
$tools_controller = new WC_REST_System_Status_Tools_Controller();
$tools_controller->execute_tool( 'recount_terms' );
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
}

View File

@ -525,7 +525,8 @@ class WC_Install {
$held_duration = get_option( 'woocommerce_hold_stock_minutes', '60' );
if ( '' !== $held_duration ) {
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );
wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
// Delay the first run of `woocommerce_cleanup_personal_data` by 10 seconds

View File

@ -622,9 +622,9 @@ class WC_Query {
$args['join'] = $this->append_product_sorting_table_join( $args['join'] );
$args['where'] .= $wpdb->prepare(
' AND wc_product_meta_lookup.min_price >= %f AND wc_product_meta_lookup.max_price <= %f ',
$current_min_price,
$current_max_price
' AND NOT (%f<wc_product_meta_lookup.min_price OR %f>wc_product_meta_lookup.max_price ) ',
$current_max_price,
$current_min_price
);
return $args;
}

View File

@ -405,7 +405,7 @@ class WC_Tax {
$criteria_string = implode( ' AND ', $criteria );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$found_rates = $wpdb->get_results(
"
SELECT tax_rates.*, COUNT( locations.location_id ) as postcode_count, COUNT( locations2.location_id ) as city_count
@ -479,8 +479,22 @@ class WC_Tax {
* @return array
*/
public static function get_rates( $tax_class = '', $customer = null ) {
$tax_class = sanitize_title( $tax_class );
$location = self::get_tax_location( $tax_class, $customer );
return self::get_rates_from_location( $tax_class, $location, $customer );
}
/**
* Get's an arrau of matching rates from location and tax class. $customer parameter is used to preserve backward compatibility for filter.
*
* @param string $tax_class Tax class to get rates for.
* @param array $location Location to compute rates for. Should be in form: array( country, state, postcode, city).
* @param object $customer Only used to maintain backward compatibility for filter `woocommerce-matched_rates`.
*
* @return mixed|void Tax rates.
*/
public static function get_rates_from_location( $tax_class, $location, $customer = null ) {
$tax_class = sanitize_title( $tax_class );
$location = self::get_tax_location( $tax_class, $customer );
$matched_tax_rates = array();
if ( count( $location ) === 4 ) {

View File

@ -364,9 +364,11 @@ class WC_Tracker {
);
$first = time();
$processing_first = $first;
$first_time = $first;
$last = 0;
$processing_first = time();
$processing_last = 0;
$order_data = array();
$orders = wc_get_orders( $args );
$orders_count = count( $orders );
@ -445,10 +447,25 @@ class WC_Tracker {
$orders_count = count( $orders );
}
$order_data['first'] = gmdate( 'Y-m-d H:i:s', $first );
$order_data['last'] = gmdate( 'Y-m-d H:i:s', $last );
$order_data['processing_first'] = gmdate( 'Y-m-d H:i:s', $processing_first );
$order_data['processing_last'] = gmdate( 'Y-m-d H:i:s', $processing_last );
if ( $first !== $first_time ) {
$order_data['first'] = gmdate( 'Y-m-d H:i:s', $first );
}
if ( $processing_first !== $first_time ) {
$order_data['processing_first'] = gmdate( 'Y-m-d H:i:s', $processing_first );
}
if ( $last ) {
$order_data['last'] = gmdate( 'Y-m-d H:i:s', $last );
}
if ( $processing_last ) {
$order_data['processing_last'] = gmdate( 'Y-m-d H:i:s', $processing_last );
}
foreach ( $order_data as $key => $value ) {
$order_data[ $key ] = (string) $value;
}
return $order_data;
}

View File

@ -818,7 +818,7 @@ class WC_Shop_Customizer {
'description' => __( 'Optionally add some text about your store privacy policy to show during checkout.', 'woocommerce' ),
'section' => 'woocommerce_checkout',
'settings' => 'woocommerce_checkout_privacy_policy_text',
'active_callback' => 'wc_privacy_policy_page_id',
'active_callback' => array( $this, 'has_privacy_policy_page_id' ),
'type' => 'textarea',
)
);
@ -830,7 +830,7 @@ class WC_Shop_Customizer {
'description' => __( 'Optionally add some text for the terms checkbox that customers must accept.', 'woocommerce' ),
'section' => 'woocommerce_checkout',
'settings' => 'woocommerce_checkout_terms_and_conditions_checkbox_text',
'active_callback' => 'wc_terms_and_conditions_page_id',
'active_callback' => array( $this, 'has_terms_and_conditions_page_id' ),
'type' => 'text',
)
);
@ -865,6 +865,24 @@ class WC_Shop_Customizer {
$options = array( 'hidden', 'optional', 'required' );
return in_array( $value, $options, true ) ? $value : '';
}
/**
* Whether or not a page has been chose for the privacy policy.
*
* @return bool
*/
public function has_privacy_policy_page_id() {
return wc_privacy_policy_page_id() > 0;
}
/**
* Whether or not a page has been chose for the terms and conditions.
*
* @return bool
*/
public function has_terms_and_conditions_page_id() {
return wc_terms_and_conditions_page_id() > 0;
}
}
new WC_Shop_Customizer();

View File

@ -272,6 +272,9 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
$product->apply_changes();
// Any time we update the product, we should flush the term count cache.
$tools_controller = new WC_REST_System_Status_Tools_Controller();
$tools_controller->execute_tool( 'recount_terms' );
do_action( 'woocommerce_update_product', $product->get_id(), $product );
}

View File

@ -1162,7 +1162,8 @@ function wc_format_option_hold_stock_minutes( $value, $option, $raw_value ) {
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
if ( '' !== $value ) {
wp_schedule_single_event( time() + ( absint( $value ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $value ) );
wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
return $value;

View File

@ -925,7 +925,8 @@ function wc_cancel_unpaid_orders() {
}
}
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );
wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
add_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );

View File

@ -352,7 +352,7 @@ function wc_no_js() {
var c = document.body.className;
c = c.replace(/woocommerce-no-js/, 'woocommerce-js');
document.body.className = c;
})()
})();
</script>
<?php
}
@ -3564,20 +3564,38 @@ function wc_empty_cart_message() {
/**
* Disable search engines indexing core, dynamic, cart/checkout pages.
*
* @todo Deprecated this function after dropping support for WP 5.6.
* @since 3.2.0
*/
function wc_page_noindex() {
// wp_no_robots is deprecated since WP 5.7.
if ( function_exists( 'wp_robots_no_robots' ) ) {
return;
}
if ( is_page( wc_get_page_id( 'cart' ) ) || is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'myaccount' ) ) ) {
// Adds support for WP 5.7.
if ( function_exists( 'wp_robots_no_robots' ) ) {
wp_robots_no_robots();
} else {
wp_no_robots();
}
wp_no_robots();
}
}
add_action( 'wp_head', 'wc_page_noindex' );
/**
* Disable search engines indexing core, dynamic, cart/checkout pages.
* Uses "wp_robots" filter introduced in WP 5.7.
*
* @since 5.0.0
* @param array $robots Associative array of robots directives.
* @return array Filtered robots directives.
*/
function wc_page_no_robots( $robots ) {
if ( is_page( wc_get_page_id( 'cart' ) ) || is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'myaccount' ) ) ) {
return wp_robots_no_robots( $robots );
}
return $robots;
}
add_filter( 'wp_robots', 'wc_page_no_robots' );
/**
* Get a slug identifying the current theme.
*

104
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "woocommerce",
"version": "4.9.0",
"version": "5.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -20615,10 +20615,11 @@
"version": "file:tests/e2e/utils",
"dev": true,
"requires": {
"@wordpress/deprecated": "^2.10.0",
"@wordpress/e2e-test-utils": "^4.6.0",
"config": "3.3.3",
"faker": "^5.1.0",
"fishery": "^1.0.1"
"fishery": "^1.2.0"
},
"dependencies": {
"@babel/runtime": {
@ -20742,15 +20743,6 @@
"integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw==",
"dev": true
},
"fishery": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fishery/-/fishery-1.0.1.tgz",
"integrity": "sha512-VV8H4ZuCbZ9cCWkrYWLLPoAfpTp0t+hlJVoNWkRRHdXOgQ08wjd8ab9di8/Ed/QhgwxY3h7Y17HgDZ9osaHSSQ==",
"dev": true,
"requires": {
"lodash.mergewith": "^4.6.2"
}
},
"gettext-parser": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz",
@ -20788,12 +20780,6 @@
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true
},
"memize": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz",
@ -20915,6 +20901,27 @@
"integrity": "sha512-pB45JlfmHuEigNFZ1X+CTgIsOT3/TTb9iZxw1DHXge/7ytY8FNhtcNwTfF9IgnS6/xaFRZBqzw4DyH4sP1Lyxg==",
"dev": true
},
"@wordpress/deprecated": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.11.1.tgz",
"integrity": "sha512-ri5M3TSAhonRN9G67KDwu8AXthrxay/1lLwBVbRA+6Dpj6hpC4qUBxOP4Yx5VLYOJEJW2YJx3w3G3XFYiyqfFg==",
"dev": true,
"requires": {
"@babel/runtime": "^7.12.5",
"@wordpress/hooks": "^2.11.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.12.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@wordpress/e2e-test-utils": {
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-4.15.0.tgz",
@ -20973,6 +20980,26 @@
}
}
},
"@wordpress/hooks": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.11.1.tgz",
"integrity": "sha512-20nsvmLH5/iw9P6M7kiEBBQ7X7G3pEbqED/aN5dqkMCklDyar+OZqYBzdpGGsthXVYgomfNy6QQZWELkGJbcbw==",
"dev": true,
"requires": {
"@babel/runtime": "^7.12.5"
},
"dependencies": {
"@babel/runtime": {
"version": "7.12.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@wordpress/i18n": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.16.0.tgz",
@ -21083,7 +21110,7 @@
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"acorn": {
@ -21280,7 +21307,7 @@
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
"dev": true
},
"are-we-there-yet": {
@ -21329,7 +21356,7 @@
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
"arr-union": {
@ -22053,7 +22080,7 @@
"babylon": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
"integrity": "sha1-ry87iPpvXB5MY00aD46sT1WzleM=",
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
"dev": true
},
"bail": {
@ -24022,7 +24049,7 @@
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
@ -24823,7 +24850,7 @@
},
"es6-promisify": {
"version": "5.0.0",
"resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
@ -25840,6 +25867,15 @@
"parse-filepath": "^1.0.1"
}
},
"fishery": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fishery/-/fishery-1.2.0.tgz",
"integrity": "sha512-0GG029KHF3p8Q0NiAl/ZOK1fvyAprOiHdtRWUNS46x9QXuQhMwzcGLNDbZ7XIEEBowwBmMsw7StkaU0ek9dSbg==",
"dev": true,
"requires": {
"lodash.mergewith": "^4.6.2"
}
},
"flagged-respawn": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
@ -25964,7 +26000,7 @@
"fs-readdir-recursive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
"integrity": "sha1-4y/AMKLM7kSmtTcTCNpUvgs5fSc=",
"integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
"dev": true
},
"fs-write-stream-atomic": {
@ -27375,7 +27411,7 @@
"grunt-postcss": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/grunt-postcss/-/grunt-postcss-0.9.0.tgz",
"integrity": "sha1-++WTSmvp6siTr20FfiMYyX+unaM=",
"integrity": "sha512-lglLcVaoOIqH0sFv7RqwUKkEFGQwnlqyAKbatxZderwZGV1nDyKHN7gZS9LUiTx1t5GOvRBx0BEalHMyVwFAIA==",
"dev": true,
"requires": {
"chalk": "^2.1.0",
@ -28738,7 +28774,7 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-callable": {
@ -28905,7 +28941,7 @@
},
"is-obj": {
"version": "1.0.1",
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
@ -31452,6 +31488,12 @@
"integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=",
"dev": true
},
"lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true
},
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
@ -31966,7 +32008,7 @@
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
@ -33134,7 +33176,7 @@
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"dev": true,
"requires": {
"are-we-there-yet": "~1.1.2",
@ -35071,7 +35113,7 @@
},
"safe-regex": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
@ -36855,7 +36897,7 @@
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": {
"os-tmpdir": "~1.0.2"

View File

@ -13,13 +13,16 @@
"wp_org_slug": "woocommerce"
},
"scripts": {
"install": "lerna bootstrap --hoist",
"install": " if [ -z \"$SKIP_LERNA_BOOTSTRAP\" ]; then npx lerna bootstrap --hoist; fi",
"check:subset-installed": "npm list --depth 1 install-subset > /dev/null 2>&1",
"install:subset-only": "npm install --no-package-lock --no-save install-subset",
"install:no-e2e": "npm run check:subset-installed --silent || npm run install:subset-only && SKIP_LERNA_BOOTSTRAP=true npx install-subset i no-e2e",
"build": "./bin/build-zip.sh",
"build:core": "grunt && npm run makepot",
"build:dev": "npm run build:core && npm run build:packages",
"build-watch": "grunt watch",
"build:packages": "lerna run build",
"build:zip": "npm run build && composer install && npm run build:dev",
"build:zip": "npm run build",
"build:assets": "grunt assets",
"lint:js": "eslint assets/js --ext=js",
"docker:down": "npx wc-e2e docker:down",
@ -125,5 +128,16 @@
"> 0.1%",
"ie 8",
"ie 9"
]
],
"subsets": {
"no-e2e": {
"exclude": [
"@woocommerce/api",
"@woocommerce/e2e-core-tests",
"@woocommerce/e2e-environment",
"@woocommerce/e2e-utils",
"@wordpress/e2e-test-utils"
]
}
}
}

View File

@ -1,7 +1,7 @@
=== WooCommerce ===
Contributors: automattic, mikejolley, jameskoster, claudiosanches, rodrigosprimo, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, wpmuguru, royho
Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, downloads, payments, paypal, storefront, stripe, woo commerce
Requires at least: 5.3
Requires at least: 5.4
Tested up to: 5.6
Requires PHP: 7.0
Stable tag: 4.9.2

View File

@ -83,6 +83,9 @@ class DownloadPermissionsAdjuster {
*/
public function adjust_download_permissions( int $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product ) {
return;
}
$children_ids = $product->get_children();
if ( ! $children_ids ) {

View File

@ -1,4 +1,4 @@
import { Model } from '../models/model';
import { Model } from '../models';
/**
* A dummy model that can be used in test files.

View File

@ -1,4 +1,4 @@
import { Model } from '../../models/model';
import { Model } from '../../models';
import {
CreatesModels,
DeletesChildModels,

View File

@ -0,0 +1,3 @@
export * from './transformations';
export * from './model-repository';
export * from './model-transformer';

View File

@ -1,4 +1,4 @@
import { Model, ModelID } from '../models/model';
import { Model, ModelID } from '../models';
/**
* An interface for describing the shape of parent identifiers for repositories.
@ -6,7 +6,7 @@ import { Model, ModelID } from '../models/model';
* @typedef ModelParentID
* @alias Object.<string,ModelID>
*/
interface ModelParentID {
export interface ModelParentID {
[ key: number ]: ModelID
}

View File

@ -1,5 +1,4 @@
import { Model } from '../models/model';
import { ModelConstructor } from '../models/shared-types';
import { Model, ModelConstructor } from '../models';
/**
* An interface for an object that can perform transformations both to and from a representation

View File

@ -0,0 +1,6 @@
export * from './add-property-transformation';
export * from './custom-transformation';
export * from './ignore-property-transformation';
export * from './key-change-transformation';
export * from './model-transformer-transformation';
export * from './property-type-transformation';

View File

@ -1,5 +1,5 @@
import { ModelTransformation, TransformationOrder } from '../model-transformer';
import { Model } from '../../models/model';
import { Model } from '../../models';
/**
* @typedef KeyChanges

View File

@ -1,6 +1,5 @@
import { ModelTransformation, ModelTransformer, TransformationOrder } from '../model-transformer';
import { Model } from '../../models/model';
import { ModelConstructor } from '../../models/shared-types';
import { Model, ModelConstructor } from '../../models';
/**
* A model transformation that applies another transformer to a property.

View File

@ -1,4 +1,4 @@
export { SimpleProduct } from './products/simple-product';
export { SettingGroup } from './settings/setting-group';
export { Setting } from './settings/setting';
export * from './products';
export * from './model';
export * from './settings';
export * from './shared-types';

View File

@ -0,0 +1,3 @@
export * from './abstract-product';
export * from './shared-types';
export * from './simple-product';

View File

@ -1,13 +1,14 @@
import { AbstractProduct, ProductSearchParams, ProductUpdateParams } from './abstract-product';
import { HTTPClient } from '../../http';
import { simpleProductRESTRepository } from '../../repositories/rest/products/simple-product';
import { simpleProductRESTRepository } from '../../repositories';
import {
CreatesModels,
DeletesModels, ListsModels,
DeletesModels,
ListsModels,
ModelRepositoryParams,
ReadsModels,
UpdatesModels,
} from '../../framework/model-repository';
} from '../../framework';
/**
* The parameters embedded in this generic can be used in the ModelRepository in order to give

View File

@ -0,0 +1,2 @@
export * from './setting-group';
export * from './setting';

View File

@ -1,7 +1,7 @@
import { Model, ModelID } from '../model';
import { HTTPClient } from '../../http';
import { settingGroupRESTRepository } from '../../repositories/rest/settings/setting-group';
import { ListsModels, ModelRepositoryParams } from '../../framework/model-repository';
import { settingGroupRESTRepository } from '../../repositories';
import { ListsModels, ModelRepositoryParams } from '../../framework';
/**
* The parameters embedded in this generic can be used in the ModelRepository in order to give

View File

@ -1,12 +1,12 @@
import { Model, ModelID } from '../model';
import { HTTPClient } from '../../http';
import { settingRESTRepository } from '../../repositories/rest/settings/setting';
import { settingRESTRepository } from '../../repositories';
import {
ModelRepositoryParams,
ListsChildModels,
ReadsChildModels,
UpdatesChildModels,
} from '../../framework/model-repository';
} from '../../framework';
/**
* The parameters embedded in this generic can be used in the ModelRepository in order to give

View File

@ -0,0 +1 @@
export * from './rest';

View File

@ -1,6 +1,6 @@
import { mock, MockProxy } from 'jest-mock-extended';
import { HTTPClient, HTTPResponse } from '../../../http';
import { ModelTransformer } from '../../../framework/model-transformer';
import { ModelTransformer, ModelRepositoryParams } from '../../../framework';
import { DummyModel } from '../../../__test_data__/dummy-model';
import {
restCreate,
@ -12,8 +12,7 @@ import {
restUpdate,
restUpdateChild,
} from '../shared';
import { ModelRepositoryParams } from '../../../framework/model-repository';
import { Model } from '../../../models/model';
import { Model } from '../../../models';
type DummyModelParams = ModelRepositoryParams< DummyModel, never, { search: string }, 'name' >

View File

@ -0,0 +1,2 @@
export * from './products';
export * from './settings';

View File

@ -0,0 +1,7 @@
import { createProductTransformer } from './shared';
import { simpleProductRESTRepository } from './simple-product';
export {
createProductTransformer,
simpleProductRESTRepository,
};

View File

@ -1,16 +1,23 @@
import { ModelTransformation, ModelTransformer, TransformationOrder } from '../../../framework/model-transformer';
import { KeyChangeTransformation } from '../../../framework/transformations/key-change-transformation';
import { AbstractProduct } from '../../../models/products/abstract-product';
import { AddPropertyTransformation } from '../../../framework/transformations/add-property-transformation';
import { IgnorePropertyTransformation } from '../../../framework/transformations/ignore-property-transformation';
import {
ModelTransformation,
ModelTransformer,
TransformationOrder,
KeyChangeTransformation,
AddPropertyTransformation,
IgnorePropertyTransformation,
PropertyType,
PropertyTypeTransformation,
} from '../../../framework/transformations/property-type-transformation';
import { CustomTransformation } from '../../../framework/transformations/custom-transformation';
import { ProductAttribute, ProductDownload, ProductImage, ProductTerm } from '../../../models/products/shared-types';
import { ModelTransformerTransformation } from '../../../framework/transformations/model-transformer-transformation';
import { MetaData } from '../../../models/shared-types';
CustomTransformation,
ModelTransformerTransformation,
} from '../../../framework';
import {
AbstractProduct,
ProductAttribute,
ProductDownload,
ProductImage,
ProductTerm,
MetaData,
} from '../../../models';
import { createMetaDataTransformer } from '../shared';
/**

View File

@ -1,17 +1,23 @@
import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework/model-repository';
import { SimpleProduct } from '../../../models';
import { ModelRepository } from '../../../framework';
import {
SimpleProduct,
ModelID,
CreatesSimpleProducts,
DeletesSimpleProducts,
ListsSimpleProducts,
ReadsSimpleProducts,
SimpleProductRepositoryParams,
UpdatesSimpleProducts,
} from '../../../models/products/simple-product';
} from '../../../models';
import { createProductTransformer } from './shared';
import { restCreate, restDelete, restList, restRead, restUpdate } from '../shared';
import { ModelID } from '../../../models/model';
import {
restCreate,
restDelete,
restList,
restRead,
restUpdate,
} from '../shared';
/**
* Creates a new ModelRepository instance for interacting with models via the REST API.

View File

@ -0,0 +1,7 @@
import settingRESTRepository from './setting';
import settingGroupRESTRepository from './setting-group';
export {
settingRESTRepository,
settingGroupRESTRepository,
};

View File

@ -1,9 +1,14 @@
import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework/model-repository';
import { SettingGroup } from '../../../models';
import { ListsSettingGroups, SettingGroupRepositoryParams } from '../../../models/settings/setting-group';
import { ModelTransformer } from '../../../framework/model-transformer';
import { KeyChangeTransformation } from '../../../framework/transformations/key-change-transformation';
import {
ModelRepository,
ModelTransformer,
KeyChangeTransformation,
} from '../../../framework';
import {
SettingGroup,
ListsSettingGroups,
SettingGroupRepositoryParams,
} from '../../../models';
import { restList } from '../shared';
function createTransformer(): ModelTransformer< SettingGroup > {
@ -20,7 +25,7 @@ function createTransformer(): ModelTransformer< SettingGroup > {
* @param {HTTPClient} httpClient The HTTP client for the REST requests to be made using.
* @return {ListsSettingGroups} The created repository.
*/
export function settingGroupRESTRepository( httpClient: HTTPClient ): ListsSettingGroups {
export default function settingGroupRESTRepository( httpClient: HTTPClient ): ListsSettingGroups {
const transformer = createTransformer();
return new ModelRepository(

View File

@ -1,15 +1,18 @@
import { HTTPClient } from '../../../http';
import { ModelRepository, ParentID } from '../../../framework/model-repository';
import { Setting } from '../../../models';
import {
ModelRepository,
ParentID,
ModelTransformer,
} from '../../../framework';
import {
ModelID,
Setting,
ListsSettings,
ReadsSettings,
SettingRepositoryParams,
UpdatesSettings,
} from '../../../models/settings/setting';
import { ModelTransformer } from '../../../framework/model-transformer';
} from '../../../models';
import { restListChild, restReadChild, restUpdateChild } from '../shared';
import { ModelID } from '../../../models/model';
function createTransformer(): ModelTransformer< Setting > {
return new ModelTransformer( [] );
@ -21,7 +24,7 @@ function createTransformer(): ModelTransformer< Setting > {
* @param {HTTPClient} httpClient The HTTP client for the REST requests to be made using.
* @return {ListsSettings|ReadsSettings|UpdatesSettings} The created repository.
*/
export function settingRESTRepository( httpClient: HTTPClient ): ListsSettings & ReadsSettings & UpdatesSettings {
export default function settingRESTRepository( httpClient: HTTPClient ): ListsSettings & ReadsSettings & UpdatesSettings {
const buildURL = ( parent: ParentID< SettingRepositoryParams >, id: ModelID ) => '/wc/v3/settings/' + parent + '/' + id;
const transformer = createTransformer();

View File

@ -1,6 +1,3 @@
import { ModelTransformer } from '../../framework/model-transformer';
import { MetaData, ModelConstructor } from '../../models/shared-types';
import { IgnorePropertyTransformation } from '../../framework/transformations/ignore-property-transformation';
import { HTTPClient } from '../../http';
import {
ListFn,
@ -16,8 +13,16 @@ import {
UpdateChildFn,
DeleteChildFn,
CreateFn,
} from '../../framework/model-repository';
import { ModelID } from '../../models/model';
ModelTransformer,
IgnorePropertyTransformation,
// @ts-ignore
ModelParentID,
} from '../../framework';
import {
ModelID,
MetaData,
ModelConstructor,
} from '../../models';
/**
* Creates a new transformer for metadata models.

View File

@ -1,5 +1,5 @@
import { mock, MockProxy } from 'jest-mock-extended';
import { UpdatesSettings } from '../../models/settings/setting';
import { UpdatesSettings } from '../../models';
import { SettingService } from '../setting-service';
describe( 'SettingService', () => {

View File

@ -1,4 +1,4 @@
import { Setting, UpdatesSettings } from '../models/settings/setting';
import { Setting, UpdatesSettings } from '../models';
/**
* A service that wraps setting changes in convenient methods.

View File

@ -11,6 +11,7 @@
- Added new config variable for Simple Product price to `tests/e2e/env/config/default.json`. Defaults to 9.99
- Merchant Product Edit tests
- Merchant Product Search tests
- Shopper Single Product tests
- Shopper Checkout Apply Coupon

View File

@ -64,7 +64,7 @@ The functions to access the core tests are:
- `runCartPageTest` - Shopper can view and update cart
- `runCheckoutPageTest` - Shopper can complete checkout
- `runMyAccountPageTest` - Shopper can access my account page
- `runSingleProductPageTest` - Shopper can view single product page
- `runSingleProductPageTest` - Shopper can view single product page in many variations (simple, variable, grouped)
## Contributing a new test

View File

@ -7,7 +7,8 @@ const {
merchant,
createCoupon,
createSimpleProduct,
uiUnblocked
uiUnblocked,
clearAndFillInput,
} = require( '@woocommerce/e2e-utils' );
/**
@ -19,11 +20,36 @@ const {
beforeAll,
} = require( '@jest/globals' );
/**
* Apply a coupon code to the cart.
*
* @param couponCode string
* @returns {Promise<void>}
*/
const applyCouponToCart = async ( couponCode ) => {
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await clearAndFillInput('#coupon_code', couponCode);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
};
/**
* Remove one coupon from the cart.
*
* @returns {Promise<void>}
*/
const removeCouponFromCart = async () => {
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon has been removed.'});
}
const runCheckoutApplyCouponsTest = () => {
describe('Checkout applying coupons', () => {
let couponFixedCart;
let couponPercentage;
let couponFixedProduct;
describe('Checkout coupons', () => {
let couponFixedCart;
let couponPercentage;
let couponFixedProduct;
beforeAll(async () => {
await merchant.login();
await createSimpleProduct();
@ -31,86 +57,63 @@ const runCheckoutApplyCouponsTest = () => {
couponPercentage = await createCoupon('50', 'Percentage discount');
couponFixedProduct = await createCoupon('5', 'Fixed product discount');
await merchant.logout();
});
it('allows customer to apply coupons in the checkout', async () => {
await shopper.goToShop();
await shopper.addToCartFromShopPage('Simple product');
await uiUnblocked();
await shopper.goToCheckout();
});
// Apply Fixed cart discount coupon
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await expect(page).toFill('#coupon_code', couponFixedCart);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'});
it('allows customer to apply fixed cart coupon', async () => {
await applyCouponToCart( couponFixedCart );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
// Wait for page to expand total calculations to avoid flakyness
await page.waitForSelector('.order-total');
// Verify discount applied and order total
await page.waitForSelector('.cart-discount .amount', {text: '$5.00'});
await page.waitForSelector('.order-total .amount', {text: '$4.99'});
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
await removeCouponFromCart();
});
// Remove coupon
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
it('allows customer to apply percentage coupon', async () => {
await applyCouponToCart( couponPercentage );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
// Apply Percentage discount coupon
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await expect(page).toFill('#coupon_code', couponPercentage);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.cart-discount .amount', {text: '$4.99'});
await page.waitForSelector('.order-total .amount', {text: '$5.00'});
// Verify discount applied and order total
await expect(page).toMatchElement('.cart-discount .amount', {text: '$4.99'});
await expect(page).toMatchElement('.order-total .amount', {text: '$5.00'});
await removeCouponFromCart();
});
// Remove coupon
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
it('allows customer to apply fixed product coupon', async () => {
await applyCouponToCart( couponFixedProduct );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
await removeCouponFromCart();
});
// Apply Fixed product discount coupon
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await expect(page).toFill('#coupon_code', couponFixedProduct);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.cart-discount .amount', {text: '$5.00'});
await page.waitForSelector('.order-total .amount', {text: '$4.99'});
it('prevents customer applying same coupon twice', async () => {
await applyCouponToCart( couponFixedCart );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await applyCouponToCart( couponFixedCart );
// Verify only one discount applied
// This is a work around for Puppeteer inconsistently finding 'Coupon code already applied'
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
await expect(page).toMatchElement('.order-total .amount', {text: '$4.99'});
});
// Try to apply the same coupon
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await expect(page).toFill('#coupon_code', couponFixedProduct);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-error', { text: 'Coupon code already applied!' });
it('allows customer to apply multiple coupons', async () => {
await applyCouponToCart( couponFixedProduct );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await expect(page).toMatchElement('.order-total .amount', {text: '$0.00'});
});
// Try to apply multiple coupons
await expect(page).toClick('a', {text: 'Click here to enter your code'});
await uiUnblocked();
await expect(page).toFill('#coupon_code', couponFixedCart);
await expect(page).toClick('button', {text: 'Apply coupon'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await page.waitForSelector('.order-total .amount', {text: '$0.00'});
// Remove coupon
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
await expect(page).toClick('.woocommerce-remove-coupon', {text: '[Remove]'});
await uiUnblocked();
await page.waitForSelector('.woocommerce-message', {text: 'Coupon has been removed.'});
// Verify the total amount after all coupons removal
await page.waitForSelector('.order-total .amount', {text: '$9.99'});
it('restores cart total when coupons are removed', async () => {
await removeCouponFromCart();
await removeCouponFromCart();
await expect(page).toMatchElement('.order-total .amount', {text: '$9.99'});
});
});
};

View File

@ -7,11 +7,13 @@ const {
merchant,
createSimpleProduct,
createVariableProduct,
createGroupedProduct,
uiUnblocked
} = require( '@woocommerce/e2e-utils' );
let simplePostIdValue;
let variablePostIdValue;
let groupedPostIdValue;
const config = require( 'config' );
const simpleProductName = config.get( 'products.simple.name' );
@ -33,7 +35,9 @@ const runSingleProductPageTest = () => {
// Verify cart contents
await shopper.goToCart();
await shopper.productIsInCart(simpleProductName, 5);
});
it('should be able to remove simple products from the cart', async () => {
// Remove items from cart
await shopper.removeFromCart(simpleProductName);
await uiUnblocked();
@ -60,13 +64,61 @@ const runSingleProductPageTest = () => {
// Verify cart contents
await shopper.goToCart();
await shopper.productIsInCart('Variable Product with Three Variations');
});
it('should be able to remove variation products from the cart', async () => {
// Remove items from cart
await shopper.removeFromCart('Variable Product with Three Variations');
await uiUnblocked();
await expect(page).toMatchElement('.cart-empty', {text: 'Your cart is currently empty.'});
});
});
describe('Grouped Product Page', () => {
beforeAll(async () => {
await merchant.login();
groupedPostIdValue = await createGroupedProduct();
await merchant.logout();
});
it('should be able to add grouped products to the cart', async () => {
// Add a grouped product to cart
await shopper.goToProduct(groupedPostIdValue);
await page.waitForSelector('form.grouped_form');
await shopper.addToCart();
await expect(page).toMatchElement('.woocommerce-error',
{text: 'Please choose the quantity of items you wish to add to your cart…'});
const quantityFields = await page.$$('div.quantity input.qty');
await quantityFields[0].click({clickCount: 3});
await quantityFields[0].type('5');
await quantityFields[1].click({clickCount: 3});
await quantityFields[1].type('5');
await shopper.addToCart();
await expect(page).toMatchElement('.woocommerce-message',
{text: '“'+simpleProductName+' 1” and “'+simpleProductName+' 2” have been added to your cart.'});
// Verify cart contents
await shopper.goToCart();
await shopper.productIsInCart(simpleProductName+' 1');
await shopper.productIsInCart(simpleProductName+' 2');
});
it('should be able to remove grouped products from the cart', async () => {
// Remove items from cart
await shopper.removeFromCart(simpleProductName+' 1');
await uiUnblocked();
await expect(page).toMatchElement('.woocommerce-message', {text: '“'+simpleProductName+' 1” removed.'});
await Promise.all( [
// Reload page and perform item removal, since removeFromCart won't remove it when placed in a row
page.reload(),
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
] );
await shopper.removeFromCart(simpleProductName+' 2');
await uiUnblocked();
await expect(page).toMatchElement('.woocommerce-message', {text: '“'+simpleProductName+' 2” removed.'});
await expect(page).toMatchElement('.cart-empty', {text: 'Your cart is currently empty.'});
});
});
};
module.exports = runSingleProductPageTest;

2
tests/e2e/env/package-lock.json generated vendored
View File

@ -1,6 +1,6 @@
{
"name": "@woocommerce/e2e-environment",
"version": "0.1.6",
"version": "0.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -18,6 +18,21 @@ import {
* @type {Array}
*/
const pageEvents = [];
/**
* Set of logged messages that will only be logged once.
*
* @type {Object<string,object>}
*/
const loggedMessages = {
proxy: {
logged: false,
text: 'Failed to load resource: net::ERR_PROXY_CONNECTION_FAILED',
},
http404: {
logged: false,
text: 'the server responded with a status of 404',
},
};
/**
* Set of console logging types observed to protect against unexpected yet
* handled (i.e. not catastrophic) errors or warnings. Each key corresponds
@ -140,16 +155,21 @@ function observeConsoleLogging() {
return;
}
// As of WordPress 5.3.2 in Chrome 79, navigating to the block editor
// (Posts > Add New) will display a console warning about
// non - unique IDs.
// See: https://core.trac.wordpress.org/ticket/23165
if ( text.includes( 'elements with non-unique id #_wpnonce' ) ) {
return;
}
const logFunction = OBSERVED_CONSOLE_MESSAGE_TYPES[ type ];
// Limit warnings on missing resources.
let previouslyLogged = false;
Object.keys( loggedMessages ).forEach( function( key ) {
if ( text.includes( loggedMessages[ key ].text ) ) {
if ( loggedMessages[ key ].logged ) {
previouslyLogged = true;
}
loggedMessages[ key ].logged = true;
}
} );
if ( previouslyLogged ) {
return;
}
// As of Puppeteer 1.6.1, `message.text()` wrongly returns an object of
// type JSHandle for error logging, instead of the expected string.
//

View File

@ -1,7 +1,7 @@
/**
* Provide the application name to bash scripts.
*/
const getAppName = require( './app-name' );
const { getAppName } = require( './app-name' );
const appName = getAppName();
console.log( appName );

View File

@ -5,12 +5,18 @@ const getAppRoot = require( './app-root' );
// Copy local test configuration file if it exists.
const appPath = getAppRoot();
const localTestConfigFile = path.resolve( appPath, 'tests/e2e/config/default.json' );
const defaultConfigFile = path.resolve( __dirname, '../config/default/default.json' );
const testConfigFile = path.resolve( __dirname, '../config/default.json' );
if ( fs.existsSync( localTestConfigFile ) ) {
fs.copyFileSync(
localTestConfigFile,
testConfigFile
);
} else {
fs.copyFileSync(
defaultConfigFile,
testConfigFile
);
}
const getTestConfig = () => {

View File

@ -15,6 +15,7 @@
- `addProductToOrder( orderId, productName )` component which adds the provided productName to the passed in orderId
- `createCoupon( couponAmount )` component which accepts a coupon amount string (it defaults to 5) and creates a basic coupon. Returns the generated coupon code.
- `evalAndClick( selector )` use Puppeteer page.$eval to select and click and element.
- `selectOptionInSelect2( selector, value )` util helper method that search and select in any select2 type field
## Changes

View File

@ -101,6 +101,7 @@ describe( 'Cart page', () => {
| `clickFilter` | `selector` | Click on a list page filter |
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
| `verifyAndPublish` | `noticeText` | Verify that an item can be published |
| `selectOptionInSelect2` | `selector, value` | helper method that searchs for select2 type fields and select plus insert value inside
### Test Utilities

View File

@ -15,7 +15,7 @@
"@wordpress/e2e-test-utils": "^4.6.0",
"config": "3.3.3",
"faker": "^5.1.0",
"fishery": "^1.0.1"
"fishery": "^1.2.0"
},
"peerDependencies": {
"@woocommerce/api": "^0.1.0"

View File

@ -6,7 +6,7 @@
* Internal dependencies
*/
import { merchant } from './flows';
import { clickTab, uiUnblocked, verifyCheckboxIsUnset, evalAndClick } from './page-utils';
import { clickTab, uiUnblocked, verifyCheckboxIsUnset, evalAndClick, selectOptionInSelect2 } from './page-utils';
import factories from './factories';
const config = require( 'config' );
@ -315,6 +315,40 @@ const createVariableProduct = async () => {
return variablePostIdValue;
};
/**
* Create grouped product.
*/
const createGroupedProduct = async () => {
// Create two products to be linked in a grouped product after
await factories.products.simple.create( {
name: simpleProductName + ' 1',
regularPrice: simpleProductPrice
} );
await factories.products.simple.create( {
name: simpleProductName + ' 2',
regularPrice: simpleProductPrice
} );
// Go to "add product" page
await merchant.openNewProduct();
// Make sure we're on the add product page
await expect( page.title() ).resolves.toMatch( 'Add new product' );
// Set product data and save the product
await expect( page ).toFill( '#title', 'Grouped Product' );
await expect( page ).toSelect( '#product-type', 'Grouped product' );
await clickTab( 'Linked Products' );
await selectOptionInSelect2( simpleProductName + ' 1' );
await selectOptionInSelect2( simpleProductName + ' 2' );
await verifyAndPublish();
// Get product ID
const groupedPostId = await page.$( '#post_ID' );
let groupedPostIdValue = ( await ( await groupedPostId.getProperty( 'value' ) ).jsonValue() );
return groupedPostIdValue;
}
/**
* Create a basic order with the provided order status.
*
@ -401,6 +435,7 @@ export {
completeOnboardingWizard,
createSimpleProduct,
createVariableProduct,
createGroupedProduct,
createSimpleOrder,
verifyAndPublish,
addProductToOrder,

View File

@ -1,41 +0,0 @@
import { Factory } from 'fishery';
/**
* A temporary class until Fishery includes better async support.
*/
export class AsyncFactory extends Factory {
constructor( generator, creator ) {
super( generator );
this.creator = creator;
}
/**
* Create an object using your factory
*
* @param {*} params The parameters that should populate the object.
* @param {*} options The options to be used in the builder.
* @return {Promise} Resolves to the created model.
*/
create( params = {}, options = {} ) {
const model = this.build( params, options );
return this.creator( model );
}
/**
* Create an array of objects using your factory
*
* @param {number} number The number of models to create.
* @param {*} params The parameters that should populate the object.
* @param {*} options The options to be used in the builder.
* @return {Promise} Resolves to the created models.
*/
createList( number, params = {}, options = {} ) {
const models = this.buildList( number, params, options );
const promises = [];
for ( const model of models ) {
promises.push( this.creator( model ) );
}
return Promise.all( promises );
}
}

View File

@ -1,6 +1,6 @@
import { SimpleProduct } from '@woocommerce/api';
import { AsyncFactory } from './async-factory';
import faker from 'faker/locale/en';
import { Factory } from 'fishery';
/**
* Creates a new factory for creating models.
@ -11,13 +11,14 @@ import faker from 'faker/locale/en';
export function simpleProductFactory( httpClient ) {
const repository = SimpleProduct.restRepository( httpClient );
return new AsyncFactory(
( { params } ) => {
return {
name: params.name ?? faker.commerce.productName(),
regularPrice: params.regularPrice ?? faker.commerce.price(),
};
},
( params ) => repository.create( params ),
);
return Factory.define( ( { params, onCreate } ) => {
onCreate( ( model ) => {
return repository.create( model );
} );
return {
name: params.name ?? faker.commerce.productName(),
regularPrice: params.regularPrice ?? faker.commerce.price(),
};
} );
}

View File

@ -196,6 +196,19 @@ const evalAndClick = async ( selector ) => {
page.$eval( selector, elem => elem.click() );
};
/**
* Select a value from select2 input field.
*
* @param {string} value Value of what to be selected
* @param {string} selector Selector of the select2
*/
const selectOptionInSelect2 = async ( value, selector = 'input.select2-search__field' ) => {
await page.waitForSelector(selector);
await page.type(selector, value);
await page.waitFor(2000); // to avoid flakyness, must wait before pressing Enter
await page.keyboard.press('Enter');
};
export {
clearAndFillInput,
clickTab,
@ -211,4 +224,5 @@ export {
clickFilter,
moveAllItemsToTrash,
evalAndClick,
selectOptionInSelect2,
};

View File

@ -73,4 +73,68 @@ class WC_Abstract_Order_Test extends WC_Unit_Test_Case {
$this->assertEquals( 1248.96, $order->get_total() );
}
/**
* Test that coupon taxes are not affected by logged in admin user.
*/
public function test_apply_coupon_for_correct_location_taxes() {
update_option( 'woocommerce_tax_round_at_subtotal', 'yes' );
update_option( 'woocommerce_prices_include_tax', 'yes' );
update_option( 'woocommerce_tax_based_on', 'billing' );
update_option( 'woocommerce_calc_taxes', 'yes' );
$password = wp_generate_password( 8, false, false );
$admin_id = wp_insert_user(
array(
'user_login' => "test_admin$password",
'user_pass' => $password,
'user_email' => "admin$password@example.com",
'role' => 'administrator',
)
);
update_user_meta( $admin_id, 'billing_country', 'MV' ); // Different than customer's address and base location.
wp_set_current_user( $admin_id );
WC()->customer = null;
WC()->initialize_cart();
update_option( 'woocommerce_default_country', 'IN:AP' );
$tax_rate = array(
'tax_rate_country' => 'IN',
'tax_rate_state' => '',
'tax_rate' => '25.0000',
'tax_rate_name' => 'tax',
'tax_rate_order' => '1',
'tax_rate_class' => '',
);
WC_Tax::_insert_tax_rate( $tax_rate );
$product = WC_Helper_Product::create_simple_product();
$product->set_regular_price( 100 );
$product->save();
$order = wc_create_order();
$order->set_billing_country( 'IN' );
$order->add_product( $product, 1 );
$order->save();
$order->calculate_totals();
$this->assertEquals( 100, $order->get_total() );
$this->assertEquals( 80, $order->get_subtotal() );
$this->assertEquals( 20, $order->get_total_tax() );
$coupon = new WC_Coupon();
$coupon->set_code( '10off' );
$coupon->set_discount_type( 'percent' );
$coupon->set_amount( 10 );
$coupon->save();
$order->apply_coupon( '10off' );
$this->assertEquals( 8, $order->get_discount_total() );
$this->assertEquals( 90, $order->get_total() );
$this->assertEquals( 18, $order->get_total_tax() );
$this->assertEquals( 2, $order->get_discount_tax() );
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* Tests for WC_Query.
*/
class WC_Query_Test extends \WC_Unit_Test_Case {
/**
* @testdox 'price_filter_post_clauses' generates the proper 'where' clause when there are 'max_price' and 'min_price' arguments in the query.
*/
public function test_price_filter_post_clauses_creates_the_proper_where_clause() {
// phpcs:disable Squiz.Commenting
$wp_query = new class() {
public function is_main_query() {
return true;
}
};
// phpcs:enable Squiz.Commenting
$_GET['min_price'] = '100';
$_GET['max_price'] = '200';
$sut = new WC_Query();
$args = array(
'join' => '(JOIN CLAUSE)',
'where' => '(WHERE CLAUSE)',
);
$args = $sut->price_filter_post_clauses( $args, $wp_query );
$expected = '(WHERE CLAUSE) AND NOT (200.000000<wc_product_meta_lookup.min_price OR 100.000000>wc_product_meta_lookup.max_price ) ';
$this->assertEquals( $expected, $args['where'] );
}
}

View File

@ -8,7 +8,7 @@
* Author URI: https://woocommerce.com
* Text Domain: woocommerce
* Domain Path: /i18n/languages/
* Requires at least: 5.3
* Requires at least: 5.4
* Requires PHP: 7.0
*
* @package WooCommerce