(core) Use slugify module to construct slugs in urlIds, addressing a long-standing TODO.

Summary:
This offers better handling for accented and non-English characters,
e.g. "Événements" becomes "Evenements" (rather than "vnements") and
"таблиця" becomes "tablicya" rather than an empty string.

Test Plan:
Added a test case. Existing documents will auto-redirect to
newly-generated names. In cases where it's different, that's probably for the
best.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4176
This commit is contained in:
Dmitry S
2024-01-25 23:58:52 -05:00
parent fb276bade7
commit be0b4a1968
4 changed files with 35 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
import {decodeUrl, getHostType, IGristUrlState, parseFirstUrlPart} from 'app/common/gristUrls';
import {decodeUrl, getHostType, getSlugIfNeeded, IGristUrlState, parseFirstUrlPart} from 'app/common/gristUrls';
import {assert} from 'chai';
import * as testUtils from 'test/server/testUtils';
@@ -129,4 +129,27 @@ describe('gristUrls', function() {
assert.equal(getHostType('doc-worker-123.internal:8079', defaultOptions), 'custom');
});
});
describe('getSlugIfNeeded', function() {
it('should only return a slug when a valid urlId is used', function() {
assert.strictEqual(getSlugIfNeeded({id: '1234567890abcdef', urlId: '1234567890ab', name: 'Foo'}), 'Foo');
// urlId too short
assert.strictEqual(getSlugIfNeeded({id: '1234567890abcdef', urlId: '12345678', name: 'Foo'}), undefined);
// urlId doesn't match docId
assert.strictEqual(getSlugIfNeeded({id: '1234567890abcdef', urlId: '1234567890ac', name: 'Foo'}), undefined);
// no urlId
assert.strictEqual(getSlugIfNeeded({id: '1234567890abcdef', urlId: '', name: 'Foo'}), undefined);
assert.strictEqual(getSlugIfNeeded({id: '1234567890abcdef', urlId: null, name: 'Foo'}), undefined);
});
it('should leave only alphamerics after replacing reasonable unicode chars', function() {
const id = '1234567890abcdef', urlId = '1234567890ab';
// This is mainly a test of the `slugify` library we now use. What matters isn't the
// specific result, but that the result is reasonable.
assert.strictEqual(getSlugIfNeeded({id, urlId, name: 'Foo'}), 'Foo');
assert.strictEqual(getSlugIfNeeded({id, urlId, name: "Hélène's résumé"}), 'Helenes-resume');
assert.strictEqual(getSlugIfNeeded({id, urlId, name: "Привіт, Їжак!"}), 'Privit-Yizhak');
assert.strictEqual(getSlugIfNeeded({id, urlId, name: "S&P500 is ~$4,894.16"}), 'SandP500-is-dollar489416');
});
});
});