You are here

PaymentCommerceCheckoutWebTestCase.test in Payment for Drupal Commerce 7

Same filename and directory in other branches
  1. 7.2 tests/PaymentCommerceCheckoutWebTestCase.test

File

tests/PaymentCommerceCheckoutWebTestCase.test
View source
<?php

class PaymentCommerceCheckoutWebTestCase extends CommerceBaseTestCase {

  /**
   * Implements DrupalTestCase::getInfo().
   */
  static function getInfo() {
    return array(
      'description' => '',
      'name' => 'Checkout',
      'group' => 'Payment for Drupal Commerce',
      'dependencies' => array(
        'payment_commerce',
        'views',
      ),
    );
  }

  /**
   * Overrides parent::setUp().
   */
  function setUp(array $modules = array()) {
    $this->profile = 'testing';
    $modules = array_merge($modules, array(
      'payment_commerce',
      'paymentmethodbasic',
    ), parent::setUpHelper('api'), parent::setUpHelper('ui'));
    parent::setUp($modules);
    $this->payment_method_unavailable = PaymentWebTestCase::paymentMethodCreate(0, payment_method_controller_load('PaymentMethodControllerUnavailable'));
    entity_save('payment_method', $this->payment_method_unavailable);

    // Payment field configuration.
    $this->field_paymentform = field_create_field(array(
      'field_name' => 'field_foo',
      'type' => 'text',
    ));
    $this->field_paymentform_instance = field_create_instance(array(
      'field_name' => 'field_foo',
      'entity_type' => 'payment',
      'bundle' => 'payment',
      'required' => TRUE,
      'widget' => array(
        'type' => 'text_textfield',
      ),
    ));

    // Set up the store.
    $this->product = $this
      ->createDummyProduct('foo', 'bar', 1234);
  }

  /**
   * Tests the checkout process for a successful payment.
   */
  function testCheckoutSuccess() {
    $status = PAYMENT_STATUS_SUCCESS;

    // Create a payment method.
    $payment_method = PaymentWebTestCase::paymentMethodCreate(0, payment_method_controller_load('PaymentMethodBasicController'));
    $payment_method->controller_data['status'] = $status;
    entity_save('payment_method', $payment_method);
    drupal_static_reset();
    drupal_flush_all_caches();

    // Test an authenticated checkout.
    $user = $this
      ->assertLogin();
    $this
      ->assertCheckout($this->product->product_id, $this->loggedInUser->uid, $payment_method->pmid, $this->payment_method_unavailable->pmid);
    $order_id = $this
      ->getLastOrderID();
    $this
      ->assertUrl('checkout/' . $order_id . '/complete');
    $this
      ->assertPaymentExists($order_id, $status);
  }

  /**
   * Tests the checkout process for a failed payment.
   */
  function testCheckoutFailed() {
    $status = PAYMENT_STATUS_FAILED;

    // Create a payment method.
    $payment_method = PaymentWebTestCase::paymentMethodCreate(0, payment_method_controller_load('PaymentMethodBasicController'));
    $payment_method->controller_data['status'] = $status;
    entity_save('payment_method', $payment_method);
    drupal_static_reset();
    drupal_flush_all_caches();

    // Test an authenticated checkout.
    $user = $this
      ->assertLogin();
    $this
      ->assertCheckout($this->product->product_id, $this->loggedInUser->uid, $payment_method->pmid, $this->payment_method_unavailable->pmid);
    $order_id = $this
      ->getLastOrderID();
    $this
      ->assertUrl('checkout/' . $order_id . '/review');
    $this
      ->assertPaymentExists($order_id, $status);
  }

  /**
   * Loads the order ID of the most recent order.
   *
   * @return integer
   */
  function getLastOrderID() {
    return db_select('commerce_order')
      ->fields('commerce_order', array(
      'order_id',
    ))
      ->orderBy('order_id', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();
  }

  /**
   * Logs in a user for an authenticated checkout.
   *
   * @return stdClass
   *   The user.
   */
  function assertLogin() {
    $permissions = $this
      ->permissionBuilder(array(
      'store admin',
      'store customer',
    ));
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array_fill_keys($permissions, TRUE));
    $user = $this
      ->drupalCreateUser($permissions);
    $this
      ->drupalLogin($user);
    return $user;
  }

  /**
   * Executes the checkout process.
   *
   * @param integer $product_id
   * @param integer $uid
   * @param integer $pmid
   * @param integer $pmid_unavailable
   */
  function assertCheckout($product_id, $uid, $pmid, $pmid_unavailable) {
    $previous_order_id = $this
      ->getLastOrderID();

    // Execute the checkout.
    $product = commerce_product_load($product_id);
    $line_item = commerce_product_line_item_new($product);
    $line_item = commerce_cart_product_add($uid, $line_item);
    $values = array(
      'customer_profile_billing[commerce_customer_address][und][0][name_line]' => 'foo',
      'customer_profile_billing[commerce_customer_address][und][0][thoroughfare]' => 'bar',
      'customer_profile_billing[commerce_customer_address][und][0][locality]' => 'baz',
    );
    $this
      ->drupalPost('checkout', $values, t('Continue to next step'));

    // Confirm that payment methods that do not validate the payment are not
    // available.
    $this
      ->assertNoFieldByXPath("//input[@name='commerce_payment[payment_method]' and @value='payment_commerce_" . $pmid_unavailable . "|commerce_payment_payment_commerce_" . $pmid_unavailable . "']");
    $values = array(
      'commerce_payment[payment_method]' => 'payment_commerce_' . $pmid . '|commerce_payment_payment_commerce_' . $pmid,
      'commerce_payment[payment_details][payment_commerce][field_foo][und][0][value]' => 'bar',
    );
    $this
      ->drupalPost(NULL, $values, t('Continue to next step'));
    $this
      ->drupalPost(NULL, $values, t('Continue to next step'));

    // Confirm the new order.
    $new_order_id = $this
      ->getLastOrderID();
    $this
      ->assertNotEqual($previous_order_id, $new_order_id);
    $pids = payment_commerce_pids_load($new_order_id);
    if ($this
      ->assertTrue($pids)) {
      $payment = entity_load_single('payment', reset($pids));
      $this
        ->assertTrue((bool) $payment);
      if ($payment) {

        // Check the payment status.
        $this
          ->assertEqual($payment
          ->getStatus()->status, $payment->method->controller_data['status']);

        // Check that the Commerce Payment transaction has an instance ID.
        $transaction_id = payment_commerce_transaction_id_load($payment->pid);
        $transaction = commerce_payment_transaction_load($transaction_id);
        $this
          ->assertTrue($transaction->instance_id);
        $this
          ->assertNotIdentical(strpos($transaction->instance_id, '|'), FALSE);
      }
      $order = commerce_order_load($new_order_id);
      $this
        ->assertEqual($payment->uid, $order->uid);
      $this
        ->assertEqual($payment->field_foo['und'][0]['value'], 'bar');
    }
  }

  /**
   * Tests that a payment exists.
   *
   * @param int $order_id
   * @param string $status
   */
  function assertPaymentExists($order_id, $status) {
    $pids = payment_commerce_pids_load($order_id);
    if ($this
      ->assertTrue($pids)) {
      $this
        ->assertTrue(count($pids), 1);
      $pid = reset($pids);
      $payment = entity_load_single('payment', $pid);
      $this
        ->assertEqual($payment
        ->getStatus()->status, $status);
    }
  }

}