'role-' . uniqid(), 'guard_name' => 'admin']); foreach ($permissions as $permission) { $role->givePermissionTo(Permission::firstOrCreate(['name' => $permission, 'guard_name' => 'admin'])); } $admin = User::factory()->create(); $admin->assignRole($role); return $admin; } public function test_stars_and_tags_customer_then_filters_list(): void { $admin = $this->admin('customer.view', 'customer.edit'); $customer = Customer::factory()->create(); Customer::factory()->create(); $tagId = $this->actingAs($admin, 'admin') ->postJson('/api/v1/administrator/tags', ['title' => 'VIP', 'color' => '#ff0000']) ->assertCreated() ->json('data.id'); $this->actingAs($admin, 'admin') ->patchJson("/api/v1/administrator/marks/customers/{$customer->uuid}", [ 'is_starred' => true, 'tag_ids' => [$tagId], ]) ->assertOk() ->assertJsonPath('data.is_starred', true) ->assertJsonPath('data.tags.0.title', 'VIP'); $this->actingAs($admin, 'admin') ->getJson('/api/v1/administrator/customers?starred=1') ->assertOk() ->assertJsonCount(1, 'data.items') ->assertJsonPath('data.items.0.uuid', $customer->uuid) ->assertJsonPath('data.items.0.tags.0.color', '#ff0000'); $this->actingAs($admin, 'admin') ->getJson("/api/v1/administrator/customers?tag_ids[]={$tagId}") ->assertJsonCount(1, 'data.items'); $this->actingAs($admin, 'admin') ->patchJson("/api/v1/administrator/marks/customers/{$customer->uuid}", ['tag_ids' => []]) ->assertOk() ->assertJsonCount(0, 'data.tags'); $this->assertTrue($customer->fresh()->is_starred); } public function test_requires_module_edit_permission_and_valid_input(): void { Permission::firstOrCreate(['name' => 'customer.edit', 'guard_name' => 'admin']); $customer = Customer::factory()->create(); $this->actingAs($this->admin('order.edit'), 'admin') ->patchJson("/api/v1/administrator/marks/customers/{$customer->uuid}", ['is_starred' => true]) ->assertForbidden(); $admin = $this->admin('customer.edit'); $this->actingAs($admin, 'admin') ->patchJson("/api/v1/administrator/marks/customers/{$customer->uuid}", ['tag_ids' => [999]]) ->assertUnprocessable(); $this->actingAs($admin, 'admin') ->postJson('/api/v1/administrator/tags', ['title' => 'X', 'color' => 'red;']) ->assertUnprocessable(); } public function test_deleting_tag_detaches_it(): void { $customer = Customer::factory()->create(); $tag = Tag::create(['title' => 'Nợ', 'color' => '#000000']); $customer->tags()->attach($tag); $this->actingAs($this->admin('setting.manager'), 'admin') ->deleteJson("/api/v1/administrator/tags/{$tag->id}") ->assertOk(); $this->assertDatabaseCount('taggables', 0); } public static function listEndpoints(): array { return [ 'services' => ['services', Service::class, '/api/v1/administrator/services', 'service'], 'orders' => ['orders', Order::class, '/api/v1/administrator/orders', 'domain'], 'invoices' => ['invoices', Invoice::class, '/api/v1/administrator/invoices', 'domain'], ]; } /** * @param class-string<\Illuminate\Database\Eloquent\Model> $model */ #[DataProvider('listEndpoints')] public function test_marks_and_filters_billing_lists(string $type, string $model, string $listUrl, string $productType): void { Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']); $admin = User::factory()->create(); $admin->assignRole('Full Administrator'); $customer = Customer::factory()->create(); $product = Product::factory()->create(['product_type' => $productType]); foreach (['a.vn', 'b.vn'] as $serverName) { $this->actingAs($admin, 'admin')->postJson( "/api/v1/administrator/customers/{$customer->uuid}/services", ['product_id' => $product->id, 'payment_method' => 'transfer', 'server_name' => $serverName, 'price' => 0], )->assertCreated(); } $tag = Tag::create(['title' => 'Gấp', 'color' => '#fa8c16']); $target = $model::query()->latest('id')->firstOrFail(); $this->actingAs($admin, 'admin') ->patchJson("/api/v1/administrator/marks/{$type}/{$target->id}", ['is_starred' => true, 'tag_ids' => [$tag->id]]) ->assertOk(); $items = $this->actingAs($admin, 'admin') ->getJson("{$listUrl}?starred=1&tag_ids[]={$tag->id}") ->assertOk() ->json('data.items'); $this->assertSame([$target->id], array_column($items, 'id')); $this->assertTrue($items[0]['is_starred']); $this->assertSame('Gấp', $items[0]['tags'][0]['title']); } }