@oneuptime/common 14.0.2 → 14.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Alert.ts +55 -0
- package/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
- package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
- package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
- package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
- package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
- package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
- package/Models/DatabaseModels/Incident.ts +55 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/Index.ts +18 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
- package/Models/DatabaseModels/TelemetryException.ts +2 -0
- package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Middleware/MultipartFormData.ts +1 -1
- package/Server/Middleware/TelemetryIngest.ts +15 -8
- package/Server/Services/AlertReminderRuleService.ts +100 -24
- package/Server/Services/DatabaseServerEndpointService.ts +895 -0
- package/Server/Services/DatabaseServerFeedService.ts +128 -0
- package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
- package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
- package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
- package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
- package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
- package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
- package/Server/Services/DatabaseServerService.ts +4546 -0
- package/Server/Services/DatabaseService.ts +14 -8
- package/Server/Services/DockerResourceService.ts +43 -2
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentReminderRuleService.ts +103 -23
- package/Server/Services/IncidentService.ts +210 -10
- package/Server/Services/IncidentStateTimelineService.ts +24 -0
- package/Server/Services/Index.ts +18 -0
- package/Server/Services/InventoryItemService.ts +113 -5
- package/Server/Services/IoTDeviceService.ts +145 -37
- package/Server/Services/OpenTelemetryIngestService.ts +19 -0
- package/Server/Services/PodmanResourceService.ts +43 -2
- package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
- package/Server/Services/ServiceService.ts +1 -1
- package/Server/Services/TelemetryUsageBillingService.ts +29 -2
- package/Server/Services/UserProjectSsoConsentService.ts +74 -0
- package/Server/Services/UserService.ts +14 -1
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
- package/Server/Types/Database/QueryHelper.ts +30 -1
- package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
- package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
- package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
- package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
- package/Server/Utils/Monitor/MonitorResource.ts +47 -11
- package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
- package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Server/Utils/StartServer.ts +26 -6
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
- package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
- package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
- package/Server/Utils/Telemetry/Telemetry.ts +16 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
- package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
- package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
- package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
- package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
- package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
- package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
- package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
- package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
- package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
- package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
- package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
- package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
- package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
- package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
- package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
- package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
- package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
- package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
- package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
- package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
- package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
- package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
- package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
- package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
- package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
- package/Tests/ClassStrings.ts +178 -0
- package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
- package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/RenderedMarkup.ts +518 -0
- package/Tests/ResponsiveVisibility.test.ts +490 -4
- package/Tests/ResponsiveVisibility.ts +505 -52
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
- package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
- package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
- package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
- package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
- package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
- package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
- package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
- package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
- package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
- package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
- package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
- package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
- package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
- package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
- package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
- package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
- package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
- package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
- package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
- package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
- package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
- package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
- package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
- package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
- package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
- package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
- package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
- package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
- package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
- package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
- package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
- package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
- package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
- package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
- package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
- package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
- package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
- package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
- package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
- package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
- package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
- package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
- package/Tests/UI/Components/Card.test.tsx +93 -2
- package/Tests/UI/Components/FeedOptions.test.ts +6 -0
- package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
- package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
- package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
- package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
- package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +80 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +23 -0
- package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
- package/Tests/UI/Utils/Navigation.test.ts +102 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
- package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
- package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
- package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
- package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Tests/Utils/ValueFormatter.test.ts +50 -0
- package/Tests/tsconfig.json +16 -0
- package/Types/AI/AIResourceContext.ts +7 -0
- package/Types/Dashboard/DashboardTemplates.ts +2 -1
- package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
- package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
- package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
- package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
- package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
- package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
- package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
- package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Monitor/CephAlertTemplates.ts +18 -0
- package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
- package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
- package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
- package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
- package/Types/Permission.ts +315 -0
- package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
- package/Types/Rules/RuleRun.ts +12 -0
- package/Types/Rum/SessionReplay.ts +25 -6
- package/Types/Rum/WebVitals.ts +52 -0
- package/Types/Telemetry/EntityType.ts +23 -0
- package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
- package/Types/Telemetry/ServiceType.ts +8 -0
- package/UI/Components/Banner/Banner.tsx +1 -1
- package/UI/Components/Card/Card.tsx +1 -1
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
- package/UI/Components/Charts/Line/LineChart.tsx +7 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
- package/UI/Components/Date/StartAndEndDate.tsx +5 -5
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
- package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
- package/UI/Components/Forms/BasicForm.tsx +1 -1
- package/UI/Components/Header/Header.tsx +1 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
- package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
- package/UI/Components/Modal/ModalFooter.tsx +1 -1
- package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +99 -21
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/Navbar/NavBar.tsx +9 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
- package/UI/Components/Page/Page.tsx +1 -1
- package/UI/Components/Pagination/Pagination.tsx +3 -3
- package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
- package/UI/Components/SideMenu/SideMenu.tsx +4 -1
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
- package/UI/Components/StatusPage/ResourceList.tsx +6 -6
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
- package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
- package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
- package/UI/Styles/Theme.css +8 -1
- package/UI/Utils/Navigation.ts +89 -42
- package/UI/Utils/PermissionGate.ts +11 -2
- package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
- package/UI/Utils/TelemetryService.ts +4 -3
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/LabelRuleImportExport.ts +2 -0
- package/Utils/MetricUnitUtil.ts +103 -11
- package/Utils/Monitor/MetricValueFormatter.ts +66 -13
- package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
- package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
- package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
- package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
- package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
- package/Utils/Telemetry/EntityKey.ts +176 -0
- package/Utils/ValueFormatter.ts +16 -0
- package/build/dist/Models/DatabaseModels/Alert.js +54 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Incident.js +54 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +18 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
- package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
- package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
- package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
- package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
- package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
- package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseService.js +8 -4
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerResourceService.js +30 -3
- package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
- package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +164 -12
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +18 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +88 -5
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceService.js +111 -24
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PodmanResourceService.js +30 -3
- package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +1 -1
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
- package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
- package/build/dist/Server/Services/UserService.js +13 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
- package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +20 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
- package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
- package/build/dist/Types/AI/AIResourceContext.js +7 -0
- package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
- package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
- package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
- package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
- package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
- package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
- package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
- package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
- package/build/dist/Types/Permission.js +276 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +23 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
- package/build/dist/Types/Telemetry/ServiceType.js +8 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Banner/Banner.js +1 -1
- package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
- package/build/dist/UI/Components/Card/Card.js +1 -1
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
- package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +70 -18
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/Page/Page.js +1 -1
- package/build/dist/UI/Components/Page/Page.js.map +1 -1
- package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
- package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
- package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
- package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +66 -33
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +3 -2
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/MetricUnitUtil.js +77 -13
- package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
- package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
- package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
- package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
- package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
- package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +15 -0
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +1 -1
- package/tsconfig.tests.json +7 -5
|
@@ -0,0 +1,1061 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
3
|
+
import {
|
|
4
|
+
act,
|
|
5
|
+
cleanup,
|
|
6
|
+
fireEvent,
|
|
7
|
+
render,
|
|
8
|
+
screen,
|
|
9
|
+
waitFor,
|
|
10
|
+
} from "@testing-library/react";
|
|
11
|
+
import React from "react";
|
|
12
|
+
import { MemoryRouter } from "react-router-dom";
|
|
13
|
+
import DiscoveryPage from "../../../../App/FeatureSet/Dashboard/src/Pages/NetworkDevice/Discovery";
|
|
14
|
+
import ProbeUtil from "../../../../App/FeatureSet/Dashboard/src/Utils/Probe";
|
|
15
|
+
import NetworkDeviceDiscoveryScan, {
|
|
16
|
+
DiscoveredNetworkDevice,
|
|
17
|
+
} from "../../../Models/DatabaseModels/NetworkDeviceDiscoveryScan";
|
|
18
|
+
import Probe from "../../../Models/DatabaseModels/Probe";
|
|
19
|
+
import Project from "../../../Models/DatabaseModels/Project";
|
|
20
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
21
|
+
import Route from "../../../Types/API/Route";
|
|
22
|
+
import Permission from "../../../Types/Permission";
|
|
23
|
+
import { VoidFunction } from "../../../Types/FunctionTypes";
|
|
24
|
+
import {
|
|
25
|
+
DiscoveredHostNetbiosStatus,
|
|
26
|
+
DiscoveredHostReverseDnsStatus,
|
|
27
|
+
} from "../../../Types/NetworkDevice/DiscoveredHostNamingStatus";
|
|
28
|
+
import ModelAPI from "../../../UI/Utils/ModelAPI/ModelAPI";
|
|
29
|
+
import ProjectUtil from "../../../UI/Utils/Project";
|
|
30
|
+
import PermissionUtil from "../../../UI/Utils/Permission";
|
|
31
|
+
import { ComponentProps as ModalProps } from "../../../UI/Components/Modal/Modal";
|
|
32
|
+
import {
|
|
33
|
+
ASK_THE_DEVICE_TIP,
|
|
34
|
+
DiscoveredHostNamingExplanation,
|
|
35
|
+
DiscoveredHostNamingScan,
|
|
36
|
+
FAILED_SCAN_EXPLANATION,
|
|
37
|
+
IN_PROGRESS_EXPLANATION,
|
|
38
|
+
NETBIOS_NOT_RECORDED_SENTENCE,
|
|
39
|
+
NETBIOS_OFF_SENTENCE,
|
|
40
|
+
NOT_YET_NAMED_HOST_LABEL,
|
|
41
|
+
NO_RECORD_TIP,
|
|
42
|
+
REVERSE_DNS_NOT_RECORDED_SENTENCE,
|
|
43
|
+
SNMP_NOT_CHECKED_SENTENCE,
|
|
44
|
+
SNMP_NO_SYSNAME_SENTENCE,
|
|
45
|
+
TRANSIENT_FAILURE_TIP,
|
|
46
|
+
UNNAMED_HOST_LABEL,
|
|
47
|
+
explainUnnamedDiscoveredHost,
|
|
48
|
+
} from "../../../Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis";
|
|
49
|
+
import { DiscoveryScanStatus } from "../../../Utils/NetworkDiscovery/DiscoveryScanStatus";
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* OneUptime issue #3916, RENDERED: the Review Discovered Devices dialog says
|
|
53
|
+
* why a host is listed by its bare address.
|
|
54
|
+
*
|
|
55
|
+
* The report: an ICMP-only scan of twelve kitchen displays named four of them
|
|
56
|
+
* by reverse DNS and listed the other eight as addresses, with nothing
|
|
57
|
+
* anywhere to say why. The probe now records per unnamed host what each
|
|
58
|
+
* naming lookup came back with, Common's explainUnnamedDiscoveredHost turns
|
|
59
|
+
* that (or, for a row from an older probe, what the scan was set to ask) into
|
|
60
|
+
* fixed sentences, and the row shows a muted "No name found" and an (i)
|
|
61
|
+
* carrying those sentences beside the name line.
|
|
62
|
+
*
|
|
63
|
+
* The wording itself is pinned by Common's own unit tests of that function.
|
|
64
|
+
* What this file pins is the WIRING, through the real page with only the
|
|
65
|
+
* scans table and the modal chrome mocked (the same harness as
|
|
66
|
+
* DiscoveryReviewInventoryRefresh.test.tsx):
|
|
67
|
+
*
|
|
68
|
+
* - the (i) is on unnamed rows and ONLY on unnamed rows;
|
|
69
|
+
* - hovering it shows exactly the explanation for THAT host under THIS
|
|
70
|
+
* scan — so the row hands the function the fresh scan (status, SNMP,
|
|
71
|
+
* NetBIOS) and whether the scan's probe is a global one;
|
|
72
|
+
* - the dialog's fresh read selects isNetbiosLookupEnabled, without which
|
|
73
|
+
* every scan would read as "NetBIOS off";
|
|
74
|
+
* - nothing the scanned host chose reaches the tooltip.
|
|
75
|
+
*
|
|
76
|
+
* Each explanation is asserted twice over: EXACTLY equal to what the Common
|
|
77
|
+
* function says for the inputs the test states (which is what catches a row
|
|
78
|
+
* passing the wrong scan or dropping the global-probe answer), and containing
|
|
79
|
+
* the specific sentences that make the case distinguishable (which is what
|
|
80
|
+
* stops the first assertion from passing because both sides went blank).
|
|
81
|
+
*
|
|
82
|
+
* Asserting tippy under jsdom: see Common/Tests/UI/Components/
|
|
83
|
+
* InfoTooltip.test.tsx. The (i) is lazy, so no tooltip exists until it is
|
|
84
|
+
* hovered; the popup is portalled to document.body and never finishes
|
|
85
|
+
* animating out, so each explanation is read through the aria-describedby
|
|
86
|
+
* link Tippy puts on the very (i) that was hovered, rather than by assuming
|
|
87
|
+
* it is the only tooltip on the page.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
interface TableProps {
|
|
91
|
+
actionButtons: Array<{
|
|
92
|
+
title: string;
|
|
93
|
+
onClick: (
|
|
94
|
+
scan: NetworkDeviceDiscoveryScan,
|
|
95
|
+
onComplete: VoidFunction,
|
|
96
|
+
) => Promise<void>;
|
|
97
|
+
}>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let capturedTable: TableProps | null = null;
|
|
101
|
+
|
|
102
|
+
jest.mock("../../../UI/Components/ModelTable/ModelTable", () => {
|
|
103
|
+
return {
|
|
104
|
+
__esModule: true,
|
|
105
|
+
default: (props: TableProps) => {
|
|
106
|
+
capturedTable = props;
|
|
107
|
+
return null;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
jest.mock("../../../UI/Components/Modal/Modal", () => {
|
|
113
|
+
return {
|
|
114
|
+
__esModule: true,
|
|
115
|
+
ModalWidth: { Medium: 1 },
|
|
116
|
+
default: (props: ModalProps) => {
|
|
117
|
+
return (
|
|
118
|
+
<div role="dialog" aria-label={props.title}>
|
|
119
|
+
<p>{props.description}</p>
|
|
120
|
+
{props.error && <p role="alert">{props.error}</p>}
|
|
121
|
+
{props.isBodyLoading ? <p>Refreshing inventory</p> : props.children}
|
|
122
|
+
<button onClick={props.onClose}>Close review</button>
|
|
123
|
+
<button
|
|
124
|
+
disabled={props.disableSubmitButton || props.isLoading}
|
|
125
|
+
onClick={props.onSubmit}
|
|
126
|
+
>
|
|
127
|
+
{props.submitButtonText}
|
|
128
|
+
</button>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
136
|
+
"11111111-1111-4111-8111-111111111111",
|
|
137
|
+
);
|
|
138
|
+
const SCAN_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
|
|
139
|
+
const OTHER_SCAN_ID: ObjectID = new ObjectID(
|
|
140
|
+
"33333333-3333-4333-8333-333333333333",
|
|
141
|
+
);
|
|
142
|
+
// The probe the scans below ran on, unless a test says otherwise.
|
|
143
|
+
const PROBE_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
|
|
144
|
+
const OTHER_PROBE_ID: ObjectID = new ObjectID(
|
|
145
|
+
"55555555-5555-4555-8555-555555555555",
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Every (i) this feature draws is named "About why <address> has no name".
|
|
149
|
+
const UNNAMED_HINT_NAME: RegExp = /^About why .+ has no name$/;
|
|
150
|
+
|
|
151
|
+
let getItemSpy: jest.SpyInstance;
|
|
152
|
+
let createSpy: jest.SpyInstance;
|
|
153
|
+
let getAllProbesSpy: jest.SpyInstance;
|
|
154
|
+
|
|
155
|
+
interface ScanShape {
|
|
156
|
+
hosts: Array<DiscoveredNetworkDevice>;
|
|
157
|
+
id?: ObjectID | undefined;
|
|
158
|
+
status?: string | undefined;
|
|
159
|
+
statusMessage?: string | undefined;
|
|
160
|
+
isSnmpEnabled?: boolean | undefined;
|
|
161
|
+
isNetbiosLookupEnabled?: boolean | undefined;
|
|
162
|
+
probeId?: ObjectID | undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* A scan as the dialog's fresh read returns it. Only the columns a test sets
|
|
167
|
+
* are set: an unset isNetbiosLookupEnabled is exactly what the dialog would
|
|
168
|
+
* have seen before it started selecting the column.
|
|
169
|
+
*/
|
|
170
|
+
function reviewScan(shape: ScanShape): NetworkDeviceDiscoveryScan {
|
|
171
|
+
const value: NetworkDeviceDiscoveryScan = new NetworkDeviceDiscoveryScan();
|
|
172
|
+
value.id = shape.id || SCAN_ID;
|
|
173
|
+
value.projectId = PROJECT_ID;
|
|
174
|
+
value.probeId = shape.probeId || PROBE_ID;
|
|
175
|
+
value.name = "Kitchen displays";
|
|
176
|
+
value.cidr = "10.18.166.0/24";
|
|
177
|
+
value.status = shape.status || DiscoveryScanStatus.Completed;
|
|
178
|
+
|
|
179
|
+
if (shape.statusMessage !== undefined) {
|
|
180
|
+
value.statusMessage = shape.statusMessage;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (shape.isSnmpEnabled !== undefined) {
|
|
184
|
+
value.isSnmpEnabled = shape.isSnmpEnabled;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (shape.isNetbiosLookupEnabled !== undefined) {
|
|
188
|
+
value.isNetbiosLookupEnabled = shape.isNetbiosLookupEnabled;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
value.discoveredDevices = shape.hosts;
|
|
192
|
+
return value;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/*
|
|
196
|
+
* The facts of a scan the explanation reads, stated separately from the scan
|
|
197
|
+
* object so each expected text below says in plain view what it was computed
|
|
198
|
+
* from.
|
|
199
|
+
*/
|
|
200
|
+
function namingFactsOf(
|
|
201
|
+
scan: NetworkDeviceDiscoveryScan,
|
|
202
|
+
): DiscoveredHostNamingScan {
|
|
203
|
+
return {
|
|
204
|
+
status: scan.status,
|
|
205
|
+
isSnmpEnabled: scan.isSnmpEnabled,
|
|
206
|
+
isNetbiosLookupEnabled: scan.isNetbiosLookupEnabled,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function expectedExplanation(data: {
|
|
211
|
+
host: DiscoveredNetworkDevice;
|
|
212
|
+
scan: NetworkDeviceDiscoveryScan;
|
|
213
|
+
isGlobalProbe: boolean | undefined;
|
|
214
|
+
}): DiscoveredHostNamingExplanation {
|
|
215
|
+
const explanation: DiscoveredHostNamingExplanation | undefined =
|
|
216
|
+
explainUnnamedDiscoveredHost({
|
|
217
|
+
host: data.host,
|
|
218
|
+
scan: namingFactsOf(data.scan),
|
|
219
|
+
isGlobalProbe: data.isGlobalProbe,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// A test that expects an explanation for a named host is a broken test.
|
|
223
|
+
if (!explanation) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`The fixture ${data.host.ipAddress} is named, so it has no explanation.`,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return explanation;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function probe(id: ObjectID, isGlobalProbe: boolean): Probe {
|
|
233
|
+
const value: Probe = new Probe();
|
|
234
|
+
value.id = id;
|
|
235
|
+
value.name = isGlobalProbe ? "probe-1" : "Kitchen probe";
|
|
236
|
+
// What ProbeUtil.getAllProbes stamps on every probe it returns.
|
|
237
|
+
value.isGlobalProbe = isGlobalProbe;
|
|
238
|
+
return value;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function renderPage(): Promise<void> {
|
|
242
|
+
const project: Project = new Project();
|
|
243
|
+
project.id = PROJECT_ID;
|
|
244
|
+
render(
|
|
245
|
+
<MemoryRouter>
|
|
246
|
+
<DiscoveryPage
|
|
247
|
+
pageRoute={new Route("/dashboard/network-devices/discovery")}
|
|
248
|
+
currentProject={project}
|
|
249
|
+
hasPaymentMethod={true}
|
|
250
|
+
/>
|
|
251
|
+
</MemoryRouter>,
|
|
252
|
+
);
|
|
253
|
+
await waitFor(() => {
|
|
254
|
+
expect(capturedTable).not.toBeNull();
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function reviewAction(): TableProps["actionButtons"][number] {
|
|
259
|
+
const action: TableProps["actionButtons"][number] | undefined =
|
|
260
|
+
capturedTable?.actionButtons.find(
|
|
261
|
+
(button: TableProps["actionButtons"][number]) => {
|
|
262
|
+
return button.title === "Review Results";
|
|
263
|
+
},
|
|
264
|
+
);
|
|
265
|
+
if (!action) {
|
|
266
|
+
throw new Error("Review Results action was not rendered");
|
|
267
|
+
}
|
|
268
|
+
return action;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/*
|
|
272
|
+
* Open Review Results on `scan`, with the dialog's fresh read answering with
|
|
273
|
+
* that same scan — so what is rendered is exactly the fixture.
|
|
274
|
+
*/
|
|
275
|
+
async function openReviewOf(scan: NetworkDeviceDiscoveryScan): Promise<void> {
|
|
276
|
+
getItemSpy.mockResolvedValue(scan);
|
|
277
|
+
await act(async () => {
|
|
278
|
+
await reviewAction().onClick(scan, () => {});
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function unnamedHint(ipAddress: string): HTMLElement {
|
|
283
|
+
return screen.getByTestId(`discovered-device-unnamed-${ipAddress}`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function queryUnnamedHint(ipAddress: string): HTMLElement | null {
|
|
287
|
+
return screen.queryByTestId(`discovered-device-unnamed-${ipAddress}`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function checkbox(ipAddress: string): HTMLElement {
|
|
291
|
+
return screen.getByTestId(`discovered-device-checkbox-${ipAddress}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/*
|
|
295
|
+
* Hover the row's (i) and return exactly what its tooltip says: the popup
|
|
296
|
+
* Tippy linked to THAT (i) through aria-describedby, so a tooltip left over
|
|
297
|
+
* from an earlier hover cannot be read by mistake. Unhovered afterwards.
|
|
298
|
+
*/
|
|
299
|
+
async function explanationShownFor(ipAddress: string): Promise<string> {
|
|
300
|
+
const trigger: HTMLElement = unnamedHint(ipAddress);
|
|
301
|
+
|
|
302
|
+
fireEvent.mouseEnter(trigger);
|
|
303
|
+
await act(async () => {
|
|
304
|
+
jest.advanceTimersByTime(200);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const describedBy: string | null = trigger.getAttribute("aria-describedby");
|
|
308
|
+
|
|
309
|
+
expect(describedBy).toBeTruthy();
|
|
310
|
+
|
|
311
|
+
const popup: HTMLElement | null = document.getElementById(
|
|
312
|
+
describedBy as string,
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
expect(popup).not.toBeNull();
|
|
316
|
+
|
|
317
|
+
const text: string = popup!.textContent || "";
|
|
318
|
+
|
|
319
|
+
fireEvent.mouseLeave(trigger);
|
|
320
|
+
await act(async () => {
|
|
321
|
+
jest.advanceTimersByTime(400);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
return text;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
* The row element for an address: the checkbox's row, found by walking up to
|
|
329
|
+
* the element that carries the row's bottom border.
|
|
330
|
+
*/
|
|
331
|
+
function rowOf(ipAddress: string): HTMLElement {
|
|
332
|
+
const row: HTMLElement | null = checkbox(ipAddress).closest(".border-b");
|
|
333
|
+
|
|
334
|
+
if (!row) {
|
|
335
|
+
throw new Error(`No row found for ${ipAddress}`);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return row as HTMLElement;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
beforeEach(() => {
|
|
342
|
+
jest.useFakeTimers();
|
|
343
|
+
capturedTable = null;
|
|
344
|
+
jest.spyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(PROJECT_ID);
|
|
345
|
+
getAllProbesSpy = jest.spyOn(ProbeUtil, "getAllProbes").mockResolvedValue([]);
|
|
346
|
+
jest
|
|
347
|
+
.spyOn(PermissionUtil, "getAllPermissions")
|
|
348
|
+
.mockReturnValue([Permission.ProjectAdmin]);
|
|
349
|
+
getItemSpy = jest.spyOn(ModelAPI, "getItem");
|
|
350
|
+
createSpy = jest
|
|
351
|
+
.spyOn(ModelAPI, "create")
|
|
352
|
+
.mockResolvedValue(undefined as never);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
afterEach(() => {
|
|
356
|
+
cleanup();
|
|
357
|
+
jest.restoreAllMocks();
|
|
358
|
+
jest.useRealTimers();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
/*
|
|
362
|
+
* The reporter's scan, cut down to one row of each kind: ICMP-only, NetBIOS
|
|
363
|
+
* lookup off, run on a project probe. Two hosts named by their PTR records;
|
|
364
|
+
* one the probe's DNS server has no PTR record for; one whose lookup timed
|
|
365
|
+
* out even on the retry; and one stored by a probe older than the per-host
|
|
366
|
+
* codes, which carries none.
|
|
367
|
+
*/
|
|
368
|
+
describe("the reporter's ICMP-only scan says why each unnamed host has no name (issue #3916)", () => {
|
|
369
|
+
const NAMED_FIRST: DiscoveredNetworkDevice = {
|
|
370
|
+
ipAddress: "10.18.166.50",
|
|
371
|
+
snmpReachable: false,
|
|
372
|
+
dnsHostname: "wb-0660-kds01.wbhq.com",
|
|
373
|
+
};
|
|
374
|
+
const NO_RECORD: DiscoveredNetworkDevice = {
|
|
375
|
+
ipAddress: "10.18.166.51",
|
|
376
|
+
snmpReachable: false,
|
|
377
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.NoRecord,
|
|
378
|
+
};
|
|
379
|
+
const NAMED_SECOND: DiscoveredNetworkDevice = {
|
|
380
|
+
ipAddress: "10.18.166.52",
|
|
381
|
+
snmpReachable: false,
|
|
382
|
+
dnsHostname: "wb-0660-kds02.wbhq.com",
|
|
383
|
+
};
|
|
384
|
+
const TIMED_OUT: DiscoveredNetworkDevice = {
|
|
385
|
+
ipAddress: "10.18.166.53",
|
|
386
|
+
snmpReachable: false,
|
|
387
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.Timeout,
|
|
388
|
+
};
|
|
389
|
+
const LEGACY: DiscoveredNetworkDevice = {
|
|
390
|
+
ipAddress: "10.18.166.54",
|
|
391
|
+
snmpReachable: false,
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
function reporterScan(): NetworkDeviceDiscoveryScan {
|
|
395
|
+
return reviewScan({
|
|
396
|
+
hosts: [NAMED_FIRST, NO_RECORD, NAMED_SECOND, TIMED_OUT, LEGACY],
|
|
397
|
+
isSnmpEnabled: false,
|
|
398
|
+
isNetbiosLookupEnabled: false,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
beforeEach(() => {
|
|
403
|
+
getAllProbesSpy.mockResolvedValue([probe(PROBE_ID, false)]);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
test("the (i) is drawn on the three unnamed rows and on neither named one", async () => {
|
|
407
|
+
await renderPage();
|
|
408
|
+
await openReviewOf(reporterScan());
|
|
409
|
+
|
|
410
|
+
expect(queryUnnamedHint("10.18.166.50")).not.toBeInTheDocument();
|
|
411
|
+
expect(queryUnnamedHint("10.18.166.52")).not.toBeInTheDocument();
|
|
412
|
+
expect(unnamedHint("10.18.166.51")).toBeInTheDocument();
|
|
413
|
+
expect(unnamedHint("10.18.166.53")).toBeInTheDocument();
|
|
414
|
+
expect(unnamedHint("10.18.166.54")).toBeInTheDocument();
|
|
415
|
+
|
|
416
|
+
// And nothing else on the page is one: exactly three, one per row.
|
|
417
|
+
expect(
|
|
418
|
+
screen.getAllByRole("button", { name: UNNAMED_HINT_NAME }),
|
|
419
|
+
).toHaveLength(3);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
test("each (i) is a button named after the address it explains", async () => {
|
|
423
|
+
await renderPage();
|
|
424
|
+
await openReviewOf(reporterScan());
|
|
425
|
+
|
|
426
|
+
const button: HTMLElement = screen.getByRole("button", {
|
|
427
|
+
name: "About why 10.18.166.51 has no name",
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
expect(button).toBe(unnamedHint("10.18.166.51"));
|
|
431
|
+
expect(button).toHaveAttribute("type", "button");
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
test("a muted 'No name found' sits beside each unnamed name, and only there", async () => {
|
|
435
|
+
await renderPage();
|
|
436
|
+
await openReviewOf(reporterScan());
|
|
437
|
+
|
|
438
|
+
expect(screen.getAllByText(UNNAMED_HOST_LABEL)).toHaveLength(3);
|
|
439
|
+
|
|
440
|
+
for (const ipAddress of ["10.18.166.51", "10.18.166.53", "10.18.166.54"]) {
|
|
441
|
+
const label: HTMLElement | null =
|
|
442
|
+
rowOf(ipAddress).querySelector("span.text-gray-400");
|
|
443
|
+
|
|
444
|
+
expect(label).toHaveTextContent(UNNAMED_HOST_LABEL);
|
|
445
|
+
// Muted, small, and never squeezed out by a long name beside it.
|
|
446
|
+
expect(label).toHaveClass("text-xs", "flex-shrink-0");
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
for (const ipAddress of ["10.18.166.50", "10.18.166.52"]) {
|
|
450
|
+
expect(rowOf(ipAddress)).not.toHaveTextContent(UNNAMED_HOST_LABEL);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
test("the explanation is not in the page until someone reaches for it", async () => {
|
|
455
|
+
await renderPage();
|
|
456
|
+
await openReviewOf(reporterScan());
|
|
457
|
+
|
|
458
|
+
expect(screen.queryByRole("tooltip")).not.toBeInTheDocument();
|
|
459
|
+
expect(
|
|
460
|
+
screen.queryByText(REVERSE_DNS_NOT_RECORDED_SENTENCE, { exact: false }),
|
|
461
|
+
).not.toBeInTheDocument();
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
test("hovering a host the DNS server has no PTR record for says exactly that", async () => {
|
|
465
|
+
await renderPage();
|
|
466
|
+
await openReviewOf(reporterScan());
|
|
467
|
+
|
|
468
|
+
fireEvent.mouseEnter(unnamedHint("10.18.166.51"));
|
|
469
|
+
await act(async () => {
|
|
470
|
+
jest.advanceTimersByTime(200);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const expected: DiscoveredHostNamingExplanation = expectedExplanation({
|
|
474
|
+
host: NO_RECORD,
|
|
475
|
+
scan: reporterScan(),
|
|
476
|
+
isGlobalProbe: false,
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// The only tooltip on the page, and exactly the Common function's text.
|
|
480
|
+
expect(screen.getByRole("tooltip").textContent).toBe(expected.text);
|
|
481
|
+
|
|
482
|
+
const text: string = screen.getByRole("tooltip").textContent || "";
|
|
483
|
+
|
|
484
|
+
// SNMP was never asked on this scan, and the tooltip says so first.
|
|
485
|
+
expect(text.startsWith(SNMP_NOT_CHECKED_SENTENCE)).toBe(true);
|
|
486
|
+
// The per-host code, not the legacy "nothing was recorded".
|
|
487
|
+
expect(text).toContain("no PTR record");
|
|
488
|
+
expect(text).not.toContain(REVERSE_DNS_NOT_RECORDED_SENTENCE);
|
|
489
|
+
// NetBIOS was off, and the way to ask the device itself is named.
|
|
490
|
+
expect(text).toContain(NETBIOS_OFF_SENTENCE);
|
|
491
|
+
expect(text).toContain(NO_RECORD_TIP);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
test("hovering a host whose lookup timed out says it timed out, not that it has no record", async () => {
|
|
495
|
+
await renderPage();
|
|
496
|
+
await openReviewOf(reporterScan());
|
|
497
|
+
|
|
498
|
+
const text: string = await explanationShownFor("10.18.166.53");
|
|
499
|
+
|
|
500
|
+
expect(text).toBe(
|
|
501
|
+
expectedExplanation({
|
|
502
|
+
host: TIMED_OUT,
|
|
503
|
+
scan: reporterScan(),
|
|
504
|
+
isGlobalProbe: false,
|
|
505
|
+
}).text,
|
|
506
|
+
);
|
|
507
|
+
expect(text).toContain("did not answer in time");
|
|
508
|
+
expect(text).toContain(TRANSIENT_FAILURE_TIP);
|
|
509
|
+
// The defect #3916 was about: a DNS failure filed as "no PTR record".
|
|
510
|
+
expect(text).not.toContain("no PTR record");
|
|
511
|
+
expect(text).not.toContain(NO_RECORD_TIP);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
test("hovering a row from an older probe says only what the scan itself can support", async () => {
|
|
515
|
+
await renderPage();
|
|
516
|
+
await openReviewOf(reporterScan());
|
|
517
|
+
|
|
518
|
+
const text: string = await explanationShownFor("10.18.166.54");
|
|
519
|
+
|
|
520
|
+
/*
|
|
521
|
+
* Spelled out from the exported sentences as well as compared to the
|
|
522
|
+
* function: this is the reporter's case exactly — no codes, ICMP only,
|
|
523
|
+
* NetBIOS off — and the one where the honest answer is "SNMP and NetBIOS
|
|
524
|
+
* were never asked, and reverse DNS recorded nothing", plus how to get
|
|
525
|
+
* the device's own name.
|
|
526
|
+
*/
|
|
527
|
+
expect(text).toBe(
|
|
528
|
+
expectedExplanation({
|
|
529
|
+
host: LEGACY,
|
|
530
|
+
scan: reporterScan(),
|
|
531
|
+
isGlobalProbe: false,
|
|
532
|
+
}).text,
|
|
533
|
+
);
|
|
534
|
+
expect(text).toBe(
|
|
535
|
+
[
|
|
536
|
+
SNMP_NOT_CHECKED_SENTENCE,
|
|
537
|
+
REVERSE_DNS_NOT_RECORDED_SENTENCE,
|
|
538
|
+
NETBIOS_OFF_SENTENCE,
|
|
539
|
+
ASK_THE_DEVICE_TIP,
|
|
540
|
+
].join(" "),
|
|
541
|
+
);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
test("the three unnamed rows are three different explanations", async () => {
|
|
545
|
+
await renderPage();
|
|
546
|
+
await openReviewOf(reporterScan());
|
|
547
|
+
|
|
548
|
+
const texts: Array<string> = [];
|
|
549
|
+
|
|
550
|
+
for (const ipAddress of ["10.18.166.51", "10.18.166.53", "10.18.166.54"]) {
|
|
551
|
+
texts.push(await explanationShownFor(ipAddress));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
expect(new Set<string>(texts).size).toBe(3);
|
|
555
|
+
|
|
556
|
+
for (const text of texts) {
|
|
557
|
+
expect(text.trim().length).toBeGreaterThan(0);
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
test("the (i) sits on the name line, after the name, not on the address line", async () => {
|
|
562
|
+
await renderPage();
|
|
563
|
+
await openReviewOf(reporterScan());
|
|
564
|
+
|
|
565
|
+
const button: HTMLElement = unnamedHint("10.18.166.51");
|
|
566
|
+
const nameLine: HTMLElement = button.parentElement as HTMLElement;
|
|
567
|
+
const name: HTMLElement = nameLine.firstElementChild as HTMLElement;
|
|
568
|
+
|
|
569
|
+
// The name div is unchanged: truncating, titled, and first.
|
|
570
|
+
expect(name).toHaveAttribute("title", "10.18.166.51");
|
|
571
|
+
expect(name).toHaveClass("truncate");
|
|
572
|
+
expect(name).toHaveTextContent("10.18.166.51");
|
|
573
|
+
// The wrapper lets the name shrink rather than push the (i) off the row.
|
|
574
|
+
expect(nameLine).toHaveClass("flex", "min-w-0");
|
|
575
|
+
// Name, then the muted label, then the (i).
|
|
576
|
+
expect(nameLine.lastElementChild).toBe(button);
|
|
577
|
+
|
|
578
|
+
const addressLine: HTMLElement = nameLine.nextElementSibling as HTMLElement;
|
|
579
|
+
|
|
580
|
+
expect(addressLine).toHaveTextContent("10.18.166.51");
|
|
581
|
+
expect(addressLine).not.toHaveTextContent(UNNAMED_HOST_LABEL);
|
|
582
|
+
expect(addressLine.querySelector("button")).toBeNull();
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
test("a named row's name line is exactly the name, with nothing beside it", async () => {
|
|
586
|
+
await renderPage();
|
|
587
|
+
await openReviewOf(reporterScan());
|
|
588
|
+
|
|
589
|
+
const name: HTMLElement = screen.getByTitle("wb-0660-kds01.wbhq.com");
|
|
590
|
+
const nameLine: HTMLElement = name.parentElement as HTMLElement;
|
|
591
|
+
|
|
592
|
+
expect(nameLine.children).toHaveLength(1);
|
|
593
|
+
expect(nameLine).toHaveTextContent(/^wb-0660-kds01\.wbhq\.com$/);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
test("the dialog's fresh read selects the NetBIOS setting the explanation needs", async () => {
|
|
597
|
+
await renderPage();
|
|
598
|
+
await openReviewOf(reporterScan());
|
|
599
|
+
|
|
600
|
+
expect(getItemSpy).toHaveBeenCalledTimes(1);
|
|
601
|
+
expect(getItemSpy.mock.calls[0]![0].select).toMatchObject({
|
|
602
|
+
status: true,
|
|
603
|
+
probeId: true,
|
|
604
|
+
isSnmpEnabled: true,
|
|
605
|
+
isNetbiosLookupEnabled: true,
|
|
606
|
+
discoveredDevices: true,
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
test("asking why does not select, deselect or import anything", async () => {
|
|
611
|
+
await renderPage();
|
|
612
|
+
await openReviewOf(reporterScan());
|
|
613
|
+
|
|
614
|
+
expect(checkbox("10.18.166.51")).toBeChecked();
|
|
615
|
+
|
|
616
|
+
fireEvent.click(unnamedHint("10.18.166.51"));
|
|
617
|
+
fireEvent.keyDown(unnamedHint("10.18.166.51"), { key: "Enter" });
|
|
618
|
+
|
|
619
|
+
expect(checkbox("10.18.166.51")).toBeChecked();
|
|
620
|
+
expect(createSpy).not.toHaveBeenCalled();
|
|
621
|
+
expect(
|
|
622
|
+
screen.getByRole("button", { name: /Import Selected/ }),
|
|
623
|
+
).toHaveTextContent("Import Selected (5)");
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
test("the explanation opens on keyboard focus too", async () => {
|
|
627
|
+
await renderPage();
|
|
628
|
+
await openReviewOf(reporterScan());
|
|
629
|
+
|
|
630
|
+
const button: HTMLElement = unnamedHint("10.18.166.54");
|
|
631
|
+
|
|
632
|
+
act(() => {
|
|
633
|
+
button.focus();
|
|
634
|
+
});
|
|
635
|
+
await act(async () => {
|
|
636
|
+
jest.advanceTimersByTime(200);
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
expect(screen.getByRole("tooltip")).toHaveTextContent(
|
|
640
|
+
REVERSE_DNS_NOT_RECORDED_SENTENCE,
|
|
641
|
+
);
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
test("the unnamed hosts still import under their address, exactly as before", async () => {
|
|
645
|
+
await renderPage();
|
|
646
|
+
await openReviewOf(reporterScan());
|
|
647
|
+
|
|
648
|
+
fireEvent.click(screen.getByRole("button", { name: /Import Selected/ }));
|
|
649
|
+
await waitFor(() => {
|
|
650
|
+
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
const names: Array<string> = createSpy.mock.calls.map(
|
|
654
|
+
(call: Array<{ model: { name?: string } }>): string => {
|
|
655
|
+
return String(call[0]!.model.name);
|
|
656
|
+
},
|
|
657
|
+
);
|
|
658
|
+
|
|
659
|
+
expect(names).toEqual([
|
|
660
|
+
"wb-0660-kds01.wbhq.com",
|
|
661
|
+
"10.18.166.51",
|
|
662
|
+
"wb-0660-kds02.wbhq.com",
|
|
663
|
+
"10.18.166.53",
|
|
664
|
+
"10.18.166.54",
|
|
665
|
+
]);
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
/*
|
|
670
|
+
* A row with no NetBIOS code, on a scan with NetBIOS turned ON. Either the
|
|
671
|
+
* probe predates the codes, or it is a GLOBAL probe — which never sends
|
|
672
|
+
* NetBIOS queries, and which is what the bundled self-hosted probe-1 and
|
|
673
|
+
* probe-2 register as. The dialog can only tell those apart from the probe
|
|
674
|
+
* list the page loaded, matched to the scan's probe; the probe used to record
|
|
675
|
+
* the refusal in a debug log and nowhere else.
|
|
676
|
+
*/
|
|
677
|
+
describe("a row with no NetBIOS code says whether the scan's probe could ever have asked", () => {
|
|
678
|
+
const LEGACY_PING_ONLY: DiscoveredNetworkDevice = {
|
|
679
|
+
ipAddress: "10.18.166.60",
|
|
680
|
+
snmpReachable: false,
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
function netbiosOnScan(
|
|
684
|
+
probeId: ObjectID = PROBE_ID,
|
|
685
|
+
id: ObjectID = SCAN_ID,
|
|
686
|
+
): NetworkDeviceDiscoveryScan {
|
|
687
|
+
return reviewScan({
|
|
688
|
+
hosts: [LEGACY_PING_ONLY],
|
|
689
|
+
isSnmpEnabled: true,
|
|
690
|
+
isNetbiosLookupEnabled: true,
|
|
691
|
+
probeId: probeId,
|
|
692
|
+
id: id,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const GLOBAL_PROBE_SENTENCE: string = "global probes never send NetBIOS";
|
|
697
|
+
|
|
698
|
+
test("on a global probe, the row says NetBIOS was never going to be asked", async () => {
|
|
699
|
+
getAllProbesSpy.mockResolvedValue([probe(PROBE_ID, true)]);
|
|
700
|
+
await renderPage();
|
|
701
|
+
await openReviewOf(netbiosOnScan());
|
|
702
|
+
|
|
703
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
704
|
+
|
|
705
|
+
expect(text).toBe(
|
|
706
|
+
expectedExplanation({
|
|
707
|
+
host: LEGACY_PING_ONLY,
|
|
708
|
+
scan: netbiosOnScan(),
|
|
709
|
+
isGlobalProbe: true,
|
|
710
|
+
}).text,
|
|
711
|
+
);
|
|
712
|
+
expect(text).toContain(GLOBAL_PROBE_SENTENCE);
|
|
713
|
+
expect(text).not.toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
test("on a project probe, the same row says only that no NetBIOS name was recorded", async () => {
|
|
717
|
+
getAllProbesSpy.mockResolvedValue([probe(PROBE_ID, false)]);
|
|
718
|
+
await renderPage();
|
|
719
|
+
await openReviewOf(netbiosOnScan());
|
|
720
|
+
|
|
721
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
722
|
+
|
|
723
|
+
expect(text).toBe(
|
|
724
|
+
expectedExplanation({
|
|
725
|
+
host: LEGACY_PING_ONLY,
|
|
726
|
+
scan: netbiosOnScan(),
|
|
727
|
+
isGlobalProbe: false,
|
|
728
|
+
}).text,
|
|
729
|
+
);
|
|
730
|
+
expect(text).toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
731
|
+
expect(text).not.toContain(GLOBAL_PROBE_SENTENCE);
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
test("a global probe that is NOT the scan's probe changes nothing", async () => {
|
|
735
|
+
/*
|
|
736
|
+
* Matched by id: the page's probe list holds global probes as a matter of
|
|
737
|
+
* course, and one of them existing says nothing about the probe this
|
|
738
|
+
* scan ran on.
|
|
739
|
+
*/
|
|
740
|
+
getAllProbesSpy.mockResolvedValue([
|
|
741
|
+
probe(OTHER_PROBE_ID, true),
|
|
742
|
+
probe(PROBE_ID, false),
|
|
743
|
+
]);
|
|
744
|
+
await renderPage();
|
|
745
|
+
await openReviewOf(netbiosOnScan());
|
|
746
|
+
|
|
747
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
748
|
+
|
|
749
|
+
expect(text).toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
750
|
+
expect(text).not.toContain(GLOBAL_PROBE_SENTENCE);
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
test("a probe the page does not know is not assumed to be global", async () => {
|
|
754
|
+
/*
|
|
755
|
+
* Deleted since the scan ran, say. Unknown costs the row the more
|
|
756
|
+
* specific sentence; it must never buy it a wrong one.
|
|
757
|
+
*/
|
|
758
|
+
getAllProbesSpy.mockResolvedValue([probe(OTHER_PROBE_ID, true)]);
|
|
759
|
+
await renderPage();
|
|
760
|
+
await openReviewOf(netbiosOnScan());
|
|
761
|
+
|
|
762
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
763
|
+
|
|
764
|
+
expect(text).toBe(
|
|
765
|
+
expectedExplanation({
|
|
766
|
+
host: LEGACY_PING_ONLY,
|
|
767
|
+
scan: netbiosOnScan(),
|
|
768
|
+
isGlobalProbe: undefined,
|
|
769
|
+
}).text,
|
|
770
|
+
);
|
|
771
|
+
expect(text).toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
772
|
+
expect(text).not.toContain(GLOBAL_PROBE_SENTENCE);
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
test("the answer follows the scan under review, not the first scan reviewed", async () => {
|
|
776
|
+
/*
|
|
777
|
+
* The global-probe answer is worked out per render from the scan the
|
|
778
|
+
* dialog is showing. Reviewing a scan on a global probe and then one on
|
|
779
|
+
* a project probe must not carry the first answer over.
|
|
780
|
+
*/
|
|
781
|
+
getAllProbesSpy.mockResolvedValue([
|
|
782
|
+
probe(PROBE_ID, true),
|
|
783
|
+
probe(OTHER_PROBE_ID, false),
|
|
784
|
+
]);
|
|
785
|
+
await renderPage();
|
|
786
|
+
|
|
787
|
+
await openReviewOf(netbiosOnScan(PROBE_ID, SCAN_ID));
|
|
788
|
+
expect(await explanationShownFor("10.18.166.60")).toContain(
|
|
789
|
+
GLOBAL_PROBE_SENTENCE,
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
fireEvent.click(screen.getByText("Close review"));
|
|
793
|
+
await openReviewOf(netbiosOnScan(OTHER_PROBE_ID, OTHER_SCAN_ID));
|
|
794
|
+
|
|
795
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
796
|
+
|
|
797
|
+
expect(text).toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
798
|
+
expect(text).not.toContain(GLOBAL_PROBE_SENTENCE);
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
test("on a global probe with NetBIOS off, the row gets the global probe's explanation", async () => {
|
|
802
|
+
/*
|
|
803
|
+
* The global-probe answer reaches the explanation on a NetBIOS-off scan
|
|
804
|
+
* too, where it decides what the row is advised to turn on: a global
|
|
805
|
+
* probe would never send the queries, so the page must not leave the
|
|
806
|
+
* function believing it might. Compared to the function's own answer for
|
|
807
|
+
* a global probe, so the wording of that advice stays Common's to own.
|
|
808
|
+
*/
|
|
809
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
810
|
+
hosts: [LEGACY_PING_ONLY],
|
|
811
|
+
isSnmpEnabled: false,
|
|
812
|
+
isNetbiosLookupEnabled: false,
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
getAllProbesSpy.mockResolvedValue([probe(PROBE_ID, true)]);
|
|
816
|
+
await renderPage();
|
|
817
|
+
await openReviewOf(scan);
|
|
818
|
+
|
|
819
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
820
|
+
|
|
821
|
+
expect(text).toBe(
|
|
822
|
+
expectedExplanation({
|
|
823
|
+
host: LEGACY_PING_ONLY,
|
|
824
|
+
scan: scan,
|
|
825
|
+
isGlobalProbe: true,
|
|
826
|
+
}).text,
|
|
827
|
+
);
|
|
828
|
+
expect(text).toContain(SNMP_NOT_CHECKED_SENTENCE);
|
|
829
|
+
expect(text).toContain(NETBIOS_OFF_SENTENCE);
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
test("a per-host NetBIOS code wins over what the dialog would infer", async () => {
|
|
833
|
+
/*
|
|
834
|
+
* A newer probe stamps what actually happened. A host it queried that
|
|
835
|
+
* never replied says so, whatever the page believes about the probe.
|
|
836
|
+
*/
|
|
837
|
+
const queried: DiscoveredNetworkDevice = {
|
|
838
|
+
...LEGACY_PING_ONLY,
|
|
839
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.NoRecord,
|
|
840
|
+
netbiosNameStatus: DiscoveredHostNetbiosStatus.NoReply,
|
|
841
|
+
};
|
|
842
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
843
|
+
hosts: [queried],
|
|
844
|
+
isSnmpEnabled: true,
|
|
845
|
+
isNetbiosLookupEnabled: true,
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
getAllProbesSpy.mockResolvedValue([probe(PROBE_ID, false)]);
|
|
849
|
+
await renderPage();
|
|
850
|
+
await openReviewOf(scan);
|
|
851
|
+
|
|
852
|
+
const text: string = await explanationShownFor("10.18.166.60");
|
|
853
|
+
|
|
854
|
+
expect(text).toBe(
|
|
855
|
+
expectedExplanation({ host: queried, scan: scan, isGlobalProbe: false })
|
|
856
|
+
.text,
|
|
857
|
+
);
|
|
858
|
+
expect(text).toContain("UDP 137");
|
|
859
|
+
expect(text).not.toContain(NETBIOS_NOT_RECORDED_SENTENCE);
|
|
860
|
+
});
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
describe("what the row says depends on the scan's own state", () => {
|
|
864
|
+
test("a scan still sweeping says its hosts are not named YET", async () => {
|
|
865
|
+
/*
|
|
866
|
+
* Names are looked up after the sweep, so every host a running scan has
|
|
867
|
+
* uploaded so far is unnamed by construction — the question has not been
|
|
868
|
+
* asked, and the row must not read as though it had been.
|
|
869
|
+
*/
|
|
870
|
+
const host: DiscoveredNetworkDevice = {
|
|
871
|
+
ipAddress: "10.18.166.70",
|
|
872
|
+
snmpReachable: false,
|
|
873
|
+
};
|
|
874
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
875
|
+
hosts: [host],
|
|
876
|
+
status: DiscoveryScanStatus.InProgress,
|
|
877
|
+
statusMessage: "Swept 64 of 254 addresses.",
|
|
878
|
+
isSnmpEnabled: false,
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
await renderPage();
|
|
882
|
+
await openReviewOf(scan);
|
|
883
|
+
|
|
884
|
+
expect(rowOf("10.18.166.70")).toHaveTextContent(NOT_YET_NAMED_HOST_LABEL);
|
|
885
|
+
expect(rowOf("10.18.166.70")).not.toHaveTextContent(UNNAMED_HOST_LABEL);
|
|
886
|
+
expect(await explanationShownFor("10.18.166.70")).toBe(
|
|
887
|
+
IN_PROGRESS_EXPLANATION,
|
|
888
|
+
);
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
test("a failed scan says it stopped before names were looked up", async () => {
|
|
892
|
+
const host: DiscoveredNetworkDevice = {
|
|
893
|
+
ipAddress: "10.18.166.71",
|
|
894
|
+
snmpReachable: false,
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
await renderPage();
|
|
898
|
+
await openReviewOf(
|
|
899
|
+
reviewScan({ hosts: [host], status: DiscoveryScanStatus.Failed }),
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
expect(rowOf("10.18.166.71")).toHaveTextContent(UNNAMED_HOST_LABEL);
|
|
903
|
+
expect(await explanationShownFor("10.18.166.71")).toBe(
|
|
904
|
+
FAILED_SCAN_EXPLANATION,
|
|
905
|
+
);
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test("an SNMP responder with a blank sysName says it answered with no name", async () => {
|
|
909
|
+
const host: DiscoveredNetworkDevice = {
|
|
910
|
+
ipAddress: "10.18.166.72",
|
|
911
|
+
snmpReachable: true,
|
|
912
|
+
sysName: " ",
|
|
913
|
+
sysDescr: "Linux kds 5.10",
|
|
914
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.ServerFailure,
|
|
915
|
+
};
|
|
916
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
917
|
+
hosts: [host],
|
|
918
|
+
isSnmpEnabled: true,
|
|
919
|
+
isNetbiosLookupEnabled: false,
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
await renderPage();
|
|
923
|
+
await openReviewOf(scan);
|
|
924
|
+
|
|
925
|
+
const text: string = await explanationShownFor("10.18.166.72");
|
|
926
|
+
|
|
927
|
+
expect(text).toBe(
|
|
928
|
+
expectedExplanation({ host: host, scan: scan, isGlobalProbe: undefined })
|
|
929
|
+
.text,
|
|
930
|
+
);
|
|
931
|
+
expect(text.startsWith(SNMP_NO_SYSNAME_SENTENCE)).toBe(true);
|
|
932
|
+
expect(text).toContain("SERVFAIL");
|
|
933
|
+
expect(text).toContain(TRANSIENT_FAILURE_TIP);
|
|
934
|
+
});
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
describe("hosts with a name carry no hint at all", () => {
|
|
938
|
+
test("named by SNMP, by reverse DNS or by NetBIOS: no label and no (i)", async () => {
|
|
939
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
940
|
+
hosts: [
|
|
941
|
+
{ ipAddress: "10.0.0.1", snmpReachable: true, sysName: "core-sw-01" },
|
|
942
|
+
{
|
|
943
|
+
ipAddress: "10.0.0.2",
|
|
944
|
+
snmpReachable: false,
|
|
945
|
+
dnsHostname: "printer.corp.example.com",
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
ipAddress: "10.0.0.3",
|
|
949
|
+
snmpReachable: false,
|
|
950
|
+
netbiosName: "accounts-pc01",
|
|
951
|
+
},
|
|
952
|
+
/*
|
|
953
|
+
* A name AND a stale code: a host an earlier pass could not name and
|
|
954
|
+
* a later one did. The name is what counts, so no hint.
|
|
955
|
+
*/
|
|
956
|
+
{
|
|
957
|
+
ipAddress: "10.0.0.4",
|
|
958
|
+
snmpReachable: false,
|
|
959
|
+
dnsHostname: "kds04.corp.example.com",
|
|
960
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.Timeout,
|
|
961
|
+
},
|
|
962
|
+
],
|
|
963
|
+
isSnmpEnabled: true,
|
|
964
|
+
isNetbiosLookupEnabled: true,
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
await renderPage();
|
|
968
|
+
await openReviewOf(scan);
|
|
969
|
+
|
|
970
|
+
for (const ipAddress of ["10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4"]) {
|
|
971
|
+
expect(checkbox(ipAddress)).toBeInTheDocument();
|
|
972
|
+
expect(queryUnnamedHint(ipAddress)).not.toBeInTheDocument();
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
expect(
|
|
976
|
+
screen.queryAllByRole("button", { name: UNNAMED_HINT_NAME }),
|
|
977
|
+
).toHaveLength(0);
|
|
978
|
+
expect(screen.queryByText(UNNAMED_HOST_LABEL)).not.toBeInTheDocument();
|
|
979
|
+
expect(
|
|
980
|
+
screen.queryByText(NOT_YET_NAMED_HOST_LABEL),
|
|
981
|
+
).not.toBeInTheDocument();
|
|
982
|
+
});
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
/*
|
|
986
|
+
* The tooltip is fixed copy picked by whitelisted codes. A scanned network
|
|
987
|
+
* chooses its PTR records, its NetBIOS answers and its sysDescr, and a probe
|
|
988
|
+
* (or anything that can write the jsonb) chooses the code strings — none of
|
|
989
|
+
* that may be rendered in the explanation.
|
|
990
|
+
*/
|
|
991
|
+
describe("nothing the scanned network chose reaches the tooltip", () => {
|
|
992
|
+
test("rejected names and a hostile sysDescr leave the host unnamed, and out of the text", async () => {
|
|
993
|
+
const HOSTILE: string = "<img src=x onerror=alert(1)>";
|
|
994
|
+
const host: DiscoveredNetworkDevice = {
|
|
995
|
+
ipAddress: "10.0.0.9",
|
|
996
|
+
snmpReachable: true,
|
|
997
|
+
sysDescr: `evil ${HOSTILE}`,
|
|
998
|
+
dnsHostname: HOSTILE,
|
|
999
|
+
netbiosName: HOSTILE,
|
|
1000
|
+
dnsHostnameStatus: DiscoveredHostReverseDnsStatus.UnusableName,
|
|
1001
|
+
};
|
|
1002
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
1003
|
+
hosts: [host],
|
|
1004
|
+
isSnmpEnabled: true,
|
|
1005
|
+
isNetbiosLookupEnabled: true,
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
await renderPage();
|
|
1009
|
+
await openReviewOf(scan);
|
|
1010
|
+
|
|
1011
|
+
// Unnamed: every name it offered was rejected.
|
|
1012
|
+
expect(checkbox("10.0.0.9")).toHaveAttribute(
|
|
1013
|
+
"aria-label",
|
|
1014
|
+
"Import 10.0.0.9 (10.0.0.9)",
|
|
1015
|
+
);
|
|
1016
|
+
|
|
1017
|
+
const text: string = await explanationShownFor("10.0.0.9");
|
|
1018
|
+
|
|
1019
|
+
expect(text).toBe(
|
|
1020
|
+
expectedExplanation({ host: host, scan: scan, isGlobalProbe: undefined })
|
|
1021
|
+
.text,
|
|
1022
|
+
);
|
|
1023
|
+
expect(text).not.toContain("onerror");
|
|
1024
|
+
expect(text).not.toContain("<img");
|
|
1025
|
+
expect(text).not.toContain("evil");
|
|
1026
|
+
expect(text).toContain("not a valid hostname");
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
test("a code that is not one of ours is dropped, and the row falls back to what the scan supports", async () => {
|
|
1030
|
+
const host: DiscoveredNetworkDevice = {
|
|
1031
|
+
ipAddress: "10.0.0.10",
|
|
1032
|
+
snmpReachable: false,
|
|
1033
|
+
};
|
|
1034
|
+
// Written straight into the jsonb, past the type system.
|
|
1035
|
+
(host as unknown as Record<string, unknown>)["dnsHostnameStatus"] =
|
|
1036
|
+
"<b>call 555-0100</b>";
|
|
1037
|
+
(host as unknown as Record<string, unknown>)["netbiosNameStatus"] = 7;
|
|
1038
|
+
|
|
1039
|
+
const scan: NetworkDeviceDiscoveryScan = reviewScan({
|
|
1040
|
+
hosts: [host],
|
|
1041
|
+
isSnmpEnabled: false,
|
|
1042
|
+
isNetbiosLookupEnabled: false,
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
await renderPage();
|
|
1046
|
+
await openReviewOf(scan);
|
|
1047
|
+
|
|
1048
|
+
const text: string = await explanationShownFor("10.0.0.10");
|
|
1049
|
+
|
|
1050
|
+
expect(text).toBe(
|
|
1051
|
+
[
|
|
1052
|
+
SNMP_NOT_CHECKED_SENTENCE,
|
|
1053
|
+
REVERSE_DNS_NOT_RECORDED_SENTENCE,
|
|
1054
|
+
NETBIOS_OFF_SENTENCE,
|
|
1055
|
+
ASK_THE_DEVICE_TIP,
|
|
1056
|
+
].join(" "),
|
|
1057
|
+
);
|
|
1058
|
+
expect(text).not.toContain("555-0100");
|
|
1059
|
+
expect(text).not.toContain("<b>");
|
|
1060
|
+
});
|
|
1061
|
+
});
|