You are here

uc_cart.test in Ubercart 7.3

Shopping cart and checkout tests.

File

uc_cart/tests/uc_cart.test
View source
<?php

/**
 * @file
 * Shopping cart and checkout tests.
 */

/**
 * Tests the cart and checkout functionality.
 */
class UbercartCartCheckoutTestCase extends UbercartTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Cart and checkout',
      'description' => 'Ensures the cart and checkout process is functioning for both anonymous and authenticated users.',
      'group' => 'Ubercart',
    );
  }

  /**
   * Overrides DrupalWebTestCase::setUp().
   */
  protected function setUp($modules = array(), $permissions = array()) {
    $modules = array(
      'uc_payment',
      'uc_payment_pack',
      'uc_roles',
    );
    $permissions = array(
      'administer permissions',
    );
    parent::setUp($modules, $permissions);
  }

  /**
   * Creates a new order.
   */
  protected function createOrder($fields = array()) {
    $order = uc_order_new();
    foreach ($fields as $key => $value) {
      $order->{$key} = $value;
    }
    if (empty($order->primary_email)) {
      $order->primary_email = $this
        ->randomString() . '@example.org';
    }
    if (!isset($fields['products'])) {
      $item = clone $this->product;
      $item->qty = 1;
      $item->price = $item->sell_price;
      $item->data = array();
      $order->products = array(
        $item,
      );
    }
    $order->order_total = uc_order_get_total($order, TRUE);
    $order->line_items = uc_order_load_line_items($order, TRUE);
    uc_order_save($order);
    return $order;
  }

  /**
   * Tests cart API.
   */
  public function testCartApi() {

    // Test the empty cart.
    $items = uc_cart_get_contents();
    $this
      ->assertEqual($items, array(), 'Cart is an empty array.');

    // Add an item to the cart.
    uc_cart_add_item($this->product->nid);
    $items = uc_cart_get_contents();
    $this
      ->assertEqual(count($items), 1, 'Cart contains one item.');
    $item = reset($items);
    $this
      ->assertEqual($item->nid, $this->product->nid, 'Cart item nid is correct.');
    $this
      ->assertEqual($item->qty, 1, 'Cart item quantity is correct.');

    // Add more of the same item.
    $qty = mt_rand(1, 100);
    uc_cart_add_item($this->product->nid, $qty);
    $items = uc_cart_get_contents();
    $this
      ->assertEqual(count($items), 1, 'Updated cart contains one item.');
    $item = reset($items);
    $this
      ->assertEqual($item->qty, $qty + 1, 'Updated cart item quantity is correct.');

    // Set the quantity and data.
    $qty = mt_rand(1, 100);
    $item->qty = $qty;
    $item->data['updated'] = TRUE;
    uc_cart_update_item($item);
    $items = uc_cart_get_contents();
    $item = reset($items);
    $this
      ->assertEqual($item->qty, $qty, 'Set cart item quantity is correct.');
    $this
      ->assertTrue($item->data['updated'], 'Set cart item data is correct.');

    // Add an item with different data to the cart.
    uc_cart_add_item($this->product->nid, 1, array(
      'test' => TRUE,
    ));
    $items = uc_cart_get_contents();
    $this
      ->assertEqual(count($items), 2, 'Updated cart contains two items.');

    // Remove the items.
    foreach ($items as $item) {
      uc_cart_remove_item($item->nid, NULL, $item->data);
    }

    // @todo Remove the need for this.
    uc_cart_get_contents(NULL, 'rebuild');
    $items = uc_cart_get_contents();
    $this
      ->assertEqual(count($items), 0, 'Cart is empty after removal.');

    // Empty the cart.
    uc_cart_add_item($this->product->nid);
    uc_cart_empty();
    $items = uc_cart_get_contents();
    $this
      ->assertEqual($items, array(), 'Cart is emptied correctly.');
  }

  /**
   * Tests basic cart functionality.
   */
  public function testCart() {
    module_enable(array(
      'uc_cart_entity_test',
    ));

    // Test the empty cart.
    $this
      ->drupalGet('cart');
    $this
      ->assertText('There are no products in your shopping cart.');

    // Add an item to the cart.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertText($this->product->title . ' added to your shopping cart.');
    $this
      ->assertText('hook_uc_cart_item_insert fired');

    // Test the cart page.
    $this
      ->drupalGet('cart');
    $this
      ->assertText($this->product->title, t('The product is in the cart.'));
    $this
      ->assertFieldByName('items[0][qty]', 1, t('The product quantity is 1.'));

    // Add the item again.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertText('Your item(s) have been updated.');
    $this
      ->assertText('hook_uc_cart_item_update fired');

    // Test the cart page again.
    $this
      ->drupalGet('cart');
    $this
      ->assertFieldByName('items[0][qty]', 2, t('The product quantity is 2.'));

    // Update the quantity.
    $qty = mt_rand(3, 100);
    $this
      ->drupalPost('cart', array(
      'items[0][qty]' => $qty,
    ), t('Update cart'));
    $this
      ->assertText('Your cart has been updated.');
    $this
      ->assertFieldByName('items[0][qty]', $qty, t('The product quantity was updated.'));
    $this
      ->assertText('hook_uc_cart_item_update fired');

    // Update the quantity to zero.
    $this
      ->drupalPost('cart', array(
      'items[0][qty]' => 0,
    ), t('Update cart'));
    $this
      ->assertText('Your cart has been updated.');
    $this
      ->assertText('There are no products in your shopping cart.');
    $this
      ->assertText('hook_uc_cart_item_delete fired');

    // Test the remove item button.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), t('Remove'));
    $this
      ->assertText($this->product->title . ' removed from your shopping cart.');
    $this
      ->assertText('There are no products in your shopping cart.');
    $this
      ->assertText('hook_uc_cart_item_delete fired');
  }

  /**
   * Tests that anonymous cart is merged into authenticated cart upon login.
   */
  public function testCartMerge() {

    // Add an item to the cart as an anonymous user.
    $this
      ->drupalLogin($this->customer);
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertText($this->product->title . ' added to your shopping cart.');
    $this
      ->drupalLogout();

    // Add an item to the cart as an anonymous user.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertText($this->product->title . ' added to your shopping cart.');

    // Log in and check the items are merged.
    $this
      ->drupalLogin($this->customer);
    $this
      ->drupalGet('cart');
    $this
      ->assertText($this->product->title, t('The product remains in the cart after logging in.'));
    $this
      ->assertFieldByName('items[0][qty]', 2, t('The product quantity is 2.'));
  }

  /**
   * Tests that cart automatically removes products that have been deleted.
   */
  public function testDeletedCartItem() {

    // Add a product to the cart, then delete the node.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    node_delete($this->product->nid);

    // Test that the cart is empty.
    $this
      ->drupalGet('cart');
    $this
      ->assertText('There are no products in your shopping cart.');
    $this
      ->assertEqual(uc_cart_get_total_qty(), 0, 'There are no items in the cart.');
  }

  /**
   * Tests Rule integration for uc_cart_maximum_product_qty reaction rule.
   */
  public function testMaximumQuantityRule() {

    // Enable the example maximum quantity rule.
    $rule = rules_config_load('uc_cart_maximum_product_qty');
    $rule->active = TRUE;
    $rule
      ->save();

    // Try to add more items than allowed to the cart.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(
      'items[0][qty]' => 11,
    ), t('Update cart'));

    // Test the restriction was applied.
    $this
      ->assertText('You are only allowed to order a maximum of 10 of ' . $this->product->title . '.');
    $this
      ->assertFieldByName('items[0][qty]', 10);
  }

  /**
   * Tests the checkout process.
   */
  public function testCheckout() {

    // Allow customer to specify username and password,
    // but don't log in after checkout.
    $settings = array(
      'uc_cart_new_account_name' => TRUE,
      'uc_cart_new_account_password' => TRUE,
      'uc_new_customer_login' => FALSE,
    );
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalPost('admin/store/settings/checkout', $settings, t('Save configuration'));
    $this
      ->drupalLogout();
    $new_user = new stdClass();
    $new_user->name = $this
      ->randomName(20);
    $new_user->pass_raw = $this
      ->randomName(20);

    // Test as anonymous user.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout(array(
      'panes[customer][new_account][name]' => $new_user->name,
      'panes[customer][new_account][pass]' => $new_user->pass_raw,
      'panes[customer][new_account][pass_confirm]' => $new_user->pass_raw,
    ));
    $this
      ->assertRaw('Your order is complete!');
    $this
      ->assertText($new_user->name, 'Username is shown on screen.');
    $this
      ->assertNoText($new_user->pass_raw, 'Password is not shown on screen.');

    // Check that cart is now empty.
    $this
      ->drupalGet('cart');
    $this
      ->assertText('There are no products in your shopping cart.');

    // Test new account email.
    $mail = $this
      ->drupalGetMails(array(
      'id' => 'user_register_no_approval_required',
    ));
    $mail = array_pop($mail);
    $this
      ->assertTrue(strpos($mail['body'], $new_user->name) !== FALSE, 'Mail body contains username.');

    // Test invoice email.
    $mail = $this
      ->drupalGetMails(array(
      'subject' => 'Your Order at Ubercart',
    ));
    $mail = array_pop($mail);
    $this
      ->assertTrue(strpos($mail['body'], $new_user->name) !== FALSE, 'Invoice body contains username.');
    $this
      ->assertFalse(strpos($mail['body'], $new_user->pass_raw) !== FALSE, 'Mail body does not contain password.');

    // Check that the password works.
    $this
      ->drupalLogout();
    $this
      ->drupalLogin($new_user);

    // Test again as authenticated user.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout();
    $this
      ->assertRaw('Your order is complete!');
    $this
      ->assertRaw('While logged in');

    // Test again with generated username and password.
    $this
      ->drupalLogout();
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout();
    $this
      ->assertRaw('Your order is complete!');

    // Test new account email.
    $mail = $this
      ->drupalGetMails(array(
      'id' => 'user_register_no_approval_required',
    ));
    $mail = array_pop($mail);
    $new_user = new stdClass();
    $new_user->name = $mail['params']['account']->name;
    $new_user->pass_raw = $mail['params']['account']->password;
    $this
      ->assertTrue(!empty($new_user->name), 'New username is not empty.');
    $this
      ->assertTrue(!empty($new_user->pass_raw), 'New password is not empty.');
    $this
      ->assertTrue(strpos($mail['body'], $new_user->name) !== FALSE, 'Mail body contains username.');

    // Test invoice email.
    $mail = $this
      ->drupalGetMails(array(
      'subject' => 'Your Order at Ubercart',
    ));
    $mail = array_pop($mail);
    $this
      ->assertTrue(strpos($mail['body'], $new_user->name) !== FALSE, 'Invoice body contains username.');
    $this
      ->assertTrue(strpos($mail['body'], $new_user->pass_raw) !== FALSE, 'Invoice body contains password.');

    // We can check the password now we know it.
    $this
      ->assertText($new_user->name, 'Username is shown on screen.');
    $this
      ->assertText($new_user->pass_raw, 'Password is shown on screen.');

    // Check that the password works.
    $this
      ->drupalLogout();
    $this
      ->drupalLogin($new_user);

    // Test again with an existing email address.
    $this
      ->drupalLogout();
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout(array(
      'panes[customer][primary_email]' => $this->customer->mail,
    ));
    $this
      ->assertRaw('Your order is complete!');
    $this
      ->assertRaw('order has been attached to the account we found');
  }

  /**
   * Tests generating a new account at checkout.
   */
  public function testCheckoutNewUsername() {

    // Configure the checkout for this test.
    $this
      ->drupalLogin($this->adminUser);
    $settings = array(
      // Allow customer to specify username.
      'uc_cart_new_account_name' => TRUE,
      // Disable address panes.
      'uc_pane_delivery_enabled' => FALSE,
      'uc_pane_billing_enabled' => FALSE,
    );
    $this
      ->drupalPost('admin/store/settings/checkout/panes', $settings, t('Save configuration'));
    $this
      ->drupalLogout();

    // Test with an account that already exists.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $edit = array(
      'panes[customer][primary_email]' => $this
        ->randomName(8) . '@example.com',
      'panes[customer][new_account][name]' => $this->adminUser->name,
    );
    $this
      ->drupalPost('cart/checkout', $edit, 'Review order');
    $this
      ->assertText('The username ' . $this->adminUser->name . ' is already taken.');

    // Let the account be automatically created instead.
    $edit = array(
      'panes[customer][primary_email]' => $this
        ->randomName(8) . '@example.com',
      'panes[customer][new_account][name]' => '',
    );
    $this
      ->drupalPost('cart/checkout', $edit, 'Review order');
    $this
      ->drupalPost(NULL, array(), 'Submit order');
    $this
      ->assertText('Your order is complete!');
    $this
      ->assertText('A new account has been created');
  }

  /**
   * Tests blocked user checkout.
   */
  public function testCheckoutBlockedUser() {

    // Block user after checkout.
    $settings = array(
      'uc_new_customer_status_active' => FALSE,
    );
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalPost('admin/store/settings/checkout', $settings, t('Save configuration'));
    $this
      ->drupalLogout();

    // Test as anonymous user.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->checkout();
    $this
      ->assertRaw('Your order is complete!');

    // Test new account email.
    $mail = $this
      ->drupalGetMails(array(
      'id' => 'user_register_pending_approval',
    ));
    $this
      ->assertTrue(!empty($mail), 'Blocked user email found.');
    $mail = $this
      ->drupalGetMails(array(
      'id' => 'user_register_no_approval_required',
    ));
    $this
      ->assertTrue(empty($mail), 'No unblocked user email found.');
  }

  /**
   * Tests logging in the customer after checkout.
   */
  public function testCheckoutLogin() {

    // Log in after checkout.
    variable_set('uc_new_customer_login', TRUE);

    // Test checkout.
    $this
      ->drupalGet('node/' . $this->product->nid);
    $this
      ->drupalPost(NULL, array(), t('Add to cart'));
    $this
      ->assertNotNull($this->session_id, 'Session ID is set.');
    $session_id = $this->session_id;
    $this
      ->checkout();
    $this
      ->assertRaw('Your order is complete!');
    $this
      ->assertRaw('you are already logged in');

    // Confirm login.
    $this
      ->assertNotNull($this->session_id, 'Session ID is set.');
    $this
      ->assertNotIdentical($this->session_id, $session_id, 'Session ID has changed.');
    $this
      ->drupalGet('<front>');
    $this
      ->assertText('My account', 'User is logged in.');

    // Check that cart is now empty.
    $this
      ->drupalGet('cart');
    $this
      ->assertText('There are no products in your shopping cart.');
  }

  /**
   * Tests checkout complete functioning.
   */
  public function testCheckoutComplete() {

    // Payment notification is received first.
    $order_data = array(
      'primary_email' => 'simpletest@ubercart.org',
    );
    $order = $this
      ->createOrder($order_data);
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);
    $output = uc_cart_complete_sale($order);

    // Check that a new account was created.
    $this
      ->assertTrue(strpos($output['#message'], 'new account has been created') !== FALSE, 'Checkout message mentions new account.');

    // 2 e-mails: new account, customer invoice.
    $mails = $this
      ->drupalGetMails();
    $this
      ->assertEqual(count($mails), 2, '2 e-mails were sent.');
    variable_del('drupal_test_email_collector');
    $password = $mails[0]['params']['account']->password;
    $this
      ->assertTrue(!empty($password), 'New password is not empty.');

    // In D7, new account emails do not contain the password.

    //$this->assertTrue(strpos($mails[0]['body'], $password) !== FALSE, 'Mail body contains password.');

    // Different user, sees the checkout page first.
    $order_data = array(
      'primary_email' => 'simpletest2@ubercart.org',
    );
    $order = $this
      ->createOrder($order_data);
    $output = uc_cart_complete_sale($order, TRUE);
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);

    // 2 e-mails: new account, customer invoice.
    $mails = $this
      ->drupalGetMails();
    $this
      ->assertEqual(count($mails), 2, '2 e-mails were sent.');
    variable_del('drupal_test_email_collector');
    $password = $mails[0]['params']['account']->password;
    $this
      ->assertTrue(!empty($password), 'New password is not empty.');

    // In D7, new account emails do not contain the password.

    //$this->assertTrue(strpos($mails[0]['body'], $password) !== FALSE, 'Mail body contains password.');

    // Same user, new order.
    $order = $this
      ->createOrder($order_data);
    $output = uc_cart_complete_sale($order, TRUE);
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);

    // Check that no new account was created.
    $this
      ->assertTrue(strpos($output['#message'], 'order has been attached to the account') !== FALSE, 'Checkout message mentions existing account.');

    // 1 e-mail: customer invoice.
    $mails = $this
      ->drupalGetMails();
    $this
      ->assertEqual(count($mails), 1, '1 e-mail was sent.');
    variable_del('drupal_test_email_collector');
  }
  public function testCheckoutRoleAssignment() {

    // Add role assignment to the test product.
    $rid = $this
      ->drupalCreateRole(array(
      'access content',
    ));
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalPost('node/' . $this->product->nid . '/edit/features', array(
      'feature' => 'role',
    ), t('Add'));
    $this
      ->drupalPost(NULL, array(
      'uc_roles_role' => $rid,
    ), t('Save feature'));

    // Process an anonymous, shippable order.
    $item = clone $this->product;
    $item->qty = 1;
    $item->price = $item->sell_price;
    $item->data = array(
      'shippable' => TRUE,
    );
    $order = $this
      ->createOrder(array(
      'products' => array(
        $item,
      ),
    ));
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);

    // Find the order uid.
    $uid = db_query("SELECT uid FROM {uc_orders} ORDER BY order_id DESC")
      ->fetchField();
    $account = user_load($uid);
    $this
      ->assertTrue(isset($account->roles[$rid]), 'New user was granted role.');
    $order = uc_order_load($order->order_id);
    $this
      ->assertEqual($order->order_status, 'payment_received', 'Shippable order was set to payment received.');

    // 3 e-mails: new account, customer invoice, role assignment.
    $mails = $this
      ->drupalGetMails();
    $this
      ->assertEqual(count($mails), 3, '3 e-mails were sent.');
    variable_del('drupal_test_email_collector');

    // Test again with an existing email address and a non-shippable order.
    $item->data = array(
      'shippable' => FALSE,
    );
    $order = $this
      ->createOrder(array(
      'primary_email' => $this->customer->mail,
      'products' => array(
        $item,
      ),
    ));
    uc_payment_enter($order->order_id, 'SimpleTest', $order->order_total);
    $account = user_load($this->customer->uid);
    $this
      ->assertTrue(isset($account->roles[$rid]), 'Existing user was granted role.');
    $order = uc_order_load($order->order_id);
    $this
      ->assertEqual($order->order_status, 'completed', 'Non-shippable order was set to completed.');

    // 2 e-mails: customer invoice, role assignment.
    $mails = $this
      ->drupalGetMails();
    $this
      ->assertEqual(count($mails), 2, '2 e-mails were sent.');
    variable_del('drupal_test_email_collector');
  }

  /**
   * Tests that cart orders are marked abandoned after a timeout.
   */
  public function testCartOrderTimeout() {
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), 'Checkout');
    $this
      ->assertText(t('Enter your billing address and information here.'), t('Viewed cart page: Billing pane has been displayed.'));

    // Build the panes.
    $zone_id = db_query_range('SELECT zone_id FROM {uc_zones} WHERE zone_country_id = :country ORDER BY rand()', 0, 1, array(
      'country' => variable_get('uc_store_country', 840),
    ))
      ->fetchField();
    $oldname = $this
      ->randomName(10);
    $edit = array(
      'panes[delivery][delivery_first_name]' => $oldname,
      'panes[delivery][delivery_last_name]' => $this
        ->randomName(10),
      'panes[delivery][delivery_street1]' => $this
        ->randomName(10),
      'panes[delivery][delivery_city]' => $this
        ->randomName(10),
      'panes[delivery][delivery_zone]' => $zone_id,
      'panes[delivery][delivery_postal_code]' => mt_rand(10000, 99999),
      'panes[billing][billing_first_name]' => $this
        ->randomName(10),
      'panes[billing][billing_last_name]' => $this
        ->randomName(10),
      'panes[billing][billing_street1]' => $this
        ->randomName(10),
      'panes[billing][billing_city]' => $this
        ->randomName(10),
      'panes[billing][billing_zone]' => $zone_id,
      'panes[billing][billing_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';
    }

    // Submit the checkout page.
    $this
      ->drupalPost('cart/checkout', $edit, t('Review order'));
    $order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(
      ':name' => $oldname,
    ))
      ->fetchField();
    if ($order_id) {

      // Go to a different page, then back to order to make sure
      // order_id is the same.
      $this
        ->drupalGet('<front>');
      $this
        ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
      $this
        ->drupalPost('cart', array(), 'Checkout');
      $this
        ->assertRaw($oldname, 'Customer name was unchanged.');
      $this
        ->drupalPost('cart/checkout', $edit, t('Review order'));
      $new_order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(
        ':name' => $edit['panes[delivery][delivery_first_name]'],
      ))
        ->fetchField();
      $this
        ->assertEqual($order_id, $new_order_id, 'Original order_id was reused.');

      // Jump 10 minutes into the future.
      db_update('uc_orders')
        ->fields(array(
        'modified' => time() - UC_CART_ORDER_TIMEOUT - 1,
      ))
        ->condition('order_id', $order_id)
        ->execute();
      $old_order = uc_order_load($order_id);

      // Go to a different page, then back to order to verify that we are
      // using a new order.
      $this
        ->drupalGet('<front>');
      $this
        ->drupalPost('cart', array(), 'Checkout');
      $this
        ->assertNoRaw($oldname, 'Customer name was cleared after timeout.');
      $newname = $this
        ->randomName(10);
      $edit['panes[delivery][delivery_first_name]'] = $newname;
      $this
        ->drupalPost('cart/checkout', $edit, t('Review order'));
      $new_order_id = db_query("SELECT order_id FROM {uc_orders} WHERE delivery_first_name = :name", array(
        ':name' => $newname,
      ))
        ->fetchField();
      $this
        ->assertNotEqual($order_id, $new_order_id, 'New order was created after timeout.');

      // Verify that the status of old order is abandoned.
      $old_order = uc_order_load($order_id, TRUE);
      $this
        ->assertEqual($old_order->order_status, 'abandoned', 'Original order was marked abandoned.');
    }
    else {
      $this
        ->fail('No order was created.');
    }
  }

  /**
   * Tests functioning of customer information pane on checkout page.
   */
  public function testCustomerInformationCheckoutPane() {

    // Log in as a customer and add an item to the cart.
    $this
      ->drupalLogin($this->customer);
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), 'Checkout');

    // Test the customer information pane.
    $mail = $this->customer->mail;
    $this
      ->assertText('Customer information');
    $this
      ->assertText('Order information will be sent to your account e-mail listed below.');
    $this
      ->assertText('E-mail address: ' . $mail);

    // Use the 'edit' link to change the email address on the account.
    $new_mail = $this
      ->randomName() . '@example.com';
    $this
      ->clickLink('edit');
    $data = array(
      'current_pass' => $this->customer->pass_raw,
      'mail' => $new_mail,
    );
    $this
      ->drupalPost(NULL, $data, 'Save');

    // Test the updated email address.
    $this
      ->assertText('Order information will be sent to your account e-mail listed below.');
    $this
      ->assertNoText('E-mail address: ' . $mail);
    $this
      ->assertText('E-mail address: ' . $new_mail);
  }

}

