diff --git a/ui/src/shared/components/dropdown_auto_refresh/autoRefreshOptions.ts b/ui/src/shared/components/dropdown_auto_refresh/autoRefreshOptions.ts index 9527d027e..c1b97bfe8 100644 --- a/ui/src/shared/components/dropdown_auto_refresh/autoRefreshOptions.ts +++ b/ui/src/shared/components/dropdown_auto_refresh/autoRefreshOptions.ts @@ -17,7 +17,7 @@ export const autoRefreshOptionPaused: AutoRefreshOption = { type: AutoRefreshOptionType.Option, } -let autoRefreshOptions: AutoRefreshOption[] = [ +const defaultAutoRefreshOptions: AutoRefreshOption[] = [ { id: 'auto-refresh-header', milliseconds: 9999, @@ -56,22 +56,27 @@ let autoRefreshOptions: AutoRefreshOption[] = [ type: AutoRefreshOptionType.Option, }, ] +let autoRefreshOptions = [...defaultAutoRefreshOptions] /** setCustomAutoRefreshOptions allows to set custom auto-refresh options */ export function setCustomAutoRefreshOptions(customSpec: string | undefined) { - if (!customSpec) { + if (customSpec === undefined) { return } - // 1st filter all custom options - autoRefreshOptions = autoRefreshOptions.filter(x => x.id.startsWith('custom')) - const [header, paused, ...other] = autoRefreshOptions + const [header, paused, ...otherDefault] = defaultAutoRefreshOptions const customOptions: AutoRefreshOption[] = customSpec .split(',') .reduce((acc, singleSpec) => { + if (!singleSpec) { + return acc // ignore empty values + } try { - const [a, b] = singleSpec.split['='] + const [a, b] = singleSpec.split('=') const label = a.trim() const milliseconds = parseInt(b, 10) + if (!(milliseconds >= 100)) { + throw new Error('Miliseconds is not a positive number >= 100') + } acc.push({ id: `custom-refresh-${label}`, milliseconds, @@ -80,16 +85,16 @@ export function setCustomAutoRefreshOptions(customSpec: string | undefined) { }) } catch (e) { console.warn( - 'Unable to parse custom autoRefreshOption, it should have format `label=milliseconds`', - e + `Ignoring custom autoRefreshOption "${singleSpec}", it must have format label=milliseconds !, e + }` ) } return acc }, [] as AutoRefreshOption[]) - return [ + autoRefreshOptions = [ header, paused, - [...other, ...customOptions].sort( + ...[...otherDefault, ...customOptions].sort( (a, b) => a.milliseconds - b.milliseconds ), ] diff --git a/ui/test/shared/components/dropdown_auto_refresh/autoRefreshOptions.test.ts b/ui/test/shared/components/dropdown_auto_refresh/autoRefreshOptions.test.ts new file mode 100644 index 000000000..16aab7133 --- /dev/null +++ b/ui/test/shared/components/dropdown_auto_refresh/autoRefreshOptions.test.ts @@ -0,0 +1,197 @@ +import { + autoRefreshOptionPaused, + AutoRefreshOptionType, + getAutoRefreshOptions, + setCustomAutoRefreshOptions, +} from 'src/shared/components/dropdown_auto_refresh/autoRefreshOptions' + +describe('setCustomAutoRefreshOptions', () => { + beforeEach(() => { + // remove all custom refresh options + setCustomAutoRefreshOptions('') + }) + it('returns unchanged auto-refresh options withou customization', () => { + const previousOpts = [...getAutoRefreshOptions()] + setCustomAutoRefreshOptions(undefined) + const newOpts = [...getAutoRefreshOptions()] + + expect(newOpts).toEqual(previousOpts) + }) + it('returns sorted auto-refresh options with single customization', () => { + setCustomAutoRefreshOptions('12s=12000') + const newOpts = getAutoRefreshOptions() + expect(newOpts).toEqual([ + { + id: 'auto-refresh-header', + milliseconds: 9999, + label: 'Refresh', + type: AutoRefreshOptionType.Header, + }, + autoRefreshOptionPaused, + { + id: 'auto-refresh-5s', + milliseconds: 5000, + label: '5s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-10s', + milliseconds: 10000, + label: '10s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'custom-refresh-12s', + milliseconds: 12000, + label: '12s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-15s', + milliseconds: 15000, + label: '15s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-30s', + milliseconds: 30000, + label: '30s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-60s', + milliseconds: 60000, + label: '60s', + type: AutoRefreshOptionType.Option, + }, + ]) + }) + it('returns sorted auto-refresh options with more customizations', () => { + setCustomAutoRefreshOptions('500ms=500,12s=12000,5m=300000') + const newOpts = getAutoRefreshOptions() + expect(newOpts).toEqual([ + { + id: 'auto-refresh-header', + milliseconds: 9999, + label: 'Refresh', + type: AutoRefreshOptionType.Header, + }, + autoRefreshOptionPaused, + { + id: 'custom-refresh-500ms', + milliseconds: 500, + label: '500ms', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-5s', + milliseconds: 5000, + label: '5s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-10s', + milliseconds: 10000, + label: '10s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'custom-refresh-12s', + milliseconds: 12000, + label: '12s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-15s', + milliseconds: 15000, + label: '15s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-30s', + milliseconds: 30000, + label: '30s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-60s', + milliseconds: 60000, + label: '60s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'custom-refresh-5m', + milliseconds: 300000, + label: '5m', + type: AutoRefreshOptionType.Option, + }, + ]) + }) + it('ignores empty or invalid customization parts', () => { + let warnings = 0 + const origConsoleWarn = console.warn + console.warn = () => (warnings += 1) + try { + setCustomAutoRefreshOptions(' 12s=12000, ,a=, b=10') + const newOpts = getAutoRefreshOptions() + expect(warnings).toBe(3) // '','a=','b=10' + expect(newOpts).toEqual([ + { + id: 'auto-refresh-header', + milliseconds: 9999, + label: 'Refresh', + type: AutoRefreshOptionType.Header, + }, + autoRefreshOptionPaused, + { + id: 'auto-refresh-5s', + milliseconds: 5000, + label: '5s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-10s', + milliseconds: 10000, + label: '10s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'custom-refresh-12s', + milliseconds: 12000, + label: '12s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-15s', + milliseconds: 15000, + label: '15s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-30s', + milliseconds: 30000, + label: '30s', + type: AutoRefreshOptionType.Option, + }, + { + id: 'auto-refresh-60s', + milliseconds: 60000, + label: '60s', + type: AutoRefreshOptionType.Option, + }, + ]) + } finally { + console.warn(origConsoleWarn) + } + }) + it('removes all custom auto refresh intervals with empty spec', () => { + // setting empty spec reset customizations + const origSize = getAutoRefreshOptions().length + setCustomAutoRefreshOptions('12s=12000,5m=300000') + const opts1 = getAutoRefreshOptions() + expect(opts1.length).toBe(origSize + 2) + setCustomAutoRefreshOptions('') + const opts2 = getAutoRefreshOptions() + expect(opts2.length).toBe(origSize) + }) +})