mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-05 16:06:01 -05:00
13f246a85e
Remove use of FileTreeManager in React code GitOrigin-RevId: f15bc9b4f84e0f65709b9850ed8cc5d3637efa7f
418 lines
14 KiB
TypeScript
418 lines
14 KiB
TypeScript
import CodemirrorEditor from '../../../../../frontend/js/features/source-editor/components/codemirror-editor'
|
|
import { EditorProviders } from '../../../helpers/editor-providers'
|
|
import { mockScope, rootFolderId } from '../helpers/mock-scope'
|
|
import { FC } from 'react'
|
|
import { FileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
|
|
|
|
const Container: FC = ({ children }) => (
|
|
<div style={{ width: 1500, height: 785 }}>{children}</div>
|
|
)
|
|
|
|
const clickToolbarButton = (text: string) => {
|
|
cy.findByLabelText(text).click()
|
|
cy.findByLabelText(text).trigger('mouseout')
|
|
}
|
|
|
|
const chooseFileFromComputer = () => {
|
|
cy.get('@file-input').selectFile(
|
|
{
|
|
fileName: 'frog.jpg',
|
|
contents: Cypress.Buffer.from('image-data'),
|
|
mimeType: 'image/jpg',
|
|
},
|
|
{
|
|
force: true,
|
|
}
|
|
)
|
|
}
|
|
|
|
const matchUrl = (urlToMatch: RegExp | string) =>
|
|
Cypress.sinon.match(req => {
|
|
if (!req || typeof req.url !== 'string') {
|
|
return false
|
|
}
|
|
if (typeof urlToMatch === 'string') {
|
|
return req.url.endsWith(urlToMatch)
|
|
}
|
|
return Boolean(req.url.match(urlToMatch))
|
|
})
|
|
|
|
describe('<FigureModal />', function () {
|
|
// TODO: rewrite these tests to be in source mode when toolbar is added there
|
|
// TODO: Write tests for width toggle, when we can match on source code
|
|
beforeEach(function () {
|
|
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
|
|
cy.interceptMathJax()
|
|
cy.interceptEvents()
|
|
cy.interceptSpelling()
|
|
|
|
const content = ''
|
|
|
|
const scope = mockScope(content)
|
|
scope.editor.showVisual = true
|
|
|
|
const FileTreePathProvider: FC = ({ children }) => (
|
|
<FileTreePathContext.Provider
|
|
value={{
|
|
dirname: cy.stub(),
|
|
findEntityByPath: cy.stub(),
|
|
pathInFolder: cy.stub(),
|
|
previewByPath: cy
|
|
.stub()
|
|
.as('previewByPath')
|
|
.returns({ url: 'frog.jpg', extension: 'jpg' }),
|
|
}}
|
|
>
|
|
{children}
|
|
</FileTreePathContext.Provider>
|
|
)
|
|
|
|
cy.mount(
|
|
<Container>
|
|
<EditorProviders scope={scope} providers={{ FileTreePathProvider }}>
|
|
<CodemirrorEditor />
|
|
</EditorProviders>
|
|
</Container>
|
|
)
|
|
})
|
|
|
|
describe('Upload from computer source', function () {
|
|
beforeEach(function () {
|
|
cy.interceptFileUpload()
|
|
clickToolbarButton('Insert Figure')
|
|
cy.findByRole('menu').within(() => {
|
|
cy.findByText('Upload from computer').click()
|
|
})
|
|
cy.findByLabelText('File Uploader')
|
|
.get('.uppy-Dashboard-input:first')
|
|
.as('file-input')
|
|
})
|
|
|
|
it('Shows file name and size when selecting file', function () {
|
|
chooseFileFromComputer()
|
|
cy.findByLabelText('File name').should('have.text', 'frog.jpg')
|
|
cy.findByLabelText('File size').should('have.text', '10 B')
|
|
})
|
|
|
|
it('Uploads file when clicking insert', function () {
|
|
chooseFileFromComputer()
|
|
cy.get('@uploadRequest').should('not.have.been.called')
|
|
cy.findByText('Insert figure').click()
|
|
cy.get('@uploadRequest').should(
|
|
'have.been.calledWith',
|
|
matchUrl(`/project/test-project/upload?folder_id=${rootFolderId}`)
|
|
)
|
|
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure} \\centering Enter Caption 🏷fig:enter-label\\end{figure}'
|
|
)
|
|
})
|
|
|
|
it('Enables insert button when choosing file', function () {
|
|
cy.findByText('Insert figure').should('be.disabled')
|
|
chooseFileFromComputer()
|
|
cy.findByText('Insert figure').should('be.enabled')
|
|
})
|
|
})
|
|
|
|
describe('Upload from project files source', function () {
|
|
beforeEach(function () {
|
|
clickToolbarButton('Insert Figure')
|
|
cy.findByRole('menu').within(() => {
|
|
cy.findByText('From project files').click()
|
|
})
|
|
})
|
|
|
|
it('Lists files from project', function () {
|
|
cy.findByText('Select image from project files').click()
|
|
cy.findByRole('listbox')
|
|
.children()
|
|
.should('have.length', 2)
|
|
.should('contain.text', 'frog.jpg')
|
|
.should('contain.text', 'unicorn.png')
|
|
.should('contain.text', 'figures/')
|
|
})
|
|
|
|
it('Enables insert button when choosing file', function () {
|
|
cy.findByText('Insert figure').should('be.disabled')
|
|
cy.findByText('Select image from project files').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('frog.jpg').click()
|
|
})
|
|
cy.findByText('Insert figure').should('be.enabled')
|
|
})
|
|
|
|
it('Inserts file when pressing insert button', function () {
|
|
cy.findByText('Select image from project files').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('frog.jpg').click()
|
|
})
|
|
cy.findByText('Insert figure').click()
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure} \\centering Enter Caption 🏷fig:enter-label\\end{figure}'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('From another project source', function () {
|
|
beforeEach(function () {
|
|
cy.interceptProjectListing()
|
|
cy.interceptCompile()
|
|
cy.interceptLinkedFile()
|
|
clickToolbarButton('Insert Figure')
|
|
cy.findByRole('menu').within(() => {
|
|
cy.findByText('From another project').click()
|
|
})
|
|
cy.findByText('Select a project').parent().as('project-dropdown')
|
|
cy.findByText('Select a file').parent().as('file-dropdown')
|
|
})
|
|
|
|
it('List projects and files in projects', function () {
|
|
cy.findByText('Insert figure').should('be.disabled')
|
|
cy.get('@file-dropdown').should('have.class', 'disabled')
|
|
cy.get('@project-dropdown').click()
|
|
cy.findByRole('listbox').as('project-select')
|
|
cy.get('@project-select').children().should('have.length', 2)
|
|
cy.get('@project-select').within(() => {
|
|
cy.findByText('My first project').click()
|
|
})
|
|
cy.get('@file-dropdown').should('not.have.class', 'disabled')
|
|
cy.get('@file-dropdown').click()
|
|
cy.findByRole('listbox').as('file-select')
|
|
cy.get('@file-select').children().should('have.length', 2)
|
|
cy.get('@file-select').should('contain.text', 'frog.jpg')
|
|
cy.get('@file-select').should('contain.text', 'figures/unicorn.png')
|
|
cy.get('@file-select').within(() => {
|
|
cy.findByText('frog.jpg').click()
|
|
})
|
|
cy.findByText('Insert figure').should('be.enabled')
|
|
})
|
|
|
|
it('Enables insert button when choosing file', function () {
|
|
cy.findByText('Insert figure').should('be.disabled')
|
|
cy.get('@project-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('My first project').click()
|
|
})
|
|
cy.get('@file-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('frog.jpg').click()
|
|
})
|
|
cy.findByText('Insert figure').should('be.enabled')
|
|
})
|
|
|
|
it('Creates linked file when pressing insert', function () {
|
|
cy.get('@project-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('My first project').click()
|
|
})
|
|
cy.get('@file-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('frog.jpg').click()
|
|
})
|
|
cy.findByText('Insert figure').click()
|
|
cy.get('@linked-file-request').should('have.been.calledWithMatch', {
|
|
body: {
|
|
provider: 'project_file',
|
|
data: {
|
|
source_entity_path: '/frog.jpg',
|
|
source_project_id: 'fake-project-1',
|
|
},
|
|
},
|
|
})
|
|
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure} \\centering Enter Caption 🏷fig:enter-label\\end{figure}'
|
|
)
|
|
})
|
|
|
|
it('Creates linked output file when pressing insert', function () {
|
|
cy.get('@project-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('My first project').click()
|
|
})
|
|
cy.findByText('select from output files').click()
|
|
cy.findByText('Select an output file').parent().as('output-file-dropdown')
|
|
cy.get('@output-file-dropdown').click()
|
|
cy.findByRole('listbox').within(() => {
|
|
cy.findByText('output.pdf').click()
|
|
})
|
|
cy.findByText('Insert figure').click()
|
|
cy.get('@linked-file-request').should('have.been.calledWithMatch', {
|
|
body: {
|
|
provider: 'project_output_file',
|
|
data: {
|
|
source_output_file_path: 'output.pdf',
|
|
source_project_id: 'fake-project-1',
|
|
},
|
|
},
|
|
})
|
|
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure} \\centering Enter Caption 🏷fig:enter-label\\end{figure}'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('From URL source', function () {
|
|
beforeEach(function () {
|
|
cy.interceptLinkedFile()
|
|
clickToolbarButton('Insert Figure')
|
|
cy.findByRole('menu').within(() => {
|
|
cy.findByText('From URL').click()
|
|
})
|
|
cy.findByLabelText('File name in this project').as(
|
|
'relocated-file-name-input'
|
|
)
|
|
cy.findByLabelText('Image URL').as('image-url-input')
|
|
cy.get('[data-cy="include-label-option"]').as('include-label-checkbox')
|
|
cy.get('[data-cy="include-caption-option"]').as(
|
|
'include-caption-checkbox'
|
|
)
|
|
})
|
|
|
|
it('Auto fills name based on url', function () {
|
|
cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
|
|
cy.get('@relocated-file-name-input').should('have.value', 'frog.jpg')
|
|
cy.get('@relocated-file-name-input').type('pig')
|
|
cy.get('@relocated-file-name-input').should('have.value', 'pig.jpg')
|
|
})
|
|
|
|
it('Enables insert button when name and url is available', function () {
|
|
cy.findByText('Insert figure').should('be.disabled')
|
|
cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
|
|
cy.findByText('Insert figure').should('be.enabled')
|
|
})
|
|
|
|
it('Adds linked file when pressing insert', function () {
|
|
cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
|
|
cy.findByText('Insert figure').click()
|
|
|
|
cy.get('@linked-file-request').should('have.been.calledWithMatch', {
|
|
body: {
|
|
provider: 'url',
|
|
data: {
|
|
url: 'https://my-fake-website.com/frog.jpg',
|
|
},
|
|
},
|
|
})
|
|
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure} \\centering Enter Caption 🏷fig:enter-label\\end{figure}'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('Editing existing figure', function () {
|
|
it('Parses existing label and caption', function () {
|
|
cy.get('.cm-content').type(
|
|
`\\begin{{}figure}
|
|
\\centering
|
|
\\includegraphics[width=0.5\\linewidth]{{}frog.jpg}
|
|
\\caption{{}My caption}
|
|
\\label{{}fig:my-label}
|
|
\\end{{}figure}`,
|
|
{ delay: 0 }
|
|
)
|
|
cy.get('[aria-label="Edit figure"]').click()
|
|
cy.get('[data-cy="include-caption-option"]').should('be.checked')
|
|
cy.get('[data-cy="include-label-option"]').should('be.checked')
|
|
})
|
|
|
|
it('Parses existing width', function () {
|
|
cy.get('.cm-content').type(
|
|
`\\begin{{}figure}
|
|
\\centering
|
|
\\includegraphics[width=0.75\\linewidth]{{}frog.jpg}
|
|
\\caption{{}My caption}
|
|
\\label{{}fig:my-label}
|
|
\\end{{}figure}`,
|
|
{ delay: 0 }
|
|
)
|
|
cy.get('[aria-label="Edit figure"]').click()
|
|
cy.get('[value="0.75"]').should('be.checked')
|
|
})
|
|
|
|
it('Removes existing label when unchecked', function () {
|
|
cy.get('.cm-content').type(
|
|
`\\begin{{}figure}
|
|
\\centering
|
|
\\includegraphics[width=0.75\\linewidth]{{}frog.jpg}
|
|
\\label{{}fig:my-label}
|
|
\\end{{}figure}`,
|
|
{ delay: 0 }
|
|
)
|
|
cy.get('[aria-label="Edit figure"]').click()
|
|
cy.get('[data-cy="include-label-option"]').click()
|
|
cy.get('[data-cy="include-label-option"]').should('not.be.checked')
|
|
cy.findByText('Done').click()
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure}\\centering\\end{figure}'
|
|
)
|
|
})
|
|
|
|
it('Removes existing caption when unchecked', function () {
|
|
cy.get('.cm-content').type(
|
|
`\\begin{{}figure}
|
|
\\centering
|
|
\\includegraphics[width=0.75\\linewidth]{{}frog.jpg}
|
|
\\caption{{}My caption}
|
|
\\label{{}fig:my-label}
|
|
\\end{{}figure}`,
|
|
{ delay: 0 }
|
|
)
|
|
cy.get('[aria-label="Edit figure"]').click()
|
|
cy.get('[data-cy="include-caption-option"]').click()
|
|
cy.get('[data-cy="include-caption-option"]').should('not.be.checked')
|
|
cy.findByText('Done').click()
|
|
cy.get('.cm-content').should(
|
|
'have.text',
|
|
'\\begin{figure}\\centering🏷fig:my-label\\end{figure}'
|
|
)
|
|
})
|
|
|
|
it('Preserves other content when removing figure', function () {
|
|
cy.get('.cm-content').type(
|
|
`text above
|
|
\\begin{{}figure}
|
|
\\centering
|
|
\\includegraphics[width=0.75\\linewidth]{{}frog.jpg}
|
|
\\caption{{}My caption}
|
|
\\label{{}fig:my-label}
|
|
\\end{{}figure}
|
|
text below`,
|
|
{ delay: 0 }
|
|
)
|
|
cy.get('[aria-label="Edit figure"]').click()
|
|
cy.get('[aria-label="Remove or replace figure"]').click()
|
|
cy.findByText('Delete figure').click()
|
|
cy.get('.cm-content').should('have.text', 'text abovetext below')
|
|
})
|
|
|
|
it('Opens figure modal on pasting image', function () {
|
|
cy.fixture<Uint8Array>('images/gradient.png').then(gradientBuffer => {
|
|
const gradientFile = new File([gradientBuffer], 'gradient.png', {
|
|
type: 'image/png',
|
|
})
|
|
const clipboardData = new DataTransfer()
|
|
clipboardData.items.add(gradientFile)
|
|
cy.wrap(clipboardData.files).should('have.length', 1)
|
|
cy.get('.cm-content').trigger('paste', { clipboardData })
|
|
cy.findByText('Upload from computer').should('be.visible')
|
|
cy.findByLabelText('File name in this project').should(
|
|
'have.value',
|
|
'gradient.png'
|
|
)
|
|
})
|
|
})
|
|
|
|
// TODO: Add tests for replacing image when we can match on image path
|
|
// TODO: Add tests for changing image size when we can match on figure width
|
|
})
|
|
})
|