You are here

public function CheckoutPaneTest::testMultipleShipments in Commerce Shipping 8.2

Tests checkout with multiple shipments.

File

tests/src/FunctionalJavascript/CheckoutPaneTest.php, line 386

Class

CheckoutPaneTest
Tests the "Shipping information" checkout pane.

Namespace

Drupal\Tests\commerce_shipping\FunctionalJavascript

Code

public function testMultipleShipments() {

  // Create a default profile to confirm that it is used at checkout.
  $default_profile = $this
    ->createEntity('profile', [
    'type' => 'customer',
    'uid' => $this->adminUser
      ->id(),
    'address' => $this->defaultAddress,
  ]);
  $this
    ->drupalGet($this->firstProduct
    ->toUrl()
    ->toString());
  $this
    ->submitForm([], 'Add to cart');
  $this
    ->drupalGet($this->secondProduct
    ->toUrl()
    ->toString());
  $this
    ->submitForm([], 'Add to cart');
  $this
    ->drupalGet('checkout/1');
  $this
    ->assertSession()
    ->pageTextContains('Shipping information');
  $this
    ->assertRenderedAddress($this->defaultAddress, 'shipping_information[shipping_profile]');
  $this
    ->assertRenderedAddress($this->defaultAddress, 'payment_information[add_payment_method][billing_information]');

  // Confirm that it is possible to enter a different address.
  $this
    ->getSession()
    ->getPage()
    ->fillField('shipping_information[shipping_profile][select_address]', '_new');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $address = [
    'given_name' => 'John',
    'family_name' => 'Smith',
    'address_line1' => '38 rue du sentier',
    'locality' => 'Paris',
    'postal_code' => '75002',
  ];
  $address_prefix = 'shipping_information[shipping_profile][address][0][address]';
  $page = $this
    ->getSession()
    ->getPage();
  $page
    ->fillField($address_prefix . '[country_code]', 'FR');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($address as $property => $value) {
    $page
      ->fillField($address_prefix . '[' . $property . ']', $value);
  }
  $page
    ->findButton('Recalculate shipping')
    ->click();
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ([
    0,
    1,
  ] as $shipment_index) {
    $label_index = $shipment_index + 1;
    $this
      ->assertSession()
      ->pageTextContains('Shipment #' . $label_index);
    $first_radio_button = $page
      ->findField('shipping_information[shipments][' . $shipment_index . '][shipping_method][0]');
    $second_radio_button = $page
      ->findField('shipping_information[shipments][' . $shipment_index . '][shipping_method][0]');
    $this
      ->assertNotNull($first_radio_button);
    $this
      ->assertNotNull($second_radio_button);

    // The radio buttons don't have access to their own labels.
    $selector = '//fieldset[@data-drupal-selector="edit-shipping-information-shipments-0-shipping-method-0"]';
    $this
      ->assertSession()
      ->elementTextContains('xpath', $selector, 'Standard shipping: $9.99');

    // The $19.99 is displayed crossed out, but Mink strips HTML.
    $this
      ->assertSession()
      ->elementTextContains('xpath', $selector, 'Overnight shipping: $19.99 $16.99');
    $this
      ->assertSession()
      ->elementTextContains('xpath', $selector, 'At your door tomorrow morning');
  }
  $this
    ->assertSession()
    ->pageTextContains('Shipment #1 $9.99');
  $this
    ->assertSession()
    ->pageTextContains('Shipment #2 $9.99');
  $this
    ->submitForm([
    'payment_information[add_payment_method][payment_details][number]' => '4111111111111111',
    'payment_information[add_payment_method][payment_details][expiration][month]' => '02',
    'payment_information[add_payment_method][payment_details][expiration][year]' => '2024',
    'payment_information[add_payment_method][payment_details][security_code]' => '123',
  ], 'Continue to review');

  // Confirm that the review is rendered correctly.
  $this
    ->assertSession()
    ->pageTextContains('Shipping information');
  foreach ($address as $property => $value) {
    $this
      ->assertSession()
      ->pageTextContains($value);
  }
  $this
    ->assertSession()
    ->pageTextContains('Shipment #1');
  $this
    ->assertSession()
    ->pageTextContains('Shipment #2');
  $this
    ->assertSession()
    ->elementsCount('xpath', '//div[@class="field__item" and .="Standard shipping"]', 2);

  // Confirm the integrity of the shipment.
  $this
    ->submitForm([], 'Pay and complete purchase');
  $order = Order::load(1);
  $billing_profile = $order
    ->getBillingProfile();
  $this
    ->assertNotEmpty($billing_profile);
  $this
    ->assertEquals('customer', $billing_profile
    ->bundle());
  $this
    ->assertEquals('Paris', $billing_profile
    ->get('address')->locality);

  // Confirm the integrity of the shipments.
  $shipments = $order
    ->get('shipments')
    ->referencedEntities();
  $this
    ->assertCount(2, $shipments);

  /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $first_shipment */
  $first_shipment = reset($shipments);
  $this
    ->assertEquals('custom_box', $first_shipment
    ->getPackageType()
    ->getId());
  $this
    ->assertEquals('Paris', $first_shipment
    ->getShippingProfile()
    ->get('address')->locality);
  $this
    ->assertEquals('Standard shipping', $first_shipment
    ->getShippingMethod()
    ->label());
  $this
    ->assertEquals('default', $first_shipment
    ->getShippingService());
  $this
    ->assertEquals('9.99', $first_shipment
    ->getAmount()
    ->getNumber());
  $this
    ->assertEquals('draft', $first_shipment
    ->getState()->value);
  $this
    ->assertCount(1, $first_shipment
    ->getItems());
  $items = $first_shipment
    ->getItems();
  $item = reset($items);
  $this
    ->assertEquals('Conference hat', $item
    ->getTitle());
  $this
    ->assertEquals(1, $item
    ->getQuantity());

  /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $second_shipment */
  $second_shipment = end($shipments);
  $this
    ->assertEquals('custom_box', $second_shipment
    ->getPackageType()
    ->getId());
  $this
    ->assertEquals('Paris', $second_shipment
    ->getShippingProfile()
    ->get('address')->locality);
  $this
    ->assertEquals('Standard shipping', $second_shipment
    ->getShippingMethod()
    ->label());
  $this
    ->assertEquals('default', $second_shipment
    ->getShippingService());
  $this
    ->assertEquals('9.99', $second_shipment
    ->getAmount()
    ->getNumber());
  $this
    ->assertEquals('draft', $second_shipment
    ->getState()->value);
  $this
    ->assertCount(1, $second_shipment
    ->getItems());
  $items = $second_shipment
    ->getItems();
  $item = reset($items);
  $this
    ->assertEquals('Conference bow tie', $item
    ->getTitle());
  $this
    ->assertEquals(1, $item
    ->getQuantity());

  // Confirm that the shipping profile is shared between shipments.
  $this
    ->assertEquals($first_shipment
    ->getShippingProfile()
    ->id(), $second_shipment
    ->getShippingProfile()
    ->id());

  // Confirm that the order total contains the shipment amounts.
  $this
    ->assertEquals(new Price('36.96', 'USD'), $order
    ->getTotalPrice());
}