@oneuptime/common 13.0.7 → 13.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +1 -1
  2. package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +1 -1
  3. package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +1 -1
  4. package/Server/API/AIBillingAPI.ts +1 -0
  5. package/Server/API/AIInsightAPI.ts +1 -4
  6. package/Server/API/AIInvestigationAPI.ts +1 -4
  7. package/Server/API/AIReadinessAPI.ts +4 -5
  8. package/Server/API/AlertAPI.ts +1 -0
  9. package/Server/API/AutoRemediationAPI.ts +1 -4
  10. package/Server/API/BaseAPI.ts +13 -0
  11. package/Server/API/BaseAnalyticsAPI.ts +80 -9
  12. package/Server/API/BillingAPI.ts +2 -0
  13. package/Server/API/BillingInvoiceAPI.ts +1 -0
  14. package/Server/API/BillingPaymentMethodAPI.ts +2 -0
  15. package/Server/API/CodeFixRunAPI.ts +1 -3
  16. package/Server/API/CommonAPI.ts +68 -4
  17. package/Server/API/DashboardAPI.ts +12 -12
  18. package/Server/API/GlobalConfigAPI.ts +17 -0
  19. package/Server/API/IncidentAPI.ts +2 -0
  20. package/Server/API/IncidentEpisodeAPI.ts +1 -0
  21. package/Server/API/NotificationAPI.ts +1 -0
  22. package/Server/API/OnCallCalendarAPI.ts +4 -5
  23. package/Server/API/OnCallDutyPolicyAPI.ts +7 -0
  24. package/Server/API/OnCallReadinessAPI.ts +4 -1
  25. package/Server/API/OnCallScheduleTimelineAPI.ts +731 -0
  26. package/Server/API/ProjectAPI.ts +1 -0
  27. package/Server/API/ScheduledMaintenanceAPI.ts +1 -0
  28. package/Server/API/StatusPageAPI.ts +161 -32
  29. package/Server/API/TeamMemberAPI.ts +3 -0
  30. package/Server/API/UserCallAPI.ts +2 -0
  31. package/Server/API/UserEmailAPI.ts +2 -0
  32. package/Server/API/UserIncomingCallNumberAPI.ts +2 -0
  33. package/Server/API/UserMicrosoftTeamsAPI.ts +1 -0
  34. package/Server/API/UserSlackAPI.ts +1 -0
  35. package/Server/API/UserSmsAPI.ts +2 -0
  36. package/Server/API/UserTotpAuthAPI.ts +1 -0
  37. package/Server/API/UserWebAuthnAPI.ts +2 -0
  38. package/Server/API/UserWebhookAPI.ts +1 -0
  39. package/Server/API/UserWhatsAppAPI.ts +2 -0
  40. package/Server/Middleware/MasterAdminAuthorization.ts +13 -2
  41. package/Server/Middleware/UserAuthorization.ts +79 -5
  42. package/Server/Services/ApiKeyPermissionService.ts +101 -4
  43. package/Server/Services/DatabaseService.ts +245 -0
  44. package/Server/Services/DetectionRuleService.ts +5 -4
  45. package/Server/Services/OnCallDutyPolicyChildService.ts +261 -0
  46. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -2
  47. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -2
  48. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -2
  49. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -2
  50. package/Server/Services/PayAsYouGoBillingService.ts +23 -28
  51. package/Server/Services/ProjectService.ts +18 -0
  52. package/Server/Services/RumSessionPinService.ts +274 -22
  53. package/Server/Services/TeamPermissionService.ts +120 -26
  54. package/Server/Services/ThreatIntelFeedService.ts +6 -3
  55. package/Server/Types/Database/Permissions/BasePermission.ts +9 -7
  56. package/Server/Types/Database/Permissions/Index.ts +75 -11
  57. package/Server/Types/Database/Permissions/TablePermission.ts +24 -28
  58. package/Server/Utils/AI/AIChatPrivacyFilter.ts +8 -0
  59. package/Server/Utils/AI/AIRunPrivacyFilter.ts +8 -0
  60. package/Server/Utils/MasterAdminPageAccess.ts +61 -0
  61. package/Server/Utils/Monitor/MonitorAlert.ts +3 -1
  62. package/Server/Utils/Monitor/MonitorIncident.ts +3 -1
  63. package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1 -1
  64. package/Server/Utils/Realtime.ts +163 -45
  65. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +11 -28
  66. package/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.ts +170 -0
  67. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +1 -1
  68. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +6 -2
  69. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.ts +10 -9
  70. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +1059 -0
  71. package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +376 -0
  72. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +757 -0
  73. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +307 -0
  74. package/Tests/App/Dashboard/ArgumentsFormGroupByUnlistedAttributes.test.tsx +131 -0
  75. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +1 -1
  76. package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +9 -1
  77. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +24 -0
  78. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +162 -8
  79. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +105 -6
  80. package/Tests/App/Dashboard/EntityFilterDropdownUnlistedSelection.test.tsx +434 -0
  81. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +276 -1
  82. package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +9 -1
  83. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +58 -42
  84. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +42 -5
  85. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +34 -23
  86. package/Tests/App/Dashboard/ScheduleTimeline.test.tsx +1580 -0
  87. package/Tests/App/Dashboard/ScheduleTimelineAPI.test.ts +280 -0
  88. package/Tests/App/Dashboard/ScheduleTimelineModel.test.ts +673 -0
  89. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +95 -68
  90. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +86 -3
  91. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +28 -3
  92. package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +761 -0
  93. package/Tests/App/Dashboard/SecurityEventsGuideContent.test.ts +1313 -0
  94. package/Tests/App/Dashboard/SecurityEventsHowItWorksCard.test.tsx +536 -0
  95. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +222 -0
  96. package/Tests/App/Dashboard/SecurityEventsThreatIntelPage.test.tsx +199 -0
  97. package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +321 -0
  98. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +171 -36
  99. package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +215 -0
  100. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +40 -3
  101. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +12 -4
  102. package/Tests/App/PublicDashboard/PublicDashboardWidgetListAuth.test.tsx +623 -0
  103. package/Tests/Models/OnCallCalendarFeedModels.test.ts +23 -1
  104. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +138 -5
  105. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +187 -0
  106. package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +51 -3
  107. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +55 -2
  108. package/Tests/Server/API/BaseAnalyticsAPIAggregateCache.test.ts +729 -0
  109. package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +93 -7
  110. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +36 -3
  111. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +1003 -24
  112. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +6 -3
  113. package/Tests/Server/API/ExpiredSessionAIRoutes.test.ts +708 -0
  114. package/Tests/Server/API/ExpiredSessionCustomRoutes.test.ts +928 -0
  115. package/Tests/Server/API/ExpiredSessionMonitorTemplate.test.ts +319 -0
  116. package/Tests/Server/API/ExpiredSessionOnCallDutyPolicy.test.ts +336 -0
  117. package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +820 -0
  118. package/Tests/Server/API/GlobalConfigLicense.test.ts +140 -0
  119. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +115 -12
  120. package/Tests/Server/API/OnCallCalendarAPI.test.ts +375 -8
  121. package/Tests/Server/API/OnCallReadinessAPI.test.ts +175 -17
  122. package/Tests/Server/API/OnCallScheduleTimelineAPI.test.ts +1513 -0
  123. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +119 -7
  124. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +111 -4
  125. package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +615 -0
  126. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +89 -2
  127. package/Tests/Server/API/SessionReplayAPI.test.ts +121 -0
  128. package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +4 -2
  129. package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +441 -0
  130. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +664 -0
  131. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +7 -0
  132. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +6 -0
  133. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +65 -4
  134. package/Tests/Server/API/UserProjectsAPI.test.ts +63 -3
  135. package/Tests/Server/API/UserTotpAuthAPI.test.ts +48 -2
  136. package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +11 -2
  137. package/Tests/Server/API/UserWebAuthnBackupCodeMinting.test.ts +46 -3
  138. package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +18 -2
  139. package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +24 -7
  140. package/Tests/Server/Middleware/ExpiredSessionUserMiddleware.test.ts +563 -0
  141. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +299 -19
  142. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +453 -0
  143. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +24 -0
  144. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +2 -0
  145. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +3 -3
  146. package/Tests/Server/Services/DatabaseServiceCreateSuppliedId.test.ts +147 -0
  147. package/Tests/Server/Services/DatabaseServiceLoginBeforeHooks.test.ts +1078 -0
  148. package/Tests/Server/Services/DatabaseServiceTenantRelationGuard.test.ts +259 -0
  149. package/Tests/Server/Services/DatabaseServiceWriteOperatorValues.test.ts +147 -0
  150. package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +115 -1
  151. package/Tests/Server/Services/OnCallChildCreateAuthorizationPostgres.test.ts +711 -0
  152. package/Tests/Server/Services/OnCallDutyPolicyChildService.test.ts +733 -0
  153. package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +190 -140
  154. package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +4 -9
  155. package/Tests/Server/Services/PermissionBlockDeletion.test.ts +780 -0
  156. package/Tests/Server/Services/PermissionBlockDeletionPostgres.test.ts +628 -0
  157. package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +77 -1
  158. package/Tests/Server/Services/RumSessionPinCreatePermission.test.ts +715 -0
  159. package/Tests/Server/Services/TeamMemberMultiTenantReadPostgres.test.ts +394 -0
  160. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +6 -0
  161. package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +131 -0
  162. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +13 -2
  163. package/Tests/Server/Types/Database/Permissions/ModelPermissionAnonymousRefusal.test.ts +518 -0
  164. package/Tests/Server/Types/Database/Permissions/MultiTenantPermissions.test.ts +350 -0
  165. package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +282 -25
  166. package/Tests/Server/Types/Database/Permissions/TableLevelBlockPermission.test.ts +459 -0
  167. package/Tests/Server/Utils/AI/AIRunPrivacyFilter.test.ts +101 -9
  168. package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +88 -4
  169. package/Tests/Server/Utils/AI/Toolbox/ExceptionTools.test.ts +459 -0
  170. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +794 -0
  171. package/Tests/Server/Utils/AI/Toolbox/RecentChangesTools.test.ts +574 -0
  172. package/Tests/Server/Utils/AI/Toolbox/SecurityEventTools.test.ts +596 -0
  173. package/Tests/Server/Utils/CaptchaRequestAndLogging.test.ts +395 -0
  174. package/Tests/Server/Utils/MasterAdminPageAccess.test.ts +251 -0
  175. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +616 -0
  176. package/Tests/Server/Utils/Realtime.test.ts +502 -0
  177. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorSeverity.test.ts +216 -0
  178. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +142 -0
  179. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.test.ts +140 -0
  180. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepairClickhouseIntegration.test.ts +542 -0
  181. package/Tests/Server/Utils/Telemetry/ChangeEventRow.test.ts +743 -0
  182. package/Tests/Server/Utils/Telemetry/RuntimeMetrics.test.ts +465 -0
  183. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.test.ts +202 -0
  184. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.test.ts +194 -0
  185. package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.test.ts +231 -0
  186. package/Tests/Server/Utils/Workspace/Slack/Messages/Alert.test.ts +194 -0
  187. package/Tests/Server/Utils/Workspace/Slack/Messages/AlertEpisode.test.ts +194 -0
  188. package/Tests/Server/Utils/Workspace/Slack/Messages/Incident.test.ts +194 -0
  189. package/Tests/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.test.ts +194 -0
  190. package/Tests/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.test.ts +247 -0
  191. package/Tests/Types/AI/AIInsightEvidence.test.ts +206 -0
  192. package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtilAnonymous.test.ts +144 -0
  193. package/Tests/Types/Call/CallProvider.test.ts +528 -0
  194. package/Tests/Types/Kubernetes/KubernetesCostIngest.test.ts +236 -0
  195. package/Tests/Types/OnCallDutyPolicy/ScheduleTimeline.test.ts +736 -0
  196. package/Tests/Types/OnCallDutyPolicy/ScheduleTimelineLayout.test.ts +996 -0
  197. package/Tests/Types/SecurityEvent/SigmaRule.test.ts +142 -0
  198. package/Tests/Types/Workflow/Components/JSON.test.ts +182 -0
  199. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +116 -1
  200. package/Tests/UI/Components/Dropdown/DropdownAsyncOptions.test.tsx +81 -0
  201. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +89 -1
  202. package/Tests/UI/Components/EventAttachmentList.test.tsx +174 -0
  203. package/Tests/UI/Components/Forms/BasicFormBurnRateTemplateDefaults.test.tsx +395 -0
  204. package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +286 -0
  205. package/Tests/UI/Components/Forms/FormSummary.test.tsx +128 -0
  206. package/Tests/UI/Components/ModelTable/BaseModelTableQueryChange.test.tsx +365 -0
  207. package/Tests/UI/Components/OpenAuthenticatedUrl.test.ts +358 -0
  208. package/Tests/UI/Components/SessionAwareImage.test.tsx +496 -0
  209. package/Tests/UI/Components/TelemetryHistogramZeroBuckets.test.tsx +190 -0
  210. package/Tests/UI/Components/TooltipInteractive.test.tsx +97 -0
  211. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardInstallGuidance.test.tsx +1 -1
  212. package/Tests/UI/Monitor/EvaluationLogListTimestamps.test.tsx +367 -0
  213. package/Tests/UI/Utils/API/BaseAPIRefreshSession.test.ts +1087 -0
  214. package/Tests/UI/Utils/API/DashboardHost.ts +12 -0
  215. package/Tests/UI/Utils/API/FakeAxiosServer.ts +183 -0
  216. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  217. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  218. package/Tests/UI/Utils/Cookie.test.ts +440 -0
  219. package/Tests/UI/Utils/ModelAPIRequestClient.test.ts +278 -0
  220. package/Tests/UI/Utils/Navigation.test.ts +33 -0
  221. package/Tests/UI/Utils/PricingPlan.test.ts +295 -0
  222. package/Tests/UI/Utils/Realtime.test.ts +759 -0
  223. package/Tests/UI/Utils/Telemetry/Telemetry.test.ts +500 -0
  224. package/Tests/Utils/APIInstanceDispatch.test.ts +311 -0
  225. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizerSeverity.test.ts +565 -0
  226. package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +40 -0
  227. package/Types/Monitor/MonitorEvaluationSummary.ts +3 -0
  228. package/Types/OnCallDutyPolicy/ScheduleTimeline.ts +507 -0
  229. package/Types/OnCallDutyPolicy/ScheduleTimelineLayout.ts +589 -0
  230. package/Types/Realtime/EventName.ts +11 -0
  231. package/Types/SecurityEvent/DetectionFindingConstants.ts +14 -0
  232. package/Types/SecurityEvent/OcsfSeverity.ts +31 -26
  233. package/Types/SecurityEvent/SigmaRule.ts +51 -0
  234. package/Types/SecurityEvent/ThreatIntelConstants.ts +18 -0
  235. package/UI/Components/AttachmentList/EventAttachmentList.tsx +30 -2
  236. package/UI/Components/Dashboard/DashboardVariableControl.tsx +12 -2
  237. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  238. package/UI/Components/EditionLabel/EditionLabel.tsx +12 -0
  239. package/UI/Components/EventItem/EventItem.tsx +12 -1
  240. package/UI/Components/Forms/BasicForm.tsx +151 -126
  241. package/UI/Components/Forms/CollapsibleFormSection.tsx +63 -0
  242. package/UI/Components/Forms/Fields/FormField.tsx +10 -4
  243. package/UI/Components/Forms/FormSummary.tsx +7 -0
  244. package/UI/Components/Forms/Types/Field.ts +10 -0
  245. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +2 -1
  246. package/UI/Components/Markdown.tsx/SessionAwareImage.tsx +122 -0
  247. package/UI/Components/ModelTable/BaseModelTable.tsx +34 -5
  248. package/UI/Components/ModelTable/TableView.tsx +1 -1
  249. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +8 -1
  250. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  251. package/UI/Utils/API/API.ts +173 -12
  252. package/UI/Utils/API/RequestOptions.ts +11 -0
  253. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +31 -7
  254. package/UI/Utils/ModelAPI/ModelAPI.ts +30 -9
  255. package/UI/Utils/Navigation.ts +9 -0
  256. package/UI/Utils/OpenAuthenticatedUrl.ts +154 -0
  257. package/UI/Utils/Realtime.ts +176 -30
  258. package/Utils/API.ts +14 -5
  259. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +157 -7
  260. package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +9 -17
  261. package/Utils/Slo/SloBurnRateTemplate.ts +2 -2
  262. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +1 -1
  263. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -1
  264. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +1 -1
  265. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -1
  266. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +1 -1
  267. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -1
  268. package/build/dist/Server/API/AIBillingAPI.js +1 -1
  269. package/build/dist/Server/API/AIBillingAPI.js.map +1 -1
  270. package/build/dist/Server/API/AIInsightAPI.js +1 -4
  271. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  272. package/build/dist/Server/API/AIInvestigationAPI.js +1 -4
  273. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  274. package/build/dist/Server/API/AIReadinessAPI.js +1 -3
  275. package/build/dist/Server/API/AIReadinessAPI.js.map +1 -1
  276. package/build/dist/Server/API/AlertAPI.js +1 -1
  277. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  278. package/build/dist/Server/API/AutoRemediationAPI.js +1 -4
  279. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  280. package/build/dist/Server/API/BaseAPI.js +12 -0
  281. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  282. package/build/dist/Server/API/BaseAnalyticsAPI.js +55 -10
  283. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  284. package/build/dist/Server/API/BillingAPI.js +2 -2
  285. package/build/dist/Server/API/BillingAPI.js.map +1 -1
  286. package/build/dist/Server/API/BillingInvoiceAPI.js +1 -1
  287. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  288. package/build/dist/Server/API/BillingPaymentMethodAPI.js +2 -2
  289. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  290. package/build/dist/Server/API/CodeFixRunAPI.js +1 -3
  291. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
  292. package/build/dist/Server/API/CommonAPI.js +50 -5
  293. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  294. package/build/dist/Server/API/DashboardAPI.js +12 -12
  295. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  296. package/build/dist/Server/API/GlobalConfigAPI.js +12 -0
  297. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  298. package/build/dist/Server/API/IncidentAPI.js +2 -2
  299. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  300. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  301. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  302. package/build/dist/Server/API/NotificationAPI.js +1 -1
  303. package/build/dist/Server/API/NotificationAPI.js.map +1 -1
  304. package/build/dist/Server/API/OnCallCalendarAPI.js +1 -4
  305. package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -1
  306. package/build/dist/Server/API/OnCallDutyPolicyAPI.js +6 -0
  307. package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -1
  308. package/build/dist/Server/API/OnCallReadinessAPI.js +4 -1
  309. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -1
  310. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +494 -0
  311. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -0
  312. package/build/dist/Server/API/ProjectAPI.js +1 -1
  313. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  314. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  315. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  316. package/build/dist/Server/API/StatusPageAPI.js +125 -33
  317. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  318. package/build/dist/Server/API/TeamMemberAPI.js +3 -3
  319. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  320. package/build/dist/Server/API/UserCallAPI.js +2 -2
  321. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  322. package/build/dist/Server/API/UserEmailAPI.js +2 -2
  323. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  324. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +2 -2
  325. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +1 -1
  327. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -1
  328. package/build/dist/Server/API/UserSlackAPI.js +1 -1
  329. package/build/dist/Server/API/UserSlackAPI.js.map +1 -1
  330. package/build/dist/Server/API/UserSmsAPI.js +2 -2
  331. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  332. package/build/dist/Server/API/UserTotpAuthAPI.js +1 -1
  333. package/build/dist/Server/API/UserTotpAuthAPI.js.map +1 -1
  334. package/build/dist/Server/API/UserWebAuthnAPI.js +2 -2
  335. package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
  336. package/build/dist/Server/API/UserWebhookAPI.js +1 -1
  337. package/build/dist/Server/API/UserWebhookAPI.js.map +1 -1
  338. package/build/dist/Server/API/UserWhatsAppAPI.js +2 -2
  339. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  340. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -2
  341. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  342. package/build/dist/Server/Middleware/UserAuthorization.js +64 -4
  343. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  344. package/build/dist/Server/Services/ApiKeyPermissionService.js +80 -4
  345. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  346. package/build/dist/Server/Services/DatabaseService.js +171 -0
  347. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  348. package/build/dist/Server/Services/DetectionRuleService.js +4 -4
  349. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
  350. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js +170 -0
  351. package/build/dist/Server/Services/OnCallDutyPolicyChildService.js.map +1 -0
  352. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -2
  353. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  354. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +2 -2
  355. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  356. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -2
  357. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  358. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -2
  359. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  360. package/build/dist/Server/Services/PayAsYouGoBillingService.js +20 -27
  361. package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -1
  362. package/build/dist/Server/Services/ProjectService.js +17 -0
  363. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  364. package/build/dist/Server/Services/RumSessionPinService.js +180 -16
  365. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  366. package/build/dist/Server/Services/TeamPermissionService.js +89 -27
  367. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  368. package/build/dist/Server/Services/ThreatIntelFeedService.js +5 -4
  369. package/build/dist/Server/Services/ThreatIntelFeedService.js.map +1 -1
  370. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +9 -6
  371. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  372. package/build/dist/Server/Types/Database/Permissions/Index.js +60 -6
  373. package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
  374. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +14 -13
  375. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  376. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +7 -0
  377. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js +7 -0
  379. package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js.map +1 -1
  380. package/build/dist/Server/Utils/MasterAdminPageAccess.js +39 -0
  381. package/build/dist/Server/Utils/MasterAdminPageAccess.js.map +1 -0
  382. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +3 -1
  383. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  384. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +3 -1
  385. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  386. package/build/dist/Server/Utils/Realtime.js +126 -37
  387. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  388. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +7 -25
  389. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
  390. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js +127 -0
  391. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js.map +1 -0
  392. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +1 -1
  393. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
  394. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +3 -2
  395. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js.map +1 -1
  396. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js +4 -8
  397. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js.map +1 -1
  398. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +31 -1
  399. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
  400. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js +321 -0
  401. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js.map +1 -0
  402. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js +372 -0
  403. package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js.map +1 -0
  404. package/build/dist/Types/Realtime/EventName.js +10 -0
  405. package/build/dist/Types/Realtime/EventName.js.map +1 -1
  406. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +11 -0
  407. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
  408. package/build/dist/Types/SecurityEvent/OcsfSeverity.js +30 -25
  409. package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -1
  410. package/build/dist/Types/SecurityEvent/SigmaRule.js +47 -0
  411. package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -1
  412. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js +14 -0
  413. package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js.map +1 -1
  414. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +9 -4
  415. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -1
  416. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +10 -2
  417. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -1
  418. package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -1
  419. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  420. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +11 -0
  421. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  422. package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
  423. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  424. package/build/dist/UI/Components/Forms/BasicForm.js +70 -64
  425. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  426. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +27 -0
  427. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -0
  428. package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -7
  429. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  430. package/build/dist/UI/Components/Forms/FormSummary.js +7 -0
  431. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  432. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +2 -1
  433. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  434. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js +84 -0
  435. package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js.map +1 -0
  436. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +14 -1
  437. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  438. package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
  439. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  440. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -1
  441. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  442. package/build/dist/UI/Components/Tooltip/Tooltip.js +2 -1
  443. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  444. package/build/dist/UI/Utils/API/API.js +143 -19
  445. package/build/dist/UI/Utils/API/API.js.map +1 -1
  446. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +21 -7
  447. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  448. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +26 -9
  449. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  450. package/build/dist/UI/Utils/Navigation.js +8 -0
  451. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  452. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js +92 -0
  453. package/build/dist/UI/Utils/OpenAuthenticatedUrl.js.map +1 -0
  454. package/build/dist/UI/Utils/Realtime.js +120 -15
  455. package/build/dist/UI/Utils/Realtime.js.map +1 -1
  456. package/build/dist/Utils/API.js +13 -5
  457. package/build/dist/Utils/API.js.map +1 -1
  458. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +123 -6
  459. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  460. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +4 -18
  461. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -1
  462. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +2 -2
  463. package/package.json +1 -1
