seed(CityWorldSeeder::class); $this->admin = User::factory()->admin()->create(); foreach (LegalDocument::where('is_current', true)->pluck('id') as $docId) { UserConsent::create([ 'user_id' => $this->admin->id, 'legal_document_id' => $docId, 'accepted_at' => now(), 'ip_address' => '127.0.0.1', 'user_agent' => 'phpunit', 'source' => 'web_form', ]); } $this->actingAs($this->admin); } protected User $admin; /** * Admin can create a new city with its own bounds. */ public function test_create_city(): void { $before = City::count(); $this->post(route('admin.cities.store'), ['name' => 'Nova Cidade']) ->assertRedirect(route('admin.cities.index')); $this->assertSame($before + 1, City::count()); $city = City::where('name', 'Nova Cidade')->first(); $this->assertNotNull($city); $this->assertFalse($city->is_active); $this->assertSame(-80.0, $city->bounds_min_x); $this->assertSame(80.0, $city->bounds_max_x); } /** * Expanding a city grows its maximum bounds by one grid step. */ public function test_expand_city_bounds(): void { $city = City::where('slug', 'city10')->firstOrFail(); $beforeMax = $city->bounds_max_x; $this->post(route('admin.cities.expand', $city)) ->assertRedirect(route('admin.cities.index')); $city->refresh(); $this->assertSame($beforeMax + 40, $city->bounds_max_x); $this->assertSame(1, $city->expansions); } /** * Expansion is capped to protect map generation. */ public function test_expand_capped(): void { $city = City::where('slug', 'city10')->firstOrFail(); $city->forceFill(['expansions' => City::MAX_EXPANSIONS])->save(); $this->from(route('admin.cities.index')) ->post(route('admin.cities.expand', $city)) ->assertSessionHasErrors('city'); } /** * City layout for a second city uses its own bounds. */ public function test_city_data_for_second_city(): void { $other = City::create([ 'name' => 'Cidade B', 'slug' => 'cidade-b', 'bounds_min_x' => 0, 'bounds_max_x' => 120, 'bounds_min_z' => 0, 'bounds_max_z' => 80, 'is_active' => false, 'expansions' => 0, ]); $response = $this->getJson('/city/data?city=cidade-b'); $response->assertOk()->assertJsonPath('city.slug', 'cidade-b'); $this->assertNotEmpty($response->json('layout.roads')); } }