From d7b3721036489b117afc54abc15d89cad6c15c15 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Thu, 20 Oct 2022 18:17:44 +0530 Subject: [PATCH] Added edited property to links api refs https://github.com/TryGhost/Team/issues/2104 - adds a boolean `edited` property to links api that denotes if the link has been edited --- .../LinkRedirectRepository.js | 6 +++++- .../admin/__snapshots__/links.test.js.snap | 20 ++++++++++++++---- ghost/core/test/e2e-api/admin/links.test.js | 21 +++++++++++++++---- ghost/link-redirects/lib/LinkRedirect.js | 3 +++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/ghost/core/core/server/services/link-redirection/LinkRedirectRepository.js b/ghost/core/core/server/services/link-redirection/LinkRedirectRepository.js index 28f3e06010..008d34cc39 100644 --- a/ghost/core/core/server/services/link-redirection/LinkRedirectRepository.js +++ b/ghost/core/core/server/services/link-redirection/LinkRedirectRepository.js @@ -36,10 +36,14 @@ module.exports = class LinkRedirectRepository { } fromModel(model) { + // Store if link has been edited + const edited = model.get('created_at')?.getTime() !== model.get('updated_at')?.getTime(); + return new LinkRedirect({ id: model.id, from: new URL(this.#trimLeadingSlash(model.get('from')), this.#urlUtils.urlFor('home', true)), - to: new URL(model.get('to')) + to: new URL(model.get('to')), + edited }); } diff --git a/ghost/core/test/e2e-api/admin/__snapshots__/links.test.js.snap b/ghost/core/test/e2e-api/admin/__snapshots__/links.test.js.snap index a64e7d793c..14f23d135b 100644 --- a/ghost/core/test/e2e-api/admin/__snapshots__/links.test.js.snap +++ b/ghost/core/test/e2e-api/admin/__snapshots__/links.test.js.snap @@ -8,6 +8,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -19,6 +20,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -30,6 +32,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -98,7 +101,7 @@ exports[`Links API Can browse all links 2: [headers] 1`] = ` Object { "access-control-allow-origin": "http://127.0.0.1:2369", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "885", + "content-length": "930", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "vary": "Accept-Version, Origin, Accept-Encoding", @@ -154,6 +157,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": true, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": "https://example.com/subscribe?ref=Test-newsletter", @@ -165,6 +169,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -176,6 +181,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -244,7 +250,7 @@ exports[`Links API Can bulk update links with external redirect 4: [headers] 1`] Object { "access-control-allow-origin": "http://127.0.0.1:2369", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "885", + "content-length": "929", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "vary": "Accept-Version, Origin, Accept-Encoding", @@ -300,6 +306,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -311,6 +318,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": true, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": "http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df", @@ -322,6 +330,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": true, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": "http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df", @@ -390,7 +399,7 @@ exports[`Links API Can bulk update multiple links with same site redirect 4: [he Object { "access-control-allow-origin": "http://127.0.0.1:2369", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "841", + "content-length": "884", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "vary": "Accept-Version, Origin, Accept-Encoding", @@ -446,6 +455,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": "https://example.com/subscripe?ref=Test-newsletter", @@ -457,6 +467,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -468,6 +479,7 @@ Object { "clicks": Any, }, "link": Object { + "edited": false, "from": Any, "link_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "to": Any, @@ -536,7 +548,7 @@ exports[`Links API Can call bulk update link with 0 matches 4: [headers] 1`] = ` Object { "access-control-allow-origin": "http://127.0.0.1:2369", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "885", + "content-length": "930", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "vary": "Accept-Version, Origin, Accept-Encoding", diff --git a/ghost/core/test/e2e-api/admin/links.test.js b/ghost/core/test/e2e-api/admin/links.test.js index 2b05da11f9..6f4f325c09 100644 --- a/ghost/core/test/e2e-api/admin/links.test.js +++ b/ghost/core/test/e2e-api/admin/links.test.js @@ -6,13 +6,20 @@ const matchLink = { link: { link_id: anyObjectId, from: anyString, - to: anyString + to: anyString, + edited: false }, count: { clicks: anyNumber } }; +async function sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); +} + describe('Links API', function () { let agent; beforeEach(async function () { @@ -41,6 +48,8 @@ describe('Links API', function () { const postId = siteLink.post_id; const originalTo = siteLink.link.to; const filter = `post_id:${postId}+to:'${originalTo}'`; + // Sleep ensures the updated time of the link is different than created + await sleep(1000); await agent .put(`links/bulk/?filter=${encodeURIComponent(filter)}`) .body({ @@ -83,14 +92,16 @@ describe('Links API', function () { ...matchLink, link: { ...matchLink.link, - to: 'http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df' + to: 'http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df', + edited: true } }, { ...matchLink, link: { ...matchLink.link, - to: 'http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df' + to: 'http://127.0.0.1:2369/blog/emails/test?example=1&ref=Test-newsletter&attribution_type=post&attribution_id=618ba1ffbe2896088840a6df', + edited: true } } ] @@ -105,6 +116,7 @@ describe('Links API', function () { const postId = siteLink.post_id; const originalTo = siteLink.link.to; const filter = `post_id:${postId}+to:'${originalTo}'`; + await sleep(1000); await agent .put(`links/bulk/?filter=${encodeURIComponent(filter)}`) .body({ @@ -146,7 +158,8 @@ describe('Links API', function () { ...matchLink, link: { ...matchLink.link, - to: 'https://example.com/subscribe?ref=Test-newsletter' + to: 'https://example.com/subscribe?ref=Test-newsletter', + edited: true } }, matchLink, diff --git a/ghost/link-redirects/lib/LinkRedirect.js b/ghost/link-redirects/lib/LinkRedirect.js index a44f8e4c38..a9ed13ad1a 100644 --- a/ghost/link-redirects/lib/LinkRedirect.js +++ b/ghost/link-redirects/lib/LinkRedirect.js @@ -7,6 +7,8 @@ module.exports = class LinkRedirect { from; /** @type {URL} */ to; + /** @type {boolean} */ + edited; constructor(data) { if (!data.id) { @@ -19,5 +21,6 @@ module.exports = class LinkRedirect { this.from = data.from; this.to = data.to; + this.edited = !!data.edited; } };