commerce-8.x-2.8/modules/order/tests/src/Kernel/PriceSplitterTest.php
modules/order/tests/src/Kernel/PriceSplitterTest.php
<?php namespace Drupal\Tests\commerce_order\Kernel; use Drupal\commerce_order\Entity\Order; use Drupal\commerce_order\Entity\OrderItem; use Drupal\commerce_order\Entity\OrderItemType; use Drupal\commerce_price\Price; use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase; /** * Tests the price splitter. * * @coversDefaultClass \Drupal\commerce_order\PriceSplitter * * @group commerce */ class PriceSplitterTest extends CommerceKernelTestBase { /** * A sample order. * * @var \Drupal\commerce_order\Entity\OrderInterface */ protected $order; /** * The price splitter. * * @var \Drupal\commerce_order\PriceSplitterInterface */ protected $splitter; /** * Modules to enable. * * @var array */ public static $modules = [ 'entity_reference_revisions', 'path', 'profile', 'state_machine', 'commerce_product', 'commerce_order', ]; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->installEntitySchema('profile'); $this->installEntitySchema('commerce_order'); $this->installEntitySchema('commerce_order_item'); $this->installEntitySchema('commerce_product'); $this->installEntitySchema('commerce_product_variation'); $this->installConfig(['commerce_product', 'commerce_order']); $user = $this->createUser(['mail' => $this->randomString() . '@example.com']); OrderItemType::create([ 'id' => 'test', 'label' => 'Test', 'orderType' => 'default', ])->save(); $order = Order::create([ 'type' => 'default', 'state' => 'draft', 'mail' => $user->getEmail(), 'uid' => $user->id(), 'ip_address' => '127.0.0.1', 'order_number' => '6', 'store_id' => $this->store->id(), ]); $order->save(); $this->order = $this->reloadEntity($order); $this->splitter = $this->container->get('commerce_order.price_splitter'); } /** * @covers ::split */ public function testSplit() { // 6 x 3 + 6 x 3 = 36. $amount = new Price('6', 'USD'); $order_items = $this->buildOrderItems([$amount, $amount]); $this->order->setItems($order_items); $this->order->save(); // Each order item should be discounted by half (9 USD). $amounts = $this->splitter->split($this->order, new Price('18', 'USD')); $expected_amount = new Price('9', 'USD'); $this->assertEquals([$expected_amount, $expected_amount], array_values($amounts)); // Same result with an explicit percentage. $amounts = $this->splitter->split($this->order, new Price('18', 'USD'), '0.5'); $expected_amount = new Price('9', 'USD'); $this->assertEquals([$expected_amount, $expected_amount], array_values($amounts)); // 9.99 x 3 + 1.01 x 3 = 33. $first_amount = new Price('9.99', 'USD'); $second_amount = new Price('1.01', 'USD'); $order_items = $this->buildOrderItems([$first_amount, $second_amount]); $this->order->setItems($order_items); $this->order->save(); $amount = new Price('5', 'USD'); $amounts = $this->splitter->split($this->order, $amount); $first_expected_amount = new Price('4.54', 'USD'); $second_expected_amount = new Price('0.46', 'USD'); $this->assertEquals($amount, $first_expected_amount->add($second_expected_amount)); $this->assertEquals([$first_expected_amount, $second_expected_amount], array_values($amounts)); // Split an amount that has a reminder. $amount = new Price('3.98', 'USD'); $amounts = $this->splitter->split($this->order, $amount); $first_expected_amount = new Price('3.62', 'USD'); $second_expected_amount = new Price('0.36', 'USD'); $this->assertEquals($amount, $first_expected_amount->add($second_expected_amount)); $this->assertEquals([$first_expected_amount, $second_expected_amount], array_values($amounts)); } /** * Builds the order items for the given unit prices. * * @param \Drupal\commerce_price\Price[] $unit_prices * The unit prices. * * @return \Drupal\commerce_order\Entity\OrderItemInterface[] * The order items. */ protected function buildOrderItems(array $unit_prices) { $order_items = []; foreach ($unit_prices as $unit_price) { $order_item = OrderItem::create([ 'type' => 'test', 'unit_price' => $unit_price, 'quantity' => '3', ]); $order_item->save(); $order_items[] = $order_item; } return $order_items; } }