Spaces:
Paused
Paused
Download web/src/__tests__/lib/api-self.spec.ts from stremio-db/a: direct link, hf CLI and curl.
- Browser
- Download file 9.71 kB
-
https://huggingface.co/spaces/stremio-db/a/resolve/main/web/src/__tests__/lib/api-self.spec.ts
- Command line
-
hf download hf://spaces/stremio-db/a/web/src/__tests__/lib/api-self.spec.ts
-
curl -L -o api-self.spec.ts https://huggingface.co/spaces/stremio-db/a/resolve/main/web/src/__tests__/lib/api-self.spec.ts
9.71 kB
| import { describe, it, expect, vi, beforeEach } from 'vitest' | |
| import { createPinia, setActivePinia } from 'pinia' | |
| const mockAuthStore = { | |
| token: null as string | null, | |
| apiKeyToken: 'test-jwt-token', | |
| refresh: vi.fn(), | |
| logout: vi.fn(), | |
| } | |
| vi.mock('@/stores/auth', () => ({ | |
| useAuthStore: () => mockAuthStore, | |
| })) | |
| import { selfApi } from '@/lib/api' | |
| function makeFetchResponse(status: number, body: unknown = {}) { | |
| return { | |
| ok: status >= 200 && status < 300, | |
| status, | |
| json: () => Promise.resolve(body), | |
| } | |
| } | |
| describe('selfApi', () => { | |
| beforeEach(() => { | |
| setActivePinia(createPinia()) | |
| vi.restoreAllMocks() | |
| mockAuthStore.apiKeyToken = 'test-jwt-token' | |
| mockAuthStore.token = null | |
| }) | |
| it('getInfo sends GET with JWT token as Bearer token', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200, { name: 'k', key_prefix: 'ab' })) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.getInfo() | |
| expect(fetchMock).toHaveBeenCalledTimes(1) | |
| const [url, options] = fetchMock.mock.calls[0] | |
| expect(url).toContain('/api/key/me') | |
| expect(options.headers.get('Authorization')).toBe('Bearer test-jwt-token') | |
| }) | |
| it('getSettings sends GET to /api/key/me/settings', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200, { image_source: 't' })) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.getSettings() | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('/api/key/me/settings') | |
| }) | |
| it('updateSettings sends PUT with JSON body', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200, { ok: true })) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.updateSettings({ | |
| image_source: 'f', | |
| lang: 'de', | |
| textless: true, | |
| ratings_limit: 3, | |
| ratings_order: 'mal,imdb,trakt', | |
| ratings_exclude: 'rt', | |
| poster_position: 'bc', | |
| logo_ratings_limit: 3, | |
| backdrop_ratings_limit: 3, | |
| poster_badge_style: 'h', | |
| logo_badge_style: 'h', | |
| backdrop_badge_style: 'v', | |
| poster_label_style: 't', | |
| logo_label_style: 't', | |
| backdrop_label_style: 't', | |
| poster_badge_direction: 'd', | |
| poster_badge_split: false, | |
| poster_badge_size: 'l', | |
| logo_badge_size: 's', | |
| backdrop_badge_size: 'xl', | |
| }) | |
| const [url, options] = fetchMock.mock.calls[0] | |
| expect(url).toContain('/api/key/me/settings') | |
| expect(options.method).toBe('PUT') | |
| expect(options.headers.get('Content-Type')).toBe('application/json') | |
| expect(JSON.parse(options.body)).toEqual({ | |
| image_source: 'f', | |
| lang: 'de', | |
| textless: true, | |
| ratings_limit: 3, | |
| ratings_order: 'mal,imdb,trakt', | |
| ratings_exclude: 'rt', | |
| poster_position: 'bc', | |
| logo_ratings_limit: 3, | |
| backdrop_ratings_limit: 3, | |
| poster_badge_style: 'h', | |
| logo_badge_style: 'h', | |
| backdrop_badge_style: 'v', | |
| poster_label_style: 't', | |
| logo_label_style: 't', | |
| backdrop_label_style: 't', | |
| poster_badge_direction: 'd', | |
| poster_badge_split: false, | |
| poster_badge_size: 'l', | |
| logo_badge_size: 's', | |
| backdrop_badge_size: 'xl', | |
| }) | |
| }) | |
| it('resetSettings sends DELETE', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200, { ok: true })) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.resetSettings() | |
| const [url, options] = fetchMock.mock.calls[0] | |
| expect(url).toContain('/api/key/me/settings') | |
| expect(options.method).toBe('DELETE') | |
| }) | |
| it('does not set Authorization when apiKeyToken is null', async () => { | |
| mockAuthStore.apiKeyToken = null as unknown as string | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.getInfo() | |
| const [, options] = fetchMock.mock.calls[0] | |
| expect(options.headers.has('Authorization')).toBe(false) | |
| }) | |
| it('does not include credentials (no cookie needed)', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.getInfo() | |
| const [, options] = fetchMock.mock.calls[0] | |
| // keyRequest does not set credentials: 'include' | |
| expect(options.credentials).toBeUndefined() | |
| }) | |
| it('previewPoster includes position when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewPoster(3, 'imdb,rt', 'r') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('position=r') | |
| }) | |
| it('previewPoster includes label_style when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewPoster(3, 'imdb,rt', 'bc', 'h', 'i') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('label_style=i') | |
| }) | |
| it('previewPoster includes badge_direction when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewPoster(3, 'imdb,rt', 'bc', 'h', 'i', 'v') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('badge_direction=v') | |
| }) | |
| it('previewLogo includes label_style when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewLogo(3, 'imdb,rt', 'h', 'i') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('label_style=i') | |
| }) | |
| it('previewBackdrop includes label_style when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewBackdrop(3, 'imdb,rt', 'v', 'i') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('label_style=i') | |
| }) | |
| it('previewEpisode calls GET with correct URL and params', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt,tmdb') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('/api/key/me/preview/episode') | |
| expect(url).toContain('ratings_limit=3') | |
| expect(url).toContain('ratings_order=imdb%2Crt%2Ctmdb') | |
| }) | |
| it('previewEpisode includes position when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt', undefined, undefined, undefined, 'tr') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('position=tr') | |
| }) | |
| it('previewEpisode includes badge_direction when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt', undefined, undefined, undefined, 'tr', 'h') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('badge_direction=h') | |
| }) | |
| it('previewEpisode includes blur=true when enabled', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt', undefined, undefined, undefined, undefined, undefined, true) | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('blur=true') | |
| }) | |
| it('previewEpisode omits blur when false', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt', undefined, undefined, undefined, undefined, undefined, false) | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).not.toContain('blur') | |
| }) | |
| it('previewEpisode includes label_style when provided', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200)) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.previewEpisode(3, 'imdb,rt', 'v', 'i') | |
| const [url] = fetchMock.mock.calls[0] | |
| expect(url).toContain('label_style=i') | |
| }) | |
| it('updateSettings includes episode fields', async () => { | |
| const fetchMock = vi.fn().mockResolvedValue(makeFetchResponse(200, { ok: true })) | |
| vi.stubGlobal('fetch', fetchMock) | |
| await selfApi.updateSettings({ | |
| image_source: 't', | |
| lang: 'en', | |
| textless: false, | |
| ratings_limit: 3, | |
| ratings_order: 'imdb,rt,tmdb', | |
| ratings_exclude: '', | |
| poster_position: 'bc', | |
| logo_ratings_limit: 3, | |
| backdrop_ratings_limit: 3, | |
| poster_badge_style: 'h', | |
| logo_badge_style: 'h', | |
| backdrop_badge_style: 'v', | |
| poster_label_style: 't', | |
| logo_label_style: 't', | |
| backdrop_label_style: 't', | |
| poster_badge_direction: 'd', | |
| poster_badge_split: false, | |
| poster_badge_size: 'l', | |
| logo_badge_size: 's', | |
| backdrop_badge_size: 'xl', | |
| episode_ratings_limit: 1, | |
| episode_badge_style: 'v', | |
| episode_label_style: 'o', | |
| episode_badge_size: 'l', | |
| episode_position: 'tr', | |
| episode_badge_direction: 'v', | |
| episode_blur: false, | |
| }) | |
| const [, options] = fetchMock.mock.calls[0] | |
| const body = JSON.parse(options.body) | |
| expect(body.episode_ratings_limit).toBe(1) | |
| expect(body.episode_badge_style).toBe('v') | |
| expect(body.episode_label_style).toBe('o') | |
| expect(body.episode_badge_size).toBe('l') | |
| expect(body.episode_position).toBe('tr') | |
| expect(body.episode_badge_direction).toBe('v') | |
| expect(body.episode_blur).toBe(false) | |
| }) | |
| }) | |