@oneuptime/common 13.0.4 → 13.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/AuditLog.ts +81 -1
- package/Models/AnalyticsModels/SecurityEvent.ts +4 -4
- package/Models/DatabaseModels/Alert.ts +62 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/Incident.ts +66 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +74 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +74 -0
- package/Models/DatabaseModels/Index.ts +10 -4
- package/Models/DatabaseModels/NetworkDevice.ts +67 -0
- package/Models/DatabaseModels/NetworkDeviceDiagnostic.ts +746 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +151 -0
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +1 -1
- package/Models/DatabaseModels/Project.ts +41 -0
- package/Models/DatabaseModels/RumApplication.ts +1 -1
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +74 -0
- package/Models/DatabaseModels/{GoogleSecOpsConnection.ts → SecurityEventConnection.ts} +61 -51
- package/Models/DatabaseModels/{GoogleSecOpsConnectionRun.ts → SecurityEventConnectionRun.ts} +24 -24
- package/Models/DatabaseModels/ServiceLevelObjective.ts +185 -8
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +746 -43
- package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +575 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +582 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +16 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +16 -0
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +75 -0
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
- package/Models/DatabaseModels/ThreatIntelFeed.ts +1 -1
- package/Server/API/AIInvestigationAPI.ts +484 -24
- package/Server/API/BaseAPI.ts +17 -0
- package/Server/API/BillingInvoiceAPI.ts +343 -30
- package/Server/API/BillingPaymentMethodAPI.ts +126 -5
- package/Server/API/DashboardAPI.ts +96 -2
- package/Server/API/SecurityEventConnectionAPI.ts +380 -0
- package/Server/API/StatusPageAPI.ts +308 -199
- package/Server/API/TelemetryAPI.ts +402 -265
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.ts +83 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.ts +36 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.ts +516 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.ts +98 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.ts +27 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.ts +97 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
- package/Server/Middleware/TelemetryIngest.ts +101 -6
- package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +138 -67
- package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +213 -84
- package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +112 -35
- package/Server/Services/AlertLabelRuleEngineService.ts +299 -217
- package/Server/Services/AlertOwnerRuleEngineService.ts +572 -396
- package/Server/Services/AlertPrivacyRuleEngineService.ts +116 -40
- package/Server/Services/AlertService.ts +111 -4
- package/Server/Services/AuditLogService.ts +612 -59
- package/Server/Services/BillingInvoiceService.ts +112 -102
- package/Server/Services/BillingService.ts +539 -11
- package/Server/Services/CephClusterLabelRuleEngineService.ts +170 -109
- package/Server/Services/CephClusterOwnerRuleEngineService.ts +233 -115
- package/Server/Services/CloudResourceLabelRuleEngineService.ts +163 -100
- package/Server/Services/CloudResourceOwnerRuleEngineService.ts +236 -115
- package/Server/Services/DashboardLabelRuleEngineService.ts +145 -84
- package/Server/Services/DashboardOwnerRuleEngineService.ts +213 -95
- package/Server/Services/DatabaseService.ts +171 -21
- package/Server/Services/DockerHostLabelRuleEngineService.ts +171 -110
- package/Server/Services/DockerHostOwnerRuleEngineService.ts +233 -115
- package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +181 -112
- package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +243 -118
- package/Server/Services/ExceptionAggregationService.ts +7 -16
- package/Server/Services/HostLabelRuleEngineService.ts +167 -106
- package/Server/Services/HostOwnerRuleEngineService.ts +229 -111
- package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +141 -67
- package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +272 -72
- package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +112 -35
- package/Server/Services/IncidentEpisodePublicNoteService.ts +24 -0
- package/Server/Services/IncidentLabelRuleEngineService.ts +279 -204
- package/Server/Services/IncidentOwnerRuleEngineService.ts +595 -425
- package/Server/Services/IncidentPrivacyRuleEngineService.ts +117 -44
- package/Server/Services/IncidentPublicNoteService.ts +24 -0
- package/Server/Services/IncidentService.ts +114 -3
- package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +147 -83
- package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +221 -100
- package/Server/Services/Index.ts +10 -4
- package/Server/Services/InventoryItemService.ts +28 -0
- package/Server/Services/IoTFleetLabelRuleEngineService.ts +145 -84
- package/Server/Services/IoTFleetOwnerRuleEngineService.ts +213 -95
- package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +181 -112
- package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +243 -118
- package/Server/Services/LabelService.ts +23 -28
- package/Server/Services/LogAggregationService.ts +17 -23
- package/Server/Services/MetricAggregationService.ts +4 -14
- package/Server/Services/MonitorLabelRuleEngineService.ts +152 -92
- package/Server/Services/MonitorOwnerRuleEngineService.ts +220 -104
- package/Server/Services/MonitorProbeService.ts +20 -2
- package/Server/Services/MonitorService.ts +11 -9
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +376 -5
- package/Server/Services/NetworkDeviceDiagnosticService.ts +417 -0
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +147 -83
- package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +218 -97
- package/Server/Services/NetworkDeviceService.ts +39 -2
- package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +151 -80
- package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +222 -97
- package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +154 -83
- package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +225 -100
- package/Server/Services/PodmanHostLabelRuleEngineService.ts +171 -110
- package/Server/Services/PodmanHostOwnerRuleEngineService.ts +235 -115
- package/Server/Services/ProjectService.ts +111 -10
- package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +174 -110
- package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +239 -116
- package/Server/Services/RumApplicationLabelRuleEngineService.ts +137 -73
- package/Server/Services/RumApplicationOwnerRuleEngineService.ts +200 -83
- package/Server/Services/RunbookLabelRuleEngineService.ts +146 -84
- package/Server/Services/RunbookOwnerRuleEngineService.ts +216 -95
- package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +324 -230
- package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +613 -428
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +24 -0
- package/Server/Services/ScheduledMaintenanceService.ts +43 -14
- package/Server/Services/{GoogleSecOpsConnectionRunService.ts → SecurityEventConnectionRunService.ts} +1 -1
- package/Server/Services/SecurityEventConnectionService.ts +590 -0
- package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +143 -74
- package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +206 -85
- package/Server/Services/ServiceLabelRuleEngineService.ts +172 -110
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +1057 -18
- package/Server/Services/ServiceLevelObjectiveFeedService.ts +108 -0
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +793 -97
- package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +1069 -0
- package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +240 -1
- package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +257 -1
- package/Server/Services/ServiceLevelObjectiveService.ts +1356 -56
- package/Server/Services/ServiceOwnerRuleEngineService.ts +238 -116
- package/Server/Services/StatusPageAnnouncementService.ts +13 -0
- package/Server/Services/StatusPageLabelRuleEngineService.ts +146 -85
- package/Server/Services/StatusPageOwnerRuleEngineService.ts +210 -99
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +28 -232
- package/Server/Services/StatusPageSubscriberService.ts +6 -0
- package/Server/Services/TelemetryUsageBillingService.ts +38 -7
- package/Server/Services/ThreatIntelFeedService.ts +1 -1
- package/Server/Services/TraceAggregationService.ts +77 -28
- package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +173 -110
- package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +238 -116
- package/Server/Services/WorkflowLabelRuleEngineService.ts +145 -84
- package/Server/Services/WorkflowOwnerRuleEngineService.ts +215 -95
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/UpdateByID.ts +3 -0
- package/Server/Types/Database/UpdateOneBy.ts +7 -0
- package/Server/Utils/AI/AlertAIContextBuilder.ts +19 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
- package/Server/Utils/AI/IncidentAIContextBuilder.ts +39 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
- package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
- package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
- package/Server/Utils/AI/Toolbox/AlertTools.ts +37 -1
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +22 -1
- package/Server/Utils/AI/Toolbox/Index.ts +38 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +416 -51
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +151 -13
- package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +17 -4
- package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +155 -8
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +16 -0
- package/Server/Utils/Database/RelationValueUtil.ts +106 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +6 -1
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +22 -27
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
- package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +3 -1
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +50 -20
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +13 -1
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +6 -11
- package/Server/Utils/Rules/MonitorRulePatternValidator.ts +51 -0
- package/Server/Utils/Rules/OwnerRuleAssignment.ts +110 -0
- package/Server/Utils/Rules/RuleRun/RuleApplication.ts +81 -0
- package/Server/Utils/Rules/RuleRun/RuleRunPermission.ts +188 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +803 -0
- package/Server/Utils/Rules/RuleRun/RuleRunner.ts +341 -0
- package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +3 -2
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
- package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +497 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
- package/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.ts +609 -74
- package/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.ts +2101 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1182 -0
- package/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.ts → Connectors/SecurityEventConnectionRunExecutor.ts} +165 -76
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +306 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +55 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
- package/Server/Utils/SecurityEvent/Connectors/Types.ts +431 -0
- package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +1 -1
- package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
- package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +2 -2
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +902 -40
- package/Server/Utils/Slo/SloFeedUtil.ts +200 -0
- package/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.ts +173 -0
- package/Server/Utils/Slo/SloMetricUtil.ts +327 -0
- package/Server/Utils/Slo/SloOwnerReferenceValidator.ts +208 -0
- package/Server/Utils/Slo/SloRecordReferenceValidator.ts +169 -0
- package/Server/Utils/StartServer.ts +10 -0
- package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +6 -43
- package/Server/Utils/StatusPageResource.ts +50 -5
- package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
- package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
- package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
- package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
- package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
- package/Server/Utils/Telemetry.ts +18 -0
- package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +1063 -1
- package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
- package/Tests/App/Dashboard/AddWidgetModal.test.tsx +4 -1
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +307 -0
- package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
- package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +289 -0
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +598 -0
- package/Tests/App/Dashboard/BillingDefaultPaymentMethod.test.tsx +1046 -0
- package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +3 -0
- package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +201 -7
- package/Tests/App/Dashboard/BooleanSeriesCriteriaFilterText.test.ts +82 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +16 -1
- package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +943 -0
- package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +168 -1
- package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
- package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
- package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +755 -0
- package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +1095 -1
- package/Tests/App/Dashboard/CorrelateFilterChips.test.tsx +910 -0
- package/Tests/App/Dashboard/CorrelateGraph.test.tsx +3747 -25
- package/Tests/App/Dashboard/CorrelateGraphHelpers.test.ts +1085 -0
- package/Tests/App/Dashboard/CorrelateInspector.test.tsx +1534 -0
- package/Tests/App/Dashboard/CorrelateNodeCard.test.tsx +965 -0
- package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +1525 -0
- package/Tests/App/Dashboard/CorrelationGraph.test.ts +1030 -0
- package/Tests/App/Dashboard/CorrelationGraphLayout.test.ts +526 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
- package/Tests/App/Dashboard/DeviceDiagnostics.test.tsx +787 -0
- package/Tests/App/Dashboard/DeviceLatencyTrend.test.tsx +278 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +279 -0
- package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +87 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +443 -8
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
- package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +340 -0
- package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
- package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2450 -0
- package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
- package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
- package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
- package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
- package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
- package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
- package/Tests/App/Dashboard/ExceptionSegmentedControl.test.tsx +1020 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
- package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
- package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
- package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
- package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
- package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
- package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1472 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1931 -25
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +159 -2
- package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1398 -0
- package/Tests/App/Dashboard/InvestigationRunDetails.test.tsx +1166 -0
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +437 -0
- package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
- package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
- package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
- package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
- package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +65 -0
- package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +5 -0
- package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
- package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
- package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +74 -0
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +125 -5
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
- package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
- package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +1764 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1958 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +448 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +1455 -0
- package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +233 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +282 -0
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
- package/Tests/App/Dashboard/SloActiveBurnEventsCard.test.tsx +538 -0
- package/Tests/App/Dashboard/SloBulkActionsArchive.test.tsx +252 -0
- package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +322 -518
- package/Tests/App/Dashboard/SloElement.test.tsx +194 -0
- package/Tests/App/Dashboard/SloFeed.test.tsx +289 -0
- package/Tests/App/Dashboard/SloHistoryCharts.test.tsx +471 -0
- package/Tests/App/Dashboard/SloHistorySeries.test.tsx +607 -0
- package/Tests/App/Dashboard/SloListWidget.test.tsx +783 -0
- package/Tests/App/Dashboard/SloMetricsPage.test.tsx +346 -0
- package/Tests/App/Dashboard/SloMonitorsPage.test.tsx +661 -0
- package/Tests/App/Dashboard/SloMonitorsSummaryCard.test.tsx +489 -0
- package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +437 -0
- package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +305 -0
- package/Tests/App/Dashboard/SloOverviewData.test.tsx +563 -0
- package/Tests/App/Dashboard/SloOverviewHero.test.tsx +311 -0
- package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +426 -0
- package/Tests/App/Dashboard/SloOverviewSidebarCards.test.tsx +493 -0
- package/Tests/App/Dashboard/SloSettings.test.tsx +633 -0
- package/Tests/App/Dashboard/SloStatusSummaryCards.test.tsx +403 -0
- package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +373 -0
- package/Tests/App/Dashboard/SloWidgetVariableBinding.test.tsx +689 -0
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
- package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
- package/Tests/App/Dashboard/TopologyConnectivitySection.test.tsx +206 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
- package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
- package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
- package/Tests/App/Dashboard/TracesEntityNames.test.tsx +617 -0
- package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
- package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +1312 -0
- package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +9 -1
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +14 -16
- package/Tests/Models/DatabaseModels/AuditLogModelConfiguration.test.ts +442 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +13 -7
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +48 -1
- package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +835 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +3 -2
- package/Tests/Models/DiscoveryScanNetbiosLookupColumn.test.ts +328 -0
- package/Tests/Models/DiscoveryScanShortDeviceNamesColumn.test.ts +335 -0
- package/Tests/Models/InventoryItemNaming.test.ts +132 -16
- package/Tests/Models/NetworkDeviceDiagnosticContract.test.ts +194 -0
- package/Tests/Models/NetworkDeviceDnsNameColumn.test.ts +321 -0
- package/Tests/Models/ProjectDataResidencyColumn.test.ts +154 -0
- package/Tests/Models/SecurityDomainAccessControl.test.ts +197 -22
- package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
- package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
- package/Tests/Server/API/BaseAPI.test.ts +6 -0
- package/Tests/Server/API/BaseAPIUpdateMiscDataProps.test.ts +217 -0
- package/Tests/Server/API/BillingInvoiceAPI.test.ts +7 -0
- package/Tests/Server/API/BillingInvoiceAPIPaymentStates.test.ts +990 -0
- package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +498 -0
- package/Tests/Server/API/DashboardPublicSloAPI.test.ts +405 -0
- package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +1750 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +644 -1
- package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +857 -0
- package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +1084 -0
- package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +33 -3
- package/Tests/Server/Infrastructure/Postgres/AddDataResidencyToProjectMigration.test.ts +202 -0
- package/Tests/Server/Infrastructure/Postgres/AddNetbiosLookupToNetworkDeviceDiscoveryScanMigration.test.ts +330 -0
- package/Tests/Server/Infrastructure/Postgres/AddNetworkDeviceDnsNameAndShortDeviceNamesMigration.test.ts +340 -0
- package/Tests/Server/Infrastructure/Postgres/BackfillSloMonitorRulesAndAffectedResourcesMigration.test.ts +343 -0
- package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +801 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
- package/Tests/Server/Services/AddSubscriberUpdateNotificationStatusMigration.test.ts +307 -0
- package/Tests/Server/Services/AuditLogService.test.ts +1124 -0
- package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +200 -1
- package/Tests/Server/Services/BillingInvoiceServiceMutexRelease.test.ts +254 -0
- package/Tests/Server/Services/BillingService.test.ts +70 -0
- package/Tests/Server/Services/BillingServicePayInvoiceStates.test.ts +723 -0
- package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +14 -2
- package/Tests/Server/Services/BillingServiceSubscriptionPaymentMethodSync.test.ts +1634 -0
- package/Tests/Server/Services/DatabaseServiceAuditRelationDiff.test.ts +492 -0
- package/Tests/Server/Services/DatabaseServicePasswordFieldSecrets.test.ts +629 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +431 -0
- package/Tests/Server/Services/IncidentAlertSloReferenceGuard.test.ts +358 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
- package/Tests/Server/Services/MonitorProbeServicePastDueMonitoring.test.ts +362 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1460 -1
- package/Tests/Server/Services/NetworkDeviceDiagnosticService.test.ts +962 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +106 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +10 -1
- package/Tests/Server/Services/NetworkDeviceServicePastDueMonitoring.test.ts +335 -0
- package/Tests/Server/Services/NetworkDeviceSiteRuleDnsName.test.ts +568 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/ProjectDataResidencyPostgres.test.ts +344 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +187 -0
- package/Tests/Server/Services/ProjectServiceDataResidency.test.ts +369 -0
- package/Tests/Server/Services/ProjectServiceDataResidencySelfHosted.test.ts +176 -0
- package/Tests/Server/Services/ProjectServicePastDueMonitoring.test.ts +289 -0
- package/Tests/Server/Services/ResourceFeedServices.test.ts +24 -8
- package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +1396 -0
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupARun.test.ts +917 -0
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +1262 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +902 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +1163 -0
- package/Tests/Server/Services/RuleRun/PrivacyRuleEnginesRun.test.ts +843 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +465 -0
- package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1754 -0
- package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +77 -23
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleFeedWrites.test.ts +777 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleOptions.test.ts +1399 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +67 -74
- package/Tests/Server/Services/ServiceLevelObjectiveChildRowTenancy.test.ts +906 -0
- package/Tests/Server/Services/ServiceLevelObjectiveDeleteTenancy.test.ts +1029 -0
- package/Tests/Server/Services/ServiceLevelObjectiveFeedService.test.ts +313 -0
- package/Tests/Server/Services/ServiceLevelObjectiveFeedWrites.test.ts +1214 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMarkdownLink.test.ts +289 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +1455 -430
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleLegacyLabelAdoption.test.ts +634 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +1193 -0
- package/Tests/Server/Services/{SloMonitorLabelRuleHooks.test.ts → ServiceLevelObjectiveMonitorRuleTriggers.test.ts} +135 -41
- package/Tests/Server/Services/ServiceLevelObjectiveOwnerFeedWrites.test.ts +671 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +180 -85
- package/Tests/Server/Services/ServiceLevelObjectiveServiceArchive.test.ts +537 -0
- package/Tests/Server/Services/ServiceLevelObjectiveServiceLegacyMonitorLabelWrite.test.ts +870 -0
- package/Tests/Server/Services/ServiceLevelObjectiveServiceMonitorRuleGuard.test.ts +343 -0
- package/Tests/Server/Services/ServiceLevelObjectiveServiceReEvaluation.test.ts +246 -0
- package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +501 -0
- package/Tests/Server/Services/SloAffectedResourceLinkContract.test.ts +86 -0
- package/Tests/Server/Services/SloAffectedResourceMetricAttributes.test.ts +547 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +10 -4
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +7 -2
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +174 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateServiceVariables.test.ts +40 -0
- package/Tests/Server/Services/SubscriberUpdateNotificationHooks.test.ts +541 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
- package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +288 -0
- package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
- package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
- package/Tests/Server/TestingUtils/PastDueMonitoringClaimSql.ts +177 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +51 -10
- package/Tests/Server/TestingUtils/__mocks__/Stripe.mock.ts +16 -1
- package/Tests/Server/Types/Database/Permissions/ProjectDataResidencyColumn.test.ts +386 -0
- package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +34 -11
- package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
- package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
- package/Tests/Server/Utils/AI/SloAffectedResourceAIContext.test.ts +445 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +423 -1
- package/Tests/Server/Utils/AI/SloToolsArchive.test.ts +294 -0
- package/Tests/Server/Utils/AI/SloToolsRuleReadPermissions.test.ts +297 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
- package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +255 -10
- package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +404 -750
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +45 -0
- package/Tests/Server/Utils/Database/RelationValueUtil.test.ts +157 -0
- package/Tests/Server/Utils/Monitor/Criteria/BooleanSeriesEvaluateOverTime.test.ts +260 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +181 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +147 -30
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
- package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.test.ts +17 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +136 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidatorLoadOrder.test.ts +472 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +48 -2
- package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +435 -475
- package/Tests/Server/Utils/Rules/MonitorRulePatternValidator.test.ts +77 -0
- package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +177 -0
- package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +365 -0
- package/Tests/Server/Utils/Rules/RuleRun/RuleRunRegistry.test.ts +173 -0
- package/Tests/Server/Utils/Rules/RuleRun/RuleRunner.test.ts +675 -0
- package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +8 -8
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorFetchSummary.test.ts +261 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1184 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsAuth.test.ts → Connectors/GoogleSecOps/GoogleSecOpsAuth.test.ts} +5 -5
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClient.test.ts → Connectors/GoogleSecOps/GoogleSecOpsClient.test.ts} +9 -5
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.test.ts +483 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorCuratedAndLateAlerts.test.ts +676 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFetchEvents.test.ts +1994 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFixtures.ts +332 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorHttpIntegration.test.ts +680 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorRequestContract.test.ts +1206 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorTestConnection.test.ts +1136 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsCuratedRuleCounts.test.ts +407 -0
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsErrorHandling.test.ts → Connectors/GoogleSecOps/GoogleSecOpsErrorHandling.test.ts} +5 -5
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingAdaptiveCatchUp.test.ts +730 -0
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClickhouseIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts} +130 -35
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFailureTaxonomy.test.ts +772 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFixtures.ts +648 -0
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsHttpIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingHttpIntegration.test.ts} +249 -222
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingIntegration.test.ts +1390 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingLoop.test.ts +981 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingNothingImportedRegression.test.ts +290 -0
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsRequestContract.test.ts → Connectors/GoogleSecOps/GoogleSecOpsRequestContract.test.ts} +2 -2
- package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsResponseParsing.test.ts → Connectors/GoogleSecOps/GoogleSecOpsResponseParsing.test.ts} +5 -5
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsSearchDetections.test.ts +763 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsTesterIntegration.test.ts +421 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +4483 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1178 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +1215 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1966 -179
- package/Tests/Server/Utils/Slo/SloFeedUtil.test.ts +326 -0
- package/Tests/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.test.ts +260 -0
- package/Tests/Server/Utils/Slo/SloMetricUtil.test.ts +592 -0
- package/Tests/Server/Utils/Slo/SloRecordReferenceValidator.test.ts +311 -0
- package/Tests/Server/Utils/StatusPageResource.test.ts +91 -3
- package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
- package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +348 -2
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
- package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
- package/Tests/Types/Billing/SubscriptionStatus.test.ts +176 -0
- package/Tests/Types/Billing/SubscriptionStatusPastDueMonitoring.test.ts +187 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +53 -7
- package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +816 -792
- package/Tests/Types/Monitor/CriteriaFilter.test.ts +216 -24
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +14 -1
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +14 -1
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +14 -1
- package/Tests/Types/Monitor/MonitorStepRetriesParsing.test.ts +201 -0
- package/Tests/Types/Rules/RuleRun.test.ts +315 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +133 -0
- package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
- package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +339 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +217 -0
- package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +200 -0
- package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
- package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
- package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +411 -0
- package/Tests/UI/Components/AlertBanner.test.tsx +319 -0
- package/Tests/UI/Components/BulkArchiveActionsCopy.test.tsx +310 -0
- package/Tests/UI/Components/Card.test.tsx +312 -1
- package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
- package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
- package/Tests/UI/Components/Checkbox.test.tsx +79 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
- package/Tests/UI/Components/Detail/DetailIdIsUnique.test.tsx +87 -0
- package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
- package/Tests/UI/Components/Dropdown/DropdownClearable.test.tsx +393 -0
- package/Tests/UI/Components/Dropdown/DropdownMultiSelectChipAccessibleName.test.tsx +64 -0
- package/Tests/UI/Components/EmptyState/EmptyState.test.tsx +335 -4
- package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +337 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
- package/Tests/UI/Components/FacetSections.test.tsx +581 -0
- package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
- package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
- package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +21 -20
- package/Tests/UI/Components/LabelRuleImportExport.test.tsx +15 -2
- package/Tests/UI/Components/LockedFilterChip.test.tsx +788 -0
- package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
- package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
- package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
- package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
- package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
- package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
- package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
- package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
- package/Tests/UI/Components/MoreMenu.test.tsx +133 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +84 -3
- package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
- package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/RuleRun/RuleDetailFields.test.tsx +336 -0
- package/Tests/UI/Components/RuleRun/RuleTable.test.tsx +304 -0
- package/Tests/UI/Components/RuleRun/RunRuleNowModal.test.tsx +231 -0
- package/Tests/UI/Components/RuleRun/RunRulesBulkAction.test.ts +213 -0
- package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
- package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +367 -0
- package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
- package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
- package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
- package/Tests/UI/Rum/ReplayEngine.test.ts +154 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +284 -124
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +189 -10
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +286 -12
- package/Tests/UI/Rum/ReplayRail.test.tsx +294 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +213 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1228 -173
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +433 -3
- package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +1391 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +222 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
- package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
- package/Tests/UI/Utils/Clipboard.test.ts +154 -0
- package/Tests/UI/Utils/DashboardStackingLayers.test.ts +8 -1
- package/Tests/UI/Utils/Navigation.test.ts +24 -0
- package/Tests/UI/Utils/RuleRunClient.test.ts +303 -0
- package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2206 -0
- package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
- package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +2 -0
- package/Tests/Utils/Dashboard/Components/DashboardSloListComponent.test.ts +206 -0
- package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +36 -2
- package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +409 -588
- package/Tests/Utils/Dashboard/SloWidgetSource.test.ts +351 -0
- package/Tests/Utils/Markdown/MarkdownEscape.test.ts +361 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +1425 -118
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +188 -3
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +661 -13
- package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +349 -0
- package/Tests/Utils/NetworkDiscovery/RunImportedDeviceNaming.test.ts +656 -0
- package/Tests/Utils/NetworkDiscovery/ShortDeviceNamePlanner.test.ts +1020 -0
- package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +619 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +317 -0
- package/Tests/Utils/Project/DataResidency.test.ts +198 -0
- package/Tests/Utils/Rules/RuleRunSummary.test.ts +394 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
- package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
- package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
- package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
- package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
- package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
- package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
- package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
- package/Tests/Utils/Slo/SloAffectedResourceMarkdown.test.ts +302 -0
- package/Tests/Utils/Slo/SloBurnRateTemplate.test.ts +468 -0
- package/Tests/Utils/Slo/SloEvaluation.test.ts +20 -4
- package/Tests/Utils/Slo/SloFeedMarkdown.test.ts +1185 -0
- package/Tests/Utils/Slo/SloHealth.test.ts +262 -0
- package/Tests/Utils/Slo/SloHistoryMetricName.test.ts +102 -0
- package/Tests/Utils/Slo/SloListWidgetFormat.test.ts +522 -0
- package/Tests/Utils/Slo/SloMetricType.test.ts +355 -0
- package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +387 -0
- package/Tests/Utils/Slo/SloMonitorStatusSummary.test.ts +210 -0
- package/Tests/Utils/Slo/SloOverviewText.test.ts +226 -0
- package/Tests/Utils/Slo/SloProjection.test.ts +1039 -0
- package/Tests/Utils/Slo/SloWidgetFormat.test.ts +47 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
- package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +521 -0
- package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
- package/Types/AI/AIChatTypes.ts +8 -0
- package/Types/AI/InvestigationEvidence.ts +96 -0
- package/Types/BaseDatabase/EnableAuditLogOn.ts +41 -0
- package/Types/Billing/SubscriptionStatus.ts +39 -4
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +5 -0
- package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +10 -0
- package/Types/Dashboard/DashboardComponents/DashboardSloListComponent.ts +29 -0
- package/Types/Dashboard/DashboardTemplates.ts +290 -297
- package/Types/Database/EnableAuditLog.ts +23 -1
- package/Types/Email/EmailTemplateType.ts +4 -0
- package/Types/Monitor/CriteriaFilter.ts +55 -8
- package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
- package/Types/Monitor/MonitorStep.ts +5 -2
- package/Types/Monitor/MonitorStepDnsMonitor.ts +3 -1
- package/Types/Monitor/MonitorStepDnssecMonitor.ts +3 -1
- package/Types/Monitor/MonitorStepDomainMonitor.ts +3 -1
- package/Types/Monitor/MonitorStepExternalStatusPageMonitor.ts +3 -1
- package/Types/Monitor/MonitorStepRetries.ts +59 -0
- package/Types/Monitor/MonitorStepSnmpMonitor.ts +9 -2
- package/Types/NetworkDevice/NetworkDeviceDiagnosticResult.ts +104 -0
- package/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.ts +47 -0
- package/Types/NetworkDevice/NetworkDeviceDiagnosticType.ts +47 -0
- package/Types/NetworkDevice/NetworkDevicePingMetricNames.ts +20 -0
- package/Types/Permission.ts +129 -2
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +5 -0
- package/Types/Rules/RuleRun.ts +518 -0
- package/Types/Rum/SessionReplay.ts +109 -0
- package/Types/Rum/SessionReplayApi.ts +49 -0
- package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +117 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +113 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +599 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +45 -0
- package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
- package/Types/ServiceLevelObjective/SloHistoryMetricName.ts +25 -0
- package/Types/ServiceLevelObjective/SloMetricType.ts +49 -0
- package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +4 -0
- package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +331 -0
- package/Types/StatusPage/SubscriberNotificationTrigger.ts +12 -0
- package/Types/StatusPage/SubscriberUpdateNotification.ts +89 -0
- package/Types/Telemetry/EntityType.ts +14 -0
- package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
- package/Types/Telemetry/LockedFilterDetail.ts +25 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
- package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
- package/Types/Telemetry/ServiceType.ts +7 -0
- package/Typings/Index.d.ts +53 -3
- package/UI/Components/AlertBanner/AlertBanner.tsx +85 -27
- package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +21 -2
- package/UI/Components/Card/Card.tsx +118 -83
- package/UI/Components/Checkbox/Checkbox.tsx +8 -5
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
- package/UI/Components/Detail/Detail.tsx +145 -23
- package/UI/Components/Dropdown/Dropdown.tsx +64 -1
- package/UI/Components/EmptyState/EmptyState.tsx +27 -3
- package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +124 -0
- package/UI/Components/ErrorBoundary.tsx +38 -0
- package/UI/Components/Forms/ModelForm.tsx +6 -5
- package/UI/Components/LabelRule/LabelRuleTable.tsx +8 -2
- package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +152 -77
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +17 -11
- package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
- package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
- package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
- package/UI/Components/LogsViewer/types.ts +6 -0
- package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
- package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
- package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
- package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
- package/UI/Components/ModelList/ModelList.tsx +33 -8
- package/UI/Components/MoreMenu/MoreMenu.tsx +14 -3
- package/UI/Components/Page/ModelPage.tsx +119 -54
- package/UI/Components/RuleRun/RuleDetailFields.tsx +359 -0
- package/UI/Components/RuleRun/RuleTable.tsx +183 -0
- package/UI/Components/RuleRun/RuleView.tsx +170 -0
- package/UI/Components/RuleRun/RunRuleNowModal.tsx +147 -0
- package/UI/Components/RuleRun/RunRulesBulkAction.ts +103 -0
- package/UI/Components/Table/Table.tsx +8 -0
- package/UI/Components/Table/TableRow.tsx +13 -5
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
- package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +7 -0
- package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
- package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
- package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
- package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +430 -0
- package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +14 -10
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
- package/UI/Components/TelemetryViewer/types.ts +19 -0
- package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
- package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
- package/UI/Utils/Clipboard.ts +68 -2
- package/UI/Utils/Navigation.ts +17 -2
- package/UI/Utils/Rules/RuleRunClient.ts +178 -0
- package/UI/Utils/Telemetry/TelemetryEntityNames.ts +628 -0
- package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
- package/Utils/AI/InvestigationReport.ts +1789 -0
- package/Utils/API.ts +90 -1
- package/Utils/Dashboard/Components/DashboardSloComponent.ts +19 -2
- package/Utils/Dashboard/Components/DashboardSloListComponent.ts +126 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/Dashboard/SloWidgetSource.ts +188 -0
- package/Utils/Markdown/MarkdownEscape.ts +63 -0
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +161 -36
- package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +25 -0
- package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +146 -0
- package/Utils/NetworkDiscovery/RunImportedDeviceNaming.ts +390 -0
- package/Utils/NetworkDiscovery/ShortDeviceNamePlanner.ts +291 -0
- package/Utils/NetworkDiscovery/ShortHostnameUtil.ts +91 -0
- package/Utils/NetworkSite/CidrMatchUtil.ts +37 -12
- package/Utils/Project/DataResidency.ts +63 -0
- package/Utils/Rules/RuleRunSummary.ts +323 -0
- package/Utils/Rum/SessionReplayHealth.ts +11 -0
- package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
- package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
- package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
- package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
- package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
- package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
- package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
- package/Utils/Slo/SloAffectedResourceMarkdown.ts +123 -0
- package/Utils/Slo/SloBurnRateTemplate.ts +373 -0
- package/Utils/Slo/SloFeedMarkdown.ts +1507 -0
- package/Utils/Slo/SloHealth.ts +96 -9
- package/Utils/Slo/SloListWidgetFormat.ts +370 -0
- package/Utils/Slo/SloMetricType.ts +237 -0
- package/Utils/Slo/SloMonitorRuleCriteria.ts +364 -0
- package/Utils/Slo/SloMonitorStatusSummary.ts +210 -0
- package/Utils/Slo/SloOverviewText.ts +265 -0
- package/Utils/Slo/SloProjection.ts +967 -0
- package/Utils/Slo/SloWidgetFormat.ts +12 -2
- package/Utils/Telemetry/CrossSignalScope.ts +22 -8
- package/Utils/Telemetry/EntityRelationship.ts +8 -0
- package/Utils/Telemetry/LockedFilterSearch.ts +366 -0
- package/Utils/Telemetry/NetworkHost.ts +43 -0
- package/Utils/Telemetry/OriginAllowList.ts +139 -4
- package/Utils/Traces/CriticalPath.ts +10 -4
- package/build/dist/Models/AnalyticsModels/AuditLog.js +70 -1
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/SecurityEvent.js +4 -4
- package/build/dist/Models/DatabaseModels/Alert.js +60 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +64 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +75 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +75 -0
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +10 -4
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +68 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js +772 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +140 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +42 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +75 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnection.js → SecurityEventConnection.js} +87 -75
- package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
- package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnectionRun.js → SecurityEventConnectionRun.js} +37 -37
- package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +192 -10
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +798 -96
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +596 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +590 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +16 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +16 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +75 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +14 -0
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js +233 -19
- package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
- package/build/dist/Server/API/BillingPaymentMethodAPI.js +86 -5
- package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +72 -2
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/SecurityEventConnectionAPI.js +263 -0
- package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +236 -154
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +248 -170
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js +207 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js +72 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +112 -56
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +167 -68
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +87 -26
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js +270 -203
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +498 -354
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +97 -34
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +91 -8
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +408 -44
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/BillingInvoiceService.js +94 -85
- package/build/dist/Server/Services/BillingInvoiceService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +406 -14
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +189 -101
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +135 -86
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +189 -100
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +117 -69
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +125 -18
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +189 -101
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +145 -91
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +191 -101
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/HostLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js +190 -102
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +112 -56
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +220 -63
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +87 -26
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +258 -192
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +519 -376
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +95 -32
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +90 -5
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +113 -65
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +22 -0
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +117 -69
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +145 -91
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +191 -101
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +20 -25
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +8 -17
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +4 -14
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +123 -77
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +167 -82
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +18 -2
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +11 -9
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +287 -5
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js +333 -0
- package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +117 -69
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +36 -2
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +117 -64
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +173 -83
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +116 -65
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +189 -101
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +82 -10
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +189 -101
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +111 -63
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +161 -77
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +117 -69
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +280 -209
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +521 -376
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +24 -8
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/{GoogleSecOpsConnectionRunService.js → SecurityEventConnectionRunService.js} +2 -2
- package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js +396 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +115 -62
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +163 -77
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +769 -18
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js +96 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +614 -87
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +844 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +207 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +221 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +997 -50
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +191 -102
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +12 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +118 -70
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +158 -76
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +19 -215
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +6 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -5
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/ThreatIntelFeedService.js +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +51 -25
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +141 -92
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +189 -101
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +117 -69
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +171 -83
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +17 -0
- package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +31 -0
- package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +24 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +21 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +337 -53
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +108 -15
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +2 -2
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +115 -6
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +13 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/Database/RelationValueUtil.js +82 -0
- package/build/dist/Server/Utils/Database/RelationValueUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +10 -6
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +17 -21
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +5 -4
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +50 -10
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +13 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +6 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js +34 -0
- package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +69 -0
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js +128 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +746 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js +221 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +3 -2
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +354 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.js +401 -68
- package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js +1417 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +839 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.js → Connectors/SecurityEventConnectionRunExecutor.js} +77 -50
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +214 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +42 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +122 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +1 -1
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +2 -2
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +599 -32
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/Slo/SloFeedUtil.js +150 -0
- package/build/dist/Server/Utils/Slo/SloFeedUtil.js.map +1 -0
- package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js +136 -0
- package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js.map +1 -0
- package/build/dist/Server/Utils/Slo/SloMetricUtil.js +269 -0
- package/build/dist/Server/Utils/Slo/SloMetricUtil.js.map +1 -0
- package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js +134 -0
- package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js +137 -0
- package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +10 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +6 -26
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageResource.js +31 -5
- package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +11 -5
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
- package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
- package/build/dist/Types/Billing/SubscriptionStatus.js +37 -3
- package/build/dist/Types/Billing/SubscriptionStatus.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +5 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +275 -286
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Database/EnableAuditLog.js +19 -1
- package/build/dist/Types/Database/EnableAuditLog.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +4 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +45 -6
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +2 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js +3 -1
- package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +3 -1
- package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +3 -1
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js +3 -1
- package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepRetries.js +47 -0
- package/build/dist/Types/Monitor/MonitorStepRetries.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -1
- package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js +29 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js +37 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js +42 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js +20 -0
- package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js.map +1 -0
- package/build/dist/Types/Permission.js +116 -2
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +5 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +267 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +95 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +17 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +439 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +39 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js +26 -0
- package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloMetricType.js +45 -0
- package/build/dist/Types/ServiceLevelObjective/SloMetricType.js.map +1 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +295 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js +13 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +67 -0
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +14 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js +7 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/AlertBanner/AlertBanner.js +48 -19
- package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +10 -2
- package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
- package/build/dist/UI/Components/Card/Card.js +34 -17
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +74 -15
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -5
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +3 -3
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +47 -0
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +1 -0
- package/build/dist/UI/Components/ErrorBoundary.js +34 -0
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +6 -5
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +6 -2
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +3 -7
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +3 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +62 -34
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/RuleRun/RuleDetailFields.js +226 -0
- package/build/dist/UI/Components/RuleRun/RuleDetailFields.js.map +1 -0
- package/build/dist/UI/Components/RuleRun/RuleTable.js +97 -0
- package/build/dist/UI/Components/RuleRun/RuleTable.js.map +1 -0
- package/build/dist/UI/Components/RuleRun/RuleView.js +83 -0
- package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -0
- package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +74 -0
- package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -0
- package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js +78 -0
- package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +3 -1
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +8 -1
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +202 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +2 -6
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
- package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
- package/build/dist/UI/Utils/Clipboard.js +59 -2
- package/build/dist/UI/Utils/Clipboard.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +11 -2
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/Rules/RuleRunClient.js +98 -0
- package/build/dist/UI/Utils/Rules/RuleRunClient.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +479 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
- package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
- package/build/dist/Utils/API.js +25 -0
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +16 -2
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js +94 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/Dashboard/SloWidgetSource.js +125 -0
- package/build/dist/Utils/Dashboard/SloWidgetSource.js.map +1 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js +49 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +112 -34
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +22 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +129 -0
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js +255 -0
- package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js +184 -0
- package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js +79 -0
- package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +21 -12
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
- package/build/dist/Utils/Project/DataResidency.js +51 -0
- package/build/dist/Utils/Project/DataResidency.js.map +1 -0
- package/build/dist/Utils/Rules/RuleRunSummary.js +197 -0
- package/build/dist/Utils/Rules/RuleRunSummary.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
- package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js +51 -0
- package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js.map +1 -0
- package/build/dist/Utils/Slo/SloBurnRateTemplate.js +228 -0
- package/build/dist/Utils/Slo/SloBurnRateTemplate.js.map +1 -0
- package/build/dist/Utils/Slo/SloFeedMarkdown.js +934 -0
- package/build/dist/Utils/Slo/SloFeedMarkdown.js.map +1 -0
- package/build/dist/Utils/Slo/SloHealth.js +75 -9
- package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
- package/build/dist/Utils/Slo/SloListWidgetFormat.js +217 -0
- package/build/dist/Utils/Slo/SloListWidgetFormat.js.map +1 -0
- package/build/dist/Utils/Slo/SloMetricType.js +212 -0
- package/build/dist/Utils/Slo/SloMetricType.js.map +1 -0
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +216 -0
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -0
- package/build/dist/Utils/Slo/SloMonitorStatusSummary.js +129 -0
- package/build/dist/Utils/Slo/SloMonitorStatusSummary.js.map +1 -0
- package/build/dist/Utils/Slo/SloOverviewText.js +110 -0
- package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -0
- package/build/dist/Utils/Slo/SloProjection.js +448 -0
- package/build/dist/Utils/Slo/SloProjection.js.map +1 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js +4 -2
- package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js +252 -0
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
- package/build/dist/Utils/Traces/CriticalPath.js +9 -4
- package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
- package/package.json +1 -1
- package/Server/API/GoogleSecOpsConnectionAPI.ts +0 -79
- package/Server/Services/GoogleSecOpsConnectionService.ts +0 -101
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +0 -774
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +0 -423
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +0 -724
- package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +0 -248
- package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +0 -153
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +0 -711
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +0 -838
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +0 -716
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +0 -860
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +0 -1231
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
- package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +0 -56
- package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
- package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
- package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
- package/UI/Components/GanttChart/Index.tsx +0 -90
- package/UI/Components/GanttChart/Row/Index.tsx +0 -22
- package/UI/Components/GanttChart/Row/Row.tsx +0 -231
- package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
- package/UI/Components/GanttChart/Rows.tsx +0 -59
- package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
- package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
- package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +0 -1
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +0 -1
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +0 -56
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +0 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +0 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +0 -62
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +0 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +0 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +0 -577
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +0 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +0 -1
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +0 -2
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
- package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Index.js +0 -39
- package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
- package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
- package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
- package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js.map +0 -1
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
fireEvent,
|
|
14
14
|
render,
|
|
15
15
|
screen,
|
|
16
|
+
within,
|
|
16
17
|
} from "@testing-library/react";
|
|
17
18
|
import * as React from "react";
|
|
18
19
|
import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
@@ -30,6 +31,7 @@ const getFriendlyMessageMock: MockFunction = getJestMockFunction();
|
|
|
30
31
|
const getCommonHeadersMock: MockFunction = getJestMockFunction();
|
|
31
32
|
const markdownViewerMock: MockFunction = getJestMockFunction();
|
|
32
33
|
const activityFeedMock: MockFunction = getJestMockFunction();
|
|
34
|
+
const widgetRendererMock: MockFunction = getJestMockFunction();
|
|
33
35
|
|
|
34
36
|
jest.mock("../../../UI/Utils/API/API", () => {
|
|
35
37
|
return {
|
|
@@ -59,6 +61,8 @@ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
|
59
61
|
/*
|
|
60
62
|
* Record MarkdownViewer's props so safeMode remains an asserted part of the
|
|
61
63
|
* contract even when the Common Jest config replaces its markdown renderer.
|
|
64
|
+
* The recorded `inlineReferences` are the panel's own chip/link renderers, so
|
|
65
|
+
* tests can call them and render what they return.
|
|
62
66
|
*/
|
|
63
67
|
jest.mock("../../../UI/Components/Markdown.tsx/LazyMarkdownViewer", () => {
|
|
64
68
|
return {
|
|
@@ -75,13 +79,30 @@ jest.mock("../../../UI/Components/Markdown.tsx/LazyMarkdownViewer", () => {
|
|
|
75
79
|
});
|
|
76
80
|
|
|
77
81
|
/*
|
|
78
|
-
* The feed owns
|
|
79
|
-
*
|
|
80
|
-
* instead of counting raw events, so the mock has to answer
|
|
81
|
-
*
|
|
82
|
-
* case that used to
|
|
82
|
+
* The feed owns "how many steps will this draw?", because several event
|
|
83
|
+
* types only close a step an earlier event opened. The panel and its run
|
|
84
|
+
* details ask it instead of counting raw events, so the mock has to answer
|
|
85
|
+
* too. countActivityStepsMock lets a test make events and steps disagree —
|
|
86
|
+
* the case that used to frame an empty box — and hasRenderableActivityMock
|
|
87
|
+
* follows it by default, exactly as the real predicate does, so the two
|
|
88
|
+
* exports can never contradict each other unless a test says so.
|
|
83
89
|
*/
|
|
84
90
|
const hasRenderableActivityMock: MockFunction = getJestMockFunction();
|
|
91
|
+
const countActivityStepsMock: MockFunction = getJestMockFunction();
|
|
92
|
+
|
|
93
|
+
// Evidence rows render through the chat widgets; their output is not under test.
|
|
94
|
+
jest.mock(
|
|
95
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/AIChat/Widgets/WidgetRenderer",
|
|
96
|
+
() => {
|
|
97
|
+
return {
|
|
98
|
+
__esModule: true,
|
|
99
|
+
default: (props: { widgets: Array<JSONObject> }): React.ReactElement => {
|
|
100
|
+
widgetRendererMock(props);
|
|
101
|
+
return React.createElement("div", { "data-testid": "evidence-widget" });
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
);
|
|
85
106
|
|
|
86
107
|
jest.mock(
|
|
87
108
|
"../../../../App/FeatureSet/Dashboard/src/Components/AIChat/ChatActivityFeed",
|
|
@@ -97,6 +118,9 @@ jest.mock(
|
|
|
97
118
|
hasRenderableActivity: (events: Array<AIRunEvent>): boolean => {
|
|
98
119
|
return hasRenderableActivityMock(events) as boolean;
|
|
99
120
|
},
|
|
121
|
+
countActivitySteps: (events: Array<AIRunEvent>): number => {
|
|
122
|
+
return countActivityStepsMock(events) as number;
|
|
123
|
+
},
|
|
100
124
|
};
|
|
101
125
|
},
|
|
102
126
|
);
|
|
@@ -108,13 +132,16 @@ import AIRunEvent from "../../../Models/DatabaseModels/AIRunEvent";
|
|
|
108
132
|
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
109
133
|
import AIRunCodeFixRecommendation from "../../../Types/AI/AIRunCodeFixRecommendation";
|
|
110
134
|
import AIRunEventType from "../../../Types/AI/AIRunEventType";
|
|
135
|
+
import AIRunHumanVerdict from "../../../Types/AI/AIRunHumanVerdict";
|
|
111
136
|
import AIRunStatus from "../../../Types/AI/AIRunStatus";
|
|
112
137
|
import { JSONArray, JSONObject } from "../../../Types/JSON";
|
|
113
138
|
import ObjectID from "../../../Types/ObjectID";
|
|
139
|
+
import type { MarkdownInlineReferenceRenderers } from "../../../UI/Components/Markdown.tsx/InlineReferences";
|
|
114
140
|
|
|
115
141
|
interface MarkdownViewerProps {
|
|
116
142
|
text: string;
|
|
117
143
|
safeMode?: boolean | undefined;
|
|
144
|
+
inlineReferences?: MarkdownInlineReferenceRenderers | undefined;
|
|
118
145
|
}
|
|
119
146
|
|
|
120
147
|
interface ActivityFeedProps {
|
|
@@ -138,6 +165,8 @@ interface InvestigationPayloadOptions {
|
|
|
138
165
|
humanVerdict?: string | null | undefined;
|
|
139
166
|
codeFixRecommendation?: AIRunCodeFixRecommendation | undefined;
|
|
140
167
|
completedAt?: string | undefined;
|
|
168
|
+
evidence?: JSONArray | undefined;
|
|
169
|
+
references?: JSONArray | undefined;
|
|
141
170
|
}
|
|
142
171
|
|
|
143
172
|
interface ApiResponse {
|
|
@@ -203,13 +232,27 @@ function investigationPayload(
|
|
|
203
232
|
run["completedAt"] = options.completedAt;
|
|
204
233
|
}
|
|
205
234
|
|
|
206
|
-
|
|
235
|
+
const payload: JSONObject = {
|
|
207
236
|
run,
|
|
208
237
|
events: options.events || [],
|
|
209
238
|
analysisMarkdown: options.analysisMarkdown ?? null,
|
|
210
239
|
analysisTldr: options.analysisTldr ?? null,
|
|
211
240
|
isAnalysisPending: options.isAnalysisPending === true,
|
|
212
241
|
};
|
|
242
|
+
|
|
243
|
+
/*
|
|
244
|
+
* Older API replicas omit these keys entirely, so they are only present
|
|
245
|
+
* when a test asks for them.
|
|
246
|
+
*/
|
|
247
|
+
if (options.evidence !== undefined) {
|
|
248
|
+
payload["evidence"] = options.evidence;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (options.references !== undefined) {
|
|
252
|
+
payload["references"] = options.references;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return payload;
|
|
213
256
|
}
|
|
214
257
|
|
|
215
258
|
function successfulResponse(payload: JSONObject): ApiResponse {
|
|
@@ -264,6 +307,8 @@ function renderPanel(data?: {
|
|
|
264
307
|
subjectId?: ObjectID | undefined;
|
|
265
308
|
onAnalysisAvailable?: (() => void) | undefined;
|
|
266
309
|
onStatusChange?: ((status: AIRunStatus | null) => void) | undefined;
|
|
310
|
+
onReportSummaryChange?: ((summary: string | null) => void) | undefined;
|
|
311
|
+
onVerdictChange?: ((verdict: AIRunHumanVerdict | null) => void) | undefined;
|
|
267
312
|
}): ReturnType<typeof render> {
|
|
268
313
|
return render(
|
|
269
314
|
<InvestigationPanel
|
|
@@ -271,6 +316,8 @@ function renderPanel(data?: {
|
|
|
271
316
|
subjectId={data?.subjectId || INCIDENT_ID}
|
|
272
317
|
onAnalysisAvailable={data?.onAnalysisAvailable}
|
|
273
318
|
onStatusChange={data?.onStatusChange}
|
|
319
|
+
onReportSummaryChange={data?.onReportSummaryChange}
|
|
320
|
+
onVerdictChange={data?.onVerdictChange}
|
|
274
321
|
/>,
|
|
275
322
|
);
|
|
276
323
|
}
|
|
@@ -334,17 +381,59 @@ function lastActivityProps(): ActivityFeedProps {
|
|
|
334
381
|
return calls[calls.length - 1]![0]!;
|
|
335
382
|
}
|
|
336
383
|
|
|
384
|
+
/*
|
|
385
|
+
* A completed run ends with one collapsed section holding its evidence, its
|
|
386
|
+
* activity and what it cost. Its body stays mounted while collapsed, so the
|
|
387
|
+
* role queries below (which skip hidden content) only find what a reader
|
|
388
|
+
* could actually reach; tests open the section before reaching inside it.
|
|
389
|
+
*/
|
|
390
|
+
function runDetails(): HTMLElement {
|
|
391
|
+
return screen.getByTestId("investigation-details");
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function detailsToggle(): HTMLElement {
|
|
395
|
+
return screen.getByTestId("investigation-details-toggle");
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function detailsBody(): HTMLElement {
|
|
399
|
+
const bodyId: string | null = detailsToggle().getAttribute("aria-controls");
|
|
400
|
+
expect(bodyId).toBeTruthy();
|
|
401
|
+
return document.getElementById(bodyId!)!;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function openDetails(): void {
|
|
405
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
406
|
+
fireEvent.click(detailsToggle());
|
|
407
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function detailsTab(name: RegExp): HTMLElement {
|
|
411
|
+
return within(
|
|
412
|
+
screen.getByRole("tablist", { name: "Investigation details" }),
|
|
413
|
+
).getByRole("tab", { name });
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function evidenceList(): HTMLElement {
|
|
417
|
+
return screen.getByRole("list", { name: "Evidence checked" });
|
|
418
|
+
}
|
|
419
|
+
|
|
337
420
|
beforeEach(() => {
|
|
338
421
|
jest.useFakeTimers();
|
|
339
422
|
jest.setSystemTime(new Date(COMPLETED_AT));
|
|
340
423
|
getCommonHeadersMock.mockReturnValue({});
|
|
341
424
|
/*
|
|
342
425
|
* Default to the real component's behaviour for the ordinary event shapes
|
|
343
|
-
* these tests use: every step-opening event draws a step
|
|
426
|
+
* these tests use: every step-opening event draws a step, and there is
|
|
427
|
+
* activity to render exactly when at least one step is drawn.
|
|
344
428
|
*/
|
|
429
|
+
countActivityStepsMock.mockImplementation(
|
|
430
|
+
(events: Array<AIRunEvent>): number => {
|
|
431
|
+
return events.length;
|
|
432
|
+
},
|
|
433
|
+
);
|
|
345
434
|
hasRenderableActivityMock.mockImplementation(
|
|
346
435
|
(events: Array<AIRunEvent>): boolean => {
|
|
347
|
-
return events
|
|
436
|
+
return (countActivityStepsMock(events) as number) > 0;
|
|
348
437
|
},
|
|
349
438
|
);
|
|
350
439
|
getFriendlyMessageMock.mockImplementation((error: unknown): string => {
|
|
@@ -371,6 +460,8 @@ afterEach(() => {
|
|
|
371
460
|
markdownViewerMock.mockReset();
|
|
372
461
|
activityFeedMock.mockReset();
|
|
373
462
|
hasRenderableActivityMock.mockReset();
|
|
463
|
+
countActivityStepsMock.mockReset();
|
|
464
|
+
widgetRendererMock.mockReset();
|
|
374
465
|
});
|
|
375
466
|
|
|
376
467
|
describe("InvestigationPanel report lifecycle", () => {
|
|
@@ -420,7 +511,7 @@ describe("InvestigationPanel report lifecycle", () => {
|
|
|
420
511
|
expect(getCommonHeadersMock).toHaveBeenCalledTimes(1);
|
|
421
512
|
});
|
|
422
513
|
|
|
423
|
-
test("renders the completed report safely and
|
|
514
|
+
test("renders the completed report safely and folds its activity into a collapsed section", async () => {
|
|
424
515
|
const onAnalysisAvailable: MockFunction = getJestMockFunction();
|
|
425
516
|
postMock.mockResolvedValue(completedResponse() as never);
|
|
426
517
|
|
|
@@ -432,25 +523,45 @@ describe("InvestigationPanel report lifecycle", () => {
|
|
|
432
523
|
expect(screen.getByTestId("investigation-markdown")).toHaveTextContent(
|
|
433
524
|
"The database connection pool was exhausted.",
|
|
434
525
|
);
|
|
526
|
+
/*
|
|
527
|
+
* The report renders section by section: the "## Root cause" heading
|
|
528
|
+
* becomes the section's own title and its body goes through the safe
|
|
529
|
+
* viewer together with the panel's inline reference renderers.
|
|
530
|
+
*/
|
|
435
531
|
expect(markdownViewerMock).toHaveBeenCalledWith({
|
|
436
|
-
text:
|
|
532
|
+
text: "The database connection pool was exhausted.",
|
|
437
533
|
safeMode: true,
|
|
534
|
+
inlineReferences: expect.objectContaining({
|
|
535
|
+
renderCitation: expect.any(Function),
|
|
536
|
+
renderEventReference: expect.any(Function),
|
|
537
|
+
}),
|
|
438
538
|
});
|
|
439
|
-
expect(
|
|
539
|
+
expect(
|
|
540
|
+
screen.getByRole("heading", { level: 4, name: "Root cause" }),
|
|
541
|
+
).toBeInTheDocument();
|
|
542
|
+
/*
|
|
543
|
+
* This report carries no evidence, so the section is only the activity
|
|
544
|
+
* and is named for it. It starts collapsed: the report is the answer.
|
|
545
|
+
*/
|
|
546
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
547
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
548
|
+
expect(detailsBody()).not.toBeVisible();
|
|
440
549
|
expect(lastActivityProps()).toEqual(
|
|
441
550
|
expect.objectContaining({
|
|
442
551
|
hideChrome: true,
|
|
443
552
|
showLiveIndicator: false,
|
|
444
|
-
maxVisibleSteps: 10,
|
|
445
553
|
}),
|
|
446
554
|
);
|
|
447
555
|
|
|
448
556
|
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
557
|
+
expect(usage).toBeVisible();
|
|
449
558
|
expect(usage).toHaveTextContent("2 telemetry queries");
|
|
450
|
-
expect(usage).toHaveTextContent("1,234 tokens");
|
|
451
559
|
expect(usage).toHaveTextContent(
|
|
452
560
|
"Read-only — nothing in your systems was changed",
|
|
453
561
|
);
|
|
562
|
+
expect(screen.getByLabelText("Model and tokens")).toHaveTextContent(
|
|
563
|
+
"1,234 tokens",
|
|
564
|
+
);
|
|
454
565
|
expect(fixButton()).toBeEnabled();
|
|
455
566
|
expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
|
|
456
567
|
expect(screen.getByRole("button", { name: "Rejected" })).toBeEnabled();
|
|
@@ -480,6 +591,8 @@ describe("InvestigationPanel report lifecycle", () => {
|
|
|
480
591
|
expect(screen.getByText("Preparing investigation report…")).toBeVisible();
|
|
481
592
|
expect(screen.getByText("Preparing the final report")).toBeVisible();
|
|
482
593
|
expect(screen.queryByTestId("investigation-markdown")).toBeNull();
|
|
594
|
+
// The steps can already be checked while the report is being written.
|
|
595
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
483
596
|
expect(onAnalysisAvailable).not.toHaveBeenCalled();
|
|
484
597
|
|
|
485
598
|
/* Status, run id, events and recommendation remain identical. */
|
|
@@ -627,6 +740,19 @@ describe("InvestigationPanel report lifecycle", () => {
|
|
|
627
740
|
expect(
|
|
628
741
|
screen.getByText("No investigation report was published."),
|
|
629
742
|
).toBeVisible();
|
|
743
|
+
/*
|
|
744
|
+
* No steps were recorded, so the notice does not point at an activity
|
|
745
|
+
* section that is not there, and there is nothing to expand: the run's
|
|
746
|
+
* usage is all that is left to say.
|
|
747
|
+
*/
|
|
748
|
+
expect(
|
|
749
|
+
screen.getByText("The run finished without a final analysis."),
|
|
750
|
+
).toBeVisible();
|
|
751
|
+
expect(screen.queryByText(/Investigation activity/)).toBeNull();
|
|
752
|
+
expect(screen.queryByTestId("investigation-details-toggle")).toBeNull();
|
|
753
|
+
expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
|
|
754
|
+
"0 telemetry queries",
|
|
755
|
+
);
|
|
630
756
|
expect(fixButton()).toBeDisabled();
|
|
631
757
|
expect(screen.getByRole("button", { name: "Confirmed" })).toBeDisabled();
|
|
632
758
|
expect(screen.getByRole("button", { name: "Rejected" })).toBeDisabled();
|
|
@@ -720,14 +846,16 @@ describe("InvestigationPanel card states", () => {
|
|
|
720
846
|
expect(screen.getByText("Starting investigation…")).toBeVisible();
|
|
721
847
|
});
|
|
722
848
|
|
|
723
|
-
test("puts a copy control
|
|
849
|
+
test("puts a copy control and a verify-first note on the report", async () => {
|
|
724
850
|
postMock.mockResolvedValue(completedResponse() as never);
|
|
725
851
|
|
|
726
852
|
renderPanel();
|
|
727
853
|
await flush();
|
|
728
854
|
|
|
729
855
|
const report: HTMLElement = screen.getByLabelText("Investigation report");
|
|
730
|
-
expect(report).toHaveTextContent(
|
|
856
|
+
expect(report).toHaveTextContent(
|
|
857
|
+
"AI-generated first pass — verify before acting.",
|
|
858
|
+
);
|
|
731
859
|
expect(report).toContainElement(
|
|
732
860
|
screen.getByRole("button", { name: "Copy report" }),
|
|
733
861
|
);
|
|
@@ -762,6 +890,45 @@ describe("InvestigationPanel card states", () => {
|
|
|
762
890
|
},
|
|
763
891
|
);
|
|
764
892
|
|
|
893
|
+
/*
|
|
894
|
+
* A failed run has no report and no collapsed details, so what it ran and
|
|
895
|
+
* the read-only guarantee close its own activity frame instead — a reader
|
|
896
|
+
* deciding whether a half-finished run touched anything finds the answer
|
|
897
|
+
* right under the steps it took.
|
|
898
|
+
*/
|
|
899
|
+
test("ends a failed run's activity with what it ran and that it changed nothing", async () => {
|
|
900
|
+
postMock.mockResolvedValue(
|
|
901
|
+
successfulResponse(
|
|
902
|
+
investigationPayload({
|
|
903
|
+
status: AIRunStatus.Error,
|
|
904
|
+
errorMessage: "The model provider timed out.",
|
|
905
|
+
events: [activityEvent],
|
|
906
|
+
toolCallCount: 3,
|
|
907
|
+
totalTokens: 900,
|
|
908
|
+
}),
|
|
909
|
+
) as never,
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
renderPanel();
|
|
913
|
+
await flush();
|
|
914
|
+
|
|
915
|
+
const activity: HTMLElement = screen.getByRole("region", {
|
|
916
|
+
name: "Investigation activity",
|
|
917
|
+
});
|
|
918
|
+
const usage: HTMLElement = within(activity).getByRole("list", {
|
|
919
|
+
name: "Investigation usage",
|
|
920
|
+
});
|
|
921
|
+
expect(activity.lastElementChild).toBe(usage);
|
|
922
|
+
expect(usage).toBeVisible();
|
|
923
|
+
expect(usage).toHaveTextContent("3 telemetry queries");
|
|
924
|
+
expect(usage).toHaveTextContent("900 tokens");
|
|
925
|
+
expect(usage).toHaveTextContent(
|
|
926
|
+
"Read-only — nothing in your systems was changed",
|
|
927
|
+
);
|
|
928
|
+
expect(screen.queryByTestId("investigation-details")).toBeNull();
|
|
929
|
+
expect(screen.getAllByLabelText("Investigation usage")).toHaveLength(1);
|
|
930
|
+
});
|
|
931
|
+
|
|
765
932
|
/*
|
|
766
933
|
* Events and rendered steps are not the same thing: RunFailed and the
|
|
767
934
|
* completion halves of tool/LLM calls only close a step an earlier event
|
|
@@ -770,7 +937,7 @@ describe("InvestigationPanel card states", () => {
|
|
|
770
937
|
* an empty panel instead of saying what happened.
|
|
771
938
|
*/
|
|
772
939
|
test("explains an empty trail instead of framing a blank panel", async () => {
|
|
773
|
-
|
|
940
|
+
countActivityStepsMock.mockReturnValue(0);
|
|
774
941
|
postMock.mockResolvedValue(
|
|
775
942
|
successfulResponse(
|
|
776
943
|
investigationPayload({
|
|
@@ -790,8 +957,14 @@ describe("InvestigationPanel card states", () => {
|
|
|
790
957
|
).toBeVisible();
|
|
791
958
|
});
|
|
792
959
|
|
|
793
|
-
|
|
794
|
-
|
|
960
|
+
/*
|
|
961
|
+
* The same event/step mismatch on a completed run: with no evidence and no
|
|
962
|
+
* step to draw, a collapsed section would open onto nothing. The run's
|
|
963
|
+
* usage is all there is, so it stands alone — tokens included, since there
|
|
964
|
+
* is no body to hold them.
|
|
965
|
+
*/
|
|
966
|
+
test("offers nothing to expand when a completed run has no evidence and no step would render", async () => {
|
|
967
|
+
countActivityStepsMock.mockReturnValue(0);
|
|
795
968
|
postMock.mockResolvedValue(completedResponse() as never);
|
|
796
969
|
|
|
797
970
|
renderPanel();
|
|
@@ -799,9 +972,17 @@ describe("InvestigationPanel card states", () => {
|
|
|
799
972
|
|
|
800
973
|
expect(screen.getByLabelText("Investigation report")).toBeInTheDocument();
|
|
801
974
|
expect(screen.queryByText("Investigation activity")).toBeNull();
|
|
975
|
+
expect(screen.queryByTestId("investigation-details-toggle")).toBeNull();
|
|
976
|
+
expect(screen.queryByTestId("investigation-activity")).toBeNull();
|
|
977
|
+
|
|
978
|
+
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
979
|
+
expect(usage).toBeVisible();
|
|
980
|
+
expect(usage).toHaveTextContent("2 telemetry queries");
|
|
981
|
+
expect(usage).toHaveTextContent("1,234 tokens");
|
|
982
|
+
expect(usage).not.toHaveTextContent("step");
|
|
802
983
|
});
|
|
803
984
|
|
|
804
|
-
test("reports a single query without pluralising
|
|
985
|
+
test("reports a single query and step without pluralising them", async () => {
|
|
805
986
|
postMock.mockResolvedValue(
|
|
806
987
|
completedResponse({ toolCallCount: 1, totalTokens: 0 }) as never,
|
|
807
988
|
);
|
|
@@ -811,8 +992,50 @@ describe("InvestigationPanel card states", () => {
|
|
|
811
992
|
|
|
812
993
|
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
813
994
|
expect(usage).toHaveTextContent("1 telemetry query");
|
|
995
|
+
expect(usage).not.toHaveTextContent("queries");
|
|
996
|
+
expect(usage).toHaveTextContent("1 step");
|
|
997
|
+
expect(usage).not.toHaveTextContent("steps");
|
|
814
998
|
expect(usage).not.toHaveTextContent("tokens");
|
|
815
999
|
});
|
|
1000
|
+
|
|
1001
|
+
/*
|
|
1002
|
+
* The no-report notice used to send every reader to "the activity below",
|
|
1003
|
+
* even when no step had been recorded and there was nothing below to read.
|
|
1004
|
+
*/
|
|
1005
|
+
test("points the no-report notice at the activity only when there is some", async () => {
|
|
1006
|
+
postMock.mockResolvedValue(
|
|
1007
|
+
completedResponse({
|
|
1008
|
+
analysisMarkdown: null,
|
|
1009
|
+
isAnalysisPending: false,
|
|
1010
|
+
}) as never,
|
|
1011
|
+
);
|
|
1012
|
+
|
|
1013
|
+
renderPanel();
|
|
1014
|
+
await flush();
|
|
1015
|
+
|
|
1016
|
+
expect(
|
|
1017
|
+
screen.getByText(
|
|
1018
|
+
"The run finished without a final analysis. Its steps are under Investigation activity below.",
|
|
1019
|
+
),
|
|
1020
|
+
).toBeVisible();
|
|
1021
|
+
|
|
1022
|
+
/*
|
|
1023
|
+
* Evidence only exists beside a report, so the section is the activity
|
|
1024
|
+
* alone: named for it, and without tabs once opened.
|
|
1025
|
+
*/
|
|
1026
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
1027
|
+
expect(detailsToggle()).not.toHaveTextContent("Evidence");
|
|
1028
|
+
expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
|
|
1029
|
+
"2 telemetry queries",
|
|
1030
|
+
);
|
|
1031
|
+
|
|
1032
|
+
openDetails();
|
|
1033
|
+
|
|
1034
|
+
expect(screen.queryByRole("tablist")).toBeNull();
|
|
1035
|
+
expect(screen.queryByRole("tabpanel")).toBeNull();
|
|
1036
|
+
expect(screen.queryByLabelText("Evidence checked")).toBeNull();
|
|
1037
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
1038
|
+
});
|
|
816
1039
|
});
|
|
817
1040
|
|
|
818
1041
|
/*
|
|
@@ -845,10 +1068,10 @@ describe("InvestigationPanel TL;DR", () => {
|
|
|
845
1068
|
// The summary is never routed through the markdown renderer.
|
|
846
1069
|
expect(markdownTexts().length).toBeGreaterThan(0);
|
|
847
1070
|
expect(
|
|
848
|
-
markdownTexts().
|
|
849
|
-
return text
|
|
1071
|
+
markdownTexts().some((text: string): boolean => {
|
|
1072
|
+
return text.includes(TLDR);
|
|
850
1073
|
}),
|
|
851
|
-
).toBe(
|
|
1074
|
+
).toBe(false);
|
|
852
1075
|
|
|
853
1076
|
// It sits above the report it summarizes.
|
|
854
1077
|
const report: HTMLElement = screen.getByLabelText("Investigation report");
|
|
@@ -1021,10 +1244,10 @@ describe("InvestigationPanel TL;DR", () => {
|
|
|
1021
1244
|
).toBeUndefined();
|
|
1022
1245
|
// The summary never reaches the markdown renderer.
|
|
1023
1246
|
expect(
|
|
1024
|
-
markdownTexts().
|
|
1025
|
-
return text
|
|
1247
|
+
markdownTexts().some((text: string): boolean => {
|
|
1248
|
+
return text.includes("__pwned");
|
|
1026
1249
|
}),
|
|
1027
|
-
).toBe(
|
|
1250
|
+
).toBe(false);
|
|
1028
1251
|
});
|
|
1029
1252
|
|
|
1030
1253
|
test("drops the previous subject's summary the moment the subject changes", async () => {
|
|
@@ -1693,3 +1916,1686 @@ describe("InvestigationPanel completed actions", () => {
|
|
|
1693
1916
|
expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
|
|
1694
1917
|
});
|
|
1695
1918
|
});
|
|
1919
|
+
|
|
1920
|
+
/*
|
|
1921
|
+
* The completed report is laid out for a responder: its Summary in a section
|
|
1922
|
+
* of its own, the report section by section, and every query the AI ran with
|
|
1923
|
+
* the rows behind it one click away. The payload's `evidence` and
|
|
1924
|
+
* `references` drive the interactive parts; older API replicas omit them and
|
|
1925
|
+
* the panel must fall back to the markdown alone.
|
|
1926
|
+
*/
|
|
1927
|
+
const PRIOR_INCIDENT_ID: string = "66666666-6666-4666-8666-666666666666";
|
|
1928
|
+
const PRIOR_ALERT_ID: string = "77777777-7777-4777-8777-777777777777";
|
|
1929
|
+
const REPORT_SUMMARY: string =
|
|
1930
|
+
"the connection pool ran dry after the 18:00 deploy.";
|
|
1931
|
+
|
|
1932
|
+
const STRUCTURED_REPORT: string = [
|
|
1933
|
+
"## \u{1F9E0} AI — Automated Root Cause Analysis",
|
|
1934
|
+
"",
|
|
1935
|
+
"**Summary** — the connection pool ran dry after the 18:00 deploy [C1].",
|
|
1936
|
+
"",
|
|
1937
|
+
"**Most likely root cause** — the deploy halved the pool size; this matches prior #6954 [C2].",
|
|
1938
|
+
"",
|
|
1939
|
+
"**Suggested next steps**",
|
|
1940
|
+
"- Roll back the deploy",
|
|
1941
|
+
"",
|
|
1942
|
+
"**Evidence checked**",
|
|
1943
|
+
"- **[C1]** Active incidents (7 total) — 7 row(s)",
|
|
1944
|
+
"- **[C2]** Logs 17:20 – 18:20 (1 shown) — 1 row(s)",
|
|
1945
|
+
"",
|
|
1946
|
+
"---",
|
|
1947
|
+
"*Investigated automatically by OneUptime AI — read-only, 2 queries run across your own telemetry using gpt-5. This is an AI-generated first pass; verify before acting.*",
|
|
1948
|
+
].join("\n");
|
|
1949
|
+
|
|
1950
|
+
const EVIDENCE_ITEMS: JSONArray = [
|
|
1951
|
+
{
|
|
1952
|
+
citationId: "C1",
|
|
1953
|
+
toolName: "query_incidents",
|
|
1954
|
+
label: "Active incidents (7 total)",
|
|
1955
|
+
rowCount: 7,
|
|
1956
|
+
durationInMs: 812,
|
|
1957
|
+
queryArguments: { state: "active" },
|
|
1958
|
+
target: { type: "Incidents" },
|
|
1959
|
+
executedAt: "2026-08-07T11:58:00.000Z",
|
|
1960
|
+
canLoadRows: true,
|
|
1961
|
+
},
|
|
1962
|
+
{
|
|
1963
|
+
citationId: "C2",
|
|
1964
|
+
toolName: "search_logs",
|
|
1965
|
+
label: "Logs 17:20 – 18:20 (1 shown)",
|
|
1966
|
+
rowCount: 1,
|
|
1967
|
+
queryArguments: { bodySearchText: "pool timeout" },
|
|
1968
|
+
target: { type: "Logs" },
|
|
1969
|
+
executedAt: "2026-08-07T11:59:00.000Z",
|
|
1970
|
+
canLoadRows: true,
|
|
1971
|
+
},
|
|
1972
|
+
];
|
|
1973
|
+
|
|
1974
|
+
const REFERENCES: JSONArray = [
|
|
1975
|
+
{
|
|
1976
|
+
kind: "incident",
|
|
1977
|
+
number: 6954,
|
|
1978
|
+
id: PRIOR_INCIDENT_ID,
|
|
1979
|
+
displayNumber: "INC-6954",
|
|
1980
|
+
title: "Checkout pool exhausted",
|
|
1981
|
+
stateName: "Resolved",
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
kind: "alert",
|
|
1985
|
+
number: 6954,
|
|
1986
|
+
id: PRIOR_ALERT_ID,
|
|
1987
|
+
displayNumber: "#6954",
|
|
1988
|
+
title: "Webhook failures",
|
|
1989
|
+
},
|
|
1990
|
+
];
|
|
1991
|
+
|
|
1992
|
+
interface EvidencePostRequest extends PostRequest {
|
|
1993
|
+
headers?: JSONObject | undefined;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
function structuredResponse(
|
|
1997
|
+
overrides: Partial<InvestigationPayloadOptions> = {},
|
|
1998
|
+
): ApiResponse {
|
|
1999
|
+
return completedResponse({
|
|
2000
|
+
analysisMarkdown: STRUCTURED_REPORT,
|
|
2001
|
+
evidence: EVIDENCE_ITEMS,
|
|
2002
|
+
references: REFERENCES,
|
|
2003
|
+
...overrides,
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
function evidenceRowsResponse(citationId: string, text: string): ApiResponse {
|
|
2008
|
+
return successfulResponse({
|
|
2009
|
+
citationId,
|
|
2010
|
+
toolName: "query_incidents",
|
|
2011
|
+
label: "Active incidents (7 total)",
|
|
2012
|
+
rowCount: 7,
|
|
2013
|
+
isTruncated: false,
|
|
2014
|
+
executedAt: COMPLETED_AT,
|
|
2015
|
+
isPinnedToInvestigationTime: false,
|
|
2016
|
+
text,
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
/*
|
|
2021
|
+
* Investigation polls and evidence re-runs share API.post, so route by URL:
|
|
2022
|
+
* the investigation handler answers the panel's own endpoint and the evidence
|
|
2023
|
+
* handler (default: never resolves) answers /ai-investigation/evidence.
|
|
2024
|
+
*/
|
|
2025
|
+
function routePosts(handlers: {
|
|
2026
|
+
investigation: (request: EvidencePostRequest) => unknown;
|
|
2027
|
+
evidence?: ((request: EvidencePostRequest) => unknown) | undefined;
|
|
2028
|
+
}): void {
|
|
2029
|
+
postMock.mockImplementation((request: unknown): unknown => {
|
|
2030
|
+
const typedRequest: EvidencePostRequest = request as EvidencePostRequest;
|
|
2031
|
+
|
|
2032
|
+
if (typedRequest.url.toString().includes("/ai-investigation/evidence")) {
|
|
2033
|
+
return handlers.evidence
|
|
2034
|
+
? handlers.evidence(typedRequest)
|
|
2035
|
+
: new Promise<never>(() => {});
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
return handlers.investigation(typedRequest);
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
function evidencePosts(): Array<EvidencePostRequest> {
|
|
2043
|
+
return (postMock.mock.calls as Array<Array<EvidencePostRequest>>)
|
|
2044
|
+
.map((call: Array<EvidencePostRequest>): EvidencePostRequest => {
|
|
2045
|
+
return call[0]!;
|
|
2046
|
+
})
|
|
2047
|
+
.filter((request: EvidencePostRequest): boolean => {
|
|
2048
|
+
return request.url.toString().includes("/ai-investigation/evidence");
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
function investigationPostCount(): number {
|
|
2053
|
+
return postMock.mock.calls.length - evidencePosts().length;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
function lastInlineReferences(): MarkdownInlineReferenceRenderers {
|
|
2057
|
+
const calls: Array<Array<MarkdownViewerProps>> = markdownViewerMock.mock
|
|
2058
|
+
.calls as Array<Array<MarkdownViewerProps>>;
|
|
2059
|
+
return calls[calls.length - 1]![0]!.inlineReferences!;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
function allMarkdownProps(): Array<MarkdownViewerProps> {
|
|
2063
|
+
return (
|
|
2064
|
+
markdownViewerMock.mock.calls as Array<Array<MarkdownViewerProps>>
|
|
2065
|
+
).map((call: Array<MarkdownViewerProps>): MarkdownViewerProps => {
|
|
2066
|
+
return call[0]!;
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
describe("InvestigationPanel structured report", () => {
|
|
2071
|
+
const scrollIntoViewMock: MockFunction = getJestMockFunction();
|
|
2072
|
+
|
|
2073
|
+
beforeEach(() => {
|
|
2074
|
+
Object.defineProperty(Element.prototype, "scrollIntoView", {
|
|
2075
|
+
configurable: true,
|
|
2076
|
+
writable: true,
|
|
2077
|
+
value: scrollIntoViewMock,
|
|
2078
|
+
});
|
|
2079
|
+
});
|
|
2080
|
+
|
|
2081
|
+
afterEach(() => {
|
|
2082
|
+
scrollIntoViewMock.mockReset();
|
|
2083
|
+
delete (Element.prototype as unknown as { scrollIntoView?: unknown })
|
|
2084
|
+
.scrollIntoView;
|
|
2085
|
+
});
|
|
2086
|
+
|
|
2087
|
+
test("lifts the report's Summary into its own section above the report", async () => {
|
|
2088
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2089
|
+
|
|
2090
|
+
renderPanel();
|
|
2091
|
+
await flush();
|
|
2092
|
+
|
|
2093
|
+
const summary: HTMLElement = screen.getByRole("region", {
|
|
2094
|
+
name: "Investigation summary",
|
|
2095
|
+
});
|
|
2096
|
+
expect(summary).toHaveTextContent(
|
|
2097
|
+
"the connection pool ran dry after the 18:00 deploy [C1].",
|
|
2098
|
+
);
|
|
2099
|
+
expect(within(summary).queryByText("TL;DR")).toBeNull();
|
|
2100
|
+
|
|
2101
|
+
const report: HTMLElement = screen.getByRole("region", {
|
|
2102
|
+
name: "Investigation report",
|
|
2103
|
+
});
|
|
2104
|
+
expect(
|
|
2105
|
+
within(report)
|
|
2106
|
+
.getAllByRole("heading", { level: 4 })
|
|
2107
|
+
.map((heading: HTMLElement): string => {
|
|
2108
|
+
return heading.textContent || "";
|
|
2109
|
+
}),
|
|
2110
|
+
).toEqual(["Most likely root cause", "Suggested next steps"]);
|
|
2111
|
+
expect(report).not.toHaveTextContent("the connection pool ran dry");
|
|
2112
|
+
expect(
|
|
2113
|
+
summary.compareDocumentPosition(report) &
|
|
2114
|
+
Node.DOCUMENT_POSITION_FOLLOWING,
|
|
2115
|
+
).toBeTruthy();
|
|
2116
|
+
|
|
2117
|
+
for (const props of allMarkdownProps()) {
|
|
2118
|
+
expect(props.safeMode).toBe(true);
|
|
2119
|
+
expect(props.text).not.toContain("Automated Root Cause Analysis");
|
|
2120
|
+
expect(props.text).not.toContain("Evidence checked");
|
|
2121
|
+
expect(props.text).not.toContain("Investigated automatically");
|
|
2122
|
+
}
|
|
2123
|
+
});
|
|
2124
|
+
|
|
2125
|
+
test("renders the evidence the API returns, below the report", async () => {
|
|
2126
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2127
|
+
|
|
2128
|
+
renderPanel();
|
|
2129
|
+
await flush();
|
|
2130
|
+
|
|
2131
|
+
expect(
|
|
2132
|
+
screen
|
|
2133
|
+
.getByLabelText("Investigation report")
|
|
2134
|
+
.compareDocumentPosition(runDetails()) &
|
|
2135
|
+
Node.DOCUMENT_POSITION_FOLLOWING,
|
|
2136
|
+
).toBeTruthy();
|
|
2137
|
+
|
|
2138
|
+
openDetails();
|
|
2139
|
+
|
|
2140
|
+
// The tab carries the query count the old list header used to show.
|
|
2141
|
+
expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
|
|
2142
|
+
"Evidence checked2",
|
|
2143
|
+
);
|
|
2144
|
+
const evidence: HTMLElement = evidenceList();
|
|
2145
|
+
expect(runDetails()).toContainElement(evidence);
|
|
2146
|
+
expect(within(evidence).getAllByRole("listitem")).toHaveLength(2);
|
|
2147
|
+
expect(
|
|
2148
|
+
within(evidence).getByRole("button", { name: /Active incidents/ }),
|
|
2149
|
+
).toHaveAttribute("aria-expanded", "false");
|
|
2150
|
+
// Rendering evidence never re-runs anything by itself.
|
|
2151
|
+
expect(evidencePosts()).toHaveLength(0);
|
|
2152
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
2153
|
+
});
|
|
2154
|
+
|
|
2155
|
+
test("expanding a query POSTs its citation once and shows the rows", async () => {
|
|
2156
|
+
routePosts({
|
|
2157
|
+
investigation: (): unknown => {
|
|
2158
|
+
return Promise.resolve(structuredResponse());
|
|
2159
|
+
},
|
|
2160
|
+
evidence: (): unknown => {
|
|
2161
|
+
return Promise.resolve(
|
|
2162
|
+
evidenceRowsResponse("C1", "id | title\n1 | Checkout down"),
|
|
2163
|
+
);
|
|
2164
|
+
},
|
|
2165
|
+
});
|
|
2166
|
+
|
|
2167
|
+
renderPanel();
|
|
2168
|
+
await flush();
|
|
2169
|
+
openDetails();
|
|
2170
|
+
|
|
2171
|
+
const toggle: HTMLElement = screen.getByRole("button", {
|
|
2172
|
+
name: /Active incidents \(7 total\)/,
|
|
2173
|
+
});
|
|
2174
|
+
fireEvent.click(toggle);
|
|
2175
|
+
await flush();
|
|
2176
|
+
|
|
2177
|
+
expect(evidencePosts()).toHaveLength(1);
|
|
2178
|
+
expect(evidencePosts()[0]!.data).toEqual({
|
|
2179
|
+
subjectType: "incident",
|
|
2180
|
+
subjectId: INCIDENT_ID.toString(),
|
|
2181
|
+
investigationRunId: RUN_ID,
|
|
2182
|
+
citationId: "C1",
|
|
2183
|
+
});
|
|
2184
|
+
expect(screen.getByText(/Checkout down/)).toBeVisible();
|
|
2185
|
+
|
|
2186
|
+
// Collapse and re-open: served from the cache.
|
|
2187
|
+
fireEvent.click(toggle);
|
|
2188
|
+
fireEvent.click(toggle);
|
|
2189
|
+
await flush();
|
|
2190
|
+
|
|
2191
|
+
expect(evidencePosts()).toHaveLength(1);
|
|
2192
|
+
expect(investigationPostCount()).toBe(1);
|
|
2193
|
+
});
|
|
2194
|
+
|
|
2195
|
+
test("falls back to the report's own Evidence checked list for an older API", async () => {
|
|
2196
|
+
postMock.mockResolvedValue(
|
|
2197
|
+
completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
|
|
2198
|
+
);
|
|
2199
|
+
|
|
2200
|
+
renderPanel();
|
|
2201
|
+
await flush();
|
|
2202
|
+
openDetails();
|
|
2203
|
+
|
|
2204
|
+
const evidence: HTMLElement = evidenceList();
|
|
2205
|
+
expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
|
|
2206
|
+
"Evidence checked2",
|
|
2207
|
+
);
|
|
2208
|
+
expect(evidence).toHaveTextContent("Active incidents (7 total)");
|
|
2209
|
+
expect(evidence).toHaveTextContent("Logs 17:20 – 18:20 (1 shown)");
|
|
2210
|
+
expect(within(evidence).queryAllByRole("button")).toHaveLength(0);
|
|
2211
|
+
// No references from an older API, so numbers stay plain text.
|
|
2212
|
+
expect(
|
|
2213
|
+
lastInlineReferences().renderEventReference!({
|
|
2214
|
+
kind: null,
|
|
2215
|
+
number: 6954,
|
|
2216
|
+
text: "#6954",
|
|
2217
|
+
}),
|
|
2218
|
+
).toBeNull();
|
|
2219
|
+
});
|
|
2220
|
+
|
|
2221
|
+
test("picks up evidence that arrives on a later poll", async () => {
|
|
2222
|
+
postMock
|
|
2223
|
+
.mockResolvedValueOnce(
|
|
2224
|
+
completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
|
|
2225
|
+
)
|
|
2226
|
+
.mockResolvedValue(structuredResponse() as never);
|
|
2227
|
+
|
|
2228
|
+
renderPanel();
|
|
2229
|
+
await flush();
|
|
2230
|
+
openDetails();
|
|
2231
|
+
expect(within(evidenceList()).getAllByRole("listitem")).toHaveLength(2);
|
|
2232
|
+
expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
|
|
2233
|
+
|
|
2234
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2235
|
+
|
|
2236
|
+
// Still open on the same list, now with a toggle per query.
|
|
2237
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2238
|
+
expect(within(evidenceList()).getAllByRole("button")).toHaveLength(2);
|
|
2239
|
+
});
|
|
2240
|
+
|
|
2241
|
+
test("never shows evidence without the report it belongs to", async () => {
|
|
2242
|
+
postMock.mockResolvedValue(
|
|
2243
|
+
completedResponse({
|
|
2244
|
+
analysisMarkdown: null,
|
|
2245
|
+
isAnalysisPending: true,
|
|
2246
|
+
evidence: EVIDENCE_ITEMS,
|
|
2247
|
+
references: REFERENCES,
|
|
2248
|
+
}) as never,
|
|
2249
|
+
);
|
|
2250
|
+
|
|
2251
|
+
renderPanel();
|
|
2252
|
+
await flush();
|
|
2253
|
+
|
|
2254
|
+
expect(screen.getByText("Preparing the final report")).toBeVisible();
|
|
2255
|
+
expect(screen.queryByLabelText("Evidence checked")).toBeNull();
|
|
2256
|
+
|
|
2257
|
+
// The section still offers the run's steps, and only those.
|
|
2258
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
2259
|
+
openDetails();
|
|
2260
|
+
expect(screen.queryByRole("tablist")).toBeNull();
|
|
2261
|
+
expect(screen.queryByLabelText("Evidence checked")).toBeNull();
|
|
2262
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
2263
|
+
});
|
|
2264
|
+
|
|
2265
|
+
test("drops evidence when the report disappears on a later poll", async () => {
|
|
2266
|
+
postMock
|
|
2267
|
+
.mockResolvedValueOnce(structuredResponse() as never)
|
|
2268
|
+
.mockResolvedValue(
|
|
2269
|
+
structuredResponse({ analysisMarkdown: null }) as never,
|
|
2270
|
+
);
|
|
2271
|
+
|
|
2272
|
+
renderPanel();
|
|
2273
|
+
await flush();
|
|
2274
|
+
expect(screen.getByLabelText("Evidence checked")).toBeInTheDocument();
|
|
2275
|
+
expect(detailsToggle()).toHaveTextContent("Evidence and activity");
|
|
2276
|
+
|
|
2277
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2278
|
+
|
|
2279
|
+
expect(screen.queryByLabelText("Evidence checked")).toBeNull();
|
|
2280
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
2281
|
+
expect(
|
|
2282
|
+
screen.getByText("No investigation report was published."),
|
|
2283
|
+
).toBeVisible();
|
|
2284
|
+
});
|
|
2285
|
+
|
|
2286
|
+
test("ignores malformed evidence and references from the API", async () => {
|
|
2287
|
+
postMock.mockResolvedValue(
|
|
2288
|
+
completedResponse({
|
|
2289
|
+
analysisMarkdown: STRUCTURED_REPORT,
|
|
2290
|
+
evidence: [
|
|
2291
|
+
{ citationId: "not-a-citation", toolName: "search_logs" },
|
|
2292
|
+
{ citationId: "C1" },
|
|
2293
|
+
] as unknown as JSONArray,
|
|
2294
|
+
references: [
|
|
2295
|
+
{ kind: "incident", number: 6954, id: "javascript:alert(1)" },
|
|
2296
|
+
] as unknown as JSONArray,
|
|
2297
|
+
}) as never,
|
|
2298
|
+
);
|
|
2299
|
+
|
|
2300
|
+
renderPanel();
|
|
2301
|
+
await flush();
|
|
2302
|
+
openDetails();
|
|
2303
|
+
|
|
2304
|
+
// Nothing valid survived, so the legacy list and plain numbers are used.
|
|
2305
|
+
expect(within(evidenceList()).getAllByRole("listitem")).toHaveLength(2);
|
|
2306
|
+
expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
|
|
2307
|
+
expect(
|
|
2308
|
+
lastInlineReferences().renderEventReference!({
|
|
2309
|
+
kind: "incident",
|
|
2310
|
+
number: 6954,
|
|
2311
|
+
text: "#6954",
|
|
2312
|
+
}),
|
|
2313
|
+
).toBeNull();
|
|
2314
|
+
});
|
|
2315
|
+
|
|
2316
|
+
/*
|
|
2317
|
+
* The report's chips are rendered by the markdown viewer, which is mocked
|
|
2318
|
+
* here, so render the panel's own chip renderer output and click it the
|
|
2319
|
+
* way a reader would.
|
|
2320
|
+
*/
|
|
2321
|
+
function clickCitation(citationId: string, name: string): void {
|
|
2322
|
+
const chip: React.ReactElement | null =
|
|
2323
|
+
lastInlineReferences().renderCitation!(citationId);
|
|
2324
|
+
expect(chip).not.toBeNull();
|
|
2325
|
+
render(chip!);
|
|
2326
|
+
|
|
2327
|
+
const chipButton: HTMLElement = screen.getByRole("button", { name });
|
|
2328
|
+
fireEvent.click(chipButton);
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
/*
|
|
2332
|
+
* The evidence sits in a section that starts collapsed, so a chip that only
|
|
2333
|
+
* highlighted its row would highlight something nobody can see. The chip
|
|
2334
|
+
* has to open the section on the Evidence tab first.
|
|
2335
|
+
*/
|
|
2336
|
+
test("a citation chip opens the collapsed details and expands, scrolls to and highlights its row", async () => {
|
|
2337
|
+
routePosts({
|
|
2338
|
+
investigation: (): unknown => {
|
|
2339
|
+
return Promise.resolve(structuredResponse());
|
|
2340
|
+
},
|
|
2341
|
+
});
|
|
2342
|
+
|
|
2343
|
+
renderPanel();
|
|
2344
|
+
await flush();
|
|
2345
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
2346
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
2347
|
+
expect(detailsBody()).not.toBeVisible();
|
|
2348
|
+
|
|
2349
|
+
const chip: React.ReactElement | null =
|
|
2350
|
+
lastInlineReferences().renderCitation!("C2");
|
|
2351
|
+
expect(chip).not.toBeNull();
|
|
2352
|
+
render(chip!);
|
|
2353
|
+
|
|
2354
|
+
const chipButton: HTMLElement = screen.getByRole("button", {
|
|
2355
|
+
name: "Citation C2: Logs 17:20 – 18:20 (1 shown)",
|
|
2356
|
+
});
|
|
2357
|
+
expect(chipButton).toHaveAttribute("title", "Logs 17:20 – 18:20 (1 shown)");
|
|
2358
|
+
|
|
2359
|
+
fireEvent.click(chipButton);
|
|
2360
|
+
await flush();
|
|
2361
|
+
|
|
2362
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2363
|
+
expect(detailsBody()).toBeVisible();
|
|
2364
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
2365
|
+
"aria-selected",
|
|
2366
|
+
"true",
|
|
2367
|
+
);
|
|
2368
|
+
|
|
2369
|
+
const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
|
|
2370
|
+
name: /Logs 17:20/,
|
|
2371
|
+
});
|
|
2372
|
+
expect(toggle).toBeVisible();
|
|
2373
|
+
expect(toggle).toHaveAttribute("aria-expanded", "true");
|
|
2374
|
+
expect(toggle).toHaveFocus();
|
|
2375
|
+
expect(toggle.closest("li")).toHaveAttribute("data-highlighted", "true");
|
|
2376
|
+
expect(scrollIntoViewMock).toHaveBeenCalledWith({
|
|
2377
|
+
block: "nearest",
|
|
2378
|
+
behavior: "smooth",
|
|
2379
|
+
});
|
|
2380
|
+
expect(evidencePosts()).toHaveLength(1);
|
|
2381
|
+
expect(evidencePosts()[0]!.data["citationId"]).toBe("C2");
|
|
2382
|
+
// The settled poll plus the single highlight timer.
|
|
2383
|
+
expect(jest.getTimerCount()).toBe(2);
|
|
2384
|
+
|
|
2385
|
+
await tick(2000);
|
|
2386
|
+
|
|
2387
|
+
expect(toggle.closest("li")).not.toHaveAttribute("data-highlighted");
|
|
2388
|
+
expect(jest.getTimerCount()).toBe(1);
|
|
2389
|
+
// The highlight fades; the section the reader was taken to stays open.
|
|
2390
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2391
|
+
});
|
|
2392
|
+
|
|
2393
|
+
test("a citation chip switches an open section from Activity to Evidence", async () => {
|
|
2394
|
+
routePosts({
|
|
2395
|
+
investigation: (): unknown => {
|
|
2396
|
+
return Promise.resolve(structuredResponse());
|
|
2397
|
+
},
|
|
2398
|
+
});
|
|
2399
|
+
|
|
2400
|
+
renderPanel();
|
|
2401
|
+
await flush();
|
|
2402
|
+
openDetails();
|
|
2403
|
+
fireEvent.click(detailsTab(/^Activity/));
|
|
2404
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
2405
|
+
expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
|
|
2406
|
+
|
|
2407
|
+
clickCitation("C1", "Citation C1: Active incidents (7 total)");
|
|
2408
|
+
await flush();
|
|
2409
|
+
|
|
2410
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2411
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
2412
|
+
"aria-selected",
|
|
2413
|
+
"true",
|
|
2414
|
+
);
|
|
2415
|
+
expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "false");
|
|
2416
|
+
expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
|
|
2417
|
+
|
|
2418
|
+
const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
|
|
2419
|
+
name: /Active incidents/,
|
|
2420
|
+
});
|
|
2421
|
+
expect(toggle).toBeVisible();
|
|
2422
|
+
expect(toggle).toHaveAttribute("aria-expanded", "true");
|
|
2423
|
+
expect(toggle).toHaveFocus();
|
|
2424
|
+
expect(toggle.closest("li")).toHaveAttribute("data-highlighted", "true");
|
|
2425
|
+
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
|
|
2426
|
+
});
|
|
2427
|
+
|
|
2428
|
+
/*
|
|
2429
|
+
* An older API sends no structured evidence, so the report's own list is
|
|
2430
|
+
* shown and its rows have no toggle. The row itself takes focus, or a
|
|
2431
|
+
* keyboard or screen-reader user would be left on the chip.
|
|
2432
|
+
*/
|
|
2433
|
+
test("a citation chip on an older report reveals and focuses its plain row", async () => {
|
|
2434
|
+
postMock.mockResolvedValue(
|
|
2435
|
+
completedResponse({ analysisMarkdown: STRUCTURED_REPORT }) as never,
|
|
2436
|
+
);
|
|
2437
|
+
|
|
2438
|
+
renderPanel();
|
|
2439
|
+
await flush();
|
|
2440
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
2441
|
+
|
|
2442
|
+
clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
|
|
2443
|
+
await flush();
|
|
2444
|
+
|
|
2445
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2446
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
2447
|
+
"aria-selected",
|
|
2448
|
+
"true",
|
|
2449
|
+
);
|
|
2450
|
+
|
|
2451
|
+
const row: HTMLElement = within(evidenceList())
|
|
2452
|
+
.getAllByRole("listitem")
|
|
2453
|
+
.find((item: HTMLElement): boolean => {
|
|
2454
|
+
return item.textContent?.includes("Logs 17:20") === true;
|
|
2455
|
+
})!;
|
|
2456
|
+
expect(row).toBeVisible();
|
|
2457
|
+
expect(row).toHaveFocus();
|
|
2458
|
+
expect(row).toHaveAttribute("data-highlighted", "true");
|
|
2459
|
+
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
|
|
2460
|
+
// A plain row has nothing to re-run.
|
|
2461
|
+
expect(evidencePosts()).toHaveLength(0);
|
|
2462
|
+
});
|
|
2463
|
+
|
|
2464
|
+
/*
|
|
2465
|
+
* A chip's request lives in the panel, so it outlives the evidence list
|
|
2466
|
+
* when the report briefly disappears between polls. When the list comes
|
|
2467
|
+
* back it must not replay that old request — scrolling the page and
|
|
2468
|
+
* stealing focus with no click behind it.
|
|
2469
|
+
*/
|
|
2470
|
+
test("does not replay a chip when the evidence comes back on a later poll", async () => {
|
|
2471
|
+
let investigationCalls: number = 0;
|
|
2472
|
+
routePosts({
|
|
2473
|
+
investigation: (): unknown => {
|
|
2474
|
+
investigationCalls += 1;
|
|
2475
|
+
return Promise.resolve(
|
|
2476
|
+
investigationCalls === 2
|
|
2477
|
+
? structuredResponse({ analysisMarkdown: null })
|
|
2478
|
+
: structuredResponse(),
|
|
2479
|
+
);
|
|
2480
|
+
},
|
|
2481
|
+
});
|
|
2482
|
+
|
|
2483
|
+
renderPanel();
|
|
2484
|
+
await flush();
|
|
2485
|
+
clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
|
|
2486
|
+
await flush();
|
|
2487
|
+
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
|
|
2488
|
+
await tick(2000);
|
|
2489
|
+
|
|
2490
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2491
|
+
expect(screen.queryByLabelText("Evidence checked")).toBeNull();
|
|
2492
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
2493
|
+
|
|
2494
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2495
|
+
expect(investigationPostCount()).toBe(3);
|
|
2496
|
+
|
|
2497
|
+
const toggle: HTMLElement = within(evidenceList()).getByRole("button", {
|
|
2498
|
+
name: /Logs 17:20/,
|
|
2499
|
+
});
|
|
2500
|
+
expect(toggle).toBeVisible();
|
|
2501
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
2502
|
+
expect(toggle).not.toHaveFocus();
|
|
2503
|
+
expect(document.querySelector('[data-highlighted="true"]')).toBeNull();
|
|
2504
|
+
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
|
|
2505
|
+
expect(evidencePosts()).toHaveLength(1);
|
|
2506
|
+
});
|
|
2507
|
+
|
|
2508
|
+
test("a new run on the same subject starts collapsed, even after a chip opened the last one", async () => {
|
|
2509
|
+
let investigationCalls: number = 0;
|
|
2510
|
+
routePosts({
|
|
2511
|
+
investigation: (): unknown => {
|
|
2512
|
+
investigationCalls += 1;
|
|
2513
|
+
return Promise.resolve(
|
|
2514
|
+
investigationCalls === 1
|
|
2515
|
+
? structuredResponse()
|
|
2516
|
+
: structuredResponse({ runId: NEXT_RUN_ID }),
|
|
2517
|
+
);
|
|
2518
|
+
},
|
|
2519
|
+
});
|
|
2520
|
+
|
|
2521
|
+
renderPanel();
|
|
2522
|
+
await flush();
|
|
2523
|
+
clickCitation("C2", "Citation C2: Logs 17:20 – 18:20 (1 shown)");
|
|
2524
|
+
await flush();
|
|
2525
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
2526
|
+
|
|
2527
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2528
|
+
|
|
2529
|
+
expect(investigationPostCount()).toBe(2);
|
|
2530
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
2531
|
+
expect(detailsBody()).not.toBeVisible();
|
|
2532
|
+
|
|
2533
|
+
openDetails();
|
|
2534
|
+
|
|
2535
|
+
expect(
|
|
2536
|
+
within(evidenceList()).getByRole("button", { name: /Logs 17:20/ }),
|
|
2537
|
+
).toHaveAttribute("aria-expanded", "false");
|
|
2538
|
+
expect(document.querySelector('[data-highlighted="true"]')).toBeNull();
|
|
2539
|
+
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
|
|
2540
|
+
});
|
|
2541
|
+
|
|
2542
|
+
test("leaves a citation that is not in the evidence as plain text", async () => {
|
|
2543
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2544
|
+
|
|
2545
|
+
renderPanel();
|
|
2546
|
+
await flush();
|
|
2547
|
+
|
|
2548
|
+
expect(lastInlineReferences().renderCitation!("C9")).toBeNull();
|
|
2549
|
+
expect(lastInlineReferences().renderCitation!("C1")).not.toBeNull();
|
|
2550
|
+
});
|
|
2551
|
+
|
|
2552
|
+
test("links a referenced incident number to that incident", async () => {
|
|
2553
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2554
|
+
|
|
2555
|
+
renderPanel();
|
|
2556
|
+
await flush();
|
|
2557
|
+
|
|
2558
|
+
const link: React.ReactElement | null = lastInlineReferences()
|
|
2559
|
+
.renderEventReference!({
|
|
2560
|
+
kind: null,
|
|
2561
|
+
number: 6954,
|
|
2562
|
+
text: "#6954",
|
|
2563
|
+
});
|
|
2564
|
+
expect(link).not.toBeNull();
|
|
2565
|
+
render(link!);
|
|
2566
|
+
|
|
2567
|
+
const anchor: HTMLElement = screen.getByRole("link", {
|
|
2568
|
+
name: "INC-6954 · Checkout pool exhausted · Resolved",
|
|
2569
|
+
});
|
|
2570
|
+
expect(anchor).toHaveTextContent("#6954");
|
|
2571
|
+
expect(anchor.getAttribute("href")).toMatch(
|
|
2572
|
+
new RegExp(`/incidents/${PRIOR_INCIDENT_ID}$`),
|
|
2573
|
+
);
|
|
2574
|
+
expect(
|
|
2575
|
+
lastInlineReferences().renderEventReference!({
|
|
2576
|
+
kind: "incident",
|
|
2577
|
+
number: 1,
|
|
2578
|
+
text: "#1",
|
|
2579
|
+
}),
|
|
2580
|
+
).toBeNull();
|
|
2581
|
+
});
|
|
2582
|
+
|
|
2583
|
+
test("resolves an unqualified number as an alert on an alert investigation", async () => {
|
|
2584
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2585
|
+
|
|
2586
|
+
renderPanel({ subjectType: "alert", subjectId: ALERT_ID });
|
|
2587
|
+
await flush();
|
|
2588
|
+
|
|
2589
|
+
const link: React.ReactElement | null = lastInlineReferences()
|
|
2590
|
+
.renderEventReference!({
|
|
2591
|
+
kind: null,
|
|
2592
|
+
number: 6954,
|
|
2593
|
+
text: "#6954",
|
|
2594
|
+
});
|
|
2595
|
+
render(link!);
|
|
2596
|
+
|
|
2597
|
+
expect(
|
|
2598
|
+
screen
|
|
2599
|
+
.getByRole("link", { name: "#6954 · Webhook failures" })
|
|
2600
|
+
.getAttribute("href"),
|
|
2601
|
+
).toMatch(new RegExp(`/alerts/${PRIOR_ALERT_ID}$`));
|
|
2602
|
+
});
|
|
2603
|
+
|
|
2604
|
+
test("ignores evidence rows that resolve after navigating to another subject", async () => {
|
|
2605
|
+
const staleRows: Deferred<ApiResponse> = createDeferred<ApiResponse>();
|
|
2606
|
+
let evidenceCalls: number = 0;
|
|
2607
|
+
routePosts({
|
|
2608
|
+
investigation: (request: EvidencePostRequest): unknown => {
|
|
2609
|
+
return Promise.resolve(
|
|
2610
|
+
request.data["alertId"]
|
|
2611
|
+
? structuredResponse({ runId: NEXT_RUN_ID })
|
|
2612
|
+
: structuredResponse(),
|
|
2613
|
+
);
|
|
2614
|
+
},
|
|
2615
|
+
evidence: (): unknown => {
|
|
2616
|
+
evidenceCalls += 1;
|
|
2617
|
+
return evidenceCalls === 1
|
|
2618
|
+
? staleRows.promise
|
|
2619
|
+
: Promise.resolve(
|
|
2620
|
+
evidenceRowsResponse("C1", "id | title\n9 | Alert subject rows"),
|
|
2621
|
+
);
|
|
2622
|
+
},
|
|
2623
|
+
});
|
|
2624
|
+
|
|
2625
|
+
const view: ReturnType<typeof render> = renderPanel();
|
|
2626
|
+
await flush();
|
|
2627
|
+
openDetails();
|
|
2628
|
+
fireEvent.click(
|
|
2629
|
+
screen.getByRole("button", { name: /Active incidents \(7 total\)/ }),
|
|
2630
|
+
);
|
|
2631
|
+
await flush();
|
|
2632
|
+
expect(evidencePosts()).toHaveLength(1);
|
|
2633
|
+
|
|
2634
|
+
view.rerender(
|
|
2635
|
+
<InvestigationPanel subjectType="alert" subjectId={ALERT_ID} />,
|
|
2636
|
+
);
|
|
2637
|
+
await flush();
|
|
2638
|
+
await resolveDeferred(
|
|
2639
|
+
staleRows,
|
|
2640
|
+
evidenceRowsResponse("C1", "id | title\n1 | Previous subject rows"),
|
|
2641
|
+
);
|
|
2642
|
+
|
|
2643
|
+
expect(screen.queryByText(/Previous subject rows/)).toBeNull();
|
|
2644
|
+
// The new subject's details start collapsed like any other.
|
|
2645
|
+
openDetails();
|
|
2646
|
+
const toggle: HTMLElement = screen.getByRole("button", {
|
|
2647
|
+
name: /Active incidents \(7 total\)/,
|
|
2648
|
+
});
|
|
2649
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
2650
|
+
|
|
2651
|
+
fireEvent.click(toggle);
|
|
2652
|
+
await flush();
|
|
2653
|
+
|
|
2654
|
+
expect(screen.getByText(/Alert subject rows/)).toBeVisible();
|
|
2655
|
+
expect(screen.queryByText(/Previous subject rows/)).toBeNull();
|
|
2656
|
+
expect(evidencePosts()[1]!.data).toEqual({
|
|
2657
|
+
subjectType: "alert",
|
|
2658
|
+
subjectId: ALERT_ID.toString(),
|
|
2659
|
+
investigationRunId: NEXT_RUN_ID,
|
|
2660
|
+
citationId: "C1",
|
|
2661
|
+
});
|
|
2662
|
+
});
|
|
2663
|
+
|
|
2664
|
+
test("renders a hostile report only through the safe viewer", async () => {
|
|
2665
|
+
const hostile: string = [
|
|
2666
|
+
'**Summary** — <img src=x onerror="window.__panelPwned = true"> [click](https://evil.example)',
|
|
2667
|
+
"",
|
|
2668
|
+
"**Most likely root cause** —  [C1]",
|
|
2669
|
+
"",
|
|
2670
|
+
"[C1]: https://evil.example/exfil",
|
|
2671
|
+
].join("\n");
|
|
2672
|
+
postMock.mockResolvedValue(
|
|
2673
|
+
structuredResponse({ analysisMarkdown: hostile }) as never,
|
|
2674
|
+
);
|
|
2675
|
+
|
|
2676
|
+
const { container } = renderPanel();
|
|
2677
|
+
await flush();
|
|
2678
|
+
|
|
2679
|
+
expect(allMarkdownProps().length).toBeGreaterThan(0);
|
|
2680
|
+
for (const props of allMarkdownProps()) {
|
|
2681
|
+
expect(props.safeMode).toBe(true);
|
|
2682
|
+
}
|
|
2683
|
+
expect(container.querySelector("img")).toBeNull();
|
|
2684
|
+
expect(container.querySelector("a")).toBeNull();
|
|
2685
|
+
expect(
|
|
2686
|
+
(window as unknown as { __panelPwned?: boolean }).__panelPwned,
|
|
2687
|
+
).toBeUndefined();
|
|
2688
|
+
});
|
|
2689
|
+
|
|
2690
|
+
/*
|
|
2691
|
+
* Collapsed, the header answers "what did it do, and did it touch
|
|
2692
|
+
* anything?". What the run cost and which model wrote the report are for
|
|
2693
|
+
* the reader who opens the details, and the verify-first note belongs on
|
|
2694
|
+
* the report it qualifies.
|
|
2695
|
+
*/
|
|
2696
|
+
test("names the model and its tokens inside the details, not in the collapsed header", async () => {
|
|
2697
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2698
|
+
|
|
2699
|
+
renderPanel();
|
|
2700
|
+
await flush();
|
|
2701
|
+
|
|
2702
|
+
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
2703
|
+
expect(usage).toBeVisible();
|
|
2704
|
+
expect(usage).toHaveTextContent("2 telemetry queries");
|
|
2705
|
+
expect(usage).not.toHaveTextContent("tokens");
|
|
2706
|
+
expect(usage).not.toHaveTextContent("gpt-5");
|
|
2707
|
+
|
|
2708
|
+
const cost: HTMLElement = screen.getByLabelText("Model and tokens");
|
|
2709
|
+
expect(detailsBody()).toContainElement(cost);
|
|
2710
|
+
expect(cost).not.toBeVisible();
|
|
2711
|
+
expect(cost).toHaveTextContent("1,234 tokens");
|
|
2712
|
+
expect(cost).toHaveTextContent("Model gpt-5");
|
|
2713
|
+
// Counts and the guarantee are already in the header; no repeats.
|
|
2714
|
+
expect(cost).not.toHaveTextContent("telemetry");
|
|
2715
|
+
expect(cost).not.toHaveTextContent("Read-only");
|
|
2716
|
+
|
|
2717
|
+
openDetails();
|
|
2718
|
+
|
|
2719
|
+
expect(screen.getByRole("list", { name: "Model and tokens" })).toBe(cost);
|
|
2720
|
+
expect(cost).toBeVisible();
|
|
2721
|
+
expect(screen.getByLabelText("Investigation report")).toHaveTextContent(
|
|
2722
|
+
"AI-generated first pass — verify before acting.",
|
|
2723
|
+
);
|
|
2724
|
+
});
|
|
2725
|
+
|
|
2726
|
+
test("does not ask to verify a report that does not exist", async () => {
|
|
2727
|
+
postMock.mockResolvedValue(
|
|
2728
|
+
successfulResponse(
|
|
2729
|
+
investigationPayload({
|
|
2730
|
+
status: AIRunStatus.Error,
|
|
2731
|
+
errorMessage: "The provider timed out.",
|
|
2732
|
+
toolCallCount: 3,
|
|
2733
|
+
}),
|
|
2734
|
+
) as never,
|
|
2735
|
+
);
|
|
2736
|
+
|
|
2737
|
+
renderPanel();
|
|
2738
|
+
await flush();
|
|
2739
|
+
|
|
2740
|
+
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
2741
|
+
expect(usage).toHaveTextContent("3 telemetry queries");
|
|
2742
|
+
expect(usage).not.toHaveTextContent("Model");
|
|
2743
|
+
expect(screen.queryByText(/verify before acting/)).toBeNull();
|
|
2744
|
+
expect(screen.queryByLabelText("Model and tokens")).toBeNull();
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
test("titles the act and rate blocks with headings instead of icon-in-paragraph", async () => {
|
|
2748
|
+
postMock.mockResolvedValue(completedResponse() as never);
|
|
2749
|
+
|
|
2750
|
+
const { container } = renderPanel();
|
|
2751
|
+
await flush();
|
|
2752
|
+
|
|
2753
|
+
expect(
|
|
2754
|
+
screen.getByRole("heading", { name: "Act on this investigation" }),
|
|
2755
|
+
).toBeVisible();
|
|
2756
|
+
expect(
|
|
2757
|
+
screen.getByRole("heading", { name: "Rate this investigation" }),
|
|
2758
|
+
).toBeVisible();
|
|
2759
|
+
expect(container.querySelectorAll("p div")).toHaveLength(0);
|
|
2760
|
+
});
|
|
2761
|
+
});
|
|
2762
|
+
|
|
2763
|
+
/*
|
|
2764
|
+
* "Evidence checked", "Investigation activity" and the usage strip used to be
|
|
2765
|
+
* three stacked boxes under the report. They are now one section that starts
|
|
2766
|
+
* collapsed: the report is the answer, this is its working. Collapsed, it
|
|
2767
|
+
* still has to say what the run did and that it changed nothing, because a
|
|
2768
|
+
* responder asks that before trusting the report at all.
|
|
2769
|
+
*/
|
|
2770
|
+
describe("InvestigationPanel run details", () => {
|
|
2771
|
+
function tabNames(): Array<string> {
|
|
2772
|
+
return within(
|
|
2773
|
+
screen.getByRole("tablist", { name: "Investigation details" }),
|
|
2774
|
+
)
|
|
2775
|
+
.getAllByRole("tab")
|
|
2776
|
+
.map((tab: HTMLElement): string => {
|
|
2777
|
+
return tab.textContent || "";
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
test("starts collapsed and still says what the run did in its header", async () => {
|
|
2782
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2783
|
+
|
|
2784
|
+
renderPanel();
|
|
2785
|
+
await flush();
|
|
2786
|
+
|
|
2787
|
+
const section: HTMLElement = screen.getByRole("region", {
|
|
2788
|
+
name: "Evidence and activity",
|
|
2789
|
+
});
|
|
2790
|
+
expect(section).toBe(runDetails());
|
|
2791
|
+
|
|
2792
|
+
/*
|
|
2793
|
+
* The toggle is named by the title alone: the usage line beside it is
|
|
2794
|
+
* not part of the button, so a screen reader hears a short name.
|
|
2795
|
+
*/
|
|
2796
|
+
const toggle: HTMLElement = within(section).getByRole("button", {
|
|
2797
|
+
name: "Evidence and activity",
|
|
2798
|
+
});
|
|
2799
|
+
expect(toggle).toBe(detailsToggle());
|
|
2800
|
+
expect(
|
|
2801
|
+
within(section).getByRole("heading", {
|
|
2802
|
+
level: 3,
|
|
2803
|
+
name: "Evidence and activity",
|
|
2804
|
+
}),
|
|
2805
|
+
).toContainElement(toggle);
|
|
2806
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
2807
|
+
expect(detailsBody()).not.toBeVisible();
|
|
2808
|
+
expect(section).toContainElement(detailsBody());
|
|
2809
|
+
expect(screen.queryByRole("tablist")).toBeNull();
|
|
2810
|
+
expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
|
|
2811
|
+
expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
|
|
2812
|
+
|
|
2813
|
+
const usage: HTMLElement = within(section).getByRole("list", {
|
|
2814
|
+
name: "Investigation usage",
|
|
2815
|
+
});
|
|
2816
|
+
expect(usage).toBeVisible();
|
|
2817
|
+
expect(
|
|
2818
|
+
within(usage)
|
|
2819
|
+
.getAllByRole("listitem")
|
|
2820
|
+
.map((item: HTMLElement): string => {
|
|
2821
|
+
return item.textContent || "";
|
|
2822
|
+
}),
|
|
2823
|
+
).toEqual([
|
|
2824
|
+
"2 telemetry queries",
|
|
2825
|
+
"1 step",
|
|
2826
|
+
"Read-only — nothing in your systems was changed",
|
|
2827
|
+
]);
|
|
2828
|
+
});
|
|
2829
|
+
|
|
2830
|
+
/*
|
|
2831
|
+
* The run's tool-call count also includes calls that failed and never
|
|
2832
|
+
* became evidence. Inside a section whose Evidence tab lists the queries,
|
|
2833
|
+
* the header has to count the same queries, or the two numbers a reader
|
|
2834
|
+
* sees side by side disagree. Without evidence the run's own count is all
|
|
2835
|
+
* there is.
|
|
2836
|
+
*/
|
|
2837
|
+
test("counts the queries the Evidence tab lists, not the run's raw call count", async () => {
|
|
2838
|
+
postMock
|
|
2839
|
+
.mockResolvedValueOnce(structuredResponse({ toolCallCount: 3 }) as never)
|
|
2840
|
+
.mockResolvedValue(
|
|
2841
|
+
structuredResponse({ toolCallCount: 3, evidence: [] }) as never,
|
|
2842
|
+
);
|
|
2843
|
+
|
|
2844
|
+
renderPanel();
|
|
2845
|
+
await flush();
|
|
2846
|
+
|
|
2847
|
+
expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
|
|
2848
|
+
"2 telemetry queries",
|
|
2849
|
+
);
|
|
2850
|
+
openDetails();
|
|
2851
|
+
expect(detailsTab(/^Evidence checked/)).toHaveTextContent(
|
|
2852
|
+
"Evidence checked2",
|
|
2853
|
+
);
|
|
2854
|
+
|
|
2855
|
+
/*
|
|
2856
|
+
* An older API: the report's own list still names the queries, so the
|
|
2857
|
+
* header follows it rather than the raw call count.
|
|
2858
|
+
*/
|
|
2859
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
2860
|
+
|
|
2861
|
+
expect(within(evidenceList()).queryAllByRole("button")).toHaveLength(0);
|
|
2862
|
+
expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
|
|
2863
|
+
"2 telemetry queries",
|
|
2864
|
+
);
|
|
2865
|
+
});
|
|
2866
|
+
|
|
2867
|
+
test("falls back to the run's call count when there is no evidence at all", async () => {
|
|
2868
|
+
postMock.mockResolvedValue(
|
|
2869
|
+
completedResponse({ toolCallCount: 3 }) as never,
|
|
2870
|
+
);
|
|
2871
|
+
|
|
2872
|
+
renderPanel();
|
|
2873
|
+
await flush();
|
|
2874
|
+
|
|
2875
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
2876
|
+
expect(screen.getByLabelText("Investigation usage")).toHaveTextContent(
|
|
2877
|
+
"3 telemetry queries",
|
|
2878
|
+
);
|
|
2879
|
+
});
|
|
2880
|
+
|
|
2881
|
+
test("opening reveals the tabs and the evidence list, and closing hides them again", async () => {
|
|
2882
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2883
|
+
|
|
2884
|
+
renderPanel();
|
|
2885
|
+
await flush();
|
|
2886
|
+
openDetails();
|
|
2887
|
+
|
|
2888
|
+
expect(detailsBody()).toBeVisible();
|
|
2889
|
+
expect(tabNames()).toEqual(["Evidence checked2", "Activity1"]);
|
|
2890
|
+
|
|
2891
|
+
const evidenceTab: HTMLElement = detailsTab(/^Evidence checked/);
|
|
2892
|
+
expect(evidenceTab).toHaveAttribute("aria-selected", "true");
|
|
2893
|
+
expect(evidenceTab).toHaveAttribute("tabindex", "0");
|
|
2894
|
+
expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "false");
|
|
2895
|
+
expect(detailsTab(/^Activity/)).toHaveAttribute("tabindex", "-1");
|
|
2896
|
+
|
|
2897
|
+
// Only the selected panel is reachable, and it is named by its tab.
|
|
2898
|
+
const panel: HTMLElement = screen.getByRole("tabpanel");
|
|
2899
|
+
expect(panel).toBe(
|
|
2900
|
+
screen.getByRole("tabpanel", { name: /^Evidence checked/ }),
|
|
2901
|
+
);
|
|
2902
|
+
expect(evidenceTab).toHaveAttribute("aria-controls", panel.id);
|
|
2903
|
+
expect(panel).toHaveAttribute("tabindex", "0");
|
|
2904
|
+
expect(panel).toContainElement(evidenceList());
|
|
2905
|
+
expect(
|
|
2906
|
+
within(evidenceList()).getByRole("button", { name: /Active incidents/ }),
|
|
2907
|
+
).toBeVisible();
|
|
2908
|
+
expect(
|
|
2909
|
+
within(evidenceList()).getByRole("button", { name: /Logs 17:20/ }),
|
|
2910
|
+
).toBeVisible();
|
|
2911
|
+
expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
|
|
2912
|
+
|
|
2913
|
+
fireEvent.click(detailsToggle());
|
|
2914
|
+
|
|
2915
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "false");
|
|
2916
|
+
expect(detailsBody()).not.toBeVisible();
|
|
2917
|
+
expect(screen.queryByRole("tablist")).toBeNull();
|
|
2918
|
+
expect(screen.queryByRole("tabpanel")).toBeNull();
|
|
2919
|
+
expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
|
|
2920
|
+
// The header's summary does not depend on the body being open.
|
|
2921
|
+
expect(screen.getByLabelText("Investigation usage")).toBeVisible();
|
|
2922
|
+
});
|
|
2923
|
+
|
|
2924
|
+
test("switches between the evidence and activity tabs", async () => {
|
|
2925
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
2926
|
+
|
|
2927
|
+
renderPanel();
|
|
2928
|
+
await flush();
|
|
2929
|
+
openDetails();
|
|
2930
|
+
|
|
2931
|
+
fireEvent.click(detailsTab(/^Activity/));
|
|
2932
|
+
|
|
2933
|
+
expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "true");
|
|
2934
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
2935
|
+
"aria-selected",
|
|
2936
|
+
"false",
|
|
2937
|
+
);
|
|
2938
|
+
const activityPanel: HTMLElement = screen.getByRole("tabpanel", {
|
|
2939
|
+
name: /^Activity/,
|
|
2940
|
+
});
|
|
2941
|
+
expect(activityPanel).toContainElement(
|
|
2942
|
+
screen.getByTestId("investigation-activity"),
|
|
2943
|
+
);
|
|
2944
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
2945
|
+
expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
|
|
2946
|
+
|
|
2947
|
+
// The footer belongs to the body, not to one tab.
|
|
2948
|
+
expect(
|
|
2949
|
+
screen.getByRole("list", { name: "Model and tokens" }),
|
|
2950
|
+
).toBeVisible();
|
|
2951
|
+
|
|
2952
|
+
fireEvent.click(detailsTab(/^Evidence checked/));
|
|
2953
|
+
|
|
2954
|
+
expect(evidenceList()).toBeVisible();
|
|
2955
|
+
expect(screen.getByTestId("investigation-activity")).not.toBeVisible();
|
|
2956
|
+
});
|
|
2957
|
+
|
|
2958
|
+
/*
|
|
2959
|
+
* The old disclosure advertised the raw event count and showed only the
|
|
2960
|
+
* last ten steps. Several event types only close a step, so the count the
|
|
2961
|
+
* reader sees has to be the steps the feed draws — and a finished run is
|
|
2962
|
+
* short enough to show its whole trail.
|
|
2963
|
+
*/
|
|
2964
|
+
test("counts the steps the feed draws and shows the whole finished trail", async () => {
|
|
2965
|
+
const events: JSONArray = [];
|
|
2966
|
+
|
|
2967
|
+
for (let index: number = 0; index < 24; index++) {
|
|
2968
|
+
events.push({
|
|
2969
|
+
_id: `55555555-5555-4555-8555-${String(index).padStart(12, "0")}`,
|
|
2970
|
+
sequence: index + 1,
|
|
2971
|
+
eventType:
|
|
2972
|
+
index % 2 === 0
|
|
2973
|
+
? AIRunEventType.ToolCallStarted
|
|
2974
|
+
: AIRunEventType.ToolCallCompleted,
|
|
2975
|
+
toolName: "search_logs",
|
|
2976
|
+
createdAt: new Date("2026-08-07T10:00:00.000Z"),
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
countActivityStepsMock.mockReturnValue(12);
|
|
2981
|
+
postMock.mockResolvedValue(structuredResponse({ events }) as never);
|
|
2982
|
+
|
|
2983
|
+
renderPanel();
|
|
2984
|
+
await flush();
|
|
2985
|
+
|
|
2986
|
+
const usage: HTMLElement = screen.getByLabelText("Investigation usage");
|
|
2987
|
+
expect(usage).toHaveTextContent("12 steps");
|
|
2988
|
+
expect(usage).not.toHaveTextContent("24");
|
|
2989
|
+
|
|
2990
|
+
openDetails();
|
|
2991
|
+
|
|
2992
|
+
expect(tabNames()).toEqual(["Evidence checked2", "Activity12"]);
|
|
2993
|
+
expect(lastActivityProps().events).toHaveLength(24);
|
|
2994
|
+
expect(lastActivityProps()).toEqual(
|
|
2995
|
+
expect.objectContaining({
|
|
2996
|
+
hideChrome: true,
|
|
2997
|
+
showLiveIndicator: false,
|
|
2998
|
+
maxVisibleSteps: 12,
|
|
2999
|
+
}),
|
|
3000
|
+
);
|
|
3001
|
+
});
|
|
3002
|
+
|
|
3003
|
+
/*
|
|
3004
|
+
* Evidence can land on a later poll than the report. A reader who opened
|
|
3005
|
+
* the section onto the activity is reading it; the arriving evidence adds
|
|
3006
|
+
* a tab beside it rather than yanking the view to the new first tab.
|
|
3007
|
+
*/
|
|
3008
|
+
test("keeps a reader on the activity when evidence arrives after they opened it", async () => {
|
|
3009
|
+
postMock
|
|
3010
|
+
.mockResolvedValueOnce(completedResponse() as never)
|
|
3011
|
+
.mockResolvedValue(structuredResponse() as never);
|
|
3012
|
+
|
|
3013
|
+
renderPanel();
|
|
3014
|
+
await flush();
|
|
3015
|
+
openDetails();
|
|
3016
|
+
|
|
3017
|
+
expect(detailsToggle()).toHaveTextContent("Investigation activity");
|
|
3018
|
+
expect(screen.queryByRole("tablist")).toBeNull();
|
|
3019
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
3020
|
+
|
|
3021
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3022
|
+
|
|
3023
|
+
expect(detailsToggle()).toHaveTextContent("Evidence and activity");
|
|
3024
|
+
expect(detailsToggle()).toHaveAttribute("aria-expanded", "true");
|
|
3025
|
+
expect(tabNames()).toEqual(["Evidence checked2", "Activity1"]);
|
|
3026
|
+
expect(detailsTab(/^Activity/)).toHaveAttribute("aria-selected", "true");
|
|
3027
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
3028
|
+
"aria-selected",
|
|
3029
|
+
"false",
|
|
3030
|
+
);
|
|
3031
|
+
expect(screen.getByTestId("investigation-activity")).toBeVisible();
|
|
3032
|
+
expect(screen.queryByRole("list", { name: "Evidence checked" })).toBeNull();
|
|
3033
|
+
});
|
|
3034
|
+
|
|
3035
|
+
/*
|
|
3036
|
+
* The counterpart: nobody has looked yet, so there is nothing to keep, and
|
|
3037
|
+
* the section opens on the evidence like any report that has some.
|
|
3038
|
+
*/
|
|
3039
|
+
test("opens on the evidence when it arrived before the reader looked", async () => {
|
|
3040
|
+
postMock
|
|
3041
|
+
.mockResolvedValueOnce(completedResponse() as never)
|
|
3042
|
+
.mockResolvedValue(structuredResponse() as never);
|
|
3043
|
+
|
|
3044
|
+
renderPanel();
|
|
3045
|
+
await flush();
|
|
3046
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3047
|
+
openDetails();
|
|
3048
|
+
|
|
3049
|
+
expect(detailsTab(/^Evidence checked/)).toHaveAttribute(
|
|
3050
|
+
"aria-selected",
|
|
3051
|
+
"true",
|
|
3052
|
+
);
|
|
3053
|
+
expect(evidenceList()).toBeVisible();
|
|
3054
|
+
});
|
|
3055
|
+
});
|
|
3056
|
+
|
|
3057
|
+
describe("InvestigationPanel report summary callback", () => {
|
|
3058
|
+
function nonNullCalls(callback: MockFunction): Array<unknown> {
|
|
3059
|
+
return callback.mock.calls
|
|
3060
|
+
.map((call: Array<unknown>): unknown => {
|
|
3061
|
+
return call[0];
|
|
3062
|
+
})
|
|
3063
|
+
.filter((value: unknown): boolean => {
|
|
3064
|
+
return value !== null;
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
test("reports the TL;DR of a completed report", async () => {
|
|
3069
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3070
|
+
postMock.mockResolvedValue(
|
|
3071
|
+
structuredResponse({ analysisTldr: TLDR }) as never,
|
|
3072
|
+
);
|
|
3073
|
+
|
|
3074
|
+
renderPanel({ onReportSummaryChange });
|
|
3075
|
+
await flush();
|
|
3076
|
+
|
|
3077
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
|
|
3078
|
+
expect(nonNullCalls(onReportSummaryChange)).toEqual([TLDR]);
|
|
3079
|
+
});
|
|
3080
|
+
|
|
3081
|
+
test("falls back to the report's Summary as plain text without a TL;DR", async () => {
|
|
3082
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3083
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
3084
|
+
|
|
3085
|
+
renderPanel({ onReportSummaryChange });
|
|
3086
|
+
await flush();
|
|
3087
|
+
|
|
3088
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(REPORT_SUMMARY);
|
|
3089
|
+
});
|
|
3090
|
+
|
|
3091
|
+
test("bounds a long Summary", async () => {
|
|
3092
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3093
|
+
postMock.mockResolvedValue(
|
|
3094
|
+
completedResponse({
|
|
3095
|
+
analysisMarkdown: `**Summary** — ${"pool exhausted ".repeat(60)}\n\n**Root cause** — a deploy.`,
|
|
3096
|
+
}) as never,
|
|
3097
|
+
);
|
|
3098
|
+
|
|
3099
|
+
renderPanel({ onReportSummaryChange });
|
|
3100
|
+
await flush();
|
|
3101
|
+
|
|
3102
|
+
const summary: string = nonNullCalls(onReportSummaryChange)[0] as string;
|
|
3103
|
+
// Bounded by the analysisTldr column; the header clamps it on screen.
|
|
3104
|
+
expect(summary.length).toBeLessThanOrEqual(500);
|
|
3105
|
+
expect(summary.length).toBeGreaterThan(280);
|
|
3106
|
+
expect(summary.endsWith("…")).toBe(true);
|
|
3107
|
+
});
|
|
3108
|
+
|
|
3109
|
+
test("reports a TL;DR at the server's 320-character cap whole", async () => {
|
|
3110
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3111
|
+
const longTldr: string =
|
|
3112
|
+
"checkout-api release 2026.09.14-2 restarted at 17:52:04 with DB_POOL_MAX=10 instead of 40, so requests waited up to 2s in pg.pool.connect for an orders-db connection and p95 latency rose from ~310 ms to 2.35 s (db.client.connections.usage pinned at 10/10). Rolling back to 2026.09.14-1 cleared it, as in #1017 and #1029.";
|
|
3113
|
+
|
|
3114
|
+
expect(longTldr).toHaveLength(320);
|
|
3115
|
+
postMock.mockResolvedValue(
|
|
3116
|
+
structuredResponse({ analysisTldr: longTldr }) as never,
|
|
3117
|
+
);
|
|
3118
|
+
|
|
3119
|
+
renderPanel({ onReportSummaryChange });
|
|
3120
|
+
await flush();
|
|
3121
|
+
|
|
3122
|
+
expect(nonNullCalls(onReportSummaryChange)).toEqual([longTldr]);
|
|
3123
|
+
});
|
|
3124
|
+
|
|
3125
|
+
test("reports null when a report has neither a TL;DR nor a Summary", async () => {
|
|
3126
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3127
|
+
postMock.mockResolvedValue(completedResponse() as never);
|
|
3128
|
+
|
|
3129
|
+
renderPanel({ onReportSummaryChange });
|
|
3130
|
+
await flush();
|
|
3131
|
+
|
|
3132
|
+
expect(onReportSummaryChange).toHaveBeenCalledWith(null);
|
|
3133
|
+
expect(nonNullCalls(onReportSummaryChange)).toEqual([]);
|
|
3134
|
+
});
|
|
3135
|
+
|
|
3136
|
+
test("reports null while the run is active or the report is pending", async () => {
|
|
3137
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3138
|
+
postMock
|
|
3139
|
+
.mockResolvedValueOnce(
|
|
3140
|
+
successfulResponse(
|
|
3141
|
+
investigationPayload({
|
|
3142
|
+
status: AIRunStatus.Running,
|
|
3143
|
+
analysisTldr: TLDR,
|
|
3144
|
+
}),
|
|
3145
|
+
) as never,
|
|
3146
|
+
)
|
|
3147
|
+
.mockResolvedValueOnce(
|
|
3148
|
+
completedResponse({
|
|
3149
|
+
analysisMarkdown: null,
|
|
3150
|
+
analysisTldr: TLDR,
|
|
3151
|
+
isAnalysisPending: true,
|
|
3152
|
+
}) as never,
|
|
3153
|
+
)
|
|
3154
|
+
.mockResolvedValue(structuredResponse({ analysisTldr: TLDR }) as never);
|
|
3155
|
+
|
|
3156
|
+
renderPanel({ onReportSummaryChange });
|
|
3157
|
+
await flush();
|
|
3158
|
+
await advanceFastPolls();
|
|
3159
|
+
|
|
3160
|
+
expect(nonNullCalls(onReportSummaryChange)).toEqual([]);
|
|
3161
|
+
|
|
3162
|
+
await advanceFastPolls();
|
|
3163
|
+
|
|
3164
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
|
|
3165
|
+
});
|
|
3166
|
+
|
|
3167
|
+
test("does not repeat an unchanged summary across polls", async () => {
|
|
3168
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3169
|
+
postMock.mockResolvedValue(
|
|
3170
|
+
structuredResponse({ analysisTldr: TLDR }) as never,
|
|
3171
|
+
);
|
|
3172
|
+
|
|
3173
|
+
renderPanel({ onReportSummaryChange });
|
|
3174
|
+
await flush();
|
|
3175
|
+
const callsAfterLoad: number = onReportSummaryChange.mock.calls.length;
|
|
3176
|
+
|
|
3177
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3178
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3179
|
+
|
|
3180
|
+
expect(investigationPostCount()).toBe(3);
|
|
3181
|
+
expect(onReportSummaryChange).toHaveBeenCalledTimes(callsAfterLoad);
|
|
3182
|
+
});
|
|
3183
|
+
|
|
3184
|
+
test("reports null the moment the subject changes, then the new summary", async () => {
|
|
3185
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3186
|
+
const nextSubject: Deferred<ApiResponse> = createDeferred<ApiResponse>();
|
|
3187
|
+
const nextTldr: string = "The webhook signer rotated its key.";
|
|
3188
|
+
postMock
|
|
3189
|
+
.mockResolvedValueOnce(
|
|
3190
|
+
structuredResponse({ analysisTldr: TLDR }) as never,
|
|
3191
|
+
)
|
|
3192
|
+
.mockReturnValueOnce(nextSubject.promise as never);
|
|
3193
|
+
|
|
3194
|
+
const view: ReturnType<typeof render> = renderPanel({
|
|
3195
|
+
onReportSummaryChange,
|
|
3196
|
+
});
|
|
3197
|
+
await flush();
|
|
3198
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
|
|
3199
|
+
|
|
3200
|
+
view.rerender(
|
|
3201
|
+
<InvestigationPanel
|
|
3202
|
+
subjectType="alert"
|
|
3203
|
+
subjectId={ALERT_ID}
|
|
3204
|
+
onReportSummaryChange={onReportSummaryChange}
|
|
3205
|
+
/>,
|
|
3206
|
+
);
|
|
3207
|
+
await flush();
|
|
3208
|
+
|
|
3209
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(null);
|
|
3210
|
+
|
|
3211
|
+
await resolveDeferred(
|
|
3212
|
+
nextSubject,
|
|
3213
|
+
structuredResponse({ runId: NEXT_RUN_ID, analysisTldr: nextTldr }),
|
|
3214
|
+
);
|
|
3215
|
+
|
|
3216
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(nextTldr);
|
|
3217
|
+
});
|
|
3218
|
+
|
|
3219
|
+
test("reports null when the report disappears", async () => {
|
|
3220
|
+
const onReportSummaryChange: MockFunction = getJestMockFunction();
|
|
3221
|
+
postMock
|
|
3222
|
+
.mockResolvedValueOnce(
|
|
3223
|
+
structuredResponse({ analysisTldr: TLDR }) as never,
|
|
3224
|
+
)
|
|
3225
|
+
.mockResolvedValue(
|
|
3226
|
+
structuredResponse({
|
|
3227
|
+
analysisMarkdown: null,
|
|
3228
|
+
analysisTldr: TLDR,
|
|
3229
|
+
}) as never,
|
|
3230
|
+
);
|
|
3231
|
+
|
|
3232
|
+
renderPanel({ onReportSummaryChange });
|
|
3233
|
+
await flush();
|
|
3234
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(TLDR);
|
|
3235
|
+
|
|
3236
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3237
|
+
|
|
3238
|
+
expect(onReportSummaryChange).toHaveBeenLastCalledWith(null);
|
|
3239
|
+
});
|
|
3240
|
+
|
|
3241
|
+
test("uses the latest callback without re-reporting", async () => {
|
|
3242
|
+
const first: MockFunction = getJestMockFunction();
|
|
3243
|
+
const second: MockFunction = getJestMockFunction();
|
|
3244
|
+
postMock.mockResolvedValue(
|
|
3245
|
+
structuredResponse({ analysisTldr: TLDR }) as never,
|
|
3246
|
+
);
|
|
3247
|
+
|
|
3248
|
+
const view: ReturnType<typeof render> = renderPanel({
|
|
3249
|
+
onReportSummaryChange: first,
|
|
3250
|
+
});
|
|
3251
|
+
await flush();
|
|
3252
|
+
expect(first).toHaveBeenLastCalledWith(TLDR);
|
|
3253
|
+
|
|
3254
|
+
view.rerender(
|
|
3255
|
+
<InvestigationPanel
|
|
3256
|
+
subjectType="incident"
|
|
3257
|
+
subjectId={INCIDENT_ID}
|
|
3258
|
+
onReportSummaryChange={second}
|
|
3259
|
+
/>,
|
|
3260
|
+
);
|
|
3261
|
+
await flush();
|
|
3262
|
+
expect(second).not.toHaveBeenCalled();
|
|
3263
|
+
|
|
3264
|
+
postMock.mockResolvedValue(
|
|
3265
|
+
structuredResponse({ analysisTldr: "A newer summary." }) as never,
|
|
3266
|
+
);
|
|
3267
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3268
|
+
|
|
3269
|
+
expect(second).toHaveBeenLastCalledWith("A newer summary.");
|
|
3270
|
+
});
|
|
3271
|
+
});
|
|
3272
|
+
|
|
3273
|
+
/*
|
|
3274
|
+
* The header shows a responder's verdict next to the report's summary, so the
|
|
3275
|
+
* panel reports it on the summary's terms: once per change, null until a
|
|
3276
|
+
* report is on screen, and afresh for every subject.
|
|
3277
|
+
*/
|
|
3278
|
+
describe("InvestigationPanel verdict callback", () => {
|
|
3279
|
+
function reportedVerdicts(callback: MockFunction): Array<unknown> {
|
|
3280
|
+
return callback.mock.calls.map((call: Array<unknown>): unknown => {
|
|
3281
|
+
return call[0];
|
|
3282
|
+
});
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
function nonNullVerdicts(callback: MockFunction): Array<unknown> {
|
|
3286
|
+
return reportedVerdicts(callback).filter((value: unknown): boolean => {
|
|
3287
|
+
return value !== null;
|
|
3288
|
+
});
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
test.each(Object.values(AIRunHumanVerdict))(
|
|
3292
|
+
"reports a %s verdict saved with the completed report",
|
|
3293
|
+
async (verdict: AIRunHumanVerdict) => {
|
|
3294
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3295
|
+
postMock.mockResolvedValue(
|
|
3296
|
+
structuredResponse({ humanVerdict: verdict }) as never,
|
|
3297
|
+
);
|
|
3298
|
+
|
|
3299
|
+
renderPanel({ onVerdictChange });
|
|
3300
|
+
await flush();
|
|
3301
|
+
|
|
3302
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(verdict);
|
|
3303
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([verdict]);
|
|
3304
|
+
},
|
|
3305
|
+
);
|
|
3306
|
+
|
|
3307
|
+
test("reports null for a report nobody has rated", async () => {
|
|
3308
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3309
|
+
postMock.mockResolvedValue(structuredResponse() as never);
|
|
3310
|
+
|
|
3311
|
+
renderPanel({ onVerdictChange });
|
|
3312
|
+
await flush();
|
|
3313
|
+
|
|
3314
|
+
expect(onVerdictChange).toHaveBeenCalledWith(null);
|
|
3315
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
|
|
3316
|
+
});
|
|
3317
|
+
|
|
3318
|
+
test("reports no verdict it cannot name", async () => {
|
|
3319
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3320
|
+
postMock.mockResolvedValue(
|
|
3321
|
+
structuredResponse({ humanVerdict: "Edited" }) as never,
|
|
3322
|
+
);
|
|
3323
|
+
|
|
3324
|
+
renderPanel({ onVerdictChange });
|
|
3325
|
+
await flush();
|
|
3326
|
+
|
|
3327
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
|
|
3328
|
+
});
|
|
3329
|
+
|
|
3330
|
+
test.each([
|
|
3331
|
+
[
|
|
3332
|
+
"while a new run is in flight",
|
|
3333
|
+
(): ApiResponse => {
|
|
3334
|
+
return successfulResponse(
|
|
3335
|
+
investigationPayload({
|
|
3336
|
+
status: AIRunStatus.Running,
|
|
3337
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3338
|
+
}),
|
|
3339
|
+
);
|
|
3340
|
+
},
|
|
3341
|
+
],
|
|
3342
|
+
[
|
|
3343
|
+
"while the report is still being prepared",
|
|
3344
|
+
(): ApiResponse => {
|
|
3345
|
+
return completedResponse({
|
|
3346
|
+
analysisMarkdown: null,
|
|
3347
|
+
isAnalysisPending: true,
|
|
3348
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3349
|
+
});
|
|
3350
|
+
},
|
|
3351
|
+
],
|
|
3352
|
+
])(
|
|
3353
|
+
"reports no verdict %s",
|
|
3354
|
+
async (_label: string, response: () => ApiResponse) => {
|
|
3355
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3356
|
+
postMock.mockResolvedValue(response() as never);
|
|
3357
|
+
|
|
3358
|
+
renderPanel({ onVerdictChange });
|
|
3359
|
+
await flush();
|
|
3360
|
+
|
|
3361
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
|
|
3362
|
+
},
|
|
3363
|
+
);
|
|
3364
|
+
|
|
3365
|
+
test("reports a rating the moment it is made, and a changed one", async () => {
|
|
3366
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3367
|
+
postMock
|
|
3368
|
+
.mockResolvedValueOnce(structuredResponse() as never)
|
|
3369
|
+
.mockResolvedValueOnce(successfulResponse({}) as never)
|
|
3370
|
+
.mockResolvedValueOnce(successfulResponse({}) as never);
|
|
3371
|
+
|
|
3372
|
+
renderPanel({ onVerdictChange });
|
|
3373
|
+
await flush();
|
|
3374
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
|
|
3375
|
+
|
|
3376
|
+
fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
|
|
3377
|
+
// Optimistic, like the panel's own pill: before the save resolves.
|
|
3378
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3379
|
+
AIRunHumanVerdict.Confirmed,
|
|
3380
|
+
);
|
|
3381
|
+
await flush();
|
|
3382
|
+
|
|
3383
|
+
fireEvent.click(screen.getByRole("button", { name: "Change" }));
|
|
3384
|
+
fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
|
|
3385
|
+
await flush();
|
|
3386
|
+
|
|
3387
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([
|
|
3388
|
+
AIRunHumanVerdict.Confirmed,
|
|
3389
|
+
AIRunHumanVerdict.Rejected,
|
|
3390
|
+
]);
|
|
3391
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3392
|
+
AIRunHumanVerdict.Rejected,
|
|
3393
|
+
);
|
|
3394
|
+
});
|
|
3395
|
+
|
|
3396
|
+
test("takes a rating back out when the save fails", async () => {
|
|
3397
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3398
|
+
postMock
|
|
3399
|
+
.mockResolvedValueOnce(structuredResponse() as never)
|
|
3400
|
+
.mockResolvedValueOnce(
|
|
3401
|
+
new HTTPErrorResponse(
|
|
3402
|
+
500,
|
|
3403
|
+
{ message: "Verdict storage is unavailable." },
|
|
3404
|
+
{},
|
|
3405
|
+
) as never,
|
|
3406
|
+
);
|
|
3407
|
+
|
|
3408
|
+
renderPanel({ onVerdictChange });
|
|
3409
|
+
await flush();
|
|
3410
|
+
fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
|
|
3411
|
+
await flush();
|
|
3412
|
+
|
|
3413
|
+
expect(screen.getByRole("alert")).toHaveTextContent(
|
|
3414
|
+
"Could not save your verdict",
|
|
3415
|
+
);
|
|
3416
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([
|
|
3417
|
+
AIRunHumanVerdict.Rejected,
|
|
3418
|
+
]);
|
|
3419
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(null);
|
|
3420
|
+
});
|
|
3421
|
+
|
|
3422
|
+
test("a poll started before a rating saved cannot flip the reported verdict", async () => {
|
|
3423
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3424
|
+
const stalePoll: Deferred<ApiResponse> = createDeferred<ApiResponse>();
|
|
3425
|
+
postMock
|
|
3426
|
+
.mockResolvedValueOnce(structuredResponse() as never)
|
|
3427
|
+
.mockReturnValueOnce(stalePoll.promise as never)
|
|
3428
|
+
.mockResolvedValueOnce(successfulResponse({}) as never);
|
|
3429
|
+
|
|
3430
|
+
renderPanel({ onVerdictChange });
|
|
3431
|
+
await flush();
|
|
3432
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3433
|
+
expect(postMock).toHaveBeenCalledTimes(2);
|
|
3434
|
+
|
|
3435
|
+
fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
|
|
3436
|
+
await flush();
|
|
3437
|
+
const callsAfterRating: number = onVerdictChange.mock.calls.length;
|
|
3438
|
+
|
|
3439
|
+
await resolveDeferred(
|
|
3440
|
+
stalePoll,
|
|
3441
|
+
structuredResponse({ humanVerdict: null }),
|
|
3442
|
+
);
|
|
3443
|
+
|
|
3444
|
+
expect(onVerdictChange).toHaveBeenCalledTimes(callsAfterRating);
|
|
3445
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3446
|
+
AIRunHumanVerdict.Confirmed,
|
|
3447
|
+
);
|
|
3448
|
+
});
|
|
3449
|
+
|
|
3450
|
+
test("follows a verdict another responder saves", async () => {
|
|
3451
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3452
|
+
postMock
|
|
3453
|
+
.mockResolvedValueOnce(structuredResponse() as never)
|
|
3454
|
+
.mockResolvedValue(
|
|
3455
|
+
structuredResponse({
|
|
3456
|
+
humanVerdict: AIRunHumanVerdict.Rejected,
|
|
3457
|
+
}) as never,
|
|
3458
|
+
);
|
|
3459
|
+
|
|
3460
|
+
renderPanel({ onVerdictChange });
|
|
3461
|
+
await flush();
|
|
3462
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([]);
|
|
3463
|
+
|
|
3464
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3465
|
+
|
|
3466
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3467
|
+
AIRunHumanVerdict.Rejected,
|
|
3468
|
+
);
|
|
3469
|
+
});
|
|
3470
|
+
|
|
3471
|
+
test("does not repeat an unchanged verdict across polls", async () => {
|
|
3472
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3473
|
+
postMock.mockResolvedValue(
|
|
3474
|
+
structuredResponse({
|
|
3475
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3476
|
+
}) as never,
|
|
3477
|
+
);
|
|
3478
|
+
|
|
3479
|
+
renderPanel({ onVerdictChange });
|
|
3480
|
+
await flush();
|
|
3481
|
+
const callsAfterLoad: number = onVerdictChange.mock.calls.length;
|
|
3482
|
+
|
|
3483
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3484
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3485
|
+
|
|
3486
|
+
expect(investigationPostCount()).toBe(3);
|
|
3487
|
+
expect(onVerdictChange).toHaveBeenCalledTimes(callsAfterLoad);
|
|
3488
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([
|
|
3489
|
+
AIRunHumanVerdict.Confirmed,
|
|
3490
|
+
]);
|
|
3491
|
+
});
|
|
3492
|
+
|
|
3493
|
+
test("drops the verdict when a new run starts", async () => {
|
|
3494
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3495
|
+
postMock
|
|
3496
|
+
.mockResolvedValueOnce(
|
|
3497
|
+
structuredResponse({
|
|
3498
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3499
|
+
}) as never,
|
|
3500
|
+
)
|
|
3501
|
+
.mockResolvedValue(
|
|
3502
|
+
successfulResponse(
|
|
3503
|
+
investigationPayload({
|
|
3504
|
+
status: AIRunStatus.Queued,
|
|
3505
|
+
runId: NEXT_RUN_ID,
|
|
3506
|
+
}),
|
|
3507
|
+
) as never,
|
|
3508
|
+
);
|
|
3509
|
+
|
|
3510
|
+
renderPanel({ onVerdictChange });
|
|
3511
|
+
await flush();
|
|
3512
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3513
|
+
AIRunHumanVerdict.Confirmed,
|
|
3514
|
+
);
|
|
3515
|
+
|
|
3516
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3517
|
+
|
|
3518
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(null);
|
|
3519
|
+
});
|
|
3520
|
+
|
|
3521
|
+
test("reports null the moment the subject changes, then the new verdict", async () => {
|
|
3522
|
+
const onVerdictChange: MockFunction = getJestMockFunction();
|
|
3523
|
+
const nextSubject: Deferred<ApiResponse> = createDeferred<ApiResponse>();
|
|
3524
|
+
postMock
|
|
3525
|
+
.mockResolvedValueOnce(
|
|
3526
|
+
structuredResponse({
|
|
3527
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3528
|
+
}) as never,
|
|
3529
|
+
)
|
|
3530
|
+
.mockReturnValueOnce(nextSubject.promise as never);
|
|
3531
|
+
|
|
3532
|
+
const view: ReturnType<typeof render> = renderPanel({ onVerdictChange });
|
|
3533
|
+
await flush();
|
|
3534
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3535
|
+
AIRunHumanVerdict.Confirmed,
|
|
3536
|
+
);
|
|
3537
|
+
|
|
3538
|
+
view.rerender(
|
|
3539
|
+
<InvestigationPanel
|
|
3540
|
+
subjectType="alert"
|
|
3541
|
+
subjectId={ALERT_ID}
|
|
3542
|
+
onVerdictChange={onVerdictChange}
|
|
3543
|
+
/>,
|
|
3544
|
+
);
|
|
3545
|
+
await flush();
|
|
3546
|
+
|
|
3547
|
+
// Before the alert's report arrives, and without a stale confirmation.
|
|
3548
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(null);
|
|
3549
|
+
|
|
3550
|
+
await resolveDeferred(
|
|
3551
|
+
nextSubject,
|
|
3552
|
+
structuredResponse({
|
|
3553
|
+
runId: NEXT_RUN_ID,
|
|
3554
|
+
humanVerdict: AIRunHumanVerdict.Rejected,
|
|
3555
|
+
}),
|
|
3556
|
+
);
|
|
3557
|
+
|
|
3558
|
+
expect(onVerdictChange).toHaveBeenLastCalledWith(
|
|
3559
|
+
AIRunHumanVerdict.Rejected,
|
|
3560
|
+
);
|
|
3561
|
+
expect(nonNullVerdicts(onVerdictChange)).toEqual([
|
|
3562
|
+
AIRunHumanVerdict.Confirmed,
|
|
3563
|
+
AIRunHumanVerdict.Rejected,
|
|
3564
|
+
]);
|
|
3565
|
+
});
|
|
3566
|
+
|
|
3567
|
+
test("uses the latest callback without re-reporting", async () => {
|
|
3568
|
+
const first: MockFunction = getJestMockFunction();
|
|
3569
|
+
const second: MockFunction = getJestMockFunction();
|
|
3570
|
+
postMock.mockResolvedValue(
|
|
3571
|
+
structuredResponse({
|
|
3572
|
+
humanVerdict: AIRunHumanVerdict.Confirmed,
|
|
3573
|
+
}) as never,
|
|
3574
|
+
);
|
|
3575
|
+
|
|
3576
|
+
const view: ReturnType<typeof render> = renderPanel({
|
|
3577
|
+
onVerdictChange: first,
|
|
3578
|
+
});
|
|
3579
|
+
await flush();
|
|
3580
|
+
expect(first).toHaveBeenLastCalledWith(AIRunHumanVerdict.Confirmed);
|
|
3581
|
+
const firstCallCount: number = first.mock.calls.length;
|
|
3582
|
+
|
|
3583
|
+
view.rerender(
|
|
3584
|
+
<InvestigationPanel
|
|
3585
|
+
subjectType="incident"
|
|
3586
|
+
subjectId={INCIDENT_ID}
|
|
3587
|
+
onVerdictChange={second}
|
|
3588
|
+
/>,
|
|
3589
|
+
);
|
|
3590
|
+
await flush();
|
|
3591
|
+
expect(second).not.toHaveBeenCalled();
|
|
3592
|
+
|
|
3593
|
+
postMock.mockResolvedValue(
|
|
3594
|
+
structuredResponse({ humanVerdict: AIRunHumanVerdict.Rejected }) as never,
|
|
3595
|
+
);
|
|
3596
|
+
await tick(SETTLED_POLL_INTERVAL_MS);
|
|
3597
|
+
|
|
3598
|
+
expect(reportedVerdicts(second)).toEqual([AIRunHumanVerdict.Rejected]);
|
|
3599
|
+
expect(first).toHaveBeenCalledTimes(firstCallCount);
|
|
3600
|
+
});
|
|
3601
|
+
});
|