From c0f20bd2bf7bbe2c731db1c8a139ce8acbc14d1a Mon Sep 17 00:00:00 2001 From: MarcosPierasNL <pieras.marcos@gmail.com> Date: Wed, 19 Mar 2025 12:01:43 +0100 Subject: [PATCH] test: adds validation on type of insights --- src/readers/insightProcessor.ts | 5 + .../insights/validateTypeInsight.test.ts | 93 +++++++++++++++++++ src/utils/insights/validateInsight.ts | 5 - src/utils/insights/validateTypeInsight.ts | 46 +++++++++ 4 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 src/tests/insights/validateTypeInsight.test.ts create mode 100644 src/utils/insights/validateTypeInsight.ts diff --git a/src/readers/insightProcessor.ts b/src/readers/insightProcessor.ts index 986a028..777c620 100644 --- a/src/readers/insightProcessor.ts +++ b/src/readers/insightProcessor.ts @@ -13,6 +13,7 @@ import { VariableNode } from '../utils/lexical'; import { populateTemplate } from '../utils/insights'; import { RabbitMqBroker } from 'ts-common/rabbitMq'; import { validateInsight } from '../utils/insights/validateInsight'; +import { validateTypeInsight } from '../utils/insights/validateTypeInsight'; const dom = new JSDOM(); function setUpDom() { @@ -58,6 +59,10 @@ export const insightProcessor = async () => { return; } + if (!validateTypeInsight(insight, message.force)) { + return; + } + log.info('Received insight to be processed', insight); const editor = createHeadlessEditor({ diff --git a/src/tests/insights/validateTypeInsight.test.ts b/src/tests/insights/validateTypeInsight.test.ts new file mode 100644 index 0000000..0cf8df1 --- /dev/null +++ b/src/tests/insights/validateTypeInsight.test.ts @@ -0,0 +1,93 @@ +import { describe, it, expect } from 'vitest'; +import { validateTypeInsight } from '../../utils/insights/validateTypeInsight'; +import { Logger } from 'ts-common'; +import type { InsightModel, AlarmModes, conditionalOperators } from 'ts-common'; + +Logger.excludedOwners.push('ts-common'); +Logger.excludedOwners.push('query-service'); + +describe('validateTypeInsight', () => { + const baseInsight: InsightModel = { + id: 1, + name: 'Test Insight', + description: 'A test insight for validation', + recipients: [], + template: 'default', + conditionsCheck: [], + frequency: 'daily', + previousResultHash: 'hash', + createdAt: '', + updatedAt: '', + saveStateId: '', + type: 'report', + alarmMode: 'conditional', + }; + + it('should return false when alarmMode is "disabled" and force is false', () => { + const insight = { ...baseInsight, alarmMode: 'disabled' as AlarmModes }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(false); + }); + + it('should return true when alarmMode is "disabled" and force is true', () => { + const insight = { ...baseInsight, alarmMode: 'disabled' as AlarmModes }; + const result = validateTypeInsight(insight, true); + expect(result).toBe(true); + }); + + it('should return false when conditionsCheck is empty in "conditional" alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'conditional' as AlarmModes, conditionsCheck: [] }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(false); + }); + + it('should return false when a condition is invalid in "conditional" alarmMode', () => { + const insight = { + ...baseInsight, + alarmMode: 'conditional' as AlarmModes, + conditionsCheck: [{ nodeLabel: '', statistic: 'average', operator: '>' as conditionalOperators, value: 10 }], + }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(false); + }); + + it('should return true when all conditions are valid in "conditional" alarmMode', () => { + const insight = { + ...baseInsight, + alarmMode: 'conditional' as AlarmModes, + conditionsCheck: [{ nodeLabel: 'label', statistic: 'average', operator: '>' as conditionalOperators, value: 10 }], + }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(true); + }); + + it('should return false when frequency or previousResultHash is missing in "diff" alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'diff' as AlarmModes, frequency: '', previousResultHash: '' }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(false); + }); + + it('should return true when frequency and previousResultHash are provided in "diff" alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'diff' as AlarmModes, frequency: 'daily', previousResultHash: 'hash' }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(true); + }); + + it('should return false when frequency is missing in "always" alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'always' as AlarmModes, frequency: '' }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(false); + }); + + it('should return true when frequency is provided in "always" alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'always' as AlarmModes, frequency: 'daily' }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(true); + }); + + it('should return true for unknown alarmMode', () => { + const insight = { ...baseInsight, alarmMode: 'unknown' as any }; + const result = validateTypeInsight(insight, false); + expect(result).toBe(true); + }); +}); diff --git a/src/utils/insights/validateInsight.ts b/src/utils/insights/validateInsight.ts index 6d04fa7..e8efc8d 100644 --- a/src/utils/insights/validateInsight.ts +++ b/src/utils/insights/validateInsight.ts @@ -7,11 +7,6 @@ export function validateInsight(insight: InsightModel, force: boolean) { return false; } - if (insight.alarmMode === 'disabled' && !force) { - log.debug('Alarm mode is disabled', insight.id); - return false; - } - if (!insight.recipients || insight.recipients.length === 0) { log.debug('No recipients found in the insight, skipping'); return false; diff --git a/src/utils/insights/validateTypeInsight.ts b/src/utils/insights/validateTypeInsight.ts new file mode 100644 index 0000000..27482f6 --- /dev/null +++ b/src/utils/insights/validateTypeInsight.ts @@ -0,0 +1,46 @@ +import { type InsightModel } from 'ts-common'; +import { log } from '../../logger'; + +export function validateTypeInsight(insight: InsightModel, force: boolean) { + switch (insight.alarmMode) { + case 'disabled': + if (!force) { + log.debug('Alarm mode is disabled', insight.id); + return false; + } else { + return true; + } + + case 'conditional': + if (!insight.conditionsCheck || insight.conditionsCheck.length === 0) { + log.error('No conditions found in Insight conditionsCheck'); + return false; + } + for (const condition of insight.conditionsCheck) { + // TODO! remove property from insight conditional model + if (!condition.nodeLabel || !condition.statistic || !condition.operator || condition.value === undefined) { + log.error('Invalid condition found:', condition); + return false; + } + } + return true; + + case 'diff': + if (!insight.frequency) { + log.error('No frequency found in Insight frequency: ', insight.frequency); + return true; + } else { + return true; + } + case 'always': + if (!insight.frequency) { + log.error('No frequency found in Insight frequency: ', insight.frequency); + return false; + } else { + return true; + } + + default: + return true; + } +} -- GitLab