| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- <?php
- namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
- use Webkul\BagistoApi\Tests\GraphQLTestCase;
- use Webkul\Core\Models\Channel;
- use Webkul\Customer\Models\Customer;
- use Webkul\Product\Models\Product;
- use Webkul\Sales\Models\Order;
- use Webkul\Sales\Models\OrderItem;
- use Webkul\Sales\Models\OrderPayment;
- class CustomerOrderTest extends GraphQLTestCase
- {
- /**
- * Create test data — customer with orders
- */
- private function createTestData(): array
- {
- $this->seedRequiredData();
- $customer = $this->createCustomer();
- $channel = Channel::first();
- $product = Product::factory()->create();
- $order1 = Order::factory()->create([
- 'customer_id' => $customer->id,
- 'customer_email' => $customer->email,
- 'customer_first_name' => $customer->first_name,
- 'customer_last_name' => $customer->last_name,
- 'channel_id' => $channel->id,
- 'status' => 'pending',
- ]);
- OrderItem::factory()->create([
- 'order_id' => $order1->id,
- 'product_id' => $product->id,
- 'sku' => 'TEST-SKU-001',
- 'type' => 'simple',
- 'name' => 'Test Product One',
- ]);
- OrderPayment::factory()->create([
- 'order_id' => $order1->id,
- ]);
- $order2 = Order::factory()->create([
- 'customer_id' => $customer->id,
- 'customer_email' => $customer->email,
- 'customer_first_name' => $customer->first_name,
- 'customer_last_name' => $customer->last_name,
- 'channel_id' => $channel->id,
- 'status' => 'completed',
- ]);
- OrderItem::factory()->create([
- 'order_id' => $order2->id,
- 'product_id' => $product->id,
- 'sku' => 'TEST-SKU-002',
- 'type' => 'simple',
- 'name' => 'Test Product Two',
- ]);
- OrderPayment::factory()->create([
- 'order_id' => $order2->id,
- ]);
- return compact('customer', 'channel', 'product', 'order1', 'order2');
- }
- // ── Collection Queries ────────────────────────────────────
- /**
- * Test: Query all customer orders collection
- */
- public function test_get_customer_orders_collection(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCustomerOrders {
- customerOrders(first: 10) {
- edges {
- cursor
- node {
- _id
- incrementId
- status
- customerEmail
- customerFirstName
- customerLastName
- grandTotal
- subTotal
- shippingMethod
- shippingTitle
- totalItemCount
- totalQtyOrdered
- baseCurrencyCode
- orderCurrencyCode
- createdAt
- }
- }
- pageInfo {
- endCursor
- startCursor
- hasNextPage
- hasPreviousPage
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrders');
- expect($data['totalCount'])->toBeGreaterThanOrEqual(2);
- expect($data['edges'])->not()->toBeEmpty();
- }
- /**
- * Test: Unauthenticated request returns error
- */
- public function test_get_customer_orders_requires_authentication(): void
- {
- $query = <<<'GQL'
- query getCustomerOrders {
- customerOrders(first: 5) {
- edges {
- node {
- _id
- }
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertOk();
- $errors = $response->json('errors');
- expect($errors)->not()->toBeEmpty();
- }
- /**
- * Test: Customer only sees their own orders
- */
- public function test_customer_only_sees_own_orders(): void
- {
- $testData = $this->createTestData();
- /** Create another customer with their own order */
- $otherCustomer = $this->createCustomer();
- $channel = Channel::first();
- Order::factory()->create([
- 'customer_id' => $otherCustomer->id,
- 'customer_email' => $otherCustomer->email,
- 'customer_first_name' => $otherCustomer->first_name,
- 'customer_last_name' => $otherCustomer->last_name,
- 'channel_id' => $channel->id,
- 'status' => 'pending',
- ]);
- $query = <<<'GQL'
- query getCustomerOrders {
- customerOrders(first: 50) {
- edges {
- node {
- _id
- }
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrders');
- /** Should only see the 2 orders belonging to testData customer */
- expect($data['totalCount'])->toBe(2);
- }
- /**
- * Test: Filter orders by status
- */
- public function test_filter_orders_by_status(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCustomerOrders($status: String) {
- customerOrders(first: 10, status: $status) {
- edges {
- node {
- _id
- status
- }
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query, [
- 'status' => 'pending',
- ]);
- $response->assertOk();
- $data = $response->json('data.customerOrders');
- expect($data['totalCount'])->toBe(1);
- $node = $data['edges'][0]['node'];
- expect($node['status'])->toBe('pending');
- }
- /**
- * Test: Filter by completed status
- */
- public function test_filter_orders_by_completed_status(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCustomerOrders($status: String) {
- customerOrders(first: 10, status: $status) {
- edges {
- node {
- _id
- status
- }
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query, [
- 'status' => 'completed',
- ]);
- $response->assertOk();
- $data = $response->json('data.customerOrders');
- expect($data['totalCount'])->toBe(1);
- $node = $data['edges'][0]['node'];
- expect($node['status'])->toBe('completed');
- }
- // ── Single Item Query ─────────────────────────────────────
- /**
- * Test: Query single customer order by ID
- */
- public function test_get_customer_order_by_id(): void
- {
- $testData = $this->createTestData();
- $orderId = "/api/shop/customer-orders/{$testData['order1']->id}";
- $query = <<<GQL
- query getCustomerOrder {
- customerOrder(id: "{$orderId}") {
- _id
- incrementId
- status
- customerEmail
- customerFirstName
- customerLastName
- grandTotal
- subTotal
- shippingMethod
- shippingTitle
- baseCurrencyCode
- orderCurrencyCode
- totalItemCount
- totalQtyOrdered
- createdAt
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrder');
- expect($data['_id'])->toBe($testData['order1']->id);
- expect($data['status'])->toBe('pending');
- expect($data['customerEmail'])->toBe($testData['customer']->email);
- expect($data['customerFirstName'])->toBe($testData['customer']->first_name);
- expect($data['customerLastName'])->toBe($testData['customer']->last_name);
- }
- /**
- * Test: Query single customer order by numeric ID
- */
- public function test_get_customer_order_by_numeric_id(): void
- {
- $testData = $this->createTestData();
- $orderId = (string) $testData['order1']->id;
- $query = <<<GQL
- query getCustomerOrder {
- customerOrder(id: "{$orderId}") {
- _id
- status
- customerEmail
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrder');
- expect($data['_id'])->toBe($testData['order1']->id);
- expect($data['status'])->toBe('pending');
- expect($data['customerEmail'])->toBe($testData['customer']->email);
- }
- /**
- * Test: Invalid customer order ID format returns validation error
- */
- public function test_get_customer_order_with_invalid_id_format_returns_error(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCustomerOrder {
- customerOrder(id: "invalid-id") {
- _id
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $errors = $response->json('errors');
- $message = $errors[0]['message'] ?? '';
- expect($errors)->not()->toBeEmpty();
- expect($message)->toContain('Invalid ID format');
- }
- /**
- * Test: Query order returns correct financial data
- */
- public function test_order_returns_financial_data(): void
- {
- $testData = $this->createTestData();
- $orderId = "/api/shop/customer-orders/{$testData['order1']->id}";
- $query = <<<GQL
- query getCustomerOrder {
- customerOrder(id: "{$orderId}") {
- _id
- grandTotal
- baseGrandTotal
- subTotal
- baseSubTotal
- taxAmount
- shippingAmount
- discountAmount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrder');
- expect($data)->toHaveKeys([
- '_id',
- 'grandTotal',
- 'baseGrandTotal',
- 'subTotal',
- 'baseSubTotal',
- 'taxAmount',
- 'shippingAmount',
- 'discountAmount',
- ]);
- }
- /**
- * Test: Query non-existent order returns error
- */
- public function test_get_nonexistent_order_returns_error(): void
- {
- $this->seedRequiredData();
- $query = <<<'GQL'
- query getCustomerOrder {
- customerOrder(id: "/api/shop/customer-orders/99999") {
- _id
- status
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertOk();
- $errors = $response->json('errors');
- expect($errors)->not()->toBeEmpty();
- }
- // ── Pagination ────────────────────────────────────────────
- /**
- * Test: Pagination with first parameter
- */
- public function test_pagination_with_first_parameter(): void
- {
- $testData = $this->createTestData();
- $query = <<<'GQL'
- query getCustomerOrders {
- customerOrders(first: 1) {
- edges {
- cursor
- node {
- _id
- }
- }
- pageInfo {
- endCursor
- hasNextPage
- }
- totalCount
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $data = $response->json('data.customerOrders');
- expect(count($data['edges']))->toBe(1);
- expect($data['totalCount'])->toBeGreaterThanOrEqual(2);
- }
- /**
- * Test: Forward pagination with after cursor
- */
- public function test_pagination_with_after_cursor(): void
- {
- $testData = $this->createTestData();
- /** First page */
- $query = <<<'GQL'
- query getCustomerOrders {
- customerOrders(first: 1) {
- edges {
- cursor
- node {
- _id
- }
- }
- pageInfo {
- endCursor
- hasNextPage
- }
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($testData['customer'], $query);
- $response->assertOk();
- $firstPageData = $response->json('data.customerOrders');
- $endCursor = $firstPageData['pageInfo']['endCursor'];
- $firstOrderId = $firstPageData['edges'][0]['node']['_id'];
- /** Second page */
- $query2 = <<<GQL
- query getCustomerOrders {
- customerOrders(first: 1, after: "{$endCursor}") {
- edges {
- node {
- _id
- }
- }
- }
- }
- GQL;
- $response2 = $this->authenticatedGraphQL($testData['customer'], $query2);
- $response2->assertOk();
- $secondPageData = $response2->json('data.customerOrders');
- $secondOrderId = $secondPageData['edges'][0]['node']['_id'] ?? null;
- /** Second page should have a different order */
- expect($secondOrderId)->not()->toBe($firstOrderId);
- }
- // ── Schema Introspection ──────────────────────────────────
- /**
- * Test: CustomerOrder type has expected fields in schema
- */
- public function test_customer_order_schema_has_expected_fields(): void
- {
- $query = <<<'GQL'
- {
- __type(name: "CustomerOrder") {
- name
- fields {
- name
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertSuccessful();
- $type = $response->json('data.__type');
- expect($type)->not->toBeNull()
- ->and($type['name'])->toBe('CustomerOrder');
- $fieldNames = array_column($type['fields'], 'name');
- expect($fieldNames)
- ->toContain('_id')
- ->toContain('incrementId')
- ->toContain('status')
- ->toContain('customerEmail')
- ->toContain('customerFirstName')
- ->toContain('customerLastName')
- ->toContain('grandTotal')
- ->toContain('subTotal')
- ->toContain('shippingMethod')
- ->toContain('shippingTitle')
- ->toContain('totalItemCount')
- ->toContain('totalQtyOrdered')
- ->toContain('baseCurrencyCode')
- ->toContain('orderCurrencyCode')
- ->toContain('createdAt');
- }
- }
|