UNPKG

podcastindexjs

Version:

client-side JS library for interacting with the Podcast Index API

218 lines (202 loc) 8.83 kB
import { PodcastIndexClient } from "../index"; import { PIApiEpisodeInfo, PIApiRandomEpisode } from "../types"; import { toEpochTimestamp } from "../utils"; describe("episodes api", () => { let client: PodcastIndexClient; let episodesByFeedUrl: PIApiEpisodeInfo[]; let episodesByFeedId: PIApiEpisodeInfo[]; let episodesByItunesId: PIApiEpisodeInfo[]; // TODO: Why are these types different? // let episodeById: ApiResponse.PodcastEpisode; let randomEpisode: PIApiRandomEpisode; const feedUrl = "https://feeds.theincomparable.com/batmanuniversity"; const feedId = 75075; const altFeedId = 920666; const iTunesId = 1441923632; const episodeId = 16795090; beforeAll(async () => { client = new PodcastIndexClient(process.env.API_KEY ?? "", process.env.API_SECRET ?? ""); episodesByFeedUrl = await (await client.episodesByFeedUrl(feedUrl)).items; episodesByFeedId = await (await client.episodesByFeedId(feedId)).items; episodesByItunesId = await (await client.episodesByItunesId(iTunesId)).items; [randomEpisode] = (await client.episodesRandom()).episodes; }); describe("episodesByFeedId", () => { it("returns all items", async () => { const searchResult = await client.episodesByFeedId(feedId); expect(searchResult.items.length).toBeGreaterThan(10); }); it("returns all items for multiple feeds", async () => { const altFeedResults = await client.episodesByFeedId(altFeedId); const searchResult = await client.episodesByFeedId([feedId, altFeedId], { max: 100 }); expect(searchResult.items.length).toEqual( altFeedResults.items.length + episodesByFeedId.length, ); }); it("returns user specified max items ", async () => { const max = 1; const searchResult = await client.episodesByFeedId(feedId, { max }); expect(searchResult.items).toHaveLength(max); }); it("returns user specified items since timestamp", async () => { const searchResult = await client.episodesByFeedId(feedId, { since: episodesByFeedId[1].datePublished - 1, }); expect(searchResult.items).toHaveLength(2); }); it("returns user specified items since negative seconds", async () => { const searchResult = await client.episodesByFeedId(feedId, { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion since: (toEpochTimestamp(new Date())! - episodesByFeedId[1].datePublished) * -1 - 2, }); expect(searchResult.items).toHaveLength(2); }); it("returns same object as byFeedUrl", async () => { const searchResult = await client.episodesByFeedId(feedId); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByFeedUrl[idx]); }); }); it("returns same object as byItunesId", async () => { const searchResult = await client.episodesByFeedId(feedId); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByItunesId[idx]); }); }); }); describe("episodesByFeedUrl", () => { it("returns all items ", async () => { const searchResult = await client.episodesByFeedUrl(feedUrl); expect(searchResult.items.length).toBeGreaterThan(10); }); it("returns user specified max items ", async () => { const max = 1; const searchResult = await client.episodesByFeedUrl(feedUrl, { max }); expect(searchResult.items).toHaveLength(max); }); it("returns user specified items since timestamp", async () => { const searchResult = await client.episodesByFeedUrl(feedUrl, { since: episodesByFeedId[1].datePublished - 1, }); expect(searchResult.items).toHaveLength(2); }); it("returns user specified items since negative seconds", async () => { const searchResult = await client.episodesByFeedUrl(feedUrl, { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion since: (toEpochTimestamp(new Date())! - episodesByFeedId[1].datePublished) * -1 - 2, }); expect(searchResult.items).toHaveLength(2); }); it("returns same object as byFeedId", async () => { const searchResult = await client.episodesByFeedUrl(feedUrl); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByFeedId[idx]); }); }); it("returns same object as byItunesId", async () => { const searchResult = await client.episodesByFeedUrl(feedUrl); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByItunesId[idx]); }); }); }); describe("episodesByItunesId", () => { it("returns all items ", async () => { const searchResult = await client.episodesByItunesId(iTunesId); expect(searchResult.items.length).toBeGreaterThan(10); }); it("returns user specified max items ", async () => { const max = 1; const searchResult = await client.episodesByItunesId(iTunesId, { max }); expect(searchResult.items).toHaveLength(max); }); it("returns user specified items since timestamp", async () => { const searchResult = await client.episodesByItunesId(iTunesId, { since: episodesByFeedId[1].datePublished - 1, }); expect(searchResult.items).toHaveLength(2); }); it("returns user specified items since negative seconds", async () => { const searchResult = await client.episodesByItunesId(iTunesId, { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion since: (toEpochTimestamp(new Date())! - episodesByFeedId[1].datePublished) * -1 - 2, }); expect(searchResult.items).toHaveLength(2); }); it("returns same object as byFeedId", async () => { const searchResult = await client.episodesByItunesId(iTunesId); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByFeedId[idx]); }); }); it("returns same object as byFeedUrl", async () => { const searchResult = await client.episodesByItunesId(iTunesId); searchResult.items.forEach((episodeInfo, idx) => { expect(episodeInfo).toEqual(episodesByFeedUrl[idx]); }); }); }); describe("episodeById", () => { it("returns an expected episode", async () => { const searchResult = await client.episodeById(episodeId); expect(searchResult.episode).toHaveProperty("title"); expect(searchResult.episode).toHaveProperty("description"); }); it("single episode shape matches all episodes", async () => { const searchResult = await client.episodeById(episodeId); // TODO: Fix this type!! const { feedTitle, ...episode } = searchResult.episode; expect(episode).toEqual(episodesByFeedId.find((ep) => ep.id === episodeId)); }); it("single episode shape matches all episodes", async () => { const searchResult = await client.episodeById(randomEpisode.id); // TODO: Fix this type!! const { categories, ...rando } = randomEpisode; const { duration, transcriptUrl, ...episode } = searchResult.episode; expect(episode).toEqual(rando); }); }); describe("random", () => { it("returns an random episode", async () => { const searchResult = await client.episodesRandom(); expect(searchResult.episodes).toHaveLength(1); }); it("returns a user specified max of random episodes", async () => { const max = 20; const searchResult = await client.episodesRandom({ max }); expect(searchResult.episodes).toHaveLength(max); }); it("returns a max of 40 random episodes", async () => { const searchResult = await client.episodesRandom({ max: 60 }); expect(searchResult.episodes).toHaveLength(40); }); it("accepts a user specified language", async () => { const lang = randomEpisode.feedLanguage.toLowerCase(); const searchResult = await client.episodesRandom({ max: 5, lang, }); searchResult.episodes.forEach((randomResult) => { expect(randomResult.feedLanguage.toLowerCase()).toEqual(lang); }); }); it("accepts a user specified categories", async () => { const extracted = Object.values(randomEpisode.categories ?? {}); const cat = extracted.length ? extracted : "Technology"; const searchResult = await client.episodesRandom({ max: 5, cat, }); searchResult.episodes.forEach((randomResult) => { expect( Object.values(randomResult.categories ?? {}).some((c) => { if (Array.isArray(cat)) { return cat.includes(c); } return c === cat; }), ).toEqual(true); }); }); }); });