fix: #12866, improve title generator, refactor tests

This commit is contained in:
Julian Lam
2024-10-25 13:18:45 -04:00
parent eccad588f4
commit beb85604bd
2 changed files with 40 additions and 32 deletions

View File

@@ -306,7 +306,7 @@ Helpers.resolveObjects = async (ids) => {
}; };
const titleishTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'title', 'p', 'span']; const titleishTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'title', 'p', 'span'];
const titleRegex = new RegExp(`<(?:${titleishTags.join('|')})>(.+?)</(?:${titleishTags.join('|')})>`); const titleRegex = new RegExp(`<(${titleishTags.join('|')})>(.+?)</\\1>`, 'm');
Helpers.generateTitle = (html) => { Helpers.generateTitle = (html) => {
// Given an html string, generates a more appropriate title if possible // Given an html string, generates a more appropriate title if possible
let title; let title;
@@ -314,12 +314,15 @@ Helpers.generateTitle = (html) => {
// Try the first paragraph-like element // Try the first paragraph-like element
const match = html.match(titleRegex); const match = html.match(titleRegex);
if (match) { if (match) {
title = match[1]; title = match[2];
} }
// Fall back to newline splitting (i.e. if no paragraph elements) // Fall back to newline splitting (i.e. if no paragraph elements)
title = title || html.split('\n').filter(Boolean).shift(); title = title || html.split('\n').filter(Boolean).shift();
// Discard everything after a line break element
title = title.replace(/<br(\s\/)?>.*/g, '');
// Strip html // Strip html
title = utils.stripHTMLTags(title); title = utils.stripHTMLTags(title);
@@ -338,6 +341,9 @@ Helpers.generateTitle = (html) => {
title = sentences.shift(); title = sentences.shift();
} }
// Trim certain punctuation marks
title = title.trim().replace(/[:]$/, '');
// Truncate down if too long // Truncate down if too long
if (title.length > meta.config.maximumTitleLength) { if (title.length > meta.config.maximumTitleLength) {
title = `${title.slice(0, meta.config.maximumTitleLength - 3)}...`; title = `${title.slice(0, meta.config.maximumTitleLength - 3)}...`;

View File

@@ -108,27 +108,41 @@ describe('ActivityPub integration', () => {
}); });
}); });
describe.only('.generateTitle', () => { describe('.generateTitle', () => {
it('should take the first paragraph element\'s text', () => { describe('test strings', () => {
const source = '<p>Lorem ipsum dolor sit amet</p><p>consectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.</p>'; const cases = new Map([
const title = activitypub.helpers.generateTitle(source); // first paragraph element
assert.strictEqual(title, 'Lorem ipsum dolor sit amet'); ['<p>test title</p><span>abc</span>', 'test title'],
});
it('should also accept a couple other tags like h1 or span', () => { // other tags like h1 or span
let source = '<h1>Lorem ipsum dolor sit amet</h1><p>consectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.</p>'; ['<h1>Lorem ipsum dolor sit amet</h1><p>consectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.</p>', 'Lorem ipsum dolor sit amet'],
let title = activitypub.helpers.generateTitle(source); ['<span>Lorem ipsum dolor sit amet</span><p>consectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.</p>', 'Lorem ipsum dolor sit amet'],
assert.strictEqual(title, 'Lorem ipsum dolor sit amet');
source = '<span>Lorem ipsum dolor sit amet</span><p>consectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.</p>'; // first line's text otherwise
title = activitypub.helpers.generateTitle(source); ['Lorem ipsum dolor sit amet\n\nconsectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.', 'Lorem ipsum dolor sit amet'],
assert.strictEqual(title, 'Lorem ipsum dolor sit amet');
});
it('should take the first line\'s text if no matched elements', () => { // first sentence of matched line/element
const source = 'Lorem ipsum dolor sit amet\n\nconsectetur adipiscing elit. Integer tincidunt metus scelerisque, dignissim risus a, fermentum leo. Pellentesque eleifend ullamcorper risus tempus vestibulum. Proin mollis ipsum et magna lobortis, at pretium enim pharetra. Ut vel ex metus. Mauris faucibus lectus et nulla iaculis, et pellentesque elit pellentesque. Aliquam rhoncus nec nulla eu lacinia. Maecenas cursus iaculis ligula, eu pharetra ex suscipit sit amet.'; ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a ex pellentesque, fringilla lorem non, blandit est. Nulla facilisi. Curabitur cursus neque vel enim semper, id lacinia elit facilisis. Vestibulum turpis orci, efficitur ut semper eu, faucibus eu turpis. Praesent eu odio non libero gravida tempor. Ut porta pellentesque orci. In porta nunc eget tincidunt interdum. Curabitur vel dui nec libero tempus porttitor. Phasellus tincidunt, diam id viverra suscipit, est diam maximus purus, in vestibulum dui ligula vel libero. Sed tempus finibus ante, sit amet consequat magna facilisis eget. Proin ullamcorper, velit sit amet feugiat varius, massa sem aliquam dui, non aliquam augue velit vel est. Phasellus eu sapien in purus feugiat scelerisque congue id velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'],
const title = activitypub.helpers.generateTitle(source);
assert.strictEqual(title, 'Lorem ipsum dolor sit amet'); // other sentence ending symbols
['Lorem ipsum dolor sit amet, consectetur adipiscing elit? Etiam a ex pellentesque, fringilla lorem non, blandit est. Nulla facilisi. Curabitur cursus neque vel enim semper, id lacinia elit facilisis. Vestibulum turpis orci, efficitur ut semper eu, faucibus eu turpis. Praesent eu odio non libero gravida tempor. Ut porta pellentesque orci. In porta nunc eget tincidunt interdum. Curabitur vel dui nec libero tempus porttitor. Phasellus tincidunt, diam id viverra suscipit, est diam maximus purus, in vestibulum dui ligula vel libero. Sed tempus finibus ante, sit amet consequat magna facilisis eget. Proin ullamcorper, velit sit amet feugiat varius, massa sem aliquam dui, non aliquam augue velit vel est. Phasellus eu sapien in purus feugiat scelerisque congue id velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit?'],
// should trim non-sentence-ending punctuation
['<span>one two three:</span><p>four five six</p>', 'one two three'],
// Content after line breaks can be discarded
['<p>Intro text<br /><a href=\"https://example.org/\">example.org/</span></a></p><p>more text</p>', 'Intro text'],
// Additional tests?
// ['', ''],
]);
cases.forEach((value, key) => {
it('should convert as expected', () => {
const title = activitypub.helpers.generateTitle(key);
assert.strictEqual(title, value);
});
});
}); });
it('should trim down the title if it is too long per settings', () => { it('should trim down the title if it is too long per settings', () => {
@@ -139,18 +153,6 @@ describe('ActivityPub integration', () => {
assert.strictEqual(title, '@@@@@@@...'); assert.strictEqual(title, '@@@@@@@...');
meta.config.maximumTitleLength = value; meta.config.maximumTitleLength = value;
}); });
it('should take the first sentence of a matched element/line', () => {
const source = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a ex pellentesque, fringilla lorem non, blandit est. Nulla facilisi. Curabitur cursus neque vel enim semper, id lacinia elit facilisis. Vestibulum turpis orci, efficitur ut semper eu, faucibus eu turpis. Praesent eu odio non libero gravida tempor. Ut porta pellentesque orci. In porta nunc eget tincidunt interdum. Curabitur vel dui nec libero tempus porttitor. Phasellus tincidunt, diam id viverra suscipit, est diam maximus purus, in vestibulum dui ligula vel libero. Sed tempus finibus ante, sit amet consequat magna facilisis eget. Proin ullamcorper, velit sit amet feugiat varius, massa sem aliquam dui, non aliquam augue velit vel est. Phasellus eu sapien in purus feugiat scelerisque congue id velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.';
const title = activitypub.helpers.generateTitle(source);
assert.strictEqual(title, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
});
it('should also consider other sentence ending symbols', () => {
const source = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit? Etiam a ex pellentesque, fringilla lorem non, blandit est. Nulla facilisi. Curabitur cursus neque vel enim semper, id lacinia elit facilisis. Vestibulum turpis orci, efficitur ut semper eu, faucibus eu turpis. Praesent eu odio non libero gravida tempor. Ut porta pellentesque orci. In porta nunc eget tincidunt interdum. Curabitur vel dui nec libero tempus porttitor. Phasellus tincidunt, diam id viverra suscipit, est diam maximus purus, in vestibulum dui ligula vel libero. Sed tempus finibus ante, sit amet consequat magna facilisis eget. Proin ullamcorper, velit sit amet feugiat varius, massa sem aliquam dui, non aliquam augue velit vel est. Phasellus eu sapien in purus feugiat scelerisque congue id velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.';
const title = activitypub.helpers.generateTitle(source);
assert.strictEqual(title, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit?');
});
}); });
}); });