diff --git a/app/Http/Controllers/Api/CityController.php b/app/Http/Controllers/Api/CityController.php index b17573e..d637fa7 100644 --- a/app/Http/Controllers/Api/CityController.php +++ b/app/Http/Controllers/Api/CityController.php @@ -30,10 +30,13 @@ class CityController extends Controller */ #[QueryParameter(name: 'search', description: 'Teilstring-Suche im Namen der Stadt.', required: false, type: 'string')] #[QueryParameter(name: 'selected', description: 'Lädt gezielt die angegebenen IDs.', required: false, type: 'array')] + #[QueryParameter(name: 'withDetails', description: 'Presence-Flag: liefert zusätzlich Country-Code und Flaggen-URL und hebt die Begrenzung auf 10 Einträge auf.', required: false, type: 'string')] public function index(Request $request) { + $withDetails = $request->exists('withDetails'); + return City::query() - ->with(['country:id,name']) + ->with([$withDetails ? 'country:id,name,code' : 'country:id,name']) ->select('id', 'name', 'country_id') ->orderBy('name') ->when( @@ -44,9 +47,16 @@ class CityController extends Controller ->when( $request->exists('selected'), fn (Builder $query) => $query->whereIn('id', $this->numericIds($request)), - fn (Builder $query) => $query->limit(10) + fn (Builder $query) => $withDetails ? $query : $query->limit(10) ) - ->get(); + ->get() + ->map(function (City $city) use ($withDetails) { + if ($withDetails) { + $city->flag = asset('vendor/blade-country-flags/4x3-'.$city->country->code.'.svg'); + } + + return $city; + }); } /** diff --git a/app/Http/Controllers/Api/VenueController.php b/app/Http/Controllers/Api/VenueController.php index 00ef62b..229b213 100644 --- a/app/Http/Controllers/Api/VenueController.php +++ b/app/Http/Controllers/Api/VenueController.php @@ -32,6 +32,7 @@ class VenueController extends Controller */ #[QueryParameter(name: 'search', description: 'Teilstring-Suche im Namen des Veranstaltungsortes.', required: false, type: 'string')] #[QueryParameter(name: 'selected', description: 'Lädt gezielt die angegebenen Veranstaltungsort-IDs (umgeht die Begrenzung auf 10 Einträge).', required: false, type: 'array')] + #[QueryParameter(name: 'withDetails', description: 'Presence-Flag: hebt die Begrenzung auf 10 Einträge auf.', required: false, type: 'string')] public function index(Request $request) { return Venue::query() @@ -46,7 +47,7 @@ class VenueController extends Controller ->when( $request->exists('selected'), fn (Builder $query) => $query->whereIn('id', $this->numericIds($request)), - fn (Builder $query) => $query->limit(10) + fn (Builder $query) => $request->exists('withDetails') ? $query : $query->limit(10) ) ->get() ->map(function (Venue $venue) { diff --git a/tests/Feature/Api/CityVenueReadApiTest.php b/tests/Feature/Api/CityVenueReadApiTest.php new file mode 100644 index 0000000..c5282b0 --- /dev/null +++ b/tests/Feature/Api/CityVenueReadApiTest.php @@ -0,0 +1,50 @@ +count(11)->create(['country_id' => Country::factory()->create()->id]); + + $this->getJson('/api/cities') + ->assertSuccessful() + ->assertJsonCount(10); +}); + +it('returns all cities with country code and flag on GET /api/cities?withDetails', function () { + $cities = City::factory()->count(11)->create(['country_id' => Country::factory()->create()->id]); + + $response = $this->getJson('/api/cities?withDetails') + ->assertSuccessful() + ->assertJsonCount(11); + + $first = collect($response->json())->firstWhere('id', $cities->first()->id); + + expect($first) + ->toHaveKeys(['id', 'name', 'country_id', 'country', 'flag']) + ->and($first['country'])->toHaveKeys(['id', 'name', 'code']) + ->and($first['flag'])->toContain('4x3-'.$cities->first()->country->code.'.svg'); +}); + +it('limits GET /api/venues to 10 entries without withDetails', function () { + Venue::factory()->count(11)->create(['city_id' => City::factory()->create()->id]); + + $this->getJson('/api/venues') + ->assertSuccessful() + ->assertJsonCount(10); +}); + +it('returns all venues on GET /api/venues?withDetails', function () { + $venues = Venue::factory()->count(11)->create(['city_id' => City::factory()->create()->id]); + + $response = $this->getJson('/api/venues?withDetails') + ->assertSuccessful() + ->assertJsonCount(11); + + $first = collect($response->json())->firstWhere('id', $venues->first()->id); + + expect($first) + ->toHaveKeys(['id', 'name', 'city_id', 'flag', 'description', 'city']) + ->and($first['city']['country'])->toHaveKeys(['id', 'name', 'code']); +});