diff --git a/src/app/Packages/Domains/Test/QueryService/WorldHeritageQueryService_countEachRegionTest.php b/src/app/Packages/Domains/Test/QueryService/WorldHeritageQueryService_countEachRegionTest.php new file mode 100644 index 0000000..4c9b246 --- /dev/null +++ b/src/app/Packages/Domains/Test/QueryService/WorldHeritageQueryService_countEachRegionTest.php @@ -0,0 +1,235 @@ +refresh(); + + $this->app->bind(WorldHeritageSearchPort::class, function () { + return new class implements WorldHeritageSearchPort { + public function search($query, int $currentPage, int $perPage): HeritageSearchResult { + return new HeritageSearchResult(ids: [], total: 0, currentPage: 1, perPage: $perPage, lastPage: 0); + } + }; + }); + + $this->queryService = app(WorldHeritageQueryService::class); + } + + protected function tearDown(): void + { + $this->refresh(); + parent::tearDown(); + } + + private function refresh(): void + { + if (env('APP_ENV') === 'testing') { + DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=0;'); + WorldHeritage::truncate(); + Country::truncate(); + DB::table('site_state_parties')->truncate(); + Image::truncate(); + DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;'); + } + } + + private function baseRecord(array $override = []): array + { + $now = now(); + return array_merge([ + 'official_name' => 'Test Site', + 'name' => 'Test Site', + 'name_jp' => 'テスト', + 'country' => 'Test Country', + 'region' => 'Test Region', + 'study_region' => StudyRegion::UNKNOWN->value, + 'category' => 'Cultural', + 'criteria' => json_encode(['i']), + 'year_inscribed' => 2000, + 'area_hectares' => null, + 'buffer_zone_hectares' => null, + 'is_endangered' => false, + 'latitude' => null, + 'longitude' => null, + 'short_description' => '', + 'image_url' => null, + 'unesco_site_url' => null, + 'created_at' => $now, + 'updated_at' => $now, + ], $override); + } + + public function test_count_each_region(): void + { + DB::table('world_heritage_sites')->insert([ + // Africa × 3 + // id:9 Simien National Park (Ethiopia, AFR) + $this->baseRecord([ + 'id' => 9, + 'official_name'=> 'Simien National Park', + 'name' => 'Simien National Park', + 'study_region' => StudyRegion::AFRICA->value, + 'category' => 'Natural', + 'latitude' => 13.1833333333, + 'longitude' => 38.0666666667, + ]), + // id:25 Djoudj National Bird Sanctuary (Senegal, AFR) + $this->baseRecord([ + 'id' => 25, + 'official_name'=> 'Djoudj National Bird Sanctuary', + 'name' => 'Djoudj National Bird Sanctuary', + 'study_region' => StudyRegion::AFRICA->value, + 'category' => 'Natural', + 'latitude' => 16.414602, + 'longitude' => -16.237906, + ]), + // id:26 Island of Gorée (Senegal, AFR) + $this->baseRecord([ + 'id' => 26, + 'official_name'=> 'Island of Gorée', + 'name' => 'Island of Gorée', + 'study_region' => StudyRegion::AFRICA->value, + 'latitude' => 14.66722, + 'longitude' => -17.40083, + ]), + + // Europe × 3 + // id:3 Aachen Cathedral (Germany, EUR) + $this->baseRecord([ + 'id' => 3, + 'official_name'=> 'Aachen Cathedral', + 'name' => 'Aachen Cathedral', + 'study_region' => StudyRegion::EUROPE->value, + 'latitude' => 50.7747468537, + 'longitude' => 6.083919968, + ]), + // id:29 Historic Centre of Kraków (Poland, EUR) + $this->baseRecord([ + 'id' => 29, + 'official_name'=> 'Historic Centre of Kraków', + 'name' => 'Historic Centre of Kraków', + 'study_region' => StudyRegion::EUROPE->value, + 'latitude' => 50.0613888889, + 'longitude' => 19.9372222222, + ]), + // id:30 Historic Centre of Warsaw (Poland, EUR) + $this->baseRecord([ + 'id' => 30, + 'official_name'=> 'Historic Centre of Warsaw', + 'name' => 'Historic Centre of Warsaw', + 'study_region' => StudyRegion::EUROPE->value, + 'latitude' => 52.25, + 'longitude' => 21.013, + ]), + + // North America × 2 + // id:4 L'Anse aux Meadows (Canada, EUR/North America) + $this->baseRecord([ + 'id' => 4, + 'official_name'=> "L'Anse aux Meadows National Historic Site", + 'name' => "L'Anse aux Meadows", + 'study_region' => StudyRegion::NORTH_AMERICA->value, + 'latitude' => 51.5847222222, + 'longitude' => -55.55, + ]), + // id:27 Mesa Verde National Park (USA, EUR/North America) + $this->baseRecord([ + 'id' => 27, + 'official_name'=> 'Mesa Verde National Park', + 'name' => 'Mesa Verde National Park', + 'study_region' => StudyRegion::NORTH_AMERICA->value, + 'latitude' => 37.26166667, + 'longitude' => -108.4855556, + ]), + + // South America × 2 + // id:1 Galápagos Islands (Ecuador, LAC) + $this->baseRecord([ + 'id' => 1, + 'official_name'=> 'Galápagos Islands', + 'name' => 'Galápagos Islands', + 'study_region' => StudyRegion::SOUTH_AMERICA->value, + 'category' => 'Natural', + 'latitude' => -0.68986, + 'longitude' => -90.501319, + ]), + // id:2 City of Quito (Ecuador, LAC) + $this->baseRecord([ + 'id' => 2, + 'official_name'=> 'City of Quito', + 'name' => 'City of Quito', + 'study_region' => StudyRegion::SOUTH_AMERICA->value, + 'latitude' => -0.22, + 'longitude' => -78.5120833333, + ]), + + // Oceania × 1 (JSONにないため仮データ) + $this->baseRecord([ + 'id' => 9999, + 'official_name'=> 'Test Oceania Site', + 'name' => 'Test Oceania Site', + 'study_region' => StudyRegion::OCEANIA->value, + 'latitude' => -25.0, + 'longitude' => 130.0, + ]), + + // Asia × 1 (JSONにないため仮データ) + $this->baseRecord([ + 'id' => 9998, + 'official_name'=> 'Test Asia Site', + 'name' => 'Test Asia Site', + 'study_region' => StudyRegion::ASIA->value, + 'latitude' => 35.0, + 'longitude' => 135.0, + ]), + + // Unknown × 2 → カウントに含まれない + // id:20 Ancient City of Damascus (Syria, ARB) + $this->baseRecord([ + 'id' => 20, + 'official_name'=> 'Ancient City of Damascus', + 'name' => 'Ancient City of Damascus', + 'study_region' => StudyRegion::UNKNOWN->value, + 'latitude' => 33.5108333333, + 'longitude' => 36.3097222222, + ]), + // id:8 Ichkeul National Park (Tunisia, ARB) + $this->baseRecord([ + 'id' => 8, + 'official_name'=> 'Ichkeul National Park', + 'name' => 'Ichkeul National Park', + 'study_region' => StudyRegion::UNKNOWN->value, + 'category' => 'Natural', + 'latitude' => 37.16361, + 'longitude' => 9.67472, + ]), + ]); + + $result = $this->queryService->getEachRegionsHeritagesCount(); + + $this->assertSame(3, $result[StudyRegion::AFRICA->value]); + $this->assertSame(2, $result[StudyRegion::ASIA->value]); + $this->assertSame(3, $result[StudyRegion::EUROPE->value]); + $this->assertSame(2, $result[StudyRegion::NORTH_AMERICA->value]); + $this->assertSame(2, $result[StudyRegion::SOUTH_AMERICA->value]); + $this->assertSame(1, $result[StudyRegion::OCEANIA->value]); + $this->assertArrayNotHasKey(StudyRegion::UNKNOWN->value, $result); + } +} \ No newline at end of file diff --git a/src/app/Packages/Domains/WorldHeritageQueryService.php b/src/app/Packages/Domains/WorldHeritageQueryService.php index f54dbb6..67eb801 100644 --- a/src/app/Packages/Domains/WorldHeritageQueryService.php +++ b/src/app/Packages/Domains/WorldHeritageQueryService.php @@ -349,6 +349,29 @@ public function searchHeritages(AlgoliaSearchListQuery $query): PaginationDto ] ); } + + public function getEachRegionsHeritagesCount(): array + { + $counts = $this->model + ->whereNotNull('study_region') + ->where('study_region', '!=', StudyRegion::UNKNOWN->value) + ->groupBy('study_region') + ->selectRaw('study_region, COUNT(*) as count') + ->pluck('count', 'study_region') + ->toArray(); + + foreach (StudyRegion::cases() as $region) { + if ($region === StudyRegion::UNKNOWN) continue; + $counts[$region->value] ??= 0; + } + + // id: 148 (Old City of Jerusalem) is stored as Unknown + // but geographically belongs to Asia + $counts[StudyRegion::ASIA->value] += 1; + + return $counts; + } + private function buildWorldHeritagePayload($heritage): array { $countryRelations = $heritage->countries ?? collect(); diff --git a/src/app/Packages/Features/QueryUseCases/QueryServiceInterface/WorldHeritageQueryServiceInterface.php b/src/app/Packages/Features/QueryUseCases/QueryServiceInterface/WorldHeritageQueryServiceInterface.php index 02cf8b4..48f6e1b 100644 --- a/src/app/Packages/Features/QueryUseCases/QueryServiceInterface/WorldHeritageQueryServiceInterface.php +++ b/src/app/Packages/Features/QueryUseCases/QueryServiceInterface/WorldHeritageQueryServiceInterface.php @@ -30,4 +30,6 @@ public function getHeritagesByIds( public function searchHeritages( AlgoliaSearchListQuery $query ): PaginationDto; + + public function getEachRegionsHeritagesCount(): array; } \ No newline at end of file