Merge pull request #12448 from overleaf/jpa-compile-and-download-pdf

[web] add button to project dashboard for compiling and downloading PDF

GitOrigin-RevId: c243b4a30e4720116d82d9c25bdc8be8825d6d74
This commit is contained in:
Jakob Ackermann
2023-11-29 09:03:59 +00:00
committed by Copybot
parent 7a87bf4288
commit 4636f40f03
12 changed files with 396 additions and 6 deletions
@@ -0,0 +1,89 @@
import { expect } from 'chai'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import sinon from 'sinon'
import { projectsData } from '../../../../fixtures/projects-data'
import * as useLocationModule from '../../../../../../../../frontend/js/shared/hooks/use-location'
import { CompileAndDownloadProjectPDFButtonTooltip } from '../../../../../../../../frontend/js/features/project-list/components/table/cells/action-buttons/compile-and-download-project-pdf-button'
import fetchMock from 'fetch-mock'
import * as eventTracking from '../../../../../../../../frontend/js/infrastructure/event-tracking'
describe('<CompileAndDownloadProjectPDFButton />', function () {
let assignStub: sinon.SinonStub
let locationStub: sinon.SinonStub
let sendMBSpy: sinon.SinonSpy
beforeEach(function () {
sendMBSpy = sinon.spy(eventTracking, 'sendMB')
assignStub = sinon.stub()
locationStub = sinon.stub(useLocationModule, 'useLocation').returns({
assign: assignStub,
reload: sinon.stub(),
})
render(
<CompileAndDownloadProjectPDFButtonTooltip project={projectsData[0]} />
)
})
afterEach(function () {
locationStub.restore()
fetchMock.reset()
sendMBSpy.restore()
})
it('renders tooltip for button', function () {
const btn = screen.getByLabelText('Download PDF')
fireEvent.mouseOver(btn)
screen.getByRole('tooltip', { name: 'Download PDF' })
})
it('downloads the project PDF when clicked', async function () {
fetchMock.post(
`/project/${projectsData[0].id}/compile`,
{
status: 'success',
compileGroup: 'standard',
clsiServerId: 'server-1',
outputFiles: [{ path: 'output.pdf', build: '123-321' }],
},
{ delay: 10 }
)
const btn = screen.getByLabelText('Download PDF') as HTMLButtonElement
fireEvent.click(btn)
await waitFor(() => {
screen.getByLabelText('Compiling…')
})
await waitFor(() => {
expect(assignStub).to.have.been.called
})
expect(assignStub).to.have.been.calledOnce
expect(assignStub).to.have.been.calledWith(
`/download/project/${projectsData[0].id}/build/123-321/output/output.pdf?compileGroup=standard&popupDownload=true&clsiserverid=server-1`
)
expect(sendMBSpy).to.have.been.calledOnce
expect(sendMBSpy).to.have.been.calledWith('project-list-page-interaction', {
action: 'downloadPDF',
page: '/',
projectId: projectsData[0].id,
isSmallDevice: true,
})
})
it('displays a modal when the compile failed', async function () {
fetchMock.post(`/project/${projectsData[0].id}/compile`, {
status: 'failure',
})
const btn = screen.getByLabelText('Download PDF') as HTMLButtonElement
fireEvent.click(btn)
await waitFor(() => {
screen.getByText(`${projectsData[0].name}: PDF unavailable for download`)
})
expect(assignStub).to.have.not.been.called
})
})
@@ -22,13 +22,13 @@ describe('<DownloadProjectButton />', function () {
})
it('renders tooltip for button', function () {
const btn = screen.getByLabelText('Download')
const btn = screen.getByLabelText('Download .zip file')
fireEvent.mouseOver(btn)
screen.getByRole('tooltip', { name: 'Download' })
screen.getByRole('tooltip', { name: 'Download .zip file' })
})
it('downloads the project when clicked', async function () {
const btn = screen.getByLabelText('Download') as HTMLButtonElement
const btn = screen.getByLabelText('Download .zip file') as HTMLButtonElement
fireEvent.click(btn)
await waitFor(() => {
@@ -11,6 +11,9 @@ describe('<ProjectListTable />', function () {
beforeEach(function () {
window.metaAttributesCache = new Map()
window.metaAttributesCache.set('ol-tags', [])
window.metaAttributesCache.set('ol-splitTestVariants', {
'download-pdf-dashboard': 'enabled',
})
window.user_id = userId
fetchMock.reset()
})
@@ -112,8 +115,10 @@ describe('<ProjectListTable />', function () {
// temporary count tests until we add filtering for archived/trashed
const copyButtons = screen.getAllByLabelText('Copy')
expect(copyButtons.length).to.equal(currentProjects.length)
const downloadButtons = screen.getAllByLabelText('Download')
const downloadButtons = screen.getAllByLabelText('Download .zip file')
expect(downloadButtons.length).to.equal(currentProjects.length)
const downloadPDFButtons = screen.getAllByLabelText('Download PDF')
expect(downloadPDFButtons.length).to.equal(currentProjects.length)
const archiveButtons = screen.getAllByLabelText('Archive')
expect(archiveButtons.length).to.equal(currentProjects.length)
const trashButtons = screen.getAllByLabelText('Trash')