2020-05-29 11:28:54 +00:00
< ? php
namespace Tests\Unit\Checkout\Cart ;
2020-09-01 08:50:16 +00:00
use Codeception\Example ;
use Exception ;
2020-05-29 11:28:54 +00:00
use Faker\Factory ;
use Illuminate\Support\Facades\DB ;
use Illuminate\Support\Facades\Event ;
use UnitTester ;
2020-09-01 08:50:16 +00:00
use Webkul\BookingProduct\Models\BookingProduct ;
use Webkul\BookingProduct\Models\BookingProductEventTicket ;
2022-02-07 10:36:38 +00:00
use Helper\Bagisto ;
2020-09-01 08:50:16 +00:00
use Webkul\Customer\Models\Customer ;
use Webkul\Product\Models\ProductDownloadableLink ;
2020-05-29 11:28:54 +00:00
class CartCest
{
private $faker ;
private $simpleProduct1 ;
private $simpleProduct2 ;
private $virtualProduct1 ;
private $virtualProduct2 ;
private $downloadableProduct1 ;
private $downloadableProduct2 ;
2020-09-01 08:50:16 +00:00
private $customer ;
2020-05-29 11:28:54 +00:00
2020-09-01 08:50:16 +00:00
public function _before ( UnitTester $I ) : void
2020-05-29 11:28:54 +00:00
{
$this -> faker = Factory :: create ();
$this -> sessionToken = $this -> faker -> uuid ;
session ([ '_token' => $this -> sessionToken ]);
2022-02-07 10:36:38 +00:00
$this -> simpleProduct1 = $I -> haveProduct ( Bagisto :: SIMPLE_PRODUCT );
2020-05-29 11:28:54 +00:00
cart () -> addProduct ( $this -> simpleProduct1 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> simpleProduct1 -> id ,
'quantity' => 1 ,
]);
2022-02-07 10:36:38 +00:00
$this -> simpleProduct2 = $I -> haveProduct ( Bagisto :: SIMPLE_PRODUCT );
2020-05-29 11:28:54 +00:00
cart () -> addProduct ( $this -> simpleProduct2 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> simpleProduct2 -> id ,
'quantity' => 1 ,
]);
2022-02-07 10:36:38 +00:00
$this -> virtualProduct1 = $I -> haveProduct ( Bagisto :: VIRTUAL_PRODUCT );
2020-05-29 11:28:54 +00:00
cart () -> addProduct ( $this -> virtualProduct1 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> virtualProduct1 -> id ,
'quantity' => 1 ,
]);
2022-02-07 10:36:38 +00:00
$this -> virtualProduct2 = $I -> haveProduct ( Bagisto :: VIRTUAL_PRODUCT );
2020-05-29 11:28:54 +00:00
cart () -> addProduct ( $this -> virtualProduct2 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> virtualProduct2 -> id ,
'quantity' => 1 ,
]);
2022-02-07 10:36:38 +00:00
$this -> downloadableProduct1 = $I -> haveProduct ( Bagisto :: DOWNLOADABLE_PRODUCT );
2020-05-29 11:28:54 +00:00
2022-02-07 10:36:38 +00:00
$this -> downloadableProduct2 = $I -> haveProduct ( Bagisto :: DOWNLOADABLE_PRODUCT );
2020-09-01 08:50:16 +00:00
$this -> customer = $I -> have ( Customer :: class );
2020-05-29 11:28:54 +00:00
}
public function testCartWithInactiveProducts ( UnitTester $I )
{
$I -> comment ( 'sP1, sP2, vP1 and vP2 in cart' );
$I -> assertEquals ( 4 , count ( cart () -> getCart () -> items ));
$I -> comment ( 'deactivate sP2' );
DB :: table ( 'product_attribute_values' )
-> where ([
'product_id' => $this -> simpleProduct2 -> id ,
'attribute_id' => 8 // status
])
-> update ([ 'boolean_value' => 0 ]);
2021-07-20 09:24:22 +00:00
$this -> simpleProduct2 -> refreshloadedAttributeValues ();
2020-05-29 11:28:54 +00:00
Event :: dispatch ( 'catalog.product.update.after' , $this -> simpleProduct2 -> refresh ());
$I -> assertFalse ( cart () -> hasError ());
$I -> comment ( 'sP2 is inactive' );
2020-07-04 13:20:59 +00:00
cart () -> validateItems ();
2020-05-29 11:28:54 +00:00
$I -> assertEquals ( 3 , count ( cart () -> getCart () -> items ));
$I -> comment ( 'add dP2 to cart' );
cart () -> addProduct ( $this -> downloadableProduct2 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> downloadableProduct2 -> id ,
'quantity' => 1 ,
'links' => $this -> downloadableProduct2 -> downloadable_links -> pluck ( 'id' ) -> all (),
]);
$I -> assertEquals ( 4 , count ( cart () -> getCart () -> items ));
2020-06-04 11:09:00 +00:00
$I -> assertFalse ( cart () -> hasError ());
2020-05-29 11:28:54 +00:00
$I -> comment ( 'deactivate dP2' );
DB :: table ( 'product_attribute_values' )
-> where ([
'product_id' => $this -> downloadableProduct2 -> id ,
'attribute_id' => 8 // status
])
-> update ([ 'boolean_value' => 0 ]);
2021-07-20 09:24:22 +00:00
$this -> simpleProduct2 -> refreshloadedAttributeValues ();
2020-05-29 11:28:54 +00:00
Event :: dispatch ( 'catalog.product.update.after' , $this -> downloadableProduct2 -> refresh ());
$I -> comment ( 'add dP1 to cart, dP2 should be removed now' );
cart () -> addProduct ( $this -> downloadableProduct1 -> id , [
'_token' => session ( '_token' ),
'product_id' => $this -> downloadableProduct1 -> id ,
'quantity' => 1 ,
'links' => $this -> downloadableProduct1 -> downloadable_links -> pluck ( 'id' ) -> all (),
]);
2020-07-04 13:20:59 +00:00
cart () -> validateItems ();
2020-05-29 11:28:54 +00:00
$I -> assertEquals ( 4 , count ( cart () -> getCart () -> items ));
$I -> comment ( 'deactivate vP2' );
DB :: table ( 'product_attribute_values' )
-> where ([
'product_id' => $this -> virtualProduct2 -> id ,
'attribute_id' => 8 // status
])
-> update ([ 'boolean_value' => 0 ]);
2021-07-20 09:24:22 +00:00
$this -> simpleProduct2 -> refreshloadedAttributeValues ();
2020-05-29 11:28:54 +00:00
Event :: dispatch ( 'catalog.product.update.after' , $this -> virtualProduct2 -> refresh ());
$I -> comment ( 'change quantity of vP1, vP2 should be removed now' );
$cartItemId = $this -> getCartItemIdFromProduct ( $this -> virtualProduct1 -> id );
cart () -> updateItems ([
'qty' => [
$cartItemId => 5
],
]);
2020-07-04 13:20:59 +00:00
// now lets check without validating cart before
2020-05-29 11:28:54 +00:00
$I -> assertEquals ( 3 , count ( cart () -> getCart () -> items ));
$I -> assertEquals ( 5 , cart () -> getCart () -> items () -> find ( $cartItemId ) -> quantity );
}
2020-09-01 08:50:16 +00:00
/**
* @ param UnitTester $I
* @ param Example $scenario
*
* @ throws Exception
*
* @ dataProvider getMergeCartScenarios
*/
public function testMergeCart ( UnitTester $I , Example $scenario ) : void
{
$product1 = $I -> haveProduct ( $scenario [ 'product_type1' ]);
$product2 = $I -> haveProduct ( $scenario [ 'product_type2' ]);
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: DOWNLOADABLE_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$downloadableLink1 = ProductDownloadableLink :: query () -> where ( 'product_id' , $product1 -> id ) -> firstOrFail ();
$I -> assertNotNull ( $downloadableLink1 );
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: BOOKING_EVENT_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$bookingProduct = BookingProduct :: query () -> where ( 'product_id' , $product1 -> id ) -> firstOrFail ();
$I -> assertNotNull ( $bookingProduct );
$bookingTicket1 = BookingProductEventTicket :: query () -> where ( 'booking_product_id' ,
$bookingProduct -> id ) -> firstOrFail ();
$I -> assertNotNull ( $bookingTicket1 );
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type2' ] === Bagisto :: DOWNLOADABLE_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$downloadableLink2 = ProductDownloadableLink :: query () -> where ( 'product_id' , $product2 -> id ) -> firstOrFail ();
$I -> assertNotNull ( $downloadableLink2 );
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type2' ] === Bagisto :: BOOKING_EVENT_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$bookingProduct = BookingProduct :: query () -> where ( 'product_id' , $product2 -> id ) -> firstOrFail ();
$I -> assertNotNull ( $bookingProduct );
$bookingTicket2 = BookingProductEventTicket :: query () -> where ( 'booking_product_id' ,
$bookingProduct -> id ) -> firstOrFail ();
$I -> assertNotNull ( $bookingTicket2 );
}
$I -> comment ( " Check, I'm a guest " );
$this -> cleanUp ();
$I -> assertFalse ( auth () -> guard ( 'customer' ) -> check ());
$I -> assertNull ( cart () -> getCart ());
$data = [
'_token' => session ( '_token' ),
'quantity' => 1 ,
'product_id' => $product1 -> id ,
];
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: DOWNLOADABLE_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'links' ] = [ $downloadableLink1 -> id ];
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: BOOKING_EVENT_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'booking' ] = [ 'qty' => [ $bookingTicket1 -> id => 1 ]];
}
$I -> comment ( 'A guest is adding a first product of type ' . $product1 -> type . ' to cart' );
cart () -> addProduct ( $product1 -> id , $data );
$I -> assertEquals ( 1 , cart () -> getCart () -> items -> count ());
$I -> comment ( 'Guest is logging in...then guest is a known customer.' );
auth () -> guard ( 'customer' ) -> onceUsingId ( $this -> customer -> id );
Event :: dispatch ( 'customer.after.login' , $this -> customer [ 'email' ]);
$I -> comment ( " Let us assume that the customer's shopping cart was empty. The individual product from the guest's shopping cart is transferred to the customer's shopping cart. " );
$I -> assertEquals ( 1 , cart () -> getCart () -> items -> count ());
auth () -> guard ( 'customer' ) -> logout ();
$data = [
'_token' => session ( '_token' ),
'quantity' => 1 ,
'product_id' => $product2 -> id ,
];
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type2' ] === Bagisto :: DOWNLOADABLE_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'links' ] = [ $downloadableLink2 -> id ];
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type2' ] === Bagisto :: BOOKING_EVENT_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'booking' ] = [ 'qty' => [ $bookingTicket2 -> id => 1 ]];
}
$I -> comment ( 'Guest is adding a product of type ' . $product2 -> type . ' to cart.' );
cart () -> addProduct ( $product2 -> id , $data );
$I -> assertEquals ( 1 , cart () -> getCart () -> items -> count ());
$I -> comment ( 'And will be logged in.' );
auth () -> guard ( 'customer' ) -> onceUsingId ( $this -> customer -> id );
Event :: dispatch ( 'customer.after.login' , $this -> customer [ 'email' ]);
$I -> assertEquals ( 2 , cart () -> getCart () -> items -> count ());
auth () -> guard ( 'customer' ) -> logout ();
$data = [
'_token' => session ( '_token' ),
'quantity' => 2 ,
'product_id' => $product1 -> id ,
];
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: DOWNLOADABLE_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'links' ] = [ $downloadableLink1 -> id ];
}
2022-02-07 10:36:38 +00:00
if ( $scenario [ 'product_type1' ] === Bagisto :: BOOKING_EVENT_PRODUCT ) {
2020-09-01 08:50:16 +00:00
$data [ 'booking' ] = [ 'qty' => [ $bookingTicket1 -> id => 2 ]];
}
$I -> comment ( 'Again, guest is adding another product of type ' . $product1 -> type . '.' );
$I -> assertNull ( cart () -> getCart ());
cart () -> addProduct ( $product1 -> id , $data );
$I -> assertEquals ( 1 , cart () -> getCart () -> items -> count ());
$I -> assertEquals ( 2 , cart () -> getCart () -> items_qty );
$I -> comment ( 'And will be logged in.' );
auth () -> guard ( 'customer' ) -> onceUsingId ( $this -> customer -> id );
Event :: dispatch ( 'customer.after.login' , $this -> customer [ 'email' ]);
$I -> assertEquals ( 2 , cart () -> getCart () -> items -> count ());
$I -> assertEquals ( 4 , cart () -> getCart () -> items_qty );
$this -> cleanUp ();
$I -> comment ( '=== DONE: Added ' . $product1 -> type . ' to ' . $product2 -> type . ' ===' );
}
private function getMergeCartScenarios () : array
{
return [
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: SIMPLE_PRODUCT ,
'product_type2' => Bagisto :: SIMPLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: VIRTUAL_PRODUCT ,
'product_type2' => Bagisto :: VIRTUAL_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: SIMPLE_PRODUCT ,
'product_type2' => Bagisto :: VIRTUAL_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: VIRTUAL_PRODUCT ,
'product_type2' => Bagisto :: SIMPLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: DOWNLOADABLE_PRODUCT ,
'product_type2' => Bagisto :: DOWNLOADABLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: DOWNLOADABLE_PRODUCT ,
'product_type2' => Bagisto :: SIMPLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: SIMPLE_PRODUCT ,
'product_type2' => Bagisto :: DOWNLOADABLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: DOWNLOADABLE_PRODUCT ,
'product_type2' => Bagisto :: VIRTUAL_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: VIRTUAL_PRODUCT ,
'product_type2' => Bagisto :: DOWNLOADABLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: BOOKING_EVENT_PRODUCT ,
'product_type2' => Bagisto :: BOOKING_EVENT_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: BOOKING_EVENT_PRODUCT ,
'product_type2' => Bagisto :: SIMPLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: SIMPLE_PRODUCT ,
'product_type2' => Bagisto :: BOOKING_EVENT_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: BOOKING_EVENT_PRODUCT ,
'product_type2' => Bagisto :: VIRTUAL_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: VIRTUAL_PRODUCT ,
'product_type2' => Bagisto :: BOOKING_EVENT_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: BOOKING_EVENT_PRODUCT ,
'product_type2' => Bagisto :: DOWNLOADABLE_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
[
2022-02-07 10:36:38 +00:00
'product_type1' => Bagisto :: DOWNLOADABLE_PRODUCT ,
'product_type2' => Bagisto :: BOOKING_EVENT_PRODUCT ,
2020-09-01 08:50:16 +00:00
],
];
}
private function cleanUp () : void
{
$cart = cart () -> getCart ();
if ( $cart ) {
foreach ( $cart -> items as $item ) {
cart () -> removeItem ( $item -> id );
}
}
session () -> forget ( 'cart' );
auth () -> guard ( 'customer' ) -> logout ();
session () -> forget ( 'cart' );
}
2020-05-29 11:28:54 +00:00
/**
* @ param int $productId
*
* @ return int | null
*/
private function getCartItemIdFromProduct ( int $productId ) : ? int
{
foreach ( cart () -> getCart () -> items as $item ) {
if ( $item -> product_id === $productId ) {
return $item -> id ;
}
}
return null ;
}
}