diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 0c159af..529edab 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -17,6 +17,7 @@ jobs: node-version: 20 registry-url: https://registry.npmjs.org/ - run: npm install + - run: node --test - if: ${{ github.event.release.tag_name != '' && env.NPM_PUBLISH_TAG != '' }} run: npm publish --provenance --access=public --tag=${{ env.NPM_PUBLISH_TAG }} env: diff --git a/.npmignore b/.npmignore index 5541459..2097f23 100644 --- a/.npmignore +++ b/.npmignore @@ -5,3 +5,4 @@ .eslintrc.json .prettierrc .prettierignore +eleventy-cache-webmentions.test.js diff --git a/eleventy-cache-webmentions.js b/eleventy-cache-webmentions.js index aab7a28..62cdca7 100644 --- a/eleventy-cache-webmentions.js +++ b/eleventy-cache-webmentions.js @@ -437,6 +437,7 @@ module.exports.defaults = defaults; module.exports.filteredWebmentions = filteredWebmentions; module.exports.webmentionsByUrl = filteredWebmentions; module.exports.fetchWebmentions = fetchWebmentions; +module.exports.performFetch = performFetch; module.exports.getWebmentions = getWebmentions; module.exports.getByType = getByType; module.exports.getWebmentionsByType = getByType; diff --git a/eleventy-cache-webmentions.test.js b/eleventy-cache-webmentions.test.js new file mode 100644 index 0000000..3d2cf36 --- /dev/null +++ b/eleventy-cache-webmentions.test.js @@ -0,0 +1,409 @@ +const assert = require("node:assert/strict"); +const { describe, it } = require("node:test"); +const nock = require("nock"); +const { + defaults, + filteredWebmentions, + fetchWebmentions, + performFetch, + getWebmentions, + getPublished, + getReceived, + getContent, + getSource, + getTarget, + getType, + getByType, + getByTypes, +} = require("./eleventy-cache-webmentions.js"); + +const options = Object.assign({}, defaults, { + refresh: true, + domain: "https://example.com", + feed: `https://example.com/mentions.json`, + key: "children", +}); + +const mentions = { + type: "feed", + name: "Webmentions", + children: [ + { + type: "entry", + author: { + type: "card", + name: "Jane Doe", + url: "https://example.com", + }, + url: "https://example.com/post1/", + published: "2024-01-01T12:00:00Z", + "wm-received": "2024-01-01T12:00:00Z", + "wm-id": 123456, + "wm-source": "https://example.com/post1/", + "wm-target": "https://example.com/page1/", + "wm-protocol": "webmention", + name: "Example Post", + content: { + "content-type": "text/html", + value: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + html: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + "mention-of": "https://example.com/page1/", + "wm-property": "mention-of", + "wm-private": false, + }, + { + type: "entry", + author: { + type: "card", + name: "Jane Doe", + url: "https://example.com", + }, + url: "https://example.com/post2/", + published: "2024-01-01T12:00:00Z", + "wm-received": "2024-01-01T12:00:00Z", + "wm-id": 234567, + "wm-source": "https://example.com/post2/", + "wm-target": "https://example.com/page2/", + "wm-protocol": "webmention", + name: "Example Post", + content: { + "content-type": "text/html", + value: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + html: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + "in-reply-to": "https://example.com/page2/", + "wm-property": "in-reply-to", + "wm-private": false, + }, + { + type: "entry", + author: { + type: "card", + name: "Jane Doe", + url: "https://example.com", + }, + url: "https://example.com/post3/", + published: "2024-01-01T12:00:00Z", + "wm-received": "2024-01-01T12:00:00Z", + "wm-id": 345678, + "wm-source": "https://example.com/post3/", + "wm-target": "https://example.com/page2/", + "wm-protocol": "webmention", + name: "Example Post", + content: { + "content-type": "text/html", + value: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + html: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + "mention-of": "https://example.com/page2/", + "wm-property": "mention-of", + "wm-private": false, + }, + ], +}; + +describe("filteredWebmentions()", () => { + const scope = nock("https://example.com") + .get("/mentions.json") + .reply(200, mentions); + it("Should return an object of Key: URL, Value: Array of Webmentions", async () => { + const webmentions = await filteredWebmentions(options); + console.log("webmentions", webmentions); + assert.strictEqual(Object.keys(webmentions).length, 2); + }); +}); + +describe("fetchWebmentions()", () => { + const scope = nock("https://example.com") + .get("/mentions.json") + .reply(200, mentions); + it("Should return an array of objects of Key: URL, Value: Array of Webmentions`", async () => { + const fetched = await fetchWebmentions(options); + assert.strictEqual(fetched.length, 3); + }); +}); + +describe("performFetch()", () => { + const scope = nock("https://example.com") + .get("/mentions.json") + .reply(200, mentions); + it("Should return an object of Key: URL, Value: Array of Webmentions`", async () => { + const fetched = await performFetch( + options, + [], + "https://example.com/mentions.json", + ); + assert.strictEqual(fetched.filtered.length, 3); + }); +}); + +describe("getWebmentions()", () => { + const scope = nock("https://example.com") + .get("/mentions.json") + .reply(200, mentions); + it("Should return an object of Key: URL, Value: Array of Webmentions`", async () => { + const fetched = await getWebmentions( + options, + "https://example.com/page2/", + ); + assert.strictEqual(fetched.length, 2); + }); + it("Should return an object of Key: URL, Value: Array of Webmentions of a specific type`", async () => { + const fetched = await getWebmentions( + options, + "https://example.com/page2/", + ["mention-of"], + ); + assert.strictEqual(fetched.length, 1); + }); +}); + +describe("getPublished()", () => { + it("Should return a published date from `data.published`", async () => { + const webmention = { + data: { + published: "2024-01-01T12:00:00Z", + }, + }; + assert.strictEqual(getPublished(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a published date from `published`", async () => { + const webmention = { + published: "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getPublished(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a published date from `wm-received`", async () => { + const webmention = { + "wm-received": "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getPublished(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a published date from `verified_date`", async () => { + const webmention = { + verified_date: "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getPublished(webmention), "2024-01-01T12:00:00Z"); + }); +}); + +describe("getReceived()", () => { + it("Should return a received date from `wm-received`", async () => { + const webmention = { + "wm-received": "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getReceived(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a received date from `verified_date`", async () => { + const webmention = { + verified_date: "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getReceived(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a received date from `published`", async () => { + const webmention = { + published: "2024-01-01T12:00:00Z", + }; + assert.strictEqual(getReceived(webmention), "2024-01-01T12:00:00Z"); + }); + + it("Should return a received date from `data.published`", async () => { + const webmention = { + data: { + published: "2024-01-01T12:00:00Z", + }, + }; + assert.strictEqual(getReceived(webmention), "2024-01-01T12:00:00Z"); + }); +}); + +describe("getContent()", () => { + it("Should return content from `contentSanitized`", async () => { + const webmention = { + contentSanitized: "Lorem ipsum", + }; + assert.strictEqual(getContent(webmention), "Lorem ipsum"); + }); + + it("Should return content from `content.html`", async () => { + const webmention = { + content: { + html: "

