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');