commerce_discount.test 28.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
<?php

/**
 * @file
 * Commerce Discounts tests.
 */

/**
 * Testing commerce discounts functionality.
 */
class CommerceDiscountTest extends CommerceDiscountTestBase {
12

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Discounts',
      'description' => 'Test discounts functionality',
      'group' => 'Commerce Discount',
    );
  }

  /**
   * Test the importing of commerce discounts.
   */
  public function testCommerceDiscountImport() {
    $exported_discount = '{
  "name" : "pf",
  "label" : "PF",
  "type" : "product_discount",
  "status" : "1",
  "component_title" : "pf",
  "sort_order" : "10",
  "commerce_discount_offer" : {
    "type" : "fixed_amount",
    "commerce_fixed_amount" : { "und" : [
        {
          "amount" : "1200",
          "currency_code" : "USD",
          "data" : { "components" : [] }
        }
      ]
    }
  },
  "commerce_compatibility_strategy" : { "und" : [ { "value" : "any" } ] },
  "commerce_compatibility_selection" : [],
  "commerce_discount_date" : [],
  "inline_conditions" : [],
  "discount_usage_per_person" : [],
  "discount_usage_limit" : []
}';

    // Import the discount.
    $import = entity_import('commerce_discount', $exported_discount);
    $this->assertNotNull($import, 'Entity export JSON imported successfully.');
    entity_save('commerce_discount', $import);

    // Export the discount to make sure it's identical to the import string.
    $discount = entity_load_single('commerce_discount', $import->discount_id);
    $export = entity_export('commerce_discount', $discount);
    $this->assertTrue($exported_discount == $export, 'Exported discount is identical to its origin.');
  }

  /**
   * Test order wrapper cache from order refresh.
   */
  public function testCommerceDiscountOrderRefreshWrapper() {
    // Create a 'free bonus products' product discount.
    $discount = $this->createDiscount('order_discount', 'free_products', array($this->product->product_id));
    // Create a completed order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);
    $line_items = $order_wrapper->value()->commerce_line_items[LANGUAGE_NONE];
    $this->assertEqual($order_wrapper->commerce_line_items->count(), count($line_items), 'Number of line items matched');

    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    $order_wrapper = commerce_cart_order_refresh($order);
    $line_items = $order_wrapper->value()->commerce_line_items[LANGUAGE_NONE];
    $this->assertEqual($order_wrapper->commerce_line_items->count(), count($line_items), 'Number of line items matched');
  }

  /**
   * Test fixed order discounts.
   */
  public function testCommerceDiscountFixedOrderDiscount() {
    // Testing fixed discount.
    // Create a fixed order discount of $3.
    $discount = $this->createDiscount('order_discount', 'fixed_amount', 300);

    // Create an order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 700, 'Fixed order discount is deducted correctly.');

103 104 105 106 107 108
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 700, 'Fixed order discount is deducted correctly even after order refresh.');

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    // Re-save the order.
    // Check if the discount was applied on the order total price.
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
    $order_wrapper->save();

    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 1000, "Fixed order discount is removed when it's not applicable.");
  }

  /**
   * Test percentage order discounts.
   */
  public function testCommerceDiscountPercentageOrderDiscount() {
    // Testing percentage discount.
    // Create a percentage order discount of 5%.
    $discount = $this->createDiscount('order_discount', 'percentage', 5);
    // Create a completed order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 950, 'Percentage order discount is deducted correctly.');

138 139 140 141 142 143
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 950, 'Percentage order discount is deducted correctly even after refresh.');

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 1000, "Percentage order discount is removed when it's not applicable.");
  }

  /**
   * Test a 100% off product percentage discount.
   *
   * A 100% off product-level discount differs from the "Free product" discount
   * offer type since those are normally used as an "add-on" that is added
   * without the user's interaction (maybe as part of a package, or bonus);
   * whereas a 100% off discount should be used for any product purposely added
   * to a cart order.
   */
  public function testCommerceDiscountOneHundredPercentOff() {
    // Login as the store admin.
    $this->drupalLogin($this->store_admin);

    // Create a 100% off discount and create a test product.
167
    $discount = $this->createDiscount('product_discount', 'percentage', 100, 'freebie');
168 169 170 171 172 173 174 175 176 177

    $product = $this->createDummyProduct('TEST-PRODUCT', 'Test Product', 999);

    // Create the order and apply the freebie discount.
    $order = $this->createDummyOrder($this->store_admin->uid, array($product->product_id => 1));
    $order_wrapper = commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('freebie', $order);
    $this->assertTrue($properly_applied, t('100% off discount applied to a product.'));

178 179 180 181 182
    // Verify that the product is now free.
    $unit_price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();

    $this->assertEqual($unit_price['amount'], 0, 'Product line item unit price amount is properly set to 0.');
    $this->assertEqual($unit_price['data']['components'][1]['price']['amount'], -999, 'Product line item unit price discount component properly set to 100% of the product price.');
183 184 185

    $order_wrapper = commerce_cart_order_refresh($order);

186 187 188
    $properly_applied = $this->discountAppliedToOrder('freebie', $order);
    $this->assertTrue($properly_applied, t('100% off discount applied to a product even after refresh.'));

189
    // Verify that the product is now free.
190
    $unit_price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
191

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
    $this->assertEqual($unit_price['amount'], 0, 'Product line item unit price amount is properly set to 0 even after refresh.');
    $this->assertEqual($unit_price['data']['components'][1]['price']['amount'], -999, 'Product line item unit price discount component properly set to 100% of the product price even after refresh.');

    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);
    $unit_price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();

    $properly_applied = $this->discountAppliedToOrder('freebie', $order);
    $this->assertFalse($properly_applied, t('100% off discount not applied to a product.'));

    $this->assertEqual($unit_price['amount'], 999, 'Product line item unit price amount is 999.');
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
  }

  /**
   * Test free bonus products order discounts.
   */
  public function testCommerceDiscountFreeProductsOrderDiscount() {
    // Create 'free bonus products' product discount.
    $discount = $this->createDiscount('order_discount', 'free_products', array($this->product->product_id));
    // Create a completed order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertEqual($order_wrapper->commerce_order_total->amount->value(), 1000, 'Free Bonus Products order discount has the price of only one product.');
    $this->assertEqual($order_wrapper->commerce_line_items->count(), 2, 'Free Bonus Products order discount is added as a line item.');

224 225 226 227 228 229 230
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertEqual($order_wrapper->commerce_order_total->amount->value(), 1000, 'Free Bonus Products order discount has the price of only one product even after refresh.');
    $this->assertEqual($order_wrapper->commerce_line_items->count(), 2, 'Free Bonus Products order discount is added as a line item even after refresh.');

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    // Re-save the order.
    // Check if the discount was applied on the order total price.
    $order_wrapper = commerce_cart_order_refresh($order);
    $this->assertEqual($order_wrapper->commerce_order_total->amount->value(), 1000, "Free Bonus Products order discount is removed when it's not applicable and price is the same.");
    $this->assertEqual($order_wrapper->commerce_line_items->count(), 1, "Free Bonus Products order discount is removed when it's not applicable and line item count is only 1");
  }

  /**
   * Test fixed product discounts.
   */
  public function testCommerceDiscountFixedProductDiscount() {
246
    $discount = $this->createDiscount('product_discount', 'fixed_amount', 300);
247 248 249

    // Create an order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
250
    $order_wrapper = commerce_cart_order_refresh($order);
251

252 253 254 255 256 257
    // Check if the discount was added as a component to the line item.
    $price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
    $this->assertTrue($price['data']['components'][1]['price']['amount'] == -300, 'Fixed product discount is added as a price component to the line item.');
    $this->assertEqual($price['amount'], 700, 'Line item price with fixed product discount is correct.');

    $order_wrapper = commerce_cart_order_refresh($order);
258 259

    // Check if the discount was added as a component to the line item.
260 261 262 263 264 265 266 267 268
    $price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
    $this->assertTrue($price['data']['components'][1]['price']['amount'] == -300, 'Fixed product discount is added as a price component to the line item even after refresh.');
    $this->assertEqual($price['amount'], 700, 'Line item price with fixed product discount is correct even after refresh.');

    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    $order_wrapper = commerce_cart_order_refresh($order);
269

270 271 272
    // Check if the discount is not applied.
    $price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
    $this->assertEqual($price['amount'], 1000, 'Disabled fixed product discount is does not appear in the price.');
273 274 275 276 277 278
  }

  /**
   * Test percentage product discounts.
   */
  public function testCommerceDiscountPercentageProductDiscount() {
279
    $discount = $this->createDiscount('product_discount', 'percentage', 5);
280 281 282

    // Create an order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
283
    $order_wrapper = commerce_cart_order_refresh($order);
284

285 286 287 288
    // Check if the discount was added as a component to the line item.
    $price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
    $this->assertEqual($price['data']['components'][1]['price']['amount'], -50, 'Percentage product discount is added as a price component to the line item.');
    $this->assertEqual($price['amount'], 950, 'Line item amount with Percentage product discount is correct.');
289

290
    $order_wrapper = commerce_cart_order_refresh($order);
291
    // Check if the discount was added as a component to the line item.
292 293 294
    $price = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
    $this->assertEqual($price['data']['components'][1]['price']['amount'], -50, 'Percentage product discount is added as a price component to the line item even after refresh.');
    $this->assertEqual($price['amount'], 950, 'Line item amount with Percentage product discount is correct even after refresh.');
295

296 297 298 299 300 301 302 303 304
    // Disable the discount.
    $discount->status = FALSE;
    entity_save('commerce_discount', $discount);

    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was added as a component to the line item.
    $price_data = $order_wrapper->commerce_line_items->get(0)->commerce_unit_price->value();
      $this->assertEqual($price_data['amount'], 1000, 'Line item amount without Percentage product discount is correct.');
305 306 307 308 309 310 311 312 313 314
  }

  /**
   * Test discounted product price display.
   */
  public function testCommerceDiscountDiscountedProductPriceDisplay() {
    // Create a product discount.
    $this->createDiscount('product_discount', 'fixed_amount', 300);
    $formatted_discounted_price = '$7.00';

315
    // Log in as a normal user.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
    $this->drupalLogin($this->store_customer);

    $nid = $this->product_node->nid;
    // View a product node.
    $this->drupalGet("node/$nid");
    $product_price = $this->xpath('//div[contains(@class, "field-name-commerce-price")]/div[contains(@class, "field-item")]');
    $this->assertTrue(trim((string) $product_price[0]->div) == $formatted_discounted_price, 'Discounted product price is shown on product page.');

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

    // View the cart.
    $this->drupalGet('cart');
    $product_price = $this->xpath('//td[contains(@class, "views-field-commerce-unit-price")]');
    $this->assertTrue(trim((string) $product_price[0]->{0}) == $formatted_discounted_price, 'Discounted product price is shown on the cart.');
  }

  /**
   * Test multiple fixed order discounts.
   */
  public function testCommerceDiscountMultipleFixedOrderDiscounts() {
    // Create two discounts.
    $this->createDiscount('order_discount', 'fixed_amount', 300, 'of1');
    $this->createDiscount('order_discount', 'fixed_amount', 200, 'of2');

    // Create an order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    $this->assertTrue($order_wrapper->commerce_discounts->count() == 2, '2 discounts are listed as applied on the order.');
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 500, 'Two fixed order discounts are applied on the total price.');
    $this->assertTrue($order_wrapper->commerce_line_items->count() == 3, 'An order with one product and two fixed order discounts has three line items.');
    $order_wrapper->save();
    $this->assertTrue($order_wrapper->commerce_line_items->count() == 3, 'After updating the order it still has three line items.');
  }

  /**
   * Test rounding in percentage based product discounts.
   *
   * To test the rounding used when adding discount price components to product
   * line items, we use a 30% discount on a product that costs $10.25. When
   * rounding was not working correctly, the unit price amount would be set to
   * $7.18 even though the sum of the unit price's price components would in
   * fact be $7.17. In reality, since the actual discount amount SHOULD be
   * rounded up to $3.08 from $3.075, the unit price amount SHOULD be $7.17.
   * This test ensures that is the case in conjunction with a patch from the
   * linked issue below.
   *
   * @link https://www.drupal.org/node/2468943#comment-10476486
   */
  public function testCommerceProductPercentageDiscountRounding() {
    // Create the 30% discount and $10.25 product.
    $this->createDiscount('product_discount', 'percentage', 30, 'discount_30_off');
    $product = $this->createDummyProduct('TEST-PRODUCT', 'Test Product', 1025);

    // Create the order and apply discount.
    $order = $this->createDummyOrder($this->store_customer->uid, array($product->product_id => 1), 'completed');
    $order_wrapper = commerce_cart_order_refresh($order);

    // Verify rounding came out properly.
    $line_item_wrapper = $order_wrapper->commerce_line_items->get(0);
    $unit_price = $line_item_wrapper->commerce_unit_price->value();

    $this->assertEqual($unit_price['amount'], 717, 'Product line item unit price amount rounded properly for a 30% discount.');
    $this->assertEqual($unit_price['data']['components'][1]['price']['amount'], -308, 'Product line item unit price discount component properly rounded for a 30% discount.');
  }

  /**
   * Test discount compatibility strategies.
   *
   * Currently implemented strategies include:
   * - any: discount is compatible with any other discount.
   * - except: discount is compatible with any discount except selected ones.
   * - only: discount is only compatible with selected ones.
   * - none: discount is not compatible with any other discount.
   *
   * Compatibility is checked first to ensure that discounts already on an order
   * are not incompatible with the discount being added. It is then checked to
   * ensure the discount being added is not incompatible with any discount that
   * has already been added to the order.
   */
  public function testCommerceDiscountCompatibilityStrategies() {
    // Create two discounts set to execute one after the other.
    $discount_one = $this->createDiscount('order_discount', 'fixed_amount', 100, 'of1', 1);
    $discount_one_wrapper = entity_metadata_wrapper('commerce_discount', $discount_one);
    $discount_two = $this->createDiscount('order_discount', 'fixed_amount', 200, 'of2', 2);
    $discount_two_wrapper = entity_metadata_wrapper('commerce_discount', $discount_two);

    // Create an order and recalculate discounts.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');

    // Test compatibility with both discounts using the "any" strategy. Both
    // discounts should be applied.
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Discount one and two applied when both are compatible with any discount.'));

    // Test compatibility with only discount one using the "none" strategy. Only
    // discount one should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'none';
    $discount_one_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && !$this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Only discount one applied when it is not compatible with any other discount.'));

    // Test compatibility with only discount two using the "none" strategy. Only
    // discount one should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'any';
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'none';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && !$this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Only discount one applied when discount two is not compatible with any other discount.'));

    // Test compatibility with discount one compatible with any discount
    // except discount two. Only discount one should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'except';
    $discount_one_wrapper->commerce_compatibility_selection = array($discount_two->discount_id);
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'any';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && !$this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Only discount one applied when it is compatible with any discount except discount two.'));

    // Test compatibility with discount two compatible with any discount
    // except discount one. Only discount one should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'any';
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'except';
    $discount_two_wrapper->commerce_compatibility_selection = array($discount_one->discount_id);
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && !$this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Only discount one applied when it is compatible with any discount and discount two is compatible with any discount except discount one.'));

    // Test compatibility with discount two compatible with only discount
    // one. Both discounts should be applied.
    $discount_two_wrapper->commerce_compatibility_strategy = 'only';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Both discounts applied when discount one is compatible with any discount and discount two is compatible only with discount one.'));

    // Test compatibility with discount two compatible with only discount
    // one. Both discounts should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'only';
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'any';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Both discounts applied when discount one is only compatible with discount two and discount two is compatible with any discount.'));
  }

  /**
481 482 483
   * Test discount deletion.
   *
   * Discount deletion should not cause fatal errors on cart refresh.
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
   *
   * @link https://www.drupal.org/node/2538812
   */
  public function testCartWithDiscountsDeleted() {
    // Testing fixed discount.
    // Create a fixed order discount of $3.
    /** @var CommerceDiscount $discount */
    $discount = $this->createDiscount('order_discount', 'fixed_amount', 300);

    // Create an order.
    $order = $this->createDummyOrder($this->store_customer->uid, array($this->product->product_id => 1), 'completed');
    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);

    // Check if the discount was applied on the order total price.
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 700, 'Fixed order discount is deducted correctly.');

    // Delete the discount.
    $discount->delete();

    // Recalculate discounts.
    $order_wrapper = commerce_cart_order_refresh($order);
    $this->assertTrue($order_wrapper->commerce_order_total->amount->value() == 1000, "Fixed order discount is removed when it's not applicable.");
  }

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
  /**
   * Test discount compatibility regression https://www.drupal.org/node/2621526.
   *
   * Discount "toggles" when cart page is refreshed.
   */
  public function testCommerceDiscountCompatibilityStrategiesRefresh() {
    // Create two discounts set to execute one after the other.
    $discount_one = $this->createDiscount('product_discount', 'percentage', 10, 'of1');
    $discount_one_wrapper = entity_metadata_wrapper('commerce_discount', $discount_one);
    $discount_two = $this->createDiscount('product_discount', 'percentage', 20, 'of2', 2);
    $discount_two_wrapper = entity_metadata_wrapper('commerce_discount', $discount_two);

    // Create an order and recalculate discounts.
    $order = $this->createDummyOrder($this->store_customer->uid, array(
      $this->product->product_id => 1
    ), 'completed');

    // Test compatibility with discount one compatible only with discount two
    // And discount two compatible with any discount. Both should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'only';
    $discount_one_wrapper->commerce_compatibility_selection = array(
      $discount_two->discount_id
    );
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'any';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Both discounts applied when discount one is compatible with any discount and discount two is compatible only with discount one.'));

    // Regression test for discount compatibility with itself.
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($properly_applied, t('Both discounts applied when discount one is compatible with any discount, discount two is compatible only with discount one and the order refreshed one more time.'));
  }

  /**
   * Test discount compatibility regression https://www.drupal.org/node/2621526.
   *
   * Two "none" compatible discounts "toggles" when cart page is refreshed.
   */
  public function testCommerceDiscountCompatibilityStrategiesRefreshNone() {
    // Create two discounts set to execute one after the other.
    $discount_one = $this->createDiscount('product_discount', 'percentage', 10, 'of1');
    $discount_one_wrapper = entity_metadata_wrapper('commerce_discount', $discount_one);
    $discount_two = $this->createDiscount('product_discount', 'percentage', 20, 'of2', 2);
    $discount_two_wrapper = entity_metadata_wrapper('commerce_discount', $discount_two);

    // Create an order and recalculate discounts.
    $order = $this->createDummyOrder($this->store_customer->uid, array(
      $this->product->product_id => 1
    ), 'completed');

    // Test compatibility with both discounts compatible with no other
    // discounts.
    // Only first discount should be applied.
    $discount_one_wrapper->commerce_compatibility_strategy = 'none';
    $discount_one_wrapper->save();
    $discount_two_wrapper->commerce_compatibility_strategy = 'none';
    $discount_two_wrapper->save();
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && ! $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($this->discountAppliedToOrder('of1', $order), t('Discount 1.'));
    $this->assertFalse($this->discountAppliedToOrder('of2', $order), t('Discount 2.'));
    $this->assertTrue($properly_applied, t('Only first discount applied when both discounts are incompatible with any discounts.'));

    // Regression test for discount compatibility with itself.
    commerce_cart_order_refresh($order);

    $properly_applied = $this->discountAppliedToOrder('of1', $order) && ! $this->discountAppliedToOrder('of2', $order);
    $this->assertTrue($this->discountAppliedToOrder('of1', $order), t('Discount 1.'));
    $this->assertFalse($this->discountAppliedToOrder('of2', $order), t('Discount 2.'));
    $this->assertTrue($properly_applied, t('Only first discount applied when both discounts are incompatible with any discounts and order refreshed once again.'));
  }

587
}