createOne(); $overlap = $video->overlap; static::assertInstanceOf(VideoOverlap::class, $overlap); } /** * The source attribute of a video shall be cast to a VideoSource enum instance. * * @return void */ public function testCastsSourceToEnum(): void { $video = Video::factory()->createOne(); $source = $video->source; static::assertInstanceOf(VideoSource::class, $source); } /** * Video shall be a searchable resource. * * @return void */ public function testSearchableAs(): void { $video = Video::factory()->createOne(); static::assertIsString($video->searchableAs()); } /** * Video shall be a searchable resource. * * @return void */ public function testToSearchableArray(): void { $video = Video::factory()->createOne(); static::assertIsArray($video->toSearchableArray()); } /** * Videos shall be nameable. * * @return void */ public function testNameable(): void { $video = Video::factory()->createOne(); static::assertIsString($video->getName()); } /** * Videos shall have subtitle. * * @return void */ public function testHasSubtitle(): void { $video = Video::factory()->createOne(); static::assertIsString($video->getSubtitle()); } /** * Videos shall have a one-to-many polymorphic relationship to View. * * @return void */ public function testViews(): void { $video = Video::factory()->createOne(); views($video)->record(); static::assertInstanceOf(MorphMany::class, $video->views()); static::assertEquals(1, $video->views()->count()); static::assertInstanceOf(View::class, $video->views()->first()); } /** * Videos shall append a 'tags' attribute. * * @return void */ public function testAppendsTags(): void { $video = Video::factory()->createOne(); static::assertArrayHasKey(Video::ATTRIBUTE_TAGS, $video); } /** * The Tags attribute shall contain 'NC' if the NC attribute is true. * * @return void */ public function testNcTag(): void { $video = Video::factory()->createOne([ Video::ATTRIBUTE_NC => true, ]); static::assertContains('NC', $video->tags); } /** * The Tags attribute shall not contain 'NC' if the NC attribute is false. * * @return void */ public function testNoNcTag(): void { $video = Video::factory()->createOne([ Video::ATTRIBUTE_NC => false, ]); static::assertNotContains('NC', $video->tags); } /** * The Tags attribute shall contain 'DVD' if the source is DVD. * * @return void */ public function testDvdTag(): void { $source = VideoSource::DVD; $video = Video::factory()->createOne([ Video::ATTRIBUTE_SOURCE => $source->value, ]); static::assertContains($source->localize(), $video->tags); } /** * The Tags attribute shall contain 'BD' if the source is BD. * * @return void */ public function testBdTag(): void { $source = VideoSource::BD; $video = Video::factory()->createOne([ Video::ATTRIBUTE_SOURCE => $source->value, ]); static::assertContains($source->localize(), $video->tags); } /** * The Tags attribute shall not contain the description of the source if not DVD or BD. * * @return void */ public function testOtherSourceTag(): void { $source = null; while ($source === null) { $sourceCandidate = Arr::random(VideoSource::cases()); if ($sourceCandidate !== VideoSource::BD && $sourceCandidate !== VideoSource::DVD) { $source = $sourceCandidate; } } $video = Video::factory()->createOne([ Video::ATTRIBUTE_SOURCE => $source->value, ]); static::assertNotContains($source->localize(), $video->tags); } /** * The Tags attribute shall contain resolution. * * @return void */ public function testResolutionTag(): void { $video = Video::factory()->createOne(); static::assertContains(strval($video->resolution), $video->tags); } /** * The Tags attribute shall exclude 720 resolution from tags. * * @return void */ public function testNo720ResolutionTag(): void { $video = Video::factory()->createOne([ Video::ATTRIBUTE_RESOLUTION => 720, ]); static::assertNotContains(strval($video->resolution), $video->tags); } /** * The Tags attribute shall contain 'Subbed' if the subbed attribute is true. * * @return void */ public function testSubbedTag(): void { $video = Video::factory()->createOne([ Video::ATTRIBUTE_SUBBED => true, ]); static::assertContains('Subbed', $video->tags); static::assertNotContains('Lyrics', $video->tags); } /** * The Tags attribute shall contain 'Lyrics' if the lyrics attribute is true and subbed attribute is false. * * @return void */ public function testLyricsTag(): void { $video = Video::factory()->createOne([ Video::ATTRIBUTE_SUBBED => false, Video::ATTRIBUTE_LYRICS => true, ]); static::assertNotContains('Subbed', $video->tags); static::assertContains('Lyrics', $video->tags); } /** * The video source shall be the primary criterion for scoring. * * @param array $a * @param array $b * @return void */ #[DataProvider('priorityProvider')] public function testSourcePriority(array $a, array $b): void { $first = Video::factory()->createOne($a); $second = Video::factory()->createOne($b); static::assertGreaterThan($first->getSourcePriority(), $second->getSourcePriority()); } /** * Videos shall have a many-to-many relationship with the type Entry. * * @return void */ public function testEntries(): void { $entryCount = $this->faker->randomDigitNotNull(); $video = Video::factory() ->has(AnimeThemeEntry::factory()->for(AnimeTheme::factory()->for(Anime::factory()))->count($entryCount)) ->createOne(); static::assertInstanceOf(BelongsToMany::class, $video->animethemeentries()); static::assertEquals($entryCount, $video->animethemeentries()->count()); static::assertInstanceOf(AnimeThemeEntry::class, $video->animethemeentries()->first()); static::assertEquals(AnimeThemeEntryVideo::class, $video->animethemeentries()->getPivotClass()); } /** * Video shall belong to an Audio. * * @return void */ public function testAudio(): void { $video = Video::factory() ->for(Audio::factory()) ->createOne(); static::assertInstanceOf(BelongsTo::class, $video->audio()); static::assertInstanceOf(Audio::class, $video->audio()->first()); } /** * Video shall have a one-to-many relationship with the type PlaylistTrack, but only if the playlist is public. * * @return void */ public function testTracksPublic(): void { $trackCount = $this->faker->randomDigitNotNull(); $playlist = Playlist::factory()->createOne([ Playlist::ATTRIBUTE_VISIBILITY => PlaylistVisibility::PUBLIC ]); $video = Video::factory() ->has(PlaylistTrack::factory()->for($playlist)->count($trackCount), Video::RELATION_TRACKS) ->createOne(); static::assertInstanceOf(HasMany::class, $video->tracks()); static::assertEquals($trackCount, $video->tracks()->count()); static::assertInstanceOf(PlaylistTrack::class, $video->tracks()->first()); } /** * Video shall have a one-to-many relationship with the type PlaylistTrack, but only if the playlist is public. * * @return void */ public function testTracksNotPublic(): void { $trackCount = $this->faker->randomDigitNotNull(); $visibility = Arr::random([ PlaylistVisibility::PRIVATE, PlaylistVisibility::UNLISTED ]); $playlist = Playlist::factory()->createOne([ Playlist::ATTRIBUTE_VISIBILITY => $visibility ]); $video = Video::factory() ->has(PlaylistTrack::factory()->for($playlist)->count($trackCount), Video::RELATION_TRACKS) ->createOne(); static::assertInstanceOf(HasMany::class, $video->tracks()); static::assertNotEquals($trackCount, $video->tracks()->count()); } /** * Video shall have a one-to-one relationship with the type Script. * * @return void */ public function testScript(): void { $video = Video::factory() ->has(VideoScript::factory(), Video::RELATION_SCRIPT) ->createOne(); static::assertInstanceOf(HasOne::class, $video->videoscript()); static::assertInstanceOf(VideoScript::class, $video->videoscript()->first()); } /** * Provider for source priority testing. * * @return array */ public static function priorityProvider(): array { return [ [ [ Video::ATTRIBUTE_SOURCE => VideoSource::WEB->value, ], [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, ], ], [ [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::OVER->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], ], [ [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::TRANS->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], ], [ [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE->value, Video::ATTRIBUTE_LYRICS => true, Video::ATTRIBUTE_SUBBED => false, ], [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], ], [ [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE->value, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => true, ], [ Video::ATTRIBUTE_SOURCE => VideoSource::BD->value, Video::ATTRIBUTE_OVERLAP => VideoOverlap::NONE, Video::ATTRIBUTE_LYRICS => false, Video::ATTRIBUTE_SUBBED => false, ], ], ]; } }