From 540660a49e2a336a4fda9d2179102cf4ff7f5329 Mon Sep 17 00:00:00 2001 From: Sag Date: Thu, 28 Mar 2024 17:02:37 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20adding=20recommendations?= =?UTF-8?q?=20with=20long=20excerpts=20(#19949)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref https://linear.app/tryghost/issue/ENG-801/unable-to-recommend-sites-with-long-excerpts - recommending a site with a long excerpt was being blocked by a validation error - with this change, we truncate the excerpt to 2000 characters max. and avoid showing an error in the UI - with this change, the description length validation is also now stricter; 200 characters max, instead of 2000, to match the UI --- ghost/recommendations/src/Recommendation.ts | 18 ++++--- .../test/Recommendation.test.ts | 51 ++++++++++++------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/ghost/recommendations/src/Recommendation.ts b/ghost/recommendations/src/Recommendation.ts index f0da1da2da..d663feaa9b 100644 --- a/ghost/recommendations/src/Recommendation.ts +++ b/ghost/recommendations/src/Recommendation.ts @@ -103,15 +103,9 @@ export class Recommendation { }); } - if (properties.description && properties.description.length > 2000) { + if (properties.description && properties.description.length > 200) { throw new errors.ValidationError({ - message: 'Description must be less than 2000 characters' - }); - } - - if (properties.excerpt && properties.excerpt.length > 2000) { - throw new errors.ValidationError({ - message: 'Excerpt must be less than 2000 characters' + message: 'Description must be less than 200 characters' }); } } @@ -121,6 +115,14 @@ export class Recommendation { this.description = null; } + if (this.excerpt !== null && this.excerpt.length === 0) { + this.excerpt = null; + } + + if (this.excerpt !== null && this.excerpt.length > 2000) { + this.excerpt = this.excerpt.slice(0, 1997) + '...'; + } + this.createdAt.setMilliseconds(0); this.updatedAt?.setMilliseconds(0); } diff --git a/ghost/recommendations/test/Recommendation.test.ts b/ghost/recommendations/test/Recommendation.test.ts index f7a8fc2357..2aaddfe028 100644 --- a/ghost/recommendations/test/Recommendation.test.ts +++ b/ghost/recommendations/test/Recommendation.test.ts @@ -41,7 +41,7 @@ describe('Recommendation', function () { assert.throws(() => { Recommendation.validate({ title: 'Test', - description: 'a'.repeat(2001), + description: 'a'.repeat(201), excerpt: null, featuredImage: null, favicon: null, @@ -50,24 +50,7 @@ describe('Recommendation', function () { }); }, { name: 'ValidationError', - message: 'Description must be less than 2000 characters' - }); - }); - - it('Throws for a long excerpt', function () { - assert.throws(() => { - Recommendation.validate({ - title: 'Test', - description: null, - excerpt: 'a'.repeat(2001), - featuredImage: null, - favicon: null, - url: 'https://example.com', - oneClickSubscribe: false - }); - }, { - name: 'ValidationError', - message: 'Excerpt must be less than 2000 characters' + message: 'Description must be less than 200 characters' }); }); }); @@ -118,6 +101,36 @@ describe('Recommendation', function () { assert.equal(recommendation.description, null); }); + it('sets empty excerpt to null', function () { + const recommendation = Recommendation.create({ + title: 'Test', + description: null, + excerpt: '', + featuredImage: null, + favicon: null, + url: 'https://example.com', + oneClickSubscribe: false, + updatedAt: new Date('2021-01-01T00:00:05Z') + }); + + assert.equal(recommendation.excerpt, null); + }); + + it('truncates long excerpts', function () { + const recommendation = Recommendation.create({ + title: 'Test', + description: null, + excerpt: 'a'.repeat(2001), + featuredImage: null, + favicon: null, + url: 'https://example.com', + oneClickSubscribe: false, + updatedAt: new Date('2021-01-01T00:00:05Z') + }); + + assert.equal(recommendation.excerpt?.length, 2000); + }); + it('keeps search and hash params', function () { const recommendation = Recommendation.create({ title: 'Test',