implemented search support in enrichment service

main
Inga 🏳‍🌈 12 months ago
parent f7b261f513
commit 4ec2cb033e
  1. 75
      src/services/omdbEnrichedDataService.spec.ts
  2. 22
      src/services/omdbEnrichedDataService.ts
  3. 25
      src/types.ts

@ -395,4 +395,79 @@ describe('createOmdbEnrichedDataService', () => {
expect(result).toBeUndefined();
});
it('returns correct search results for writer = George Lucas', async () => {
const service = await servicePromise;
const result = service.getSearchResults({ writers: 'George Lucas' });
expect(result).toMatchObject([
{ title: 'Indiana Jones and the Last Crusade' },
{ title: 'Star Wars: Episode IV - A New Hope' },
]);
});
it('returns correct search results for writer = George Lucas and actor = Harrison Ford', async () => {
const service = await servicePromise;
const result = service.getSearchResults({
actors: 'Harrison Ford',
writers: 'George Lucas',
});
expect(result).toMatchObject([
{ title: 'Indiana Jones and the Last Crusade' },
{ title: 'Star Wars: Episode IV - A New Hope' },
]);
});
it('returns correct search results for writer = George Lucas and actor = Mark Hamill', async () => {
const service = await servicePromise;
const result = service.getSearchResults({
actors: 'Mark Hamill',
writers: 'George Lucas',
});
expect(result).toMatchObject([
{ title: 'Star Wars: Episode IV - A New Hope' },
]);
});
it('returns correct search results for title = The Jungle Book', async () => {
const service = await servicePromise;
const result = service.getSearchResults({ title: 'The Jungle Book' });
expect(result).toMatchObject([{ title: 'The Jungle Book' }]);
});
it('returns correct search results for local title = Das Dschungelbuch', async () => {
const service = await servicePromise;
const result = service.getSearchResults({
localTitle: 'Das Dschungelbuch',
});
expect(result).toMatchObject([{ title: 'The Jungle Book' }]);
});
it('returns correct search results for production year = 1967', async () => {
const service = await servicePromise;
const result = service.getSearchResults({ productionYear: 1967 });
expect(result).toMatchObject([{ title: 'The Jungle Book' }]);
});
it('returns empty search results for writer = George Lucas and actor = Bruce Willis', async () => {
const service = await servicePromise;
const result = service.getSearchResults({
actors: 'Bruce Willis',
writers: 'George Lucas',
});
expect(result).toMatchObject([]);
});
it('returns empty search results for title = Blood Quantum', async () => {
const service = await servicePromise;
const result = service.getSearchResults({ title: 'Blood Quantum' });
expect(result).toMatchObject([]);
});
});

@ -3,6 +3,7 @@ import type {
InternalProvider,
MovieData,
OmdbProvider,
SearchFilters,
} from '../types';
export const createOmdbEnrichedDataService = async (
@ -37,5 +38,26 @@ export const createOmdbEnrichedDataService = async (
),
getMetadataByImdbId: (requestedId) =>
mergedMetadataList.find(({ imdbId }) => imdbId === requestedId),
getSearchResults: (filters) => {
const nonEmptyFilters = Object.entries(filters).filter(
([, filterValue]) => filterValue !== undefined,
);
return mergedMetadataList.filter((metadata) => {
return nonEmptyFilters.every(([fieldName, filterValue]) => {
const metadataValue =
metadata[fieldName as keyof SearchFilters];
if (Array.isArray(metadataValue)) {
// filterValue here is filters[fieldName], and is not undefined (because it comes from nonEmptyFilters),
// so it's guaranteed to have a matching type because of SearchFilters / GenericSearchFilters definition,
// but this logic is too complicated for TS to prove it automatically.
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
return metadataValue.includes(filterValue as any);
} else {
return metadataValue === filterValue;
}
});
});
},
};
};

@ -75,6 +75,30 @@ export type NormalizedInternalData = Omit<
| 'writers'
>;
type SearchFilterValue<TDataValue> = TDataValue extends (infer U)[]
? U
: TDataValue;
type GenericSearchFilters<TKeys extends keyof MovieData> = Partial<{
[TKey in keyof MovieData as TKey extends TKeys ? TKey : never]:
| SearchFilterValue<Exclude<MovieData[TKey], undefined>>
| undefined;
}>;
export type SearchFilters = GenericSearchFilters<
| 'actors'
| 'availableLanguages'
| 'directors'
| 'localTitle'
| 'originalLanguage'
| 'productionCountries'
| 'productionYear'
| 'studios'
| 'title'
| 'type'
| 'writers'
>;
export type InternalProvider = {
getMetadataByInternalId(
internalId: number,
@ -92,4 +116,5 @@ export type OmdbProvider = {
export type EnrichedDataService = {
getMetadataByInternalId(internalId: number): MovieData | undefined;
getMetadataByImdbId(imdbId: string): MovieData | undefined;
getSearchResults(filters: SearchFilters): MovieData[];
};

Loading…
Cancel
Save