You are here

commerce_free_shipping.test in Commerce Free Shipping 7

Functional tests for the commerce free shipping module.

File

tests/commerce_free_shipping.test
View source
<?php

/**
 * @file
 * Functional tests for the commerce free shipping module.
 */

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

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

  /**
   * Flat rate service.
   */
  protected $flat_rate_service;

  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Commerce free shipping',
      'description' => 'Test simple free shipping conditions.',
      'group' => 'Drupal Commerce',
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    $modules = parent::setUpHelper('all', array(
      'commerce_shipping',
      'commerce_free_shipping',
      'commerce_flat_rate',
    ));
    parent::setUp($modules);

    // User creation for different operations.
    $permissions = $this
      ->permissionBuilder('site admin');

    // Add shipping permissions to site admin set.
    $permissions[] = 'administer shipping';
    $site_admin = $this
      ->drupalCreateUser($permissions);
    $this->site_admin = $site_admin;
    $permissions = $this
      ->permissionBuilder('store admin');

    // Add shipping permissions to site admin set.
    $permissions[] = 'administer shipping';
    $store_admin = $this
      ->drupalCreateUser($permissions);
    $this->store_admin = $store_admin;
    $permissions = $this
      ->permissionBuilder('store customer');
    $store_customer = $this
      ->drupalCreateUser($permissions);
    $this->store_customer = $store_customer;

    // 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 flat rate service
   */
  protected function createFlateRateService($name = 'shipping_service_test', $title = '', $amount = 700) {
    $flat_rate_service = commerce_flat_rate_service_new();
    $flat_rate_service['name'] = $name;
    $flat_rate_service['title'] = empty($title) ? t('Delivery service') : $title;
    $flat_rate_service['base_rate']['amount'] = $amount;
    commerce_flat_rate_service_save($flat_rate_service);
    return $flat_rate_service;
  }

  /**
   * Enable free shipping.
   */
  protected function enableFreeShipping() {
    $shipping_services = commerce_shipping_services();
    foreach ($shipping_services as $service) {

      // Enable free shipping for every service.
      $base = $service['base'];
      $this
        ->verbose($base . ' : enabling free shipping');
      variable_set($base . '_free_shipping_enabled', TRUE);
      variable_set($base . '_free_shipping_rate_limit', 6000);
      variable_set($base . '_free_shipping_gift_message', 'You have got free pricing on ' . $service['display_title'] . ', because your order total has raise %rate !');
      variable_set($base . '_free_shipping_reject_message', '%rate left to get free pricing on ' . $service['display_title']);
      variable_set($base . '_free_shipping_rules_reject_message', "You can get free shipping with " . $service['display_title'] . ", but you don't have enough {explain your conditions}.");
    }
  }

  /**
   * Disable free shipping.
   */
  protected function disableFreeShipping() {
    $shipping_services = commerce_shipping_services();
    foreach ($shipping_services as $service) {

      // Enable free shipping for every service.
      $base = $service['base'];
      $this
        ->verbose($base . ' : disable free shipping');
      variable_set($base . '_free_shipping_enabled', FALSE);
    }
  }

  /**
   * Enable free shipping rules and add a default conditions that fail.
   */
  protected function enableFailingFreeShippingRules() {

    // Loop over every shipping method and define a rule to let user
    // add condition for free shipping.
    $shipping_services = commerce_shipping_services();
    foreach ($shipping_services as $service) {
      $base = $service['base'];

      // Set rules for this service.
      variable_set($base . '_free_shipping_additionnal_rules', TRUE);

      // Create a new condition set.
      // See rules doc: https://drupal.org/node/905262 for tips.
      $condition_set = rules_and(commerce_free_shipping_service_component_variables());
      $condition_set->label = t('Free shipping conditions for: @title', array(
        '@title' => $service['display_title'],
      ));
      $condition_set->active = TRUE;
      $condition_set->tags = array(
        'Commerce free shipping',
      );
      $condition_set
        ->condition('data_is', array(
        'data:select' => 'commerce-order:type',
        'op' => '==',
        'value' => 'commerce_order',
      ))
        ->negate();
      $condition_set
        ->save('commerce_free_shipping_service_' . $base);
    }
    rules_clear_cache();
  }

  /**
   * Enable free shipping rules and add a default conditions that succeed.
   */
  protected function enableValidFreeShippingRules() {

    // Loop over every shipping method and define a rule to let user
    // add condition for free shipping.
    $shipping_services = commerce_shipping_services();
    foreach ($shipping_services as $service) {
      $base = $service['base'];

      // Set rules for this service.
      variable_set($base . '_free_shipping_additionnal_rules', TRUE);

      // Create a new condition set.
      // See rules doc: https://drupal.org/node/905262 for tips.
      $condition_set = rules_and(commerce_free_shipping_service_component_variables());
      $condition_set->label = t('Free shipping conditions for: @title', array(
        '@title' => $service['display_title'],
      ));
      $condition_set->active = TRUE;
      $condition_set->tags = array(
        'Commerce free shipping',
      );
      $condition_set
        ->condition('data_is', array(
        'data:select' => 'commerce-order:type',
        'op' => '==',
        'value' => 'commerce_order',
      ));
      $condition_set
        ->save('commerce_free_shipping_service_' . $base);
    }
  }

  /**
   * Test the checkout process using an authenticated user and basic free shipping configuration.
   */
  public function testCommerceFreeShippingCheckoutAuthenticatedUser() {
    $this->flat_rate_service = $this
      ->createFlateRateService();

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

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

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

    // 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'));
    $product_price = commerce_currency_format(8000, commerce_default_currency());
    $this
      ->assertText($product_price, t('Product price is correct, and product is added to the order'));

    // 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', 'Billing country selected');

    // Fill in the required information for billing pane, with a random State.
    $info_billing = 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'],
    );

    // Fill in the shipping address information.
    $shipping_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_shipping[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $shipping_pane[0]['name'] => 'US',
    ), (string) $shipping_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-shipping-commerce-customer-address')]//option[@selected='selected']", 'US', 'Shipping country selected');

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

    // Check for default panes and information in this checkout phase.
    $this
      ->pass('Checking the flat rate service and the pane information:');
    $this
      ->assertTitle(t('Shipping') . ' | Drupal', 'Title of the checkout phase \'Shipping\' is correct');
    $this
      ->assertText($this->flat_rate_service['title'], 'Flat rate service correctly enabled');
    $price = commerce_currency_format($this->flat_rate_service['base_rate']['amount'], commerce_default_currency());
    $this
      ->assertText($price, 'Flat rate price service is correct');
    $this
      ->drupalPost(NULL, array(), t('Go back'));
    $this
      ->enableFreeShipping();

    // Reset the cache as we don't want to keep the lock.
    entity_get_controller('commerce_order')
      ->resetCache();
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));
    $price_free = commerce_currency_format(0, commerce_default_currency());
    $this
      ->assertText($this->flat_rate_service['title'], 'Flat rate service correctly enabled.');
    $this
      ->assertText($price_free, 'Free shipping is correctly applied');
    $price_thresold = commerce_currency_format(6000, commerce_default_currency());
    $this
      ->assertText('You have got free pricing on ' . $this->flat_rate_service['title'] . ', because your order total has raise ' . $price_thresold . ' !', 'Free shipping success message is correctly displayed to the customer.');
    $this
      ->drupalPost(NULL, array(), t('Continue to next step'));

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

    // Load the order to check if the shipping price is zero.
    $orders = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);
    $order_wrapper = entity_metadata_wrapper('commerce_order', reset($orders));
    foreach ($order_wrapper->commerce_line_items as $line_item) {
      if ($line_item->type
        ->value() == 'shipping') {

        // The line item shipping amount must be zero.
        $this
          ->assertEqual($line_item->commerce_total->amount
          ->value(), 0, 'The line item shipping is equal to zero at the Review order phase of the checkout.');
      }
    }

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

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

    // Check if the completion message has been displayed.
    $this
      ->assertTitle(t('Checkout complete') . ' | Drupal', t('Checkout process completed successfully'));

    // Load the order to check if the shipping price is zero.
    $orders = commerce_order_load_multiple(array(
      $this->order->order_id,
    ), array(), TRUE);
    $order_wrapper = entity_metadata_wrapper('commerce_order', reset($orders));
    foreach ($order_wrapper->commerce_line_items as $line_item) {
      if ($line_item->type
        ->value() == 'shipping') {

        // The line item shipping amount must be zero.
        $this
          ->assertEqual($line_item->commerce_total->amount
          ->value(), 0, 'The line item shipping is equal to zero at the end of the checkout.');
      }
    }

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

  /**
   * Test the checkout process with a rules condition for free shipping that succeed using an authenticated user.
   */
  public function testCommerceFreeShippingWithValidRulesConditionsCheckoutAuthenticatedUser() {

    // Create a flat rate service.
    $this->flat_rate_service = $this
      ->createFlateRateService();
    $this
      ->enableFreeShipping();
    $this
      ->enableValidFreeShippingRules();

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

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

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

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

    // Test if the product is in the cart at the good price.
    $product_price = commerce_currency_format(8000, commerce_default_currency());
    $this
      ->assertText($product_price, t('Product price is correct, and product is added to the order'));

    // 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', 'Billing country selected');

    // Fill in the required information for billing pane, with a random State.
    $info_billing = 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'],
    );

    // Fill in the shipping address information.
    $shipping_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_shipping[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $shipping_pane[0]['name'] => 'US',
    ), (string) $shipping_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-shipping-commerce-customer-address')]//option[@selected='selected']", 'US', 'Shipping country selected');

    // Fill in the required information for billing pane, with a random State.
    $info_shipping = array(
      'customer_profile_shipping[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_shipping[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_shipping[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_shipping[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_shipping[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );
    $this
      ->drupalPost(NULL, array_merge($info_billing, $info_shipping), t('Continue to next step'));
    $price = commerce_currency_format(0, commerce_default_currency());
    $this
      ->assertText($price, t('Flat rate price service is correct'));
    $price_thresold = commerce_currency_format(6000, commerce_default_currency());
    $this
      ->assertText('You have got free pricing on ' . $this->flat_rate_service['title'] . ', because your order total has raise ' . $price_thresold . ' !', 'Free shipping success message is correctly displayed');
  }

  /**
   * Test the checkout process with a rules condition for free shipping that failed using an authenticated user.
   */
  public function testCommerceFreeShippingWithFailingRulesConditionsCheckoutAuthenticatedUser() {

    // Create a flat rate service.
    $this->flat_rate_service = $this
      ->createFlateRateService();
    $this
      ->enableFreeShipping();
    $this
      ->enableFailingFreeShippingRules();

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

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

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

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

    // Test if the product is in the cart at the good price.
    $product_price = commerce_currency_format(8000, commerce_default_currency());
    $this
      ->assertText($product_price, t('Product price is correct, and product is added to the order'));

    // 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', 'Billing country selected');

    // Fill in the required information for billing pane, with a random State.
    $info_billing = 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'],
    );

    // Fill in the shipping address information.
    $shipping_pane = $this
      ->xpath("//select[starts-with(@name, 'customer_profile_shipping[commerce_customer_address]')]");
    $this
      ->drupalPostAJAX(NULL, array(
      (string) $shipping_pane[0]['name'] => 'US',
    ), (string) $shipping_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-shipping-commerce-customer-address')]//option[@selected='selected']", 'US', 'Shipping country selected');

    // Fill in the required information for billing pane, with a random State.
    $info_shipping = array(
      'customer_profile_shipping[commerce_customer_address][und][0][name_line]' => $address_info['name_line'],
      'customer_profile_shipping[commerce_customer_address][und][0][thoroughfare]' => $address_info['thoroughfare'],
      'customer_profile_shipping[commerce_customer_address][und][0][locality]' => $address_info['locality'],
      'customer_profile_shipping[commerce_customer_address][und][0][administrative_area]' => 'KY',
      'customer_profile_shipping[commerce_customer_address][und][0][postal_code]' => $address_info['postal_code'],
    );
    $this
      ->drupalPost(NULL, array_merge($info_billing, $info_shipping), t('Continue to next step'));
    $this
      ->assertText('{explain your conditions}', t('The rules reject message is well displayed.'));
    $price = commerce_currency_format($this->flat_rate_service['base_rate']['amount'], commerce_default_currency());
    $this
      ->assertText($price, t('Flat rate price service is correct'));
  }

}

Classes

Namesort descending Description
CommerceFreeShippingTestProcess Test checkout process.