diff --git a/modules/checkout/commerce_checkout.module b/modules/checkout/commerce_checkout.module index 522ac151..8fc85015 100644 --- a/modules/checkout/commerce_checkout.module +++ b/modules/checkout/commerce_checkout.module @@ -43,6 +43,9 @@ function commerce_checkout_theme() { 'commerce_checkout_pane' => [ 'render element' => 'elements', ], + 'commerce_checkout_completion_registration' => [ + 'render element' => 'form', + ], ]; return $theme; diff --git a/modules/checkout/src/Event/CheckoutAccountCreateEvent.php b/modules/checkout/src/Event/CheckoutAccountCreateEvent.php new file mode 100644 index 00000000..c314f81b --- /dev/null +++ b/modules/checkout/src/Event/CheckoutAccountCreateEvent.php @@ -0,0 +1,110 @@ +account = $account; + $this->order = $order; + } + + /** + * Gets the created account. + * + * @return \Drupal\Core\Session\AccountInterface + * The account created during checkout. + */ + public function getAccount() { + return $this->account; + } + + /** + * Gets the checkout order. + * + * @return \Drupal\commerce_order\Entity\OrderInterface + * The checkout order. + */ + public function getOrder() { + return $this->order; + } + + /** + * Sets the redirect for redirecting after the account event has finished. + * + * @param string $route_name + * The name of the route. + * @param array $route_parameters + * (optional) An associative array of parameter names and values. + * @param array $options + * (optional) An associative array of additional options. See + * \Drupal\Core\Url for the available keys. + * + * @return $this + */ + public function setRedirect($route_name, array $route_parameters = [], array $options = []) { + $url = new Url($route_name, $route_parameters, $options); + return $this->setRedirectUrl($url); + } + + /** + * Sets the redirect URL for redirecting after the account event has finished. + * + * @param \Drupal\Core\Url $url + * The URL to redirect to. + * + * @return $this + */ + public function setRedirectUrl(Url $url) { + $this->redirect = $url; + return $this; + } + + /** + * Gets the value to use for redirecting after the account event has finished. + * + * @return \Drupal\Core\Url|null + * A redirect url, if set. Null otherwise. + */ + public function getRedirectUrl() { + return $this->redirect; + } + +} diff --git a/modules/checkout/src/Event/CheckoutEvents.php b/modules/checkout/src/Event/CheckoutEvents.php new file mode 100644 index 00000000..b766bd72 --- /dev/null +++ b/modules/checkout/src/Event/CheckoutEvents.php @@ -0,0 +1,19 @@ +credentialsCheckFlood = $credentials_check_flood; + $this->currentUser = $current_user; + $this->userAuth = $user_auth; + $this->clientIp = $request_stack->getCurrentRequest()->getClientIp(); + $this->eventDispatcher = $event_dispatcher; + $this->userStorage = $entity_type_manager->getStorage('user'); + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $checkout_flow, + $container->get('commerce.credentials_check_flood'), + $container->get('current_user'), + $container->get('entity_type.manager'), + $container->get('user.auth'), + $container->get('request_stack'), + $container->get('event_dispatcher'), + $container->get('messenger') + ); + } + + /** + * {@inheritdoc} + */ + public function isVisible() { + // Registering is only possible for anonymous users and this pane can only + // be shown at the end of checkout. Ensure that there is no user on the site + // with the same email address. + return $this->currentUser->isAnonymous() + && $this->order->getState()->value != 'draft' + && !$this->userStorage->loadByProperties(['mail' => $this->order->getEmail()]); + } + + /** + * {@inheritdoc} + */ + public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) { + $pane_form['register'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Account information'), + ]; + + $pane_form['register']['name'] = [ + '#type' => 'textfield', + '#title' => $this->t('Username'), + '#maxlength' => UserInterface::USERNAME_MAX_LENGTH, + '#description' => $this->t("Several special characters are allowed, including space, period (.), hyphen (-), apostrophe ('), underscore (_), and the @ sign."), + '#required' => FALSE, + '#attributes' => [ + 'class' => ['username'], + 'autocorrect' => 'off', + 'autocapitalize' => 'off', + 'spellcheck' => 'false', + ], + '#default_value' => '', + ]; + + $pane_form['register']['password'] = [ + '#type' => 'password_confirm', + '#size' => 60, + '#description' => $this->t('Provide a password for the new account.'), + '#required' => TRUE, + ]; + + $pane_form['register']['actions'] = ['#type' => 'actions']; + $pane_form['register']['actions']['register'] = [ + '#type' => 'submit', + '#value' => $this->t('Create my account'), + '#name' => 'commerce_checkout_completion_registration_submit', + ]; + + // Additional fields. + $pane_form['register']['fields'] = []; + $user = $this->userStorage->create([]); + $form_display = EntityFormDisplay::collectRenderDisplay($user, 'register'); + $form_display->buildForm($user, $pane_form['register']['fields'], $form_state); + + return [ + '#theme' => 'commerce_checkout_completion_registration', + 'form' => $pane_form, + ]; + } + + /** + * {@inheritdoc} + */ + public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { + // Validate the entity. This will ensure that the username and email are in + // the right format and not already taken. The pane should only appear for + // a non-existent email, but users can modify the email for their account. + $values = $form_state->getValue($pane_form['#parents']); + $account = $this->userStorage->create([ + 'pass' => $values['register']['password'], + 'mail' => $this->order->getEmail(), + 'name' => $values['register']['name'], + ]); + + if (!empty($pane_form['register']['fields'])) { + $form_display = EntityFormDisplay::collectRenderDisplay($account, 'register'); + $form_display->extractFormValues($account, $pane_form['register']['fields'], $form_state); + $form_display->validateFormValues($account, $pane_form['register']['fields'], $form_state); + } + + $form_state->setTemporaryValue('new_account', $account); + + $violations = $account->validate(); + foreach ($violations->getByFields(['name']) as $violation) { + list($field_name) = explode('.', $violation->getPropertyPath(), 2); + if (isset($values['fields'][$field_name])) { + $form_state->setError($pane_form['form']['register']['fields'][$field_name], $violation->getMessage()); + } + else { + $form_state->setError($pane_form['form']['register'][$field_name], $violation->getMessage()); + } + } + } + + /** + * {@inheritdoc} + */ + public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { + /** @var \Drupal\user\User $user */ + $user = $form_state->getTemporaryValue('new_account'); + $user->enforceIsNew(); + $user->activate(); + $user->save(); + + // Load the new user account. + /** @var \Drupal\user\UserInterface $account */ + $account = $this->userStorage->load($user->id()); + + user_login_finalize($account); + $this->messenger->addStatus($this->t('Registration successful. You are now logged in.')); + $this->order->setCustomer($account); + + // Add the billing profile to the user's address book. + $profile = $this->order->getBillingProfile(); + if ($profile) { + $profile->setOwner($account); + $profile->save(); + } + + // Normally advancing steps in the checkout automatically saves the order. + // Since this pane occurs on the last step, manual order saving is needed. + $this->order->save(); + + $this->credentialsCheckFlood->clearAccount($this->clientIp, $account->getAccountName()); + + // Notify other modules about the account creation. + $event = new CheckoutAccountCreateEvent($account, $this->order); + $this->eventDispatcher->dispatch(CheckoutEvents::ACCOUNT_CREATE, $event); + // Redirect the user to a different page, if a redirect has been set. + if ($url = $event->getRedirectUrl()) { + $form_state->setRedirectUrl($url); + } + } + +} diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Login.php b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Login.php index 5af18f32..76f0af3b 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutPane/Login.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutPane/Login.php @@ -233,7 +233,7 @@ class Login extends CheckoutPaneBase implements CheckoutPaneInterface, Container $pane_form['guest']['text'] = [ '#prefix' => '

', '#suffix' => '

', - '#markup' => $this->t('Proceed to checkout. You can optionally create an account at the end.'), + '#markup' => $this->isRegistrationPaneAvailable() ? $this->t('Proceed to checkout. You can optionally create an account at the end.') : $this->t('Proceed to checkout.'), ]; $pane_form['guest']['continue'] = [ '#type' => 'submit', @@ -292,7 +292,8 @@ class Login extends CheckoutPaneBase implements CheckoutPaneInterface, Container public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { $values = $form_state->getValue($pane_form['#parents']); $triggering_element = $form_state->getTriggeringElement(); - switch ($triggering_element['#op']) { + $trigger = !empty($triggering_element['#op']) ? $triggering_element['#op'] : 'continue'; + switch ($trigger) { case 'continue': return; @@ -376,7 +377,8 @@ class Login extends CheckoutPaneBase implements CheckoutPaneInterface, Container */ public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) { $triggering_element = $form_state->getTriggeringElement(); - switch ($triggering_element['#op']) { + $trigger = !empty($triggering_element['#op']) ? $triggering_element['#op'] : 'continue'; + switch ($trigger) { case 'continue': break; @@ -397,4 +399,16 @@ class Login extends CheckoutPaneBase implements CheckoutPaneInterface, Container ]); } + /** + * Checks if guests can register at the end of the process. + * + * @return bool + * TRUE if guests may create an account. + * FALSE otherwise. + */ + protected function isRegistrationPaneAvailable() { + $completion_registration_pane = $this->checkoutFlow->getPane('completion_registration'); + return $completion_registration_pane->getStepId() != '_disabled'; + } + } diff --git a/modules/checkout/templates/commerce-checkout-completion-registration.html.twig b/modules/checkout/templates/commerce-checkout-completion-registration.html.twig new file mode 100644 index 00000000..63997f52 --- /dev/null +++ b/modules/checkout/templates/commerce-checkout-completion-registration.html.twig @@ -0,0 +1,20 @@ +{# +/** + * @file + * A layout for the checkout registration form + * + * Available variables: + * - form: The form. + * + * @ingroup themeable + */ +#} +
+
+

{%trans%}Create an account?{%endtrans%}

+

{%trans%}Complete your account registration now to be able to access your order information at any time.{%endtrans%}

+
+
+ {{ form }} +
+
diff --git a/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.info.yml b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.info.yml new file mode 100644 index 00000000..425ebcda --- /dev/null +++ b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.info.yml @@ -0,0 +1,5 @@ +name: Commerce Checkout Account Create Event Test +type: module +description: 'Helper module for testing creating an account after checkout.' +package: Testing +core: 8.x diff --git a/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.services.yml b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.services.yml new file mode 100644 index 00000000..9671250f --- /dev/null +++ b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/commerce_checkout_account_create_event_test.services.yml @@ -0,0 +1,5 @@ +services: + commerce_checkout_account_create_event_test.account_create: + class: Drupal\commerce_checkout_account_create_event_test\EventSubscriber\AccountCreate + tags: + - {name: event_subscriber} diff --git a/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/src/EventSubscriber/AccountCreate.php b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/src/EventSubscriber/AccountCreate.php new file mode 100644 index 00000000..ecba5fd3 --- /dev/null +++ b/modules/checkout/tests/modules/commerce_checkout_account_create_event_test/src/EventSubscriber/AccountCreate.php @@ -0,0 +1,38 @@ +getAccount(); + + // Set a redirect to the user edit page. + $event->setRedirect('entity.user.edit_form', [ + 'user' => $account->id(), + ]); + } + +} diff --git a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php index 22cb2539..dce7535d 100644 --- a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php +++ b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\commerce_checkout\Functional; +use Drupal\Core\Url; use Drupal\Tests\commerce\Functional\CommerceBrowserTestBase; /** @@ -80,7 +81,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { */ public function testCacheMetadata() { $this->drupalLogout(); - $this->drupalGet($this->product->toUrl()->toString()); + $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); @@ -135,7 +136,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { */ public function testGuestOrderCheckout() { $this->drupalLogout(); - $this->drupalGet($this->product->toUrl()->toString()); + $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); @@ -165,7 +166,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $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->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); @@ -203,7 +204,9 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { } /** - * Tests that you can register from the checkout pane. + * Tests that you can register from the login checkout pane. + * + * This checkout pane usually appears on the "login" step. */ public function testRegisterOrderCheckout() { $config = \Drupal::configFactory()->getEditable('commerce_checkout.commerce_checkout_flow.default'); @@ -212,7 +215,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $config->save(); $this->drupalLogout(); - $this->drupalGet($this->product->toUrl()->toString()); + $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); @@ -228,7 +231,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { // Test account validation. $this->drupalLogout(); - $this->drupalGet($this->product->toUrl()->toString()); + $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $cart_link = $this->getSession()->getPage()->findLink('your cart'); $cart_link->click(); @@ -284,11 +287,206 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->assertSession()->pageTextContains('The username User name is already taken.'); } + /** + * Tests that you can register after completing the order as a guest. + */ + public function testRegistrationAfterGuestOrderCheckout() { + // Enable the completion_registration pane. + /** @var \Drupal\commerce_checkout\Entity\CheckoutFlowInterface $checkout_flow */ + $checkout_flow = $this->container + ->get('entity_type.manager') + ->getStorage('commerce_checkout_flow') + ->load('default'); + /** @var \Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface $checkout_flow_plugin */ + $checkout_flow_plugin = $checkout_flow->getPlugin(); + /** @var \Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CompletionRegistration $pane */ + $pane = $checkout_flow_plugin->getPane('completion_registration'); + $pane->setConfiguration([]); + $pane->setStepId('complete'); + $checkout_flow_plugin_configuration = $checkout_flow_plugin->getConfiguration(); + $checkout_flow_plugin_configuration['panes']['completion_registration'] = $pane->getConfiguration(); + $checkout_flow_plugin->setConfiguration($checkout_flow_plugin_configuration); + $checkout_flow->save(); + + $this->drupalLogout(); + $this->drupalGet($this->product->toUrl()); + $this->submitForm([], 'Add to cart'); + $cart_link = $this->getSession()->getPage()->findLink('your cart'); + $cart_link->click(); + $this->submitForm([], 'Checkout'); + + // Checkout as guest. + $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.'); + + // Assert that the completion_registration checkout pane is shown. + $this->assertSession()->pageTextContains('Create an account?'); + // Register. + $this->submitForm([ + 'completion_registration[register][name]' => 'User name', + 'completion_registration[register][password][pass1]' => 'pass', + 'completion_registration[register][password][pass2]' => 'pass', + ], 'Create my account'); + // Assert that the account was created successfully. + $this->assertSession()->pageTextContains('Registration successful. You are now logged in.'); + + // Log out and try to login again with the chosen password. + $this->drupalLogout(); + $accounts = \Drupal::service('entity_type.manager')->getStorage('user')->loadByProperties(['mail' => 'guest@example.com']); + $account = reset($accounts); + $account->passRaw = 'pass'; + $this->drupalLogin($account); + + // Checkout again as guest to test account validation. + $this->drupalLogout(); + $this->drupalGet($this->product->toUrl()); + $this->submitForm([], 'Add to cart'); + $cart_link = $this->getSession()->getPage()->findLink('your cart'); + $cart_link->click(); + $this->submitForm([], 'Checkout'); + $this->assertCheckoutProgressStep('Login'); + $this->submitForm([], 'Continue as Guest'); + $this->assertCheckoutProgressStep('Order information'); + $this->submitForm([ + 'contact_information[email]' => 'guest2@example.com', + 'contact_information[email_confirm]' => 'guest2@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 2. You can view your order on your account page when logged in.'); + + $this->submitForm([ + 'completion_registration[register][name]' => '', + 'completion_registration[register][password][pass1]' => 'pass', + 'completion_registration[register][password][pass2]' => 'pass', + ], 'Create my account'); + $this->assertSession()->pageTextContains('You must enter a username.'); + + $this->submitForm([ + 'completion_registration[register][name]' => 'User name', + 'completion_registration[register][password][pass1]' => '', + 'completion_registration[register][password][pass2]' => '', + ], 'Create my account'); + $this->assertSession()->pageTextContains('Password field is required.'); + + $this->submitForm([ + 'completion_registration[register][name]' => 'User @#.``^ รน % name invalid', + 'completion_registration[register][password][pass1]' => 'pass', + 'completion_registration[register][password][pass2]' => 'pass', + ], 'Create my account'); + $this->assertSession()->pageTextContains('The username contains an illegal character.'); + + $this->submitForm([ + 'completion_registration[register][name]' => 'User name', + 'completion_registration[register][password][pass1]' => 'pass', + 'completion_registration[register][password][pass2]' => 'pass', + ], 'Create my account'); + $this->assertSession()->pageTextContains('The username User name is already taken.'); + } + + /** + * Tests that you can get redirected after registering at the end of checkout. + */ + public function testRedirectAfterRegistrationOnCheckout() { + // Enable the test module 'commerce_checkout_account_create_event_test'. + $this->container + ->get('module_installer') + ->install(['commerce_checkout_account_create_event_test']); + + // Enable the completion_registration pane. + /** @var \Drupal\commerce_checkout\Entity\CheckoutFlowInterface $checkout_flow */ + $checkout_flow = $this->container + ->get('entity_type.manager') + ->getStorage('commerce_checkout_flow') + ->load('default'); + /** @var \Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface $checkout_flow_plugin */ + $checkout_flow_plugin = $checkout_flow->getPlugin(); + /** @var \Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CompletionRegistration $pane */ + $pane = $checkout_flow_plugin->getPane('completion_registration'); + $pane->setConfiguration([]); + $pane->setStepId('complete'); + $checkout_flow_plugin_configuration = $checkout_flow_plugin->getConfiguration(); + $checkout_flow_plugin_configuration['panes']['completion_registration'] = $pane->getConfiguration(); + $checkout_flow_plugin->setConfiguration($checkout_flow_plugin_configuration); + $checkout_flow->save(); + + $this->drupalLogout(); + $this->drupalGet($this->product->toUrl()); + $this->submitForm([], 'Add to cart'); + $cart_link = $this->getSession()->getPage()->findLink('your cart'); + $cart_link->click(); + $this->submitForm([], 'Checkout'); + + // Checkout as guest. + $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.'); + + // Assert that the completion_registration checkout pane is shown. + $this->assertSession()->pageTextContains('Create an account?'); + // Register. + $this->submitForm([ + 'completion_registration[register][name]' => 'User name', + 'completion_registration[register][password][pass1]' => 'pass', + 'completion_registration[register][password][pass2]' => 'pass', + ], 'Create my account'); + // Assert that the account was created successfully. + $this->assertSession()->pageTextContains('Registration successful. You are now logged in.'); + + // Assert that a redirect had taken place. + $this->assertUrl(Url::fromRoute('entity.user.edit_form', ['user' => 3], ['absolute' => TRUE])); + } + /** * Tests checkout behaviour after a cart update. */ public function testCheckoutFlowOnCartUpdate() { - $this->drupalGet($this->product->toUrl()->toString()); + $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $this->getSession()->getPage()->findLink('your cart')->click(); // Submit the form until review. @@ -325,7 +523,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { 'stores' => [$this->store], ]); // Adding a new product to the cart resets the checkout step. - $this->drupalGet($product2->toUrl()->toString()); + $this->drupalGet($product2->toUrl()); $this->submitForm([], 'Add to cart'); $this->getSession()->getPage()->findLink('your cart')->click(); $this->submitForm([], 'Checkout');