|
|
@@ -0,0 +1,141 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
|
|
|
+
|
|
|
+use Webkul\BagistoApi\Models\StorefrontKey;
|
|
|
+use Webkul\BagistoApi\Tests\GraphQLTestCase;
|
|
|
+use Webkul\Product\Models\Product;
|
|
|
+
|
|
|
+class MergeCartTest extends GraphQLTestCase
|
|
|
+{
|
|
|
+ public function setUp(): void
|
|
|
+ {
|
|
|
+ parent::setUp();
|
|
|
+
|
|
|
+ $this->storefrontKey = StorefrontKey::generateKey();
|
|
|
+
|
|
|
+ StorefrontKey::query()->create([
|
|
|
+ 'name' => 'Merge Cart Test',
|
|
|
+ 'key' => $this->storefrontKey,
|
|
|
+ 'is_active' => true,
|
|
|
+ 'rate_limit' => 1000,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function test_merge_recalculates_totals_when_same_product_exists_in_both_carts(): void
|
|
|
+ {
|
|
|
+ $product = Product::query()
|
|
|
+ ->where('type', 'simple')
|
|
|
+ ->whereHas('inventories', fn ($query) => $query->where('qty', '>=', 3))
|
|
|
+ ->get()
|
|
|
+ ->first(fn (Product $product) => (bool) $product->status);
|
|
|
+
|
|
|
+ if (! $product) {
|
|
|
+ $this->markTestSkipped('A saleable simple product is required for this test.');
|
|
|
+ }
|
|
|
+
|
|
|
+ $guestCart = $this->createCart();
|
|
|
+ $this->addProduct($guestCart['token'], $product->id, 2);
|
|
|
+
|
|
|
+ $customerData = $this->createTestCustomer();
|
|
|
+ $this->addProduct($customerData['token'], $product->id, 1);
|
|
|
+
|
|
|
+ $mutation = <<<'GQL'
|
|
|
+ mutation mergeCart($cartId: Int!) {
|
|
|
+ createMergeCart(input: {cartId: $cartId}) {
|
|
|
+ mergeCart {
|
|
|
+ success
|
|
|
+ baseSubtotal
|
|
|
+ items {
|
|
|
+ edges {
|
|
|
+ node {
|
|
|
+ quantity
|
|
|
+ basePrice
|
|
|
+ baseTotal
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GQL;
|
|
|
+
|
|
|
+ $response = $this->graphQL($mutation, [
|
|
|
+ 'cartId' => $guestCart['id'],
|
|
|
+ ], $this->customerHeaders($customerData['token']));
|
|
|
+
|
|
|
+ $response->assertSuccessful();
|
|
|
+
|
|
|
+ $cart = $response->json('data.createMergeCart.mergeCart');
|
|
|
+ $item = $cart['items']['edges'][0]['node'];
|
|
|
+
|
|
|
+ $this->assertTrue($cart['success']);
|
|
|
+ $this->assertSame(3, $item['quantity']);
|
|
|
+ $this->assertEqualsWithDelta(
|
|
|
+ (float) $item['basePrice'] * 3,
|
|
|
+ (float) $item['baseTotal'],
|
|
|
+ 0.0001
|
|
|
+ );
|
|
|
+ $this->assertEqualsWithDelta(
|
|
|
+ (float) $item['baseTotal'],
|
|
|
+ (float) $cart['baseSubtotal'],
|
|
|
+ 0.0001
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function createCart(): array
|
|
|
+ {
|
|
|
+ $mutation = <<<'GQL'
|
|
|
+ mutation createCart {
|
|
|
+ createCartToken(input: {}) {
|
|
|
+ cartToken {
|
|
|
+ _id
|
|
|
+ cartToken
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GQL;
|
|
|
+
|
|
|
+ $response = $this->graphQL($mutation);
|
|
|
+ $response->assertSuccessful();
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'id' => (int) $response->json('data.createCartToken.cartToken._id'),
|
|
|
+ 'token' => (string) $response->json('data.createCartToken.cartToken.cartToken'),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private function addProduct(string $token, int $productId, int $quantity): void
|
|
|
+ {
|
|
|
+ $mutation = <<<'GQL'
|
|
|
+ mutation addProduct($productId: Int!, $quantity: Int!) {
|
|
|
+ createAddProductInCart(input: {
|
|
|
+ productId: $productId
|
|
|
+ quantity: $quantity
|
|
|
+ }) {
|
|
|
+ addProductInCart {
|
|
|
+ success
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GQL;
|
|
|
+
|
|
|
+ $response = $this->graphQL($mutation, [
|
|
|
+ 'productId' => $productId,
|
|
|
+ 'quantity' => $quantity,
|
|
|
+ ], $this->customerHeaders($token));
|
|
|
+
|
|
|
+ $response->assertSuccessful();
|
|
|
+ $this->assertTrue(
|
|
|
+ (bool) $response->json('data.createAddProductInCart.addProductInCart.success'),
|
|
|
+ $response->getContent()
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function customerHeaders(string $token): array
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ 'Authorization' => 'Bearer '.$token,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|