From 5040c947d2f47e5ec66285fa353e3e0ffd127ba7 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 14:29:07 -0400 Subject: [PATCH] fix: validation for Percentage of Max SUV input field in TMTV module (#5417) Co-authored-by: Joe Boccanfuso --- .../ROIThresholdConfiguration.tsx | 58 +++++++------------ tests/TMTVCSVReport.spec.ts | 1 - tests/TMTVSUV.spec.ts | 58 +++++++++++++++++++ 3 files changed, 78 insertions(+), 39 deletions(-) create mode 100644 tests/TMTVSUV.spec.ts diff --git a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/ROIThresholdConfiguration.tsx b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/ROIThresholdConfiguration.tsx index c03750013..31ae76b39 100644 --- a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/ROIThresholdConfiguration.tsx +++ b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/ROIThresholdConfiguration.tsx @@ -22,6 +22,19 @@ const options = [ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { const { t } = useTranslation('ROIThresholdConfiguration'); + const handlePercentageOfMaxSUVChange = (e: React.ChangeEvent) => { + let value = e.target.value; + + if (value === '.') { + value = '0.'; + } + + if (isNaN(Number(value)) || Number(value) < 0 || Number(value) > 1) { + return; + } + dispatch({ type: 'setWeight', payload: { weight: value } }); + }; + return (
@@ -32,12 +45,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { { - dispatch({ - type: 'setWeight', - payload: { - weight: e.target.value, - }, - }); - }} + onChange={handlePercentageOfMaxSUVChange} />
)} @@ -113,12 +115,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { type="text" value={config.ctLower} onChange={e => { - dispatch({ - type: 'setThreshold', - payload: { - ctLower: e.target.value, - }, - }); + dispatch({ type: 'setThreshold', payload: { ctLower: e.target.value } }); }} />
@@ -128,12 +125,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { type="text" value={config.ctUpper} onChange={e => { - dispatch({ - type: 'setThreshold', - payload: { - ctUpper: e.target.value, - }, - }); + dispatch({ type: 'setThreshold', payload: { ctUpper: e.target.value } }); }} /> @@ -152,12 +144,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { type="text" value={config.ptLower} onChange={e => { - dispatch({ - type: 'setThreshold', - payload: { - ptLower: e.target.value, - }, - }); + dispatch({ type: 'setThreshold', payload: { ptLower: e.target.value } }); }} /> @@ -167,12 +154,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) { type="text" value={config.ptUpper} onChange={e => { - dispatch({ - type: 'setThreshold', - payload: { - ptUpper: e.target.value, - }, - }); + dispatch({ type: 'setThreshold', payload: { ptUpper: e.target.value } }); }} /> diff --git a/tests/TMTVCSVReport.spec.ts b/tests/TMTVCSVReport.spec.ts index 770e961aa..fc472fe1a 100644 --- a/tests/TMTVCSVReport.spec.ts +++ b/tests/TMTVCSVReport.spec.ts @@ -2,7 +2,6 @@ import { test, expect } from 'playwright-test-coverage'; import { visitStudy, simulateNormalizedClickOnElement } from './utils/index'; import { viewportLocator } from './utils/locators'; import { downloadAsString } from './utils/download'; -import toArray from 'extensions/dicom-microscopy/src/utils/toArray'; test('should create and download the TMTV CSV report correctly', async ({ page }) => { const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501'; diff --git a/tests/TMTVSUV.spec.ts b/tests/TMTVSUV.spec.ts new file mode 100644 index 000000000..552847398 --- /dev/null +++ b/tests/TMTVSUV.spec.ts @@ -0,0 +1,58 @@ +import { test, expect } from 'playwright-test-coverage'; +import { visitStudy, simulateNormalizedClickOnElement } from './utils/index'; +import { viewportLocator } from './utils/locators'; +import { downloadAsString } from './utils/download'; + +test('should restrict the percentage of max SUV to be between 0 and 1', async ({ page }) => { + const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501'; + const mode = 'tmtv'; + await visitStudy(page, studyInstanceUID, mode, 10000); + + await viewportLocator({ viewportId: 'ptAXIAL', page }).click(); + + await page.getByTestId('addSegmentation').click(); + await page.getByTestId('RectangleROIStartEndThreshold-btn').click(); + + await page.getByTestId('percentage-of-max-suv-input').fill('0'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0'); + + await page.getByTestId('percentage-of-max-suv-input').fill('0.27'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.27'); + + await page.getByTestId('percentage-of-max-suv-input').fill('0.9467'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.9467'); + + await page.getByTestId('percentage-of-max-suv-input').fill('.'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.'); + + await page.getByTestId('percentage-of-max-suv-input').fill('1'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('1'); + + await page.getByTestId('percentage-of-max-suv-input').fill('1.1'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('1'); + + await page.getByTestId('percentage-of-max-suv-input').fill('1806'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('1'); + + await page.getByTestId('percentage-of-max-suv-input').fill(''); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe(''); + + // Add some valid input for the tests that follow. Note that when invalid input is + // entered the previous valid input is retained. + await page.getByTestId('percentage-of-max-suv-input').fill('0.275'); + + await page.getByTestId('percentage-of-max-suv-input').fill('9'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.275'); + + await page.getByTestId('percentage-of-max-suv-input').fill('-678'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.275'); + + await page.getByTestId('percentage-of-max-suv-input').fill('+'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.275'); + + await page.getByTestId('percentage-of-max-suv-input').fill('-'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.275'); + + await page.getByTestId('percentage-of-max-suv-input').fill('e'); + expect(await page.getByTestId('percentage-of-max-suv-input').inputValue()).toBe('0.275'); +});