commerce-8.x-2.8/modules/checkout/tests/src/Functional/CheckoutOrderTest.php
modules/checkout/tests/src/Functional/CheckoutOrderTest.php
<?php namespace Drupal\Tests\commerce_checkout\Functional; use Drupal\Tests\commerce\Functional\CommerceBrowserTestBase; /** * Tests the checkout of an order. * * @group commerce */ class CheckoutOrderTest extends CommerceBrowserTestBase { /** * The current user. * * @var \Drupal\Core\Session\AccountInterface */ protected $account; /** * The product. * * @var \Drupal\commerce_product\Entity\ProductInterface */ protected $product; /** * Modules to enable. * * @var array */ public static $modules = [ 'commerce_product', 'commerce_order', 'commerce_cart', 'commerce_checkout', 'views_ui', ]; /** * {@inheritdoc} */ protected function getAdministratorPermissions() { return array_merge([ 'administer commerce_checkout_flow', 'administer views', ], parent::getAdministratorPermissions()); } /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->placeBlock('commerce_cart'); $this->placeBlock('commerce_checkout_progress'); $variation = $this->createEntity('commerce_product_variation', [ 'type' => 'default', 'sku' => strtolower($this->randomMachineName()), 'price' => [ 'number' => 9.99, 'currency_code' => 'USD', ], ]); /** @var \Drupal\commerce_product\Entity\ProductInterface $product */ $this->product = $this->createEntity('commerce_product', [ 'type' => 'default', 'title' => 'My product', 'variations' => [$variation], 'stores' => [$this->store], ]); } /** * Tests checkout flow cache metadata. */ public function testCacheMetadata() { $this->drupalLogout(); $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextNotContains('Order Summary'); $this->assertCheckoutProgressStep('Login'); /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ $order = $this->container->get('entity_type.manager')->getStorage('commerce_order')->load(1); /** @var \Drupal\commerce_checkout\Entity\CheckoutFlowInterface $checkout_flow */ $checkout_flow = $this->container->get('entity_type.manager')->getStorage('commerce_checkout_flow')->load('default'); // We're on a form, so no Page Cache. $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', NULL); // Dynamic page cache should be present, and a MISS. $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'MISS'); // Assert cache tags bubbled. $cache_tags_header = $this->getSession()->getResponseHeader('X-Drupal-Cache-Tags'); $this->assertTrue(strpos($cache_tags_header, 'commerce_order:' . $order->id()) !== FALSE); foreach ($order->getItems() as $item) { $this->assertTrue(strpos($cache_tags_header, 'commerce_order_item:' . $item->id()) !== FALSE); } foreach ($checkout_flow->getCacheTags() as $cache_tag) { $this->assertTrue(strpos($cache_tags_header, $cache_tag) !== FALSE); } $this->getSession()->reload(); $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'HIT'); // Saving the order should bust the cache. $this->container->get('commerce_order.order_refresh')->refresh($order); $order->save(); $this->getSession()->reload(); $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'MISS'); $this->getSession()->reload(); $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'HIT'); // Saving the checkout flow configuration entity should bust the cache. $checkout_flow->save(); $this->getSession()->reload(); $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'MISS'); $this->getSession()->reload(); $this->assertSession()->responseHeaderEquals('X-Drupal-Dynamic-Cache', 'HIT'); } /** * Tests than an order can go through checkout steps. */ public function testGuestOrderCheckout() { $this->drupalLogout(); $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextNotContains('Order Summary'); $this->assertCheckoutProgressStep('Login'); $this->submitForm([], 'Continue as Guest'); $this->assertCheckoutProgressStep('Order information'); $this->submitForm([ 'contact_information[email]' => 'guest@example.com', 'contact_information[email_confirm]' => 'guest@example.com', 'billing_information[profile][address][0][address][given_name]' => $this->randomString(), 'billing_information[profile][address][0][address][family_name]' => $this->randomString(), 'billing_information[profile][address][0][address][organization]' => $this->randomString(), 'billing_information[profile][address][0][address][address_line1]' => $this->randomString(), 'billing_information[profile][address][0][address][postal_code]' => '94043', 'billing_information[profile][address][0][address][locality]' => 'Mountain View', 'billing_information[profile][address][0][address][administrative_area]' => 'CA', ], 'Continue to review'); $this->assertCheckoutProgressStep('Review'); $this->assertSession()->pageTextContains('Contact information'); $this->assertSession()->pageTextContains('Billing information'); $this->assertSession()->pageTextContains('Order Summary'); $this->submitForm([], 'Complete checkout'); $this->assertSession()->pageTextContains('Your order number is 1. You can view your order on your account page when logged in.'); $this->assertSession()->pageTextContains('0 items'); // Test second order. $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); $this->submitForm([], 'Checkout'); $this->assertCheckoutProgressStep('Login'); $this->assertSession()->pageTextNotContains('Order Summary'); $this->submitForm([], 'Continue as Guest'); $this->assertCheckoutProgressStep('Order information'); $this->submitForm([ 'contact_information[email]' => 'guest@example.com', 'contact_information[email_confirm]' => 'guest@example.com', 'billing_information[profile][address][0][address][given_name]' => $this->randomString(), 'billing_information[profile][address][0][address][family_name]' => $this->randomString(), 'billing_information[profile][address][0][address][organization]' => $this->randomString(), 'billing_information[profile][address][0][address][address_line1]' => $this->randomString(), 'billing_information[profile][address][0][address][postal_code]' => '94043', 'billing_information[profile][address][0][address][locality]' => 'Mountain View', 'billing_information[profile][address][0][address][administrative_area]' => 'CA', ], 'Continue to review'); $this->assertSession()->pageTextContains('Contact information'); $this->assertSession()->pageTextContains('Billing information'); $this->assertSession()->pageTextContains('Order Summary'); $this->assertCheckoutProgressStep('Review'); // Go back and forth. $this->getSession()->getPage()->clickLink('Go back'); $this->assertCheckoutProgressStep('Order information'); $this->getSession()->getPage()->pressButton('Continue to review'); $this->assertCheckoutProgressStep('Review'); $this->submitForm([], 'Complete checkout'); $this->assertSession()->pageTextContains('Your order number is 2. You can view your order on your account page when logged in.'); $this->assertSession()->pageTextContains('0 items'); } /** * Tests that you can register from the checkout pane. */ public function testRegisterOrderCheckout() { $config = \Drupal::configFactory()->getEditable('commerce_checkout.commerce_checkout_flow.default'); $config->set('configuration.panes.login.allow_guest_checkout', FALSE); $config->set('configuration.panes.login.allow_registration', TRUE); $config->save(); $this->drupalLogout(); $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextContains('New Customer'); $this->submitForm([ 'login[register][name]' => 'User name', 'login[register][mail]' => 'guest@example.com', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('Billing information'); // Test account validation. $this->drupalLogout(); $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextContains('New Customer'); $this->submitForm([ 'login[register][name]' => 'User name', 'login[register][mail]' => '', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('Email field is required.'); $this->submitForm([ 'login[register][name]' => '', 'login[register][mail]' => 'guest@example.com', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('Username field is required.'); $this->submitForm([ 'login[register][name]' => 'User name', 'login[register][mail]' => 'guest@example.com', 'login[register][password][pass1]' => '', 'login[register][password][pass2]' => '', ], 'Create account and continue'); $this->assertSession()->pageTextContains('Password field is required.'); $this->submitForm([ 'login[register][name]' => 'User name double email', 'login[register][mail]' => 'guest@example.com', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('The email address guest@example.com is already taken.'); $this->submitForm([ 'login[register][name]' => 'User @#.``^ ù % name invalid', 'login[register][mail]' => 'guest2@example.com', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('The username contains an illegal character.'); $this->submitForm([ 'login[register][name]' => 'User name', 'login[register][mail]' => 'guest2@example.com', 'login[register][password][pass1]' => 'pass', 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('The username User name is already taken.'); } /** * Tests checkout behaviour after a cart update. */ public function testCheckoutFlowOnCartUpdate() { $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $this->getSession()->getPage()->findLink('your cart')->click(); // Submit the form until review. $this->submitForm([], 'Checkout'); $this->assertSession()->elementContains('css', 'h1.page-title', 'Order information'); $this->assertSession()->elementNotContains('css', 'h1.page-title', 'Review'); $this->submitForm([ 'billing_information[profile][address][0][address][given_name]' => $this->randomString(), 'billing_information[profile][address][0][address][family_name]' => $this->randomString(), 'billing_information[profile][address][0][address][organization]' => $this->randomString(), 'billing_information[profile][address][0][address][address_line1]' => $this->randomString(), 'billing_information[profile][address][0][address][postal_code]' => '94043', 'billing_information[profile][address][0][address][locality]' => 'Mountain View', 'billing_information[profile][address][0][address][administrative_area]' => 'CA', ], 'Continue to review'); $this->assertSession()->elementContains('css', 'h1.page-title', 'Review'); // By default the checkout step is preserved upon return. $this->drupalGet('/checkout/1'); $this->assertSession()->elementContains('css', 'h1.page-title', 'Review'); $variation = $this->createEntity('commerce_product_variation', [ 'type' => 'default', 'sku' => strtolower($this->randomMachineName()), 'price' => [ 'number' => 9.99, 'currency_code' => 'USD', ], ]); /** @var \Drupal\commerce_product\Entity\ProductInterface $product */ $product2 = $this->createEntity('commerce_product', [ 'type' => 'default', 'title' => 'My product', 'variations' => [$variation], 'stores' => [$this->store], ]); // Adding a new product to the cart resets the checkout step. $this->drupalGet($product2->toUrl()->toString()); $this->submitForm([], 'Add to cart'); $this->getSession()->getPage()->findLink('your cart')->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->elementContains('css', 'h1.page-title', 'Order information'); $this->assertSession()->elementNotContains('css', 'h1.page-title', 'Review'); // Removing a product from the cart resets the checkout step. $this->submitForm([], 'Continue to review'); $this->drupalGet('/cart'); $this->submitForm([], 'Remove'); $this->submitForm([], 'Checkout'); $this->assertSession()->elementContains('css', 'h1.page-title', 'Order information'); $this->assertSession()->elementNotContains('css', 'h1.page-title', 'Review'); } /** * Asserts the current step in the checkout progress block. * * @param string $expected * The expected value. */ protected function assertCheckoutProgressStep($expected) { $current_step = $this->getSession()->getPage()->find('css', '.checkout-progress--step__current')->getText(); $this->assertEquals($expected, $current_step); } }