| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657 |
- <?php
- namespace Webkul\BagistoApi\Tests\Feature\GraphQL;
- use Illuminate\Support\Facades\DB;
- use Webkul\BagistoApi\Tests\GraphQLTestCase;
- use Webkul\Customer\Models\Customer;
- class CustomerProfileTest extends GraphQLTestCase
- {
- // ── Read Profile (Query) ──────────────────────────────────
- /**
- * Test: Read authenticated customer profile returns all fields
- */
- public function test_read_customer_profile_returns_all_fields(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Alice',
- 'last_name' => 'Wonder',
- 'email' => 'alice@example.com',
- 'phone' => '555-1234',
- 'gender' => 'Female',
- 'date_of_birth' => '1995-06-15',
- 'status' => 1,
- 'subscribed_to_news_letter' => true,
- 'is_verified' => 1,
- ]);
- $query = <<<'GQL'
- query readProfile {
- readCustomerProfile {
- id
- firstName
- lastName
- email
- phone
- gender
- dateOfBirth
- status
- subscribedToNewsLetter
- isVerified
- isSuspended
- image
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $query, [
- 'id' => '/api/shop/customer-profiles/'.$customer->id,
- ]);
- $response->assertSuccessful();
- $data = $response->json('data.readCustomerProfile');
- expect($data)->not->toBeNull()
- ->and($data['firstName'])->toBe('Alice')
- ->and($data['lastName'])->toBe('Wonder')
- ->and($data['email'])->toBe('alice@example.com')
- ->and($data['phone'])->toBe('555-1234')
- ->and($data['gender'])->toBe('Female')
- ->and($data['dateOfBirth'])->toBe('1995-06-15')
- ->and($data['subscribedToNewsLetter'])->toBeTrue()
- ->and($data['isVerified'])->toBe('1');
- }
- /**
- * Test: Read profile without authentication returns error
- */
- public function test_read_profile_without_auth_returns_error(): void
- {
- $query = <<<'GQL'
- query readProfile($id: ID!) {
- readCustomerProfile(id: $id) {
- id
- firstName
- lastName
- email
- }
- }
- GQL;
- $response = $this->graphQL($query, [
- 'id' => '/api/shop/customer-profiles/1',
- ]);
- $response->assertSuccessful();
- $json = $response->json();
- expect($json)->toHaveKey('errors')
- ->and($json['errors'])->not->toBeEmpty();
- }
- /**
- * Test: Read profile returns correct id format
- */
- public function test_read_profile_returns_correct_id_format(): void
- {
- $customer = $this->createCustomer();
- $query = <<<'GQL'
- query readProfile {
- readCustomerProfile {
- id
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $query, [
- 'id' => '/api/shop/customer-profiles/'.$customer->id,
- ]);
- $response->assertSuccessful();
- $data = $response->json('data.readCustomerProfile');
- expect($data)->not->toBeNull()
- ->and($data['id'])->toContain('/api/shop/customer-profiles/');
- }
- /**
- * Test: Read profile with selective fields
- */
- public function test_read_profile_with_selective_fields(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Bob',
- 'email' => 'bob@example.com',
- ]);
- $query = <<<'GQL'
- query readProfile {
- readCustomerProfile {
- firstName
- email
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $query, [
- 'id' => '/api/shop/customer-profiles/'.$customer->id,
- ]);
- $response->assertSuccessful();
- $data = $response->json('data.readCustomerProfile');
- expect($data)->not->toBeNull()
- ->and($data['firstName'])->toBe('Bob')
- ->and($data['email'])->toBe('bob@example.com')
- ->and($data)->not->toHaveKey('lastName')
- ->and($data)->not->toHaveKey('phone');
- }
- // ── Update Profile (Mutation) ─────────────────────────────
- /**
- * Test: Update customer first name
- */
- public function test_update_customer_first_name(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Original',
- 'last_name' => 'Name',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => ['firstName' => 'Updated'],
- ]);
- $response->assertSuccessful();
- $response->assertJsonPath('data.createCustomerProfileUpdate.clientMutationId', null);
- $customer->refresh();
- expect($customer->first_name)->toBe('Updated')
- ->and($customer->last_name)->toBe('Name');
- }
- /**
- * Test: Update multiple profile fields
- */
- public function test_update_multiple_profile_fields(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Old',
- 'last_name' => 'User',
- 'phone' => '000-0000',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => [
- 'firstName' => 'NewFirst',
- 'lastName' => 'NewLast',
- 'phone' => '999-8888',
- 'gender' => 'Male',
- ],
- ]);
- $response->assertSuccessful();
- $customer->refresh();
- expect($customer->first_name)->toBe('NewFirst')
- ->and($customer->last_name)->toBe('NewLast')
- ->and($customer->phone)->toBe('999-8888')
- ->and($customer->gender)->toBe('Male');
- }
- /**
- * Test: Update profile without authentication returns error
- */
- public function test_update_profile_without_auth_returns_error(): void
- {
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->graphQL($mutation, [
- 'input' => ['firstName' => 'Hacker'],
- ]);
- $response->assertSuccessful();
- $json = $response->json();
- expect($json)->toHaveKey('errors')
- ->and($json['errors'])->not->toBeEmpty();
- }
- /**
- * Test: Update customer email
- */
- public function test_update_customer_email(): void
- {
- $customer = $this->createCustomer([
- 'email' => 'old@example.com',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => ['email' => 'new@example.com'],
- ]);
- $response->assertSuccessful();
- $customer->refresh();
- expect($customer->email)->toBe('new@example.com');
- }
- /**
- * Test: Update customer date of birth
- */
- public function test_update_customer_date_of_birth(): void
- {
- $customer = $this->createCustomer([
- 'date_of_birth' => '1990-01-01',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => ['dateOfBirth' => '1985-12-25'],
- ]);
- $response->assertSuccessful();
- $customer->refresh();
- expect($customer->date_of_birth)->toBe('1985-12-25');
- }
- /**
- * Test: Update newsletter subscription
- */
- public function test_update_newsletter_subscription(): void
- {
- $customer = $this->createCustomer([
- 'subscribed_to_news_letter' => false,
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => ['subscribedToNewsLetter' => true],
- ]);
- $response->assertSuccessful();
- $customer->refresh();
- expect((bool) $customer->subscribed_to_news_letter)->toBeTrue();
- }
- /**
- * Test: Update with empty input does not change data
- */
- public function test_update_with_empty_input_preserves_data(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Unchanged',
- 'last_name' => 'User',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => [],
- ]);
- $response->assertSuccessful();
- $customer->refresh();
- expect($customer->first_name)->toBe('Unchanged')
- ->and($customer->last_name)->toBe('User');
- }
- /**
- * Test: Verify update is confirmed by subsequent read
- */
- public function test_update_confirmed_by_read_query(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'Before',
- 'last_name' => 'Update',
- ]);
- $mutation = <<<'GQL'
- mutation updateProfile($input: createCustomerProfileUpdateInput!) {
- createCustomerProfileUpdate(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => [
- 'firstName' => 'After',
- 'lastName' => 'Change',
- ],
- ]);
- $readQuery = <<<'GQL'
- query readProfile {
- readCustomerProfile {
- firstName
- lastName
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $readQuery, [
- 'id' => '/api/shop/customer-profiles/'.$customer->id,
- ]);
- $response->assertSuccessful();
- $data = $response->json('data.readCustomerProfile');
- expect($data['firstName'])->toBe('After')
- ->and($data['lastName'])->toBe('Change');
- }
- // ── Delete Profile (Mutation) ─────────────────────────────
- /**
- * Test: Delete customer profile removes the customer
- */
- public function test_delete_customer_profile(): void
- {
- $customer = $this->createCustomer([
- 'first_name' => 'ToDelete',
- 'email' => 'delete-me@example.com',
- ]);
- $customerId = $customer->id;
- $mutation = <<<'GQL'
- mutation deleteProfile($input: createCustomerProfileDeleteInput!) {
- createCustomerProfileDelete(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => [],
- ]);
- $response->assertSuccessful();
- expect(Customer::find($customerId))->toBeNull();
- }
- /**
- * Test: Delete profile also removes access tokens
- */
- public function test_delete_profile_removes_tokens(): void
- {
- $customer = $this->createCustomer([
- 'email' => 'token-delete@example.com',
- ]);
- $customer->createToken('token-1');
- $customer->createToken('token-2');
- $tokenCount = DB::table('personal_access_tokens')
- ->where('tokenable_id', $customer->id)
- ->where('tokenable_type', Customer::class)
- ->count();
- expect($tokenCount)->toBeGreaterThanOrEqual(2);
- $mutation = <<<'GQL'
- mutation deleteProfile($input: createCustomerProfileDeleteInput!) {
- createCustomerProfileDelete(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $this->authenticatedGraphQL($customer, $mutation, [
- 'input' => [],
- ]);
- $remainingTokens = DB::table('personal_access_tokens')
- ->where('tokenable_id', $customer->id)
- ->where('tokenable_type', Customer::class)
- ->count();
- expect($remainingTokens)->toBe(0);
- }
- /**
- * Test: Delete profile without authentication returns error
- */
- public function test_delete_profile_without_auth_returns_error(): void
- {
- $mutation = <<<'GQL'
- mutation deleteProfile($input: createCustomerProfileDeleteInput!) {
- createCustomerProfileDelete(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $response = $this->graphQL($mutation, [
- 'input' => [],
- ]);
- $response->assertSuccessful();
- $json = $response->json();
- expect($json)->toHaveKey('errors')
- ->and($json['errors'])->not->toBeEmpty();
- }
- /**
- * Test: Read profile after delete returns error
- */
- public function test_read_profile_after_delete_returns_error(): void
- {
- $customer = $this->createCustomer([
- 'email' => 'ghost@example.com',
- ]);
- $customerId = $customer->id;
- $deleteMutation = <<<'GQL'
- mutation deleteProfile($input: createCustomerProfileDeleteInput!) {
- createCustomerProfileDelete(input: $input) {
- clientMutationId
- }
- }
- GQL;
- $this->authenticatedGraphQL($customer, $deleteMutation, [
- 'input' => [],
- ]);
- expect(Customer::find($customerId))->toBeNull();
- $readQuery = <<<'GQL'
- query readProfile($id: ID!) {
- readCustomerProfile(id: $id) {
- id
- firstName
- }
- }
- GQL;
- $response = $this->authenticatedGraphQL($customer, $readQuery, [
- 'id' => '/api/shop/customer-profiles/'.$customerId,
- ]);
- $json = $response->json();
- expect($json)->toHaveKey('errors')
- ->and($json['errors'])->not->toBeEmpty();
- }
- // ── Schema Introspection ──────────────────────────────────
- /**
- * Test: CustomerProfile type has expected fields in schema
- */
- public function test_customer_profile_schema_has_expected_fields(): void
- {
- $query = <<<'GQL'
- {
- __type(name: "CustomerProfile") {
- name
- fields {
- name
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertSuccessful();
- $type = $response->json('data.__type');
- expect($type)->not->toBeNull()
- ->and($type['name'])->toBe('CustomerProfile');
- $fieldNames = array_column($type['fields'], 'name');
- expect($fieldNames)
- ->toContain('id')
- ->toContain('firstName')
- ->toContain('lastName')
- ->toContain('email')
- ->toContain('phone')
- ->toContain('gender')
- ->toContain('dateOfBirth')
- ->toContain('status')
- ->toContain('subscribedToNewsLetter')
- ->toContain('isVerified')
- ->toContain('isSuspended')
- ->toContain('image');
- }
- /**
- * Test: Update mutation input has expected fields
- */
- public function test_update_mutation_input_has_expected_fields(): void
- {
- $query = <<<'GQL'
- {
- __type(name: "createCustomerProfileUpdateInput") {
- name
- inputFields {
- name
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertSuccessful();
- $type = $response->json('data.__type');
- expect($type)->not->toBeNull();
- $fieldNames = array_column($type['inputFields'], 'name');
- expect($fieldNames)
- ->toContain('firstName')
- ->toContain('lastName')
- ->toContain('email')
- ->toContain('phone')
- ->toContain('gender')
- ->toContain('dateOfBirth')
- ->toContain('password')
- ->toContain('confirmPassword');
- }
- /**
- * Test: Delete mutation exists in schema
- */
- public function test_delete_mutation_exists_in_schema(): void
- {
- $query = <<<'GQL'
- {
- __schema {
- mutationType {
- fields {
- name
- }
- }
- }
- }
- GQL;
- $response = $this->graphQL($query);
- $response->assertSuccessful();
- $mutationNames = array_column(
- $response->json('data.__schema.mutationType.fields'),
- 'name'
- );
- expect($mutationNames)
- ->toContain('createCustomerProfileUpdate')
- ->toContain('createCustomerProfileDelete');
- }
- }
|