import { describe, expect, test } from "@odoo/hoot";
import { addLink, parseAndTransform } from "@mail/utils/common/format";
import {
click,
contains,
defineMailModels,
insertText,
openDiscuss,
start,
startServer,
} from "./mail_test_helpers";
import { useSequential } from "@mail/utils/common/hooks";
describe.current.tags("desktop");
defineMailModels();
test("add_link utility function", () => {
const testInputs = {
"http://admin:password@example.com:8/%2020": true,
"https://admin:password@example.com/test": true,
"www.example.com:8/test": true,
"https://127.0.0.5:8069": true,
"www.127.0.0.5": false,
"should.notmatch": false,
"fhttps://test.example.com/test": false,
"https://www.transifex.com/odoo/odoo-11/translate/#fr/lunch?q=text%3A'La+Tartiflette'": true,
"https://www.transifex.com/odoo/odoo-11/translate/#fr/$/119303430?q=text%3ATartiflette": true,
"https://tenor.com/view/chỗgiặt-dog-smile-gif-13860250": true,
"http://www.boîtenoire.be": true,
"https://github.com/odoo/enterprise/compare/16.0...odoo-dev:enterprise:16.0-voip-fix_demo_data-tsm?expand=1": true,
"https://github.com/odoo/enterprise/compare/16.0...16.0-voip-fix_demo_data-tsm?expand=1": true,
"https://github.com/odoo/enterprise/compare/16.0...chỗgiặt-voip-fix_demo_data-tsm?expand=1": true,
"https://github.com/odoo/enterprise/compare/chỗgiặt...chỗgiặt-voip-fix_demo_data-tsm?expand=1": true,
"https://github.com/odoo/enterprise/compare/@...}-voip-fix_demo_data-tsm?expand=1": true,
"https://x.com": true,
};
for (const [content, willLinkify] of Object.entries(testInputs)) {
const output = parseAndTransform(content, addLink);
if (willLinkify) {
expect(output.indexOf("")).toBe(output.length - 4);
} else {
expect(output.indexOf(" {
const testInputs = {
// textContent not unescaped
" https://example.com/?¤cy_id https://example.com/?¤cy_id https://example.com/> https://example.com/"hello"> https://example.com/"hello"> https://example.com/&hello https://example.com/'yeah'
some text https://somelink.com
"; const linkified = parseAndTransform(content, addLink); expect(linkified.startsWith("")).toBe(true); // linkify may add some attributes. Since we do not care of their exact // stringified representation, we continue deeper assertion with query // selectors. const fragment = document.createDocumentFragment(); const div = document.createElement("div"); fragment.appendChild(div); div.innerHTML = linkified; expect(div).toHaveText("some text https://somelink.com"); await contains("a", { target: div }); expect(div.querySelector(":scope a")).toHaveText("https://somelink.com"); }); test("addLink: linkify inside text node (2 occurrences)", () => { // linkify may add some attributes. Since we do not care of their exact // stringified representation, we continue deeper assertion with query // selectors. const content = "some text https://somelink.com and again https://somelink2.com ...
"; const linkified = parseAndTransform(content, addLink); const fragment = document.createDocumentFragment(); const div = document.createElement("div"); fragment.appendChild(div); div.innerHTML = linkified; expect(div).toHaveText("some text https://somelink.com and again https://somelink2.com ..."); expect(div.querySelectorAll(":scope a")).toHaveCount(2); expect(div.querySelectorAll(":scope a")[0]).toHaveText("https://somelink.com"); expect(div.querySelectorAll(":scope a")[1]).toHaveText("https://somelink2.com"); }); test("url", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); // see: https://www.ietf.org/rfc/rfc1738.txt const messageBody = "https://odoo.com?test=~^|`{}[]#"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains(`.o-mail-Message a:contains(${messageBody})`); }); test("url with comma at the end", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); const messageBody = "Go to https://odoo.com, it's great!"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains(".o-mail-Message a:contains(https://odoo.com)"); await contains(`.o-mail-Message-content:contains(${messageBody}`); }); test("url with dot at the end", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); const messageBody = "Go to https://odoo.com. It's great!"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains(".o-mail-Message a:contains(https://odoo.com)"); await contains(`.o-mail-Message-content:contains(${messageBody})`); }); test("url with semicolon at the end", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); const messageBody = "Go to https://odoo.com; it's great!"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains(".o-mail-Message a:contains(https://odoo.com)"); await contains(`.o-mail-Message-content:contains(${messageBody})`); }); test("url with ellipsis at the end", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); const messageBody = "Go to https://odoo.com... it's great!"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains(".o-mail-Message a:contains(https://odoo.com)"); await contains(`.o-mail-Message-content:contains(${messageBody})`); }); test("url with number in subdomain", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); await start(); await openDiscuss(channelId); const messageBody = "https://www.45017478-master-all.runbot134.odoo.com/odoo"; await insertText(".o-mail-Composer-input", messageBody); await click("button[aria-label='Send']:enabled"); await contains( ".o-mail-Message a:contains(https://www.45017478-master-all.runbot134.odoo.com/odoo)" ); }); test("isSequential doesn't execute intermediate call.", async () => { const sequential = useSequential(); let index = 0; const sequence = () => { index++; const i = index; return sequential(async () => { expect.step(i.toString()); return new Promise((r) => setTimeout(() => r(i), 1)); }); }; const result = await Promise.all([sequence(), sequence(), sequence(), sequence(), sequence()]); expect(result).toEqual([1, undefined, undefined, undefined, 5]); expect.verifySteps(["1", "5"]); });