@@ -9,6 +9,13 @@ import '@testing-library/jest-dom/extend-expect';
99import { MemoryRouter } from 'react-router-dom' ;
1010import Configuration from './Configuration' ;
1111import { DataSourceContext } from '../TopNQueries/TopNQueries' ;
12+ import { TIME_UNITS_TEXT , EXPORTER_TYPE } from '../../../common/constants' ;
13+ import {
14+ validateTopNSize ,
15+ validateWindowSize ,
16+ validateDeleteAfterDays ,
17+ validateConfiguration ,
18+ } from './configurationValidation' ;
1219
1320const mockConfigInfo = jest . fn ( ) ;
1421const mockCoreStart = {
@@ -145,4 +152,183 @@ describe('Configuration Component', () => {
145152 fireEvent . click ( screen . getByText ( 'Cancel' ) ) ;
146153 expect ( getTopNSizeConfiguration ( ) [ 0 ] ) . toHaveValue ( 5 ) ; // Resets to initial value
147154 } ) ;
155+
156+ describe ( 'Validation Logic Tests' , ( ) => {
157+ describe ( 'TopN Size Validation' , ( ) => {
158+ it ( 'should hide Save button when topN size is less than 1' , ( ) => {
159+ renderConfiguration ( ) ;
160+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '0' } } ) ;
161+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
162+ } ) ;
163+
164+ it ( 'should hide Save button when topN size is greater than 100' , ( ) => {
165+ renderConfiguration ( ) ;
166+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '101' } } ) ;
167+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
168+ } ) ;
169+
170+ it ( 'should show Save button when topN size is within valid range (1-100)' , ( ) => {
171+ renderConfiguration ( ) ;
172+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '50' } } ) ;
173+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
174+ } ) ;
175+ } ) ;
176+
177+ describe ( 'Window Size Validation - Minutes' , ( ) => {
178+ it ( 'should hide Save button when window size is empty for minutes' , ( ) => {
179+ renderConfiguration ( ) ;
180+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
181+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 2 ] , { target : { value : 'MINUTES' } } ) ;
182+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 1 ] , { target : { value : '' } } ) ;
183+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
184+ } ) ;
185+
186+ it ( 'should hide Save button when window size is NaN for minutes' , ( ) => {
187+ renderConfiguration ( ) ;
188+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
189+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 2 ] , { target : { value : 'MINUTES' } } ) ;
190+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 1 ] , { target : { value : 'invalid' } } ) ;
191+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
192+ } ) ;
193+
194+ it ( 'should show Save button when window size is valid for minutes' , ( ) => {
195+ renderConfiguration ( ) ;
196+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
197+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 2 ] , { target : { value : 'MINUTES' } } ) ;
198+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 1 ] , { target : { value : '5' } } ) ;
199+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
200+ } ) ;
201+ } ) ;
202+
203+ describe ( 'Window Size Validation - Hours' , ( ) => {
204+ it ( 'should show Save button when window size is within valid range (1-24) for hours' , ( ) => {
205+ renderConfiguration ( ) ;
206+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
207+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 2 ] , { target : { value : 'HOURS' } } ) ;
208+ fireEvent . change ( getWindowSizeConfigurations ( ) [ 1 ] , { target : { value : '12' } } ) ;
209+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
210+ } ) ;
211+ } ) ;
212+
213+ describe ( 'Delete After Days Validation' , ( ) => {
214+ it ( 'should hide Save button when delete after days is less than 1 for local index' , ( ) => {
215+ renderConfiguration ( ) ;
216+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
217+ const deleteAfterField = getTopNSizeConfiguration ( ) [ 1 ] ;
218+ fireEvent . change ( deleteAfterField , { target : { value : '0' } } ) ;
219+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
220+ } ) ;
221+
222+ it ( 'should hide Save button when delete after days is greater than 180 for local index' , ( ) => {
223+ renderConfiguration ( ) ;
224+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
225+ const deleteAfterField = getTopNSizeConfiguration ( ) [ 1 ] ;
226+ fireEvent . change ( deleteAfterField , { target : { value : '181' } } ) ;
227+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
228+ } ) ;
229+
230+ it ( 'should show Save button when delete after days is within valid range (1-180) for local index' , ( ) => {
231+ renderConfiguration ( ) ;
232+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
233+ const deleteAfterField = getTopNSizeConfiguration ( ) [ 1 ] ;
234+ fireEvent . change ( deleteAfterField , { target : { value : '90' } } ) ;
235+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
236+ } ) ;
237+
238+ it ( 'should show Save button when exporter is changed to none' , ( ) => {
239+ renderConfiguration ( ) ;
240+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '6' } } ) ;
241+ fireEvent . change ( screen . getByDisplayValue ( 'Local Index' ) , { target : { value : 'none' } } ) ;
242+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
243+ } ) ;
244+ } ) ;
245+
246+ describe ( 'Combined Validation Scenarios' , ( ) => {
247+ it ( 'should hide Save button when multiple validation rules fail' , ( ) => {
248+ renderConfiguration ( ) ;
249+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '101' } } ) ;
250+ expect ( screen . queryByText ( 'Save' ) ) . not . toBeInTheDocument ( ) ;
251+ } ) ;
252+
253+ it ( 'should show Save button when all validation rules pass' , ( ) => {
254+ renderConfiguration ( ) ;
255+ fireEvent . change ( getTopNSizeConfiguration ( ) [ 0 ] , { target : { value : '25' } } ) ;
256+ expect ( screen . getByText ( 'Save' ) ) . toBeInTheDocument ( ) ;
257+ } ) ;
258+ } ) ;
259+ } ) ;
260+
261+ describe ( 'Validation Utility Functions' , ( ) => {
262+ describe ( 'validateTopNSize' , ( ) => {
263+ it ( 'should return false for values less than 1' , ( ) => {
264+ expect ( validateTopNSize ( '0' ) ) . toBe ( false ) ;
265+ expect ( validateTopNSize ( '-1' ) ) . toBe ( false ) ;
266+ } ) ;
267+
268+ it ( 'should return false for values greater than 100' , ( ) => {
269+ expect ( validateTopNSize ( '101' ) ) . toBe ( false ) ;
270+ expect ( validateTopNSize ( '200' ) ) . toBe ( false ) ;
271+ } ) ;
272+
273+ it ( 'should return true for valid values (1-100)' , ( ) => {
274+ expect ( validateTopNSize ( '1' ) ) . toBe ( true ) ;
275+ expect ( validateTopNSize ( '50' ) ) . toBe ( true ) ;
276+ expect ( validateTopNSize ( '100' ) ) . toBe ( true ) ;
277+ } ) ;
278+
279+ it ( 'should return false for non-numeric strings' , ( ) => {
280+ expect ( validateTopNSize ( 'abc' ) ) . toBe ( false ) ;
281+ expect ( validateTopNSize ( '' ) ) . toBe ( false ) ;
282+ expect ( validateTopNSize ( '10.5' ) ) . toBe ( false ) ;
283+ } ) ;
284+ } ) ;
285+
286+ describe ( 'validateWindowSize' , ( ) => {
287+ it ( 'should validate minutes correctly' , ( ) => {
288+ const minutesUnit = TIME_UNITS_TEXT [ 0 ] . value ;
289+ expect ( validateWindowSize ( '' , minutesUnit ) ) . toBe ( false ) ;
290+ expect ( validateWindowSize ( 'abc' , minutesUnit ) ) . toBe ( false ) ;
291+ expect ( validateWindowSize ( '1' , minutesUnit ) ) . toBe ( true ) ;
292+ expect ( validateWindowSize ( '30' , minutesUnit ) ) . toBe ( true ) ;
293+ } ) ;
294+
295+ it ( 'should validate hours correctly' , ( ) => {
296+ const hoursUnit = TIME_UNITS_TEXT [ 1 ] . value ;
297+ expect ( validateWindowSize ( '0' , hoursUnit ) ) . toBe ( false ) ;
298+ expect ( validateWindowSize ( '25' , hoursUnit ) ) . toBe ( false ) ;
299+ expect ( validateWindowSize ( '1' , hoursUnit ) ) . toBe ( true ) ;
300+ expect ( validateWindowSize ( '24' , hoursUnit ) ) . toBe ( true ) ;
301+ } ) ;
302+ } ) ;
303+
304+ describe ( 'validateDeleteAfterDays' , ( ) => {
305+ it ( 'should validate local index correctly' , ( ) => {
306+ const localIndexType = EXPORTER_TYPE . localIndex ;
307+ expect ( validateDeleteAfterDays ( '0' , localIndexType ) ) . toBe ( false ) ;
308+ expect ( validateDeleteAfterDays ( '181' , localIndexType ) ) . toBe ( false ) ;
309+ expect ( validateDeleteAfterDays ( '1' , localIndexType ) ) . toBe ( true ) ;
310+ expect ( validateDeleteAfterDays ( '180' , localIndexType ) ) . toBe ( true ) ;
311+ } ) ;
312+
313+ it ( 'should return true for non-local index' , ( ) => {
314+ const noneType = EXPORTER_TYPE . none ;
315+ expect ( validateDeleteAfterDays ( '0' , noneType ) ) . toBe ( true ) ;
316+ expect ( validateDeleteAfterDays ( 'abc' , noneType ) ) . toBe ( true ) ;
317+ } ) ;
318+ } ) ;
319+
320+ describe ( 'validateConfiguration' , ( ) => {
321+ it ( 'should return false when any validation fails' , ( ) => {
322+ expect ( validateConfiguration ( '101' , '5' , 'MINUTES' , '30' , EXPORTER_TYPE . localIndex ) ) . toBe (
323+ false
324+ ) ;
325+ expect ( validateConfiguration ( '50' , '' , 'MINUTES' , '30' , EXPORTER_TYPE . localIndex ) ) . toBe (
326+ false
327+ ) ;
328+ expect ( validateConfiguration ( '50' , '5' , 'MINUTES' , '181' , EXPORTER_TYPE . localIndex ) ) . toBe (
329+ false
330+ ) ;
331+ } ) ;
332+ } ) ;
333+ } ) ;
148334} ) ;
0 commit comments