@@ -0,0 +1,536 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ afterEach,
4
+ beforeEach,
5
+ describe,
6
+ expect,
7
+ jest,
8
+ test,
9
+ } from "@jest/globals";
10
+ import {
11
+ cleanup,
12
+ fireEvent,
13
+ render,
14
+ screen,
15
+ within,
16
+ } from "@testing-library/react";
17
+ import * as React from "react";
18
+ import { MemoryRouter } from "react-router-dom";
19
+ import SecurityEventsHowItWorksCard, {
20
+ getHowItWorksCollapsedStorageKey,
21
+ } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/HowItWorks/SecurityEventsHowItWorksCard";
22
+ import {
23
+ SecurityEventsGuide,
24
+ SecurityEventsGuideSection,
25
+ } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/HowItWorks/SecurityEventsGuide";
26
+ import DetectionRulesGuide from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/HowItWorks/DetectionRulesGuide";
27
+ import ThreatIntelGuide from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/HowItWorks/ThreatIntelGuide";
28
+ import URL from "../../../Types/API/URL";
29
+ import IconProp from "../../../Types/Icon/IconProp";
30
+ import OcsfSeverity from "../../../Types/SecurityEvent/OcsfSeverity";
31
+ import { DOCS_URL } from "../../../UI/Config";
32
+ import LocalStorage from "../../../UI/Utils/LocalStorage";
33
+
34
+ /*
35
+ * The "how it works" card as a customer meets it: the pipeline and the
36
+ * level mapping visible on the page, the full guide one click away in a
37
+ * tabbed modal, and a Hide that sticks — per guide, and without ever
38
+ * breaking when browser storage is unavailable.
39
+ *
40
+ * What the guides SAY is pinned against the engine in
41
+ * SecurityEventsGuideContent.test.ts; this suite pins how it is shown.
42
+ *
43
+ * The guide renders its markdown through LazyMarkdownViewer (a React.lazy
44
+ * boundary); render the source straight through, as the other suites that
45
+ * assert on a lazy viewer's text do.
46
+ */
47
+
48
+ interface MarkdownViewerProps {
49
+ text: string;
50
+ }
51
+
52
+ jest.mock("../../../UI/Components/Markdown.tsx/LazyMarkdownViewer", () => {
53
+ return {
54
+ __esModule: true,
55
+ default: (props: MarkdownViewerProps): React.ReactElement => {
56
+ return React.createElement("div", {}, props.text);
57
+ },
58
+ };
59
+ });
60
+
61
+ const TEST_GUIDE: SecurityEventsGuide = {
62
+ id: "test-guide",
63
+ title: "How the test feature works",
64
+ summary: "A summary of the test feature.",
65
+ steps: [
66
+ {
67
+ title: "First step",
68
+ description: "First step description.",
69
+ icon: IconProp.InboxArrowDown,
70
+ },
71
+ {
72
+ title: "Second step",
73
+ description: "Second step description.",
74
+ icon: IconProp.Clock,
75
+ },
76
+ {
77
+ title: "Third step",
78
+ description: "Third step description.",
79
+ icon: IconProp.Funnel,
80
+ },
81
+ {
82
+ title: "Fourth step",
83
+ description: "Fourth step description.",
84
+ icon: IconProp.BellAlert,
85
+ },
86
+ ],
87
+ levels: {
88
+ title: "Severity levels",
89
+ description: "How levels map to severities.",
90
+ items: [
91
+ { label: "low", severity: OcsfSeverity.Low },
92
+ { label: "critical", severity: OcsfSeverity.Critical },
93
+ ],
94
+ sectionId: "levels",
95
+ },
96
+ guideTitle: "Test Feature Guide",
97
+ guideDescription: "Everything about the test feature.",
98
+ sections: [
99
+ { id: "overview", title: "Overview", markdown: "Overview body text." },
100
+ { id: "levels", title: "Levels", markdown: "Levels body text." },
101
+ {
102
+ id: "troubleshooting",
103
+ title: "Troubleshooting",
104
+ markdown: "Troubleshooting body text.",
105
+ },
106
+ ],
107
+ documentationPath: "/telemetry/test-feature",
108
+ };
109
+
110
+ function renderCard(guide: SecurityEventsGuide = TEST_GUIDE): void {
111
+ render(
112
+ <MemoryRouter>
113
+ <SecurityEventsHowItWorksCard guide={guide} />
114
+ </MemoryRouter>,
115
+ );
116
+ }
117
+
118
+ function card(guide: SecurityEventsGuide = TEST_GUIDE): HTMLElement {
119
+ return screen.getByTestId(`how-it-works-${guide.id}`);
120
+ }
121
+
122
+ function toggleButton(guide: SecurityEventsGuide = TEST_GUIDE): HTMLElement {
123
+ return within(card(guide)).getByTestId("how-it-works-toggle");
124
+ }
125
+
126
+ function openGuideButton(guide: SecurityEventsGuide = TEST_GUIDE): HTMLElement {
127
+ return within(card(guide)).getByTestId("how-it-works-open-guide");
128
+ }
129
+
130
+ function tabFor(section: SecurityEventsGuideSection): HTMLElement {
131
+ return within(screen.getByTestId("modal")).getByRole("tab", {
132
+ name: section.title,
133
+ });
134
+ }
135
+
136
+ describe("SecurityEventsHowItWorksCard", () => {
137
+ beforeEach(() => {
138
+ window.localStorage.clear();
139
+ });
140
+
141
+ afterEach(() => {
142
+ cleanup();
143
+ jest.restoreAllMocks();
144
+ window.localStorage.clear();
145
+ });
146
+
147
+ describe("the card", () => {
148
+ test("shows the guide's title and summary as a labelled region", () => {
149
+ renderCard();
150
+
151
+ const region: HTMLElement = screen.getByRole("region", {
152
+ name: TEST_GUIDE.title,
153
+ });
154
+
155
+ expect(region).toBe(card());
156
+ expect(region).toHaveTextContent(TEST_GUIDE.summary);
157
+ });
158
+
159
+ test("lists every step, in order, numbered", () => {
160
+ renderCard();
161
+
162
+ const steps: Array<HTMLElement> =
163
+ within(card()).getAllByTestId("how-it-works-step");
164
+
165
+ expect(steps).toHaveLength(TEST_GUIDE.steps.length);
166
+
167
+ TEST_GUIDE.steps.forEach(
168
+ (step: SecurityEventsGuide["steps"][number], index: number) => {
169
+ expect(steps[index]).toHaveTextContent(`Step ${index + 1}`);
170
+ expect(steps[index]).toHaveTextContent(step.title);
171
+ expect(steps[index]).toHaveTextContent(step.description);
172
+ },
173
+ );
174
+ });
175
+
176
+ test("shows each level next to the severity it becomes", () => {
177
+ renderCard();
178
+
179
+ const levels: Array<HTMLElement> =
180
+ within(card()).getAllByTestId("how-it-works-level");
181
+
182
+ expect(levels).toHaveLength(2);
183
+ expect(levels[0]).toHaveTextContent("low");
184
+ expect(levels[0]).toHaveTextContent(OcsfSeverity.Low);
185
+ expect(levels[1]).toHaveTextContent("critical");
186
+ expect(levels[1]).toHaveTextContent(OcsfSeverity.Critical);
187
+ expect(within(card()).getByText(TEST_GUIDE.levels.title)).toBeVisible();
188
+ expect(
189
+ within(card()).getByText(TEST_GUIDE.levels.description),
190
+ ).toBeVisible();
191
+ });
192
+
193
+ test("does not open the guide until asked", () => {
194
+ renderCard();
195
+
196
+ expect(screen.queryByTestId("modal")).not.toBeInTheDocument();
197
+ });
198
+ });
199
+
200
+ describe("hiding and showing", () => {
201
+ test("starts expanded, with the toggle reporting it", () => {
202
+ renderCard();
203
+
204
+ expect(toggleButton()).toHaveTextContent("Hide");
205
+ expect(toggleButton()).toHaveAttribute("aria-expanded", "true");
206
+
207
+ const controlledId: string | null =
208
+ toggleButton().getAttribute("aria-controls");
209
+ expect(controlledId).toBeTruthy();
210
+ expect(document.getElementById(controlledId!)).toContainElement(
211
+ within(card()).getAllByTestId("how-it-works-step")[0]!,
212
+ );
213
+ });
214
+
215
+ test("Hide shrinks the card to its title row and remembers it", () => {
216
+ renderCard();
217
+
218
+ fireEvent.click(toggleButton());
219
+
220
+ expect(within(card()).queryAllByTestId("how-it-works-step")).toHaveLength(
221
+ 0,
222
+ );
223
+ expect(
224
+ within(card()).queryAllByTestId("how-it-works-level"),
225
+ ).toHaveLength(0);
226
+ expect(card()).not.toHaveTextContent(TEST_GUIDE.summary);
227
+ expect(card()).toHaveTextContent(TEST_GUIDE.title);
228
+ expect(toggleButton()).toHaveTextContent("Show");
229
+ expect(toggleButton()).toHaveAttribute("aria-expanded", "false");
230
+ expect(
231
+ window.localStorage.getItem(
232
+ getHowItWorksCollapsedStorageKey(TEST_GUIDE.id),
233
+ ),
234
+ ).toBe("true");
235
+ });
236
+
237
+ test("the full guide stays one click away while hidden", () => {
238
+ renderCard();
239
+
240
+ fireEvent.click(toggleButton());
241
+ fireEvent.click(openGuideButton());
242
+
243
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
244
+ TEST_GUIDE.guideTitle,
245
+ );
246
+ });
247
+
248
+ test("Show brings the card back and forgets the hidden state", () => {
249
+ renderCard();
250
+
251
+ fireEvent.click(toggleButton());
252
+ fireEvent.click(toggleButton());
253
+
254
+ expect(within(card()).getAllByTestId("how-it-works-step")).toHaveLength(
255
+ TEST_GUIDE.steps.length,
256
+ );
257
+ expect(toggleButton()).toHaveAttribute("aria-expanded", "true");
258
+ expect(
259
+ window.localStorage.getItem(
260
+ getHowItWorksCollapsedStorageKey(TEST_GUIDE.id),
261
+ ),
262
+ ).toBeNull();
263
+ });
264
+
265
+ test("a card hidden on an earlier visit renders hidden", () => {
266
+ window.localStorage.setItem(
267
+ getHowItWorksCollapsedStorageKey(TEST_GUIDE.id),
268
+ "true",
269
+ );
270
+
271
+ renderCard();
272
+
273
+ expect(toggleButton()).toHaveTextContent("Show");
274
+ expect(within(card()).queryAllByTestId("how-it-works-step")).toHaveLength(
275
+ 0,
276
+ );
277
+ });
278
+
279
+ test("anything other than a stored true renders expanded", () => {
280
+ window.localStorage.setItem(
281
+ getHowItWorksCollapsedStorageKey(TEST_GUIDE.id),
282
+ "garbage",
283
+ );
284
+
285
+ renderCard();
286
+
287
+ expect(toggleButton()).toHaveTextContent("Hide");
288
+ });
289
+
290
+ test("hiding one guide leaves the other alone", () => {
291
+ render(
292
+ <MemoryRouter>
293
+ <SecurityEventsHowItWorksCard guide={DetectionRulesGuide} />
294
+ <SecurityEventsHowItWorksCard guide={ThreatIntelGuide} />
295
+ </MemoryRouter>,
296
+ );
297
+
298
+ fireEvent.click(toggleButton(DetectionRulesGuide));
299
+
300
+ expect(toggleButton(DetectionRulesGuide)).toHaveTextContent("Show");
301
+ expect(toggleButton(ThreatIntelGuide)).toHaveTextContent("Hide");
302
+ expect(getHowItWorksCollapsedStorageKey(DetectionRulesGuide.id)).not.toBe(
303
+ getHowItWorksCollapsedStorageKey(ThreatIntelGuide.id),
304
+ );
305
+ });
306
+
307
+ test("unreadable storage falls back to expanded instead of breaking the page", () => {
308
+ jest.spyOn(LocalStorage, "getItem").mockImplementation(() => {
309
+ throw new Error("SecurityError: storage is disabled");
310
+ });
311
+
312
+ renderCard();
313
+
314
+ expect(toggleButton()).toHaveTextContent("Hide");
315
+ expect(within(card()).getAllByTestId("how-it-works-step")).toHaveLength(
316
+ TEST_GUIDE.steps.length,
317
+ );
318
+ });
319
+
320
+ test("unwritable storage still lets the toggle work", () => {
321
+ jest.spyOn(LocalStorage, "setItem").mockImplementation(() => {
322
+ throw new Error("QuotaExceededError");
323
+ });
324
+ jest.spyOn(LocalStorage, "removeItem").mockImplementation(() => {
325
+ throw new Error("QuotaExceededError");
326
+ });
327
+
328
+ renderCard();
329
+
330
+ fireEvent.click(toggleButton());
331
+ expect(toggleButton()).toHaveTextContent("Show");
332
+
333
+ fireEvent.click(toggleButton());
334
+ expect(toggleButton()).toHaveTextContent("Hide");
335
+ });
336
+ });
337
+
338
+ describe("the full guide", () => {
339
+ test("opens on the first section, with the guide's title and description", () => {
340
+ renderCard();
341
+
342
+ fireEvent.click(openGuideButton());
343
+
344
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
345
+ TEST_GUIDE.guideTitle,
346
+ );
347
+ expect(screen.getByTestId("modal-description")).toHaveTextContent(
348
+ TEST_GUIDE.guideDescription,
349
+ );
350
+ expect(tabFor(TEST_GUIDE.sections[0]!)).toHaveAttribute(
351
+ "aria-selected",
352
+ "true",
353
+ );
354
+ expect(
355
+ screen.getByTestId("how-it-works-section-overview"),
356
+ ).toHaveTextContent("Overview body text.");
357
+ });
358
+
359
+ test("has one tab per section, in order", () => {
360
+ renderCard();
361
+
362
+ fireEvent.click(openGuideButton());
363
+
364
+ const tabs: Array<HTMLElement> = within(
365
+ screen.getByTestId("modal"),
366
+ ).getAllByRole("tab");
367
+
368
+ expect(
369
+ tabs.map((tab: HTMLElement) => {
370
+ return tab.textContent;
371
+ }),
372
+ ).toEqual(
373
+ TEST_GUIDE.sections.map((section: SecurityEventsGuideSection) => {
374
+ return section.title;
375
+ }),
376
+ );
377
+ });
378
+
379
+ test("switching tabs shows that section instead", () => {
380
+ renderCard();
381
+
382
+ fireEvent.click(openGuideButton());
383
+ fireEvent.click(tabFor(TEST_GUIDE.sections[2]!));
384
+
385
+ expect(tabFor(TEST_GUIDE.sections[2]!)).toHaveAttribute(
386
+ "aria-selected",
387
+ "true",
388
+ );
389
+ expect(
390
+ screen.getByTestId("how-it-works-section-troubleshooting"),
391
+ ).toHaveTextContent("Troubleshooting body text.");
392
+ expect(
393
+ screen.queryByTestId("how-it-works-section-overview"),
394
+ ).not.toBeInTheDocument();
395
+ });
396
+
397
+ test("the levels link opens straight onto the section that explains them", () => {
398
+ renderCard();
399
+
400
+ fireEvent.click(within(card()).getByTestId("how-it-works-levels-link"));
401
+
402
+ expect(tabFor(TEST_GUIDE.sections[1]!)).toHaveAttribute(
403
+ "aria-selected",
404
+ "true",
405
+ );
406
+ expect(
407
+ screen.getByTestId("how-it-works-section-levels"),
408
+ ).toHaveTextContent("Levels body text.");
409
+ });
410
+
411
+ test("the levels link names the levels it explains", () => {
412
+ renderCard();
413
+
414
+ expect(
415
+ within(card()).getByTestId("how-it-works-levels-link"),
416
+ ).toHaveTextContent("How severity levels are chosen");
417
+ });
418
+
419
+ test("the footer Close button closes it", () => {
420
+ renderCard();
421
+
422
+ fireEvent.click(openGuideButton());
423
+
424
+ const closeButton: HTMLElement = screen.getByTestId(
425
+ "modal-footer-close-button",
426
+ );
427
+ expect(closeButton).toHaveTextContent("Close");
428
+
429
+ fireEvent.click(closeButton);
430
+
431
+ expect(screen.queryByTestId("modal")).not.toBeInTheDocument();
432
+ });
433
+
434
+ test("the header close button closes it", () => {
435
+ renderCard();
436
+
437
+ fireEvent.click(openGuideButton());
438
+ fireEvent.click(screen.getByTestId("close-button"));
439
+
440
+ expect(screen.queryByTestId("modal")).not.toBeInTheDocument();
441
+ });
442
+
443
+ test("offers no Save button — it is a guide, not a form", () => {
444
+ renderCard();
445
+
446
+ fireEvent.click(openGuideButton());
447
+
448
+ expect(
449
+ screen.queryByTestId("modal-footer-submit-button"),
450
+ ).not.toBeInTheDocument();
451
+ });
452
+
453
+ test("reopening after switching tabs starts from the first section again", () => {
454
+ renderCard();
455
+
456
+ fireEvent.click(openGuideButton());
457
+ fireEvent.click(tabFor(TEST_GUIDE.sections[2]!));
458
+ fireEvent.click(screen.getByTestId("close-button"));
459
+ fireEvent.click(openGuideButton());
460
+
461
+ expect(tabFor(TEST_GUIDE.sections[0]!)).toHaveAttribute(
462
+ "aria-selected",
463
+ "true",
464
+ );
465
+ });
466
+
467
+ test("links to the full public documentation in a new tab", () => {
468
+ renderCard();
469
+
470
+ fireEvent.click(openGuideButton());
471
+
472
+ const link: HTMLElement = within(
473
+ screen.getByTestId("modal-footer"),
474
+ ).getByText("Full documentation");
475
+ const anchor: HTMLElement | null = link.closest("a");
476
+
477
+ expect(anchor).not.toBeNull();
478
+ expect(anchor).toHaveAttribute(
479
+ "href",
480
+ URL.fromString(
481
+ `${DOCS_URL.toString()}${TEST_GUIDE.documentationPath}`,
482
+ ).toString(),
483
+ );
484
+ expect(anchor?.getAttribute("href")).toContain(
485
+ TEST_GUIDE.documentationPath,
486
+ );
487
+ expect(anchor).toHaveAttribute("target", "_blank");
488
+ });
489
+ });
490
+
491
+ describe.each([
492
+ ["Detection Rules", DetectionRulesGuide],
493
+ ["Threat Intel", ThreatIntelGuide],
494
+ ] as Array<[string, SecurityEventsGuide]>)(
495
+ "the real %s guide",
496
+ (_name: string, guide: SecurityEventsGuide) => {
497
+ test("renders all of its steps and levels on the card", () => {
498
+ renderCard(guide);
499
+
500
+ expect(
501
+ within(card(guide)).getAllByTestId("how-it-works-step"),
502
+ ).toHaveLength(guide.steps.length);
503
+ expect(
504
+ within(card(guide)).getAllByTestId("how-it-works-level"),
505
+ ).toHaveLength(guide.levels.items.length);
506
+ });
507
+
508
+ test("every tab shows its section's full markdown", () => {
509
+ renderCard(guide);
510
+
511
+ fireEvent.click(openGuideButton(guide));
512
+
513
+ for (const section of guide.sections) {
514
+ fireEvent.click(tabFor(section));
515
+
516
+ expect(
517
+ screen.getByTestId(`how-it-works-section-${section.id}`)
518
+ .textContent,
519
+ ).toBe(section.markdown);
520
+ }
521
+ });
522
+
523
+ test("the levels link lands on the levels section", () => {
524
+ renderCard(guide);
525
+
526
+ fireEvent.click(
527
+ within(card(guide)).getByTestId("how-it-works-levels-link"),
528
+ );
529
+
530
+ expect(
531
+ screen.getByTestId(`how-it-works-section-${guide.levels.sectionId}`),
532
+ ).toBeInTheDocument();
533
+ });
534
+ },
535
+ );
536
+ });