/**
 * Tests the cart settings page.
 */
class UbercartCartSettingsTestCase extends UbercartTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Cart settings',
      'description' => 'Tests the cart settings page.',
      'group' => 'Ubercart',
    );
  }

  /**
   * Tests add-to-cart redirection.
   */
  public function testAddToCartRedirect() {
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/cart');
    $this
      ->assertField('uc_add_item_redirect', t('Add to cart redirect field exists'));
    $redirect = $this
      ->randomName(8);
    $this
      ->drupalPost('admin/store/settings/cart', array(
      'uc_add_item_redirect' => $redirect,
    ), t('Save configuration'));
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $url_pass = $this
      ->getUrl() == url($redirect, array(
      'absolute' => TRUE,
    ));
    $this
      ->assertTrue($url_pass, t('Add to cart redirect takes user to the correct URL.'));
    $this
      ->drupalPost('admin/store/settings/cart', array(
      'uc_add_item_redirect' => '<none>',
    ), t('Save configuration'));
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'), array(
      'query' => array(
        'test' => 'querystring',
      ),
    ));
    $url = url('node/' . $this->product->nid, array(
      'absolute' => TRUE,
      'query' => array(
        'test' => 'querystring',
      ),
    ));
    $this
      ->assertTrue($this
      ->getUrl() == $url, 'Add to cart no-redirect works with a query string.');
  }

  /**
   * Tests minimum subtotal for checkout.
   */
  public function testMinimumSubtotal() {
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/cart');
    $this
      ->assertField('uc_minimum_subtotal', t('Minimum order subtotal field exists'));
    $minimum_subtotal = mt_rand(2, 9999);
    $this
      ->drupalPost(NULL, array(
      'uc_minimum_subtotal' => $minimum_subtotal,
    ), t('Save configuration'));

    // Create two products, one below the minimum price and one above.
    $product_below_limit = $this
      ->createProduct(array(
      'sell_price' => $minimum_subtotal - 1,
    ));
    $product_above_limit = $this
      ->createProduct(array(
      'sell_price' => $minimum_subtotal + 1,
    ));
    $this
      ->drupalLogout();

    // Checks if the lower priced product triggers the minimum price logic.
    $this
      ->drupalPost('node/' . $product_below_limit->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), t('Checkout'));
    $this
      ->assertRaw('The minimum order subtotal for checkout is', t('Prevented checkout below the minimum order total.'));

    // Add another product to the cart, and verify that we land on
    // the checkout page.
    $this
      ->drupalPost('node/' . $product_above_limit->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), t('Checkout'));
    $this
      ->assertText('Enter your billing address and information here.');
  }
  public function testEmptyCart() {

    // Test that the feature is not enabled by default.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), 'Add to cart');
    $this
      ->assertNoRaw('Empty cart');

    // Test the admin settings itself.
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/cart');
    $this
      ->assertField('uc_cart_empty_button', 'Empty cart button checkbox found.');
    $this
      ->drupalPost(NULL, array(
      'uc_cart_empty_button' => TRUE,
    ), 'Save configuration');

    // Test the feature itself.
    $this
      ->drupalGet('cart');
    $this
      ->drupalPost(NULL, array(), 'Empty cart');
    $this
      ->assertText('Are you sure you want to empty your shopping cart? ');
    $this
      ->drupalPost(NULL, array(), 'Confirm');
    $this
      ->assertText('There are no products in your shopping cart.');
  }

  /**
   * Tests that continue shopping link returns customer to the correct place.
   */
  public function testContinueShopping() {

    // Continue shopping link should take you back to the product page.
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertLink(t('Continue shopping'), 0, t('Continue shopping link appears on the page.'));
    $links = $this
      ->xpath('//a[@href="' . url('node/' . $this->product->nid, array(
      'absolute' => FALSE,
    )) . '"]');
    $this
      ->assertTrue(isset($links[0]), t('Continue shopping link returns to the product page.'));
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/cart');
    $this
      ->assertField('uc_continue_shopping_type', t('Continue shopping element display field exists'));
    $this
      ->assertField('uc_continue_shopping_url', t('Default continue shopping link URL field exists'));

    // Test continue shopping button that sends users to a fixed URL.
    $settings = array(
      'uc_continue_shopping_type' => 'button',
      'uc_continue_shopping_use_last_url' => FALSE,
      'uc_continue_shopping_url' => $this
        ->randomName(8),
    );
    $this
      ->drupalPost(NULL, $settings, t('Save configuration'));
    $this
      ->drupalPost('cart', array(), t('Continue shopping'));
    $url_pass = $this
      ->getUrl() == url($settings['uc_continue_shopping_url'], array(
      'absolute' => TRUE,
    ));
    $this
      ->assertTrue($url_pass, t('Continue shopping button takes the user to the correct URL.'));
  }

  /**
   * Tests the shopping cart page breadcrumb.
   */
  public function testCartBreadcrumb() {
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/cart');
    $this
      ->assertField('uc_cart_breadcrumb_text', t('Custom cart breadcrumb text field exists'));
    $this
      ->assertField('uc_cart_breadcrumb_url', t('Custom cart breadcrumb URL'));
    $settings = array(
      'uc_cart_breadcrumb_text' => $this
        ->randomName(8),
      'uc_cart_breadcrumb_url' => $this
        ->randomName(7),
    );
    $this
      ->drupalPost(NULL, $settings, t('Save configuration'));
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertLink($settings['uc_cart_breadcrumb_text'], 0, t('The breadcrumb link text is set correctly.'));
    $links = $this
      ->xpath('//a[@href="' . url($settings['uc_cart_breadcrumb_url']) . '"]');
    $this
      ->assertTrue(isset($links[0]), t('The breadcrumb link is set correctly.'));
  }

}

