mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: trim name and description before validation (#8275)
This fixes a bug where you can input just whitespace for name/description. It also means that you can no longer have both "my role" and "my role " as separate roles. API fix will follow.
This commit is contained in:
		
							parent
							
								
									eb01b44e69
								
							
						
					
					
						commit
						e20ef56374
					
				| @ -28,10 +28,10 @@ const StyledInputFullWidth = styled(Input)({ | |||||||
| interface IRoleFormProps { | interface IRoleFormProps { | ||||||
|     type?: PredefinedRoleType; |     type?: PredefinedRoleType; | ||||||
|     name: string; |     name: string; | ||||||
|     setName: React.Dispatch<React.SetStateAction<string>>; |     setName: (name: string) => void; | ||||||
|     validateName: (name: string) => boolean; |     validateName: (name: string) => boolean; | ||||||
|     description: string; |     description: string; | ||||||
|     setDescription: React.Dispatch<React.SetStateAction<string>>; |     setDescription: (description: string) => void; | ||||||
|     validateDescription: (description: string) => boolean; |     validateDescription: (description: string) => boolean; | ||||||
|     checkedPermissions: ICheckedPermissions; |     checkedPermissions: ICheckedPermissions; | ||||||
|     setCheckedPermissions: React.Dispatch< |     setCheckedPermissions: React.Dispatch< | ||||||
|  | |||||||
| @ -0,0 +1,50 @@ | |||||||
|  | import { renderHook } from '@testing-library/react'; | ||||||
|  | import { useRoleForm } from './useRoleForm'; | ||||||
|  | import { act } from 'react-test-renderer'; | ||||||
|  | import { test } from 'vitest'; | ||||||
|  | 
 | ||||||
|  | describe('trim names and description', () => { | ||||||
|  |     test('name is trimmed before being set', () => { | ||||||
|  |         const { result } = renderHook(() => useRoleForm()); | ||||||
|  | 
 | ||||||
|  |         act(() => { | ||||||
|  |             result.current.setName('  my role    '); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(result.current.name).toBe('my role'); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('description is trimmed before being set', () => { | ||||||
|  |         const { result } = renderHook(() => useRoleForm()); | ||||||
|  | 
 | ||||||
|  |         act(() => { | ||||||
|  |             result.current.setDescription('  my description    '); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(result.current.description).toBe('my description'); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('name that is just whitespace triggers an error', () => { | ||||||
|  |         const { result } = renderHook(() => useRoleForm()); | ||||||
|  | 
 | ||||||
|  |         act(() => { | ||||||
|  |             result.current.validateName('    '); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(result.current.errors).toMatchObject({ | ||||||
|  |             name: 'Name is required.', | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     test('description that is just whitespace triggers an error', () => { | ||||||
|  |         const { result } = renderHook(() => useRoleForm()); | ||||||
|  | 
 | ||||||
|  |         act(() => { | ||||||
|  |             result.current.validateDescription('    '); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(result.current.errors).toMatchObject({ | ||||||
|  |             description: 'Description is required.', | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
| @ -27,7 +27,10 @@ export const useRoleForm = ( | |||||||
|     const { roles, projectRoles } = useRoles(); |     const { roles, projectRoles } = useRoles(); | ||||||
| 
 | 
 | ||||||
|     const [name, setName] = useState(initialName); |     const [name, setName] = useState(initialName); | ||||||
|  |     const setTrimmedName = (newName: string) => setName(newName.trim()); | ||||||
|     const [description, setDescription] = useState(initialDescription); |     const [description, setDescription] = useState(initialDescription); | ||||||
|  |     const setTrimmedDescription = (newDescription: string) => | ||||||
|  |         setDescription(newDescription.trim()); | ||||||
|     const [checkedPermissions, setCheckedPermissions] = |     const [checkedPermissions, setCheckedPermissions] = | ||||||
|         useState<ICheckedPermissions>({}); |         useState<ICheckedPermissions>({}); | ||||||
|     const [errors, setErrors] = useState<IRoleFormErrors>(DEFAULT_ERRORS); |     const [errors, setErrors] = useState<IRoleFormErrors>(DEFAULT_ERRORS); | ||||||
| @ -78,12 +81,13 @@ export const useRoleForm = ( | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const validateName = (name: string) => { |     const validateName = (name: string) => { | ||||||
|         if (!isNotEmpty(name)) { |         const trimmedName = name.trim(); | ||||||
|  |         if (!isNotEmpty(trimmedName)) { | ||||||
|             setError(ErrorField.NAME, 'Name is required.'); |             setError(ErrorField.NAME, 'Name is required.'); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!isNameUnique(name)) { |         if (!isNameUnique(trimmedName)) { | ||||||
|             setError(ErrorField.NAME, 'Name must be unique.'); |             setError(ErrorField.NAME, 'Name must be unique.'); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| @ -93,7 +97,8 @@ export const useRoleForm = ( | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     const validateDescription = (description: string) => { |     const validateDescription = (description: string) => { | ||||||
|         if (!isNotEmpty(description)) { |         const trimmedDescription = description.trim(); | ||||||
|  |         if (!isNotEmpty(trimmedDescription)) { | ||||||
|             setError(ErrorField.DESCRIPTION, 'Description is required.'); |             setError(ErrorField.DESCRIPTION, 'Description is required.'); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| @ -139,10 +144,10 @@ export const useRoleForm = ( | |||||||
| 
 | 
 | ||||||
|     return { |     return { | ||||||
|         name, |         name, | ||||||
|         setName, |         setName: setTrimmedName, | ||||||
|         validateName, |         validateName, | ||||||
|         description, |         description, | ||||||
|         setDescription, |         setDescription: setTrimmedDescription, | ||||||
|         validateDescription, |         validateDescription, | ||||||
|         checkedPermissions, |         checkedPermissions, | ||||||
|         setCheckedPermissions, |         setCheckedPermissions, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user