commerce_shipping-8.x-2.0-rc2/tests/src/Kernel/Entity/ShipmentTest.php
tests/src/Kernel/Entity/ShipmentTest.php
<?php namespace Drupal\Tests\commerce_shipping\Kernel\Entity; use Drupal\Core\Entity\EntityStorageException; use Drupal\Tests\commerce_shipping\Kernel\ShippingKernelTestBase; use Drupal\commerce_order\Adjustment; use Drupal\commerce_order\Entity\Order; use Drupal\commerce_price\Price; use Drupal\commerce_shipping\Entity\Shipment; use Drupal\commerce_shipping\Entity\ShipmentType; use Drupal\commerce_shipping\Entity\ShippingMethod; use Drupal\commerce_shipping\ProposedShipment; use Drupal\commerce_shipping\ShipmentItem; use Drupal\physical\Weight; use Drupal\profile\Entity\Profile; use Drupal\profile\Entity\ProfileType; /** * Tests the Shipment entity. * * @coversDefaultClass \Drupal\commerce_shipping\Entity\Shipment * * @group commerce_shipping */ class ShipmentTest extends ShippingKernelTestBase { /** * @covers ::getOrder * @covers ::getOrderId * @covers ::getPackageType * @covers ::setPackageType * @covers ::getShippingMethod * @covers ::getShippingMethodId * @covers ::setShippingMethod * @covers ::getShippingService * @covers ::setShippingService * @covers ::getShippingProfile * @covers ::setShippingProfile * @covers ::getTitle * @covers ::setTitle * @covers ::getItems * @covers ::setItems * @covers ::hasItems * @covers ::addItem * @covers ::removeItem * @covers ::getTotalQuantity * @covers ::getTotalDeclaredValue * @covers ::getWeight * @covers ::setWeight * @covers ::getOriginalAmount * @covers ::setOriginalAmount * @covers ::getAmount * @covers ::setAmount * @covers ::getAdjustments * @covers ::setAdjustments * @covers ::addAdjustment * @covers ::removeAdjustment * @covers ::getAdjustedAmount * @covers ::getTrackingCode * @covers ::setTrackingCode * @covers ::getState * @covers ::getData * @covers ::setData * @covers ::getCreatedTime * @covers ::setCreatedTime * @covers ::getShippedTime * @covers ::setShippedTime * @covers ::recalculateWeight */ public function testShipment() { $user = $this->createUser(); /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ $order = Order::create([ 'type' => 'default', 'state' => 'completed', 'mail' => $user->getEmail(), 'uid' => $user->id(), 'store_id' => $this->store->id(), ]); $order->save(); $order = $this->reloadEntity($order); /** @var \Drupal\commerce_shipping\Entity\ShippingMethodInterface $shipping_method */ $shipping_method = ShippingMethod::create([ 'name' => $this->randomString(), 'status' => 1, ]); $shipping_method->save(); $shipping_method = $this->reloadEntity($shipping_method); /** @var \Drupal\profile\Entity\ProfileInterface $profile */ $profile = Profile::create([ 'type' => 'customer', ]); $profile->save(); $profile = $this->reloadEntity($profile); $shipment = Shipment::create([ 'type' => 'default', 'state' => 'ready', 'order_id' => $order->id(), 'title' => 'Shipment', 'amount' => new Price('12.00', 'USD'), ]); $this->assertEquals($order, $shipment->getOrder()); $this->assertEquals($order->id(), $shipment->getOrderId()); $package_type_manager = $this->container->get('plugin.manager.commerce_package_type'); $package_type = $package_type_manager->createInstance('custom_box'); $shipment->setPackageType($package_type); $this->assertEquals($package_type, $shipment->getPackageType()); $shipment->setShippingMethod($shipping_method); $this->assertEquals($shipping_method, $shipment->getShippingMethod()); $this->assertEquals($shipping_method->id(), $shipment->getShippingMethodId()); $shipping_service = $this->randomString(); $shipment->setShippingService($shipping_service); $this->assertEquals($shipping_service, $shipment->getShippingService()); $shipment->setShippingProfile($profile); $this->assertEquals($profile, $shipment->getShippingProfile()); $shipment->setTitle('Shipment #1'); $this->assertEquals('Shipment #1', $shipment->getTitle()); $items = []; $items[] = new ShipmentItem([ 'order_item_id' => 10, 'title' => 'T-shirt (red, large)', 'quantity' => 2, 'weight' => new Weight('40', 'kg'), 'declared_value' => new Price('30', 'USD'), ]); $items[] = new ShipmentItem([ 'order_item_id' => 10, 'title' => 'T-shirt (blue, large)', 'quantity' => 2, 'weight' => new Weight('30', 'kg'), 'declared_value' => new Price('30', 'USD'), ]); $shipment->addItem($items[0]); $shipment->addItem($items[1]); $this->assertTrue($shipment->hasItems()); $this->assertEquals($items, $shipment->getItems()); $shipment->removeItem($items[0]); $this->assertEquals([$items[1]], $shipment->getItems()); $shipment->setItems($items); $this->assertEquals($items, $shipment->getItems()); $this->assertEquals('4.00', $shipment->getTotalQuantity()); $this->assertEquals(new Price('60', 'USD'), $shipment->getTotalDeclaredValue()); $calculated_weight = new Weight('70', 'kg'); $this->assertEquals($calculated_weight, $shipment->getWeight()->convert('kg')); $new_weight = new Weight('4', 'kg'); $shipment->setWeight($new_weight); $this->assertEquals($new_weight, $shipment->getWeight()); $original_amount = new Price('15.00', 'USD'); $shipment->setOriginalAmount($original_amount); $this->assertEquals($original_amount, $shipment->getOriginalAmount()); $amount = new Price('10.00', 'USD'); $shipment->setAmount($amount); $this->assertEquals($amount, $shipment->getAmount()); $adjustments = []; $adjustments[] = new Adjustment([ 'type' => 'custom', 'label' => '10% off', 'amount' => new Price('-1.00', 'USD'), 'locked' => FALSE, ]); $adjustments[] = new Adjustment([ 'type' => 'fee', 'label' => 'Random fee', 'amount' => new Price('2.00', 'USD'), ]); $shipment->addAdjustment($adjustments[0]); $shipment->addAdjustment($adjustments[1]); $this->assertEquals($adjustments, $shipment->getAdjustments()); $shipment->removeAdjustment($adjustments[0]); $this->assertEquals([$adjustments[1]], $shipment->getAdjustments()); $shipment->setAdjustments($adjustments); $this->assertEquals($adjustments, $shipment->getAdjustments()); $this->assertEquals(new Price('11.00', 'USD'), $shipment->getAdjustedAmount()); $this->assertEquals(new Price('9.00', 'USD'), $shipment->getAdjustedAmount(['custom'])); $this->assertEquals(new Price('12.00', 'USD'), $shipment->getAdjustedAmount(['fee'])); $tracking_code = $this->randomString(); $shipment->setTrackingCode($tracking_code); $this->assertEquals($tracking_code, $shipment->getTrackingCode()); $this->assertEquals('ready', $shipment->getState()->value); $this->assertEquals('default', $shipment->getData('test', 'default')); $shipment->setData('test', 'value'); $this->assertEquals('value', $shipment->getData('test', 'default')); $shipment->setCreatedTime(635879700); $this->assertEquals(635879700, $shipment->getCreatedTime()); $shipment->setShippedTime(635879800); $this->assertEquals(635879800, $shipment->getShippedTime()); $shipment->save(); $order->set('shipments', [$shipment]); $order->addAdjustment(new Adjustment([ 'type' => 'shipping', 'label' => t('Shipping'), 'amount' => $shipment->getAmount(), 'source_id' => $shipment->id(), ])); // Transfer the shipment adjustments to the order, to ensure they're // cleared on destruct() after deleting the shipment. foreach ($shipment->getAdjustments() as $adjustment) { $order->addAdjustment($adjustment); } // Add a random adjustment that isn't related to a shipment, to ensure it's // kept after the shipments are cleared. $order->addAdjustment(new Adjustment([ 'type' => 'custom', 'label' => t('Custom'), 'amount' => new Price('12', 'USD'), 'locked' => FALSE, ])); $order->save(); $order = $this->reloadEntity($order); $this->assertCount(4, $order->getAdjustments()); $this->assertCount(1, $order->get('shipments')->referencedEntities()); $shipment->delete(); $this->assertNull($this->entityTypeManager->getStorage('profile')->load($profile->id())); // The order shipments are cleared on destruct by the shipment subscriber. $this->container->get('commerce_shipping.shipment_subscriber')->destruct(); $order = $this->reloadEntity($order); $adjustments = $order->getAdjustments(); $this->assertCount(1, $adjustments); $this->assertEquals(new Adjustment([ 'type' => 'custom', 'label' => t('Custom'), 'amount' => new Price('12', 'USD'), 'locked' => FALSE, ]), reset($adjustments)); $this->assertCount(0, $order->get('shipments')->referencedEntities()); } /** * @covers ::bundleFieldDefinitions */ public function testCustomProfileType() { $profile_type = ProfileType::create([ 'id' => 'customer_shipping', ]); $profile_type->setThirdPartySetting('commerce_order', 'customer_profile_type', TRUE); $profile_type->save(); $shipment_type = ShipmentType::load('default'); $shipment_type->setProfileTypeId('customer_shipping'); $shipment_type->save(); $profile = Shipment::create(['type' => 'default']); /** @var \Drupal\Core\Field\FieldItemListInterface $shipping_profile_field */ $shipping_profile_field = $profile->get('shipping_profile'); $handler_settings = $shipping_profile_field->getFieldDefinition()->getSetting('handler_settings'); $this->assertEquals('customer_shipping', reset($handler_settings['target_bundles'])); } /** * @covers ::populateFromProposedShipment */ public function testPopulatingFromProposedShipment() { /** @var \Drupal\profile\Entity\ProfileInterface $profile */ $profile = Profile::create([ 'type' => 'customer', ]); $profile->save(); $profile = $this->reloadEntity($profile); $proposed_shipment = new ProposedShipment([ 'type' => 'default', 'order_id' => 10, 'title' => 'Test title', 'items' => [ new ShipmentItem([ 'order_item_id' => 10, 'title' => 'T-shirt (red, large)', 'quantity' => 1, 'weight' => new Weight('10', 'kg'), 'declared_value' => new Price('15', 'USD'), ]), ], 'shipping_profile' => $profile, 'package_type_id' => 'custom_box', // State is not a custom field, but it simplifies this test. 'custom_fields' => [ 'state' => 'ready', 'no_field' => 'custom_value', ], ]); $shipment = Shipment::create([ 'type' => 'default', 'title' => 'Shipment', ]); $shipment->populateFromProposedShipment($proposed_shipment); $this->assertEquals($proposed_shipment->getOrderId(), $shipment->getOrderId()); $this->assertEquals($proposed_shipment->getPackageTypeId(), $shipment->getPackageType()->getId()); $this->assertEquals($profile, $shipment->getShippingProfile()); $this->assertEquals($proposed_shipment->getTitle(), $shipment->getTitle()); $this->assertEquals($proposed_shipment->getItems(), $shipment->getItems()); $this->assertEquals(new Weight('10', 'kg'), $shipment->getWeight()); $this->assertEquals('ready', $shipment->getState()->value); $this->assertEquals('custom_value', $shipment->getData('no_field')); } /** * @covers ::preSave */ public function testDefaults() { /** @var \Drupal\commerce_shipping\Entity\ShippingMethodInterface $shipping_method */ $shipping_method = ShippingMethod::create([ 'name' => $this->randomString(), 'plugin' => [ 'target_plugin_id' => 'flat_rate', 'target_plugin_configuration' => [], ], 'status' => 1, ]); $shipping_method->save(); // Saving a shipment with a shipping method but no package type should // populate the package type. $shipment = Shipment::create([ 'type' => 'default', 'order_id' => 10, 'shipping_method' => $shipping_method, 'title' => 'Shipment', 'items' => [ new ShipmentItem([ 'order_item_id' => 10, 'title' => 'T-shirt (red, large)', 'quantity' => 1, 'weight' => new Weight('10', 'kg'), 'declared_value' => new Price('15', 'USD'), ]), ], ]); $shipment->save(); $this->assertEquals('custom_box', $shipment->getPackageType()->getId()); } /** * @covers ::preSave */ public function testEmptyValidation() { $shipment = Shipment::create([ 'type' => 'default', 'title' => 'Shipment', ]); $this->expectException(EntityStorageException::class); $this->expectExceptionMessage('Required shipment field "order_id" is empty.'); $shipment->save(); } /** * @covers ::clearRate */ public function testClearRate() { $fields = ['amount', 'original_amount', 'shipping_method', 'shipping_service']; $user = $this->createUser(); /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ $order = Order::create([ 'type' => 'default', 'state' => 'draft', 'mail' => $user->getEmail(), 'uid' => $user->id(), 'store_id' => $this->store->id(), ]); $order->setRefreshState(Order::REFRESH_SKIP); $order->save(); $order = $this->reloadEntity($order); /** @var \Drupal\commerce_shipping\Entity\ShippingMethodInterface $shipping_method */ $shipping_method = ShippingMethod::create([ 'name' => $this->randomString(), 'status' => 1, ]); $shipping_method->save(); $shipping_method = $this->reloadEntity($shipping_method); $shipment = Shipment::create([ 'amount' => new Price('0', 'USD'), 'original_amount' => new Price('0', 'USD'), 'shipping_service' => $this->randomString(), 'order_id' => $order->id(), 'type' => 'default', ]); $shipment->setShippingMethod($shipping_method); foreach ($fields as $field) { $this->assertFalse($shipment->get($field)->isEmpty()); } $shipment->clearRate(); foreach ($fields as $field) { $this->assertTrue($shipment->get($field)->isEmpty()); } } }