Skip to content

Commit 6da3688

Browse files
committed
🧪 Add failing tests with new expectations
1 parent a0951c9 commit 6da3688

2 files changed

Lines changed: 262 additions & 0 deletions

File tree

‎tests/PHPUnit/StoreSync/CartValidation/ShippingValidatorTest.php‎

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,265 @@ public function test_validate_handles_product_not_found_for_signature_check(): v
378378
$this->assertNull( $result );
379379
}
380380

381+
/**
382+
* Given a cart containing a shippable product and no shipping address
383+
* When validate() is called
384+
* Then a ValidationIssue for the 'shipping_address' field is returned
385+
* And the issue asks the customer to provide a shipping address
386+
* And a PROVIDE_MISSING_FIELD resolution option is included
387+
*/
388+
public function test_validate_returns_missing_address_issue_when_cart_needs_shipping(): void {
389+
$product = \Mockery::mock( 'WC_Product' );
390+
$product->shouldReceive( 'needs_shipping' )->andReturn( true );
391+
$this->product_manager->shouldReceive( 'find_product' )
392+
->andReturn( $product );
393+
394+
$cart = PayPalCart::from_array(
395+
array(
396+
'items' => array(
397+
array(
398+
'item_id' => '1',
399+
'quantity' => 1,
400+
'name' => 'Shippable Product',
401+
),
402+
),
403+
'payment_method' => 'paypal',
404+
)
405+
);
406+
407+
$result = $this->validator->validate( $cart );
408+
409+
$this->assertIsArray( $result );
410+
$this->assertCount( 1, $result );
411+
$this->assertInstanceOf( ValidationIssue::class, $result[0] );
412+
413+
$issue_data = $result[0]->to_array();
414+
$this->assertStringContainsString( 'Shipping address is required', $issue_data['message'] );
415+
$this->assertStringContainsString( 'Please provide a shipping address', $issue_data['user_message'] );
416+
$this->assertSame( 'shipping_address', $issue_data['field'] );
417+
418+
$this->assertArrayHasKey( 'resolution_options', $issue_data );
419+
$actions = array_column( $issue_data['resolution_options'], 'action' );
420+
$this->assertContains( 'PROVIDE_MISSING_FIELD', $actions );
421+
}
422+
423+
/**
424+
* Given a cart shipping to a US address with a postal code containing invalid characters
425+
* When validate() is called
426+
* Then a ValidationIssue for 'shipping_address.postal_code' is returned
427+
* And the issue message mentions an invalid postal code format
428+
*/
429+
public function test_validate_detects_invalid_postal_code_format(): void {
430+
$this->mock_wc_countries(
431+
array( 'US' => 'United States' ),
432+
array( 'US' => 'United States' )
433+
);
434+
435+
$cart = $this->create_cart_with_shipping(
436+
array(
437+
'country_code' => 'US',
438+
'address_line_1' => '123 Main St',
439+
'admin_area_2' => 'New York',
440+
'postal_code' => '100!01',
441+
)
442+
);
443+
444+
$result = $this->validator->validate( $cart );
445+
446+
$this->assertIsArray( $result );
447+
$this->assertCount( 1, $result );
448+
$this->assertInstanceOf( ValidationIssue::class, $result[0] );
449+
450+
$issue_data = $result[0]->to_array();
451+
$this->assertStringContainsString( 'Invalid postal code format', $issue_data['message'] );
452+
$this->assertSame( 'shipping_address.postal_code', $issue_data['field'] );
453+
}
454+
455+
// Gap A3: Fallback from empty shipping countries to allowed countries
456+
457+
/**
458+
* Given WooCommerce has no shipping-specific countries configured (empty list)
459+
* And the allowed-countries list contains US
460+
* And the cart ships to US
461+
* When validate() is called
462+
* Then no country issue is returned (US is permitted via the allowed-countries fallback)
463+
*/
464+
public function test_validate_falls_back_to_allowed_countries_when_shipping_countries_is_empty(): void {
465+
$this->mock_wc_countries(
466+
array( 'US' => 'United States' ),
467+
array() // empty shipping countries → fallback to allowed countries
468+
);
469+
470+
$cart = $this->create_cart_with_shipping(
471+
array(
472+
'country_code' => 'US',
473+
'address_line_1' => '123 Main St',
474+
'admin_area_2' => 'New York',
475+
'postal_code' => '10001',
476+
)
477+
);
478+
479+
$result = $this->validator->validate( $cart );
480+
481+
$this->assertNull( $result );
482+
}
483+
484+
// Group B: PayPal-level US-only restriction (failing tests — feature not yet implemented)
485+
486+
/**
487+
* Given PayPal's supported-country allowlist only includes the United States
488+
* And WooCommerce also allows US
489+
* And the cart ships to US
490+
* When validate() is called
491+
* Then no PayPal-restriction issue is returned
492+
*/
493+
public function test_validate_accepts_us_shipping_address_for_paypal_restriction(): void {
494+
$this->mock_wc_countries(
495+
array( 'US' => 'United States' ),
496+
array( 'US' => 'United States' )
497+
);
498+
499+
$cart = $this->create_cart_with_shipping(
500+
array(
501+
'country_code' => 'US',
502+
'address_line_1' => '123 Main St',
503+
'admin_area_2' => 'New York',
504+
'postal_code' => '10001',
505+
)
506+
);
507+
508+
$result = $this->validator->validate( $cart );
509+
510+
$this->assertNull( $result );
511+
}
512+
513+
/**
514+
* Given PayPal's supported-country allowlist only includes the United States
515+
* And WooCommerce allows both US and CA
516+
* And the cart ships to CA (Canada)
517+
* When validate() is called
518+
* Then a ValidationIssue is returned indicating CA is not supported by PayPal
519+
* And the issue targets 'shipping_address.country_code'
520+
* And the user message mentions that only specific countries are currently supported
521+
*/
522+
public function test_validate_rejects_canada_shipping_address_due_to_paypal_restriction(): void {
523+
$this->mock_wc_countries(
524+
array( 'US' => 'United States', 'CA' => 'Canada' ),
525+
array( 'US' => 'United States', 'CA' => 'Canada' )
526+
);
527+
528+
$cart = $this->create_cart_with_shipping(
529+
array(
530+
'country_code' => 'CA',
531+
'address_line_1' => '456 Maple Ave',
532+
'admin_area_2' => 'Toronto',
533+
'postal_code' => 'M5V 3A8',
534+
)
535+
);
536+
537+
$result = $this->validator->validate( $cart );
538+
539+
$this->assertIsArray( $result );
540+
$this->assertCount( 1, $result );
541+
$this->assertInstanceOf( ValidationIssue::class, $result[0] );
542+
543+
$issue_data = $result[0]->to_array();
544+
$this->assertSame( 'shipping_address.country_code', $issue_data['field'] );
545+
546+
$message_lower = strtolower( $issue_data['message'] );
547+
$this->assertTrue(
548+
strpos( $message_lower, 'ca' ) !== false
549+
|| strpos( $message_lower, 'paypal' ) !== false
550+
|| strpos( $message_lower, 'not supported' ) !== false,
551+
'Expected issue message to reference CA, PayPal, or "not supported", got: ' . $issue_data['message']
552+
);
553+
554+
$user_message_lower = strtolower( $issue_data['user_message'] );
555+
$this->assertTrue(
556+
strpos( $user_message_lower, 'united states' ) !== false
557+
|| strpos( $user_message_lower, 'supported' ) !== false
558+
|| strpos( $user_message_lower, 'country' ) !== false,
559+
'Expected user_message to mention supported countries, got: ' . $issue_data['user_message']
560+
);
561+
}
562+
563+
/**
564+
* Given PayPal's supported-country allowlist only includes the United States
565+
* And WooCommerce allows both US and DE
566+
* And the cart ships to DE (Germany)
567+
* When validate() is called
568+
* Then a ValidationIssue is returned indicating DE is not supported by PayPal
569+
* And the issue targets 'shipping_address.country_code'
570+
*/
571+
public function test_validate_rejects_germany_shipping_address_due_to_paypal_restriction(): void {
572+
$this->mock_wc_countries(
573+
array( 'US' => 'United States', 'DE' => 'Germany' ),
574+
array( 'US' => 'United States', 'DE' => 'Germany' )
575+
);
576+
577+
$cart = $this->create_cart_with_shipping(
578+
array(
579+
'country_code' => 'DE',
580+
'address_line_1' => '1 Unter den Linden',
581+
'admin_area_2' => 'Berlin',
582+
'postal_code' => '10117',
583+
)
584+
);
585+
586+
$result = $this->validator->validate( $cart );
587+
588+
$this->assertIsArray( $result );
589+
$this->assertCount( 1, $result );
590+
$this->assertInstanceOf( ValidationIssue::class, $result[0] );
591+
592+
$issue_data = $result[0]->to_array();
593+
$this->assertSame( 'shipping_address.country_code', $issue_data['field'] );
594+
595+
$message_lower = strtolower( $issue_data['message'] );
596+
$this->assertTrue(
597+
strpos( $message_lower, 'de' ) !== false
598+
|| strpos( $message_lower, 'paypal' ) !== false
599+
|| strpos( $message_lower, 'not supported' ) !== false,
600+
'Expected issue message to reference DE, PayPal, or "not supported", got: ' . $issue_data['message']
601+
);
602+
}
603+
604+
/**
605+
* Given a country is disallowed by both WooCommerce settings and the PayPal country restriction
606+
* And the cart ships to FR (France), which WooCommerce does not allow and PayPal does not support
607+
* When validate() is called
608+
* Then exactly one country-level ValidationIssue is returned (checks do not stack)
609+
*/
610+
public function test_validate_produces_single_country_issue_when_disallowed_by_both_woocommerce_and_paypal(): void {
611+
$this->mock_wc_countries(
612+
array( 'US' => 'United States', 'FR' => 'France' ),
613+
array( 'US' => 'United States' ) // FR not in shipping countries
614+
);
615+
616+
$cart = $this->create_cart_with_shipping(
617+
array(
618+
'country_code' => 'FR',
619+
'address_line_1' => '123 Rue de la Paix',
620+
'admin_area_2' => 'Paris',
621+
'postal_code' => '75001',
622+
)
623+
);
624+
625+
$result = $this->validator->validate( $cart );
626+
627+
$this->assertIsArray( $result );
628+
629+
$country_issues = array_filter(
630+
$result,
631+
static function ( ValidationIssue $issue ): bool {
632+
$data = $issue->to_array();
633+
return isset( $data['field'] ) && $data['field'] === 'shipping_address.country_code';
634+
}
635+
);
636+
637+
$this->assertCount( 1, $country_issues );
638+
}
639+
381640
private function create_cart_with_shipping( array $address_data ): PayPalCart {
382641
return PayPalCart::from_array(
383642
array(

‎tests/stubs/WC_Validation.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
if ( ! class_exists( 'WC_Validation' ) ) {
44
class WC_Validation {
55
public static function is_postcode( string $postcode, string $country ): bool {
6+
if ( strlen( trim( preg_replace( '/[\s\-A-Za-z0-9]/', '', $postcode ) ) ) > 0 ) {
7+
return false;
8+
}
69
return true;
710
}
811
}

0 commit comments

Comments
 (0)