You are here

commerce_checkout.test in Commerce Core 7

Functional tests for the commerce checkout module.

File

modules/checkout/tests/commerce_checkout.test
View source
<?php

/**
 * @file
 * Functional tests for the commerce checkout module.
 */

/**
 * Test checkout process.
 */
class CommerceCheckoutTestProcess extends CommerceBaseTestCase {

  /**
   * Order object.
   */
  protected $order;

  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Checkout process',
      'description' => 'Test the entire checkout process. Including anonymous checkout and checkout panes functionality.',
      'group' => 'Drupal Commerce',
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    $modules = parent::setUpHelper('all');
    parent::setUp($modules);

    // User creation for different operations.
    $this->site_admin = $this
      ->createSiteAdmin();
    $this->store_admin = $this
      ->createStoreAdmin();
    $this->store_customer = $this
      ->createStoreCustomer();

    // The rule that sends a mail after checkout completion should be disabled
    //  as it returns an error caused by how mail messages are stored.
    $rules_config = rules_config_load('commerce_checkout_order_email');
    $rules_config->active = FALSE;
    $rules_config
      ->save();
  }

  /**
   * Helper function to prepare an anonymous enviroment, it sets the user,
   *  products and prepares a cart.
   */
  protected function prepareAnonymousEnviroment() {

    // Login as admin user to grant permissions.
    $this
      ->drupalLogin($this->site_admin);
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
      'access checkout' => TRUE,
    ));

    // Create a dummy product display content type.
    $this
      ->createDummyProductDisplayContentType();

    // Create dummy product display nodes (and their corresponding product
    //  entities).
    $sku = 'PROD-01';
    $product_name = 'Product One';
    $this->product = $this
      ->createDummyProduct($sku, $product_name);
    $this->product_node = $this
      ->createDummyProductNode(array(
      $this->product->product_id,
    ), $product_name);

    // Logout to test the checkout process with anonymous user.
    $this
      ->drupalLogout();

    // Override user variable to get the enviroment fully set.
    global $user;
    $user = user_load(0);

    // Submit the add to cart form.
    $this
      ->drupalPost('node/' . $this->product_node->nid, array(), t('Add to cart'));

    // Get the order for the anonymous user.
    $orders = commerce_order_load_multiple(array(), array(
      'uid' => $user->uid,
      'status' => 'cart',
    ), TRUE);
    $this->order = reset($orders);

    // Reset the cache as we don't want to keep the lock.
    entity_get_controller('commerce_order')
      ->resetCache();
  }

  /**
   * Test changing the weight and page of a pane.
   */
  public function testCommerceCheckoutPanesForm() {

    // Log in as store customer.
    $this
      ->drupalLogin($this->store_customer);

    // Access to the config page for checkout forms
    $this
      ->drupalGet('admin/commerce/config/checkout/form');
    $this
      ->assertResponse(403, t('A normal user is not able to access to the checkout configuration form page.'));

    // Log in as store admin.
    $this
      ->drupalLogin($this->store_admin);

    // Access to the config page for checkout forms.
    $this
      ->drupalGet('admin/commerce/config/checkout/form');
    $this
      ->assertResponse(200, t('Store admin can access to the checkout configuration form page.'));

    // Modify weight of the panes
    $this
      ->drupalPost('admin/commerce/config/checkout/form', array(
      'panes[cart_contents][weight]' => 1,
    ), t('Save configuration'));
    $this
      ->assertOptionSelected('edit-panes-cart-contents-weight', 1, t('Pane weight changed'));

    // Change one pane to other page
    $this
      ->drupalPost('admin/commerce/config/checkout/form', array(
      'panes[checkout_review][page]' => 'disabled',
    ), t('Save configuration'));
    $this
      ->assertOptionSelected('edit-panes-checkout-review-page', 'disabled', t('Pane page changed'));
  }

  /**
   * Test the checkout process using an authenticated user.
   */
  public function testCommerceCheckoutProcessAuthenticatedUser() {

    // Log in as normal user.
    $this
      ->drupalLogin($this->store_customer);

    // Order creation, in cart status.
    $this->order = $this
      ->createDummyOrder($this->store_customer->uid);

    // Access to checkout page.
    $this
      ->drupalGet($this
      ->getCommerceUrl('checkout'));

    // Check if the page resolves and if the default panes are present.
    $this
      ->assertResponse(200, t('The owner of the order can access to the checkout page'));
    $this
      ->assertTitle(t('Checkout') . ' | Drupal', t('Title of the checkout phase is correct'));
    $this
      ->assertText(t('Shopping cart contents'), t('Shopping cart contents pane is present'));
    $this
      ->assertText(t('Billing information'), t('Billing information pane is present'));

    // We are testing with authenticated user, so no account information
    // should appear.
    $this
      ->assertNoText(t('Account information'), t('Account information pane is not present'));

    // Generate random information, as city, postal code, etc.
    $address_info = $this
      ->generateAddressInformation();

    // Fill in the billing address information.
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Check if the country has been selected correctly, this uses XPath as the
    //  ajax call replaces the element and the id may change.
    $this
      ->assertFieldByXPath("//select[starts-with(@id, 'edit-customer-profile-billing-commerce-customer-address')]//option[@selected='selected']", 'US', t('Country selected'));

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // Check for default panes and information in this checkout phase.
    $this
      ->pass(t('Checking the default panes and the page information:'));
    $this
      ->assertTitle(t('Review order') . ' | Drupal', t('Title of the checkout phase \'Review order\' is correct'));
    $this
      ->assertText($address_info['name_line'], t('Billing information for \'name_line\' is correct'));
    $this
      ->assertText($address_info['thoroughfare'], t('Billing information for \'thoroughfare\' is correct'));
    $this
      ->assertText($address_info['locality'], t('Billing information for \'locality\' is correct'));
    $this
      ->assertText(trim($address_info['postal_code']), t('Billing information for \'postal_code\' is correct'));
    $this
      ->assertText('United States', t('Billing information country is correct'));
    $this
      ->assertText('Example payment', t('Example payment method pane is present'));

    // Load the order to check the status.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Reset the cache as we don't want to keep the lock.
    entity_get_controller('commerce_order')
      ->resetCache();

    // At this point we should be in Checkout Review.
    $this
      ->assertEqual(reset($order)->status, 'checkout_review', t('Order status is \'Checkout Review\' in the review phase.'));

    // Test the back & continue buttons.
    $this
      ->drupalPost(NULL, array(), t('Go back'));
    $this
      ->assertTitle(t('Checkout') . ' | Drupal', t('When clicking in the \'Back\' button, the title displayed corresponds with the current checkout phase: \'Checkout\''));
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));
    $this
      ->assertTitle(t('Review order') . ' | Drupal', t('When clicking in the \'Continue\' button, the title displayed corresponds with the current checkout phase: \'Review order\''));

    // Finish checkout process
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // Reload the order directly from db to update status.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Order status should be pending when completing checkout process.
    $this
      ->assertEqual(reset($order)->status, 'pending', t('Order status is \'Pending\' after completing checkout'));

    // Check if the completion message has been displayed.
    $this
      ->assertTitle(t('Checkout complete') . ' | Drupal', t('Title of the page is \'Checkout complete\' when finishing the checkout process'));
    $this
      ->assertText(t('Your order number is @order-number.', array(
      '@order-number' => $this->order->order_number,
    )), t('Completion message for the checkout is correctly displayed'));
  }

  /**
   * Test the checkout validation panes with anonymous user.
   */
  public function testCommerceCheckoutValidatePanesAnonymousUser() {

    // Prepare the cart for Anonymous.
    $this
      ->prepareAnonymousEnviroment();

    // Access to checkout page.
    $this
      ->drupalGet($this
      ->getCommerceUrl('checkout'));

    // Test billing information and account information panes.
    $this
      ->assertText(t('Billing information'), t('Billing information pane is present in the checkout page'));
    $this
      ->assertText(t('Account information'), t('Account information pane is present in the checkout page'));

    // Test validation messages not filling any information.
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // Get all panes from the system to get their forms.
    $panes = commerce_checkout_panes();

    // Test the validation of Billing Information pane.
    $callback = commerce_checkout_pane_callback($panes['customer_profile_billing'], 'checkout_form');
    $pane_form = drupal_get_form($callback, $panes['customer_profile_billing'], $this->order);
    foreach (element_children($pane_form['commerce_customer_address'][LANGUAGE_NONE][0]) as $key) {
      $element = $pane_form['commerce_customer_address'][LANGUAGE_NONE][0][$key];
      if ($element['#required'] && empty($element['#default_value'])) {
        $this
          ->assertText(t('!pane_message field is required', array(
          '!pane_message' => $element['#title'],
        )), t('Check required billing information pane messages'));
      }
    }

    // Test the validation of Account pane.
    $callback = commerce_checkout_pane_callback($panes['account'], 'checkout_form');
    $pane_form = drupal_get_form($callback, $panes['account'], $this->order);
    foreach (element_children($pane_form['login']) as $key) {
      if ($pane_form['login'][$key]['#required']) {
        $this
          ->assertText(t('!pane_message field is required', array(
          '!pane_message' => $pane_form['login'][$key]['#title'],
        )), t('Check required account pane message.'));
      }
    }

    // Generate random information, as city name, postal code etc.
    $address_info = $this
      ->generateAddressInformation();

    // Also generate a not-valid mail address.
    $user_mail = $this
      ->randomName();

    // Fill in the billing address information
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );

    // Also add the mail for the account pane.
    $info += array(
      'account[login][mail]' => $user_mail,
    );

    // Go to the next checkout step with the required information.
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // Check if the wrong e-mail address fails validation.
    $this
      ->assertRaw(t('The e-mail address %mail is not valid.', array(
      '%mail' => $user_mail,
    )), t('A warning message is displayed when the e-mail address for the anonymous user is not valid'));

    // Fix it and continue to next step.
    $user_mail = $this
      ->randomName() . '@example.com';
    $info['account[login][mail]'] = $user_mail;
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));
    $this
      ->assertNoRaw(t('The e-mail address %mail is not valid.', array(
      '%mail' => $user_mail,
    )), t('A warning message is not displayed when the e-mail address for the anonymous user is valid'));

    // Finish checkout process for good.
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));
  }

  /**
   * Test the checkout process with anonymous user.
   */
  public function testCommerceCheckoutProcessAnonymousUser() {

    // Prepare the cart for Anonymous.
    $this
      ->prepareAnonymousEnviroment();

    // Access to checkout page.
    $this
      ->drupalGet($this
      ->getCommerceUrl('checkout'));

    // Check if the page resolves and if the default panes are present
    $this
      ->assertResponse(200, t('Anonymous user can access to the checkout page for the order.'));
    $this
      ->assertTitle(t('Checkout') . ' | Drupal', t('Title of the checkout phase is correct'));
    $this
      ->assertText(t('Shopping cart contents'), t('Shopping cart contents pane is present'));
    $this
      ->assertText(t('Billing information'), t('Billing information pane is present'));
    $this
      ->assertText(t('Account information'), t('Account information pane is present'));

    // Generate random information, as user mail, city, etc.
    $user_mail = $this
      ->randomName() . '@example.com';
    $address_info = $this
      ->generateAddressInformation();

    // Fill in the billing address information
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Check if the country has been selected correctly, this uses XPath as the
    //  ajax call replaces the element and the id may change
    $this
      ->assertFieldByXPath("//select[starts-with(@id, 'edit-customer-profile-billing-commerce-customer-address')]//option[@selected='selected']", 'US', t('Country selected'));

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );

    // Also add the mail for the account pane.
    $info += array(
      'account[login][mail]' => $user_mail,
    );

    // Go to the next checkout step with the required information.
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // Check for default panes and information in this checkout phase.
    $this
      ->pass(t('Checking the default panes and the page information:'));
    $this
      ->assertTitle(t('Review order') . ' | Drupal', t('Title of the checkout phase \'Review order\' is correct'));
    $this
      ->assertText($address_info['name_line'], t('Billing information for \'name_line\' is correct'));
    $this
      ->assertText($address_info['thoroughfare'], t('Billing information for \'thoroughfare\' is correct'));
    $this
      ->assertText($address_info['locality'], t('Billing information for \'locality\' is correct'));
    $this
      ->assertText(trim($address_info['postal_code']), t('Billing information for \'postal_code\' is correct'));
    $this
      ->assertText('United States', t('Billing information country is correct'));
    $this
      ->assertText('Example payment', t('Example payment method pane is present'));
    $this
      ->assertText($user_mail, t('Account information is correct'));

    // Load the order to check the status.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Reset the cache as we don't want to keep the lock.
    entity_get_controller('commerce_order')
      ->resetCache();

    // At this point we should be in Checkout Review.
    $this
      ->assertEqual(reset($order)->status, 'checkout_review', t('Order status is \'Checkout Review\' in the review phase.'));

    // Finish checkout process
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // Reload the order directly from db to check status.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Order status should be pending when completing checkout process.
    $this
      ->assertEqual(reset($order)->status, 'pending', t('Order status is \'Pending\' after completing checkout.'));

    // Check if the completion message has been displayed.
    $this
      ->assertTitle(t('Checkout complete') . ' | Drupal', t('Title of the page is \'Checkout complete\' when finishing the checkout process'));

    // Check completion message.
    $this
      ->assertText(t('Your order number is @order-number.', array(
      '@order-number' => $this->order->order_number,
    )), t('Completion message for the checkout is correctly displayed'));
  }

  /**
   * Test the checkout process with anonymous user using an e-mail address that
   * belongs to an existing user, the final result should be the order
   * assigned to the existing user.
   */
  public function testCommerceCheckoutProcessAnonymousExistingUser() {

    // Prepare the cart for Anonymous.
    $this
      ->prepareAnonymousEnviroment();

    // Access to checkout page.
    $this
      ->drupalGet($this
      ->getCommerceUrl('checkout'));

    // Generate random information.
    $address_info = $this
      ->generateAddressInformation();

    // Fill in the billing address information
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );

    // Also add the mail for the account pane.
    $info += array(
      'account[login][mail]' => $this->store_customer->mail,
    );

    // Go to the next checkout step with the required information.
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // Finish checkout process
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // Reload the order directly from db to check its owner.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Assert that the owner of the order is the owner of the e-mail address used.
    $this
      ->assertEqual($this->store_customer->uid, reset($order)->uid, t('The order has been correctly assigned to the user owner of the mail address'));
  }

  /**
   * Test the checkout process with anonymous user using an e-mail addres that
   * doesn't exists in the system, the final result is that the user gets the
   * account created and the order is assigned to that user.
   */
  public function testCommerceCheckoutProcessAnonymousNonExistingUser() {

    // Prepare the cart for Anonymous.
    $this
      ->prepareAnonymousEnviroment();

    // Access to checkout page.
    $this
      ->drupalGet($this
      ->getCommerceUrl('checkout'));

    // Generate random information, as user mail, city, etc.
    $user_mail = $this
      ->randomName() . '@example.com';
    $address_info = $this
      ->generateAddressInformation();

    // Fill in the billing address information
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );

    // Also add the mail for the account pane.
    $info += array(
      'account[login][mail]' => $user_mail,
    );

    // Go to the next checkout step with the required information.
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // Finish checkout process
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // Reload the order directly from db to check its owner.
    $order = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);

    // Check if the order completion triggered the user creation rule.
    $user = user_load(reset($order)->uid);
    $this
      ->assertEqual($user->mail, $user_mail, t('The e-mail address of the owner of the order matches the one in the checkout input'));
    $this
      ->assertTrue($this->store_customer->uid < $user->uid, t('User id of the new user is higher than the last user created then it is a new account'));
  }

  /**
   * Test order completion page access.
   */
  public function testCommerceCheckoutAccessOrder() {

    // Log in as normal user.
    $this
      ->drupalLogin($this->store_customer);

    // Create dummy product.
    $product = $this
      ->createDummyProduct('PROD-01', 'Product One');

    // Order creation, in complete status.
    $this->order = $this
      ->createDummyOrder($this->store_customer->uid, array(
      $product->product_id => 1,
    ), 'complete');

    // Access to the complete page, this one should be always accesible.
    $this
      ->assertCheckoutPageAccessible($this->order, 'complete');
  }
  public function assertCheckoutPageAccessible($order, $page) {
    $path = $this
      ->getCommerceUrl('checkout') . '/' . $order->order_id . ($page ? '/' . $page : '');
    $this
      ->drupalGet($path);
    return $this
      ->assertEqual($this
      ->getUrl(), url($path, array(
      'absolute' => TRUE,
    )), t('@page checkout page is accessible.', array(
      '@page' => $page,
    )));
  }
  public function assertCheckoutPageNotAccessible($order, $page) {
    $path = $this
      ->getCommerceUrl('checkout') . '/' . $order->order_id . ($page ? '/' . $page : '');
    $this
      ->drupalGet($path);
    return $this
      ->assertNotEqual($this
      ->getUrl(), url($path, array(
      'absolute' => TRUE,
    )), t('@page checkout page is not accessible.', array(
      '@page' => $page,
    )));
  }

  /**
   * Test order completion page access.
   */
  public function testCommerceCheckoutAccessPages() {

    // Log in as normal user.
    $this
      ->drupalLogin($this->store_customer);

    // Order creation, in cart status.
    $this->order = $this
      ->createDummyOrder($this->store_customer->uid);

    // At this point, the rest of checkout pages shouldn't be accessible.
    $this
      ->assertCheckoutPageAccessible($this->order, '');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'review');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'payment');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'complete');

    // Generate random information, as city, postal code, etc.
    $address_info = $this
      ->generateAddressInformation();

    // Fill in the billing address information
    $billing_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_billing[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $billing_pane[0]['name'] => 'US',
    ), (string) $billing_pane[0]['name']);

    // Check if the country has been selected correctly, this uses XPath as the
    //  ajax call replaces the element and the id may change
    $this
      ->assertFieldByXPath("//select[starts-with(@id, 'edit-customer-profile-billing-commerce-customer-address')]//option[@selected='selected']", 'US', t('Country selected'));

    // Fill in the required information for billing pane, with a random State.
    $info = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_billing[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_billing[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );
    $this
      ->drupalPost(NULL, $info, t('Continue to next step'));

    // At this point, only first page and review should be accessible, but the
    //  rest shouldn't.
    $this
      ->assertCheckoutPageAccessible($this->order, '');
    $this
      ->assertCheckoutPageAccessible($this->order, 'review');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'payment');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'complete');

    // Fill in the payment method and continue the process.
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

    // At this point, only the complete page should be accessible.
    $this
      ->assertCheckoutPageNotAccessible($this->order, '');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'review');
    $this
      ->assertCheckoutPageNotAccessible($this->order, 'payment');
    $this
      ->assertCheckoutPageAccessible($this->order, 'complete');
  }

  /**
   * Test programmatic checkout completion.
   */
  function testCommerceCheckoutProgrammaticCheckout() {

    // Log in as normal user.
    $this
      ->drupalLogin($this->store_customer);

    // Order creation, in cart status.
    $this->order = $this
      ->createDummyOrder($this->store_customer->uid);
    commerce_checkout_complete($this->order);

    // Ensure the "placed" property is set when the order completes checkout.
    $this
      ->assertTrue($this->order->placed > 0, 'commerce_checkout_complete() added the placed date to the order');

    // Ensure the "placed" property is not updated when the order completes
    // checkout more than once, such as when simulating checkout via the admin
    // pages.
    // If commerce_checkout_complete does not work as expected and does update
    // the value, we wouldn't know because in the context of this test it would
    // be set to REQUEST_TIME which is the current value as well. REQUEST_TIME
    // is a constant and we cannot change it either. We therefore manually set
    // the value to a different non-zero value and check if that value is
    // changed.
    $this->order->placed = 1;
    commerce_checkout_complete($this->order);
    $this
      ->assertEqual($this->order->placed, 1, 'commerce_checkout_complete() did not update the already placed date of the order');
  }

}

Classes

Namesort descending Description
CommerceCheckoutTestProcess Test checkout process.