You are here

public function BuyXGetYTest::testAutoRemoveOrderItem in Commerce Core 8.2

Tests that the auto-added get order item is automatically removed.

@covers ::apply @covers ::clear

File

modules/promotion/tests/src/Kernel/Plugin/Commerce/PromotionOffer/BuyXGetYTest.php, line 656

Class

BuyXGetYTest
Tests the "Buy X Get Y" offer.

Namespace

Drupal\Tests\commerce_promotion\Kernel\Plugin\Commerce\PromotionOffer

Code

public function testAutoRemoveOrderItem() {
  $offer = $this->promotion
    ->getOffer();
  $offer_configuration = $offer
    ->getConfiguration();
  $offer_configuration['buy_quantity'] = '1';
  $offer_configuration['buy_conditions'] = [
    [
      'plugin' => 'order_item_purchased_entity:commerce_product_variation',
      'configuration' => [
        'entities' => [
          $this->variations[0]
            ->uuid(),
        ],
      ],
    ],
  ];

  // The customer receives 1 specific product for free.
  $offer_configuration['get_quantity'] = '1';
  $offer_configuration['get_conditions'] = [
    [
      'plugin' => 'order_item_purchased_entity:commerce_product_variation',
      'configuration' => [
        'entities' => [
          $this->variations[1]
            ->uuid(),
        ],
      ],
    ],
  ];
  $offer_configuration['get_auto_add'] = TRUE;
  $offer_configuration['offer_type'] = 'percentage';
  $offer_configuration['offer_percentage'] = '1';
  $offer_configuration['offer_amount'] = NULL;
  $offer
    ->setConfiguration($offer_configuration);
  $this->promotion
    ->setOffer($offer);
  $this->promotion
    ->set('conditions', [
    [
      'target_plugin_id' => 'order_total_price',
      'target_plugin_configuration' => [
        'operator' => '>=',
        'amount' => [
          'number' => '15.00',
          'currency_code' => 'USD',
        ],
      ],
    ],
  ]);
  $this->promotion
    ->save();
  $this->variations[1]
    ->setPrice(new Price('15', 'USD'))
    ->save();

  /** @var \Drupal\commerce_order\OrderItemStorageInterface $order_item_storage */
  $order_item_storage = \Drupal::entityTypeManager()
    ->getStorage('commerce_order_item');
  $first_order_item = $order_item_storage
    ->createFromPurchasableEntity($this->variations[0], [
    'quantity' => '2',
  ]);
  $first_order_item
    ->save();
  $this->order
    ->setItems([
    $first_order_item,
  ]);
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  list($first_order_item, $second_order_item) = $this->order
    ->getItems();
  $this
    ->assertEquals(2, $first_order_item
    ->getQuantity());
  $this
    ->assertEquals(2, $second_order_item
    ->getQuantity());
  $this
    ->assertCount(1, $second_order_item
    ->getAdjustments());
  $this
    ->assertAdjustmentPrice($second_order_item
    ->getAdjustments()[0], '-30');
  $first_order_item
    ->setQuantity('1');
  $first_order_item
    ->save();
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  $this
    ->assertCount(1, $this->order
    ->getItems());
  $this
    ->assertEquals(new Price('10', 'USD'), $this->order
    ->getTotalPrice());

  // Test that a promotion that is no longer applicable is also cleared out.
  $first_order_item
    ->setQuantity('2');
  $first_order_item
    ->save();
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  $this
    ->assertCount(2, $this->order
    ->getItems());
  $this->promotion
    ->setEnabled(FALSE);
  $this->promotion
    ->save();
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  $this
    ->assertCount(1, $this->order
    ->getItems());

  // Test that a free auto-added order item is automatically cleared out when
  // the promotion offer no longer applies.
  $this->promotion
    ->setEnabled(TRUE);
  $this->promotion
    ->save();
  $this->variations[1]
    ->setPrice(new Price('0', 'USD'));
  $this->variations[1]
    ->save();
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  $order_items = $this->order
    ->getItems();
  $this
    ->assertCount(2, $order_items);
  $this
    ->assertEquals(new Price('0', 'USD'), $order_items[1]
    ->getUnitPrice());

  // Disable the promotion, since it no longer applies, the auto-added "get"
  // order item should be removed.
  $this->promotion
    ->setEnabled(FALSE);
  $this->promotion
    ->save();
  $this->container
    ->get('commerce_order.order_refresh')
    ->refresh($this->order);
  $order_items = $this->order
    ->getItems();
  $this
    ->assertCount(1, $order_items);
  $this
    ->assertEquals(new Price('20', 'USD'), $order_items[0]
    ->getTotalPrice());
}