-
-
Notifications
You must be signed in to change notification settings - Fork 10
TV series, seasons and episodes #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
1535907
54cb6f8
a43dfd6
c41a754
b1068a6
7ba205b
849399a
3c7915a
d96f91f
fd95374
0e8a8da
fb65842
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,14 +9,22 @@ import { | |||||||||||||||||||||||||
| CSFDGenres, | ||||||||||||||||||||||||||
| CSFDMovieCreator, | ||||||||||||||||||||||||||
| CSFDMovieListItem, | ||||||||||||||||||||||||||
| CSFDParent, | ||||||||||||||||||||||||||
| CSFDPremiere, | ||||||||||||||||||||||||||
| CSFDSeason, | ||||||||||||||||||||||||||
| CSFDTitlesOther, | ||||||||||||||||||||||||||
| CSFDVod, | ||||||||||||||||||||||||||
| CSFDVodService, | ||||||||||||||||||||||||||
| MovieJsonLd | ||||||||||||||||||||||||||
| } from '../dto/movie'; | ||||||||||||||||||||||||||
| import { CSFDOptions } from '../types'; | ||||||||||||||||||||||||||
| import { addProtocol, getColor, parseISO8601Duration, parseIdFromUrl } from './global.helper'; | ||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||
| addProtocol, | ||||||||||||||||||||||||||
| getColor, | ||||||||||||||||||||||||||
| parseISO8601Duration, | ||||||||||||||||||||||||||
| parseIdFromUrl, | ||||||||||||||||||||||||||
| parseLastIdFromUrl | ||||||||||||||||||||||||||
| } from './global.helper'; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const CREATOR_LABELS: Record< | ||||||||||||||||||||||||||
| string, | ||||||||||||||||||||||||||
|
|
@@ -101,6 +109,26 @@ export const getMovieId = (el: HTMLElement): number => { | |||||||||||||||||||||||||
| return parseIdFromUrl(url); | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getSeriesAndSeasonTitle = ( | ||||||||||||||||||||||||||
| el: HTMLElement | ||||||||||||||||||||||||||
| ): { seriesName: string | null; seasonName: string | null } => { | ||||||||||||||||||||||||||
| const titleElement = el.querySelector('h1'); | ||||||||||||||||||||||||||
| if (!titleElement) { | ||||||||||||||||||||||||||
| return { seriesName: null, seasonName: null }; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const fullText = titleElement.innerText.trim(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Check if there's a series part indicated by ' - ' | ||||||||||||||||||||||||||
| if (fullText.includes(' - ')) { | ||||||||||||||||||||||||||
| const [seriesName, seasonName] = fullText.split(' - ').map((part) => part.trim()); | ||||||||||||||||||||||||||
| return { seriesName, seasonName }; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+122
to
+126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If a title like Proposed fix- if (fullText.includes(' - ')) {
- const [seriesName, seasonName] = fullText.split(' - ').map((part) => part.trim());
- return { seriesName, seasonName };
- }
+ const separatorIndex = fullText.indexOf(' - ');
+ if (separatorIndex !== -1) {
+ const seriesName = fullText.substring(0, separatorIndex).trim();
+ const seasonName = fullText.substring(separatorIndex + 3).trim();
+ return { seriesName, seasonName };
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // If no series part found, return just the name | ||||||||||||||||||||||||||
| return { seriesName: fullText, seasonName: null }; | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getMovieTitle = (el: HTMLElement): string => { | ||||||||||||||||||||||||||
| return el.querySelector('h1').innerText.split(`(`)[0].trim(); | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
@@ -321,6 +349,91 @@ export const getMovieCreators = (el: HTMLElement, options?: CSFDOptions): CSFDCr | |||||||||||||||||||||||||
| return creators; | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getSeasonsOrEpisodes = ( | ||||||||||||||||||||||||||
| el: HTMLElement, | ||||||||||||||||||||||||||
| serie?: { id: number; title: string } | ||||||||||||||||||||||||||
| ): CSFDSeason[] | null => { | ||||||||||||||||||||||||||
| const childrenList = el.querySelector('.film-episodes-list'); | ||||||||||||||||||||||||||
| if (!childrenList) return null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const childrenNodes = childrenList.querySelectorAll('.film-title'); | ||||||||||||||||||||||||||
| if (!childrenNodes?.length) return []; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return childrenNodes.map((season) => { | ||||||||||||||||||||||||||
| const nameContainer = season.querySelector('.film-title-name'); | ||||||||||||||||||||||||||
| const infoContainer = season.querySelector('.info'); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||
| id: parseLastIdFromUrl(nameContainer?.getAttribute('href') || ''), | ||||||||||||||||||||||||||
| name: nameContainer?.textContent?.trim() || null, | ||||||||||||||||||||||||||
| url: nameContainer?.getAttribute('href') || null, | ||||||||||||||||||||||||||
| info: infoContainer?.textContent?.replace(/[{()}]/g, '').trim() || null | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getEpisodeCode = (el: HTMLElement): string | null => { | ||||||||||||||||||||||||||
| const filmHeaderName = el.querySelector('.film-header-name h1'); | ||||||||||||||||||||||||||
| if (!filmHeaderName) return null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const text = filmHeaderName.textContent?.trim() || ''; | ||||||||||||||||||||||||||
| const match = text.match(/\(([^)]+)\)/); | ||||||||||||||||||||||||||
| const code = match ? match[1] : null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return code; | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const detectSeasonOrEpisodeListType = (el: HTMLElement) => { | ||||||||||||||||||||||||||
| const headerText = el.querySelector('.box-header h3')?.innerText.trim() ?? ''; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (headerText.includes('Série')) return 'seasons'; | ||||||||||||||||||||||||||
| if (headerText.startsWith('Epizody')) return 'episodes'; | ||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
Comment on lines
+386
to
+392
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check if the API supports language options that would change page content
rg -n "language" src/vars.ts -A 3
echo "---"
rg -n "language" src/services/movie.service.ts -B 1 -A 3Repository: bartholomej/node-csfd-api Length of output: 2958 🏁 Script executed: #!/bin/bash
# Find CSFDLanguage type definition
rg -n "CSFDLanguage" src/ -B 2 -A 5 | head -100
echo "---"
# Search for localization or translation constants
rg -n "Série|Epizody" src/ -B 2 -A 2
echo "---"
# Find where detectSeasonOrEpisodeListType is called
rg -n "detectSeasonOrEpisodeListType" src/ -B 2 -A 2Repository: bartholomej/node-csfd-api Length of output: 4053 🏁 Script executed: #!/bin/bash
# Check the getMovie function context
rg -n "export class MovieScraper\|getMovie\|detectSeasonOrEpisodeListType" src/services/movie.service.ts -B 2 -A 10 | head -150
echo "---"
# Check localization helpers
rg -n "getLocalizedCreatorLabel" src/helpers/ -B 2 -A 10 | head -80Repository: bartholomej/node-csfd-api Length of output: 754 🏁 Script executed: #!/bin/bash
# Check the getMovie function signature and full context
sed -n '30,80p' src/services/movie.service.tsRepository: bartholomej/node-csfd-api Length of output: 2053
The strings Either add language-aware detection (following the pattern of 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getSeasonOrEpisodeParent = ( | ||||||||||||||||||||||||||
| el: HTMLElement, | ||||||||||||||||||||||||||
| serie?: { id: number; name: string } | ||||||||||||||||||||||||||
| ): CSFDParent | null => { | ||||||||||||||||||||||||||
| // Try h2 first (for episodes), then h1 (for seasons) | ||||||||||||||||||||||||||
| let parents = el.querySelectorAll('.film-header h2 a'); | ||||||||||||||||||||||||||
| if (parents.length === 0) { | ||||||||||||||||||||||||||
| parents = el.querySelectorAll('.film-header h1 a'); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (parents.length === 0) { | ||||||||||||||||||||||||||
| if (!serie) return null; | ||||||||||||||||||||||||||
| return { series: serie, season: null }; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const [parentSeries, parentSeason] = parents; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const seriesId = parseIdFromUrl(parentSeries?.getAttribute('href')); | ||||||||||||||||||||||||||
| const seasonId = parseLastIdFromUrl(parentSeason?.getAttribute('href') || ''); | ||||||||||||||||||||||||||
| const seriesName = parentSeries?.textContent?.trim() || null; | ||||||||||||||||||||||||||
| const seasonName = parentSeason?.textContent?.trim() || null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const series = seriesId && seriesName ? { id: seriesId, name: seriesName } : null; | ||||||||||||||||||||||||||
| const season = seasonId && seasonName ? { id: seasonId, name: seasonName } : null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (!series && !season) return null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return { series, season }; | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getMovieGroup = ( | ||||||||||||||||||||||||||
| el: HTMLElement, | ||||||||||||||||||||||||||
| group: CSFDCreatorGroups | CSFDCreatorGroupsEnglish | CSFDCreatorGroupsSlovak | ||||||||||||||||||||||||||
| ): CSFDMovieCreator[] => { | ||||||||||||||||||||||||||
| const creators = el.querySelectorAll('.creators h4'); | ||||||||||||||||||||||||||
| const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0]; | ||||||||||||||||||||||||||
| if (element?.parentNode) { | ||||||||||||||||||||||||||
| return parseMoviePeople(element.parentNode as HTMLElement); | ||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| return []; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getMovieType = (el: HTMLElement): string => { | ||||||||||||||||||||||||||
| const type = el.querySelector('.film-header-name .type'); | ||||||||||||||||||||||||||
| return type?.innerText?.replace(/[{()}]/g, '') || 'film'; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ import { CSFDFilmTypes } from '../dto/global'; | |
| import { CSFDMovie, MovieJsonLd } from '../dto/movie'; | ||
| import { fetchPage } from '../fetchers'; | ||
| import { | ||
| detectSeasonOrEpisodeListType, | ||
| getEpisodeCode, | ||
| getMovieBoxMovies, | ||
| getMovieColorRating, | ||
| getMovieCreators, | ||
|
|
@@ -21,7 +23,10 @@ import { | |
| getMovieTrivia, | ||
| getMovieType, | ||
| getMovieVods, | ||
| getMovieYear | ||
| getMovieYear, | ||
| getSeasonOrEpisodeParent, | ||
| getSeasonsOrEpisodes, | ||
| getSeriesAndSeasonTitle | ||
| } from '../helpers/movie.helper'; | ||
| import { CSFDOptions } from '../types'; | ||
| import { movieUrl } from '../vars'; | ||
|
|
@@ -57,15 +62,21 @@ export class MovieScraper { | |
| pageClasses: string[], | ||
| jsonLd: MovieJsonLd | null, | ||
| options: CSFDOptions | ||
| ): CSFDMovie { | ||
| ) { | ||
| const type = getMovieType(el) as CSFDFilmTypes; | ||
| const { seriesName = null, seasonName = null } = | ||
| type === 'série' ? getSeriesAndSeasonTitle(el) : {}; | ||
| const seasonOrEpisodeListType = detectSeasonOrEpisodeListType(el); | ||
|
|
||
| const title = type === 'série' && seriesName ? seriesName : getMovieTitle(el); | ||
| return { | ||
| id: movieId, | ||
| title: getMovieTitle(el), | ||
| title, | ||
| year: getMovieYear(jsonLd), | ||
| duration: getMovieDuration(jsonLd, el), | ||
| descriptions: getMovieDescriptions(el), | ||
| genres: getMovieGenres(el), | ||
| type: getMovieType(el) as CSFDFilmTypes, | ||
| type, | ||
| url: movieUrl(movieId, { language: options?.language }), | ||
| origins: getMovieOrigins(el), | ||
| colorRating: getMovieColorRating(pageClasses), | ||
|
|
@@ -80,7 +91,12 @@ export class MovieScraper { | |
| tags: getMovieTags(asideEl), | ||
| premieres: getMoviePremieres(asideEl), | ||
| related: getMovieBoxMovies(asideEl, 'Související'), | ||
| similar: getMovieBoxMovies(asideEl, 'Podobné') | ||
| similar: getMovieBoxMovies(asideEl, 'Podobné'), | ||
| seasons: seasonOrEpisodeListType === 'seasons' ? getSeasonsOrEpisodes(el) : null, | ||
| episodes: seasonOrEpisodeListType === 'episodes' ? getSeasonsOrEpisodes(el) : null, | ||
|
Comment on lines
+95
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: rg -nA15 "export const getSeasonsOrEpisodes" src/helpers/movie.helper.tsRepository: bartholomej/node-csfd-api Length of output: 721 🏁 Script executed: rg -nA40 "export const getSeasonsOrEpisodes" src/helpers/movie.helper.tsRepository: bartholomej/node-csfd-api Length of output: 1641 getSeasonsOrEpisodes does not filter incomplete nodes or normalize URLs. The helper function at lines 288-309 in 🤖 Prompt for AI Agents |
||
| parent: type === 'seriál' ? null : getSeasonOrEpisodeParent(el, { id: movieId, name: title }), | ||
| episodeCode: type === 'epizoda' ? getEpisodeCode(el) : null, | ||
| seasonName | ||
| }; | ||
|
Comment on lines
94
to
100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainParent/seasons/episodes population: verify nullability contract and absolute URLs.
To verify field presence: 🏁 Script executed: #!/bin/bash
rg -nC2 "seasons:|episodes:|parent:|episodeCode:|seasonName" src --type=tsLength of output: 3403 Length of output: 1168 🏁 Script executed: #!/bin/bash
# Find CSFDSeason type definition and related types
rg -nC3 "type CSFDSeason|interface CSFDSeason" src --type=tsLength of output: 279 🏁 Script executed: #!/bin/bash
# Search for getSeasonorEpisodeParent implementation details
rg -nC8 "getSeasonorEpisodeParent\s*=" src --type=tsLength of output: 1162 🏁 Script executed: #!/bin/bash
# Search for getSeasonsOrEpisodes implementation
rg -nC8 "getSeasonsOrEpisodes\s*=" src --type=tsLength of output: 1169 Length of output: 934 🏁 Script executed: #!/bin/bash
# Get complete getSeasonsOrEpisodes implementation including URL handling
rg -nA25 "export const getSeasonsOrEpisodes" src/helpers/movie.helper.tsLength of output: 1166 🏁 Script executed: #!/bin/bash
# Check for any recent changes to CSFDParent or related code
cat src/dto/movie.ts | head -40Length of output: 919 Critical type contract violations in parent/seasons/episodes population require fixes. The original review comment identified valid concerns that remain unaddressed:
Requires action:
🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -159,25 +159,102 @@ describe('Live: Movie page. Fetch `10135-forrest-gump`', () => { | |||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| describe('Live: Tv series', () => { | ||||||||||||||||||||
| let movie: CSFDMovie = {} as CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(71924); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Year', () => { | ||||||||||||||||||||
| expect(movie.year).toEqual<number>(1994); | ||||||||||||||||||||
| describe('Live: Series Patterns', () => { | ||||||||||||||||||||
| // Pattern 1: Series with Seasons (The Simpsons) | ||||||||||||||||||||
| describe('Series with Seasons (The Simpsons)', () => { | ||||||||||||||||||||
| let movie: CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(72489); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type and Title', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('seriál'); | ||||||||||||||||||||
| expect(movie.title).toEqual('Simpsonovi'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Seasons', () => { | ||||||||||||||||||||
| expect(movie.seasons).toBeDefined(); | ||||||||||||||||||||
| expect(movie.seasons!.length).toBeGreaterThan(20); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
Comment on lines
+173
to
+176
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Proposed fix test('Seasons', () => {
expect(movie.seasons).toBeDefined();
+ expect(movie.seasons).not.toBeNull();
expect(movie.seasons!.length).toBeGreaterThan(20);
});Same for Line 198: test('Episodes', () => {
expect(movie.episodes).toBeDefined();
+ expect(movie.episodes).not.toBeNull();
expect(movie.episodes!.length).toBeGreaterThan(0);
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
| test('No Episodes on main page', () => { | ||||||||||||||||||||
| expect(movie.episodes).toBeNull(); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('seriál'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Pattern 1: Season Page (The Simpsons S01) | ||||||||||||||||||||
| describe('Season Page (The Simpsons S01)', () => { | ||||||||||||||||||||
| let movie: CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(474212); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type and Title', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('série'); | ||||||||||||||||||||
| expect(movie.title).toEqual('Simpsonovi'); | ||||||||||||||||||||
| expect(movie.seasonName).toEqual('Série 1'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Parent Series', () => { | ||||||||||||||||||||
| expect(movie.parent?.series?.id).toEqual(72489); | ||||||||||||||||||||
| expect(movie.parent?.season).toBeNull(); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Episodes', () => { | ||||||||||||||||||||
| expect(movie.episodes).toBeDefined(); | ||||||||||||||||||||
| expect(movie.episodes!.length).toBeGreaterThan(0); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Title', () => { | ||||||||||||||||||||
| expect(movie.title).toEqual<string>('Království'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Pattern 1: Episode Page (The Simpsons S01E08) | ||||||||||||||||||||
| describe('Episode Page (The Simpsons S01E08)', () => { | ||||||||||||||||||||
| let movie: CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(474220); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type and Title', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('epizoda'); | ||||||||||||||||||||
| expect(movie.title).toEqual('Mluvící hlava'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Episode Code', () => { | ||||||||||||||||||||
| expect(movie.episodeCode).toEqual('S01E08'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Parents', () => { | ||||||||||||||||||||
| expect(movie.parent?.series?.id).toEqual(72489); | ||||||||||||||||||||
| expect(movie.parent?.season?.id).toEqual(474212); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Duration', () => { | ||||||||||||||||||||
| expect(movie.duration).toBeGreaterThan(50); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Pattern 2: Series without Seasons (The Curse) | ||||||||||||||||||||
| describe('Series without Seasons (The Curse)', () => { | ||||||||||||||||||||
| let movie: CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(1431651); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type and Title', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('seriál'); | ||||||||||||||||||||
| expect(movie.title).toEqual('The Curse'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Episodes directly', () => { | ||||||||||||||||||||
| expect(movie.episodes).toBeDefined(); | ||||||||||||||||||||
| expect(movie.episodes!.length).toBeGreaterThan(0); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('No Seasons', () => { | ||||||||||||||||||||
| expect(movie.seasons).toBeNull(); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Fetch not number', async () => { | ||||||||||||||||||||
| await expect(csfd.movie('test' as any)).rejects.toThrow(Error); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Pattern 2: Episode without Season (The Curse E01) | ||||||||||||||||||||
| describe('Episode without Season (The Curse E01)', () => { | ||||||||||||||||||||
| let movie: CSFDMovie; | ||||||||||||||||||||
| beforeAll(async () => { | ||||||||||||||||||||
| movie = await csfd.movie(1436408); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Type and Title', () => { | ||||||||||||||||||||
| expect(movie.type).toEqual<CSFDFilmTypes>('epizoda'); | ||||||||||||||||||||
| expect(movie.title).toEqual('Kouzelná země'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Episode Code', () => { | ||||||||||||||||||||
| expect(movie.episodeCode).toEqual('E01'); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| test('Parents', () => { | ||||||||||||||||||||
| expect(movie.parent?.series?.id).toEqual(1431651); | ||||||||||||||||||||
| expect(movie.parent?.season).toBeNull(); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.