$name]; $slug = Str::slug(is_array($name) ? ($name['en'] ?? reset($name)) : $name); return Collection::create(array_merge([ 'name' => $nameValue, 'slug' => $slug, 'is_visible' => true, 'sort_order' => 1, ], $attributes)); } function createProductForCollection(array $attributes = []): Product { $name = $attributes['name'] ?? 'Test Product '.Str::random(5); return Product::create(array_merge([ 'name' => $name, 'slug' => Str::slug($name), 'is_visible' => true, 'price_amount' => 100.00, 'stock' => 10, 'parent_id' => null, ], $attributes)); } test('can list collections', function () { // Arrange createCollection(['name' => 'Collection 1']); createCollection(['name' => 'Collection 2']); createCollection(['name' => 'Collection 3']); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson('/api/v1/collections'); // Assert $response->assertOk() ->assertJsonStructure([ 'data' => [ '*' => [ 'id', 'name', 'slug', ], ], ]); $this->assertCount(3, $response->json('data')); }); test('does not list invisible collections', function () { // Arrange createCollection(['name' => 'Visible', 'is_visible' => true]); createCollection(['name' => 'Invisible', 'is_visible' => false]); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson('/api/v1/collections'); // Assert $response->assertOk(); $this->assertCount(1, $response->json('data')); $this->assertEquals('Visible', $response->json('data.0.name')); }); test('can list paginated collections', function () { // Arrange $collections = collect(range(1, 10))->map(fn () => createCollection()); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson('/api/v1/collections-paginated?perPage=5'); // Assert $response->assertOk() ->assertJsonStructure([ 'data', ]); $this->assertCount(5, $response->json('data')); }); test('can show a specific collection', function () { // Arrange $collection = createCollection(['name' => 'Test Collection']); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson("/api/v1/collections/{$collection->id}"); // Assert $response->assertOk() ->assertJson([ 'data' => [ 'id' => $collection->id, 'name' => 'Test Collection', ], ]); }); test('returns 404 for non-existent collection', function () { // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson('/api/v1/collections/99999'); // Assert $response->assertNotFound(); }); test('returns 404 for invalid collection id format', function () { // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson('/api/v1/collections/invalid-id'); // Assert $response->assertNotFound(); }); test('can list products for a collection', function () { // Arrange $collection = createCollection(); $products = collect(range(1, 5))->map(fn () => createProductForCollection()); // Attach products to collection $collection->products()->attach($products->pluck('id')); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson("/api/v1/collections/{$collection->id}/products"); // Assert $response->assertOk() ->assertJsonStructure([ 'data' => [ '*' => [ 'id', 'name', ], ], ]); $this->assertCount(5, $response->json('data')); }); test('does not list invisible products for a collection', function () { // Arrange $collection = createCollection(); $visibleProduct = createProductForCollection(['is_visible' => true]); $invisibleProduct = createProductForCollection(['is_visible' => false]); // Attach products to collection $collection->products()->attach([$visibleProduct->id, $invisibleProduct->id]); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson("/api/v1/collections/{$collection->id}/products"); // Assert $response->assertOk(); $this->assertCount(1, $response->json('data')); $this->assertEquals($visibleProduct->id, $response->json('data.0.id')); }); test('returns empty product list for collection with no products', function () { // Arrange $collection = createCollection(); // Act $response = $this->withHeaders([ 'Api-Token' => 'test-token', 'Accept' => 'application/json', ])->getJson("/api/v1/collections/{$collection->id}/products"); // Assert $response->assertOk(); $this->assertCount(0, $response->json('data')); });