Skip to content

Commit

Permalink
fix(endpoint-syndicate): correctly syndicate to targets
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrobertlloyd committed Nov 3, 2023
1 parent ee056d8 commit e8cbb44
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 32 deletions.
45 changes: 30 additions & 15 deletions packages/endpoint-syndicate/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,48 @@ export const getPostData = async (application, url) => {
* @returns {boolean} Target returned a syndication URL
*/
export const hasSyndicationUrl = (syndicatedUrls, syndicateTo) => {
return syndicatedUrls.some((url) => url.startsWith(syndicateTo));
return syndicatedUrls.some((url) => {
const { origin } = new URL(url);
return syndicateTo.includes(origin);
});
};

/**
* Check if post syndication target is a publication target
* @param {Array} publicationTargets - Publication syndication targets
* @param {string} syndicateTo - Syndication target
* @returns {boolean} Post syndication target is a publication target
* Get syndication target for syndication URL
* @param {Array} syndicationTargets - Publication syndication targets
* @param {string} syndicateTo - Syndication URL
* @returns {object|undefined} Publication syndication target
*/
export const isSyndicationTarget = (publicationTargets, syndicateTo) => {
return publicationTargets.some((target) =>
syndicateTo.includes(target?.info?.uid),
);
export const getSyndicationTarget = (syndicationTargets, syndicateTo) => {
return syndicationTargets.find((target) => {
if (!target?.info?.uid) {
return;
}

const targetOrigin = new URL(target.info.uid).origin;
const syndicateToOrigin = new URL(syndicateTo).origin;
return targetOrigin === syndicateToOrigin;
});
};

/**
* Syndicate URLs to configured syndication targets
* @param {object} publication - Publication configuration
* @param {object} properties - JF2 properties
* @returns {Promise<object>} Syndication target
*/
export const syndicateToTargets = async (publication, properties) => {
const { syndicationTargets } = publication;
const syndicateTo = properties["mp-syndicate-to"];
const syndicateToUrls = Array.isArray ? syndicateTo : [syndicateTo];
const syndicatedUrls = properties.syndication || [];
const { syndicationTargets } = publication;
const failedTargets = [];

for await (const target of syndicationTargets) {
const canSyndicate =
!hasSyndicationUrl(syndicatedUrls, syndicateTo) &&
isSyndicationTarget(syndicationTargets, syndicateTo);
for (const url of syndicateToUrls) {
const target = getSyndicationTarget(syndicationTargets, url);
const alreadySyndicated = hasSyndicationUrl(syndicatedUrls, url);

if (canSyndicate) {
if (target && !alreadySyndicated) {
try {
const syndicatedUrl = await target.syndicate(properties, publication);

Expand Down
43 changes: 26 additions & 17 deletions packages/endpoint-syndicate/tests/unit/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import test from "ava";
import { testDatabase } from "@indiekit-test/database";
import {
getPostData,
getSyndicationTarget,
hasSyndicationUrl,
isSyndicationTarget,
} from "../../lib/utils.js";

const posts = await testDatabase("posts");
Expand Down Expand Up @@ -38,25 +38,34 @@ test("Gets post data from database", async (t) => {
t.is(result.properties["mp-syndicate-to"], "https://mastodon.example/");
});

test("Checks if target already returned a syndication URL", (t) => {
const syndicationUrls = [
"https://web.archive.org/",
"https://mastodon.example/@username/67890",
];
test("Gets syndication target for syndication URL", (t) => {
const targets = [{ info: { uid: "https://mastodon.example" } }];
const result = getSyndicationTarget(targets, "https://mastodon.example");

t.true(hasSyndicationUrl(syndicationUrls, "https://mastodon.example"));
t.false(hasSyndicationUrl(syndicationUrls, "https://mastodon.foo"));
t.is(result.info.uid, "https://mastodon.example");
});

test("Check if post target is a publication target", (t) => {
const syndicationTargets = [
{
info: {
uid: "https://mastodon.example",
},
},
test("Returns undefined getting unknown target for syndication URL", (t) => {
const targets = [{ info: { uid: "https://mastodon.example" } }];
const result = getSyndicationTarget(targets, "https://mastodon.foo");

t.falsy(result);
});

test("Returns undefined if no target URLs defined for syndication URL", (t) => {
const targets = [{ info: { name: "Example" } }];
const result = getSyndicationTarget(targets, "https://mastodon.example");

t.falsy(result);
});

test("Checks if target already returned a syndication URL", (t) => {
const syndication = [
"https://mastodon.example/@username/67890",
"https://web.archive.org/web/20230116193035/https://example.com/",
];

t.true(isSyndicationTarget(syndicationTargets, "https://mastodon.example"));
t.false(isSyndicationTarget(syndicationTargets, "https://mastodon.foo"));
t.true(hasSyndicationUrl(syndication, "https://mastodon.example"));
t.true(hasSyndicationUrl(syndication, "https://web.archive.org"));
t.false(hasSyndicationUrl(syndication, "https://mastodon.foo"));
});

0 comments on commit e8cbb44

Please sign in to comment.