[FIX] web_editor: adapt link unit tests

Change the unit test to reflect new spec:

* Some TLD are white listed to not required a subdomain to be considered a valid URL.
 => .com, .net, .org + all ccTLD

* URL of a link need to be changed to equal the label, is the label is a new valid URL.

* Domain Extention cannot be only digit

task-2858621

X-original-commit: c13ba3ec771334c9cd7708305b40b9bf1a234bcc
Part-of: odoo/odoo#97297
This commit is contained in:
Sébastien Geelen (sge)
2022-08-02 13:06:45 +02:00
committed by David Monjoie
parent 0a4fcbfb68
commit bacda923e2
3 changed files with 206 additions and 7 deletions
@@ -1260,6 +1260,29 @@ describe('Copy and paste', () => {
},
contentAfter: '<p>a<a href="http://existing.com">bhttp://www.xyz.com[]c</a>d</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="http://existing.com">b[]c</a>d</p>',
stepFunction: async editor => {
await pasteText(editor, 'random');
},
contentAfter: '<p>a<a href="http://existing.com">brandom[]c</a>d</p>',
});
});
it('should paste and transform an URL in a existing link if pasting valid url', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="http://existing.com">[]c</a>d</p>',
stepFunction: async editor => {
await pasteText(editor, 'https://www.xyz.xdc');
},
contentAfter: '<p>a<a href="https://www.xyz.xdcc">https://www.xyz.xdc[]c</a>d</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="http://existing.com">b[].com</a>d</p>',
stepFunction: async editor => {
await pasteText(editor, 'oom');
},
contentAfter: '<p>a<a href="https://boom.com">boom[].com</a>d</p>',
});
});
});
describe('range not collapsed', async () => {
@@ -7,6 +7,7 @@ import {
insertLineBreak,
testEditor,
createLink,
undo
} from '../utils.js';
const convertToLink = createLink;
@@ -20,7 +21,7 @@ const testUrlRegex = (url) => {
});
}
const testNotUrlRegex = (url) => {
it(`should be a link: ${url}`, () => {
it(`should NOT be a link: ${url}`, () => {
window.chai.assert.notExists(url.match(URL_REGEX));
window.chai.assert.notExists(url.match(URL_REGEX_WITH_INFOS));
});
@@ -28,14 +29,25 @@ const testNotUrlRegex = (url) => {
describe('Link', () => {
describe('regex', () => {
testUrlRegex('google.com');
testUrlRegex('google.co.uk');
testUrlRegex('http://google.com');
testUrlRegex('https://google.com');
testUrlRegex('https://www.google.com');
testNotUrlRegex('google.shop');
testUrlRegex('google.com/');
testUrlRegex('http://google.com/');
testUrlRegex('https://google.com/');
testUrlRegex('https://google.co.uk/');
testUrlRegex('https://www.google.com/');
testNotUrlRegex('google.shop/');
testUrlRegex('http://google.com/foo#test');
testUrlRegex('a.bcd.ef');
testUrlRegex('a.bc.de');
testNotUrlRegex('google.com');
testNotUrlRegex('a.bc.d');
testNotUrlRegex('a.b.bc');
testNotUrlRegex('20.08.2022');
testNotUrlRegex('31.12');
});
describe('insert Link', () => {
// This fails, but why would the cursor stay inside the link
@@ -162,6 +174,113 @@ describe('Link', () => {
});
});
});
describe('edit link label', () => {
describe('range collapsed', () => {
it('should not change the url when a link is not edited', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.co">google.com</a>b</p>',
contentAfter: '<p>a<a href="https://google.co">google.com</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.xx">google.com</a>b<a href="https://google.co">cd[]</a></p>',
stepFunction: async editor => {
await insertText(editor, 'e');
},
contentAfter: '<p>a<a href="https://google.xx">google.com</a>b<a href="https://google.co">cde[]</a></p>',
});
});
it('should change the url when the label change', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.co">google.co[]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'm');
},
contentAfter: '<p>a<a href="https://google.com">google.com[]</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://gogle.com">go[]gle.com</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'o');
},
contentAfter: '<p>a<a href="https://google.com">goo[]gle.com</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://else.com">go[]gle.com</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'o');
},
contentAfter: '<p>a<a href="https://google.com">goo[]gle.com</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://else.com">http://go[]gle.com</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'o');
},
contentAfter: '<p>a<a href="http://google.com">http://goo[]gle.com</a>b</p>',
});
});
it('should change the url in one step', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.co">google.co[]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'm');
await undo(editor);
},
contentAfter: '<p>a<a href="https://google.co">google.co[]</a>b</p>',
});
});
it('should not change the url when the label change', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.com">google.com[]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'u');
},
contentAfter: '<p>a<a href="https://google.com">google.comu[]</a>b</p>',
});
});
});
describe('range not collapsed', () => {
it('should change the url when the label change', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.com">google.[com]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'be');
},
contentAfter: '<p>a<a href="https://google.be">google.be[]</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://gogle.com">[yahoo].com</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'google');
},
contentAfter: '<p>a<a href="https://google.com">google[].com</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://else.com">go[gle.c]om</a>b</p>',
stepFunction: async editor => {
await insertText(editor, '.c');
},
contentAfter: '<p>a<a href="https://go.com">go.c[]om</a>b</p>',
});
});
it('should not change the url when the label change', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.com">googl[e.com]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'e');
},
contentAfter: '<p>a<a href="https://google.com">google[]</a>b</p>',
});
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="https://google.com">google.[com]</a>b</p>',
stepFunction: async editor => {
await insertText(editor, 'vvv');
},
contentAfter: '<p>a<a href="https://google.com">google.vvv[]</a>b</p>',
});
});
});
});
describe('remove link', () => {
describe('range collapsed', () => {
it('should remove the link if collapsed range at the end of a link', async () => {
@@ -317,6 +436,15 @@ describe('Link', () => {
contentAfter: '<p>a<a href="exist">bc[]</a>d</p>',
});
});
it('should add two character after the link', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="exist">b[]</a>e</p>',
stepFunction: async editor => {
await insertText(editor, 'cd');
},
contentAfter: '<p>a<a href="exist">bcd[]</a>e</p>',
});
});
it('should add a character after the link if range just after link', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>a<a href="exist">b</a>[]d</p>',
@@ -1,20 +1,24 @@
import { URL_REGEX } from '../../src/OdooEditor.js';
import { URL_REGEX, URL_REGEX_WITH_INFOS } from '../../src/OdooEditor.js';
describe('urlRegex', () => {
it('should not match foo.com', () => {
it('should match foo.com', () => {
const url = 'foo.com';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX);
chai.expect(match[0]).to.be.equal(url);
});
it('should not match foo.else', () => {
const url = 'foo.else';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX);
chai.expect(match).to.be.equal(null);
});
it('should match abc.abc.abc', () => {
const url = 'abc.abc.abc';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX);
chai.expect(match[0]).to.be.equal(url);
});
it('should match http://abc.abc.abc', () => {
const url = 'http://abc.abc.abc';
const text = `abc ${url} abc`;
@@ -27,7 +31,6 @@ describe('urlRegex', () => {
const match = text.match(URL_REGEX);
chai.expect(match[0]).to.be.equal(url);
});
it('should match 1234-abc.runbot007.odoo.com/web#id=3&menu_id=221', () => {
const url = '1234-abc.runbot007.odoo.com/web#id=3&menu_id=221';
const text = `abc ${url} abc`;
@@ -41,3 +44,48 @@ describe('urlRegex', () => {
chai.expect(match[0]).to.be.equal(url);
});
});
describe('urlRegex with infos', () => {
it('should match foo.com', () => {
const url = 'foo.com';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
it('should not match foo.else', () => {
const url = 'foo.else';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match).to.be.equal(null);
});
it('should match abc.abc.abc', () => {
const url = 'abc.abc.abc';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
it('should match http://abc.abc.abc', () => {
const url = 'http://abc.abc.abc';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
it('should match https://abc.abc.abc', () => {
const url = 'https://abc.abc.abc';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
it('should match 1234-abc.runbot007.odoo.com/web#id=3&menu_id=221', () => {
const url = '1234-abc.runbot007.odoo.com/web#id=3&menu_id=221';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
it('should match https://1234-abc.runbot007.odoo.com/web#id=3&menu_id=221', () => {
const url = 'https://1234-abc.runbot007.odoo.com/web#id=3&menu_id=221';
const text = `abc ${url} abc`;
const match = text.match(URL_REGEX_WITH_INFOS);
chai.expect(match[0]).to.be.equal(url);
});
});