diff --git a/lesson_10/libraries/src/lesson10.test.ts b/lesson_10/libraries/src/lesson10.test.ts index bf3c8994b..622859725 100644 --- a/lesson_10/libraries/src/lesson10.test.ts +++ b/lesson_10/libraries/src/lesson10.test.ts @@ -62,6 +62,14 @@ describe('Lesson10Test', () => { } const items = await loader.loadData(); expect(items.filter((i) => i.getCredits().length).length).toBe(100); + + // Every item that has credits should have the right credits. + const itemsWithCredits = items.filter((i) => i.getCredits().length); + expect( + itemsWithCredits.every((i) => + i.getCredits().every((c) => c.getMediaItemId() === i.getId()), + ), + ).toBe(true); } }); }); diff --git a/lesson_10/libraries/src/models/credit.ts b/lesson_10/libraries/src/models/credit.ts index fb9cee262..cbf3e7ba1 100644 --- a/lesson_10/libraries/src/models/credit.ts +++ b/lesson_10/libraries/src/models/credit.ts @@ -1,13 +1,25 @@ import { Role } from './role.js'; export class Credit { - mediaItemId: string; - name: string; - role: Role; + private mediaItemId: string; + private name: string; + private role: Role; constructor(mediaItemId: string, name: string, role: Role) { this.mediaItemId = mediaItemId; this.name = name; this.role = role; } + + getMediaItemId(): string { + return this.mediaItemId; + } + + getName(): string { + return this.name; + } + + getRole(): Role { + return this.role; + } } diff --git a/lesson_10/libraries/src/models/media_collection.ts b/lesson_10/libraries/src/models/media_collection.ts index bde07fb17..9209be969 100644 --- a/lesson_10/libraries/src/models/media_collection.ts +++ b/lesson_10/libraries/src/models/media_collection.ts @@ -13,55 +13,59 @@ export class MediaCollection { } search(criteria?: SearchCriteria): ReadonlySet { - const items = [...this.items.values()]; - if (!criteria) { - return new Set(items); + if (criteria?.title) { + return this.searchByTitle(criteria.title); } - const title = criteria.title; - if (title) { - return new Set(items.filter((item) => item.getTitle().includes(title))); + if (criteria?.releaseYear) { + return this.searchByReleaseYear(criteria.releaseYear); } - if (criteria.releaseYear) { - return new Set( - items.filter((item) => item.getReleaseYear() === criteria.releaseYear), - ); + if (criteria?.type) { + return this.searchByType(criteria.type); } - if (criteria.type) { - return new Set(items.filter((item) => item.getType() === criteria.type)); + if (criteria?.creditName) { + return this.searchByCreditName(criteria.creditName); } - if (criteria.creditName) { - return new Set( - items.filter((item) => - [...item.getCredits()].some( - (credit) => credit.name === criteria.creditName, - ), - ), - ); - } - return new Set(items); + return new Set(this.getItems()); } - searchByTitle(title: string): MediaItem[] { - return [...this.items.values()].filter((item) => - item.getTitle().includes(title), + searchByTitle(title: string): ReadonlySet { + return new Set( + this.getItems().filter((item) => + item + .getTitle() + .toLowerCase() + .includes(title?.toLowerCase() ?? ''), + ), ); } - searchByReleaseYear(releaseYear: number): MediaItem[] { - return [...this.items.values()].filter( - (item) => item.getReleaseYear() === releaseYear, + searchByReleaseYear(releaseYear: number): ReadonlySet { + return new Set( + this.getItems().filter((item) => item.getReleaseYear() === releaseYear), ); } - searchByType(type: string): MediaItem[] { - return [...this.items.values()].filter((item) => item.getType() === type); + searchByType(type: string): ReadonlySet { + return new Set(this.getItems().filter((item) => item.getType() === type)); } - searchByCreditName(name: string): MediaItem[] { - return [...this.items.values()].filter((item) => - [...item.getCredits()].some((credit) => credit.name === name), + searchByCreditName(name: string): ReadonlySet { + return new Set( + this.getItems().filter((item) => + item.getCredits().some((credit) => + credit + .getName() + .toLowerCase() + .includes(name?.toLowerCase() ?? ''), + ), + ), ); } + + private getItems(): readonly MediaItem[] { + return [...this.items.values()]; + } + getInfo() { return { getItems: () => [...this.items] as readonly [string, MediaItem][],