You are here

uc_addresses.checkout.test in Ubercart Addresses 6.2

Same filename and directory in other branches
  1. 7 tests/uc_addresses.checkout.test

Test cases for checkout.

File

tests/uc_addresses.checkout.test
View source
<?php

/**
 * @file
 * Test cases for checkout.
 */

// Ensure UcAddressesTestCase is available.
require_once 'UcAddressesTestCase.test';

// Ensure UbercartCartCheckoutTestCase is available.
module_load_include('test', 'uc_cart', 'uc_cart');

/**
 * Test cases for checkout.
 */
class UcAddressesCartCheckoutTestCase extends UbercartCartCheckoutTestCase {

  /**
   * Describes this test.
   *
   * @return array
   */
  public static function getInfo() {
    return array(
      'name' => 'Cart and checkout',
      'description' => 'Ensures the cart and checkout process is functioning when Ubercart Addresses is enabled.',
      'group' => 'Ubercart Addresses',
      'dependencies' => array(
        'ctools',
        'token',
        'uc_store',
        'uc_cart',
      ),
    );
  }

  /**
   * Setup modules.
   */
  public function setUp() {
    parent::setUp();

    // Install Ubercart Addresses and flush schema cache.
    drupal_install_modules(array(
      'ctools',
      'uc_addresses',
    ));
    drupal_get_schema(NULL, TRUE);

    // Reset permissions so that Ubercart Addresses permissions are available.
    $this
      ->checkPermissions(array(), TRUE);
  }

  // -----------------------------------------------------------------------------
  // Overrides of methods in UbercartCartCheckoutTestCase from uc_cart.
  // -----------------------------------------------------------------------------

