test(subscribe): cover season, files and history dialogs (#544)

This commit is contained in:
InfinityPacer
2026-07-17 18:25:28 +08:00
committed by GitHub
parent 7d2c98c5ae
commit 2b310c9a97
10 changed files with 1532 additions and 10 deletions

View File

@@ -1,7 +1,8 @@
import type { MediaInfo, TmdbEpisode } from '@/api/types'
import type { MediaInfo, MediaSeason, NotExistMediaInfo, TmdbEpisode } from '@/api/types'
let episodeSeed = 0
let mediaSeed = 0
let seasonSeed = 0
export function createTmdbEpisode(overrides: Partial<TmdbEpisode> = {}): TmdbEpisode {
episodeSeed += 1
@@ -32,3 +33,28 @@ export function createMediaInfo(overrides: Partial<MediaInfo> = {}): MediaInfo {
...overrides,
}
}
/** 构造季选择弹窗使用的最小季信息。 */
export function createMediaSeason(overrides: Partial<MediaSeason> = {}): MediaSeason {
seasonSeed += 1
return {
air_date: `202${seasonSeed % 10}-01-01`,
episode_count: 12,
name: `${seasonSeed}`,
poster_path: `/images/season-${seasonSeed}.jpg`,
season_number: seasonSeed,
vote_average: 8,
...overrides,
}
}
/** 构造媒体服务器返回的单季缺失状态。 */
export function createNotExistMediaInfo(overrides: Partial<NotExistMediaInfo> = {}): NotExistMediaInfo {
return {
episodes: [],
season: 1,
start_episode: 1,
total_episode: 12,
...overrides,
}
}

View File

@@ -1,8 +1,15 @@
import type { MediaInfo, TmdbEpisode } from '@/api/types'
import type { MediaInfo, MediaSeason, NotExistMediaInfo, TmdbEpisode } from '@/api/types'
import { HttpResponse, http, type JsonBodyType } from 'msw'
const API_BASE_URL = 'http://localhost/api/v1/'
export const mediaApiUrls = {
episodeGroups: (tmdbId: number) => new URL(`media/groups/${tmdbId}`, API_BASE_URL).href,
groupSeasons: (episodeGroup: string) => new URL(`media/group/seasons/${episodeGroup}`, API_BASE_URL).href,
notExists: new URL('mediaserver/notexists', API_BASE_URL).href,
seasons: new URL('media/seasons', API_BASE_URL).href,
}
export function mediaDetailsHandler(
tmdbId: number,
response: MediaInfo,
@@ -27,3 +34,50 @@ export function tmdbSeasonEpisodesHandler(
return HttpResponse.json(response as unknown as JsonBodyType, { status })
})
}
export function mediaSeasonsHandler(
response: MediaSeason[],
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.get(mediaApiUrls.seasons, async ({ request }) => {
await onRequest(new URL(request.url))
return HttpResponse.json(response as unknown as JsonBodyType, { status })
})
}
export function mediaEpisodeGroupsHandler(
tmdbId: number,
response: Record<string, unknown>[],
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.get(mediaApiUrls.episodeGroups(tmdbId), async ({ request }) => {
await onRequest(new URL(request.url))
return HttpResponse.json(response as JsonBodyType, { status })
})
}
export function mediaGroupSeasonsHandler(
episodeGroup: string,
response: MediaSeason[],
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.get(mediaApiUrls.groupSeasons(episodeGroup), async ({ request }) => {
await onRequest(new URL(request.url))
return HttpResponse.json(response as unknown as JsonBodyType, { status })
})
}
export function mediaNotExistsHandler(
response: NotExistMediaInfo[],
status = 200,
onRequest: (payload: Record<string, unknown>, url: URL) => void | Promise<void> = () => {},
) {
return http.post(mediaApiUrls.notExists, async ({ request }) => {
const payload = (await request.json()) as Record<string, unknown>
await onRequest(payload, new URL(request.url))
return HttpResponse.json(response as unknown as JsonBodyType, { status })
})
}

View File

@@ -25,6 +25,9 @@ export const subscribeApiUrls = {
downloaders: new URL('download/clients', API_BASE_URL).href,
episodeGroups: (tmdbId: number) => new URL(`media/groups/${tmdbId}`, API_BASE_URL).href,
filterRuleGroups: new URL('system/setting/UserFilterRuleGroups', API_BASE_URL).href,
filesById: (id: number) => new URL(`subscribe/files/${id}`, API_BASE_URL).href,
historyById: (id: number) => new URL(`subscribe/history/${id}`, API_BASE_URL).href,
historyByType: (type: SubscribeMediaType) => new URL(`subscribe/history/${type}`, API_BASE_URL).href,
queryByMedia: (mediaId: string) => new URL(`subscribe/media/${mediaId}`, API_BASE_URL).href,
list: new URL('subscribe/', API_BASE_URL).href,
orderConfig: (type: SubscribeMediaType) =>
@@ -51,6 +54,42 @@ export function subscribeListHandler(
})
}
export function subscribeFilesHandler(
id: number,
response: JsonBodyType = { episodes: {}, subscribe: null },
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.get(subscribeApiUrls.filesById(id), async ({ request }) => {
await onRequest(new URL(request.url))
return jsonResponse(response, status)
})
}
export function subscribeHistoryHandler(
type: SubscribeMediaType,
response: Subscribe[] = [],
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.get(subscribeApiUrls.historyByType(type), async ({ request }) => {
await onRequest(new URL(request.url))
return jsonResponse(response as unknown as JsonBodyType, status)
})
}
export function deleteSubscribeHistoryHandler(
id: number,
response: SubscribeMutationResponse = { success: true },
status = 200,
onRequest: (url: URL) => void | Promise<void> = () => {},
) {
return http.delete(subscribeApiUrls.historyById(id), async ({ request }) => {
await onRequest(new URL(request.url))
return jsonResponse(response, status)
})
}
export function subscribeOrderConfigHandler(
type: SubscribeMediaType,
value: JsonBodyType = [],