Merge pull request #3446 from overleaf/ae-clone-project-modal
Migrate left menu Clone Project modal to React GitOrigin-RevId: ad113e2b40de4007def513d40551d55bb0c913db
This commit is contained in:
+237
@@ -0,0 +1,237 @@
|
||||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { expect } from 'chai'
|
||||
import CloneProjectModalContent from '../../../../../frontend/js/features/clone-project-modal/components/clone-project-modal-content'
|
||||
import CloneProjectModal from '../../../../../frontend/js/features/clone-project-modal/components/clone-project-modal'
|
||||
import sinon from 'sinon'
|
||||
import fetchMock from 'fetch-mock'
|
||||
|
||||
const cancel = sinon.stub()
|
||||
const cloneProject = sinon.stub()
|
||||
const handleHide = sinon.stub()
|
||||
|
||||
describe('<CloneProjectModal />', function() {
|
||||
afterEach(function() {
|
||||
fetchMock.reset()
|
||||
})
|
||||
|
||||
it('posts the generated project name', async function() {
|
||||
const matcher = 'express:/project/:projectId/clone'
|
||||
|
||||
fetchMock.postOnce(
|
||||
matcher,
|
||||
() => {
|
||||
return {
|
||||
project_id: 'test'
|
||||
}
|
||||
},
|
||||
{
|
||||
body: {
|
||||
projectName: 'A Project (Copy)'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
render(
|
||||
<CloneProjectModal
|
||||
handleHide={handleHide}
|
||||
projectId="project-1"
|
||||
projectName="A Project"
|
||||
show
|
||||
/>
|
||||
)
|
||||
|
||||
const button = await screen.findByRole('button', {
|
||||
name: 'Copy',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
const cancelButton = await screen.findByRole('button', {
|
||||
name: 'Cancel',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
expect(cancelButton.disabled).to.be.false
|
||||
|
||||
fireEvent.click(button)
|
||||
|
||||
expect(fetchMock.done(matcher)).to.be.true
|
||||
// TODO: window.location?
|
||||
|
||||
const errorMessage = screen.queryByText('Sorry, something went wrong')
|
||||
expect(errorMessage).to.be.null
|
||||
|
||||
expect(button.disabled).to.be.true
|
||||
expect(cancelButton.disabled).to.be.true
|
||||
})
|
||||
|
||||
it('handles a generic error response', async function() {
|
||||
const matcher = 'express:/project/:projectId/clone'
|
||||
|
||||
fetchMock.postOnce(matcher, {
|
||||
status: 500,
|
||||
body: 'There was an error!'
|
||||
})
|
||||
|
||||
render(
|
||||
<CloneProjectModal
|
||||
handleHide={handleHide}
|
||||
projectId="project-2"
|
||||
projectName="A Project"
|
||||
show
|
||||
/>
|
||||
)
|
||||
|
||||
const button = await screen.findByRole('button', {
|
||||
name: 'Copy',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
const cancelButton = await screen.findByRole('button', {
|
||||
name: 'Cancel',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
expect(cancelButton.disabled).to.be.false
|
||||
|
||||
fireEvent.click(button)
|
||||
|
||||
expect(fetchMock.done(matcher)).to.be.true
|
||||
|
||||
await screen.findByText('Sorry, something went wrong')
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
expect(cancelButton.disabled).to.be.false
|
||||
})
|
||||
|
||||
it('handles a specific error response', async function() {
|
||||
const matcher = 'express:/project/:projectId/clone'
|
||||
|
||||
fetchMock.postOnce(matcher, {
|
||||
status: 400,
|
||||
body: 'There was an error!'
|
||||
})
|
||||
|
||||
render(
|
||||
<CloneProjectModal
|
||||
handleHide={handleHide}
|
||||
projectId="project-3"
|
||||
projectName="A Project"
|
||||
show
|
||||
/>
|
||||
)
|
||||
|
||||
const button = await screen.findByRole('button', {
|
||||
name: 'Copy',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
const cancelButton = await screen.findByRole('button', {
|
||||
name: 'Cancel',
|
||||
hidden: true // TODO: this shouldn't be needed
|
||||
})
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
expect(cancelButton.disabled).to.be.false
|
||||
|
||||
fireEvent.click(button)
|
||||
|
||||
expect(fetchMock.done(matcher)).to.be.true
|
||||
|
||||
await screen.findByText('There was an error!')
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
expect(cancelButton.disabled).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
describe('<CloneProjectModalContent />', function() {
|
||||
it('renders the translated modal title', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight={false}
|
||||
/>
|
||||
)
|
||||
|
||||
await screen.findByText('Copy Project')
|
||||
})
|
||||
|
||||
it('shows the copy button', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight={false}
|
||||
/>
|
||||
)
|
||||
|
||||
const button = await screen.findByRole('button', { name: 'Copy' })
|
||||
|
||||
expect(button.disabled).to.be.false
|
||||
})
|
||||
|
||||
it('disables the copy button when loading', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight
|
||||
/>
|
||||
)
|
||||
|
||||
const button = await screen.findByText(
|
||||
(content, element) =>
|
||||
element.nodeName === 'BUTTON' &&
|
||||
element.textContent.trim().match(/^Copying…$/)
|
||||
)
|
||||
|
||||
expect(button.disabled).to.be.true
|
||||
})
|
||||
|
||||
it('renders a generic error message', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight={false}
|
||||
error
|
||||
/>
|
||||
)
|
||||
|
||||
await screen.findByText('Sorry, something went wrong')
|
||||
})
|
||||
|
||||
it('renders a specific error message', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight={false}
|
||||
error={{
|
||||
message: 'Uh oh!'
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
await screen.findByText('Uh oh!')
|
||||
})
|
||||
|
||||
it('displays a project name', async function() {
|
||||
render(
|
||||
<CloneProjectModalContent
|
||||
cloneProject={cloneProject}
|
||||
cancel={cancel}
|
||||
inFlight={false}
|
||||
projectName="A copy of a project"
|
||||
/>
|
||||
)
|
||||
|
||||
const input = await screen.getByLabelText('New Name')
|
||||
|
||||
expect(input.value).to.equal('A copy of a project (Copy)')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user