Просмотр исходного кода

Merge pull request #32801 from overleaf/ii-fix-mobile-trash-delete

[web] Fix Delete/Leave dropdown items not working on mobile trashed projects list

GitOrigin-RevId: ce7c79f0c77bb1f0df023159ee6c463c577e26e1
ilkin-overleaf 5 месяцев назад
Родитель
Сommit
5d3d58e8f4

+ 14 - 4
services/web/frontend/js/features/project-list/components/dropdown/actions-dropdown.tsx

@@ -160,18 +160,28 @@ function ActionsDropdown({ project }: ActionDropdownProps) {
           )}
         </UntrashProjectButton>
         <LeaveProjectButton project={project}>
-          {text => (
+          {(text, handleOpenModal) => (
             <li role="none">
-              <DropdownItem as="button" tabIndex={-1} leadingIcon="logout">
+              <DropdownItem
+                as="button"
+                tabIndex={-1}
+                onClick={handleOpenModal}
+                leadingIcon="logout"
+              >
                 {text}
               </DropdownItem>
             </li>
           )}
         </LeaveProjectButton>
         <DeleteProjectButton project={project}>
-          {text => (
+          {(text, handleOpenModal) => (
             <li role="none">
-              <DropdownItem as="button" tabIndex={-1} leadingIcon="block">
+              <DropdownItem
+                as="button"
+                tabIndex={-1}
+                onClick={handleOpenModal}
+                leadingIcon="block"
+              >
                 {text}
               </DropdownItem>
             </li>

+ 85 - 0
services/web/test/frontend/features/project-list/components/table/cells/actions-dropdown.test.tsx

@@ -0,0 +1,85 @@
+import { expect } from 'chai'
+import { fireEvent, screen, waitFor } from '@testing-library/react'
+import fetchMock from 'fetch-mock'
+import ActionsDropdown from '../../../../../../../frontend/js/features/project-list/components/dropdown/actions-dropdown'
+import {
+  trashedProject,
+  trashedAndNotOwnedProject,
+} from '../../../fixtures/projects-data'
+import {
+  renderWithProjectListContext,
+  resetProjectListContextFetch,
+} from '../../../helpers/render-with-context'
+
+describe('<ActionsDropdown />', function () {
+  afterEach(function () {
+    resetProjectListContextFetch()
+    window.metaAttributesCache.clear()
+  })
+
+  describe('Delete button for trashed project (mobile view)', function () {
+    it('opens the delete modal when clicking Delete in the dropdown', async function () {
+      window.metaAttributesCache.set('ol-user_id', trashedProject.owner?.id)
+      const project = Object.assign({}, trashedProject)
+      const deleteProjectMock = fetchMock.delete(
+        `express:/project/:projectId`,
+        { status: 200 },
+        { delay: 0 }
+      )
+
+      renderWithProjectListContext(<ActionsDropdown project={project} />)
+
+      const toggle = screen.getByRole('button', { name: 'Actions' })
+      fireEvent.click(toggle)
+
+      const deleteBtn = await screen.findByRole('menuitem', { name: /delete/i })
+      fireEvent.click(deleteBtn)
+
+      await screen.findByText('Delete Projects')
+
+      const confirmBtn = screen.getByRole('button', {
+        name: 'Confirm',
+      }) as HTMLButtonElement
+      fireEvent.click(confirmBtn)
+
+      await waitFor(
+        () =>
+          expect(deleteProjectMock.callHistory.called(`/project/${project.id}`))
+            .to.be.true
+      )
+    })
+  })
+
+  describe('Leave button for trashed non-owned project (mobile view)', function () {
+    it('opens the leave modal when clicking Leave in the dropdown', async function () {
+      const project = Object.assign({}, trashedAndNotOwnedProject)
+      const leaveProjectMock = fetchMock.post(
+        `express:/project/${project.id}/leave`,
+        { status: 200 },
+        { delay: 0 }
+      )
+
+      renderWithProjectListContext(<ActionsDropdown project={project} />)
+
+      const toggle = screen.getByRole('button', { name: 'Actions' })
+      fireEvent.click(toggle)
+
+      const leaveBtn = await screen.findByRole('menuitem', { name: /leave/i })
+      fireEvent.click(leaveBtn)
+
+      await screen.findByText('Leave Projects')
+
+      const confirmBtn = screen.getByRole('button', {
+        name: 'Confirm',
+      }) as HTMLButtonElement
+      fireEvent.click(confirmBtn)
+
+      await waitFor(
+        () =>
+          expect(
+            leaveProjectMock.callHistory.called(`/project/${project.id}/leave`)
+          ).to.be.true
+      )
+    })
+  })
+})