/**
 * Tests the checkout settings page.
 */
class UbercartCheckoutSettingsTestCase extends UbercartTestHelper {
  public static function getInfo() {
    return array(
      'name' => 'Checkout settings',
      'description' => 'Tests the checkout settings page.',
      'group' => 'Ubercart',
    );
  }

  /**
   * Tests enabling checkout functionality.
   */
  public function testEnableCheckout() {
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/checkout');
    $this
      ->assertField('uc_checkout_enabled', t('Enable checkout field exists'));
    $this
      ->drupalPost('admin/store/settings/checkout', array(
      'uc_checkout_enabled' => FALSE,
    ), t('Save configuration'));
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->assertNoRaw(t('Checkout'));
    $buttons = $this
      ->xpath('//input[@value="' . t('Checkout') . '"]');
    $this
      ->assertFalse(isset($buttons[0]), t('The checkout button is not shown.'));
  }

  /**
   * Tests anonymous checkout functionality.
   */
  public function testAnonymousCheckout() {
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/store/settings/checkout');
    $this
      ->assertField('uc_checkout_anonymous', t('Anonymous checkout field exists'));
    $this
      ->drupalPost('admin/store/settings/checkout', array(
      'uc_checkout_anonymous' => FALSE,
    ), t('Save configuration'));
    $this
      ->drupalLogout();
    $this
      ->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
    $this
      ->drupalPost('cart', array(), 'Checkout');
    $this
      ->assertNoText('Enter your billing address and information here.', t('The checkout page is not displayed.'));
  }

}

Classes

Namesort descending Description
UbercartCartCheckoutTestCase Tests the cart and checkout functionality.
UbercartCartSettingsTestCase Tests the cart settings page.
UbercartCheckoutSettingsTestCase Tests the checkout settings page.