Skip to content

Commit 91dbde4

Browse files
committed
Add - Pin the sanitize_key() collapse boundary at the rate-table seam.
state_compact_provider() already pins what the *projection* returns for a collapsing state. Nothing pinned what that collapse does to the rate table, which is the claim the changelog entry actually makes — and the reason the entry was able to drift. Adds two rows to provide_rate_table_round_trips(), which feeds both the round-trip test and the matched-rates lookup test, so two rows are four cases: - 'state partially collapsing' (RO / 'ÎF', stored as 'F') is a regression test. Against the pre-migration space-stripping lookup both its cases fail: the round trip inserts a second row, and allow_street_address_for_matched_rates() cannot see the row create_or_update_tax_rate() had just written. - 'state wholly non-Latin' (RU / 'ЛЕН', stored as '') is a boundary characterization and passes with or without the migration. The blank matches the '' arm of core's `tax_rate_state IN ( %s, '' )`, so this shape never duplicated. It also pins that such an address yields a country-wide rate. Together they are the narrowing: the same "non-Latin character" trigger, opposite outcomes, decided by whether anything survives the stripping. Both cities are plain ASCII on purpose, so the state dimension is not confounded with the separate byte-parity contract to_find_rates_args() keeps with core.
1 parent c5b6158 commit 91dbde4

1 file changed

Lines changed: 71 additions & 2 deletions

File tree

tests/php/test-class-wc-connect-taxjar-integration.php

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3288,8 +3288,9 @@ public function provide_rate_table_round_trips() {
32883288
* The same divergence, where space-stripping was not enough.
32893289
* `sanitize_key()` drops the periods too, so the row was stored as `'NY'`
32903290
* while both readers asked for `'N.Y.'` — nothing ever matched and every
3291-
* calculation inserted a fresh row. Any state value carrying a character
3292-
* outside `[a-z0-9_-]` behaved this way, non-ASCII included.
3291+
* calculation inserted a fresh row. A state carrying a character outside
3292+
* `[a-z0-9_-]` behaved this way only when something survived the stripping;
3293+
* see the two cases below for the boundary that qualifier draws.
32933294
*
32943295
* `Address::state_compact()` now mirrors `sanitize_key()` rather than
32953296
* approximating it, so the lookup asks for the value core actually stored.
@@ -3313,6 +3314,74 @@ public function provide_rate_table_round_trips() {
33133314
),
33143315
),
33153316

3317+
/*
3318+
* The boundary the changelog entry has to respect: a state `sanitize_key()`
3319+
* empties *outright* never duplicated a row, not even before the fix. Core
3320+
* stores `''` and matches with `tax_rate_state IN ( %s, '' )`
3321+
* (`WC_Tax::get_matched_tax_rates()`), so the stored blank satisfies the
3322+
* second arm whatever the lookup asked for — the old space-stripping lookup
3323+
* asked for `'ЛЕН'` and still found the row. The rate is country-wide, which
3324+
* is a real behaviour worth pinning in its own right.
3325+
*
3326+
* Passes with and without the seam migration. That is what makes it a
3327+
* boundary characterization rather than a regression test, and it is here so
3328+
* the duplication story cannot be restated as "any non-ASCII state".
3329+
*
3330+
* The city is deliberately plain ASCII: this row is about the state
3331+
* dimension, and a multibyte city would confound it with the separate
3332+
* byte-parity contract `to_find_rates_args()` keeps with core.
3333+
*/
3334+
'state wholly non-Latin' => array(
3335+
array(
3336+
'to_country' => 'RU',
3337+
'to_state' => 'ЛЕН',
3338+
'to_zip' => '190000',
3339+
'to_city' => 'Saint Petersburg',
3340+
'from_state' => 'ЛЕН',
3341+
),
3342+
'Tax',
3343+
array(
3344+
'duplicates' => false,
3345+
'matched' => true,
3346+
'country' => 'RU',
3347+
'state' => '',
3348+
'postcodes' => array( '190000' ),
3349+
'cities' => array( 'SAINT PETERSBURG' ),
3350+
),
3351+
),
3352+
3353+
/*
3354+
* The shape that actually duplicated, and the reason the changelog says "a
3355+
* character WooCommerce strips" rather than naming scripts. `sanitize_key()`
3356+
* drops the diacritic and keeps the rest, so the row was stored as `'F'`
3357+
* while the space-stripping lookup asked for `'ÎF'` — non-empty, different
3358+
* from the stored value, and so matching neither arm of the `IN` clause. A
3359+
* fresh row every calculation.
3360+
*
3361+
* Fails without the seam migration: two rows, and `first_id !== second_id`.
3362+
* Paired with the case above, the two of them are the narrowing — same
3363+
* "non-Latin character" trigger, opposite outcomes, decided by whether
3364+
* anything survives the stripping.
3365+
*/
3366+
'state partially collapsing' => array(
3367+
array(
3368+
'to_country' => 'RO',
3369+
'to_state' => 'ÎF',
3370+
'to_zip' => '077100',
3371+
'to_city' => 'Buftea',
3372+
'from_state' => 'ÎF',
3373+
),
3374+
'Tax',
3375+
array(
3376+
'duplicates' => false,
3377+
'matched' => true,
3378+
'country' => 'RO',
3379+
'state' => 'F',
3380+
'postcodes' => array( '077100' ),
3381+
'cities' => array( 'BUFTEA' ),
3382+
),
3383+
),
3384+
33163385
/*
33173386
* A2's live half. The write sanitized the city with `wc_clean()` and the
33183387
* lookup did not, so anything `sanitize_text_field()` removes made the two

0 commit comments

Comments
 (0)