From acc611a3d99a58e9afe9e19d4e764d776927b485 Mon Sep 17 00:00:00 2001 From: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Date: Tue, 14 May 2024 17:35:16 +0200 Subject: [PATCH] fix(web): admin settings number input validation (#9470) * fix(web): admin settings number input validation * fix import by creating *.ts file * just ignore import error --- web/package-lock.json | 14 +++++++++ web/package.json | 1 + .../settings/setting-input-field.spec.ts | 30 +++++++++++++++++++ .../settings/setting-input-field.svelte | 7 ++--- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 web/src/lib/components/shared-components/settings/setting-input-field.spec.ts diff --git a/web/package-lock.json b/web/package-lock.json index 4761a6b6a9..43c4bafa01 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -36,6 +36,7 @@ "@sveltejs/vite-plugin-svelte": "^3.0.2", "@testing-library/jest-dom": "^6.4.2", "@testing-library/svelte": "^5.0.0", + "@testing-library/user-event": "^14.5.2", "@types/dom-to-image": "^2.6.7", "@types/justified-layout": "^4.1.4", "@types/lodash-es": "^4.17.12", @@ -2154,6 +2155,19 @@ } } }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@types/aria-query": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.2.tgz", diff --git a/web/package.json b/web/package.json index a0b9207de8..b31b2f1e8d 100644 --- a/web/package.json +++ b/web/package.json @@ -31,6 +31,7 @@ "@sveltejs/vite-plugin-svelte": "^3.0.2", "@testing-library/jest-dom": "^6.4.2", "@testing-library/svelte": "^5.0.0", + "@testing-library/user-event": "^14.5.2", "@types/dom-to-image": "^2.6.7", "@types/justified-layout": "^4.1.4", "@types/lodash-es": "^4.17.12", diff --git a/web/src/lib/components/shared-components/settings/setting-input-field.spec.ts b/web/src/lib/components/shared-components/settings/setting-input-field.spec.ts new file mode 100644 index 0000000000..7b59affdb3 --- /dev/null +++ b/web/src/lib/components/shared-components/settings/setting-input-field.spec.ts @@ -0,0 +1,30 @@ +import { render } from '@testing-library/svelte'; +import userEvent from '@testing-library/user-event'; +// @ts-expect-error the import works but tsc check errors +import SettingInputField, { SettingInputFieldType } from './setting-input-field.svelte'; + +describe('SettingInputField component', () => { + it('validates number input on blur', async () => { + const { getByRole } = render(SettingInputField, { + props: { + label: 'test-number-input', + inputType: SettingInputFieldType.NUMBER, + value: 0, + min: 0, + max: 100, + step: '0.1', + }, + }); + const user = userEvent.setup(); + + const numberInput = getByRole('spinbutton') as HTMLInputElement; + expect(numberInput.value).toEqual('0'); + + await user.click(numberInput); + await user.keyboard('100.1'); + expect(numberInput.value).toEqual('100.1'); + + await user.click(document.body); + expect(numberInput.value).toEqual('100'); + }); +}); diff --git a/web/src/lib/components/shared-components/settings/setting-input-field.svelte b/web/src/lib/components/shared-components/settings/setting-input-field.svelte index 8e966c8f5f..a92482b178 100644 --- a/web/src/lib/components/shared-components/settings/setting-input-field.svelte +++ b/web/src/lib/components/shared-components/settings/setting-input-field.svelte @@ -25,9 +25,7 @@ export let isEdited = false; export let passwordAutocomplete: string = 'current-password'; - const handleInput = (e: Event) => { - value = (e.target as HTMLInputElement).value; - + const validateInput = () => { if (inputType === SettingInputFieldType.NUMBER) { let newValue = Number(value) || 0; if (newValue < min) { @@ -79,7 +77,8 @@ {step} {required} {value} - on:input={handleInput} + on:input={(e) => (value = e.currentTarget.value)} + on:blur={validateInput} {disabled} {title} />