@oneuptime/common 14.0.1 → 14.0.2

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.
Files changed (1090) hide show
  1. package/Models/DatabaseModels/AlertEpisodeMember.ts +8 -1
  2. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
  3. package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
  4. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
  5. package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
  6. package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
  7. package/Models/DatabaseModels/Monitor.ts +48 -0
  8. package/Models/DatabaseModels/Runner.ts +5 -4
  9. package/Models/DatabaseModels/RunnerJob.ts +66 -0
  10. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
  11. package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
  12. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
  13. package/Server/API/AIInvestigationAPI.ts +341 -0
  14. package/Server/API/AutoRemediationAPI.ts +184 -2
  15. package/Server/API/CommonAPI.ts +70 -0
  16. package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
  17. package/Server/API/MicrosoftTeamsAPI.ts +770 -315
  18. package/Server/API/MonitorAPI.ts +140 -0
  19. package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
  20. package/Server/API/SlackAPI.ts +447 -99
  21. package/Server/API/StatusPageAPI.ts +146 -26
  22. package/Server/API/TelemetryAPI.ts +216 -5
  23. package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
  24. package/Server/API/WorkflowVariableAPI.ts +156 -0
  25. package/Server/Infrastructure/GlobalCache.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
  33. package/Server/Middleware/TelemetryIngest.ts +47 -2
  34. package/Server/Middleware/UserAuthorization.ts +56 -2
  35. package/Server/Services/AIAgentService.ts +1 -0
  36. package/Server/Services/AccessTokenService.ts +121 -48
  37. package/Server/Services/AlertEpisodeMemberService.ts +9 -0
  38. package/Server/Services/AlertEpisodeService.ts +14 -1
  39. package/Server/Services/AlertService.ts +134 -22
  40. package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
  41. package/Server/Services/AutoRemediationRuleService.ts +118 -0
  42. package/Server/Services/BillingService.ts +1 -0
  43. package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
  44. package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
  45. package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
  46. package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
  47. package/Server/Services/IncidentEpisodeService.ts +14 -1
  48. package/Server/Services/IncidentGroupingEngineService.ts +11 -0
  49. package/Server/Services/IncidentMemberService.ts +21 -0
  50. package/Server/Services/IncidentPublicNoteService.ts +63 -0
  51. package/Server/Services/IncidentService.ts +120 -20
  52. package/Server/Services/IncidentStateTimelineService.ts +15 -0
  53. package/Server/Services/IncidentTemplateService.ts +83 -3
  54. package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
  55. package/Server/Services/KubernetesClusterService.ts +1570 -1
  56. package/Server/Services/LogAggregationService.ts +14 -6
  57. package/Server/Services/MonitorService.ts +651 -52
  58. package/Server/Services/MonitorStatusTimelineService.ts +639 -2
  59. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
  60. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
  61. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
  62. package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
  63. package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
  64. package/Server/Services/OnCallSetupReminderService.ts +1 -0
  65. package/Server/Services/ProbeService.ts +7 -1
  66. package/Server/Services/ProjectService.ts +11 -1
  67. package/Server/Services/RunbookCredentialService.ts +26 -1
  68. package/Server/Services/RunbookSecretService.ts +36 -0
  69. package/Server/Services/RunnerJobService.ts +941 -23
  70. package/Server/Services/RunnerService.ts +439 -6
  71. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
  72. package/Server/Services/ScheduledMaintenanceService.ts +124 -19
  73. package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
  74. package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
  75. package/Server/Services/StatusPagePrivateUserService.ts +1 -0
  76. package/Server/Services/StatusPageService.ts +301 -74
  77. package/Server/Services/StatusPageSubscriberService.ts +4 -0
  78. package/Server/Services/TeamMemberService.ts +309 -7
  79. package/Server/Services/TraceAggregationService.ts +10 -6
  80. package/Server/Services/UserEmailService.ts +1 -0
  81. package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
  82. package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
  83. package/Server/Services/UserNotificationRuleService.ts +4 -0
  84. package/Server/Services/UserService.ts +122 -1
  85. package/Server/Services/WorkflowVariableService.ts +593 -8
  86. package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
  87. package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
  88. package/Server/Types/Database/QueryHelper.ts +22 -0
  89. package/Server/Types/Markdown.ts +502 -27
  90. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
  91. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
  92. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
  93. package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
  94. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
  95. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
  96. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
  97. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
  98. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
  99. package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
  100. package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
  101. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
  102. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
  103. package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
  104. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
  105. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
  106. package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
  107. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
  108. package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
  109. package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
  110. package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
  111. package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
  112. package/Server/Utils/PushNotificationUtil.ts +45 -0
  113. package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
  114. package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
  115. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
  116. package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
  117. package/Server/Utils/StartServer.ts +4 -3
  118. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
  119. package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
  120. package/Server/Utils/UserPermission/UserPermission.ts +16 -0
  121. package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
  122. package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
  123. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
  124. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
  125. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
  126. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
  127. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
  128. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
  129. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
  130. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
  131. package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
  132. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
  133. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
  134. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
  135. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
  136. package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
  137. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
  138. package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
  139. package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
  140. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
  141. package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
  142. package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  143. package/Server/Utils/Workspace/Workspace.ts +171 -54
  144. package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
  145. package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
  146. package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
  147. package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
  148. package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
  149. package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
  150. package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
  151. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
  152. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
  153. package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
  154. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
  155. package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
  156. package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
  157. package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
  158. package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
  159. package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
  160. package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
  161. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +218 -0
  162. package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
  163. package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
  164. package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
  165. package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
  166. package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
  167. package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
  168. package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
  169. package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
  170. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
  171. package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
  172. package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
  173. package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
  174. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
  175. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
  176. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
  177. package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
  178. package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
  179. package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
  180. package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
  181. package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
  182. package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
  183. package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
  184. package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
  185. package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
  186. package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
  187. package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
  188. package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
  189. package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
  190. package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
  191. package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
  192. package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
  193. package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
  194. package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
  195. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
  196. package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
  197. package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
  198. package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
  199. package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
  200. package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
  201. package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
  202. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
  203. package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
  204. package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
  205. package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
  206. package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
  207. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
  208. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
  209. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
  210. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
  211. package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
  212. package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
  213. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
  214. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
  215. package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
  216. package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
  217. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
  218. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
  219. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
  220. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
  221. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
  222. package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
  223. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
  224. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
  225. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
  226. package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
  227. package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
  228. package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
  229. package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
  230. package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
  231. package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
  232. package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
  233. package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
  234. package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
  235. package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
  236. package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
  237. package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
  238. package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
  239. package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
  240. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
  241. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
  242. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
  243. package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
  244. package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
  245. package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
  246. package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
  247. package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
  248. package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
  249. package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
  250. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
  251. package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
  252. package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
  253. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
  254. package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
  255. package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
  256. package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
  257. package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
  258. package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
  259. package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
  260. package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
  261. package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
  262. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
  263. package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
  264. package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
  265. package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
  266. package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
  267. package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
  268. package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
  269. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
  270. package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
  271. package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
  272. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
  273. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
  274. package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
  275. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
  276. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
  277. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
  278. package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
  279. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
  280. package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
  281. package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
  282. package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
  283. package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
  284. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
  285. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
  286. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
  287. package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
  288. package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
  289. package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
  290. package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
  291. package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
  292. package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
  293. package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
  294. package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
  295. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
  296. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
  297. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
  298. package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
  299. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
  300. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
  301. package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
  302. package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
  303. package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
  304. package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
  305. package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
  306. package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
  307. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
  308. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
  309. package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
  310. package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
  311. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
  312. package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
  313. package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
  314. package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
  315. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
  316. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
  317. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
  318. package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
  319. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
  320. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
  321. package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
  322. package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
  323. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
  324. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
  325. package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
  326. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
  327. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
  328. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
  329. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
  330. package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
  331. package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
  332. package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
  333. package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
  334. package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
  335. package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
  336. package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
  337. package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
  338. package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
  339. package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
  340. package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
  341. package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
  342. package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
  343. package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
  344. package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
  345. package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
  346. package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
  347. package/Tests/Server/Types/Markdown.test.ts +1033 -0
  348. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
  349. package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
  350. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
  351. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
  352. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
  353. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
  354. package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
  355. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
  356. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
  357. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
  358. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
  359. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
  360. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
  361. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
  362. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
  363. package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
  364. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
  365. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
  366. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
  367. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
  368. package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
  369. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
  370. package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
  371. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
  372. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
  373. package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
  374. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
  375. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
  376. package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
  377. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
  378. package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
  379. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
  380. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
  381. package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
  382. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
  383. package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
  384. package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
  385. package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
  386. package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
  387. package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
  388. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
  389. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
  390. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
  391. package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
  392. package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
  393. package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
  394. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
  395. package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
  396. package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
  397. package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
  398. package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
  399. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
  400. package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
  401. package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
  402. package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
  403. package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
  404. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
  405. package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
  406. package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
  407. package/Tests/Types/DateUserTimezone.test.ts +177 -4
  408. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
  409. package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
  410. package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
  411. package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
  412. package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
  413. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
  414. package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
  415. package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
  416. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
  417. package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
  418. package/Tests/Types/Timezone.test.ts +5 -0
  419. package/Tests/Types/TimezoneAlias.test.ts +1034 -0
  420. package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
  421. package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
  422. package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
  423. package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
  424. package/Tests/Types/Workflow/Templates.test.ts +79 -4
  425. package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
  426. package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
  427. package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
  428. package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
  429. package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
  430. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
  431. package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
  432. package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
  433. package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
  434. package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
  435. package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
  436. package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
  437. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
  438. package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
  439. package/Tests/UI/Components/Dropdown.test.tsx +999 -2
  440. package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
  441. package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
  442. package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
  443. package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
  444. package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
  445. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
  446. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
  447. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
  448. package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
  449. package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
  450. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
  451. package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
  452. package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
  453. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
  454. package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
  455. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
  456. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
  457. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
  458. package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
  459. package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
  460. package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
  461. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
  462. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -0
  463. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
  464. package/Tests/UI/Utils/Timezone.test.ts +747 -33
  465. package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
  466. package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
  467. package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
  468. package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
  469. package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
  470. package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
  471. package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
  472. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
  473. package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
  474. package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
  475. package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
  476. package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
  477. package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
  478. package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
  479. package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
  480. package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
  481. package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
  482. package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
  483. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
  484. package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
  485. package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
  486. package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
  487. package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
  488. package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
  489. package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
  490. package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
  491. package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
  492. package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
  493. package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
  494. package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
  495. package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
  496. package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
  497. package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
  498. package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
  499. package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
  500. package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
  501. package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
  502. package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
  503. package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
  504. package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
  505. package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
  506. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
  507. package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
  508. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
  509. package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
  510. package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
  511. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
  512. package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
  513. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
  514. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
  515. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
  516. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
  517. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
  518. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
  519. package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
  520. package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
  521. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
  522. package/Types/Date.ts +121 -7
  523. package/Types/Email/EmailMessage.ts +8 -0
  524. package/Types/Email/EmailTemplateType.ts +1 -0
  525. package/Types/Exception/ExceptionMessages.ts +1 -0
  526. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
  527. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
  528. package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
  529. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
  530. package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
  531. package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
  532. package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
  533. package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
  534. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
  535. package/Types/Rum/SessionReplay.ts +55 -2
  536. package/Types/Rum/SessionReplayApi.ts +44 -1
  537. package/Types/Rum/UserFlow.ts +187 -0
  538. package/Types/Runbook/RunbookStepType.ts +10 -0
  539. package/Types/Runbook/RunnerJobOrigin.ts +15 -0
  540. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
  541. package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
  542. package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
  543. package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
  544. package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
  545. package/Types/Timezone.ts +5 -0
  546. package/Types/TimezoneAlias.ts +385 -0
  547. package/Types/Workflow/Templates.ts +3041 -2
  548. package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
  549. package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
  550. package/Typings/Index.d.ts +24 -0
  551. package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
  552. package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
  553. package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
  554. package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
  555. package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
  556. package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
  557. package/UI/Components/Calendar/Calendar.css +83 -0
  558. package/UI/Components/Calendar/Calendar.tsx +136 -7
  559. package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
  560. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
  561. package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
  562. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
  563. package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
  564. package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
  565. package/UI/Components/Dropdown/Dropdown.tsx +58 -9
  566. package/UI/Components/Forms/Fields/FormField.tsx +49 -14
  567. package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
  568. package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
  569. package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
  570. package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
  571. package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
  572. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
  573. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
  574. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
  575. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
  576. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
  577. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
  578. package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
  579. package/UI/Components/ModelTable/BaseModelTable.tsx +66 -14
  580. package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
  581. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
  582. package/UI/Components/Page/ModelPage.tsx +59 -3
  583. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
  584. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
  585. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
  586. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
  587. package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
  588. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
  589. package/UI/Utils/Timezone.ts +69 -28
  590. package/Utils/AI/InvestigationReport.ts +195 -25
  591. package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
  592. package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
  593. package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
  594. package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
  595. package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
  596. package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
  597. package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
  598. package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
  599. package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
  600. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
  601. package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
  602. package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
  603. package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
  604. package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
  605. package/Utils/Rum/SessionIdentity.ts +44 -0
  606. package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
  607. package/Utils/Rum/UserFlow.ts +1527 -0
  608. package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
  609. package/Utils/StatusPage/ResourceUptime.ts +99 -0
  610. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
  611. package/Utils/Telemetry/AttributesJSON.ts +367 -0
  612. package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
  613. package/Utils/Uptime/UptimeUtil.ts +122 -38
  614. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
  615. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  616. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  617. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  618. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
  619. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  620. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
  621. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  622. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
  623. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  624. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
  625. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  626. package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
  627. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  628. package/build/dist/Models/DatabaseModels/Runner.js +4 -4
  629. package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
  630. package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
  631. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  632. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
  633. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  634. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
  635. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  636. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
  637. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  638. package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
  639. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  640. package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
  641. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  642. package/build/dist/Server/API/CommonAPI.js +49 -0
  643. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  644. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
  645. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
  646. package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
  647. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  648. package/build/dist/Server/API/MonitorAPI.js +107 -1
  649. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  650. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
  651. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
  652. package/build/dist/Server/API/SlackAPI.js +322 -78
  653. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  654. package/build/dist/Server/API/StatusPageAPI.js +123 -17
  655. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  656. package/build/dist/Server/API/TelemetryAPI.js +144 -5
  657. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  658. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
  659. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
  660. package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
  661. package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
  662. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  663. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  664. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
  665. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
  666. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
  667. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
  668. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
  669. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
  670. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
  671. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
  672. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
  673. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js.map +1 -0
  674. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  675. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  676. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +21 -0
  677. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  678. package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
  679. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  680. package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
  681. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  682. package/build/dist/Server/Services/AIAgentService.js +1 -0
  683. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  684. package/build/dist/Server/Services/AccessTokenService.js +87 -42
  685. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  686. package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
  687. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  688. package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
  689. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  690. package/build/dist/Server/Services/AlertService.js +110 -23
  691. package/build/dist/Server/Services/AlertService.js.map +1 -1
  692. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
  693. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  694. package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
  695. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  696. package/build/dist/Server/Services/BillingService.js +1 -0
  697. package/build/dist/Server/Services/BillingService.js.map +1 -1
  698. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
  699. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
  700. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
  701. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  702. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
  703. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  704. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
  705. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
  706. package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
  707. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  708. package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
  709. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/IncidentMemberService.js +14 -0
  711. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  712. package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
  713. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  714. package/build/dist/Server/Services/IncidentService.js +99 -21
  715. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  716. package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
  717. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  718. package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
  719. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  720. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
  721. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
  722. package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
  723. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  724. package/build/dist/Server/Services/LogAggregationService.js +14 -6
  725. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  726. package/build/dist/Server/Services/MonitorService.js +487 -48
  727. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  728. package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
  729. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  730. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
  731. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  732. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
  733. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  734. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
  735. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  736. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
  737. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  738. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
  739. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
  740. package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
  741. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
  742. package/build/dist/Server/Services/ProbeService.js +7 -1
  743. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  744. package/build/dist/Server/Services/ProjectService.js +11 -1
  745. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  746. package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
  747. package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
  748. package/build/dist/Server/Services/RunbookSecretService.js +44 -0
  749. package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
  750. package/build/dist/Server/Services/RunnerJobService.js +641 -21
  751. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  752. package/build/dist/Server/Services/RunnerService.js +344 -5
  753. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  754. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
  755. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  756. package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
  757. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  758. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
  759. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  760. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
  761. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  762. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
  763. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  764. package/build/dist/Server/Services/StatusPageService.js +230 -32
  765. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  766. package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
  767. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  768. package/build/dist/Server/Services/TeamMemberService.js +270 -11
  769. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  770. package/build/dist/Server/Services/TraceAggregationService.js +10 -6
  771. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  772. package/build/dist/Server/Services/UserEmailService.js +1 -0
  773. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  774. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
  775. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
  776. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
  777. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
  778. package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
  779. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  780. package/build/dist/Server/Services/UserService.js +107 -1
  781. package/build/dist/Server/Services/UserService.js.map +1 -1
  782. package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
  783. package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
  784. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
  785. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  786. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
  787. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  788. package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
  789. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  790. package/build/dist/Server/Types/Markdown.js +394 -27
  791. package/build/dist/Server/Types/Markdown.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
  793. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
  794. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
  795. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
  796. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
  797. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
  798. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
  799. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
  800. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
  801. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  802. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
  803. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  804. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
  805. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  806. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
  807. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  808. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
  809. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  810. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
  811. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  812. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
  813. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  814. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
  815. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  816. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
  817. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  818. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
  819. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
  820. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
  821. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  822. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
  823. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  824. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
  825. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  826. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
  827. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  828. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
  829. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  830. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
  831. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
  832. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
  833. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
  834. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
  835. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
  836. package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
  837. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  838. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
  839. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  840. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
  841. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
  842. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
  843. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  844. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
  845. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
  846. package/build/dist/Server/Utils/StartServer.js +4 -3
  847. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  848. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
  849. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
  850. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
  851. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
  852. package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
  853. package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
  854. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
  855. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
  856. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
  857. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
  858. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
  859. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  860. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
  861. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  862. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
  863. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  864. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
  865. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  866. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
  867. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
  868. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
  869. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  870. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
  871. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  872. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
  873. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
  874. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
  875. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
  876. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
  877. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  878. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
  879. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  880. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
  881. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
  882. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
  883. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  884. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
  885. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
  886. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
  887. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  888. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
  889. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
  890. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
  891. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
  892. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
  893. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  894. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
  895. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  896. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  897. package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
  898. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
  899. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
  900. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
  901. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
  902. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  903. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
  904. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
  905. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
  906. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
  907. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
  908. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
  909. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
  910. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  911. package/build/dist/Types/Date.js +97 -7
  912. package/build/dist/Types/Date.js.map +1 -1
  913. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  914. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  915. package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
  916. package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
  917. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
  918. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
  919. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
  920. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
  921. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
  922. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
  923. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
  924. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
  925. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
  926. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  927. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
  928. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
  929. package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
  930. package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
  931. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
  932. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  933. package/build/dist/Types/Rum/SessionReplay.js +52 -2
  934. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  935. package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
  936. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  937. package/build/dist/Types/Rum/UserFlow.js +115 -0
  938. package/build/dist/Types/Rum/UserFlow.js.map +1 -0
  939. package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
  940. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  941. package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
  942. package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
  943. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
  944. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
  945. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
  946. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
  947. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
  948. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
  949. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
  950. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  951. package/build/dist/Types/Timezone.js +5 -0
  952. package/build/dist/Types/Timezone.js.map +1 -1
  953. package/build/dist/Types/TimezoneAlias.js +340 -0
  954. package/build/dist/Types/TimezoneAlias.js.map +1 -0
  955. package/build/dist/Types/Workflow/Templates.js +2694 -2
  956. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  957. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
  958. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
  959. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
  960. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
  961. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
  962. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
  963. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
  964. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
  965. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
  966. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
  967. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
  968. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
  969. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
  970. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
  971. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
  972. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
  973. package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
  974. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  975. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
  976. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
  977. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
  978. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  979. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
  980. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
  981. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
  982. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
  983. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
  984. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
  985. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
  986. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
  987. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
  988. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  989. package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
  990. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  991. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
  992. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  993. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
  994. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  995. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
  996. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
  997. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  998. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
  999. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
  1000. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
  1001. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  1002. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
  1003. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  1004. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  1005. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  1006. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
  1007. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  1008. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
  1009. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  1010. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
  1011. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  1012. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
  1013. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
  1014. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -8
  1015. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  1016. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
  1017. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  1018. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
  1019. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  1020. package/build/dist/UI/Components/Page/ModelPage.js +37 -3
  1021. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  1022. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
  1023. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  1024. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
  1025. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  1026. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  1027. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  1028. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
  1029. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  1030. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
  1031. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
  1032. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
  1033. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
  1034. package/build/dist/UI/Utils/Timezone.js +52 -17
  1035. package/build/dist/UI/Utils/Timezone.js.map +1 -1
  1036. package/build/dist/Utils/AI/InvestigationReport.js +116 -21
  1037. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  1038. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
  1039. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
  1040. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
  1041. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
  1042. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
  1043. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
  1044. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
  1045. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
  1046. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
  1047. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
  1048. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
  1049. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
  1050. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
  1051. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
  1052. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
  1053. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
  1054. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
  1055. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
  1056. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
  1057. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
  1058. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
  1059. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
  1060. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
  1061. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
  1062. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
  1063. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
  1064. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
  1065. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
  1066. package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
  1067. package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
  1068. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
  1069. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
  1070. package/build/dist/Utils/Rum/UserFlow.js +941 -0
  1071. package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
  1072. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
  1073. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
  1074. package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
  1075. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  1076. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  1077. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
  1078. package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
  1079. package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
  1080. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
  1081. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
  1082. package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
  1083. package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
  1084. package/jest.config.json +2 -1
  1085. package/package.json +2 -1
  1086. package/tsconfig.tests.json +36 -0
  1087. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
  1088. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
  1089. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
  1090. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
