From 031b4dee1e72b161a0227ead3a539ba38df513bc Mon Sep 17 00:00:00 2001 From: RaenonX Date: Thu, 5 Aug 2021 14:48:12 -0500 Subject: [PATCH] ADD - Validation for duplicated unit names (#188) Signed-off-by: RaenonX --- src/components/pages/gameData/nameRef/entry.tsx | 11 ++++++----- .../pages/gameData/nameRef/main.test.tsx | 13 +++++++++++++ src/components/pages/gameData/nameRef/manage.tsx | 16 ++++++++++++++-- test/data/resources | 2 +- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/components/pages/gameData/nameRef/entry.tsx b/src/components/pages/gameData/nameRef/entry.tsx index 9b40c23a..33a9d47d 100644 --- a/src/components/pages/gameData/nameRef/entry.tsx +++ b/src/components/pages/gameData/nameRef/entry.tsx @@ -14,9 +14,10 @@ import {ArrayDataFormOnChangedHandler} from '../../../elements/posts/form/array' type UnitNameRefEntryProps = { entry: UnitNameRefEntryApi, onChanged: ArrayDataFormOnChangedHandler, + isNameInvalid: boolean, } -export const UnitNameRefEntry = ({entry, onChanged}: UnitNameRefEntryProps) => { +export const UnitNameRefEntry = ({entry, onChanged, isNameInvalid}: UnitNameRefEntryProps) => { const {t, lang} = useI18n(); const {unitInfoMap} = useUnitInfo(); @@ -25,7 +26,7 @@ export const UnitNameRefEntry = ({entry, onChanged}: UnitNameRefEntryProps) => { // This is the height of `form-control` const unitIconHeight = 'calc(1.5em + 0.75rem + 2px)'; - const isValid = !!unitInfo; + const isNameInputAllowed = !!unitInfo; return (
@@ -33,7 +34,7 @@ export const UnitNameRefEntry = ({entry, onChanged}: UnitNameRefEntryProps) => { {t((t) => t.game.nameRef.unitId)} { if (Number(e.target.value) || !e.target.value) { onChanged('unitId')(+e.target.value); @@ -70,8 +71,8 @@ export const UnitNameRefEntry = ({entry, onChanged}: UnitNameRefEntryProps) => { {t((t) => t.game.nameRef.desiredName)} onChanged('name')(e.target.value)} - isInvalid={!entry.name} - disabled={!isValid} + isInvalid={!entry.name || isNameInvalid} + disabled={!isNameInputAllowed} value={entry.name} /> diff --git a/src/components/pages/gameData/nameRef/main.test.tsx b/src/components/pages/gameData/nameRef/main.test.tsx index ca2ec4d6..0a285060 100644 --- a/src/components/pages/gameData/nameRef/main.test.tsx +++ b/src/components/pages/gameData/nameRef/main.test.tsx @@ -236,4 +236,17 @@ describe('Name reference management', () => { typeInput(unitIdInput, '10950101', {rerender}); expect(updateButton).toBeEnabled(); }); + + it('disables update if multiple units share the same name', async () => { + const {rerender} = renderReact(() => , {hasSession: true, user: {isAdmin: true}}); + + const unitNameInput = await screen.findByDisplayValue('Furis'); + userEvent.clear(unitNameInput); + typeInput(unitNameInput, 'G!Leon', {rerender}); + + await waitFor(() => expect(unitNameInput).toHaveClass('is-invalid')); + + const updateButton = screen.getByText(translationEN.misc.update); + expect(updateButton).toBeDisabled(); + }); }); diff --git a/src/components/pages/gameData/nameRef/manage.tsx b/src/components/pages/gameData/nameRef/manage.tsx index 9e994734..0738049b 100644 --- a/src/components/pages/gameData/nameRef/manage.tsx +++ b/src/components/pages/gameData/nameRef/manage.tsx @@ -10,6 +10,7 @@ import { UnitNameRefEntry as UnitNameRefEntryApi, ApiResponseCodeUtil, } from '../../../../api-def/api'; import {useI18n} from '../../../../i18n/hook'; +import {getElementCounter} from '../../../../utils/counter'; import {overrideObject} from '../../../../utils/override'; import {ApiRequestSender} from '../../../../utils/services/api/requestSender'; import {useUnitInfo} from '../../../../utils/services/resources/unitInfo/hooks'; @@ -40,7 +41,13 @@ export const UnitNameRefManagement = ({refs, uid}: RefsManagementProps) => { isInit: true, }); const {unitInfoMap} = useUnitInfo(); - const isValid = refsStatus.refs.every((entry) => !!unitInfoMap.get(entry.unitId) && !!entry.name); + + const nameCounter = getElementCounter(refsStatus.refs.map((ref) => ref.name)); + + const isValid = ( + refsStatus.refs.every((entry) => !!unitInfoMap.get(entry.unitId) && !!entry.name) && + [...nameCounter.values()].every((count) => count === 1) + ); const isJustUpdated = !!refsStatus.updateStatus && ApiResponseCodeUtil.isSuccess(refsStatus.updateStatus); const generateNewElement: () => UnitNameRefEntryApi = () => ({ @@ -80,7 +87,12 @@ export const UnitNameRefManagement = ({refs, uid}: RefsManagementProps) => { [key]: newValue, })} generateNewElement={generateNewElement} - renderEntries={(element, onChange) => } + renderEntries={(element, onChange) => ( + 1} + /> + )} />
diff --git a/test/data/resources b/test/data/resources index 23210e48..cd974e6b 160000 --- a/test/data/resources +++ b/test/data/resources @@ -1 +1 @@ -Subproject commit 23210e48c0c96bad25250e7c02d93ec9874cd33b +Subproject commit cd974e6ba6501bea532d86c06b09c45b2016cf36