  /**
   * Override of UbercartTestHelper::checkout().
   *
   * @return object
   *   An Ubercart order object, if checkout succeeded.
   *   False otherwise.
   */
  function checkout($edit = array()) {
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Build the panes.
    $edit += $this
      ->populateCheckoutForm();

    // Submit the checkout page.
    $this
      ->drupalPost('cart/checkout', $edit, t('Review order'));
    $this
      ->assertRaw(t('Your order is almost complete.'));

    // Complete the review page.
    $this
      ->drupalPost(NULL, array(), t('Submit order'));
    $order_id = db_result(db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = '%s'", $edit['panes[delivery][delivery][delivery_first_name]']));
    if ($order_id) {
      $this
        ->pass(t('Order %order_id has been created', array(
        '%order_id' => $order_id,
      )));
      $order = uc_order_load($order_id);
    }
    else {
      $this
        ->fail(t('An order was created.'));
      $order = FALSE;
    }
    return $order;
  }

  /**
   * Populates the checkout form.
   *
   * With Ubercart Addresses, address fields on checkout have a bit different name.
   * Example:
   * Instead of "panes[delivery][delivery_first_name]",
   * Ubercart Addresses uses "panes[delivery][delivery][delivery_first_name]".
   * This is done to fix issues with the zone field.
   *
   * @param array $edit
   *   The form-values array to which to add required fields.
   * @param array $address_panes
   *   (optional) The address panes to populate.
   *   Defaults to both billing and delivery pane.
   */
  function populateCheckoutForm($edit = array(), $address_panes = array(
    'billing',
    'delivery',
  )) {
    foreach ($address_panes as $pane) {
      $prefix = 'panes[' . $pane . '][' . $pane . '][' . $pane;
      $key = $prefix . '_country]';
      $country = empty($edit[$key]) ? variable_get('uc_store_country', 840) : $edit[$key];
      $zone_id = db_result(db_query('SELECT zone_id FROM {uc_zones} WHERE zone_country_id = %d ORDER BY rand()', variable_get('uc_store_country', $country)));
      $edit += array(
        $prefix . '_first_name]' => $this
          ->randomName(10),
        $prefix . '_last_name]' => $this
          ->randomName(10),
        $prefix . '_street1]' => $this
          ->randomName(10),
        $prefix . '_city]' => $this
          ->randomName(10),
        $prefix . '_zone]' => $zone_id,
        $prefix . '_postal_code]' => mt_rand(10000, 99999),
      );
    }

    // If the email address has not been set, and the user has not logged in,
    // add a primary email address.
    if (!isset($edit['panes[customer][primary_email]']) && !$this->loggedInUser) {
      $edit['panes[customer][primary_email]'] = $this
        ->randomName(8) . '@example.com';
    }
    return $edit;
  }

  // -----------------------------------------------------------------------------
  // Ubercart Addresses own tests.
  // -----------------------------------------------------------------------------

  /**
   * Test if the address fields are prefilled with the customer's
   * default addresses.
   *
   * @see doDefaultAddressesTests()
   * @see checkCheckoutAddressFields()
   */
  public function testDefaultAddresses() {

    // Create an user with edit address privileges.
    $this->customer = $this
      ->drupalCreateUser(array(
      'add/edit own addresses',
      'delete own addresses',
    ));

    // Create a default shipping and a default billing address for this user.
    $addressBook = UcAddressesAddressBook::get($this->customer->uid);
    $address_types = uc_addresses_address_types();
    foreach ($address_types as $address_type) {
      $address = $addressBook
        ->addAddress();
      $values = UcAddressesTestCase::getEditAddressValues(array(), array(), 'address_form');
      $address
        ->setMultipleFields($values['values']);
      $address
        ->setAsDefault($address_type);
      $address
        ->save();
    }

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

    // Check if address fields are prefilled with values from the default addresses.
    $this
      ->doDefaultAddressesTests($this->customer);

    // Now, turn off the option to prefill the billing address and check again.
    variable_set('uc_addresses_default_shipping_address', TRUE);
    variable_set('uc_addresses_default_billing_address', FALSE);
    $this
      ->doDefaultAddressesTests($this->customer);

    // Reverse, don't fill in a default for the delivery address, but do
    // so for the billing address.
    variable_set('uc_addresses_default_shipping_address', FALSE);
    variable_set('uc_addresses_default_billing_address', TRUE);
    $this
      ->doDefaultAddressesTests($this->customer);

    // Now turn off both and check again.
    variable_set('uc_addresses_default_shipping_address', FALSE);
    variable_set('uc_addresses_default_billing_address', FALSE);
    $this
      ->doDefaultAddressesTests($this->customer);
  }

  /**
   * Checkout with the default addresses.
   *
   * Helper method for testDefaultAddresses().
   *
   * @param object $account
   *   The user that's currently logged in.
   *
   * @see testDefaultAddresses()
   * @see checkCheckoutAddressFields()
   */
  protected function doDefaultAddressesTests($account) {

    // Load default addresses for this user.
    $address_types = uc_addresses_address_types();
    $addresses = array();
    foreach ($address_types as $address_type) {
      $address = UcAddressesAddressBook::get($account->uid)
        ->getDefaultAddress($address_type);
      if ($address instanceof UcAddressesAddress) {
        $addresses[$address_type] = $address;
      }
      else {
        $addresses[$address_type] = UcAddressesAddressBook::newAddress();
      }
    }

    // Create an empty address too.
    $empty_address = UcAddressesAddressBook::newAddress();

    // Initialize values for checkout form.
    $edit = array();

    // Initialize array for newly added addresses.
    $new_addresses = array();

    // Clear out the static variable in form_clean_id().
    form_clean_id(NULL, TRUE);

    // Place item in cart.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));

    // Continue to checkout.
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Check if the address form is prefilled with the default addresses
    // according to the settings.
    foreach ($address_types as $address_type) {
      $order_address_type = $address_type;
      if ($address_type == 'shipping') {
        $order_address_type = 'delivery';
      }
      if (variable_get('uc_addresses_default_' . $address_type . '_address', TRUE)) {
        $this
          ->checkCheckoutAddressFields($order_address_type, $addresses[$address_type]);
      }
      else {
        $this
          ->checkCheckoutAddressFields($order_address_type, $empty_address);
        $values = UcAddressesTestCase::getEditAddressValues(array(
          'panes',
          $order_address_type,
          $order_address_type,
        ), array(), 'checkout_form', $order_address_type . '_');
        $edit += $values['form_values'];
        $new_addresses[$order_address_type] = $values['values'];
      }
    }

    // And checkout.
    $this
      ->drupalPost(NULL, $edit, t('Review order'));
    $messages = uc_cart_uc_message();
    $this
      ->assertText($messages['review_instructions']);
    $this
      ->drupalPost(NULL, array(), t('Submit order'));

    // Check if any new addresses got saved.
    foreach ($new_addresses as $address_type => $address_values) {
      $message = '';
      switch ($address_type) {
        case 'delivery':
          $message = t('The delivery address is correctly saved to the database.');
          break;
        case 'billing':
          $message = t('The billing address is correctly saved to the database.');
          break;
      }
      $this
        ->assertTrue(UcAddressesTestCase::checkAddressValuesInDatabase($address_values), $message);
    }
  }

  /**
   * Checks values on checkout form for given address and type.
   *
   * @param string $order_address_type
   *   The type of address on the checkout form the check values for:
   *   delivery or billing.
   * @param UcAddressesAddress $address
   *   The address to check values against.
   */
  protected function checkCheckoutAddressFields($order_address_type, $address) {
    $handlers = uc_addresses_get_address_field_handler_instances($address, 'checkout_form');
    foreach ($handlers as $fieldname => $handler) {
      if ($handler
        ->checkContext()) {
        $field_id = 'edit-panes-' . $order_address_type . '-' . $order_address_type . '-' . $order_address_type . '-' . $fieldname;
        $field_id = form_clean_id($field_id);
        $value = $address
          ->getField($fieldname);
        $message_variables = array(
          '@address_type' => $order_address_type,
          '%field' => $handler
            ->getFieldTitle(),
          '%value' => $value,
        );
        if (empty($value)) {
          $message = t('The @address_type field %field is empty.', $message_variables);
        }
        else {
          $message = t('The @address_type field %field contains %value.', $message_variables);
        }
        $this
          ->assertFieldById($field_id, $value, $message);
      }
    }
  }

  /**
   * Test if double addresses are not saved when checking out.
   */
  public function testDoubleAddresses() {

    // Create an user with edit address privileges.
    $this->customer = $this
      ->drupalCreateUser(array(
      'add/edit own addresses',
      'delete own addresses',
    ));

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

    // Place item in cart.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));

    // Continue to checkout.
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Fill in the same address in both the delivery and billing pane.
    $edit = array();
    $delivery_values = UcAddressesTestCase::getEditAddressValues(array(
      'panes',
      'delivery',
      'delivery',
    ), array(), 'checkout_form', 'delivery_');
    $billing_values = UcAddressesTestCase::getEditAddressValues(array(
      'panes',
      'billing',
      'billing',
    ), $delivery_values['values'], 'checkout_form', 'billing_');
    $edit += $delivery_values['form_values'];
    $edit += $billing_values['form_values'];

    // And checkout.
    $this
      ->checkout($edit);

    // Check that only one address is saved for the customer.
    $result = db_query('SELECT COUNT(aid) FROM {uc_addresses} WHERE uid = %d', $this->customer->uid);
    $count = (int) db_result($result);
    $this
      ->assertTrue($count === 1, t('The customer has @number addresses. (Actual: @count)', array(
      '@number' => 1,
      '@count' => $count,
    )));

    // Checkout with the default addresses filled and verify that the customer still has only one address.
    $edit = array();
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), 'Checkout');
    $this
      ->drupalPost(NULL, $edit, t('Review order'));
    $messages = uc_cart_uc_message();
    $this
      ->assertText($messages['review_instructions']);
    $this
      ->drupalPost(NULL, array(), t('Submit order'));
    $result = db_query('SELECT COUNT(aid) FROM {uc_addresses} WHERE uid = %d', $this->customer->uid);
    $count = (int) db_result($result);
    $this
      ->assertTrue($count === 1, t('The customer has @number addresses. (Actual: @count)', array(
      '@number' => 1,
      '@count' => $count,
    )));

