import { describe, expect, test } from "@odoo/hoot"; import { setupEditor, testEditor } from "./_helpers/editor"; import { deleteBackward, deleteForward, insertText, undo } from "./_helpers/user_actions"; import { getContent } from "./_helpers/selection"; import { execCommand } from "./_helpers/userCommands"; function insertFontAwesome(faClass) { return (editor) => { execCommand(editor, "insertFontAwesome", { faClass }); }; } describe("parse/render", () => { test("should parse an old-school fontawesome", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a brand fontawesome", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a duotone fontawesome", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a light fontawesome", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a regular fontawesome", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a solid fontawesome", async () => { await testEditor({ // @phoenix content adapted to make it valid html contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a fontawesome in a ", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a fontawesome in a ", async () => { await testEditor({ // @phoenix content adapted to make it valid html contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); await testEditor({ // @phoenix content adapted to make it valid html contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a fontawesome with more classes", async () => { await testEditor({ contentBefore: '

', contentBeforeEdit: '

\u200b

', contentAfter: '

', }); }); test("should parse a fontawesome with multi-line classes", async () => { await testEditor({ contentBefore: `

`, contentBeforeEdit: `

\u200b

`, contentAfter: `

`, }); }); test("should parse a fontawesome with more multi-line classes", async () => { await testEditor({ contentBefore: `

`, contentBeforeEdit: `

\u200b

`, contentAfter: `

`, }); }); test("should parse a fontawesome at the beginning of a paragraph", async () => { await testEditor({ contentBefore: '

a[b]c

', contentBeforeEdit: '

\u200ba[b]c

', contentAfter: '

a[b]c

', }); }); test("should parse a fontawesome in the middle of a paragraph", async () => { await testEditor({ contentBefore: '

a[b]cdef

', contentBeforeEdit: '

a[b]c\u200bdef

', contentAfter: '

a[b]cdef

', }); }); test("should parse a fontawesome at the end of a paragraph", async () => { await testEditor({ contentBefore: '

a[b]c

', contentBeforeEdit: '

a[b]c\u200b

', contentAfter: '

a[b]c

', }); }); /** not sure this is necessary, keep for now in case it is test('should insert navigation helpers when before a fontawesome, in an editable', async () => { await testEditor({ contentBefore: '

abc[]

', contentAfter: '

abc[]\u200B\u200B

', }); await testEditor({ contentBefore: '

[]

', contentAfter: '

\u200B[]\u200B

', }); }); test('should insert navigation helpers when after a fontawesome, in an editable', async () => { await testEditor({ contentBefore: '

[]abc

', contentAfter: '

\u200B\u200B[]abc

', }); await testEditor({ contentBefore: '

[]

', contentAfter: '

\u200B\u200B[]

', }); }); test('should not insert navigation helpers when not adjacent to a fontawesome, in an editable', async () => { await testEditor({ contentBefore: '

ab[]c

', contentAfter: '

ab[]c

', }); await testEditor({ contentBefore: '

a[]bc

', contentAfter: '

a[]bc

', }); }); test('should not insert navigation helpers when adjacent to a fontawesome in contenteditable=false container', async () => { await testEditor({ contentBefore: '

abc[]

', contentAfter: '

abc

', }); await testEditor({ contentBefore: '

[]abc

', contentAfter: '

abc

', }); }); test('should not insert navigation helpers when adjacent to a fontawesome in contenteditable=false format', async () => { await testEditor({ contentBefore: '

abc[]

', contentAfter: '

abc

', }); await testEditor({ contentBefore: '

[]abc

', contentAfter: '

abc

', }); }); test('should not insert navigation helpers when adjacent to a fontawesome in contenteditable=false format (oe-nested)', async () => { await testEditor({ contentBefore: '

abc[]

', contentAfter: '

abc

', }); await testEditor({ contentBefore: '

[]abc

', contentAfter: '

abc

', }); });*/ }); describe("deleteForward", () => { describe("Selection collapsed", () => { describe("Basic", () => { test("should delete a fontawesome (deleteForward, collapsed)", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab[]\u200bcd

', stepFunction: deleteForward, contentAfter: "

ab[]cd

", }); }); test("should not delete a fontawesome", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab\u200b[]cd

', stepFunction: deleteForward, contentAfterEdit: '

ab\u200b[]d

', contentAfter: '

ab[]d

', }); }); test("should not delete a fontawesome after multiple deleteForward", async () => { await testEditor({ contentBefore: '

ab[]cdefghij

', contentBeforeEdit: '

ab[]cde\u200bfghij

', stepFunction: async (editor) => { deleteForward(editor); deleteForward(editor); deleteForward(editor); }, contentAfterEdit: '

ab[]\u200bfghij

', contentAfter: '

ab[]fghij

', }); }); test("should not delete a fontawesome after one deleteForward with spaces", async () => { await testEditor({ contentBefore: '

ab[] cd

', contentBeforeEdit: '

ab[] \u200b cd

', stepFunction: async (editor) => { deleteForward(editor); }, contentAfterEdit: '

ab[]\u200b cd

', contentAfter: '

ab[] cd

', }); }); test("should not delete a fontawesome after multiple deleteForward with spaces", async () => { await testEditor({ contentBefore: '

a[]b cd

', contentBeforeEdit: '

a[]b \u200b cd

', stepFunction: async (editor) => { deleteForward(editor); deleteForward(editor); }, contentAfterEdit: '

a[]\u200b cd

', contentAfter: '

a[] cd

', }); }); test("should not delete a fontawesome after multiple deleteForward with spaces inside a ", async () => { await testEditor({ contentBefore: '
ab[]c def
', contentBeforeEdit: '
ab[]c \u200b def
', stepFunction: async (editor) => { deleteForward(editor); deleteForward(editor); }, contentAfterEdit: '
ab[]\u200b def
', contentAfter: '
ab[] def
', }); }); }); }); describe("Selection not collapsed", () => { describe("Basic", () => { test("should delete a fontawesome (forward selection, deleteForward, !collapsed)", async () => { await testEditor({ contentBefore: '

ab[]cd

', stepFunction: deleteForward, contentAfter: "

ab[]cd

", }); }); test("should delete a fontawesome (backward selection, deleteForward, !collapsed)", async () => { await testEditor({ contentBefore: '

ab][cd

', stepFunction: deleteForward, contentAfter: "

ab[]cd

", }); }); }); }); }); describe("deleteBackward", () => { describe("Selection collapsed", () => { describe("Basic", () => { test("should delete a fontawesome (deleteBackward, collapsed)", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab\u200b[]cd

', stepFunction: deleteBackward, contentAfter: "

ab[]cd

", }); await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab\u200b[]cd

', stepFunction: deleteBackward, contentAfter: "

ab[]cd

", }); }); test("should delete a fontawesome before a span", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab\u200b[]cd

', stepFunction: deleteBackward, contentAfter: '

ab[]cd

', }); }); test("should not delete a fontawesome before a span", async () => { await testEditor({ contentBefore: '

abc[]d

', contentBeforeEdit: '

ab\u200bc[]d

', stepFunction: deleteBackward, contentAfterEdit: '

ab\u200b[]d

', contentAfter: '

ab[]d

', }); }); test("should not delete a fontawesome", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab[]\u200bcd

', stepFunction: deleteBackward, contentAfterEdit: '

a[]\u200bcd

', contentAfter: '

a[]cd

', }); }); test("should not delete a fontawesome after multiple deleteBackward", async () => { await testEditor({ contentBefore: '

abcdefgh[]ij

', contentBeforeEdit: '

abcde\u200bfgh[]ij

', stepFunction: async (editor) => { deleteBackward(editor); deleteBackward(editor); deleteBackward(editor); }, contentAfterEdit: '

abcde\u200b[]ij

', contentAfter: '

abcde[]ij

', }); }); test("should not delete a fontawesome after multiple deleteBackward with spaces", async () => { await testEditor({ contentBefore: '

abcde fg[]hij

', contentBeforeEdit: '

abcde \u200b fg[]hij

', stepFunction: async (editor) => { deleteBackward(editor); deleteBackward(editor); deleteBackward(editor); }, contentAfterEdit: '

abcde \u200b[]hij

', contentAfter: '

abcde []hij

', }); }); }); }); describe("Selection not collapsed", () => { describe("Basic", () => { test("should delete a fontawesome (forward selection, deleteBackward, !collapsed)", async () => { // Forward selection await testEditor({ contentBefore: '

ab[]cd

', stepFunction: deleteBackward, contentAfter: "

ab[]cd

", }); }); test("should delete a fontawesome (backward selection, deleteBackward, !collapsed)", async () => { // Backward selection await testEditor({ contentBefore: '

ab][cd

', stepFunction: deleteBackward, contentAfter: "

ab[]cd

", }); }); }); }); }); describe("FontAwesome insertion", () => { test("should insert a fontAwesome at the start of an element", async () => { await testEditor({ contentBefore: "

[]abc

", stepFunction: insertFontAwesome("fa fa-star"), contentAfterEdit: '

\u200b[]abc

', contentAfter: '

[]abc

', }); }); test("should insert a fontAwesome within an element", async () => { await testEditor({ contentBefore: "

ab[]cd

", stepFunction: insertFontAwesome("fa fa-star"), contentAfterEdit: '

ab\u200b[]cd

', contentAfter: '

ab[]cd

', }); }); test("should insert a fontAwesome at the end of an element", async () => { await testEditor({ contentBefore: "

abc[]

", stepFunction: insertFontAwesome("fa fa-star"), contentAfterEdit: '

abc\u200b[]

', contentAfter: '

abc[]

', }); }); test("should insert a fontAwesome after", async () => { await testEditor({ contentBefore: '

abc[]d

', stepFunction: insertFontAwesome("fa fa-star"), contentAfterEdit: '

ab\u200bc\u200b[]d

', contentAfter: '

abc[]d

', }); }); test("should insert a fontAwesome before", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab[]\u200bcd

', stepFunction: insertFontAwesome("fa fa-star"), contentAfterEdit: '

ab\u200b[]\u200bcd

', contentAfter: '

ab[]cd

', }); }); test.skip("should insert a fontAwesome and replace the icon", async () => { await testEditor({ contentBefore: '

ab[]cd

', stepFunction: insertFontAwesome("fa fa-star"), contentAfter: '

abs[]cd

', }); }); test("should insert fontAwesome consecutively", async () => { await testEditor({ contentBefore: "

[]

", stepFunction: async (editor) => { execCommand(editor, "insertFontAwesome", { faClass: "fa fa-star" }); execCommand(editor, "insertFontAwesome", { faClass: "fa fa-glass" }); }, contentAfterEdit: '

\u200b\u200b[]

', contentAfter: '

[]

', }); }); }); describe("Text insertion", () => { test("should insert a character before", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab[]\u200bcd

', stepFunction: async (editor) => { await insertText(editor, "s"); }, contentAfterEdit: '

abs[]\u200bcd

', contentAfter: '

abs[]cd

', }); }); test("should insert a character after", async () => { await testEditor({ contentBefore: '

ab[]cd

', contentBeforeEdit: '

ab\u200b[]cd

', stepFunction: async (editor) => { await insertText(editor, "s"); }, contentAfterEdit: '

ab\u200bs[]cd

', contentAfter: '

abs[]cd

', }); }); test.skip("should insert a character and replace the icon", async () => { await testEditor({ contentBefore: '

ab[]cd

', stepFunction: async (editor) => { await insertText(editor, "s"); }, contentAfter: "

abs[]cd

", }); }); test("undo shouldn't remove changes applied by the editor setup", async () => { const { el, editor } = await setupEditor(`

`); expect(getContent(el)).toBe( `

\u200b

` ); undo(editor); expect(getContent(el)).toBe( `

\u200b

` ); }); });