@@ -65,6 +65,7 @@ class CartManagerTest extends CommerceKernelTestBase {
6565 'state_machine ' ,
6666 'commerce_product ' ,
6767 'commerce_order ' ,
68+ 'extra_order_item_field ' ,
6869 ];
6970
7071 /**
@@ -76,6 +77,7 @@ protected function setUp() {
7677 $ this ->installEntitySchema ('commerce_order ' );
7778 $ this ->installConfig (['commerce_order ' ]);
7879 $ this ->installConfig (['commerce_product ' ]);
80+ $ this ->installConfig (['extra_order_item_field ' ]);
7981
8082 $ this ->variation1 = ProductVariation::create ([
8183 'type ' => 'default ' ,
@@ -162,4 +164,99 @@ public function testAddOrderItem() {
162164 $ this ->assertEquals (1 , count ($ cart ->getItems ()));
163165 }
164166
167+ /**
168+ * Tests that duplicate order items are combined.
169+ */
170+ public function testAddDuplicateOrderItem () {
171+ $ this ->installCommerceCart ();
172+
173+ $ cart = $ this ->cartProvider ->createCart ('default ' , $ this ->store , $ this ->user );
174+ $ this ->assertInstanceOf (OrderInterface::class, $ cart );
175+ $ this ->assertEmpty ($ cart ->getItems ());
176+
177+ // First item added.
178+ $ order_item1 = $ this ->cartManager ->addEntity ($ cart , $ this ->variation1 );
179+ $ order_item1 = $ this ->reloadEntity ($ order_item1 );
180+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item1 ));
181+ $ this ->assertEquals (1 , $ order_item1 ->getQuantity ());
182+ $ this ->assertEquals ($ cart ->id (), $ order_item1 ->getOrderId ());
183+ $ this ->assertEquals (new Price ('1.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
184+
185+ // Second item should be combined.
186+ $ order_item2 = $ this ->cartManager ->addEntity ($ cart , $ this ->variation1 , 3 );
187+ $ order_item2 = $ this ->reloadEntity ($ order_item2 );
188+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item2 ));
189+ $ this ->assertEquals (4 , $ order_item2 ->getQuantity ());
190+ $ this ->assertEquals ($ cart ->id (), $ order_item2 ->getOrderId ());
191+ $ this ->assertEquals (new Price ('4.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
192+
193+ // Test FALSE combine flag.
194+ $ order_item3 = $ this ->cartManager ->addEntity ($ cart , $ this ->variation1 , 3 , FALSE );
195+ $ order_item3 = $ this ->reloadEntity ($ order_item3 );
196+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item3 ));
197+ $ this ->assertEquals (4 , $ order_item2 ->getQuantity ());
198+ $ this ->assertEquals ($ cart ->id (), $ order_item2 ->getOrderId ());
199+ $ this ->assertEquals (3 , $ order_item3 ->getQuantity ());
200+ $ this ->assertEquals ($ cart ->id (), $ order_item3 ->getOrderId ());
201+ $ this ->assertEquals (new Price ('7.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
202+ }
203+
204+ /**
205+ * Tests that adding duplicate order items with extra fields results in merging.
206+ */
207+ public function testAddDuplicateOrderItemExtraField () {
208+ $ this ->installCommerceCart ();
209+
210+ // Add an extra field to the default order item type form display.
211+ $ form_display = \Drupal::entityTypeManager ()
212+ ->getStorage ('entity_form_display ' )
213+ ->load ('commerce_order_item.default.add_to_cart ' );
214+ $ this ->assertNotEmpty ($ form_display );
215+ $ form_display ->setComponent ('field_custom_text ' , [
216+ 'type ' => 'string_textfield ' ,
217+ ]);
218+ $ form_display ->save ();
219+
220+ $ cart = $ this ->cartProvider ->createCart ('default ' , $ this ->store , $ this ->user );
221+ $ this ->assertInstanceOf (OrderInterface::class, $ cart );
222+ $ this ->assertEmpty ($ cart ->getItems ());
223+
224+ // Add order item with custom text.
225+ $ order_item1 = $ this ->cartManager ->createOrderItem ($ this ->variation1 );
226+ $ order_item1 ->set ('field_custom_text ' , 'Blue ' );
227+ $ order_item1 ->save ();
228+ $ order_item1 = $ this ->cartManager ->addOrderItem ($ cart , $ order_item1 );
229+ $ order_item1 = $ this ->reloadEntity ($ order_item1 );
230+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item1 ));
231+ $ this ->assertEquals (1 , $ order_item1 ->getQuantity ());
232+ $ this ->assertEquals ($ cart ->id (), $ order_item1 ->getOrderId ());
233+ $ this ->assertEquals (new Price ('1.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
234+
235+ // Second item for same variation, different text should not be combined.
236+ $ order_item2 = $ this ->cartManager ->createOrderItem ($ this ->variation1 , 3 );
237+ $ order_item2 ->set ('field_custom_text ' , 'Red ' );
238+ $ order_item2 ->save ();
239+ $ order_item2 = $ this ->cartManager ->addOrderItem ($ cart , $ order_item2 );
240+ $ order_item2 = $ this ->reloadEntity ($ order_item2 );
241+ $ this ->assertEquals (1 , $ order_item1 ->getQuantity ());
242+ $ this ->assertEquals ($ cart ->id (), $ order_item1 ->getOrderId ());
243+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item2 ));
244+ $ this ->assertEquals (3 , $ order_item2 ->getQuantity ());
245+ $ this ->assertEquals ($ cart ->id (), $ order_item2 ->getOrderId ());
246+ $ this ->assertEquals (new Price ('4.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
247+
248+ // Third item should be combined with first.
249+ $ order_item3 = $ this ->cartManager ->createOrderItem ($ this ->variation1 , 3 );
250+ $ order_item3 ->set ('field_custom_text ' , 'Blue ' );
251+ $ order_item3 ->save ();
252+ $ order_item3 = $ this ->cartManager ->addOrderItem ($ cart , $ order_item3 );
253+ $ order_item3 = $ this ->reloadEntity ($ order_item3 );
254+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item2 ));
255+ $ this ->assertEquals (3 , $ order_item2 ->getQuantity ());
256+ $ this ->assertNotEmpty ($ cart ->hasItem ($ order_item3 ));
257+ $ this ->assertEquals (4 , $ order_item3 ->getQuantity ());
258+ $ this ->assertEquals ($ cart ->id (), $ order_item3 ->getOrderId ());
259+ $ this ->assertEquals (new Price ('7.00 ' , 'USD ' ), $ cart ->getTotalPrice ());
260+ }
261+
165262}
0 commit comments