diff --git a/cypress/e2e/project/project-view-kanban.spec.ts b/cypress/e2e/project/project-view-kanban.spec.ts index 719319373..2c74ba9a9 100644 --- a/cypress/e2e/project/project-view-kanban.spec.ts +++ b/cypress/e2e/project/project-view-kanban.spec.ts @@ -5,6 +5,19 @@ import {ProjectFactory} from '../../factories/project' import {TaskFactory} from '../../factories/task' import {prepareProjects} from './prepareProjects' +function createSingleTaskInBucket(count = 1, attrs = {}) { + const projects = ProjectFactory.create(1) + const buckets = BucketFactory.create(2, { + project_id: projects[0].id, + }) + const tasks = TaskFactory.create(count, { + project_id: projects[0].id, + bucket_id: buckets[0].id, + ...attrs, + }) + return tasks[0] +} + describe('Project View Kanban', () => { createFakeUserAndLogin() prepareProjects() @@ -207,15 +220,7 @@ describe('Project View Kanban', () => { }) it('Should remove a task from the board when deleting it', () => { - const projects = ProjectFactory.create(1) - const buckets = BucketFactory.create(2, { - project_id: projects[0].id, - }) - const tasks = TaskFactory.create(5, { - project_id: 1, - bucket_id: buckets[0].id, - }) - const task = tasks[0] + const task = createSingleTaskInBucket(5) cy.visit('/projects/1/kanban') cy.get('.kanban .bucket .tasks .task') @@ -238,4 +243,43 @@ describe('Project View Kanban', () => { cy.get('.kanban .bucket .tasks') .should('not.contain', task.title) }) + + it('Should show a task description icon if the task has a description', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/buckets**').as('loadTasks') + const task = createSingleTaskInBucket(1, { + description: 'Lorem Ipsum', + }) + + cy.visit(`/projects/${task.project_id}/kanban`) + cy.wait('@loadTasks') + + cy.get('.bucket .tasks .task .footer .icon svg') + .should('exist') + }) + + it('Should not show a task description icon if the task has an empty description', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/buckets**').as('loadTasks') + const task = createSingleTaskInBucket(1, { + description: '', + }) + + cy.visit(`/projects/${task.project_id}/kanban`) + cy.wait('@loadTasks') + + cy.get('.bucket .tasks .task .footer .icon svg') + .should('not.exist') + }) + + it('Should not show a task description icon if the task has a description containing only an empty p tag', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/buckets**').as('loadTasks') + const task = createSingleTaskInBucket(1, { + description: '
', + }) + + cy.visit(`/projects/${task.project_id}/kanban`) + cy.wait('@loadTasks') + + cy.get('.bucket .tasks .task .footer .icon svg') + .should('not.exist') + }) }) \ No newline at end of file diff --git a/cypress/e2e/task/task.spec.ts b/cypress/e2e/task/task.spec.ts index c2019f08b..57cc87d7b 100644 --- a/cypress/e2e/task/task.spec.ts +++ b/cypress/e2e/task/task.spec.ts @@ -36,7 +36,7 @@ function uploadAttachmentAndVerify(taskId: number) { cy.get('.task-view .action-buttons .button') .contains('Add Attachments') .click() - cy.get('input[type=file]', {timeout: 1000}) + cy.get('input[type=file]#files', {timeout: 1000}) .selectFile('cypress/fixtures/image.jpg', {force: true}) // The input is not visible, but on purpose cy.wait('@uploadAttachment') @@ -112,10 +112,50 @@ describe('Task', () => { .should('contain', 'Favorites') }) + it('Should show a task description icon if the task has a description', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/tasks**').as('loadTasks') + TaskFactory.create(1, { + description: 'Lorem Ipsum', + }) + + cy.visit('/projects/1/list') + cy.wait('@loadTasks') + + cy.get('.tasks .task .project-task-icon') + .should('exist') + }) + + it('Should not show a task description icon if the task has an empty description', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/tasks**').as('loadTasks') + TaskFactory.create(1, { + description: '', + }) + + cy.visit('/projects/1/list') + cy.wait('@loadTasks') + + cy.get('.tasks .task .project-task-icon') + .should('not.exist') + }) + + it('Should not show a task description icon if the task has a description containing only an empty p tag', () => { + cy.intercept(Cypress.env('API_URL') + '/projects/1/tasks**').as('loadTasks') + TaskFactory.create(1, { + description: '', + }) + + cy.visit('/projects/1/list') + cy.wait('@loadTasks') + + cy.get('.tasks .task .project-task-icon') + .should('not.exist') + }) + describe('Task Detail View', () => { beforeEach(() => { TaskCommentFactory.truncate() LabelTaskFactory.truncate() + TaskAttachmentFactory.truncate() }) it('Shows all task details', () => { @@ -213,6 +253,45 @@ describe('Task', () => { .should('exist') }) + it('Shows an empty editor when the description of a task is empty', () => { + const tasks = TaskFactory.create(1, { + id: 1, + description: '', + }) + cy.visit(`/tasks/${tasks[0].id}`) + + cy.get('.task-view .details.content.description .tiptap.ProseMirror p') + .should('have.attr', 'data-placeholder') + cy.get('.task-view .details.content.description .tiptap button.done-edit') + .should('not.exist') + }) + + it('Shows a preview editor when the description of a task is not empty', () => { + const tasks = TaskFactory.create(1, { + id: 1, + description: 'Lorem Ipsum dolor sit amet', + }) + cy.visit(`/tasks/${tasks[0].id}`) + + cy.get('.task-view .details.content.description .tiptap.ProseMirror p') + .should('not.have.attr', 'data-placeholder') + cy.get('.task-view .details.content.description .tiptap button.done-edit') + .should('exist') + }) + + it('Shows a preview editor when the description of a task contains html', () => { + const tasks = TaskFactory.create(1, { + id: 1, + description: 'Lorem Ipsum dolor sit amet
', + }) + cy.visit(`/tasks/${tasks[0].id}`) + + cy.get('.task-view .details.content.description .tiptap.ProseMirror p') + .should('not.have.attr', 'data-placeholder') + cy.get('.task-view .details.content.description .tiptap button.done-edit') + .should('exist') + }) + it('Can add a new comment', () => { const tasks = TaskFactory.create(1, { id: 1, @@ -692,7 +771,7 @@ describe('Task', () => { .should('exist') }) - it('Can check items off a checklist', () => { + it.only('Can check items off a checklist', () => { const tasks = TaskFactory.create(1, { id: 1, description: ` @@ -761,7 +840,7 @@ describe('Task', () => { .should('exist') }) - it.only('Should render an image from attachment', async () => { + it('Should render an image from attachment', async () => { TaskAttachmentFactory.truncate() diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 35021a398..7a967d1f7 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -118,7 +118,6 @@