district = District::factory()->create(['shortname' => 'ТСТОКР', 'name' => 'Тестовый округ']); } protected function tearDown(): void { if (isset($this->tempFilePath) && file_exists($this->tempFilePath)) { unlink($this->tempFilePath); } parent::tearDown(); } public function test_import_creates_new_areas(): void { $this->createTestFile([ ['', 'ТестТверской', 'ТСТОКР', $this->district->id], ['', 'ТестАрбат', 'ТСТОКР', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(2, $result['imported']); $this->assertDatabaseHas('areas', ['name' => 'ТестТверской', 'district_id' => $this->district->id]); $this->assertDatabaseHas('areas', ['name' => 'ТестАрбат', 'district_id' => $this->district->id]); } public function test_import_updates_existing_areas_by_id(): void { $area = Area::factory()->create([ 'name' => 'Старое название', 'district_id' => $this->district->id, ]); $newDistrict = District::factory()->create(['shortname' => 'САО']); $this->createTestFile([ [$area->id, 'Новое название', 'САО', $newDistrict->id], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['updated']); $this->assertDatabaseHas('areas', [ 'id' => $area->id, 'name' => 'Новое название', 'district_id' => $newDistrict->id, ]); } public function test_import_updates_existing_areas_by_name_and_district(): void { $area = Area::factory()->create([ 'name' => 'Тверской', 'district_id' => $this->district->id, ]); $this->createTestFile([ ['', 'Тверской', 'ЦАО', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['updated']); } public function test_import_finds_district_by_shortname(): void { $this->createTestFile([ ['', 'ТестовыйИмп1', 'ТСТОКР', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['imported']); $this->assertDatabaseHas('areas', [ 'name' => 'ТестовыйИмп1', 'district_id' => $this->district->id, ]); } public function test_import_finds_district_by_id(): void { $this->createTestFile([ ['', 'Тестовый', '', $this->district->id], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['imported']); $this->assertDatabaseHas('areas', [ 'name' => 'Тестовый', 'district_id' => $this->district->id, ]); } public function test_import_skips_rows_without_district(): void { $this->createTestFile([ ['', 'Район без округа', '', ''], ['', 'Район с несуществующим округом', 'НЕСУЩЕСТВУЮЩИЙ', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(0, $result['imported']); $this->assertEquals(2, $result['skipped']); } public function test_import_skips_empty_rows(): void { $this->createTestFile([ ['', '', '', ''], ['', 'Тестовый', 'ЦАО', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['imported']); $this->assertEquals(1, $result['skipped']); } public function test_import_restores_soft_deleted_areas(): void { $area = Area::factory()->create([ 'name' => 'Удалённый', 'district_id' => $this->district->id, ]); $area->delete(); $this->createTestFile([ [$area->id, 'Восстановленный', 'ЦАО', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['updated']); $this->assertDatabaseHas('areas', [ 'id' => $area->id, 'name' => 'Восстановленный', 'deleted_at' => null, ]); } public function test_import_is_case_insensitive_for_district_shortname(): void { $this->createTestFile([ ['', 'ТестовыйИмп2', 'тстокр', ''], // lowercase ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertTrue($result['success']); $this->assertEquals(1, $result['imported']); $this->assertDatabaseHas('areas', [ 'name' => 'ТестовыйИмп2', 'district_id' => $this->district->id, ]); } public function test_import_returns_logs(): void { $this->createTestFile([ ['', 'Тестовый', 'ЦАО', ''], ]); $service = new ImportAreasService($this->tempFilePath, 1); $result = $service->handle(); $this->assertArrayHasKey('logs', $result); $this->assertNotEmpty($result['logs']); } private function createTestFile(array $rows): void { $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Headers $sheet->setCellValue('A1', 'ID'); $sheet->setCellValue('B1', 'Название'); $sheet->setCellValue('C1', 'Округ (сокращение)'); $sheet->setCellValue('D1', 'ID округа'); // Data rows $rowNum = 2; foreach ($rows as $row) { $sheet->setCellValue('A' . $rowNum, $row[0] ?? ''); $sheet->setCellValue('B' . $rowNum, $row[1] ?? ''); $sheet->setCellValue('C' . $rowNum, $row[2] ?? ''); $sheet->setCellValue('D' . $rowNum, $row[3] ?? ''); $rowNum++; } $this->tempFilePath = sys_get_temp_dir() . '/test_areas_' . uniqid() . '.xlsx'; $writer = new Xlsx($spreadsheet); $writer->save($this->tempFilePath); } }