diff --git a/backend/tests/Feature/Database/TanachSeederTest.php b/backend/tests/Feature/Database/TanachSeederTest.php new file mode 100644 index 0000000..1cb44bb --- /dev/null +++ b/backend/tests/Feature/Database/TanachSeederTest.php @@ -0,0 +1,184 @@ + [ + 'Bereishis' => 50, + 'Shemos' => 40, + 'Vayikra' => 27, + 'Bamidbar' => 36, + 'Devarim' => 34, + ], + "Nevi'im" => [ + 'Yehoshua' => 24, + 'Shoftim' => 21, + 'Shmuel Alef' => 31, + 'Shmuel Beis' => 24, + 'Melachim Alef' => 22, + 'Melachim Beis' => 25, + 'Yeshayahu' => 66, + 'Yirmiyahu' => 52, + 'Yechezkel' => 48, + 'Hoshea' => 14, + 'Yoel' => 4, + 'Amos' => 9, + 'Ovadiah' => 1, + 'Yonah' => 4, + 'Michah' => 7, + 'Nachum' => 3, + 'Chavakuk' => 3, + 'Tzefaniah' => 3, + 'Chaggai' => 2, + 'Zechariah' => 14, + 'Malachi' => 3, + ], + 'Kesuvim' => [ + 'Tehillim' => 150, + 'Mishlei' => 31, + 'Iyov' => 42, + 'Shir HaShirim' => 8, + 'Rus' => 4, + 'Eichah' => 5, + 'Koheles' => 12, + 'Esther' => 10, + 'Daniel' => 12, + 'Ezra' => 10, + 'Nechemiah' => 13, + 'Divrei HaYamim Alef' => 29, + 'Divrei HaYamim Beis' => 36, + ], + ]; + + public function test_it_seeds_the_complete_tanach_idempotently(): void + { + $this->seed(TanachSeeder::class); + $this->seed(TanachSeeder::class); + + $this->assertDatabaseCount('users', 1); + $this->assertDatabaseCount('sets', 1); + $this->assertDatabaseCount('set_levels', 3); + $this->assertDatabaseCount('elements', 971); + + $user = app(UserRepository::class)->findByEmail( + new EmailAddress(UserSeeder::EMAIL), + ); + $this->assertNotNull($user); + + $tanach = $this->findTanach(); + $this->assertSame( + UserSeeder::EMAIL, + $tanach->getCreator()->getEmail()->value(), + ); + + $levels = app(SetLevelRepository::class)->findBySet($tanach); + $this->assertSame( + ['chelek', 'sefer', 'perek'], + array_map(function ($level): string { + return $level->getKind(); + }, $levels), + ); + + $elementRepository = app(ElementRepository::class); + $chelakim = $elementRepository->findTopLevelBySet($tanach); + $this->assertElements( + elements: $chelakim, + expectedNames: array_keys(self::SEFARIM_BY_CHELEK), + expectedKind: 'chelek', + ); + + $seferCount = 0; + $perekCount = 0; + + foreach ($chelakim as $chelek) { + $expectedSefarim = self::SEFARIM_BY_CHELEK[ + $chelek->getName() + ] ?? null; + $this->assertNotNull($expectedSefarim); + + $sefarim = $elementRepository->findByParentElement($chelek); + $this->assertElements( + elements: $sefarim, + expectedNames: array_keys($expectedSefarim), + expectedKind: 'sefer', + ); + $seferCount += count($sefarim); + + foreach ($sefarim as $sefer) { + $expectedPerekCount = $expectedSefarim[ + $sefer->getName() + ] ?? null; + $this->assertNotNull($expectedPerekCount); + + $expectedPerekNames = []; + for ( + $perekNumber = 1; + $perekNumber <= $expectedPerekCount; + $perekNumber++ + ) { + $expectedPerekNames[] = "Perek {$perekNumber}"; + } + + $perakim = $elementRepository->findByParentElement($sefer); + $this->assertElements( + elements: $perakim, + expectedNames: $expectedPerekNames, + expectedKind: 'perek', + ); + $perekCount += count($perakim); + } + } + + $this->assertSame(39, $seferCount); + $this->assertSame(929, $perekCount); + } + + private function findTanach(): Set + { + foreach (app(SetRepository::class)->all() as $set) { + if ($set->getName() === 'Tanach') { + return $set; + } + } + + $this->fail('Tanach set was not seeded'); + } + + /** + * @param list $elements + * @param list $expectedNames + */ + private function assertElements( + array $elements, + array $expectedNames, + string $expectedKind, + ): void { + $this->assertSame( + $expectedNames, + array_map(function (Element $element): string { + return $element->getName(); + }, $elements), + ); + + foreach ($elements as $index => $element) { + $this->assertSame($expectedKind, $element->getKind()); + $this->assertSame($index + 1, $element->getPosition()); + } + } +}