Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/parser/phase/__test__/phase-8.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* eslint-disable sonarjs/no-duplicate-string */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import * as helpers from "../../__test__/helpers";

const phase = 8;

describe("phase 8", () => {
let feed;
beforeAll(async () => {
feed = await helpers.loadSimple();
});

describe("podcast:follow", () => {
const supportedName = "follow";

it("correctly identifies a basic feed", () => {
const result = helpers.parseValidFeed(feed);

expect(result).not.toHaveProperty("podcastFollow");
expect(helpers.getPhaseSupport(result, phase)).not.toContain(supportedName);
});

it("ignores missing url", () => {
const xml = helpers.spliceFeed(
feed,
// missing url, not valid
`<podcast:follow/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).not.toHaveProperty("podcastFollow");
expect(helpers.getPhaseSupport(result, phase)).not.toContain(supportedName);
});

it("extracts a single follow url", () => {
const xml = helpers.spliceFeed(
feed,
`<podcast:follow url="https://examplehost.com/feed/12345678/followlinks.json"/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).toHaveProperty("podcastFollow");
expect(result.podcastFollow).toHaveProperty("url", "https://examplehost.com/feed/12345678/followlinks.json");
expect(helpers.getPhaseSupport(result, phase)).toContain(supportedName);
});

it("extracts follow url with different domain", () => {
const xml = helpers.spliceFeed(
feed,
`<podcast:follow url="https://f.prxu.org/72/subscribelinks.json"/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).toHaveProperty("podcastFollow");
expect(result.podcastFollow).toHaveProperty("url", "https://f.prxu.org/72/subscribelinks.json");
expect(helpers.getPhaseSupport(result, phase)).toContain(supportedName);
});

it("handles multiple follow tags by taking the first one", () => {
const xml = helpers.spliceFeed(
feed,
`<podcast:follow url="https://examplehost.com/feed/12345678/followlinks.json"/>
<podcast:follow url="https://anotherhost.com/feed/87654321/followlinks.json"/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).toHaveProperty("podcastFollow");
expect(result.podcastFollow).toHaveProperty("url", "https://examplehost.com/feed/12345678/followlinks.json");
expect(helpers.getPhaseSupport(result, phase)).toContain(supportedName);
});

it("handles empty url attribute", () => {
const xml = helpers.spliceFeed(
feed,
`<podcast:follow url=""/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).not.toHaveProperty("podcastFollow");
expect(helpers.getPhaseSupport(result, phase)).not.toContain(supportedName);
});

it("handles whitespace-only url attribute", () => {
const xml = helpers.spliceFeed(
feed,
`<podcast:follow url=" "/>`
);
const result = helpers.parseValidFeed(xml);

expect(result).not.toHaveProperty("podcastFollow");
expect(helpers.getPhaseSupport(result, phase)).not.toContain(supportedName);
});
});
});
3 changes: 3 additions & 0 deletions src/parser/phase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as phase4 from "./phase-4";
import * as phase5 from "./phase-5";
import * as phase6 from "./phase-6";
import * as phase7 from "./phase-7";
import * as phase8 from "./phase-8";
import * as pending from "./phase-pending";
import { XmlNodeSource } from "./types";

Expand Down Expand Up @@ -92,6 +93,8 @@ const feeds: FeedUpdate[] = [
phase7.podcastChat,
phase7.podcastPublisher,

phase8.podcastFollow,

pending.id,
pending.social,
pending.podcastRecommendations,
Expand Down
22 changes: 22 additions & 0 deletions src/parser/phase/phase-8.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { firstIfArray, getAttribute, getKnownAttribute } from "../shared";
import type { XmlNode } from "../types";

export type Phase8Follow = {
url: string;
};

export const podcastFollow = {
phase: 8,
name: "follow",
tag: "podcast:follow",
nodeTransform: firstIfArray,
supportCheck: (node: XmlNode): boolean =>
Boolean(getAttribute(node, "url")),
fn(node: XmlNode): { podcastFollow: Phase8Follow } {
return {
podcastFollow: {
url: getKnownAttribute(node, "url"),
},
};
},
};
5 changes: 5 additions & 0 deletions src/parser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
import type { Phase5Blocked, Phase5BlockedPlatforms, Phase5SocialInteract } from "./phase/phase-5";
import type { Phase6RemoteItem, Phase6TxtEntry } from "./phase/phase-6";
import type { Phase7Chat, Phase7Publisher } from "./phase/phase-7";
import type { Phase8Follow } from "./phase/phase-8";
import {
PhasePendingPodcastId,
PhasePendingSocial,
Expand Down Expand Up @@ -199,6 +200,10 @@ export interface FeedObject extends BasicFeed {
podcastImages?: Phase4PodcastImage[];
podcastRecommendations?: PhasePendingPodcastRecommendation[];
// #endregion
// #region Phase 8
/** URL pointing to a JSON file containing follow links for the podcast */
podcastFollow?: Phase8Follow;
// #endregion
}

export type Enclosure = {
Expand Down