    // Checkout again, but now with a different billing address.
    // The customer should have two addresses now.
    $edit = array();
    $billing_values = UcAddressesTestCase::getEditAddressValues(array(
      'panes',
      'billing',
      'billing',
    ), array(), 'checkout_form', 'billing_');
    $edit += $delivery_values['form_values'];
    $edit += $billing_values['form_values'];
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout($edit);
    $result = db_query('SELECT COUNT(aid) FROM {uc_addresses} WHERE uid = %d', $this->customer->uid);
    $count = (int) db_result($result);
    $this
      ->assertTrue($count === 2, t('The customer has @number addresses. (Actual: @count)', array(
      '@number' => 2,
      '@count' => $count,
    )));
  }

  /**
   * Test if checkout works when customer has previous placed
   * orders, but no addresses in the address book.
   */
  public function testCheckoutWithPreviousOrders() {

    // Create an order for the customer first.
    $order_data = array(
      'uid' => $this->customer->uid,
    );
    $delivery_values = UcAddressesTestCase::getEditAddressValues(array(), array(), 'order_form', 'delivery_');
    $billing_values = UcAddressesTestCase::getEditAddressValues(array(), array(), 'order_form', 'billing_');
    $order_data += $delivery_values['form_values'];
    $order_data += $billing_values['form_values'];
    $order = $this
      ->createOrder($order_data);
    uc_cart_complete_sale($order, TRUE);
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);

    // Ensure an order was created for the customer.
    $result = db_query("SELECT COUNT(order_id) FROM {uc_orders} WHERE uid = %d AND order_status IN " . uc_order_status_list('general', TRUE), $this->customer->uid);
    $count = (int) db_result($result);
    $this
      ->assertTrue($count === 1, 'An order was created.');

    // Now go to checkout as customer.
    $this
      ->drupalLogin($this->customer);
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Fill in the checkout form, choose the first available address from the
    // address book.
    // Omit filling in "last name" for the billing address to ensure checkout
    // will succeed if there were form errors the first time.
    $edit = array();
    foreach (uc_addresses_order_address_types() as $address_type) {

      // Ensure the customer can choose an address for this address type.
      $field_id = 'edit-panes-' . $address_type . '-' . $address_type . '-' . $address_type . '-addressbook';
      $this
        ->assertFieldById($field_id);

      // Get address book option to choose.
      $fields = $this
        ->xpath($this
        ->constructFieldXpath('id', $field_id));
      $field = reset($fields);
      $options = $this
        ->getAllOptions($field);
      $edit['panes[' . $address_type . '][' . $address_type . '][' . $address_type . '_addressbook]'] = (string) $options[1]
        ->attributes()->value;
    }
    $delivery_values = UcAddressesTestCase::getEditAddressValues(array(
      'panes',
      'delivery',
      'delivery',
    ), array(), 'checkout_form', 'delivery_');
    $billing_values = UcAddressesTestCase::getEditAddressValues(array(
      'panes',
      'billing',
      'billing',
    ), $delivery_values['values'], 'checkout_form', 'billing_');
    $edit += $delivery_values['form_values'];
    $edit += $billing_values['form_values'];
    unset($edit['panes[billing][billing][billing_last_name]']);
    $this
      ->drupalPost(NULL, $edit, t('Review order'));

    // Ensure there was at least one form error.
    $this
      ->assertText(t('!name field is required.', array(
      '!name' => t('Last name'),
    )));

    // Now fix the form errors and try to checkout again.
    $edit = array();
    $edit['panes[billing][billing][billing_last_name]'] = 'custom last name';
    $this
      ->drupalPost(NULL, $edit, t('Review order'));
    $messages = uc_cart_uc_message();
    $this
      ->assertText($messages['review_instructions']);
    $this
      ->drupalPost(NULL, array(), t('Submit order'));
  }

  /**
   * Tests if a customer can checkout when not providing a mail address.
   */
  function testAnonymousCheckoutWithoutMailAddress() {

    // Disable the Customer information pane.
    variable_set('uc_pane_customer_enabled', FALSE);

    // Place item in cart.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));

    // Continue to checkout.
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Populate checkout form, but omit filling mail address.
    $edit = $this
      ->populateCheckoutForm();
    unset($edit['panes[customer][primary_email]']);

    // And checkout.
    $this
      ->drupalPost(NULL, $edit, t('Review order'));
    $this
      ->assertRaw(t('Your order is almost complete.'));
    $this
      ->drupalPost(NULL, array(), t('Submit order'));

    // Check if an order has been created.
    $order_id = db_result(db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = '%s'", $edit['panes[delivery][delivery][delivery_first_name]']));
    if ($order_id) {
      $this
        ->pass(t('Order %order_id has been created', array(
        '%order_id' => $order_id,
      )));
    }
    else {
      $this
        ->fail(t('An order was created.'));
    }
  }

}

Classes

Namesort descending Description
UcAddressesCartCheckoutTestCase Test cases for checkout.