From 988fc57574db56aafc80ab1d735d7cada3198353 Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Wed, 17 May 2023 08:48:21 +0100 Subject: [PATCH] Merge pull request #13077 from overleaf/mj-figure-modal-tests [web] Add cypress tests for figure modal GitOrigin-RevId: 4debae1c665a68fd7bfa9f0dcfc150bec38a7c64 --- .../cypress/support/shared/commands/index.ts | 9 + .../support/shared/commands/linked-file.ts | 12 + .../support/shared/commands/project-list.ts | 22 + .../cypress/support/shared/commands/upload.ts | 18 + .../web/frontend/extracted-translations.json | 6 + .../figure-modal/figure-modal-options.tsx | 2 + .../figure-modal-other-project-source.tsx | 6 +- .../figure-modal-upload-source.tsx | 9 +- .../components/toolbar/button-menu.tsx | 2 + .../visual-widgets/editable-graphics.ts | 1 + services/web/locales/en.json | 6 + .../components/figure-modal.spec.tsx | 390 ++++++++++++++++++ .../source-editor/helpers/mock-scope.ts | 37 +- 13 files changed, 514 insertions(+), 6 deletions(-) create mode 100644 services/web/cypress/support/shared/commands/linked-file.ts create mode 100644 services/web/cypress/support/shared/commands/project-list.ts create mode 100644 services/web/cypress/support/shared/commands/upload.ts create mode 100644 services/web/test/frontend/features/source-editor/components/figure-modal.spec.tsx diff --git a/services/web/cypress/support/shared/commands/index.ts b/services/web/cypress/support/shared/commands/index.ts index 676906bf75..41433ba258 100644 --- a/services/web/cypress/support/shared/commands/index.ts +++ b/services/web/cypress/support/shared/commands/index.ts @@ -7,6 +7,9 @@ import { import { interceptEvents } from './events' import { interceptSpelling } from './spelling' import { interceptAsync } from './intercept-async' +import { interceptFileUpload } from './upload' +import { interceptProjectListing } from './project-list' +import { interceptLinkedFile } from './linked-file' // eslint-disable-next-line no-unused-vars,@typescript-eslint/no-namespace declare global { @@ -20,6 +23,9 @@ declare global { interceptSpelling: typeof interceptSpelling waitForCompile: typeof waitForCompile interceptDeferredCompile: typeof interceptDeferredCompile + interceptFileUpload: typeof interceptFileUpload + interceptProjectListing: typeof interceptProjectListing + interceptLinkedFile: typeof interceptLinkedFile } } } @@ -30,3 +36,6 @@ Cypress.Commands.add('interceptEvents', interceptEvents) Cypress.Commands.add('interceptSpelling', interceptSpelling) Cypress.Commands.add('waitForCompile', waitForCompile) Cypress.Commands.add('interceptDeferredCompile', interceptDeferredCompile) +Cypress.Commands.add('interceptFileUpload', interceptFileUpload) +Cypress.Commands.add('interceptProjectListing', interceptProjectListing) +Cypress.Commands.add('interceptLinkedFile', interceptLinkedFile) diff --git a/services/web/cypress/support/shared/commands/linked-file.ts b/services/web/cypress/support/shared/commands/linked-file.ts new file mode 100644 index 0000000000..b3e17775f2 --- /dev/null +++ b/services/web/cypress/support/shared/commands/linked-file.ts @@ -0,0 +1,12 @@ +import { HttpRequestInterceptor } from 'cypress/types/net-stubbing' + +export const interceptLinkedFile = () => { + cy.intercept( + { method: 'POST', url: '/project/*/linked_file' }, + cy + .spy((req: Parameters[0]) => { + req.reply({ statusCode: 200, body: { success: true } }) + }) + .as('linked-file-request') + ) +} diff --git a/services/web/cypress/support/shared/commands/project-list.ts b/services/web/cypress/support/shared/commands/project-list.ts new file mode 100644 index 0000000000..ea98947235 --- /dev/null +++ b/services/web/cypress/support/shared/commands/project-list.ts @@ -0,0 +1,22 @@ +export const interceptProjectListing = () => { + cy.intercept('GET', '/user/projects', { + projects: [ + { + _id: 'fake-project-1', + accessLevel: 'owner', + name: 'My first project', + }, + { + _id: 'fake-project-2', + accessLevel: 'owner', + name: 'My second project', + }, + ], + }) + cy.intercept('GET', '/project/*/entities', { + entities: [ + { path: '/frog.jpg', type: 'file' }, + { path: 'figures/unicorn.png', type: 'file' }, + ], + }) +} diff --git a/services/web/cypress/support/shared/commands/upload.ts b/services/web/cypress/support/shared/commands/upload.ts new file mode 100644 index 0000000000..b03e5663e8 --- /dev/null +++ b/services/web/cypress/support/shared/commands/upload.ts @@ -0,0 +1,18 @@ +import { HttpRequestInterceptor } from 'cypress/types/net-stubbing' + +export const interceptFileUpload = () => { + cy.intercept( + { method: 'POST', url: /\/project\/.*\/upload/ }, + cy + .spy((req: Parameters[0]) => { + const folderMatch = req.url.match( + /project\/.*\/upload\?folder_id=[a-f0-9]{24}/ + ) + if (!folderMatch) { + req.reply({ statusCode: 500, body: { success: false } }) + } + req.reply({ statusCode: 200, body: { success: true } }) + }) + .as('uploadRequest') + ) +} diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index d939053283..1e0157abf0 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -274,9 +274,11 @@ "file_already_exists": "", "file_already_exists_in_this_location": "", "file_name": "", + "file_name_figure_modal": "", "file_name_in_this_project": "", "file_name_in_this_project_figure_modal": "", "file_outline": "", + "file_size": "", "files_cannot_include_invalid_characters": "", "find_out_more": "", "find_out_more_about_institution_login": "", @@ -745,6 +747,7 @@ "remove_collaborator": "", "remove_from_group": "", "remove_manager": "", + "remove_or_replace_figure": "", "remove_tag": "", "removing": "", "rename": "", @@ -799,11 +802,14 @@ "search_whole_word": "", "search_within_selection": "", "select_a_file": "", + "select_a_file_figure_modal": "", "select_a_payment_method": "", "select_a_project": "", + "select_a_project_figure_modal": "", "select_all": "", "select_all_projects": "", "select_an_output_file": "", + "select_an_output_file_figure_modal": "", "select_folder_from_project": "", "select_from_output_files": "", "select_from_project_files": "", diff --git a/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal-options.tsx b/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal-options.tsx index f51f49848b..342c93ebd6 100644 --- a/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal-options.tsx +++ b/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal-options.tsx @@ -20,6 +20,7 @@ export const FigureModalFigureOptions: FC = () => { dispatch({ includeCaption: event.target.checked })} /> @@ -31,6 +32,7 @@ export const FigureModalFigureOptions: FC = () => { dispatch({ includeLabel: event.target.checked })} /> diff --git a/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx b/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx index ecf196af4f..c3b51abe95 100644 --- a/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx +++ b/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx @@ -126,7 +126,7 @@ export const FigureModalOtherProjectSource: FC = () => { items={projects ?? []} itemToString={project => (project ? project.name : '')} itemToKey={item => item._id} - defaultText={t('select_a_project')} + defaultText={t('select_a_project_figure_modal')} label={t('project_figure_modal')} disabled={projectsLoading} onSelectedItemChanged={item => { @@ -201,7 +201,7 @@ const SelectFile = ({ onSelectedItemChange?: (item: T | null | undefined) => any }) => { const { t } = useTranslation() - defaultText = defaultText ?? t('select_a_file') + defaultText = defaultText ?? t('select_a_file_figure_modal') label = label ?? t('image_file') const imageFiles = useMemo(() => files?.filter(isImageEntity), [files]) const empty = loading || !imageFiles || imageFiles.length === 0 @@ -257,7 +257,7 @@ const SelectFromProjectOutputFiles: FC<{ return ( any }> = ({ name, size, status, onDelete }) => { + const { t } = useTranslation() let icon switch (status) { case FileUploadStatus.ERROR: @@ -280,7 +281,9 @@ export const FileContainer: FC<{ )} />
- {name} + + {name} + {size !== undefined && ( )} @@ -288,6 +291,7 @@ export const FileContainer: FC<{