Lorem ipsum

", + }, + }; + assert.strictEqual(getContent(webmention), "

Lorem ipsum

"); + }); + + it("Should return content from `content.value`", async () => { + const webmention = { + content: { + value: "Lorem ipsum", + }, + }; + assert.strictEqual(getContent(webmention), "Lorem ipsum"); + }); + + it("Should return content from `content`", async () => { + const webmention = { + content: "Lorem ipsum", + }; + assert.strictEqual(getContent(webmention), "Lorem ipsum"); + }); + + it("Should return content from `data.content`", async () => { + const webmention = { + data: { + content: "Lorem ipsum", + }, + }; + assert.strictEqual(getContent(webmention), "Lorem ipsum"); + }); +}); + +describe("getSource()", () => { + it("Should return a source URL from `wm-source`", async () => { + const webmention = { + "wm-source": "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a source URL from `source`", async () => { + const webmention = { + source: "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a source URL from `data.url`", async () => { + const webmention = { + data: { + url: "https://example.com", + }, + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a source URL from `url`", async () => { + const webmention = { + url: "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); +}); + +describe("getURL()", () => { + it("Should return a origin URL from `data.url`", async () => { + const webmention = { + data: { + url: "https://example.com", + }, + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a origin URL from `url`", async () => { + const webmention = { + url: "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a origin URL from `wm-source`", async () => { + const webmention = { + "wm-source": "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); + + it("Should return a origin URL from `source`", async () => { + const webmention = { + source: "https://example.com", + }; + assert.strictEqual(getSource(webmention), "https://example.com"); + }); +}); + +describe("getTarget()", () => { + it("Should return a target URL from `wm-target`", async () => { + const webmention = { + "wm-target": "https://example.com", + }; + assert.strictEqual(getTarget(webmention), "https://example.com"); + }); + + it("Should return a target URL from `target`", async () => { + const webmention = { + target: "https://example.com", + }; + assert.strictEqual(getTarget(webmention), "https://example.com"); + }); +}); + +describe("getType()", () => { + it("Should return a Webmention type from `wm-property`", async () => { + const webmention = { + "wm-property": "mention-of", + }; + assert.strictEqual(getType(webmention), "mention-of"); + }); + + it("Should return a Webmention type from `activity.type`", async () => { + const webmention = { + activity: { + type: "mention-of", + }, + }; + assert.strictEqual(getType(webmention), "mention-of"); + }); + + it("Should return a Webmention type from `type`", async () => { + const webmention = { + type: "mention-of", + }; + assert.strictEqual(getType(webmention), "mention-of"); + }); +}); + +describe("getByType()", () => { + it("Should return an array of Webmentions based on a type", async () => { + const webmentions = [ + { + type: "mention-of", + }, + { + type: "in-reply-to", + }, + ]; + assert.strictEqual(getByType(webmentions, "mention-of").length, 1); + }); +}); + +describe("getByTypes()", () => { + it("Should return an array of Webmentions based on multiple types", async () => { + const webmentions = [ + { + type: "bookmark-of", + }, + { + type: "mention-of", + }, + { + type: "in-reply-to", + }, + ]; + assert.strictEqual( + getByTypes(webmentions, ["in-reply-to", "mention-of"]).length, + 2, + ); + }); +}); diff --git a/package.json b/package.json index 75745f4..52efb92 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@chrisburnell/eleventy-cache-webmentions", - "version": "2.1.5", + "version": "2.1.6", "description": "Cache webmentions using eleventy-fetch and make them available to use in collections, layouts, pages, etc. in Eleventy.", "license": "MIT", "repository": { @@ -39,7 +39,8 @@ }, "main": "eleventy-cache-webmentions.js", "scripts": { - "lint": "eslint eleventy-cache-webmentions.js" + "lint": "eslint eleventy-cache-webmentions.js", + "test": "node --test" }, "keywords": [ "eleventy", @@ -56,6 +57,7 @@ "sanitize-html": "^2.13.0" }, "devDependencies": { - "eslint": "^9.8.0" + "eslint": "^9.8.0", + "nock": "^13.5.4" } }