@@ -0,0 +1,1868 @@
1
+ import Incident from "../../../Models/DatabaseModels/Incident";
2
+ import IncidentEpisode from "../../../Models/DatabaseModels/IncidentEpisode";
3
+ import ScheduledMaintenance from "../../../Models/DatabaseModels/ScheduledMaintenance";
4
+ import ScheduledMaintenanceState from "../../../Models/DatabaseModels/ScheduledMaintenanceState";
5
+ import PublicNoteSubscriberNotificationDefault, {
6
+ IncidentEpisodeSubscriberNotificationSetting,
7
+ IncidentSubscriberNotificationSetting,
8
+ ScheduledMaintenanceStateChangeSubscriberNotificationSetting,
9
+ ScheduledMaintenanceSubscriberNotificationSetting,
10
+ ScheduledMaintenanceTargetState,
11
+ } from "../../../Types/StatusPage/PublicNoteSubscriberNotificationDefault";
12
+ import { describe, expect, test } from "@jest/globals";
13
+
14
+ /*
15
+ * A public note on an incident that was declared without notifying status
16
+ * page subscribers starts with "notify subscribers" off. Only an explicit
17
+ * "no" on the incident may turn that default off: anything unknown keeps the
18
+ * long-standing default of notifying, so a missing or unloaded incident never
19
+ * silences a note by accident.
20
+ */
21
+ describe("PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident", () => {
22
+ test("is false when the incident was declared without notifying subscribers", () => {
23
+ expect(
24
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident({
25
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
26
+ }),
27
+ ).toBe(false);
28
+ });
29
+
30
+ test("is true when the incident notified subscribers when declared", () => {
31
+ expect(
32
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident({
33
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: true,
34
+ }),
35
+ ).toBe(true);
36
+ });
37
+
38
+ test("is true when the incident setting is undefined", () => {
39
+ expect(
40
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident({
41
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: undefined,
42
+ }),
43
+ ).toBe(true);
44
+ });
45
+
46
+ test("is true when the incident setting is null, as on rows from before the setting existed", () => {
47
+ expect(
48
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident({
49
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: null,
50
+ }),
51
+ ).toBe(true);
52
+ });
53
+
54
+ test("is true when the incident setting was not selected at all", () => {
55
+ const incident: IncidentSubscriberNotificationSetting = {};
56
+
57
+ expect(
58
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
59
+ ).toBe(true);
60
+ });
61
+
62
+ test("is true when the incident could not be found", () => {
63
+ expect(
64
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(null),
65
+ ).toBe(true);
66
+ });
67
+
68
+ test("is true when there is no incident yet", () => {
69
+ expect(
70
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(
71
+ undefined,
72
+ ),
73
+ ).toBe(true);
74
+ });
75
+
76
+ test("always returns a boolean, never the raw setting", () => {
77
+ const inputs: Array<
78
+ IncidentSubscriberNotificationSetting | null | undefined
79
+ > = [
80
+ null,
81
+ undefined,
82
+ {},
83
+ { shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: null },
84
+ { shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: undefined },
85
+ { shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: true },
86
+ { shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false },
87
+ ];
88
+
89
+ for (const input of inputs) {
90
+ expect(
91
+ typeof PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(
92
+ input,
93
+ ),
94
+ ).toBe("boolean");
95
+ }
96
+ });
97
+
98
+ test("does not change the incident it reads", () => {
99
+ const incident: IncidentSubscriberNotificationSetting = {
100
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
101
+ };
102
+
103
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident);
104
+
105
+ expect(incident).toEqual({
106
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
107
+ });
108
+ });
109
+ });
110
+
111
+ describe("PublicNoteSubscriberNotificationDefault with an Incident model", () => {
112
+ test("is false for an incident declared without notifying subscribers", () => {
113
+ const incident: Incident = new Incident();
114
+ incident.shouldStatusPageSubscribersBeNotifiedOnIncidentCreated = false;
115
+
116
+ expect(
117
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
118
+ ).toBe(false);
119
+ });
120
+
121
+ test("is true for an incident that notified subscribers", () => {
122
+ const incident: Incident = new Incident();
123
+ incident.shouldStatusPageSubscribersBeNotifiedOnIncidentCreated = true;
124
+
125
+ expect(
126
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
127
+ ).toBe(true);
128
+ });
129
+
130
+ test("is true for an incident whose setting was never loaded", () => {
131
+ const incident: Incident = new Incident();
132
+
133
+ expect(
134
+ incident.shouldStatusPageSubscribersBeNotifiedOnIncidentCreated,
135
+ ).toBeUndefined();
136
+ expect(
137
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
138
+ ).toBe(true);
139
+ });
140
+
141
+ test("is false for an incident read back from API JSON with the setting off", () => {
142
+ const incident: Incident = Incident.fromJSONObject(
143
+ {
144
+ _id: "5a2b3c4d-0000-4000-8000-000000000001",
145
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
146
+ },
147
+ Incident,
148
+ );
149
+
150
+ expect(
151
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
152
+ ).toBe(false);
153
+ });
154
+
155
+ test("is true for an incident read back from API JSON without the setting", () => {
156
+ const incident: Incident = Incident.fromJSONObject(
157
+ {
158
+ _id: "5a2b3c4d-0000-4000-8000-000000000002",
159
+ title: "Checkout is slow",
160
+ },
161
+ Incident,
162
+ );
163
+
164
+ expect(
165
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(incident),
166
+ ).toBe(true);
167
+ });
168
+ });
169
+
170
+ describe("PublicNoteSubscriberNotificationDefault.quietIncidentDescription", () => {
171
+ test("is a non-empty sentence", () => {
172
+ const text: string =
173
+ PublicNoteSubscriberNotificationDefault.quietIncidentDescription;
174
+
175
+ expect(text.trim().length).toBeGreaterThan(0);
176
+ expect(text).toBe(text.trim());
177
+ expect(text).toMatch(/^[A-Z]/);
178
+ expect(text.endsWith(".")).toBe(true);
179
+ });
180
+
181
+ test("explains that subscribers were not notified when the incident was declared", () => {
182
+ const text: string =
183
+ PublicNoteSubscriberNotificationDefault.quietIncidentDescription;
184
+
185
+ expect(text).toContain("subscribers");
186
+ expect(text).toContain("declared");
187
+ expect(text).toContain("not notified");
188
+ });
189
+
190
+ test("keeps the exact wording the dashboard locale files translate", () => {
191
+ expect(
192
+ PublicNoteSubscriberNotificationDefault.quietIncidentDescription,
193
+ ).toBe(
194
+ "Unticked by default because status page subscribers were not notified when this incident was declared.",
195
+ );
196
+ });
197
+ });
198
+
199
+ /*
200
+ * The rule every event type shares: only an explicit "no" when the event
201
+ * started turns the default off.
202
+ */
203
+ describe("PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting", () => {
204
+ test("is false only for an explicit false", () => {
205
+ expect(
206
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(false),
207
+ ).toBe(false);
208
+ });
209
+
210
+ test("is true for an explicit true", () => {
211
+ expect(
212
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(true),
213
+ ).toBe(true);
214
+ });
215
+
216
+ test("is true when the setting is null, as on rows from before the setting existed", () => {
217
+ expect(
218
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(null),
219
+ ).toBe(true);
220
+ });
221
+
222
+ test("is true when the setting is unknown", () => {
223
+ expect(
224
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(undefined),
225
+ ).toBe(true);
226
+ });
227
+
228
+ test("always returns a boolean, never the raw setting", () => {
229
+ const inputs: Array<boolean | null | undefined> = [
230
+ null,
231
+ undefined,
232
+ true,
233
+ false,
234
+ ];
235
+
236
+ for (const input of inputs) {
237
+ expect(
238
+ typeof PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(
239
+ input,
240
+ ),
241
+ ).toBe("boolean");
242
+ }
243
+ });
244
+
245
+ test("the incident, episode and scheduled maintenance helpers all follow it", () => {
246
+ const flags: Array<boolean | null | undefined> = [
247
+ null,
248
+ undefined,
249
+ true,
250
+ false,
251
+ ];
252
+
253
+ for (const flag of flags) {
254
+ const expected: boolean =
255
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForSetting(flag);
256
+
257
+ expect(
258
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident({
259
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: flag,
260
+ }),
261
+ ).toBe(expected);
262
+ expect(
263
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode({
264
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: flag,
265
+ }),
266
+ ).toBe(expected);
267
+ expect(
268
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
269
+ {
270
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: flag,
271
+ },
272
+ ),
273
+ ).toBe(expected);
274
+ }
275
+ });
276
+ });
277
+
278
+ /*
279
+ * The same rule for a public note on an incident episode: it follows whether
280
+ * subscribers were told the episode was created.
281
+ */
282
+ describe("PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode", () => {
283
+ test("is false when the episode was created without notifying subscribers", () => {
284
+ expect(
285
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode({
286
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
287
+ }),
288
+ ).toBe(false);
289
+ });
290
+
291
+ test("is true when the episode notified subscribers when created", () => {
292
+ expect(
293
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode({
294
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: true,
295
+ }),
296
+ ).toBe(true);
297
+ });
298
+
299
+ test("is true when the episode setting is undefined", () => {
300
+ expect(
301
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode({
302
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: undefined,
303
+ }),
304
+ ).toBe(true);
305
+ });
306
+
307
+ test("is true when the episode setting is null, as on rows from before the setting existed", () => {
308
+ expect(
309
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode({
310
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: null,
311
+ }),
312
+ ).toBe(true);
313
+ });
314
+
315
+ test("is true when the episode setting was not selected at all", () => {
316
+ const episode: IncidentEpisodeSubscriberNotificationSetting = {};
317
+
318
+ expect(
319
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
320
+ episode,
321
+ ),
322
+ ).toBe(true);
323
+ });
324
+
325
+ test("is true when the episode could not be found", () => {
326
+ expect(
327
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
328
+ null,
329
+ ),
330
+ ).toBe(true);
331
+ });
332
+
333
+ test("is true when there is no episode yet", () => {
334
+ expect(
335
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
336
+ undefined,
337
+ ),
338
+ ).toBe(true);
339
+ });
340
+
341
+ test("always returns a boolean, never the raw setting", () => {
342
+ const inputs: Array<
343
+ IncidentEpisodeSubscriberNotificationSetting | null | undefined
344
+ > = [
345
+ null,
346
+ undefined,
347
+ {},
348
+ { shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: null },
349
+ { shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: undefined },
350
+ { shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: true },
351
+ { shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false },
352
+ ];
353
+
354
+ for (const input of inputs) {
355
+ expect(
356
+ typeof PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
357
+ input,
358
+ ),
359
+ ).toBe("boolean");
360
+ }
361
+ });
362
+
363
+ test("does not change the episode it reads", () => {
364
+ const episode: IncidentEpisodeSubscriberNotificationSetting = {
365
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
366
+ };
367
+
368
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
369
+ episode,
370
+ );
371
+
372
+ expect(episode).toEqual({
373
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
374
+ });
375
+ });
376
+ });
377
+
378
+ describe("PublicNoteSubscriberNotificationDefault with an IncidentEpisode model", () => {
379
+ test("is false for an episode created without notifying subscribers", () => {
380
+ const episode: IncidentEpisode = new IncidentEpisode();
381
+ episode.shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated = false;
382
+
383
+ expect(
384
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
385
+ episode,
386
+ ),
387
+ ).toBe(false);
388
+ });
389
+
390
+ test("is true for an episode that notified subscribers", () => {
391
+ const episode: IncidentEpisode = new IncidentEpisode();
392
+ episode.shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated = true;
393
+
394
+ expect(
395
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
396
+ episode,
397
+ ),
398
+ ).toBe(true);
399
+ });
400
+
401
+ test("is true for an episode whose setting was never loaded", () => {
402
+ const episode: IncidentEpisode = new IncidentEpisode();
403
+
404
+ expect(
405
+ episode.shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated,
406
+ ).toBeUndefined();
407
+ expect(
408
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
409
+ episode,
410
+ ),
411
+ ).toBe(true);
412
+ });
413
+
414
+ test("is false for an episode read back from API JSON with the setting off", () => {
415
+ const episode: IncidentEpisode = IncidentEpisode.fromJSONObject(
416
+ {
417
+ _id: "5a2b3c4d-0000-4000-8000-000000000011",
418
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
419
+ },
420
+ IncidentEpisode,
421
+ );
422
+
423
+ expect(
424
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
425
+ episode,
426
+ ),
427
+ ).toBe(false);
428
+ });
429
+
430
+ test("is true for an episode read back from API JSON with the setting on", () => {
431
+ const episode: IncidentEpisode = IncidentEpisode.fromJSONObject(
432
+ {
433
+ _id: "5a2b3c4d-0000-4000-8000-000000000012",
434
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: true,
435
+ },
436
+ IncidentEpisode,
437
+ );
438
+
439
+ expect(
440
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
441
+ episode,
442
+ ),
443
+ ).toBe(true);
444
+ });
445
+
446
+ test("is true for an episode read back from API JSON without the setting", () => {
447
+ const episode: IncidentEpisode = IncidentEpisode.fromJSONObject(
448
+ {
449
+ _id: "5a2b3c4d-0000-4000-8000-000000000013",
450
+ title: "Checkout and payments are down",
451
+ },
452
+ IncidentEpisode,
453
+ );
454
+
455
+ expect(
456
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
457
+ episode,
458
+ ),
459
+ ).toBe(true);
460
+ });
461
+ });
462
+
463
+ /*
464
+ * And for a public note on a scheduled maintenance event: it follows whether
465
+ * subscribers were told the event was created.
466
+ */
467
+ describe("PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance", () => {
468
+ test("is false when the event was created without notifying subscribers", () => {
469
+ expect(
470
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
471
+ {
472
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
473
+ },
474
+ ),
475
+ ).toBe(false);
476
+ });
477
+
478
+ test("is true when the event notified subscribers when created", () => {
479
+ expect(
480
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
481
+ {
482
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: true,
483
+ },
484
+ ),
485
+ ).toBe(true);
486
+ });
487
+
488
+ test("is true when the event setting is undefined", () => {
489
+ expect(
490
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
491
+ {
492
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: undefined,
493
+ },
494
+ ),
495
+ ).toBe(true);
496
+ });
497
+
498
+ test("is true when the event setting is null, as on rows from before the setting existed", () => {
499
+ expect(
500
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
501
+ {
502
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: null,
503
+ },
504
+ ),
505
+ ).toBe(true);
506
+ });
507
+
508
+ test("is true when the event setting was not selected at all", () => {
509
+ const scheduledMaintenance: ScheduledMaintenanceSubscriberNotificationSetting =
510
+ {};
511
+
512
+ expect(
513
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
514
+ scheduledMaintenance,
515
+ ),
516
+ ).toBe(true);
517
+ });
518
+
519
+ test("is true when the event could not be found", () => {
520
+ expect(
521
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
522
+ null,
523
+ ),
524
+ ).toBe(true);
525
+ });
526
+
527
+ test("is true when there is no event yet", () => {
528
+ expect(
529
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
530
+ undefined,
531
+ ),
532
+ ).toBe(true);
533
+ });
534
+
535
+ test("always returns a boolean, never the raw setting", () => {
536
+ const inputs: Array<
537
+ ScheduledMaintenanceSubscriberNotificationSetting | null | undefined
538
+ > = [
539
+ null,
540
+ undefined,
541
+ {},
542
+ { shouldStatusPageSubscribersBeNotifiedOnEventCreated: null },
543
+ { shouldStatusPageSubscribersBeNotifiedOnEventCreated: undefined },
544
+ { shouldStatusPageSubscribersBeNotifiedOnEventCreated: true },
545
+ { shouldStatusPageSubscribersBeNotifiedOnEventCreated: false },
546
+ ];
547
+
548
+ for (const input of inputs) {
549
+ expect(
550
+ typeof PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
551
+ input,
552
+ ),
553
+ ).toBe("boolean");
554
+ }
555
+ });
556
+
557
+ test("does not change the event it reads", () => {
558
+ const scheduledMaintenance: ScheduledMaintenanceSubscriberNotificationSetting =
559
+ {
560
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
561
+ };
562
+
563
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
564
+ scheduledMaintenance,
565
+ );
566
+
567
+ expect(scheduledMaintenance).toEqual({
568
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
569
+ });
570
+ });
571
+
572
+ test("only reads the event-created setting, not the ongoing or ended ones", () => {
573
+ const scheduledMaintenance: ScheduledMaintenance =
574
+ new ScheduledMaintenance();
575
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing =
576
+ false;
577
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded =
578
+ false;
579
+
580
+ expect(
581
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
582
+ scheduledMaintenance,
583
+ ),
584
+ ).toBe(true);
585
+ });
586
+ });
587
+
588
+ describe("PublicNoteSubscriberNotificationDefault with a ScheduledMaintenance model", () => {
589
+ test("is false for an event created without notifying subscribers", () => {
590
+ const scheduledMaintenance: ScheduledMaintenance =
591
+ new ScheduledMaintenance();
592
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedOnEventCreated =
593
+ false;
594
+
595
+ expect(
596
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
597
+ scheduledMaintenance,
598
+ ),
599
+ ).toBe(false);
600
+ });
601
+
602
+ test("is true for an event that notified subscribers", () => {
603
+ const scheduledMaintenance: ScheduledMaintenance =
604
+ new ScheduledMaintenance();
605
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedOnEventCreated =
606
+ true;
607
+
608
+ expect(
609
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
610
+ scheduledMaintenance,
611
+ ),
612
+ ).toBe(true);
613
+ });
614
+
615
+ test("is true for an event whose setting was never loaded", () => {
616
+ const scheduledMaintenance: ScheduledMaintenance =
617
+ new ScheduledMaintenance();
618
+
619
+ expect(
620
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedOnEventCreated,
621
+ ).toBeUndefined();
622
+ expect(
623
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
624
+ scheduledMaintenance,
625
+ ),
626
+ ).toBe(true);
627
+ });
628
+
629
+ test("is false for an event read back from API JSON with the setting off", () => {
630
+ const scheduledMaintenance: ScheduledMaintenance =
631
+ ScheduledMaintenance.fromJSONObject(
632
+ {
633
+ _id: "5a2b3c4d-0000-4000-8000-000000000021",
634
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
635
+ },
636
+ ScheduledMaintenance,
637
+ );
638
+
639
+ expect(
640
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
641
+ scheduledMaintenance,
642
+ ),
643
+ ).toBe(false);
644
+ });
645
+
646
+ test("is true for an event read back from API JSON with the setting on", () => {
647
+ const scheduledMaintenance: ScheduledMaintenance =
648
+ ScheduledMaintenance.fromJSONObject(
649
+ {
650
+ _id: "5a2b3c4d-0000-4000-8000-000000000022",
651
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: true,
652
+ },
653
+ ScheduledMaintenance,
654
+ );
655
+
656
+ expect(
657
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
658
+ scheduledMaintenance,
659
+ ),
660
+ ).toBe(true);
661
+ });
662
+
663
+ test("is true for an event read back from API JSON without the setting", () => {
664
+ const scheduledMaintenance: ScheduledMaintenance =
665
+ ScheduledMaintenance.fromJSONObject(
666
+ {
667
+ _id: "5a2b3c4d-0000-4000-8000-000000000023",
668
+ title: "Database upgrade",
669
+ },
670
+ ScheduledMaintenance,
671
+ );
672
+
673
+ expect(
674
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
675
+ scheduledMaintenance,
676
+ ),
677
+ ).toBe(true);
678
+ });
679
+ });
680
+
681
+ /*
682
+ * Each helper reads only its own event's setting. A quiet flag that belongs
683
+ * to a different kind of event must not silence the note.
684
+ */
685
+ describe("PublicNoteSubscriberNotificationDefault reads only its own event's setting", () => {
686
+ type EveryEventSetting = IncidentSubscriberNotificationSetting &
687
+ IncidentEpisodeSubscriberNotificationSetting &
688
+ ScheduledMaintenanceSubscriberNotificationSetting;
689
+
690
+ test("the incident helper ignores the episode and scheduled maintenance settings", () => {
691
+ const setting: EveryEventSetting = {
692
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
693
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
694
+ };
695
+
696
+ expect(
697
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(setting),
698
+ ).toBe(true);
699
+ });
700
+
701
+ test("the episode helper ignores the incident and scheduled maintenance settings", () => {
702
+ const setting: EveryEventSetting = {
703
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
704
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
705
+ };
706
+
707
+ expect(
708
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
709
+ setting,
710
+ ),
711
+ ).toBe(true);
712
+ });
713
+
714
+ test("the scheduled maintenance helper ignores the incident and episode settings", () => {
715
+ const setting: EveryEventSetting = {
716
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
717
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: false,
718
+ };
719
+
720
+ expect(
721
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
722
+ setting,
723
+ ),
724
+ ).toBe(true);
725
+ });
726
+
727
+ test("each helper turns off for its own setting alone", () => {
728
+ const setting: EveryEventSetting = {
729
+ shouldStatusPageSubscribersBeNotifiedOnIncidentCreated: false,
730
+ shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated: true,
731
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: true,
732
+ };
733
+
734
+ expect(
735
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(setting),
736
+ ).toBe(false);
737
+ expect(
738
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
739
+ setting,
740
+ ),
741
+ ).toBe(true);
742
+ expect(
743
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
744
+ setting,
745
+ ),
746
+ ).toBe(true);
747
+ });
748
+
749
+ test("an incident model with its setting off does not silence an episode or scheduled maintenance note", () => {
750
+ const incident: Incident = new Incident();
751
+ incident.shouldStatusPageSubscribersBeNotifiedOnIncidentCreated = false;
752
+
753
+ expect(
754
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
755
+ incident as unknown as IncidentEpisodeSubscriberNotificationSetting,
756
+ ),
757
+ ).toBe(true);
758
+ expect(
759
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
760
+ incident as unknown as ScheduledMaintenanceSubscriberNotificationSetting,
761
+ ),
762
+ ).toBe(true);
763
+ });
764
+
765
+ test("an episode or scheduled maintenance model with its setting off does not silence an incident note", () => {
766
+ const episode: IncidentEpisode = new IncidentEpisode();
767
+ episode.shouldStatusPageSubscribersBeNotifiedOnEpisodeCreated = false;
768
+
769
+ const scheduledMaintenance: ScheduledMaintenance =
770
+ new ScheduledMaintenance();
771
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedOnEventCreated =
772
+ false;
773
+
774
+ expect(
775
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(
776
+ episode as unknown as IncidentSubscriberNotificationSetting,
777
+ ),
778
+ ).toBe(true);
779
+ expect(
780
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncident(
781
+ scheduledMaintenance as unknown as IncidentSubscriberNotificationSetting,
782
+ ),
783
+ ).toBe(true);
784
+ expect(
785
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
786
+ episode as unknown as ScheduledMaintenanceSubscriberNotificationSetting,
787
+ ),
788
+ ).toBe(true);
789
+ expect(
790
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForIncidentEpisode(
791
+ scheduledMaintenance as unknown as IncidentEpisodeSubscriberNotificationSetting,
792
+ ),
793
+ ).toBe(true);
794
+ });
795
+ });
796
+
797
+ describe("PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription", () => {
798
+ test("is a non-empty sentence", () => {
799
+ const text: string =
800
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription;
801
+
802
+ expect(text.trim().length).toBeGreaterThan(0);
803
+ expect(text).toBe(text.trim());
804
+ expect(text).toMatch(/^[A-Z]/);
805
+ expect(text.endsWith(".")).toBe(true);
806
+ });
807
+
808
+ test("explains that subscribers were not notified when the episode was created", () => {
809
+ const text: string =
810
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription;
811
+
812
+ expect(text).toContain("subscribers");
813
+ expect(text).toContain("episode");
814
+ expect(text).toContain("created");
815
+ expect(text).toContain("not notified");
816
+ });
817
+
818
+ test("keeps the exact wording the dashboard locale files translate", () => {
819
+ expect(
820
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription,
821
+ ).toBe(
822
+ "Unticked by default because status page subscribers were not notified when this episode was created.",
823
+ );
824
+ });
825
+ });
826
+
827
+ describe("PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription", () => {
828
+ test("is a non-empty sentence", () => {
829
+ const text: string =
830
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription;
831
+
832
+ expect(text.trim().length).toBeGreaterThan(0);
833
+ expect(text).toBe(text.trim());
834
+ expect(text).toMatch(/^[A-Z]/);
835
+ expect(text.endsWith(".")).toBe(true);
836
+ });
837
+
838
+ test("explains that subscribers were not notified when the event was created", () => {
839
+ const text: string =
840
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription;
841
+
842
+ expect(text).toContain("subscribers");
843
+ expect(text).toContain("scheduled maintenance event");
844
+ expect(text).toContain("created");
845
+ expect(text).toContain("not notified");
846
+ });
847
+
848
+ test("keeps the exact wording the dashboard locale files translate", () => {
849
+ expect(
850
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription,
851
+ ).toBe(
852
+ "Unticked by default because status page subscribers were not notified when this scheduled maintenance event was created.",
853
+ );
854
+ });
855
+ });
856
+
857
+ describe("PublicNoteSubscriberNotificationDefault quiet descriptions", () => {
858
+ test("each event type explains itself in its own words", () => {
859
+ const descriptions: Array<string> = [
860
+ PublicNoteSubscriberNotificationDefault.quietIncidentDescription,
861
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription,
862
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription,
863
+ ];
864
+
865
+ expect(new Set(descriptions).size).toBe(descriptions.length);
866
+ });
867
+
868
+ test("all start the same way, so they read as one family under the checkbox", () => {
869
+ const descriptions: Array<string> = [
870
+ PublicNoteSubscriberNotificationDefault.quietIncidentDescription,
871
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription,
872
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription,
873
+ ];
874
+
875
+ for (const description of descriptions) {
876
+ expect(
877
+ description.startsWith(
878
+ "Unticked by default because status page subscribers were not notified when this ",
879
+ ),
880
+ ).toBe(true);
881
+ }
882
+ });
883
+
884
+ test("the episode and scheduled maintenance descriptions do not talk about declaring an incident", () => {
885
+ expect(
886
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription,
887
+ ).not.toContain("incident");
888
+ expect(
889
+ PublicNoteSubscriberNotificationDefault.quietIncidentEpisodeDescription,
890
+ ).not.toContain("declared");
891
+ expect(
892
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription,
893
+ ).not.toContain("incident");
894
+ expect(
895
+ PublicNoteSubscriberNotificationDefault.quietScheduledMaintenanceDescription,
896
+ ).not.toContain("declared");
897
+ });
898
+ });
899
+
900
+ /*
901
+ * Moving a scheduled maintenance event to another state by hand. The state
902
+ * change modal's checkbox also decides whether subscribers hear about the
903
+ * change itself, and the event has its own "Event Ongoing" and "Event Ended"
904
+ * settings that the automatic workers honour. So on an event created without
905
+ * notifying subscribers, a move into an ongoing state follows "Event Ongoing",
906
+ * a move into an ended or resolved state follows "Event Ended", and any other
907
+ * move starts unticked, like a public note. An event that notified
908
+ * subscribers when it was created keeps the old default of notifying on every
909
+ * move, whatever its Ongoing and Ended settings say.
910
+ */
911
+ describe("PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenanceStateChange", () => {
912
+ type Flag = boolean | null | undefined;
913
+
914
+ type TargetState = ScheduledMaintenanceTargetState | null | undefined;
915
+
916
+ type EventSetting =
917
+ | ScheduledMaintenanceStateChangeSubscriberNotificationSetting
918
+ | null
919
+ | undefined;
920
+
921
+ // Which of the event's own settings announces a move into a state.
922
+ type Announcement = "ongoing" | "ended" | "none";
923
+
924
+ type TargetCase = {
925
+ target: string;
926
+ targetState: TargetState;
927
+ announcement: Announcement;
928
+ };
929
+
930
+ type MatrixRow = {
931
+ created: Flag;
932
+ target: string;
933
+ targetState: TargetState;
934
+ ongoing: Flag;
935
+ ended: Flag;
936
+ expected: boolean;
937
+ };
938
+
939
+ /*
940
+ * A ScheduledMaintenanceState also says whether it is the scheduled state.
941
+ * The helper does not read that flag.
942
+ */
943
+ type TargetStateWithScheduled = ScheduledMaintenanceTargetState & {
944
+ isScheduledState?: boolean | null | undefined;
945
+ };
946
+
947
+ const flags: Array<Flag> = [true, false, null, undefined];
948
+
949
+ // Every Event Created value except an explicit "no".
950
+ const notifyingCreatedFlags: Array<Flag> = [true, undefined, null];
951
+
952
+ const createdFlags: Array<Flag> = [...notifyingCreatedFlags, false];
953
+
954
+ const ongoingState: ScheduledMaintenanceTargetState = {
955
+ isOngoingState: true,
956
+ };
957
+
958
+ const endedState: ScheduledMaintenanceTargetState = {
959
+ isEndedState: true,
960
+ };
961
+
962
+ const resolvedState: ScheduledMaintenanceTargetState = {
963
+ isResolvedState: true,
964
+ };
965
+
966
+ const scheduledState: TargetStateWithScheduled = {
967
+ isScheduledState: true,
968
+ isOngoingState: false,
969
+ isEndedState: false,
970
+ isResolvedState: false,
971
+ };
972
+
973
+ const targetCases: Array<TargetCase> = [
974
+ {
975
+ target: "an ongoing state",
976
+ targetState: ongoingState,
977
+ announcement: "ongoing",
978
+ },
979
+ {
980
+ target: "an ongoing state with every other flag off",
981
+ targetState: {
982
+ isOngoingState: true,
983
+ isEndedState: false,
984
+ isResolvedState: false,
985
+ },
986
+ announcement: "ongoing",
987
+ },
988
+ {
989
+ target: "an ended state",
990
+ targetState: endedState,
991
+ announcement: "ended",
992
+ },
993
+ {
994
+ target: "a resolved state",
995
+ targetState: resolvedState,
996
+ announcement: "ended",
997
+ },
998
+ {
999
+ target: "a state that is both ended and resolved",
1000
+ targetState: { isEndedState: true, isResolvedState: true },
1001
+ announcement: "ended",
1002
+ },
1003
+ {
1004
+ target: "a resolved state whose ended flag is off",
1005
+ targetState: {
1006
+ isOngoingState: false,
1007
+ isEndedState: false,
1008
+ isResolvedState: true,
1009
+ },
1010
+ announcement: "ended",
1011
+ },
1012
+ {
1013
+ // The helper checks ongoing first.
1014
+ target: "a state flagged both ongoing and ended",
1015
+ targetState: { isOngoingState: true, isEndedState: true },
1016
+ announcement: "ongoing",
1017
+ },
1018
+ {
1019
+ target: "the scheduled state",
1020
+ targetState: scheduledState,
1021
+ announcement: "none",
1022
+ },
1023
+ {
1024
+ target: "a custom state with no flags",
1025
+ targetState: {},
1026
+ announcement: "none",
1027
+ },
1028
+ {
1029
+ target: "a custom state with every flag off",
1030
+ targetState: {
1031
+ isOngoingState: false,
1032
+ isEndedState: false,
1033
+ isResolvedState: false,
1034
+ },
1035
+ announcement: "none",
1036
+ },
1037
+ {
1038
+ target: "a custom state with every flag null",
1039
+ targetState: {
1040
+ isOngoingState: null,
1041
+ isEndedState: null,
1042
+ isResolvedState: null,
1043
+ },
1044
+ announcement: "none",
1045
+ },
1046
+ {
1047
+ target: "an unknown state (null)",
1048
+ targetState: null,
1049
+ announcement: "none",
1050
+ },
1051
+ {
1052
+ target: "an unknown state (undefined)",
1053
+ targetState: undefined,
1054
+ announcement: "none",
1055
+ },
1056
+ ];
1057
+
1058
+ const announcedTargetCases: Array<TargetCase> = targetCases.filter(
1059
+ (targetCase: TargetCase) => {
1060
+ return targetCase.announcement !== "none";
1061
+ },
1062
+ );
1063
+
1064
+ const unannouncedTargetCases: Array<TargetCase> = targetCases.filter(
1065
+ (targetCase: TargetCase) => {
1066
+ return targetCase.announcement === "none";
1067
+ },
1068
+ );
1069
+
1070
+ const makeEvent: (
1071
+ created: Flag,
1072
+ ongoing: Flag,
1073
+ ended: Flag,
1074
+ ) => ScheduledMaintenanceStateChangeSubscriberNotificationSetting = (
1075
+ created: Flag,
1076
+ ongoing: Flag,
1077
+ ended: Flag,
1078
+ ): ScheduledMaintenanceStateChangeSubscriberNotificationSetting => {
1079
+ return {
1080
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: created,
1081
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing: ongoing,
1082
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded: ended,
1083
+ };
1084
+ };
1085
+
1086
+ const shouldNotify: (
1087
+ event: EventSetting,
1088
+ targetState: TargetState,
1089
+ ) => boolean = (event: EventSetting, targetState: TargetState): boolean => {
1090
+ return PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenanceStateChange(
1091
+ event,
1092
+ targetState,
1093
+ );
1094
+ };
1095
+
1096
+ /*
1097
+ * An unknown (null or undefined) setting keeps the long-standing default of
1098
+ * notifying; only an explicit false turns it off. Written out as a table so
1099
+ * the matrix below checks the helper against the rule rather than against a
1100
+ * copy of its code.
1101
+ */
1102
+ const settingStartsTicked: Map<Flag, boolean> = new Map<Flag, boolean>([
1103
+ [true, true],
1104
+ [false, false],
1105
+ [null, true],
1106
+ [undefined, true],
1107
+ ]);
1108
+
1109
+ const expectedDefault: (
1110
+ created: Flag,
1111
+ announcement: Announcement,
1112
+ ongoing: Flag,
1113
+ ended: Flag,
1114
+ ) => boolean = (
1115
+ created: Flag,
1116
+ announcement: Announcement,
1117
+ ongoing: Flag,
1118
+ ended: Flag,
1119
+ ): boolean => {
1120
+ if (notifyingCreatedFlags.includes(created)) {
1121
+ return true;
1122
+ }
1123
+
1124
+ if (announcement === "ongoing") {
1125
+ return settingStartsTicked.get(ongoing) === true;
1126
+ }
1127
+
1128
+ if (announcement === "ended") {
1129
+ return settingStartsTicked.get(ended) === true;
1130
+ }
1131
+
1132
+ return false;
1133
+ };
1134
+
1135
+ const matrix: Array<MatrixRow> = [];
1136
+
1137
+ for (const created of createdFlags) {
1138
+ for (const targetCase of targetCases) {
1139
+ for (const ongoing of flags) {
1140
+ for (const ended of flags) {
1141
+ matrix.push({
1142
+ created: created,
1143
+ target: targetCase.target,
1144
+ targetState: targetCase.targetState,
1145
+ ongoing: ongoing,
1146
+ ended: ended,
1147
+ expected: expectedDefault(
1148
+ created,
1149
+ targetCase.announcement,
1150
+ ongoing,
1151
+ ended,
1152
+ ),
1153
+ });
1154
+ }
1155
+ }
1156
+ }
1157
+ }
1158
+
1159
+ describe("across every combination", () => {
1160
+ test("covers every Event Created, target state, Event Ongoing and Event Ended value", () => {
1161
+ expect(matrix).toHaveLength(
1162
+ createdFlags.length * targetCases.length * flags.length * flags.length,
1163
+ );
1164
+ });
1165
+
1166
+ // One test over the whole matrix, listing every row that disagrees.
1167
+ test("matches the rule for every combination", () => {
1168
+ const mismatches: Array<string> = matrix
1169
+ .filter((row: MatrixRow): boolean => {
1170
+ return (
1171
+ shouldNotify(
1172
+ makeEvent(row.created, row.ongoing, row.ended),
1173
+ row.targetState,
1174
+ ) !== row.expected
1175
+ );
1176
+ })
1177
+ .map((row: MatrixRow): string => {
1178
+ return `moving to ${row.target} with Event Created ${String(row.created)}, Event Ongoing ${String(row.ongoing)} and Event Ended ${String(row.ended)} should start ticked: ${String(row.expected)}`;
1179
+ });
1180
+
1181
+ expect(mismatches).toEqual([]);
1182
+ });
1183
+ });
1184
+
1185
+ describe("on an event that notified subscribers when it was created", () => {
1186
+ type NotifyingRow = {
1187
+ created: Flag;
1188
+ target: string;
1189
+ targetState: TargetState;
1190
+ };
1191
+
1192
+ const notifyingRows: Array<NotifyingRow> = [];
1193
+
1194
+ for (const created of notifyingCreatedFlags) {
1195
+ for (const targetCase of targetCases) {
1196
+ notifyingRows.push({
1197
+ created: created,
1198
+ target: targetCase.target,
1199
+ targetState: targetCase.targetState,
1200
+ });
1201
+ }
1202
+ }
1203
+
1204
+ test.each(notifyingRows)(
1205
+ "keeps the old default of notifying when moving to $target with Event Created $created, whatever Event Ongoing and Event Ended say",
1206
+ (row: NotifyingRow) => {
1207
+ for (const ongoing of flags) {
1208
+ for (const ended of flags) {
1209
+ expect(
1210
+ shouldNotify(
1211
+ makeEvent(row.created, ongoing, ended),
1212
+ row.targetState,
1213
+ ),
1214
+ ).toBe(true);
1215
+ }
1216
+ }
1217
+ },
1218
+ );
1219
+
1220
+ test("is true even with Event Ongoing and Event Ended both off", () => {
1221
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1222
+ makeEvent(true, false, false);
1223
+
1224
+ expect(shouldNotify(event, ongoingState)).toBe(true);
1225
+ expect(shouldNotify(event, endedState)).toBe(true);
1226
+ expect(shouldNotify(event, resolvedState)).toBe(true);
1227
+ expect(shouldNotify(event, scheduledState)).toBe(true);
1228
+ expect(shouldNotify(event, {})).toBe(true);
1229
+ expect(shouldNotify(event, null)).toBe(true);
1230
+ expect(shouldNotify(event, undefined)).toBe(true);
1231
+ });
1232
+
1233
+ test("is true for an event whose Event Created setting was not loaded, even with Event Ongoing and Event Ended off", () => {
1234
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1235
+ {
1236
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing: false,
1237
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded: false,
1238
+ };
1239
+
1240
+ for (const targetCase of targetCases) {
1241
+ expect(shouldNotify(event, targetCase.targetState)).toBe(true);
1242
+ }
1243
+ });
1244
+ });
1245
+
1246
+ describe("on an event created without notifying subscribers", () => {
1247
+ /*
1248
+ * [Event Ongoing, Event Ended, starts ticked] for a move into an ongoing
1249
+ * state: only the Event Ongoing column matters.
1250
+ */
1251
+ const quietMoveToOngoing: Array<[Flag, Flag, boolean]> = [
1252
+ [true, true, true],
1253
+ [true, false, true],
1254
+ [true, null, true],
1255
+ [true, undefined, true],
1256
+ [false, true, false],
1257
+ [false, false, false],
1258
+ [false, null, false],
1259
+ [false, undefined, false],
1260
+ [null, true, true],
1261
+ [null, false, true],
1262
+ [null, null, true],
1263
+ [null, undefined, true],
1264
+ [undefined, true, true],
1265
+ [undefined, false, true],
1266
+ [undefined, null, true],
1267
+ [undefined, undefined, true],
1268
+ ];
1269
+
1270
+ test.each(quietMoveToOngoing)(
1271
+ "moving to an ongoing state with Event Ongoing %p and Event Ended %p starts ticked: %p",
1272
+ (ongoing: Flag, ended: Flag, expected: boolean) => {
1273
+ expect(
1274
+ shouldNotify(makeEvent(false, ongoing, ended), ongoingState),
1275
+ ).toBe(expected);
1276
+ },
1277
+ );
1278
+
1279
+ /*
1280
+ * [Event Ongoing, Event Ended, starts ticked] for a move into an ended or
1281
+ * resolved state: only the Event Ended column matters.
1282
+ */
1283
+ const quietMoveToEnded: Array<[Flag, Flag, boolean]> = [
1284
+ [true, true, true],
1285
+ [false, true, true],
1286
+ [null, true, true],
1287
+ [undefined, true, true],
1288
+ [true, false, false],
1289
+ [false, false, false],
1290
+ [null, false, false],
1291
+ [undefined, false, false],
1292
+ [true, null, true],
1293
+ [false, null, true],
1294
+ [null, null, true],
1295
+ [undefined, null, true],
1296
+ [true, undefined, true],
1297
+ [false, undefined, true],
1298
+ [null, undefined, true],
1299
+ [undefined, undefined, true],
1300
+ ];
1301
+
1302
+ const quietEndedRows: Array<[string, TargetState, Flag, Flag, boolean]> =
1303
+ [];
1304
+
1305
+ for (const targetCase of targetCases) {
1306
+ if (targetCase.announcement !== "ended") {
1307
+ continue;
1308
+ }
1309
+
1310
+ for (const [ongoing, ended, expected] of quietMoveToEnded) {
1311
+ quietEndedRows.push([
1312
+ targetCase.target,
1313
+ targetCase.targetState,
1314
+ ongoing,
1315
+ ended,
1316
+ expected,
1317
+ ]);
1318
+ }
1319
+ }
1320
+
1321
+ test("the ended table covers ended, resolved and ended-and-resolved states", () => {
1322
+ expect(quietEndedRows).toHaveLength(4 * quietMoveToEnded.length);
1323
+ });
1324
+
1325
+ test.each(quietEndedRows)(
1326
+ "moving to %s with Event Ongoing %p and Event Ended %p starts ticked: %p",
1327
+ (
1328
+ _target: string,
1329
+ targetState: TargetState,
1330
+ ongoing: Flag,
1331
+ ended: Flag,
1332
+ expected: boolean,
1333
+ ) => {
1334
+ expect(
1335
+ shouldNotify(makeEvent(false, ongoing, ended), targetState),
1336
+ ).toBe(expected);
1337
+ },
1338
+ );
1339
+
1340
+ test("moving to an ongoing state follows Event Ongoing, not Event Ended", () => {
1341
+ expect(shouldNotify(makeEvent(false, true, false), ongoingState)).toBe(
1342
+ true,
1343
+ );
1344
+ expect(shouldNotify(makeEvent(false, false, true), ongoingState)).toBe(
1345
+ false,
1346
+ );
1347
+ });
1348
+
1349
+ test("moving to an ended state follows Event Ended, not Event Ongoing", () => {
1350
+ expect(shouldNotify(makeEvent(false, false, true), endedState)).toBe(
1351
+ true,
1352
+ );
1353
+ expect(shouldNotify(makeEvent(false, true, false), endedState)).toBe(
1354
+ false,
1355
+ );
1356
+ });
1357
+
1358
+ test("moving to a resolved state follows Event Ended, not Event Ongoing", () => {
1359
+ expect(shouldNotify(makeEvent(false, false, true), resolvedState)).toBe(
1360
+ true,
1361
+ );
1362
+ expect(shouldNotify(makeEvent(false, true, false), resolvedState)).toBe(
1363
+ false,
1364
+ );
1365
+ });
1366
+
1367
+ test("marking an event ended early still tells subscribers when Event Ended is on", () => {
1368
+ // Created quietly, set to announce going ongoing and ending.
1369
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1370
+ makeEvent(false, true, true);
1371
+
1372
+ expect(shouldNotify(event, endedState)).toBe(true);
1373
+ expect(shouldNotify(event, resolvedState)).toBe(true);
1374
+ expect(shouldNotify(event, ongoingState)).toBe(true);
1375
+ });
1376
+
1377
+ test.each(unannouncedTargetCases)(
1378
+ "moving to $target starts unticked, even with Event Ongoing and Event Ended on",
1379
+ (targetCase: TargetCase) => {
1380
+ for (const ongoing of flags) {
1381
+ for (const ended of flags) {
1382
+ expect(
1383
+ shouldNotify(
1384
+ makeEvent(false, ongoing, ended),
1385
+ targetCase.targetState,
1386
+ ),
1387
+ ).toBe(false);
1388
+ }
1389
+ }
1390
+ },
1391
+ );
1392
+
1393
+ test("a move neither setting announces starts the same as a public note on the event", () => {
1394
+ for (const created of createdFlags) {
1395
+ for (const targetCase of unannouncedTargetCases) {
1396
+ for (const ongoing of flags) {
1397
+ for (const ended of flags) {
1398
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1399
+ makeEvent(created, ongoing, ended);
1400
+
1401
+ expect(shouldNotify(event, targetCase.targetState)).toBe(
1402
+ PublicNoteSubscriberNotificationDefault.shouldNotifyForScheduledMaintenance(
1403
+ event,
1404
+ ),
1405
+ );
1406
+ }
1407
+ }
1408
+ }
1409
+ }
1410
+ });
1411
+
1412
+ test("an explicit Event Ongoing or Event Ended setting gives the answer the automatic change would", () => {
1413
+ /*
1414
+ * The workers that move an event to ongoing or ended notify subscribers
1415
+ * when Boolean(setting) is true.
1416
+ */
1417
+ const explicitFlags: Array<boolean> = [true, false];
1418
+
1419
+ for (const setting of explicitFlags) {
1420
+ expect(
1421
+ shouldNotify(makeEvent(false, setting, !setting), ongoingState),
1422
+ ).toBe(Boolean(setting));
1423
+ expect(
1424
+ shouldNotify(makeEvent(false, !setting, setting), endedState),
1425
+ ).toBe(Boolean(setting));
1426
+ expect(
1427
+ shouldNotify(makeEvent(false, !setting, setting), resolvedState),
1428
+ ).toBe(Boolean(setting));
1429
+ }
1430
+ });
1431
+
1432
+ test("an unknown Event Ongoing or Event Ended setting keeps the long-standing default of notifying", () => {
1433
+ const unknownFlags: Array<Flag> = [null, undefined];
1434
+
1435
+ for (const unknown of unknownFlags) {
1436
+ expect(
1437
+ shouldNotify(makeEvent(false, unknown, false), ongoingState),
1438
+ ).toBe(true);
1439
+ expect(shouldNotify(makeEvent(false, false, unknown), endedState)).toBe(
1440
+ true,
1441
+ );
1442
+ expect(
1443
+ shouldNotify(makeEvent(false, false, unknown), resolvedState),
1444
+ ).toBe(true);
1445
+ }
1446
+ });
1447
+
1448
+ test("with Event Ongoing and Event Ended both off, every move starts unticked", () => {
1449
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1450
+ makeEvent(false, false, false);
1451
+
1452
+ for (const targetCase of targetCases) {
1453
+ expect(shouldNotify(event, targetCase.targetState)).toBe(false);
1454
+ }
1455
+ });
1456
+
1457
+ test("with Event Ongoing and Event Ended both on, only the moves they announce start ticked", () => {
1458
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1459
+ makeEvent(false, true, true);
1460
+
1461
+ for (const targetCase of announcedTargetCases) {
1462
+ expect(shouldNotify(event, targetCase.targetState)).toBe(true);
1463
+ }
1464
+
1465
+ for (const targetCase of unannouncedTargetCases) {
1466
+ expect(shouldNotify(event, targetCase.targetState)).toBe(false);
1467
+ }
1468
+ });
1469
+ });
1470
+
1471
+ /*
1472
+ * A real state is only one of ongoing, ended or resolved. The helper checks
1473
+ * ongoing first, so a state flagged as ongoing and something else follows
1474
+ * Event Ongoing. These tests pin that order down; they do not bless such a
1475
+ * state.
1476
+ */
1477
+ describe("on a state flagged as more than one kind", () => {
1478
+ const ongoingAndMore: Array<[string, ScheduledMaintenanceTargetState]> = [
1479
+ ["ongoing and ended", { isOngoingState: true, isEndedState: true }],
1480
+ ["ongoing and resolved", { isOngoingState: true, isResolvedState: true }],
1481
+ [
1482
+ "ongoing, ended and resolved",
1483
+ { isOngoingState: true, isEndedState: true, isResolvedState: true },
1484
+ ],
1485
+ ];
1486
+
1487
+ test.each(ongoingAndMore)(
1488
+ "a state flagged %s takes the ongoing branch and follows Event Ongoing",
1489
+ (_name: string, targetState: ScheduledMaintenanceTargetState) => {
1490
+ expect(shouldNotify(makeEvent(false, false, true), targetState)).toBe(
1491
+ false,
1492
+ );
1493
+ expect(shouldNotify(makeEvent(false, true, false), targetState)).toBe(
1494
+ true,
1495
+ );
1496
+ expect(shouldNotify(makeEvent(false, null, false), targetState)).toBe(
1497
+ true,
1498
+ );
1499
+ },
1500
+ );
1501
+
1502
+ test("a state flagged ended and resolved follows Event Ended", () => {
1503
+ const targetState: ScheduledMaintenanceTargetState = {
1504
+ isEndedState: true,
1505
+ isResolvedState: true,
1506
+ };
1507
+
1508
+ expect(shouldNotify(makeEvent(false, false, true), targetState)).toBe(
1509
+ true,
1510
+ );
1511
+ expect(shouldNotify(makeEvent(false, true, false), targetState)).toBe(
1512
+ false,
1513
+ );
1514
+ });
1515
+
1516
+ test("an ongoing flag that is off does not stop a resolved state following Event Ended", () => {
1517
+ const targetState: ScheduledMaintenanceTargetState = {
1518
+ isOngoingState: false,
1519
+ isResolvedState: true,
1520
+ };
1521
+
1522
+ expect(shouldNotify(makeEvent(false, false, true), targetState)).toBe(
1523
+ true,
1524
+ );
1525
+ expect(shouldNotify(makeEvent(false, true, false), targetState)).toBe(
1526
+ false,
1527
+ );
1528
+ });
1529
+ });
1530
+
1531
+ describe("when the event or the target state is missing", () => {
1532
+ type MissingEventRow = {
1533
+ event: string;
1534
+ setting: EventSetting;
1535
+ target: string;
1536
+ targetState: TargetState;
1537
+ };
1538
+
1539
+ const missingEvents: Array<[string, EventSetting]> = [
1540
+ ["a missing event (null)", null],
1541
+ ["a missing event (undefined)", undefined],
1542
+ ["an event with no settings loaded", {}],
1543
+ ];
1544
+
1545
+ const missingEventRows: Array<MissingEventRow> = [];
1546
+
1547
+ for (const [eventName, setting] of missingEvents) {
1548
+ for (const targetCase of targetCases) {
1549
+ missingEventRows.push({
1550
+ event: eventName,
1551
+ setting: setting,
1552
+ target: targetCase.target,
1553
+ targetState: targetCase.targetState,
1554
+ });
1555
+ }
1556
+ }
1557
+
1558
+ test.each(missingEventRows)(
1559
+ "is true for $event moving to $target",
1560
+ (row: MissingEventRow) => {
1561
+ expect(shouldNotify(row.setting, row.targetState)).toBe(true);
1562
+ },
1563
+ );
1564
+
1565
+ test.each([null, undefined])(
1566
+ "a quiet event moving to an unknown state (%p) starts unticked",
1567
+ (targetState: null | undefined) => {
1568
+ expect(shouldNotify(makeEvent(false, true, true), targetState)).toBe(
1569
+ false,
1570
+ );
1571
+ },
1572
+ );
1573
+ });
1574
+
1575
+ describe("return value and inputs", () => {
1576
+ test("always returns a boolean, never a raw setting", () => {
1577
+ for (const row of matrix) {
1578
+ expect(
1579
+ typeof shouldNotify(
1580
+ makeEvent(row.created, row.ongoing, row.ended),
1581
+ row.targetState,
1582
+ ),
1583
+ ).toBe("boolean");
1584
+ }
1585
+
1586
+ const missingEvents: Array<EventSetting> = [null, undefined, {}];
1587
+
1588
+ for (const event of missingEvents) {
1589
+ for (const targetCase of targetCases) {
1590
+ expect(typeof shouldNotify(event, targetCase.targetState)).toBe(
1591
+ "boolean",
1592
+ );
1593
+ }
1594
+ }
1595
+ });
1596
+
1597
+ test("does not change the event or the target state it reads", () => {
1598
+ for (const row of matrix) {
1599
+ const event: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1600
+ makeEvent(row.created, row.ongoing, row.ended);
1601
+ const eventBefore: ScheduledMaintenanceStateChangeSubscriberNotificationSetting =
1602
+ { ...event };
1603
+
1604
+ const targetStateBefore: TargetState = row.targetState
1605
+ ? { ...row.targetState }
1606
+ : row.targetState;
1607
+
1608
+ shouldNotify(event, row.targetState);
1609
+
1610
+ expect(event).toStrictEqual(eventBefore);
1611
+ expect(row.targetState).toStrictEqual(targetStateBefore);
1612
+ }
1613
+ });
1614
+
1615
+ test("works on frozen inputs", () => {
1616
+ const event: Readonly<ScheduledMaintenanceStateChangeSubscriberNotificationSetting> =
1617
+ Object.freeze(makeEvent(false, false, true));
1618
+ const targetState: Readonly<ScheduledMaintenanceTargetState> =
1619
+ Object.freeze({ isEndedState: true });
1620
+
1621
+ expect(shouldNotify(event, targetState)).toBe(true);
1622
+ expect(shouldNotify(event, Object.freeze({ ...ongoingState }))).toBe(
1623
+ false,
1624
+ );
1625
+ });
1626
+ });
1627
+
1628
+ describe("with ScheduledMaintenance and ScheduledMaintenanceState models", () => {
1629
+ const makeModelEvent: (
1630
+ created: boolean,
1631
+ ongoing: boolean,
1632
+ ended: boolean,
1633
+ ) => ScheduledMaintenance = (
1634
+ created: boolean,
1635
+ ongoing: boolean,
1636
+ ended: boolean,
1637
+ ): ScheduledMaintenance => {
1638
+ const scheduledMaintenance: ScheduledMaintenance =
1639
+ new ScheduledMaintenance();
1640
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedOnEventCreated =
1641
+ created;
1642
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing =
1643
+ ongoing;
1644
+ scheduledMaintenance.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded =
1645
+ ended;
1646
+ return scheduledMaintenance;
1647
+ };
1648
+
1649
+ const makeModelState: (
1650
+ name: string,
1651
+ kind: "scheduled" | "ongoing" | "ended" | "resolved" | "custom",
1652
+ ) => ScheduledMaintenanceState = (
1653
+ name: string,
1654
+ kind: "scheduled" | "ongoing" | "ended" | "resolved" | "custom",
1655
+ ): ScheduledMaintenanceState => {
1656
+ const state: ScheduledMaintenanceState = new ScheduledMaintenanceState();
1657
+ state.name = name;
1658
+ state.isScheduledState = kind === "scheduled";
1659
+ state.isOngoingState = kind === "ongoing";
1660
+ state.isEndedState = kind === "ended";
1661
+ state.isResolvedState = kind === "resolved";
1662
+ return state;
1663
+ };
1664
+
1665
+ const scheduledModelState: ScheduledMaintenanceState = makeModelState(
1666
+ "Scheduled",
1667
+ "scheduled",
1668
+ );
1669
+ const ongoingModelState: ScheduledMaintenanceState = makeModelState(
1670
+ "Ongoing",
1671
+ "ongoing",
1672
+ );
1673
+ const endedModelState: ScheduledMaintenanceState = makeModelState(
1674
+ "Ended",
1675
+ "ended",
1676
+ );
1677
+ const resolvedModelState: ScheduledMaintenanceState = makeModelState(
1678
+ "Completed",
1679
+ "resolved",
1680
+ );
1681
+ const customModelState: ScheduledMaintenanceState = makeModelState(
1682
+ "Paused",
1683
+ "custom",
1684
+ );
1685
+
1686
+ test("a quiet event moving to an ongoing state follows Event Ongoing", () => {
1687
+ expect(
1688
+ shouldNotify(makeModelEvent(false, true, false), ongoingModelState),
1689
+ ).toBe(true);
1690
+ expect(
1691
+ shouldNotify(makeModelEvent(false, false, true), ongoingModelState),
1692
+ ).toBe(false);
1693
+ });
1694
+
1695
+ test("a quiet event moving to an ended state follows Event Ended", () => {
1696
+ expect(
1697
+ shouldNotify(makeModelEvent(false, false, true), endedModelState),
1698
+ ).toBe(true);
1699
+ expect(
1700
+ shouldNotify(makeModelEvent(false, true, false), endedModelState),
1701
+ ).toBe(false);
1702
+ });
1703
+
1704
+ test("a quiet event moving to a resolved state follows Event Ended", () => {
1705
+ expect(
1706
+ shouldNotify(makeModelEvent(false, false, true), resolvedModelState),
1707
+ ).toBe(true);
1708
+ expect(
1709
+ shouldNotify(makeModelEvent(false, true, false), resolvedModelState),
1710
+ ).toBe(false);
1711
+ });
1712
+
1713
+ test("a quiet event moving to the scheduled state or a custom state starts unticked", () => {
1714
+ const event: ScheduledMaintenance = makeModelEvent(false, true, true);
1715
+
1716
+ expect(shouldNotify(event, scheduledModelState)).toBe(false);
1717
+ expect(shouldNotify(event, customModelState)).toBe(false);
1718
+ });
1719
+
1720
+ test("a quiet event moving to a state whose flags were never loaded starts unticked", () => {
1721
+ const state: ScheduledMaintenanceState = new ScheduledMaintenanceState();
1722
+
1723
+ expect(state.isOngoingState).toBeUndefined();
1724
+ expect(state.isEndedState).toBeUndefined();
1725
+ expect(state.isResolvedState).toBeUndefined();
1726
+ expect(shouldNotify(makeModelEvent(false, true, true), state)).toBe(
1727
+ false,
1728
+ );
1729
+ });
1730
+
1731
+ test("an event that notified subscribers keeps notifying on every move, even with Event Ongoing and Event Ended off", () => {
1732
+ const event: ScheduledMaintenance = makeModelEvent(true, false, false);
1733
+
1734
+ expect(shouldNotify(event, scheduledModelState)).toBe(true);
1735
+ expect(shouldNotify(event, ongoingModelState)).toBe(true);
1736
+ expect(shouldNotify(event, endedModelState)).toBe(true);
1737
+ expect(shouldNotify(event, resolvedModelState)).toBe(true);
1738
+ expect(shouldNotify(event, customModelState)).toBe(true);
1739
+ });
1740
+
1741
+ test("an event whose settings were never loaded keeps notifying", () => {
1742
+ const event: ScheduledMaintenance = new ScheduledMaintenance();
1743
+
1744
+ expect(
1745
+ event.shouldStatusPageSubscribersBeNotifiedOnEventCreated,
1746
+ ).toBeUndefined();
1747
+ expect(shouldNotify(event, scheduledModelState)).toBe(true);
1748
+ expect(shouldNotify(event, ongoingModelState)).toBe(true);
1749
+ expect(shouldNotify(event, endedModelState)).toBe(true);
1750
+ });
1751
+
1752
+ test("a quiet event read back from API JSON follows its own Ongoing and Ended settings", () => {
1753
+ const event: ScheduledMaintenance = ScheduledMaintenance.fromJSONObject(
1754
+ {
1755
+ _id: "5a2b3c4d-0000-4000-8000-000000000031",
1756
+ title: "Database upgrade",
1757
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
1758
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing: false,
1759
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded: true,
1760
+ },
1761
+ ScheduledMaintenance,
1762
+ );
1763
+
1764
+ expect(shouldNotify(event, ongoingModelState)).toBe(false);
1765
+ expect(shouldNotify(event, endedModelState)).toBe(true);
1766
+ expect(shouldNotify(event, resolvedModelState)).toBe(true);
1767
+ expect(shouldNotify(event, scheduledModelState)).toBe(false);
1768
+ });
1769
+
1770
+ test("a quiet event read back from API JSON without its Ongoing and Ended settings keeps notifying on those moves", () => {
1771
+ const event: ScheduledMaintenance = ScheduledMaintenance.fromJSONObject(
1772
+ {
1773
+ _id: "5a2b3c4d-0000-4000-8000-000000000032",
1774
+ shouldStatusPageSubscribersBeNotifiedOnEventCreated: false,
1775
+ },
1776
+ ScheduledMaintenance,
1777
+ );
1778
+
1779
+ expect(
1780
+ event.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing,
1781
+ ).toBeUndefined();
1782
+ expect(shouldNotify(event, ongoingModelState)).toBe(true);
1783
+ expect(shouldNotify(event, endedModelState)).toBe(true);
1784
+ expect(shouldNotify(event, scheduledModelState)).toBe(false);
1785
+ });
1786
+
1787
+ test("an event read back from API JSON without the Event Created setting keeps notifying", () => {
1788
+ const event: ScheduledMaintenance = ScheduledMaintenance.fromJSONObject(
1789
+ {
1790
+ _id: "5a2b3c4d-0000-4000-8000-000000000033",
1791
+ title: "Database upgrade",
1792
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing: false,
1793
+ shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded: false,
1794
+ },
1795
+ ScheduledMaintenance,
1796
+ );
1797
+
1798
+ expect(shouldNotify(event, scheduledModelState)).toBe(true);
1799
+ expect(shouldNotify(event, ongoingModelState)).toBe(true);
1800
+ expect(shouldNotify(event, endedModelState)).toBe(true);
1801
+ });
1802
+
1803
+ test("states read back from API JSON are recognised", () => {
1804
+ const event: ScheduledMaintenance = makeModelEvent(false, true, false);
1805
+
1806
+ const ongoing: ScheduledMaintenanceState =
1807
+ ScheduledMaintenanceState.fromJSONObject(
1808
+ {
1809
+ _id: "5a2b3c4d-0000-4000-8000-000000000041",
1810
+ name: "Ongoing",
1811
+ isScheduledState: false,
1812
+ isOngoingState: true,
1813
+ isEndedState: false,
1814
+ isResolvedState: false,
1815
+ },
1816
+ ScheduledMaintenanceState,
1817
+ );
1818
+
1819
+ const ended: ScheduledMaintenanceState =
1820
+ ScheduledMaintenanceState.fromJSONObject(
1821
+ {
1822
+ _id: "5a2b3c4d-0000-4000-8000-000000000042",
1823
+ name: "Ended",
1824
+ isScheduledState: false,
1825
+ isOngoingState: false,
1826
+ isEndedState: true,
1827
+ isResolvedState: false,
1828
+ },
1829
+ ScheduledMaintenanceState,
1830
+ );
1831
+
1832
+ const nameOnly: ScheduledMaintenanceState =
1833
+ ScheduledMaintenanceState.fromJSONObject(
1834
+ {
1835
+ _id: "5a2b3c4d-0000-4000-8000-000000000043",
1836
+ name: "Ongoing",
1837
+ },
1838
+ ScheduledMaintenanceState,
1839
+ );
1840
+
1841
+ expect(shouldNotify(event, ongoing)).toBe(true);
1842
+ expect(shouldNotify(event, ended)).toBe(false);
1843
+
1844
+ // The state's name is not what counts: only its flags do.
1845
+ expect(shouldNotify(event, nameOnly)).toBe(false);
1846
+ });
1847
+
1848
+ test("does not change the models it reads", () => {
1849
+ const event: ScheduledMaintenance = makeModelEvent(false, false, true);
1850
+
1851
+ shouldNotify(event, resolvedModelState);
1852
+
1853
+ expect(event.shouldStatusPageSubscribersBeNotifiedOnEventCreated).toBe(
1854
+ false,
1855
+ );
1856
+ expect(
1857
+ event.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToOngoing,
1858
+ ).toBe(false);
1859
+ expect(
1860
+ event.shouldStatusPageSubscribersBeNotifiedWhenEventChangedToEnded,
1861
+ ).toBe(true);
1862
+ expect(resolvedModelState.isScheduledState).toBe(false);
1863
+ expect(resolvedModelState.isOngoingState).toBe(false);
1864
+ expect(resolvedModelState.isEndedState).toBe(false);
1865
+ expect(resolvedModelState.isResolvedState).toBe(true);
1866
+ });
1867
+ });
1868
+ });