Last active
March 7, 2018 16:29
-
-
Save steveoliver/313e1b2e6d86a254a04fc2c2a05731f7 to your computer and use it in GitHub Desktop.
Testing an event subscriber
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\Tests\commerce_cart\Kernel; | |
use Drupal\commerce_order\Entity\OrderItem; | |
use Drupal\commerce_price\Price; | |
use Drupal\commerce_order\Entity\OrderInterface; | |
use Drupal\commerce_product\Entity\ProductVariation; | |
use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase; | |
/** | |
* Tests the cart manager. | |
* | |
* @coversDefaultClass \Drupal\commerce_cart\CartManager | |
* @group commerce | |
*/ | |
class CartManagerTest extends CommerceKernelTestBase { | |
use CartManagerTestTrait; | |
/** | |
* The cart manager. | |
* | |
* @var \Drupal\commerce_cart\CartManager | |
*/ | |
protected $cartManager; | |
/** | |
* The cart provider. | |
* | |
* @var \Drupal\commerce_cart\CartProvider | |
*/ | |
protected $cartProvider; | |
/** | |
* A sample user. | |
* | |
* @var \Drupal\user\UserInterface | |
*/ | |
protected $user; | |
/** | |
* A product variation. | |
* | |
* @var \Drupal\commerce_product\Entity\ProductVariation | |
*/ | |
protected $variation1; | |
/** | |
* A product variation. | |
* | |
* @var \Drupal\commerce_product\Entity\ProductVariation | |
*/ | |
protected $variation2; | |
/** | |
* A product variation. | |
* | |
* @var \Drupal\commerce_product\Entity\ProductVariation | |
*/ | |
protected $variation3; | |
/** | |
* 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('commerce_order'); | |
$this->installConfig(['commerce_order']); | |
$this->installConfig(['commerce_product']); | |
$this->variation1 = ProductVariation::create([ | |
'type' => 'default', | |
'sku' => 'variation1', | |
'title' => $this->randomString(), | |
'price' => new Price('1.00', 'USD'), | |
'status' => 1, | |
]); | |
$this->variation2 = ProductVariation::create([ | |
'type' => 'default', | |
'sku' => 'variation2', | |
'title' => $this->randomString(), | |
'price' => new Price('2.00', 'USD'), | |
'status' => 1, | |
]); | |
$this->variation3 = ProductVariation::create([ | |
'type' => 'default', | |
'sku' => 'variation3', | |
'title' => $this->randomString(), | |
'price' => new Price('3.00', 'USD'), | |
'status' => 1, | |
]); | |
$user = $this->createUser(); | |
$this->user = $this->reloadEntity($user); | |
} | |
// /** | |
// * Tests the cart manager. | |
// * | |
// * @covers ::addEntity | |
// * @covers ::createOrderItem | |
// * @covers ::addOrderItem | |
// * @covers ::updateOrderItem | |
// * @covers ::removeOrderItem | |
// * @covers ::emptyCart | |
// */ | |
// public function testCartManager() { | |
// $this->installCommerceCart(); | |
// | |
// $cart = $this->cartProvider->createCart('default', $this->store, $this->user); | |
// $this->assertInstanceOf(OrderInterface::class, $cart); | |
// $this->assertEmpty($cart->getItems()); | |
// | |
// $order_item1 = $this->cartManager->addEntity($cart, $this->variation1); | |
// $order_item1 = $this->reloadEntity($order_item1); | |
// $this->assertNotEmpty($cart->hasItem($order_item1)); | |
// $this->assertEquals(1, $order_item1->getQuantity()); | |
// $this->assertEquals(new Price('1.00', 'USD'), $cart->getTotalPrice()); | |
// | |
// $order_item1->setQuantity(2); | |
// $this->cartManager->updateOrderItem($cart, $order_item1); | |
// $this->assertNotEmpty($cart->hasItem($order_item1)); | |
// $this->assertEquals(2, $order_item1->getQuantity()); | |
// $this->assertEquals(new Price('2.00', 'USD'), $cart->getTotalPrice()); | |
// | |
// $order_item2 = $this->cartManager->addEntity($cart, $this->variation2, 3); | |
// $order_item2 = $this->reloadEntity($order_item2); | |
// $this->assertNotEmpty($cart->hasItem($order_item1)); | |
// $this->assertNotEmpty($cart->hasItem($order_item2)); | |
// $this->assertEquals(3, $order_item2->getQuantity()); | |
// $this->assertEquals(new Price('8.00', 'USD'), $cart->getTotalPrice()); | |
// | |
// $this->cartManager->removeOrderItem($cart, $order_item1); | |
// $this->assertNotEmpty($cart->hasItem($order_item2)); | |
// $this->assertEmpty($cart->hasItem($order_item1)); | |
// $this->assertEquals(new Price('6.00', 'USD'), $cart->getTotalPrice()); | |
// | |
// $this->cartManager->emptyCart($cart); | |
// $this->assertEmpty($cart->getItems()); | |
// $this->assertEquals(NULL, $cart->getTotalPrice()); | |
// } | |
// | |
// /** | |
// * Tests that order items without purchasable entities do not cause crashes. | |
// */ | |
// public function testAddOrderItem() { | |
// $this->installCommerceCart(); | |
// $cart = $this->cartProvider->createCart('default', $this->store, $this->user); | |
// | |
// $order_item = OrderItem::create([ | |
// 'type' => 'default', | |
// 'quantity' => 2, | |
// 'unit_price' => new Price('12.00', 'USD'), | |
// ]); | |
// $order_item->save(); | |
// $this->cartManager->addOrderItem($cart, $order_item); | |
// $this->assertEquals(1, count($cart->getItems())); | |
// } | |
/** | |
* Tests that order items added in an event subscriber get added to the order. | |
*/ | |
public function testEventAddOrderItem() { | |
$this->installCommerceCart(); | |
$this->enableModules(['commerce_cart_test_event_subscriber']); | |
$cart = $this->cartProvider->createCart('default', $this->store, $this->user); | |
$order_item = OrderItem::create([ | |
'type' => 'default', | |
'quantity' => 1, | |
'unit_price' => new Price('12.00', 'USD'), | |
'purchased_entity' => $this->variation3, | |
]); | |
$order_item->save(); | |
$this->cartManager->addOrderItem($cart, $order_item); | |
$this->assertEquals(2, count($cart->getItems())); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\commerce_cart_test_event_subscriber\EventSubscriber; | |
use Drupal\commerce\PurchasableEntityInterface; | |
use Drupal\commerce_cart\CartManagerInterface; | |
use Drupal\commerce_cart\CartProviderInterface; | |
use Drupal\commerce_cart\Event\CartEntityAddEvent; | |
use Drupal\commerce_cart\Event\CartEvents; | |
use Drupal\commerce_cart\Event\CartOrderItemRemoveEvent; | |
use Drupal\commerce_order\Entity\OrderInterface; | |
use Drupal\commerce_order\Entity\OrderItemInterface; | |
use Drupal\commerce_product\Entity\ProductInterface; | |
use Drupal\commerce_product\Entity\ProductVariation; | |
use Drupal\commerce_product\ProductVariationStorage; | |
use Drupal\commerce_store\CurrentStoreInterface; | |
use Drupal\commerce_store\Entity\StoreInterface; | |
use Drupal\Core\Entity\EntityStorageException; | |
use Drupal\Core\Entity\EntityTypeManagerInterface; | |
use Drupal\user\UserInterface; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
/** | |
* Responds to cart events. | |
*/ | |
class CartEventSubscriber implements EventSubscriberInterface { | |
/** | |
* The cart manager. | |
* | |
* @var \Drupal\commerce_cart\CartManagerInterface | |
*/ | |
protected $cartManager; | |
/** | |
* The cart provider. | |
* | |
* @var \Drupal\commerce_cart\CartProviderInterface | |
*/ | |
protected $cartProvider; | |
/** | |
* The current store. | |
* | |
* @var \Drupal\commerce_store\CurrentStoreInterface | |
*/ | |
protected $currentStore; | |
/** | |
* The order item storage. | |
* | |
* @var \Drupal\commerce_order\OrderItemStorageInterface | |
*/ | |
protected $orderItemStorage; | |
/** | |
* Product variation storage. | |
* | |
* @var \Drupal\commerce_product\ProductVariationStorageInterface | |
*/ | |
protected $variationStorage; | |
/** | |
* CartEventSubscriber constructor. | |
* | |
* @param \Drupal\commerce_cart\CartManagerInterface $cart_manager | |
* The cart manager. | |
* @param \Drupal\commerce_cart\CartProviderInterface $cart_provider | |
* The cart provider. | |
* @param \Drupal\commerce_store\CurrentStoreInterface $current_store | |
* The current store. | |
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager | |
* The entity type manager. | |
* | |
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException | |
*/ | |
public function __construct(CartManagerInterface $cart_manager, CartProviderInterface $cart_provider, CurrentStoreInterface $current_store, EntityTypeManagerInterface $entity_type_manager) { | |
$this->cartManager = $cart_manager; | |
$this->cartProvider = $cart_provider; | |
$this->currentStore = $current_store; | |
$this->orderItemStorage = $entity_type_manager->getStorage('commerce_order_item'); | |
$this->variationStorage = $entity_type_manager->getStorage('commerce_product_variation'); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function getSubscribedEvents() { | |
return [ | |
CartEvents::CART_ENTITY_ADD => 'onAddToCart', | |
]; | |
} | |
/** | |
* Responds to Add to cart events. | |
* | |
* @param \Drupal\commerce_cart\Event\CartEntityAddEvent $event | |
* The entity add to cart event. | |
* | |
* @throws \Exception | |
*/ | |
public function onAddToCart(CartEntityAddEvent $event) { | |
$order_item = $event->getOrderItem(); | |
echo 'FOO'; | |
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $purchased_entity */ | |
$purchased_entity = $order_item->getPurchasedEntity(); | |
if ($purchased_entity->getSku() === 'variation3') { | |
$store = $this->selectStore($purchased_entity); | |
$cart = $this->getCart($store, 'default'); | |
$variation2_id = $this->variationStorage->getQuery() | |
->condition('sku', 'variation2') | |
->execute(); | |
$variation2 = $this->variationStorage->load($variation2_id); | |
$order_item = $this->cartManager->addEntity($cart, $variation2, 1); | |
try { | |
$order_item->save(); | |
// @todo: BUG: Sessions don't get added to cart on a fresh cart (after | |
// checkout). Once cart is initialized, it looks like, then will session | |
// products be added. WTF? | |
} | |
catch (EntityStorageException $e) { | |
drupal_set_message(t(':variation could not be added to cart. Please contact customer support.', [ | |
':variation' => $variation2->label(), | |
])); | |
} | |
} | |
} | |
/** | |
* Gets or creates a cart for the given store and order type. | |
* | |
* @param \Drupal\commerce_store\Entity\StoreInterface $store | |
* The store. | |
* @param string $order_type_id | |
* The order type id. | |
* | |
* @return \Drupal\commerce_order\Entity\OrderInterface | |
* A cart. | |
*/ | |
protected function getCart(StoreInterface $store, $order_type_id) { | |
$cart = $this->cartProvider->getCart($order_type_id, $store); | |
if (!$cart) { | |
$cart = $this->cartProvider->createCart($order_type_id, $store); | |
} | |
return $cart; | |
} | |
/** | |
* Selects the store for the given purchasable entity. | |
* | |
* If the entity is sold from one store, then that store is selected. | |
* If the entity is sold from multiple stores, and the current store is | |
* one of them, then that store is selected. | |
* | |
* @param \Drupal\commerce\PurchasableEntityInterface $entity | |
* The entity being added to cart. | |
* | |
* @throws \Exception | |
* When the entity can't be purchased from the current store. | |
* | |
* @return \Drupal\commerce_store\Entity\StoreInterface | |
* The selected store. | |
*/ | |
protected function selectStore(PurchasableEntityInterface $entity) { | |
$stores = $entity->getStores(); | |
if (count($stores) === 1) { | |
$store = reset($stores); | |
} | |
elseif (count($stores) === 0) { | |
// Malformed entity. | |
throw new \Exception('The given entity is not assigned to any store.'); | |
} | |
else { | |
$store = $this->currentStore->getStore(); | |
if (!in_array($store, $stores)) { | |
// Indicates that the site listings are not filtered properly. | |
throw new \Exception("The given entity can't be purchased from the current store."); | |
} | |
} | |
return $store; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment