createLegacyTables(); } public function testImportMapsBooks(): void { $this->addLegacyBook(['id' => 0, 'tytul' => 'Zerowa', 'autor' => 'A', 'jezyk' => 'polski', 'rok' => 2005, 'miejsce' => 'Wrocław', 'wydawnictwo' => 'W', 'wydanie' => '2', 'ISBN' => '9788373843455', 'regal' => 'HOL', 'polka' => '4', 'rzad' => '1']); $this->addLegacyBook(['id' => 1, 'tytul' => 'Bez danych', 'autor' => 'B', 'jezyk' => '', 'rok' => 0]); $this->addLegacyBook(['id' => 2, 'tytul' => 'Częściowa lokalizacja', 'autor' => 'C', 'jezyk' => 'eng', 'regal' => 'K', 'ISBN' => '306406152', 'ISSN' => '3161234']); $this->addLegacyBook(['id' => 3, 'tytul' => 'Wycofana', 'autor' => 'D', 'jezyk' => 'polski', 'regal' => 'JK', 'polka' => '1', 'ISBN' => '9788303001795', 'wycofana' => '1', 'powod' => 'Zniszczona']); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); $this->entityManager()->clear(); $full = $this->findBook(0); self::assertSame('Zerowa', $full?->getTitle()); self::assertSame('polski', $full?->getLanguage()); self::assertSame(2005, $full?->getPublicationYear()); self::assertSame('9788373843455', $full?->getIsbn()); self::assertSame('HOL/4/1', $full?->getPlacement()); $sparse = $this->findBook(1); self::assertNull($sparse?->getLanguage()); self::assertNull($sparse?->getPublicationYear()); self::assertNull($sparse?->getPlacement()); $partial = $this->findBook(2); self::assertSame('K', $partial?->getPlacement()); self::assertSame('9780306406157', $partial?->getIsbn()); self::assertSame('03161234', $partial?->getIssn()); $ousted = $this->entityManager()->find(OustedBook::class, 3); self::assertSame('Zniszczona', $ousted?->getReason()); self::assertSame('JK/1', $ousted?->getPlacement()); self::assertSame('9788303001795', $ousted?->getIsbn()); self::assertNull($this->findBook(3)); } public function testInvalidIsbnIsKeptAsATextLabel(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Zły numer', 'autor' => 'A', 'jezyk' => 'polski', 'ISBN' => '9788373843456']); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); self::assertStringContainsString('book 1: 9788373843456', $tester->getDisplay()); $book = $this->findBook(1); self::assertNull($book?->getIsbn()); self::assertSame('9788373843456', $book?->getTextLabels()[0]->getLabel()); } public function testImportedBooksAreSearchable(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Łódź', 'autor' => 'A', 'jezyk' => 'polski']); $this->runImport(); $crawler = $this->client->request('GET', '/search', ['q' => 'Łódź']); self::assertCount(1, $crawler->filter('.tile')); } public function testImportMapsLoans(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Na półce', 'autor' => 'A', 'jezyk' => 'polski']); $this->addLegacyBook(['id' => 2, 'tytul' => 'Wycofana', 'autor' => 'B', 'jezyk' => 'polski', 'wycofana' => '1', 'powod' => 'Prezent']); $this->legacy->insert('pozycz', ['id' => 1, 'kto' => 'Osoba A', 'od' => 1556909792]); $this->legacy->insert('pozycz_historia', ['id' => 1, 'kto' => 'Osoba B', 'od' => 1212076475, '"do"' => 1212176475]); $this->legacy->insert('pozycz_historia', ['id' => 2, 'kto' => 'Osoba C', 'od' => 1212076475, '"do"' => 1212176475]); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); $book = $this->findBook(1); self::assertSame('Osoba A', $book?->getBorrow()?->getWho()); self::assertSame(1556909792, $book?->getBorrow()?->getAt()->getTimestamp()); $entry = $book?->getBorrowHistory()->first(); self::assertSame('Osoba B', $entry->getWho()); self::assertSame(1212176475, $entry->getTill()->getTimestamp()); self::assertCount(1, $this->entityManager()->find(OustedBook::class, 2)?->getBorrowHistory() ?? []); self::assertStringNotContainsString('left out', $tester->getDisplay()); } public function testRowsWithoutAPlaceInTheNewSchemaAreReported(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Dwa razy', 'autor' => 'A', 'jezyk' => 'polski']); $this->addLegacyBook(['id' => 2, 'tytul' => 'Wycofana', 'autor' => 'B', 'jezyk' => 'polski', 'wycofana' => '1', 'powod' => 'Prezent']); $this->legacy->insert('pozycz', ['id' => 1, 'kto' => 'Starsze', 'od' => 1000]); $this->legacy->insert('pozycz', ['id' => 1, 'kto' => 'Nowsze', 'od' => 2000]); $this->legacy->insert('pozycz', ['id' => 2, 'kto' => 'Osoba', 'od' => 1000]); $this->legacy->insert('pozycz', ['id' => 99, 'kto' => 'Osoba', 'od' => 1000]); $this->legacy->insert('pozycz_historia', ['id' => 99, 'kto' => 'Osoba', 'od' => 1000, '"do"' => 2000]); $this->legacy->insert('pozycz_historia', ['id' => 1, 'kto' => 'Osoba', 'od' => 1000, '"do"' => null]); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); self::assertSame('Nowsze', $this->findBook(1)?->getBorrow()?->getWho()); $display = preg_replace('/\s+/', ' ', $tester->getDisplay()); self::assertStringContainsString('5 rows were left out', $display); self::assertStringContainsString('book 1 has more than one open loan', $display); self::assertStringContainsString('book 2 is on loan but ousted', $display); self::assertStringContainsString('pozycz: book 99 does not exist', $display); self::assertStringContainsString('pozycz_historia: book 99 does not exist', $display); self::assertStringContainsString('has no end date', $display); } public function testDryRunSavesNothing(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Książka', 'autor' => 'A', 'jezyk' => 'polski']); $tester = $this->runImport(['--dry-run' => true]); $tester->assertCommandIsSuccessful(); self::assertStringContainsString('nothing was saved', $tester->getDisplay()); self::assertSame(0, $this->entityManager()->getRepository(Book::class)->count()); } public function testImportKeepsBooksAlreadyInTheTarget(): void { $this->createBook(1, 'Edited title'); $ousted = new OustedBook('Lost')->setId(2)->setTitle('Ousted since')->setAuthor('B'); $this->entityManager()->persist($ousted); $this->entityManager()->flush(); $this->addLegacyBook(['id' => 1, 'tytul' => 'Legacy title', 'autor' => 'A', 'jezyk' => 'polski']); $this->addLegacyBook(['id' => 2, 'tytul' => 'Na półce', 'autor' => 'B', 'jezyk' => 'polski']); $this->addLegacyBook(['id' => 3, 'tytul' => 'Nowa', 'autor' => 'C', 'jezyk' => 'polski']); $this->legacy->insert('pozycz', ['id' => 1, 'kto' => 'Osoba A', 'od' => 1000]); $this->legacy->insert('pozycz_historia', ['id' => 2, 'kto' => 'Osoba B', 'od' => 1000, '"do"' => 2000]); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); $book = $this->findBook(1); self::assertSame('Edited title', $book?->getTitle()); self::assertNull($book?->getBorrow()); self::assertNull($this->findBook(2)); self::assertCount(0, $this->entityManager()->find(OustedBook::class, 2)?->getBorrowHistory() ?? [1]); self::assertSame('Nowa', $this->findBook(3)?->getTitle()); self::assertMatchesRegularExpression('/already in target, kept\s+2/', $tester->getDisplay()); self::assertStringNotContainsString('left out', $tester->getDisplay()); } public function testRunningTheImportTwiceChangesNothing(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Książka', 'autor' => 'A', 'jezyk' => 'polski', 'ISBN' => '9788373843456']); $this->addLegacyBook(['id' => 2, 'tytul' => 'Wycofana', 'autor' => 'B', 'jezyk' => 'polski', 'wycofana' => '1', 'powod' => 'Prezent']); $this->legacy->insert('pozycz', ['id' => 1, 'kto' => 'Osoba A', 'od' => 2000]); $this->legacy->insert('pozycz_historia', ['id' => 1, 'kto' => 'Osoba B', 'od' => 1000, '"do"' => 1500]); $this->legacy->insert('pozycz_historia', ['id' => 2, 'kto' => 'Osoba C', 'od' => 1000, '"do"' => 1500]); $this->runImport()->assertCommandIsSuccessful(); $tester = $this->runImport(); $tester->assertCommandIsSuccessful(); self::assertSame(1, $this->entityManager()->getRepository(Book::class)->count()); self::assertSame(1, $this->entityManager()->getRepository(OustedBook::class)->count()); $book = $this->findBook(1); self::assertSame('Osoba A', $book?->getBorrow()?->getWho()); self::assertCount(1, $book?->getBorrowHistory() ?? []); self::assertCount(1, $book?->getTextLabels() ?? []); self::assertCount(1, $this->entityManager()->find(OustedBook::class, 2)?->getBorrowHistory() ?? []); self::assertMatchesRegularExpression('/already in target, kept\s+2/', $tester->getDisplay()); } public function testFailureLeavesTheTargetUntouched(): void { $this->addLegacyBook(['id' => 1, 'tytul' => 'Książka', 'autor' => 'A', 'jezyk' => 'polski']); $this->legacy->executeStatement('ALTER TABLE pozycz RENAME TO pozycz_missing'); try { $this->runImport(); self::fail('The import should have failed.'); } catch (\Doctrine\DBAL\Exception) { self::assertSame(0, $this->entityManager()->getRepository(Book::class)->count()); } } /** * @param array $row */ private function addLegacyBook(array $row): void { $this->legacy->insert('ksiazki', $row); } /** * @param array $input */ private function runImport(array $input = []): CommandTester { $application = new Application(static::$kernel); $tester = new CommandTester($application->find('app:import-legacy')); $tester->execute($input); return $tester; } }