actingAsApiAdministrator(); $roles = $this->seedApiRoles(); $createPayload = $this->validUserPayload((int) $roles['parent']->id, [ 'email' => 'api-user-crud@example.test', 'firstname' => 'Original', ]); $create = $this->postJson('/api/v1/users', $createPayload) ->assertCreated() ->assertJsonPath('ok', true); $userId = (int) $create->json('user_id'); $this->assertGreaterThan(0, $userId); $created = User::query()->findOrFail($userId); $this->assertSame('api-user-crud@example.test', $created->email); $this->assertTrue(Hash::check('password', (string) $created->password)); $this->assertSame(['parent'], $created->roleNames()); $this->getJson('/api/v1/users') ->assertOk() ->assertJsonPath('ok', true) ->assertJsonFragment(['email' => 'api-user-crud@example.test']); $this->putJson("/api/v1/users/$userId", [ 'firstname' => 'Updated', 'status' => 'Inactive', ]) ->assertOk() ->assertJsonPath('ok', true); $this->assertDatabaseHas('users', [ 'id' => $userId, 'firstname' => 'Updated', 'status' => 'Inactive', ]); $this->deleteJson("/api/v1/users/$userId") ->assertOk() ->assertJsonPath('ok', true); } public function test_user_creation_validates_required_payload_and_unique_email(): void { $this->actingAsApiAdministrator(); $roles = $this->seedApiRoles(); $this->postJson('/api/v1/users', []) ->assertStatus(422) ->assertJsonValidationErrors(['firstname', 'lastname', 'cellphone', 'email', 'address_street', 'city', 'state', 'zip', 'accept_school_policy', 'role_id', 'password', 'semester']); User::factory()->create(['email' => 'already-used@example.test']); $this->postJson('/api/v1/users', $this->validUserPayload((int) $roles['teacher']->id, [ 'email' => 'already-used@example.test', ])) ->assertStatus(422) ->assertJsonValidationErrors(['email']); } public function test_user_creation_rejects_nonexistent_role_id(): void { $this->actingAsApiAdministrator(); $this->postJson('/api/v1/users', $this->validUserPayload(999999)) ->assertStatus(422) ->assertJsonValidationErrors(['role_id']); } }