| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- <?php
- namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
- use Webkul\BagistoApi\Tests\GraphQLTestCase;
- use Webkul\Customer\Models\CompareItem;
- use Webkul\Product\Models\Product;
- class CompareItemTest extends GraphQLTestCase
- {
- /**
- * Create test data - customer, products and compare items
- */
- private function createTestData(): array
- {
- $this->seedRequiredData();
- $customer = $this->createCustomer();
- $product1 = Product::factory()->create();
- $product2 = Product::factory()->create();
- $compareItem1 = CompareItem::factory()->create([
- 'customer_id' => $customer->id,
- 'product_id' => $product1->id,
- ]);
- $compareItem2 = CompareItem::factory()->create([
- 'customer_id' => $customer->id,
- 'product_id' => $product2->id,
- ]);
- return compact('customer', 'product1', 'product2', 'compareItem1', 'compareItem2');
- }
- /**
- * Test: Query all compare items collection
- */
- public function test_get_compare_items_collection(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems {
- edges {
- cursor
- node {
- id
- _id
- product {
- id
- }
- customer {
- id
- }
- createdAt
- updatedAt
- }
- }
- pageInfo {
- endCursor
- startCursor
- hasNextPage
- hasPreviousPage
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.compareItems');
- expect($data['totalCount'])->toBeGreaterThanOrEqual(2);
- expect($data['edges'])->not()->toBeEmpty();
- }
- /**
- * Test: Query single compare item by ID
- */
- public function test_get_compare_item_by_id(): void
- {
- $testData = $this->createTestData();
- $compareItemId = "/api/shop/compare-items/{$testData['compareItem1']->id}";
- $query = <<<GQL
- query getCompareItem {
- compareItem(id: "{$compareItemId}") {
- id
- _id
- product {
- id
- }
- customer {
- id
- }
- createdAt
- updatedAt
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertOk();
- $data = $response->json('data.compareItem');
- expect($data['_id'])->toBe($testData['compareItem1']->id);
- expect($data['product'])->toHaveKey('id');
- expect($data['customer'])->toHaveKey('id');
- }
- /**
- * Test: Timestamps are returned in ISO8601 format
- */
- public function test_compare_item_timestamps_are_iso8601_format(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- node {
- _id
- createdAt
- updatedAt
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $compareItem = $response->json('data.compareItems.edges.0.node');
- expect($compareItem['createdAt'])->toMatch('/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/');
- expect($compareItem['updatedAt'])->toMatch('/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/');
- }
- /**
- * Test: Query compare items with pagination (first)
- */
- public function test_compare_items_pagination_first(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- node {
- _id
- }
- }
- pageInfo {
- hasNextPage
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.compareItems');
- expect($data['edges'])->toHaveCount(1);
- }
- /**
- * Test: Query compare items with product relationship
- */
- public function test_query_compare_items_with_product(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- node {
- id
- product {
- id
- }
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $compareItem = $response->json('data.compareItems.edges.0.node');
- expect($compareItem)->toHaveKey('product');
- }
- /**
- * Test: Query all fields of compare item
- */
- public function test_query_all_compare_item_fields(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- node {
- id
- _id
- product {
- id
- }
- customer {
- id
- }
- createdAt
- updatedAt
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $node = $response->json('data.compareItems.edges.0.node');
- expect($node)->toHaveKeys(['id', '_id', 'product', 'customer', 'createdAt', 'updatedAt']);
- }
- /**
- * Test: Query returns appropriate error for invalid ID
- */
- public function test_invalid_compare_item_id_returns_error(): void
- {
- $query = <<<'GQL'
- query getCompareItem {
- compareItem(id: "/api/shop/compare-items/99999") {
- id
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertOk();
- expect($response->json('data.compareItem'))->toBeNull();
- }
- /**
- * Test: Pagination with cursor
- */
- public function test_compare_items_pagination_with_cursor(): void
- {
- $testData = $this->createTestData();
- $firstQuery = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- cursor
- }
- }
- }
- GQL;
- $firstResponse = $this->authenticatedGraphQL($testData['customer'], $firstQuery);
- $cursor = $firstResponse->json('data.compareItems.edges.0.cursor');
- $secondQuery = <<<GQL
- query getCompareItems {
- compareItems(first: 1, after: "{$cursor}") {
- edges {
- node {
- _id
- }
- }
- }
- }
- GQL;
- $secondResponse = $this->authenticatedGraphQL($testData['customer'], $secondQuery);
- $secondResponse->assertOk();
- }
- /**
- * Test: Numeric ID is an integer
- */
- public function test_compare_item_numeric_id_is_integer(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 1) {
- edges {
- node {
- _id
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $compareItem = $response->json('data.compareItems.edges.0.node');
- expect($compareItem['_id'])->toBeInt();
- }
- /**
- * Test: Multiple compare items can be queried
- */
- public function test_query_multiple_compare_items(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 5) {
- edges {
- node {
- id
- _id
- }
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.compareItems');
- expect($data['totalCount'])->toBeGreaterThanOrEqual(2);
- expect($data['edges'])->not()->toBeEmpty();
- }
- /**
- * Test: Schema introspection for CompareItem
- */
- public function test_compare_item_introspection_query(): void
- {
- $query = <<<'GQL'
- {
- __type(name: "CompareItem") {
- name
- kind
- fields {
- name
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertOk();
- $type = $response->json('data.__type');
- expect($type['name'])->toBe('CompareItem');
- expect($type['kind'])->toBe('OBJECT');
- $fieldNames = collect($type['fields'])->pluck('name')->toArray();
- expect($fieldNames)->toContain('id', '_id', 'product', 'customer', 'createdAt', 'updatedAt');
- }
- /**
- * Test: Compare items are properly sorted by creation date
- */
- public function test_compare_items_sorted_by_created_at(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCompareItems {
- compareItems(first: 10) {
- edges {
- node {
- _id
- createdAt
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $edges = $response->json('data.compareItems.edges');
- // Verify we have items
- expect($edges)->not()->toBeEmpty();
- }
- /**
- * Test: Create compare item via mutation
- */
- public function test_create_compare_item_mutation(): void
- {
- $customer = $this->createCustomer();
- $product = Product::factory()->create();
- $mutation = <<<'GQL'
- mutation CreateCompareItem($productId: Int!) {
- createCompareItem(input: {productId: $productId}) {
- compareItem {
- id
- _id
- createdAt
- updatedAt
- product {
- id
- _id
- sku
- type
- }
- customer {
- id
- }
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, ['productId' => $product->id]);
- $response->assertOk();
- $errors = $response->json('errors');
- if (! empty($errors)) {
- $this->fail('GraphQL errors: '.json_encode($errors));
- }
-
- $compareItem = $response->json('data.createCompareItem.compareItem');
- expect($compareItem)->not()->toBeNull();
- expect($compareItem['_id'])->toBeInt();
- expect($compareItem['product']['_id'])->toBe($product->id);
- expect($compareItem['createdAt'])->not()->toBeNull();
- expect($compareItem['updatedAt'])->not()->toBeNull();
- }
- /**
- * Test: Delete compare item via mutation
- */
- public function test_delete_compare_item_mutation(): void
- {
- $customer = $this->createCustomer();
- $product = Product::factory()->create();
- $compareItem = CompareItem::factory()->create([
- 'customer_id' => $customer->id,
- 'product_id' => $product->id,
- ]);
- $mutation = <<<'GQL'
- mutation DeleteCompareItem($id: ID!) {
- deleteCompareItem(input: {id: $id}) {
- compareItem {
- id
- _id
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'id' => "/api/shop/compare-items/{$compareItem->id}",
- ]);
- $response->assertOk();
- $deletedItem = $response->json('data.deleteCompareItem.compareItem');
- expect($deletedItem)->not()->toBeNull();
- expect($deletedItem['_id'])->toBe($compareItem->id);
- expect(CompareItem::find($compareItem->id))->toBeNull();
- }
- /**
- * Test: Create compare item mutation with duplicate product
- */
- public function test_create_duplicate_compare_item_mutation_fails(): void
- {
- $customer = $this->createCustomer();
- $product1 = Product::factory()->create();
- CompareItem::factory()->create([
- 'customer_id' => $customer->id,
- 'product_id' => $product1->id,
- ]);
- $mutation = <<<'GQL'
- mutation CreateCompareItem($productId: Int!) {
- createCompareItem(input: {productId: $productId}) {
- compareItem {
- id
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, ['productId' => $product1->id]);
- $response->assertOk();
- $errors = $response->json('errors');
- expect($errors)->not()->toBeEmpty();
- if (isset($errors[0]['extensions']['code'])) {
- expect($errors[0]['extensions']['code'])->toBe('INVALID_INPUT');
- } else {
- expect(implode(' ', array_column($errors, 'message')))->toContain('already');
- }
- }
- /**
- * Test: Delete all compare items successfully
- */
- public function test_delete_all_compare_items(): void
- {
- $testData = $this->createTestData();
- $mutation = <<<'GQL'
- mutation DeleteAllCompareItems {
- createDeleteAllCompareItems(input: {}) {
- deleteAllCompareItems {
- message
- deletedCount
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $mutation);
- $response->assertOk();
- $response->assertJsonMissingPath('errors');
- $data = $response->json('data.createDeleteAllCompareItems.deleteAllCompareItems');
- expect($data)->not()->toBeNull();
- expect($data['deletedCount'])->toBe(2);
- expect($data['message'])->toContain('removed');
- expect(CompareItem::where('customer_id', $testData['customer']->id)->count())->toBe(0);
- }
- /**
- * Test: Delete all compare items requires authentication
- */
- public function test_delete_all_compare_items_requires_authentication(): void
- {
- $mutation = <<<'GQL'
- mutation DeleteAllCompareItems {
- createDeleteAllCompareItems(input: {}) {
- deleteAllCompareItems {
- message
- deletedCount
- }
- }
- }
- GQL;
- $response = $this->graphQL($mutation);
- $response->assertOk();
- $errors = $response->json('errors');
- expect($errors)->not()->toBeEmpty();
- }
- /**
- * Test: Delete all compare items with no items returns zero count
- */
- public function test_delete_all_compare_items_with_no_items(): void
- {
- $this->seedRequiredData();
- $customer = $this->createCustomer();
- $mutation = <<<'GQL'
- mutation DeleteAllCompareItems {
- createDeleteAllCompareItems(input: {}) {
- deleteAllCompareItems {
- message
- deletedCount
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation);
- $response->assertOk();
- $response->assertJsonMissingPath('errors');
- $data = $response->json('data.createDeleteAllCompareItems.deleteAllCompareItems');
- expect($data)->not()->toBeNull();
- expect($data['deletedCount'])->toBe(0);
- }
- }
|