🐛 Fixed adding recommendations with long excerpts (#19949)

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
This commit is contained in:
Sag 2024-03-28 17:02:37 +01:00 committed by GitHub
parent 60b8316bb6
commit 540660a49e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 27 deletions

View File

@ -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({ throw new errors.ValidationError({
message: 'Description must be less than 2000 characters' message: 'Description must be less than 200 characters'
});
}
if (properties.excerpt && properties.excerpt.length > 2000) {
throw new errors.ValidationError({
message: 'Excerpt must be less than 2000 characters'
}); });
} }
} }
@ -121,6 +115,14 @@ export class Recommendation {
this.description = null; 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.createdAt.setMilliseconds(0);
this.updatedAt?.setMilliseconds(0); this.updatedAt?.setMilliseconds(0);
} }

View File

@ -41,7 +41,7 @@ describe('Recommendation', function () {
assert.throws(() => { assert.throws(() => {
Recommendation.validate({ Recommendation.validate({
title: 'Test', title: 'Test',
description: 'a'.repeat(2001), description: 'a'.repeat(201),
excerpt: null, excerpt: null,
featuredImage: null, featuredImage: null,
favicon: null, favicon: null,
@ -50,24 +50,7 @@ describe('Recommendation', function () {
}); });
}, { }, {
name: 'ValidationError', name: 'ValidationError',
message: 'Description must be less than 2000 characters' message: 'Description must be less than 200 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'
}); });
}); });
}); });
@ -118,6 +101,36 @@ describe('Recommendation', function () {
assert.equal(recommendation.description, null); 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 () { it('keeps search and hash params', function () {
const recommendation = Recommendation.create({ const recommendation = Recommendation.create({
title: 'Test', title: 'Test',