diff --git a/cypress/e2e/mentions.spec.js b/cypress/e2e/mentions.spec.js new file mode 100644 index 00000000000..6285bfe70dd --- /dev/null +++ b/cypress/e2e/mentions.spec.js @@ -0,0 +1,74 @@ +import { initUserAndFiles, randHash } from '../utils/index.js' +import 'cypress-file-upload' + +const randUser = randHash() +const randUser1 = randHash() +const currentUser = randUser + +const refresh = () => { + cy.get('.files-controls .crumb:not(.hidden) a') + .last() + .click({ force: true }) +} + +const createFileWithMention = (target, userToMention) => { + const mimeType = 'text/markdown' + const content = `Hello @[${userToMention}](mention://user/${userToMention})` + cy.createFile(target, content, mimeType) + .then(refresh) +} + +describe('Test mentioning users', () => { + before(() => { + initUserAndFiles(randUser, 'test.md') + cy.nextcloudCreateUser(randUser1, 'password') + }) + + beforeEach(() => { + cy.login(currentUser, 'password') + }) + + it('Type @ and see the user list', () => { + const requestAlias = 'fetchUsersList' + cy.intercept({ method: 'POST', url: '**/users' }).as(requestAlias) + + cy.openFile('test.md') + cy.get('.text-editor__content div[contenteditable="true"]') + .clear() + .type(`@${randUser1.substring(0, 3)}`) + + return cy.wait(`@${requestAlias}`) + .then(() => { + cy.get('.tippy-box .items').children().should(($children) => { + const users = $children.map((i, el) => el.innerText).get() + expect(users.length).to.be.greaterThan(0) + expect(randUser1).to.be.oneOf(users) + }) + }) + }) + + it('Select a user will insert the mention', () => { + const autocompleteReauestAlias = 'fetchUsersList' + cy.intercept({ method: 'POST', url: '**/users' }).as(autocompleteReauestAlias) + + cy.openFile('test.md') + cy.get('.text-editor__content div[contenteditable="true"]') + .clear() + .type(`@${randUser1.substring(0, 3)}`) + + return cy.wait(`@${autocompleteReauestAlias}`) + .then(() => { + cy.get('.tippy-box .items').contains(randUser1).click() + cy.get('span.mention').contains(randUser1).should('be.visible') + }) + }) + + it(' Open a document with an existing mention and properly see the user bubble rendered', () => { + const mentionFilename = 'mention.md' + createFileWithMention(mentionFilename, randUser1) + cy.openFile(mentionFilename) + cy.get('.text-editor__content div[contenteditable="true"] span.mention') + .contains(randUser1) + .should('be.visible') + }) +}) diff --git a/src/extensions/Mention.js b/src/extensions/Mention.js index 39443b1f9fb..4bd8662c97a 100644 --- a/src/extensions/Mention.js +++ b/src/extensions/Mention.js @@ -11,7 +11,7 @@ export default TipTapMention.extend({ getAttrs: element => { return { id: element.getAttribute('data-id'), - label: element.innerText ?? element.getAttribute('data-id'), + label: element.innerText || element.textContent || element.getAttribute('data-label'), } }, priority: 100, diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js index f71dde3b010..7f84cd4a653 100644 --- a/src/tests/markdown.spec.js +++ b/src/tests/markdown.spec.js @@ -152,6 +152,10 @@ describe('Markdown though editor', () => { expect(markdownThroughEditor(entry)).toBe(entry) }) }) + + test('mentions', () => { + expect(markdownThroughEditor('@[username](mention://user/id)')).toBe(' @[username](mention://user/id) ') + }) }) describe('Markdown serializer from html', () => { @@ -203,6 +207,10 @@ describe('Markdown serializer from html', () => { // Test --- within front matter is allowed expect(markdownThroughEditorHtml('
---

Heading

')).toBe('----\n---\n----\n\n# Heading') }) + + test('mentions', () => { + expect(markdownThroughEditorHtml('username')).toBe(' @[username](mention://user/id) ') + }) }) describe('Trailing nodes', () => {