RTE plain text mentions as pills (#10852)
* insert mentions as links styled as pills * post merge fix and update test * update comments, move typeguard out * create a text node instead of setting innerText * update test * update test * fix broken cypress test, remove .only * make it able to deal with inserting in middle of blank lines * update comment * fix strict null error * use typeguard * avoid implicit truth check * add hook tests * add comment * Update test/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners-test.tsx Co-authored-by: Andy Balaam <andy.balaam@matrix.org> --------- Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
parent
acdbae3e8c
commit
0d981326ac
6 changed files with 146 additions and 40 deletions
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { act } from "@testing-library/react";
|
||||
|
||||
import { usePlainTextListeners } from "../../../../../../src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners";
|
||||
|
||||
describe("setContent", () => {
|
||||
it("calling with a string calls the onChange argument", () => {
|
||||
const mockOnChange = jest.fn();
|
||||
const { result } = renderHook(() => usePlainTextListeners("initialContent", mockOnChange));
|
||||
|
||||
const newContent = "new content";
|
||||
act(() => {
|
||||
result.current.setContent(newContent);
|
||||
});
|
||||
|
||||
expect(mockOnChange).toHaveBeenCalledWith(newContent);
|
||||
});
|
||||
|
||||
it("calling with no argument and no editor ref does not call onChange", () => {
|
||||
const mockOnChange = jest.fn();
|
||||
const { result } = renderHook(() => usePlainTextListeners("initialContent", mockOnChange));
|
||||
|
||||
act(() => {
|
||||
result.current.setContent();
|
||||
});
|
||||
|
||||
expect(mockOnChange).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calling with no argument and a valid editor ref calls onChange with the editorRef innerHTML", () => {
|
||||
const mockOnChange = jest.fn();
|
||||
|
||||
// create a div to represent the editor and append some content
|
||||
const mockEditor = document.createElement("div");
|
||||
const mockEditorText = "some text content";
|
||||
const textNode = document.createTextNode(mockEditorText);
|
||||
mockEditor.appendChild(textNode);
|
||||
|
||||
const { result } = renderHook(() => usePlainTextListeners("initialContent", mockOnChange));
|
||||
|
||||
// @ts-ignore in order to allow us to reassign the ref without complaint
|
||||
result.current.ref.current = mockEditor;
|
||||
|
||||
act(() => {
|
||||
result.current.setContent();
|
||||
});
|
||||
|
||||
expect(mockOnChange).toHaveBeenCalledWith(mockEditor.innerHTML);
|
||||
});
|
||||
});
|
|
@ -78,34 +78,42 @@ describe("processMention", () => {
|
|||
expect(mockSetText).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can insert a mention into an empty text node", () => {
|
||||
// make an empty text node, set the cursor inside it and then append to the document
|
||||
const textNode = document.createTextNode("");
|
||||
document.body.appendChild(textNode);
|
||||
document.getSelection()?.setBaseAndExtent(textNode, 0, textNode, 0);
|
||||
it("can insert a mention into a text node", () => {
|
||||
// make a text node and an editor div, set the cursor inside the text node and then
|
||||
// append node to editor, then editor to document
|
||||
const textNode = document.createTextNode("@a");
|
||||
const mockEditor = document.createElement("div");
|
||||
mockEditor.appendChild(textNode);
|
||||
document.body.appendChild(mockEditor);
|
||||
document.getSelection()?.setBaseAndExtent(textNode, 1, textNode, 1);
|
||||
|
||||
// call the util function
|
||||
const href = "href";
|
||||
const displayName = "displayName";
|
||||
const mockSetSuggestion = jest.fn();
|
||||
const mockSetSuggestionData = jest.fn();
|
||||
const mockSetText = jest.fn();
|
||||
processMention(
|
||||
href,
|
||||
displayName,
|
||||
{},
|
||||
{ node: textNode, startOffset: 0, endOffset: 0 } as unknown as Suggestion,
|
||||
mockSetSuggestion,
|
||||
{ "data-test-attribute": "test" },
|
||||
{ node: textNode, startOffset: 0, endOffset: 2 } as unknown as Suggestion,
|
||||
mockSetSuggestionData,
|
||||
mockSetText,
|
||||
);
|
||||
|
||||
// placeholder testing for the changed content - these tests will all be changed
|
||||
// when the mention is inserted as an <a> tagfs
|
||||
const { textContent } = textNode;
|
||||
expect(textContent!.includes(href)).toBe(true);
|
||||
expect(textContent!.includes(displayName)).toBe(true);
|
||||
// check that the editor has a single child
|
||||
expect(mockEditor.children).toHaveLength(1);
|
||||
const linkElement = mockEditor.firstElementChild as HTMLElement;
|
||||
|
||||
expect(mockSetText).toHaveBeenCalledWith(expect.stringContaining(displayName));
|
||||
expect(mockSetSuggestion).toHaveBeenCalledWith(null);
|
||||
// and that the child is an <a> tag with the expected attributes and content
|
||||
expect(linkElement).toBeInstanceOf(HTMLAnchorElement);
|
||||
expect(linkElement).toHaveAttribute(href, href);
|
||||
expect(linkElement).toHaveAttribute("contenteditable", "false");
|
||||
expect(linkElement).toHaveAttribute("data-test-attribute", "test");
|
||||
expect(linkElement.textContent).toBe(displayName);
|
||||
|
||||
expect(mockSetText).toHaveBeenCalledWith();
|
||||
expect(mockSetSuggestionData).toHaveBeenCalledWith(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue