@oneuptime/common 9.4.7 → 9.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Alert.ts +76 -0
- package/Models/DatabaseModels/AlertEpisode.ts +1201 -0
- package/Models/DatabaseModels/AlertEpisodeFeed.ts +529 -0
- package/Models/DatabaseModels/AlertEpisodeInternalNote.ts +455 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +586 -0
- package/Models/DatabaseModels/AlertEpisodeOwnerTeam.ts +421 -0
- package/Models/DatabaseModels/AlertEpisodeOwnerUser.ts +419 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +523 -0
- package/Models/DatabaseModels/AlertFeed.ts +1 -0
- package/Models/DatabaseModels/AlertGroupingRule.ts +1432 -0
- package/Models/DatabaseModels/Index.ts +18 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +70 -0
- package/Models/DatabaseModels/StatusPageDomain.ts +2 -0
- package/Models/DatabaseModels/WorkspaceNotificationLog.ts +57 -0
- package/Server/API/SlackAPI.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.ts +751 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.ts +177 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.ts +71 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Services/AlertEpisodeFeedService.ts +94 -0
- package/Server/Services/AlertEpisodeInternalNoteService.ts +71 -0
- package/Server/Services/AlertEpisodeMemberService.ts +267 -0
- package/Server/Services/AlertEpisodeOwnerTeamService.ts +10 -0
- package/Server/Services/AlertEpisodeOwnerUserService.ts +10 -0
- package/Server/Services/AlertEpisodeService.ts +988 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +557 -0
- package/Server/Services/AlertGroupingEngineService.ts +1120 -0
- package/Server/Services/AlertGroupingRuleService.ts +14 -0
- package/Server/Services/AlertService.ts +12 -0
- package/Server/Services/CallService.ts +2 -0
- package/Server/Services/Index.ts +21 -0
- package/Server/Services/MailService.ts +5 -0
- package/Server/Services/OnCallDutyPolicyService.ts +5 -0
- package/Server/Services/SmsService.ts +2 -0
- package/Server/Services/UserNotificationSettingService.ts +23 -0
- package/Server/Services/WhatsAppService.ts +5 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +26 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +6 -2
- package/Server/Utils/WhatsAppTemplateUtil.ts +13 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +18 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +689 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +16 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +11 -0
- package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +915 -0
- package/Server/Utils/Workspace/Slack/Messages/AlertEpisode.ts +120 -0
- package/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.ts +74 -0
- package/Tests/Server/Services/AlertEpisodeMemberService.test.ts +200 -0
- package/Tests/Server/Services/AlertEpisodeService.test.ts +240 -0
- package/Tests/Server/Services/AlertGroupingEngineService.test.ts +542 -0
- package/Tests/Server/Services/AlertGroupingRuleService.test.ts +383 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/TextArea.test.tsx +2 -2
- package/Types/BaseDatabase/SortOrder.ts +9 -0
- package/Types/Email/EmailTemplateType.ts +5 -0
- package/Types/NotificationRule/NotificationRuleType.ts +1 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
- package/Types/Permission.ts +309 -0
- package/Types/UserNotification/UserNotificationEventType.ts +1 -0
- package/Types/WhatsApp/WhatsAppTemplates.ts +20 -0
- package/Types/Workspace/NotificationRules/EventType.ts +1 -0
- package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +32 -3
- package/UI/Components/Accordion/Accordion.tsx +20 -2
- package/UI/Components/Alerts/Alert.tsx +1 -0
- package/UI/Components/Button/Button.tsx +29 -0
- package/UI/Components/CardSelect/CardSelect.tsx +5 -1
- package/UI/Components/Checkbox/Checkbox.tsx +7 -3
- package/UI/Components/ColorCircle/ColorCircle.tsx +2 -0
- package/UI/Components/ColorViewer/ColorViewer.tsx +19 -3
- package/UI/Components/CopyableButton/CopyableButton.tsx +22 -5
- package/UI/Components/Detail/Detail.tsx +1 -1
- package/UI/Components/Dropdown/Dropdown.tsx +14 -1
- package/UI/Components/Forms/Fields/FormField.tsx +28 -0
- package/UI/Components/FullPageModal/FullPageModal.tsx +35 -4
- package/UI/Components/Input/Input.tsx +14 -2
- package/UI/Components/Link/Link.tsx +1 -0
- package/UI/Components/Loader/Loader.tsx +8 -2
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +76 -1
- package/UI/Components/Modal/Modal.tsx +47 -3
- package/UI/Components/ModelTable/BaseModelTable.tsx +42 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +84 -2
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +30 -8
- package/UI/Components/Pagination/Pagination.tsx +113 -8
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -2
- package/UI/Components/Radio/Radio.tsx +21 -3
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +54 -27
- package/UI/Components/StatusBubble/StatusBubble.tsx +7 -2
- package/UI/Components/Table/TableHeader.tsx +20 -3
- package/UI/Components/Tabs/Tab.tsx +16 -1
- package/UI/Components/Tabs/Tabs.tsx +12 -1
- package/UI/Components/TextArea/TextArea.tsx +12 -2
- package/UI/Components/Toggle/Toggle.tsx +14 -3
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/TopAlert/TopAlert.tsx +2 -0
- package/build/dist/Models/DatabaseModels/Alert.js +77 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisode.js +1225 -0
- package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js +553 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js +467 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +607 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js +437 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js +436 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +546 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +1437 -0
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +69 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js +58 -0
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +18 -0
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js +266 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js +68 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeFeedService.js +83 -0
- package/build/dist/Server/Services/AlertEpisodeFeedService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js +70 -0
- package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +256 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js +9 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeService.js +885 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -0
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +494 -0
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -0
- package/build/dist/Server/Services/AlertGroupingEngineService.js +893 -0
- package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -0
- package/build/dist/Server/Services/AlertGroupingRuleService.js +13 -0
- package/build/dist/Server/Services/AlertGroupingRuleService.js.map +1 -0
- package/build/dist/Server/Services/AlertService.js +11 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/CallService.js +11 -10
- package/build/dist/Server/Services/CallService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +18 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MailService.js +3 -0
- package/build/dist/Server/Services/MailService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +3 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/SmsService.js +11 -10
- package/build/dist/Server/Services/SmsService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +9 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/WhatsAppService.js +3 -0
- package/build/dist/Server/Services/WhatsAppService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +25 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +4 -2
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +8 -0
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +17 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +545 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +13 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +10 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +651 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js +100 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js +70 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js.map +1 -0
- package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js +165 -0
- package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js.map +1 -0
- package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js +193 -0
- package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js.map +1 -0
- package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js +412 -0
- package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js.map +1 -0
- package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js +308 -0
- package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js.map +1 -0
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +1 -1
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +1 -1
- package/build/dist/Tests/UI/Components/Input.test.js +1 -1
- package/build/dist/Tests/UI/Components/Input.test.js.map +1 -1
- package/build/dist/Tests/UI/Components/TextArea.test.js +2 -2
- package/build/dist/Tests/UI/Components/TextArea.test.js.map +1 -1
- package/build/dist/Types/BaseDatabase/SortOrder.js +5 -0
- package/build/dist/Types/BaseDatabase/SortOrder.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +4 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/NotificationRule/NotificationRuleType.js +1 -0
- package/build/dist/Types/NotificationRule/NotificationRuleType.js.map +1 -1
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/Permission.js +264 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
- package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
- package/build/dist/Types/WhatsApp/WhatsAppTemplates.js +12 -0
- package/build/dist/Types/WhatsApp/WhatsAppTemplates.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/EventType.js +1 -0
- package/build/dist/Types/Workspace/NotificationRules/EventType.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +28 -3
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +10 -3
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/Alerts/Alert.js +1 -1
- package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +8 -2
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +2 -2
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/ColorCircle/ColorCircle.js +1 -1
- package/build/dist/UI/Components/ColorCircle/ColorCircle.js.map +1 -1
- package/build/dist/UI/Components/ColorViewer/ColorViewer.js +12 -3
- package/build/dist/UI/Components/ColorViewer/ColorViewer.js.map +1 -1
- package/build/dist/UI/Components/CopyableButton/CopyableButton.js +12 -5
- package/build/dist/UI/Components/CopyableButton/CopyableButton.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +1 -1
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -3
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +19 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/FullPageModal/FullPageModal.js +24 -5
- package/build/dist/UI/Components/FullPageModal/FullPageModal.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +3 -3
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/Link/Link.js +1 -1
- package/build/dist/UI/Components/Link/Link.js.map +1 -1
- package/build/dist/UI/Components/Loader/Loader.js +6 -4
- package/build/dist/UI/Components/Loader/Loader.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +56 -3
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +28 -3
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +67 -6
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +14 -3
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/Pagination/Pagination.js +69 -13
- package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +2 -2
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/Radio/Radio.js +8 -5
- package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -4
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/StatusBubble/StatusBubble.js +2 -2
- package/build/dist/UI/Components/StatusBubble/StatusBubble.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +12 -4
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js +8 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Tabs/Tabs.js +4 -3
- package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +3 -3
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Toggle/Toggle.js +7 -4
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +4 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/TopAlert/TopAlert.js +1 -1
- package/build/dist/UI/Components/TopAlert/TopAlert.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import Alert from "../../../Models/DatabaseModels/Alert";
|
|
2
|
+
import AlertEpisode from "../../../Models/DatabaseModels/AlertEpisode";
|
|
3
|
+
import AlertGroupingRule from "../../../Models/DatabaseModels/AlertGroupingRule";
|
|
4
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
5
|
+
import AlertSeverity from "../../../Models/DatabaseModels/AlertSeverity";
|
|
6
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
7
|
+
import { describe, expect, test, beforeEach } from "@jest/globals";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* These tests focus on model-level testing for alert grouping components.
|
|
11
|
+
* Service integration tests require database connections and are covered
|
|
12
|
+
* in E2E tests.
|
|
13
|
+
*/
|
|
14
|
+
describe("AlertGroupingEngineService Models", () => {
|
|
15
|
+
const projectId: ObjectID = ObjectID.generate();
|
|
16
|
+
const alertId: ObjectID = ObjectID.generate();
|
|
17
|
+
const monitorId: ObjectID = ObjectID.generate();
|
|
18
|
+
const severityId: ObjectID = ObjectID.generate();
|
|
19
|
+
const ruleId: ObjectID = ObjectID.generate();
|
|
20
|
+
const episodeId: ObjectID = ObjectID.generate();
|
|
21
|
+
|
|
22
|
+
let mockAlert: Alert;
|
|
23
|
+
let mockMonitor: Monitor;
|
|
24
|
+
let mockSeverity: AlertSeverity;
|
|
25
|
+
let mockRule: AlertGroupingRule;
|
|
26
|
+
let mockEpisode: AlertEpisode;
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
// Setup mock monitor
|
|
30
|
+
mockMonitor = new Monitor();
|
|
31
|
+
mockMonitor._id = monitorId.toString();
|
|
32
|
+
mockMonitor.name = "Test Monitor";
|
|
33
|
+
|
|
34
|
+
// Setup mock severity
|
|
35
|
+
mockSeverity = new AlertSeverity();
|
|
36
|
+
mockSeverity._id = severityId.toString();
|
|
37
|
+
mockSeverity.name = "Critical";
|
|
38
|
+
|
|
39
|
+
// Setup mock alert
|
|
40
|
+
mockAlert = new Alert();
|
|
41
|
+
mockAlert._id = alertId.toString();
|
|
42
|
+
mockAlert.id = alertId;
|
|
43
|
+
mockAlert.projectId = projectId;
|
|
44
|
+
mockAlert.title = "CPU Usage High";
|
|
45
|
+
mockAlert.description = "CPU usage exceeded 90%";
|
|
46
|
+
mockAlert.monitor = mockMonitor;
|
|
47
|
+
mockAlert.monitorId = monitorId;
|
|
48
|
+
mockAlert.alertSeverity = mockSeverity;
|
|
49
|
+
mockAlert.alertSeverityId = severityId;
|
|
50
|
+
|
|
51
|
+
// Setup mock rule
|
|
52
|
+
mockRule = new AlertGroupingRule();
|
|
53
|
+
mockRule._id = ruleId.toString();
|
|
54
|
+
mockRule.id = ruleId;
|
|
55
|
+
mockRule.name = "Critical Alerts Rule";
|
|
56
|
+
mockRule.isEnabled = true;
|
|
57
|
+
mockRule.priority = 1;
|
|
58
|
+
mockRule.groupByMonitor = true;
|
|
59
|
+
mockRule.enableTimeWindow = true;
|
|
60
|
+
mockRule.timeWindowMinutes = 30;
|
|
61
|
+
|
|
62
|
+
// Setup mock episode
|
|
63
|
+
mockEpisode = new AlertEpisode();
|
|
64
|
+
mockEpisode._id = episodeId.toString();
|
|
65
|
+
mockEpisode.id = episodeId;
|
|
66
|
+
mockEpisode.projectId = projectId;
|
|
67
|
+
mockEpisode.title = "Test Episode";
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe("Alert Model for Grouping", () => {
|
|
71
|
+
test("should have alertEpisodeId field", () => {
|
|
72
|
+
const alert: Alert = new Alert();
|
|
73
|
+
const episodeId: ObjectID = ObjectID.generate();
|
|
74
|
+
alert.alertEpisodeId = episodeId;
|
|
75
|
+
expect(alert.alertEpisodeId).toEqual(episodeId);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("should store title and description for template variables", () => {
|
|
79
|
+
expect(mockAlert.title).toBe("CPU Usage High");
|
|
80
|
+
expect(mockAlert.description).toBe("CPU usage exceeded 90%");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("should reference monitor for template variables", () => {
|
|
84
|
+
expect(mockAlert.monitor?.name).toBe("Test Monitor");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("should reference alert severity for template variables", () => {
|
|
88
|
+
expect(mockAlert.alertSeverity?.name).toBe("Critical");
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("AlertGroupingRule Matching Criteria", () => {
|
|
93
|
+
describe("Monitor Matching", () => {
|
|
94
|
+
test("should support array of monitors for matching", () => {
|
|
95
|
+
mockRule.monitors = [mockMonitor];
|
|
96
|
+
expect(mockRule.monitors).toHaveLength(1);
|
|
97
|
+
expect(mockRule.monitors[0]).toBe(mockMonitor);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("should check if monitor exists in rule monitors", () => {
|
|
101
|
+
const otherMonitor: Monitor = new Monitor();
|
|
102
|
+
otherMonitor._id = ObjectID.generate().toString();
|
|
103
|
+
|
|
104
|
+
mockRule.monitors = [mockMonitor, otherMonitor];
|
|
105
|
+
|
|
106
|
+
const monitorIds: Array<string | undefined> = mockRule.monitors.map(
|
|
107
|
+
(m: Monitor) => {
|
|
108
|
+
return m._id;
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
expect(monitorIds).toContain(mockMonitor._id);
|
|
112
|
+
expect(monitorIds).toContain(otherMonitor._id);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("Severity Matching", () => {
|
|
117
|
+
test("should support array of severities for matching", () => {
|
|
118
|
+
mockRule.alertSeverities = [mockSeverity];
|
|
119
|
+
expect(mockRule.alertSeverities).toHaveLength(1);
|
|
120
|
+
expect(mockRule.alertSeverities[0]).toBe(mockSeverity);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe("Pattern Matching", () => {
|
|
125
|
+
test("should store title pattern for regex matching", () => {
|
|
126
|
+
mockRule.alertTitlePattern = "CPU.*High";
|
|
127
|
+
expect(mockRule.alertTitlePattern).toBe("CPU.*High");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("should match alert title against pattern", () => {
|
|
131
|
+
mockRule.alertTitlePattern = "CPU.*High";
|
|
132
|
+
const pattern: RegExp = new RegExp(mockRule.alertTitlePattern, "i");
|
|
133
|
+
expect(pattern.test(mockAlert.title!)).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("should not match when pattern doesn't match", () => {
|
|
137
|
+
mockRule.alertTitlePattern = "Memory.*Low";
|
|
138
|
+
const pattern: RegExp = new RegExp(mockRule.alertTitlePattern, "i");
|
|
139
|
+
expect(pattern.test(mockAlert.title!)).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("should store description pattern for regex matching", () => {
|
|
143
|
+
mockRule.alertDescriptionPattern = "CPU usage exceeded.*";
|
|
144
|
+
expect(mockRule.alertDescriptionPattern).toBe("CPU usage exceeded.*");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("should match alert description against pattern", () => {
|
|
148
|
+
mockRule.alertDescriptionPattern = "CPU usage exceeded.*";
|
|
149
|
+
const pattern: RegExp = new RegExp(
|
|
150
|
+
mockRule.alertDescriptionPattern,
|
|
151
|
+
"i",
|
|
152
|
+
);
|
|
153
|
+
expect(pattern.test(mockAlert.description!)).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe("Grouping Key Generation Logic", () => {
|
|
159
|
+
test("should generate grouping key with monitor when groupByMonitor is true", () => {
|
|
160
|
+
mockRule.groupByMonitor = true;
|
|
161
|
+
mockRule.groupBySeverity = false;
|
|
162
|
+
mockRule.groupByAlertTitle = false;
|
|
163
|
+
|
|
164
|
+
const parts: string[] = [`rule:${mockRule._id}`];
|
|
165
|
+
if (mockRule.groupByMonitor && mockAlert.monitorId) {
|
|
166
|
+
parts.push(`monitor:${mockAlert.monitorId.toString()}`);
|
|
167
|
+
}
|
|
168
|
+
if (mockRule.groupBySeverity && mockAlert.alertSeverityId) {
|
|
169
|
+
parts.push(`severity:${mockAlert.alertSeverityId.toString()}`);
|
|
170
|
+
}
|
|
171
|
+
if (mockRule.groupByAlertTitle && mockAlert.title) {
|
|
172
|
+
parts.push(`title:${mockAlert.title}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const groupingKey: string = parts.join("|");
|
|
176
|
+
expect(groupingKey).toContain(`rule:${mockRule._id}`);
|
|
177
|
+
expect(groupingKey).toContain(
|
|
178
|
+
`monitor:${mockAlert.monitorId!.toString()}`,
|
|
179
|
+
);
|
|
180
|
+
expect(groupingKey).not.toContain("severity:");
|
|
181
|
+
expect(groupingKey).not.toContain("title:");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("should generate grouping key with severity when groupBySeverity is true", () => {
|
|
185
|
+
mockRule.groupByMonitor = false;
|
|
186
|
+
mockRule.groupBySeverity = true;
|
|
187
|
+
mockRule.groupByAlertTitle = false;
|
|
188
|
+
|
|
189
|
+
const parts: string[] = [`rule:${mockRule._id}`];
|
|
190
|
+
if (mockRule.groupByMonitor && mockAlert.monitorId) {
|
|
191
|
+
parts.push(`monitor:${mockAlert.monitorId.toString()}`);
|
|
192
|
+
}
|
|
193
|
+
if (mockRule.groupBySeverity && mockAlert.alertSeverityId) {
|
|
194
|
+
parts.push(`severity:${mockAlert.alertSeverityId.toString()}`);
|
|
195
|
+
}
|
|
196
|
+
if (mockRule.groupByAlertTitle && mockAlert.title) {
|
|
197
|
+
parts.push(`title:${mockAlert.title}`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const groupingKey: string = parts.join("|");
|
|
201
|
+
expect(groupingKey).toContain(`rule:${mockRule._id}`);
|
|
202
|
+
expect(groupingKey).not.toContain("monitor:");
|
|
203
|
+
expect(groupingKey).toContain(
|
|
204
|
+
`severity:${mockAlert.alertSeverityId!.toString()}`,
|
|
205
|
+
);
|
|
206
|
+
expect(groupingKey).not.toContain("title:");
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("should generate grouping key with all dimensions", () => {
|
|
210
|
+
mockRule.groupByMonitor = true;
|
|
211
|
+
mockRule.groupBySeverity = true;
|
|
212
|
+
mockRule.groupByAlertTitle = true;
|
|
213
|
+
|
|
214
|
+
const parts: string[] = [`rule:${mockRule._id}`];
|
|
215
|
+
if (mockRule.groupByMonitor && mockAlert.monitorId) {
|
|
216
|
+
parts.push(`monitor:${mockAlert.monitorId.toString()}`);
|
|
217
|
+
}
|
|
218
|
+
if (mockRule.groupBySeverity && mockAlert.alertSeverityId) {
|
|
219
|
+
parts.push(`severity:${mockAlert.alertSeverityId.toString()}`);
|
|
220
|
+
}
|
|
221
|
+
if (mockRule.groupByAlertTitle && mockAlert.title) {
|
|
222
|
+
parts.push(`title:${mockAlert.title}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const groupingKey: string = parts.join("|");
|
|
226
|
+
expect(groupingKey).toContain(`rule:${mockRule._id}`);
|
|
227
|
+
expect(groupingKey).toContain(
|
|
228
|
+
`monitor:${mockAlert.monitorId!.toString()}`,
|
|
229
|
+
);
|
|
230
|
+
expect(groupingKey).toContain(
|
|
231
|
+
`severity:${mockAlert.alertSeverityId!.toString()}`,
|
|
232
|
+
);
|
|
233
|
+
expect(groupingKey).toContain(`title:${mockAlert.title}`);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe("Time Window Configuration", () => {
|
|
238
|
+
test("should store enableTimeWindow flag", () => {
|
|
239
|
+
mockRule.enableTimeWindow = true;
|
|
240
|
+
expect(mockRule.enableTimeWindow).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test("should store timeWindowMinutes", () => {
|
|
244
|
+
mockRule.timeWindowMinutes = 60;
|
|
245
|
+
expect(mockRule.timeWindowMinutes).toBe(60);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("should store enableReopenWindow flag", () => {
|
|
249
|
+
mockRule.enableReopenWindow = true;
|
|
250
|
+
expect(mockRule.enableReopenWindow).toBe(true);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("should store reopenWindowMinutes", () => {
|
|
254
|
+
mockRule.reopenWindowMinutes = 30;
|
|
255
|
+
expect(mockRule.reopenWindowMinutes).toBe(30);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("should calculate if episode is within time window", () => {
|
|
259
|
+
const windowMinutes: number = 30;
|
|
260
|
+
const episodeCreatedAt: Date = new Date(Date.now() - 15 * 60 * 1000); // 15 minutes ago
|
|
261
|
+
const windowStart: Date = new Date(
|
|
262
|
+
Date.now() - windowMinutes * 60 * 1000,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const isWithinWindow: boolean = episodeCreatedAt >= windowStart;
|
|
266
|
+
expect(isWithinWindow).toBe(true);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test("should calculate if episode is outside time window", () => {
|
|
270
|
+
const windowMinutes: number = 30;
|
|
271
|
+
const episodeCreatedAt: Date = new Date(Date.now() - 45 * 60 * 1000); // 45 minutes ago
|
|
272
|
+
const windowStart: Date = new Date(
|
|
273
|
+
Date.now() - windowMinutes * 60 * 1000,
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const isWithinWindow: boolean = episodeCreatedAt >= windowStart;
|
|
277
|
+
expect(isWithinWindow).toBe(false);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
describe("Reopen Window Logic", () => {
|
|
282
|
+
test("should identify recently resolved episode for reopening", () => {
|
|
283
|
+
const reopenWindowMinutes: number = 30;
|
|
284
|
+
const resolvedAt: Date = new Date(Date.now() - 10 * 60 * 1000); // 10 minutes ago
|
|
285
|
+
const reopenWindowStart: Date = new Date(
|
|
286
|
+
Date.now() - reopenWindowMinutes * 60 * 1000,
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
mockEpisode.resolvedAt = resolvedAt;
|
|
290
|
+
|
|
291
|
+
const canReopen: boolean = mockEpisode.resolvedAt >= reopenWindowStart;
|
|
292
|
+
expect(canReopen).toBe(true);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test("should not reopen episode outside reopen window", () => {
|
|
296
|
+
const reopenWindowMinutes: number = 30;
|
|
297
|
+
const resolvedAt: Date = new Date(Date.now() - 45 * 60 * 1000); // 45 minutes ago
|
|
298
|
+
const reopenWindowStart: Date = new Date(
|
|
299
|
+
Date.now() - reopenWindowMinutes * 60 * 1000,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
mockEpisode.resolvedAt = resolvedAt;
|
|
303
|
+
|
|
304
|
+
const canReopen: boolean = mockEpisode.resolvedAt >= reopenWindowStart;
|
|
305
|
+
expect(canReopen).toBe(false);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
describe("Rule Priority", () => {
|
|
310
|
+
test("should sort rules by priority", () => {
|
|
311
|
+
const rule1: AlertGroupingRule = new AlertGroupingRule();
|
|
312
|
+
rule1.priority = 10;
|
|
313
|
+
|
|
314
|
+
const rule2: AlertGroupingRule = new AlertGroupingRule();
|
|
315
|
+
rule2.priority = 1;
|
|
316
|
+
|
|
317
|
+
const rule3: AlertGroupingRule = new AlertGroupingRule();
|
|
318
|
+
rule3.priority = 5;
|
|
319
|
+
|
|
320
|
+
const rules: AlertGroupingRule[] = [rule1, rule2, rule3];
|
|
321
|
+
rules.sort((a: AlertGroupingRule, b: AlertGroupingRule) => {
|
|
322
|
+
return (a.priority || 0) - (b.priority || 0);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
expect(rules[0]!.priority).toBe(1);
|
|
326
|
+
expect(rules[1]!.priority).toBe(5);
|
|
327
|
+
expect(rules[2]!.priority).toBe(10);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
describe("Template Variable Replacement Logic", () => {
|
|
333
|
+
const alertId: ObjectID = ObjectID.generate();
|
|
334
|
+
const monitorId: ObjectID = ObjectID.generate();
|
|
335
|
+
const severityId: ObjectID = ObjectID.generate();
|
|
336
|
+
|
|
337
|
+
let mockAlert: Alert;
|
|
338
|
+
let mockMonitor: Monitor;
|
|
339
|
+
let mockSeverity: AlertSeverity;
|
|
340
|
+
|
|
341
|
+
beforeEach(() => {
|
|
342
|
+
mockMonitor = new Monitor();
|
|
343
|
+
mockMonitor._id = monitorId.toString();
|
|
344
|
+
mockMonitor.name = "API Server";
|
|
345
|
+
|
|
346
|
+
mockSeverity = new AlertSeverity();
|
|
347
|
+
mockSeverity._id = severityId.toString();
|
|
348
|
+
mockSeverity.name = "Critical";
|
|
349
|
+
|
|
350
|
+
mockAlert = new Alert();
|
|
351
|
+
mockAlert._id = alertId.toString();
|
|
352
|
+
mockAlert.id = alertId;
|
|
353
|
+
mockAlert.title = "High CPU Usage";
|
|
354
|
+
mockAlert.description = "CPU usage is above threshold";
|
|
355
|
+
mockAlert.monitor = mockMonitor;
|
|
356
|
+
mockAlert.alertSeverity = mockSeverity;
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
describe("Static Variable Replacement", () => {
|
|
360
|
+
test("should replace {{alertTitle}} with alert title", () => {
|
|
361
|
+
const template: string = "Episode: {{alertTitle}}";
|
|
362
|
+
const result: string = template.replace(
|
|
363
|
+
/\{\{alertTitle\}\}/g,
|
|
364
|
+
mockAlert.title!,
|
|
365
|
+
);
|
|
366
|
+
expect(result).toBe("Episode: High CPU Usage");
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
test("should replace {{alertDescription}} with alert description", () => {
|
|
370
|
+
const template: string = "Details: {{alertDescription}}";
|
|
371
|
+
const result: string = template.replace(
|
|
372
|
+
/\{\{alertDescription\}\}/g,
|
|
373
|
+
mockAlert.description!,
|
|
374
|
+
);
|
|
375
|
+
expect(result).toBe("Details: CPU usage is above threshold");
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test("should replace {{monitorName}} with monitor name", () => {
|
|
379
|
+
const template: string = "Alert on {{monitorName}}";
|
|
380
|
+
const result: string = template.replace(
|
|
381
|
+
/\{\{monitorName\}\}/g,
|
|
382
|
+
mockAlert.monitor?.name || "",
|
|
383
|
+
);
|
|
384
|
+
expect(result).toBe("Alert on API Server");
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test("should replace {{alertSeverity}} with severity name", () => {
|
|
388
|
+
const template: string = "{{alertSeverity}} Alert Episode";
|
|
389
|
+
const result: string = template.replace(
|
|
390
|
+
/\{\{alertSeverity\}\}/g,
|
|
391
|
+
mockAlert.alertSeverity?.name || "",
|
|
392
|
+
);
|
|
393
|
+
expect(result).toBe("Critical Alert Episode");
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
test("should replace multiple variables in same template", () => {
|
|
397
|
+
let template: string =
|
|
398
|
+
"{{alertSeverity}}: {{alertTitle}} on {{monitorName}}";
|
|
399
|
+
template = template.replace(/\{\{alertTitle\}\}/g, mockAlert.title!);
|
|
400
|
+
template = template.replace(
|
|
401
|
+
/\{\{alertSeverity\}\}/g,
|
|
402
|
+
mockAlert.alertSeverity?.name || "",
|
|
403
|
+
);
|
|
404
|
+
template = template.replace(
|
|
405
|
+
/\{\{monitorName\}\}/g,
|
|
406
|
+
mockAlert.monitor?.name || "",
|
|
407
|
+
);
|
|
408
|
+
expect(template).toBe("Critical: High CPU Usage on API Server");
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
describe("Dynamic Variable Replacement", () => {
|
|
413
|
+
test("should replace {{alertCount}} with count", () => {
|
|
414
|
+
const template: string = "Episode ({{alertCount}} alerts)";
|
|
415
|
+
const alertCount: number = 5;
|
|
416
|
+
const result: string = template.replace(
|
|
417
|
+
/\{\{alertCount\}\}/g,
|
|
418
|
+
alertCount.toString(),
|
|
419
|
+
);
|
|
420
|
+
expect(result).toBe("Episode (5 alerts)");
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("should preserve {{alertCount}} placeholder in preprocessed template", () => {
|
|
424
|
+
let template: string = "{{alertTitle}} - {{alertCount}} alerts";
|
|
425
|
+
|
|
426
|
+
// Preprocess: replace static variables only
|
|
427
|
+
template = template.replace(/\{\{alertTitle\}\}/g, mockAlert.title!);
|
|
428
|
+
|
|
429
|
+
// {{alertCount}} should still be present
|
|
430
|
+
expect(template).toBe("High CPU Usage - {{alertCount}} alerts");
|
|
431
|
+
expect(template).toContain("{{alertCount}}");
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
test("should render final title with dynamic values", () => {
|
|
435
|
+
// Start with preprocessed template (static vars already replaced)
|
|
436
|
+
const preprocessedTemplate: string =
|
|
437
|
+
"High CPU Usage - {{alertCount}} alerts";
|
|
438
|
+
const alertCount: number = 10;
|
|
439
|
+
|
|
440
|
+
// Render dynamic values
|
|
441
|
+
const finalTitle: string = preprocessedTemplate.replace(
|
|
442
|
+
/\{\{alertCount\}\}/g,
|
|
443
|
+
alertCount.toString(),
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
expect(finalTitle).toBe("High CPU Usage - 10 alerts");
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
describe("Unknown Placeholder Handling", () => {
|
|
451
|
+
test("should remove unknown placeholders", () => {
|
|
452
|
+
let template: string = "{{alertTitle}} {{unknownVar}} Episode";
|
|
453
|
+
template = template.replace(/\{\{alertTitle\}\}/g, mockAlert.title!);
|
|
454
|
+
// Remove any remaining placeholders
|
|
455
|
+
template = template.replace(/\{\{[^}]+\}\}/g, "");
|
|
456
|
+
// Clean up extra spaces
|
|
457
|
+
template = template.replace(/\s+/g, " ").trim();
|
|
458
|
+
expect(template).toBe("High CPU Usage Episode");
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
describe("Default Title Generation", () => {
|
|
463
|
+
test("should use monitor name when no template provided", () => {
|
|
464
|
+
const defaultTitle: string = `Alert Episode: ${mockAlert.monitor?.name || mockAlert.title || "Alert Episode"}`;
|
|
465
|
+
expect(defaultTitle).toBe("Alert Episode: API Server");
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
test("should use alert title when no monitor", () => {
|
|
469
|
+
// Create alert without monitor
|
|
470
|
+
const alertNoMonitor: Alert = new Alert();
|
|
471
|
+
alertNoMonitor._id = alertId.toString();
|
|
472
|
+
alertNoMonitor.id = alertId;
|
|
473
|
+
alertNoMonitor.title = "High CPU Usage";
|
|
474
|
+
// monitor is intentionally not set
|
|
475
|
+
|
|
476
|
+
const defaultTitle: string = `Alert Episode: ${alertNoMonitor.monitor?.name || alertNoMonitor.title || "Alert Episode"}`;
|
|
477
|
+
expect(defaultTitle).toBe("Alert Episode: High CPU Usage");
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
test("should use generic title when no monitor and no alert title", () => {
|
|
481
|
+
// Create minimal alert without monitor and title
|
|
482
|
+
const alertMinimal: Alert = new Alert();
|
|
483
|
+
alertMinimal._id = alertId.toString();
|
|
484
|
+
alertMinimal.id = alertId;
|
|
485
|
+
// monitor and title are intentionally not set
|
|
486
|
+
|
|
487
|
+
const defaultTitle: string = `Alert Episode: ${alertMinimal.monitor?.name || alertMinimal.title || "Alert Episode"}`;
|
|
488
|
+
expect(defaultTitle).toBe("Alert Episode: Alert Episode");
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
describe("AlertEpisode Template Storage", () => {
|
|
494
|
+
test("should store titleTemplate for dynamic re-rendering", () => {
|
|
495
|
+
const episode: AlertEpisode = new AlertEpisode();
|
|
496
|
+
episode.titleTemplate = "High CPU Usage - {{alertCount}} alerts";
|
|
497
|
+
expect(episode.titleTemplate).toBe(
|
|
498
|
+
"High CPU Usage - {{alertCount}} alerts",
|
|
499
|
+
);
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
test("should store descriptionTemplate for dynamic re-rendering", () => {
|
|
503
|
+
const episode: AlertEpisode = new AlertEpisode();
|
|
504
|
+
episode.descriptionTemplate =
|
|
505
|
+
"Episode contains {{alertCount}} related alerts";
|
|
506
|
+
expect(episode.descriptionTemplate).toBe(
|
|
507
|
+
"Episode contains {{alertCount}} related alerts",
|
|
508
|
+
);
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
test("should store both title and titleTemplate", () => {
|
|
512
|
+
const episode: AlertEpisode = new AlertEpisode();
|
|
513
|
+
episode.title = "High CPU Usage - 1 alerts";
|
|
514
|
+
episode.titleTemplate = "High CPU Usage - {{alertCount}} alerts";
|
|
515
|
+
|
|
516
|
+
expect(episode.title).toBe("High CPU Usage - 1 alerts");
|
|
517
|
+
expect(episode.titleTemplate).toBe(
|
|
518
|
+
"High CPU Usage - {{alertCount}} alerts",
|
|
519
|
+
);
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
test("should re-render title from template when alert count changes", () => {
|
|
523
|
+
const episode: AlertEpisode = new AlertEpisode();
|
|
524
|
+
episode.titleTemplate = "High CPU Usage - {{alertCount}} alerts";
|
|
525
|
+
episode.alertCount = 1;
|
|
526
|
+
episode.title = episode.titleTemplate.replace(
|
|
527
|
+
/\{\{alertCount\}\}/g,
|
|
528
|
+
episode.alertCount.toString(),
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
expect(episode.title).toBe("High CPU Usage - 1 alerts");
|
|
532
|
+
|
|
533
|
+
// Simulate adding more alerts
|
|
534
|
+
episode.alertCount = 5;
|
|
535
|
+
episode.title = episode.titleTemplate.replace(
|
|
536
|
+
/\{\{alertCount\}\}/g,
|
|
537
|
+
episode.alertCount.toString(),
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
expect(episode.title).toBe("High CPU Usage - 5 alerts");
|
|
541
|
+
});
|
|
542
|
+
});
|