From 43e96ad863bc674f8f4dbd4e0b2a0d41ea5e6d63 Mon Sep 17 00:00:00 2001 From: David <33458145+davidmcpowell@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:42:03 +0100 Subject: [PATCH] Merge pull request #29253 from overleaf/dp-settings-modal-test-improvements Improvements to settings modal frontend tests GitOrigin-RevId: cbf30df51aa4b290580340507ba591e863a4f83b --- .../settings/auto-compile-setting.test.tsx | 44 ++++++++++++++ .../settings/breadcrumbs-setting.test.tsx | 51 ++++++++++++++++ .../settings/compiler-setting.test.tsx | 59 +++++++++++++++---- .../settings/draft-setting.test.tsx | 45 ++++++++++++++ .../settings/editor-theme-setting.test.tsx | 24 +++++++- .../settings/font-family-setting.test.tsx | 46 +++++++++++---- .../settings/font-size-setting.test.tsx | 17 +++++- .../settings/image-name-setting.test.tsx | 26 +++++++- .../settings/keybinding-setting.test.tsx | 45 +++++++++++--- .../settings/line-height-setting.test.tsx | 42 ++++++++++--- .../settings/overall-theme-setting.test.tsx | 20 ++++++- .../settings/pdf-viewer-setting.test.tsx | 38 ++++++++++-- .../settings/root-document-setting.test.tsx | 48 +++++++++++++-- .../settings/spell-check-setting.test.tsx | 35 ++++++++++- .../stop-on-first-error-setting.test.tsx | 44 ++++++++++++++ 15 files changed, 526 insertions(+), 58 deletions(-) create mode 100644 services/web/test/frontend/features/settings-modal/settings/auto-compile-setting.test.tsx create mode 100644 services/web/test/frontend/features/settings-modal/settings/breadcrumbs-setting.test.tsx create mode 100644 services/web/test/frontend/features/settings-modal/settings/draft-setting.test.tsx create mode 100644 services/web/test/frontend/features/settings-modal/settings/stop-on-first-error-setting.test.tsx diff --git a/services/web/test/frontend/features/settings-modal/settings/auto-compile-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/auto-compile-setting.test.tsx new file mode 100644 index 0000000000..089d7654e7 --- /dev/null +++ b/services/web/test/frontend/features/settings-modal/settings/auto-compile-setting.test.tsx @@ -0,0 +1,44 @@ +import { screen, render } from '@testing-library/react' +import { expect } from 'chai' +import fetchMock from 'fetch-mock' +import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' +import AutoCompileSetting from '@/features/ide-redesign/components/settings/compiler-settings/auto-compile-setting' +import localStorage from '@/infrastructure/local-storage' +import userEvent from '@testing-library/user-event' + +describe('', function () { + afterEach(function () { + fetchMock.removeRoutes().clearHistory() + }) + + it('can toggle', async function () { + render( + + + + + + ) + + const toggle = screen.getByLabelText('Autocompile') + const startingCheckedValue = (toggle as HTMLInputElement).checked + + // Toggle the checkbox + await userEvent.click(toggle) + expect((toggle as HTMLInputElement).checked).to.equal(!startingCheckedValue) + expect( + localStorage.getItem(`autocompile_enabled:${projectDefaults._id}`) + ).to.equal(!startingCheckedValue) + + // Toggle back to original value + await userEvent.click(toggle) + expect((toggle as HTMLInputElement).checked).to.equal(startingCheckedValue) + expect( + !!localStorage.getItem(`autocompile_enabled:${projectDefaults._id}`) + ).to.equal(startingCheckedValue) + }) +}) diff --git a/services/web/test/frontend/features/settings-modal/settings/breadcrumbs-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/breadcrumbs-setting.test.tsx new file mode 100644 index 0000000000..2129d1557d --- /dev/null +++ b/services/web/test/frontend/features/settings-modal/settings/breadcrumbs-setting.test.tsx @@ -0,0 +1,51 @@ +import { screen, render } from '@testing-library/react' +import { expect } from 'chai' +import fetchMock from 'fetch-mock' +import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' +import { EditorProviders } from '../../../helpers/editor-providers' +import BreadcrumbsSetting from '@/features/ide-redesign/components/settings/editor-settings/breadcrumbs-setting' + +describe('', function () { + afterEach(function () { + fetchMock.removeRoutes().clearHistory() + }) + + it('can toggle', async function () { + render( + + + + + + ) + + const saveSettingsMock = fetchMock.post( + `express:/user/settings`, + { + status: 200, + }, + { delay: 0 } + ) + + const toggle = screen.getByLabelText('Breadcrumbs') + const startingCheckedValue = (toggle as HTMLInputElement).checked + + // Toggle the checkbox + toggle.click() + expect((toggle as HTMLInputElement).checked).to.equal(!startingCheckedValue) + expect( + saveSettingsMock.callHistory.called(`/user/settings`, { + body: { breadcrumbs: !startingCheckedValue }, + }) + ).to.be.true + + // Toggle back to original value + toggle.click() + expect((toggle as HTMLInputElement).checked).to.equal(startingCheckedValue) + expect( + saveSettingsMock.callHistory.called(`/user/settings`, { + body: { breadcrumbs: startingCheckedValue }, + }) + ).to.be.true + }) +}) diff --git a/services/web/test/frontend/features/settings-modal/settings/compiler-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/compiler-setting.test.tsx index 6411c09ebd..6cf045ea9d 100644 --- a/services/web/test/frontend/features/settings-modal/settings/compiler-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/compiler-setting.test.tsx @@ -2,15 +2,38 @@ import { screen, within, render } from '@testing-library/react' import { expect } from 'chai' import fetchMock from 'fetch-mock' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' -import { EditorProviders } from '../../../helpers/editor-providers' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' import CompilerSetting from '@/features/ide-redesign/components/settings/compiler-settings/compiler-setting' +import userEvent from '@testing-library/user-event' + +const OPTIONS = [ + { + label: 'pdfLaTeX', + value: 'pdflatex', + }, + { + label: 'LaTeX', + value: 'latex', + }, + { + label: 'XeLaTeX', + value: 'xelatex', + }, + { + label: 'LuaLaTeX', + value: 'lualatex', + }, +] describe('', function () { afterEach(function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -19,18 +42,30 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + `express:/project/:projectId/settings`, + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Compiler') - const optionPdfLaTeX = within(select).getByText('pdfLaTeX') - expect(optionPdfLaTeX.getAttribute('value')).to.equal('pdflatex') + // Reverse order so we test changing to each option + for (const option of OPTIONS.reverse()) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) - const optionLaTeX = within(select).getByText('LaTeX') - expect(optionLaTeX.getAttribute('value')).to.equal('latex') - - const optionXeLaTeX = within(select).getByText('XeLaTeX') - expect(optionXeLaTeX.getAttribute('value')).to.equal('xelatex') - - const optionLuaLaTeX = within(select).getByText('LuaLaTeX') - expect(optionLuaLaTeX.getAttribute('value')).to.equal('lualatex') + expect( + saveSettingsMock.callHistory.called( + `/project/${projectDefaults._id}/settings`, + { + body: { compiler: option.value }, + } + ) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/draft-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/draft-setting.test.tsx new file mode 100644 index 0000000000..d8d0fe3831 --- /dev/null +++ b/services/web/test/frontend/features/settings-modal/settings/draft-setting.test.tsx @@ -0,0 +1,45 @@ +import { screen, within, render } from '@testing-library/react' +import { expect } from 'chai' +import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' +import userEvent from '@testing-library/user-event' +import DraftSetting from '@/features/ide-redesign/components/settings/compiler-settings/draft-setting' + +const OPTIONS = [ + { + label: 'Normal', + value: false, + }, + { + label: 'Fast [draft]', + value: true, + }, +] + +describe('', function () { + it('each option is shown and can be selected', async function () { + render( + + + + + + ) + + const select = screen.getByLabelText('Compile mode') + + for (const option of OPTIONS) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal( + option.value.toString() + ) + await userEvent.selectOptions(select, [optionElement]) + expect(!!localStorage.getItem(`draft:${projectDefaults._id}`)).to.equal( + option.value + ) + } + }) +}) diff --git a/services/web/test/frontend/features/settings-modal/settings/editor-theme-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/editor-theme-setting.test.tsx index 3bd5e6ae1e..7751309634 100644 --- a/services/web/test/frontend/features/settings-modal/settings/editor-theme-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/editor-theme-setting.test.tsx @@ -4,10 +4,10 @@ import fetchMock from 'fetch-mock' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import { EditorProviders } from '../../../helpers/editor-providers' import EditorThemeSetting from '@/features/ide-redesign/components/settings/appearance-settings/editor-theme-setting' +import userEvent from '@testing-library/user-event' describe('', function () { const editorThemes = ['editortheme-1', 'editortheme-2', 'editortheme-3'] - const legacyEditorThemes = ['legacytheme-1', 'legacytheme-2', 'legacytheme-3'] beforeEach(function () { @@ -19,7 +19,7 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -28,11 +28,25 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + `express:/user/settings`, + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Editor theme') for (const theme of editorThemes) { const option = within(select).getByText(theme.replace(/_/g, ' ')) expect(option.getAttribute('value')).to.equal(theme) + await userEvent.selectOptions(select, [option]) + expect( + saveSettingsMock.callHistory.called(`/user/settings`, { + body: { editorTheme: theme }, + }) + ).to.be.true } for (const theme of legacyEditorThemes) { @@ -40,6 +54,12 @@ describe('', function () { theme.replace(/_/g, ' ') + ' (Legacy)' ) expect(option.getAttribute('value')).to.equal(theme) + await userEvent.selectOptions(select, [option]) + expect( + saveSettingsMock.callHistory.called(`/user/settings`, { + body: { editorTheme: theme }, + }) + ).to.be.true } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/font-family-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/font-family-setting.test.tsx index d08845cdc3..b6a1b2f67b 100644 --- a/services/web/test/frontend/features/settings-modal/settings/font-family-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/font-family-setting.test.tsx @@ -4,13 +4,29 @@ import fetchMock from 'fetch-mock' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import { EditorProviders } from '../../../helpers/editor-providers' import FontFamilySetting from '@/features/ide-redesign/components/settings/appearance-settings/font-family-setting' +import userEvent from '@testing-library/user-event' + +const options = [ + { + label: 'Monaco / Menlo / Consolas', + value: 'monaco', + }, + { + label: 'Lucida / Source Code Pro', + value: 'lucida', + }, + { + label: 'OpenDyslexic Mono', + value: 'opendyslexicmono', + }, +] describe('', function () { afterEach(function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -19,17 +35,27 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Editor font family') - const optionMonaco = within(select).getByText('Monaco / Menlo / Consolas') - expect(optionMonaco.getAttribute('value')).to.equal('monaco') + // Reverse order so we test changing to each option + for (const option of options.reverse()) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) - const optionLucida = within(select).getByText('Lucida / Source Code Pro') - expect(optionLucida.getAttribute('value')).to.equal('lucida') - - const optionOpenDyslexicMono = within(select).getByText('OpenDyslexic Mono') - expect(optionOpenDyslexicMono.getAttribute('value')).to.equal( - 'opendyslexicmono' - ) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { fontFamily: option.value }, + }) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/font-size-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/font-size-setting.test.tsx index ec49a9317b..d64094eaab 100644 --- a/services/web/test/frontend/features/settings-modal/settings/font-size-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/font-size-setting.test.tsx @@ -4,6 +4,7 @@ import fetchMock from 'fetch-mock' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import { EditorProviders } from '../../../helpers/editor-providers' import FontSizeSetting from '@/features/ide-redesign/components/settings/appearance-settings/font-size-setting' +import userEvent from '@testing-library/user-event' describe('', function () { const sizes = ['10', '11', '12', '13', '14', '16', '18', '20', '22', '24'] @@ -12,7 +13,7 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -21,11 +22,25 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Editor font size') for (const size of sizes) { const option = within(select).getByText(`${size}px`) expect(option.getAttribute('value')).to.equal(size) + await userEvent.selectOptions(select, [option]) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { fontSize: Number(size) }, + }) + ).to.be.true } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/image-name-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/image-name-setting.test.tsx index fdda2d46c8..0cba0077ae 100644 --- a/services/web/test/frontend/features/settings-modal/settings/image-name-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/image-name-setting.test.tsx @@ -3,8 +3,12 @@ import { expect } from 'chai' import fetchMock from 'fetch-mock' import type { ImageName } from '../../../../../types/project-settings' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' -import { EditorProviders } from '../../../helpers/editor-providers' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' import ImageNameSetting from '@/features/ide-redesign/components/settings/compiler-settings/image-name-setting' +import userEvent from '@testing-library/user-event' describe('', function () { const imageNames: ImageName[] = [ @@ -28,7 +32,7 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -37,11 +41,29 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + `express:/project/:projectId/settings`, + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('TeX Live version') for (const { imageName, imageDesc } of imageNames) { const option = within(select).getByText(imageDesc) expect(option.getAttribute('value')).to.equal(imageName) + await userEvent.selectOptions(select, [option]) + + expect( + saveSettingsMock.callHistory.called( + `/project/${projectDefaults._id}/settings`, + { + body: { imageName }, + } + ) + ).to.be.true } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/keybinding-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/keybinding-setting.test.tsx index 491647da0f..bb309758b7 100644 --- a/services/web/test/frontend/features/settings-modal/settings/keybinding-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/keybinding-setting.test.tsx @@ -4,13 +4,29 @@ import fetchMock from 'fetch-mock' import { EditorProviders } from '../../../helpers/editor-providers' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import KeybindingSetting from '@/features/ide-redesign/components/settings/editor-settings/keybinding-setting' +import userEvent from '@testing-library/user-event' + +const OPTIONS = [ + { + label: 'None', + value: 'default', + }, + { + label: 'Vim', + value: 'vim', + }, + { + label: 'Emacs', + value: 'emacs', + }, +] describe('', function () { afterEach(function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -19,15 +35,26 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Keybindings') - const optionNone = within(select).getByText('None') - expect(optionNone.getAttribute('value')).to.equal('default') - - const optionVim = within(select).getByText('Vim') - expect(optionVim.getAttribute('value')).to.equal('vim') - - const optionEmacs = within(select).getByText('Emacs') - expect(optionEmacs.getAttribute('value')).to.equal('emacs') + // Reverse order so we test changing to each option + for (const option of OPTIONS.reverse()) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { mode: option.value }, + }) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/line-height-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/line-height-setting.test.tsx index 72bc117d6f..c311f7493a 100644 --- a/services/web/test/frontend/features/settings-modal/settings/line-height-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/line-height-setting.test.tsx @@ -4,13 +4,29 @@ import fetchMock from 'fetch-mock' import { EditorProviders } from '../../../helpers/editor-providers' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import LineHeightSetting from '@/features/ide-redesign/components/settings/appearance-settings/line-height-setting' +import userEvent from '@testing-library/user-event' + +const OPTIONS = [ + { + label: 'Compact', + value: 'compact', + }, + { + label: 'Normal', + value: 'normal', + }, + { + label: 'Wide', + value: 'wide', + }, +] describe('', function () { afterEach(function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -21,13 +37,23 @@ describe('', function () { const select = screen.getByLabelText('Editor line height') - const optionCompact = within(select).getByText('Compact') - expect(optionCompact.getAttribute('value')).to.equal('compact') + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) - const optionNormal = within(select).getByText('Normal') - expect(optionNormal.getAttribute('value')).to.equal('normal') - - const optionWide = within(select).getByText('Wide') - expect(optionWide.getAttribute('value')).to.equal('wide') + for (const option of OPTIONS) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { lineHeight: option.value }, + }) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/overall-theme-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/overall-theme-setting.test.tsx index 9f88363653..cb5f81de0f 100644 --- a/services/web/test/frontend/features/settings-modal/settings/overall-theme-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/overall-theme-setting.test.tsx @@ -7,6 +7,7 @@ import getMeta from '@/utils/meta' import { EditorProviders } from '../../../helpers/editor-providers' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import OverallThemeSetting from '@/features/ide-redesign/components/settings/appearance-settings/overall-theme-setting' +import userEvent from '@testing-library/user-event' const IEEE_BRAND_ID = 1234 const OTHER_BRAND_ID = 2234 @@ -36,7 +37,7 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -45,11 +46,26 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Overall theme') - for (const theme of overallThemes) { + // Reverse order so we test changing to each option + for (const theme of overallThemes.reverse()) { const option = within(select).getByText(theme.name) expect(option.getAttribute('value')).to.equal(theme.val) + await userEvent.selectOptions(select, [option]) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { overallTheme: theme.val }, + }) + ).to.be.true } }) describe('Branded Project', function () { diff --git a/services/web/test/frontend/features/settings-modal/settings/pdf-viewer-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/pdf-viewer-setting.test.tsx index 51c828dedb..5929bf071e 100644 --- a/services/web/test/frontend/features/settings-modal/settings/pdf-viewer-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/pdf-viewer-setting.test.tsx @@ -4,13 +4,25 @@ import fetchMock from 'fetch-mock' import { EditorProviders } from '../../../helpers/editor-providers' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import PDFViewerSetting from '@/features/ide-redesign/components/settings/editor-settings/pdf-viewer-setting' +import userEvent from '@testing-library/user-event' + +const OPTIONS = [ + { + label: 'Overleaf', + value: 'pdfjs', + }, + { + label: 'Browser', + value: 'native', + }, +] describe('', function () { afterEach(function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -19,12 +31,26 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + 'express:/user/settings', + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('PDF Viewer') - const optionOverleaf = within(select).getByText('Overleaf') - expect(optionOverleaf.getAttribute('value')).to.equal('pdfjs') - - const optionBrowser = within(select).getByText('Browser') - expect(optionBrowser.getAttribute('value')).to.equal('native') + // Reverse order so we test changing to each option + for (const option of OPTIONS.reverse()) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) + expect( + saveSettingsMock.callHistory.called('/user/settings', { + body: { pdfViewer: option.value }, + }) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/root-document-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/root-document-setting.test.tsx index 35312341b4..8b010db51d 100644 --- a/services/web/test/frontend/features/settings-modal/settings/root-document-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/root-document-setting.test.tsx @@ -3,8 +3,23 @@ import { expect } from 'chai' import fetchMock from 'fetch-mock' import { Folder } from '../../../../../types/folder' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' -import { EditorProviders } from '../../../helpers/editor-providers' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' import RootDocumentSetting from '@/features/ide-redesign/components/settings/compiler-settings/root-document-setting' +import userEvent from '@testing-library/user-event' + +const OPTIONS = [ + { + label: 'main.tex', + value: '123abc', + }, + { + label: 'another.tex', + value: '123abcd', + }, +] describe('', function () { const rootFolder: Folder = { @@ -15,6 +30,10 @@ describe('', function () { _id: '123abc', name: 'main.tex', }, + { + _id: '123abcd', + name: 'another.tex', + }, ], fileRefs: [], folders: [], @@ -34,7 +53,7 @@ describe('', function () { window.metaAttributesCache.set('ol-ExposedSettings', originalSettings) }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -43,9 +62,30 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + `express:/project/:projectId/settings`, + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Main document') - const optionOn = within(select).getByText('main.tex') - expect(optionOn.getAttribute('value')).to.equal('123abc') + // Reverse order so we test changing to each option + for (const option of OPTIONS.reverse()) { + const optionElement = within(select).getByText(option.label) + expect(optionElement.getAttribute('value')).to.equal(option.value) + await userEvent.selectOptions(select, [optionElement]) + + expect( + saveSettingsMock.callHistory.called( + `/project/${projectDefaults._id}/settings`, + { + body: { rootDocId: option.value }, + } + ) + ).to.be.true + } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/spell-check-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/spell-check-setting.test.tsx index 0d8facb094..eb2c9d4a86 100644 --- a/services/web/test/frontend/features/settings-modal/settings/spell-check-setting.test.tsx +++ b/services/web/test/frontend/features/settings-modal/settings/spell-check-setting.test.tsx @@ -2,9 +2,13 @@ import { screen, within, render } from '@testing-library/react' import { expect } from 'chai' import fetchMock from 'fetch-mock' import type { SpellCheckLanguage } from '../../../../../types/project-settings' -import { EditorProviders } from '../../../helpers/editor-providers' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' import SpellCheckSetting from '@/features/ide-redesign/components/settings/editor-settings/spell-check-setting' +import userEvent from '@testing-library/user-event' describe('', function () { const languages: SpellCheckLanguage[] = [ @@ -28,7 +32,7 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) - it('shows correct menu', async function () { + it('each option is shown and can be selected', async function () { render( @@ -37,14 +41,41 @@ describe('', function () { ) + const saveSettingsMock = fetchMock.post( + `express:/project/:projectId/settings`, + { + status: 200, + }, + { delay: 0 } + ) + const select = screen.getByLabelText('Spellcheck language') const optionEmpty = within(select).getByText('Off') expect(optionEmpty.getAttribute('value')).to.equal('') + await userEvent.selectOptions(select, [optionEmpty]) + expect( + saveSettingsMock.callHistory.called( + `/project/${projectDefaults._id}/settings`, + { + body: { spellCheckLanguage: '' }, + } + ) + ).to.be.true for (const language of languages) { const option = within(select).getByText(language.name) expect(option.getAttribute('value')).to.equal(language.code) + await userEvent.selectOptions(select, [option]) + + expect( + saveSettingsMock.callHistory.called( + `/project/${projectDefaults._id}/settings`, + { + body: { spellCheckLanguage: language.code }, + } + ) + ).to.be.true } }) }) diff --git a/services/web/test/frontend/features/settings-modal/settings/stop-on-first-error-setting.test.tsx b/services/web/test/frontend/features/settings-modal/settings/stop-on-first-error-setting.test.tsx new file mode 100644 index 0000000000..a2807ff97d --- /dev/null +++ b/services/web/test/frontend/features/settings-modal/settings/stop-on-first-error-setting.test.tsx @@ -0,0 +1,44 @@ +import { screen, render } from '@testing-library/react' +import { expect } from 'chai' +import fetchMock from 'fetch-mock' +import { SettingsModalProvider } from '@/features/ide-redesign/contexts/settings-modal-context' +import { + EditorProviders, + projectDefaults, +} from '../../../helpers/editor-providers' +import localStorage from '@/infrastructure/local-storage' +import userEvent from '@testing-library/user-event' +import StopOnFirstErrorSetting from '@/features/ide-redesign/components/settings/compiler-settings/stop-on-first-error-setting' + +describe('', function () { + afterEach(function () { + fetchMock.removeRoutes().clearHistory() + }) + + it('can toggle', async function () { + render( + + + + + + ) + + const toggle = screen.getByLabelText('Stop on first error') + const startingCheckedValue = (toggle as HTMLInputElement).checked + + // Toggle the checkbox + await userEvent.click(toggle) + expect((toggle as HTMLInputElement).checked).to.equal(!startingCheckedValue) + expect( + localStorage.getItem(`stop_on_first_error:${projectDefaults._id}`) + ).to.equal(!startingCheckedValue) + + // Toggle back to original value + await userEvent.click(toggle) + expect((toggle as HTMLInputElement).checked).to.equal(startingCheckedValue) + expect( + !!localStorage.getItem(`stop_on_first_error:${projectDefaults._id}`) + ).to.equal(startingCheckedValue) + }) +})