user = User::factory()->create([ 'first_name' => 'John', 'last_name' => 'Doe', 'phone_number' => 61929248, 'options' => ['address' => '123 Main St'], 'password' => 'password', ]); }); test('unauthenticated user cannot access profile', function () { $response = $this->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->getJson('/api/v1/profile'); $response->assertStatus(401); }); test('authenticated user can view profile', function () { $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->getJson('/api/v1/profile'); $response->assertStatus(200) ->assertJson([ 'data' => [ 'first_name' => 'John', 'last_name' => 'Doe', 'phone_number' => 61929248, 'address' => '123 Main St', ], ]); }); test('unauthenticated user cannot update profile', function () { $response = $this->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => 'Jane', 'phone_number' => 61929248, 'address' => '456 Another St', ]); $response->assertStatus(401); }); test('authenticated user can update profile', function () { $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => 'Jane', 'phone_number' => 61929248, 'address' => '456 Another St', ]); $response->assertStatus(200); $this->assertDatabaseHas('users', [ 'id' => $this->user->id, 'first_name' => 'Jane', 'phone_number' => 61929248, ]); $this->user->refresh(); expect($this->user->options['address'])->toBe('456 Another St'); }); test('profile update validation fails with invalid data', function () { $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => '', // Required 'phone_number' => 'invalid', // Integer required 'address' => '', // Required ]); $response->assertStatus(422) ->assertJsonValidationErrors(['name', 'phone_number', 'address']); }); test('profile update validation fails with invalid phone number range', function () { $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => 'Jane', 'phone_number' => 12345, // Invalid range 'address' => '456 Another St', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['phone_number']); }); test('profile update fails if phone number is already taken by another user', function () { User::factory()->create([ 'phone_number' => 61929248, 'password' => 'password', ]); $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => 'Jane', 'phone_number' => 61929248, // Taken 'address' => '456 Another St', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['phone_number']); }); test('profile update succeeds if phone number is unchanged', function () { $response = $this->actingAs($this->user, 'sanctum') ->withHeaders(['Api-Token' => config('ecommerce.api.token')]) ->postJson('/api/v1/profile', [ 'name' => 'Jane', 'phone_number' => $this->user->phone_number, // Same number 'address' => 'New Address', ]); $response->assertStatus(200); $this->user->refresh(); expect($this->user->first_name)->toBe('Jane'); expect($this->user->options['address'])->toBe('New Address'); });