@oneuptime/common 12.0.31 → 12.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/Span.ts +14 -0
- package/Models/DatabaseModels/AlertState.ts +0 -2
- package/Models/DatabaseModels/Domain.ts +1 -1
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/Incident.ts +1 -1
- package/Models/DatabaseModels/IncidentTemplate.ts +1 -1
- package/Models/DatabaseModels/Index.ts +12 -0
- package/Models/DatabaseModels/MetricType.ts +0 -2
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/MonitorStatusTimeline.ts +0 -2
- package/Models/DatabaseModels/MonitorTest.ts +0 -2
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +297 -3
- package/Models/DatabaseModels/NetworkDeviceOidTemplate.ts +3 -1
- package/Models/DatabaseModels/NetworkDeviceRole.ts +648 -0
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -1
- package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -1
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +0 -2
- package/Models/DatabaseModels/StatusPageAnnouncementTemplate.ts +0 -2
- package/Models/DatabaseModels/StatusPagePrivateUser.ts +0 -2
- package/Models/DatabaseModels/StatusPageResource.ts +0 -2
- package/Models/DatabaseModels/StatusPageSubscriber.ts +0 -2
- package/Models/DatabaseModels/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- package/Server/EnvironmentConfig.ts +14 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.ts +72 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Infrastructure/QueueWorker.ts +38 -8
- package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
- package/Server/Middleware/ProjectAuthorization.ts +11 -0
- package/Server/Middleware/SCIMAuthorization.ts +12 -0
- package/Server/Middleware/TelemetryIngest.ts +11 -0
- package/Server/Services/AIBillingService.ts +101 -27
- package/Server/Services/DatabaseService.ts +39 -9
- package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/Index.ts +12 -0
- package/Server/Services/MonitorService.ts +143 -21
- package/Server/Services/MonitorStatusTimelineService.ts +150 -8
- package/Server/Services/MonitorTemplateService.ts +217 -1
- package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
- package/Server/Services/NetworkAlertPolicyService.ts +944 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
- package/Server/Services/NetworkDeviceRoleService.ts +90 -0
- package/Server/Services/NetworkDeviceService.ts +1032 -73
- package/Server/Services/NetworkSiteService.ts +1502 -129
- package/Server/Services/NetworkSiteTypeService.ts +1216 -0
- package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
- package/Server/Services/NotificationService.ts +118 -28
- package/Server/Services/ProjectService.ts +186 -44
- package/Server/Services/StatusPagePrivateUserService.ts +103 -3
- package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
- package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
- package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
- package/Server/Services/UserNotificationSettingService.ts +62 -31
- package/Server/Services/UserService.ts +95 -0
- package/Server/Types/Database/QueryHelper.ts +2 -2
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
- package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
- package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
- package/Server/Utils/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +8 -0
- package/Server/Utils/Logger.ts +79 -1
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
- package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -0
- package/Server/Utils/StartServer.ts +51 -19
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
- package/Server/Utils/Telemetry.ts +198 -51
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +158 -27
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +35 -8
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +107 -3
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DashboardWideChartZoom.test.tsx +401 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
- package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
- package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +318 -0
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
- package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +357 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
- package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
- package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
- package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +626 -0
- package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
- package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
- package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
- package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
- package/Tests/App/Dashboard/SideMenuHarness.tsx +11 -3
- package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
- package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/Models/DatabaseModels/ModelRegistryInvariants.test.ts +115 -41
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
- package/Tests/Server/Infrastructure/Postgres/NetworkDeviceRoleTableMigration.test.ts +476 -0
- package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
- package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- package/Tests/Server/Services/DatabaseServiceGenerateSlug.test.ts +215 -0
- package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
- package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
- package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
- package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
- package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
- package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
- package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
- package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
- package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
- package/Tests/Server/Services/NetworkDeviceRoleModel.test.ts +672 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +1 -1
- package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
- package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
- package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
- package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
- package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +67 -4
- package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberEndTime.test.ts +369 -0
- package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
- package/Tests/Server/Services/UserNotificationSettingMonitorDefaults.test.ts +248 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +145 -3
- package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
- package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
- package/Tests/Server/Utils/BasicCron.test.ts +283 -0
- package/Tests/Server/Utils/Captcha.test.ts +422 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
- package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +174 -0
- package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
- package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
- package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
- package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
- package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
- package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
- package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
- package/Tests/Server/Utils/Telemetry.test.ts +456 -66
- package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
- package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
- package/Tests/Types/NetworkDevice/DefaultNetworkDeviceRole.test.ts +417 -0
- package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
- package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
- package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- package/Tests/UI/Components/Charts/ChartClickDoubleClickDisambiguation.test.tsx +221 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickReset.test.tsx +220 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +751 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +475 -43
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +89 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +103 -8
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/SideMenuItem.test.tsx +256 -4
- package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
- package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
- package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
- package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
- package/Tests/UI/Utils/TableColumnsToCsv.test.ts +30 -0
- package/Tests/UI/Utils/UseDashboardTimeRangeZoom.test.tsx +187 -0
- package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +302 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +242 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleCatalog.test.ts +981 -0
- package/Tests/Utils/Monitor/NetworkTopologyRoleCatalog.test.ts +865 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
- package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
- package/Tests/Utils/NetworkDevice/DeviceRoleKeyUtil.test.ts +538 -0
- package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
- package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
- package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
- package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
- package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
- package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
- package/Tests/Utils/Slo/SloEvaluation.test.ts +171 -0
- package/Tests/Utils/Slug.test.ts +61 -1
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
- package/Tests/jest.setup.ts +19 -0
- package/Types/AI/ExceptionAIClassification.ts +10 -24
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
- package/Types/Exception/ApiException.ts +10 -0
- package/Types/Exception/BadDataException.ts +11 -0
- package/Types/Exception/BadRequestException.ts +11 -0
- package/Types/Exception/Exception.ts +65 -0
- package/Types/Exception/ForbiddenException.ts +10 -0
- package/Types/Exception/NotAuthenticatedException.ts +10 -0
- package/Types/Exception/NotAuthorizedException.ts +10 -0
- package/Types/Exception/NotFoundException.ts +11 -0
- package/Types/Exception/PayloadTooLargeException.ts +11 -0
- package/Types/Exception/PaymentRequiredException.ts +10 -0
- package/Types/Exception/ServiceUnavailableException.ts +10 -0
- package/Types/Exception/SsoAuthorizationException.ts +10 -0
- package/Types/Exception/TenantNotFoundException.ts +11 -0
- package/Types/Exception/TimeoutException.ts +10 -0
- package/Types/Exception/TooManyRequestsException.ts +10 -0
- package/Types/Exception/UnableToReachServer.ts +10 -0
- package/Types/Exception/WebsiteRequestException.ts +10 -0
- package/Types/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
- package/Types/Monitor/MonitorMetricType.ts +71 -0
- package/Types/Monitor/MonitorStep.ts +76 -0
- package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
- package/Types/Monitor/MonitorType.ts +47 -1
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +61 -0
- package/Types/Monitor/SqlConnectionConfig.ts +31 -0
- package/Types/NetworkDevice/DefaultNetworkDeviceRole.ts +145 -0
- package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
- package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
- package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
- package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
- package/Types/Permission.ts +135 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -0
- package/Types/Telemetry/ErrorClass.ts +274 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +7 -0
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -0
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +9 -1
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +97 -35
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +14 -0
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +97 -35
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +13 -0
- package/UI/Components/Charts/Line/LineChart.tsx +7 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +50 -15
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/Navbar/NavBar.tsx +62 -13
- package/UI/Components/Navbar/NavBarMenuModal.tsx +7 -2
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +2 -0
- package/UI/Components/SideMenu/SideMenu.tsx +135 -7
- package/UI/Components/SideMenu/SideMenuItem.tsx +80 -85
- package/UI/Components/SideMenu/SideMenuSection.tsx +69 -25
- package/UI/Components/SideOver/SideOver.tsx +21 -20
- package/UI/Utils/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/UI/Utils/UseDashboardTimeRangeZoom.ts +77 -0
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +118 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkDeviceRoleCatalog.ts +232 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +2 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +139 -36
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- package/Utils/NetworkDevice/DeviceRoleKeyUtil.ts +137 -0
- package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
- package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
- package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
- package/Utils/Rules/RulePatternMatchUtil.ts +1 -1
- package/Utils/Slug.ts +34 -1
- package/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertState.js +0 -2
- package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Domain.js +1 -1
- package/build/dist/Models/DatabaseModels/Domain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +12 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MetricType.js +0 -2
- package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +0 -2
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTest.js +0 -2
- package/build/dist/Models/DatabaseModels/MonitorTest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +304 -4
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js +3 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js +677 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +0 -2
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js +0 -2
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +0 -2
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +0 -2
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +0 -2
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -13
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +12 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js +39 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIBillingService.js +70 -16
- package/build/dist/Server/Services/AIBillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +31 -5
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +119 -21
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceRoleService.js +70 -0
- package/build/dist/Server/Services/NetworkDeviceRoleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
- package/build/dist/Server/Services/NotificationService.js +80 -17
- package/build/dist/Server/Services/NotificationService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +131 -30
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +46 -21
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +90 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +8 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +63 -1
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +38 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
- package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
- package/build/dist/Types/Exception/ApiException.js +9 -0
- package/build/dist/Types/Exception/ApiException.js.map +1 -1
- package/build/dist/Types/Exception/BadDataException.js +10 -0
- package/build/dist/Types/Exception/BadDataException.js.map +1 -1
- package/build/dist/Types/Exception/BadRequestException.js +10 -0
- package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
- package/build/dist/Types/Exception/Exception.js +56 -0
- package/build/dist/Types/Exception/Exception.js.map +1 -1
- package/build/dist/Types/Exception/ForbiddenException.js +9 -0
- package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
- package/build/dist/Types/Exception/NotFoundException.js +10 -0
- package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
- package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
- package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
- package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
- package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
- package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
- package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/TimeoutException.js +9 -0
- package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
- package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
- package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
- package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
- package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
- package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +54 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +45 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
- package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
- package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js +105 -0
- package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
- package/build/dist/Types/Permission.js +120 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +6 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +79 -31
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +7 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +79 -31
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +14 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -0
- 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 +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +39 -13
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +44 -9
- 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/ProgressBar/ProgressBar.js +12 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +76 -11
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +50 -54
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +32 -9
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +31 -3
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +42 -1
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
- package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
- package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js +42 -0
- package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +74 -0
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js +126 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +2 -1
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +75 -35
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js +114 -0
- package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
- package/build/dist/Utils/Rules/RulePatternMatchUtil.js +1 -1
- package/build/dist/Utils/Slug.js +31 -1
- package/build/dist/Utils/Slug.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { cleanup, render, waitFor } from "@testing-library/react";
|
|
3
|
+
import React, { ReactElement } from "react";
|
|
4
|
+
import { MemoryRouter } from "react-router-dom";
|
|
5
|
+
import {
|
|
6
|
+
afterEach,
|
|
7
|
+
beforeEach,
|
|
8
|
+
describe,
|
|
9
|
+
expect,
|
|
10
|
+
jest,
|
|
11
|
+
test,
|
|
12
|
+
} from "@jest/globals";
|
|
13
|
+
import NetworkSite from "../../../Models/DatabaseModels/NetworkSite";
|
|
14
|
+
import NetworkSnmpCredentialProfile from "../../../Models/DatabaseModels/NetworkSnmpCredentialProfile";
|
|
15
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
16
|
+
import FormFieldSchemaType from "../../../UI/Components/Forms/Types/FormFieldSchemaType";
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* WHY THIS FILE EXISTS
|
|
20
|
+
*
|
|
21
|
+
* Registering a device asks what the device IS, and the two answers it cannot
|
|
22
|
+
* work without are the address and the PROBE that can reach it. A device with
|
|
23
|
+
* no probe is not polled by anything: it is created, it sits on Pending
|
|
24
|
+
* wearing "No probe", and nobody finds out until somebody wonders why a
|
|
25
|
+
* switch has no interfaces. So the probe is required here — and because
|
|
26
|
+
* requiring a field an operator cannot answer is just a wall, the form
|
|
27
|
+
* answers it for them wherever it honestly can:
|
|
28
|
+
*
|
|
29
|
+
* 1. the selected site's own default probe (the site exists to hold it),
|
|
30
|
+
* 2. otherwise the project's single non-global probe, when there is exactly
|
|
31
|
+
* one — a question with one possible answer is not a question,
|
|
32
|
+
* 3. otherwise empty, and the operator picks.
|
|
33
|
+
*
|
|
34
|
+
* Every property that makes step 1 SAFE is invisible on screen: it is one
|
|
35
|
+
* request per site id and not one per keystroke, it is remembered so that
|
|
36
|
+
* re-opening the form or flipping between two sites costs nothing, a site
|
|
37
|
+
* with no probe is remembered as such, and it never overwrites a probe the
|
|
38
|
+
* operator picked themselves.
|
|
39
|
+
*
|
|
40
|
+
* The SNMP step is the other half. It stays, it is optional, and it now
|
|
41
|
+
* offers the credential PROFILE beside the device's own credentials — the
|
|
42
|
+
* same either/or the Settings page offers, in the same words, because a
|
|
43
|
+
* device created here and a device edited there have to end up describing
|
|
44
|
+
* their credentials the same way.
|
|
45
|
+
*
|
|
46
|
+
* ModelTable is replaced by a prop recorder — the point is what the page
|
|
47
|
+
* hands it, not re-testing the table (the same approach as
|
|
48
|
+
* NetworkDeviceBulkDelete.test.tsx).
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
jest.mock("react-i18next", () => {
|
|
52
|
+
return {
|
|
53
|
+
useTranslation: () => {
|
|
54
|
+
return {
|
|
55
|
+
t: (key: string): string => {
|
|
56
|
+
return key;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
jest.mock("../../../UI/Utils/Permission", () => {
|
|
64
|
+
return {
|
|
65
|
+
__esModule: true,
|
|
66
|
+
default: {
|
|
67
|
+
getAllPermissions: () => {
|
|
68
|
+
return [];
|
|
69
|
+
},
|
|
70
|
+
getProjectPermissions: () => {
|
|
71
|
+
return [];
|
|
72
|
+
},
|
|
73
|
+
getGlobalPermissions: () => {
|
|
74
|
+
return [];
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
jest.mock("../../../UI/Utils/User", () => {
|
|
81
|
+
return {
|
|
82
|
+
__esModule: true,
|
|
83
|
+
default: {
|
|
84
|
+
isMasterAdmin: () => {
|
|
85
|
+
return false;
|
|
86
|
+
},
|
|
87
|
+
getUserId: () => {
|
|
88
|
+
return null;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const SITE_ID: string = "77777777-0000-4000-8000-000000000001";
|
|
95
|
+
const OTHER_SITE_ID: string = "77777777-0000-4000-8000-000000000002";
|
|
96
|
+
const SITE_PROBE_ID: string = "88888888-0000-4000-8000-000000000001";
|
|
97
|
+
const OTHER_PROBE_ID: string = "88888888-0000-4000-8000-000000000002";
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
* The probe list the page fetches on mount, and the site rows the create form
|
|
101
|
+
* looks up. Both are `let`s with the `mock` prefix so the hoisted factories
|
|
102
|
+
* below may close over them and each test can set what this project owns.
|
|
103
|
+
*/
|
|
104
|
+
type ProbeRow = {
|
|
105
|
+
_id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
isGlobalProbe?: boolean | undefined;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
let mockProbeList: Array<ProbeRow> = [];
|
|
111
|
+
|
|
112
|
+
type GetItemRequest = {
|
|
113
|
+
modelType: unknown;
|
|
114
|
+
id: ObjectID;
|
|
115
|
+
select: Record<string, unknown>;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const mockGetItemCalls: Array<GetItemRequest> = [];
|
|
119
|
+
|
|
120
|
+
let mockGetItem: (
|
|
121
|
+
request: GetItemRequest,
|
|
122
|
+
) => Promise<unknown> = (): Promise<unknown> => {
|
|
123
|
+
return Promise.resolve(null);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
127
|
+
return {
|
|
128
|
+
__esModule: true,
|
|
129
|
+
default: {
|
|
130
|
+
getItem: (request: GetItemRequest): Promise<unknown> => {
|
|
131
|
+
mockGetItemCalls.push(request);
|
|
132
|
+
return mockGetItem(request);
|
|
133
|
+
},
|
|
134
|
+
getList: () => {
|
|
135
|
+
return Promise.resolve({ data: [], count: 0 });
|
|
136
|
+
},
|
|
137
|
+
// The unbound-devices banner counts on mount; not what this file is about.
|
|
138
|
+
count: () => {
|
|
139
|
+
return Promise.resolve(0);
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
jest.mock("../../../../App/FeatureSet/Dashboard/src/Utils/Probe", () => {
|
|
146
|
+
return {
|
|
147
|
+
__esModule: true,
|
|
148
|
+
default: {
|
|
149
|
+
getAllProbes: async () => {
|
|
150
|
+
return mockProbeList;
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
* The facet bar fetches sites, labels and probes on mount and owns the query
|
|
158
|
+
* the table is given. None of that is what these tests are about.
|
|
159
|
+
*/
|
|
160
|
+
jest.mock(
|
|
161
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/ResourceOwners/useResourceOwners",
|
|
162
|
+
() => {
|
|
163
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
164
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/ResourceOwners/useResourceOwners",
|
|
165
|
+
) as Record<string, unknown>;
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
...actual,
|
|
169
|
+
__esModule: true,
|
|
170
|
+
default: () => {
|
|
171
|
+
return {
|
|
172
|
+
filterBar: null,
|
|
173
|
+
mergeFiltersIntoQuery: (
|
|
174
|
+
base: Record<string, unknown> | undefined,
|
|
175
|
+
) => {
|
|
176
|
+
return base || {};
|
|
177
|
+
},
|
|
178
|
+
hasActiveFilters: false,
|
|
179
|
+
facetSelections: {},
|
|
180
|
+
facetOperators: {},
|
|
181
|
+
setFacetSelection: () => {
|
|
182
|
+
// no-op
|
|
183
|
+
},
|
|
184
|
+
clearAllFacets: () => {
|
|
185
|
+
// no-op
|
|
186
|
+
},
|
|
187
|
+
facetSaveState: {},
|
|
188
|
+
restoreFacetState: () => {
|
|
189
|
+
// no-op
|
|
190
|
+
},
|
|
191
|
+
getOwnersForResource: () => {
|
|
192
|
+
return [];
|
|
193
|
+
},
|
|
194
|
+
isLoadingOwners: false,
|
|
195
|
+
onResourcesFetched: () => {
|
|
196
|
+
// no-op
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
jest.mock("../../../UI/Components/BulkUpdate/BulkLabelActions", () => {
|
|
205
|
+
return {
|
|
206
|
+
__esModule: true,
|
|
207
|
+
default: () => {
|
|
208
|
+
return { bulkActions: [], modals: null };
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
jest.mock(
|
|
214
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/useBulkOidTemplateActions",
|
|
215
|
+
() => {
|
|
216
|
+
return {
|
|
217
|
+
__esModule: true,
|
|
218
|
+
default: () => {
|
|
219
|
+
return { bulkActions: [], modals: null };
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
/*
|
|
226
|
+
* Stubbed to a recognisable button, so "the page mounts the hook" and "the
|
|
227
|
+
* page puts its actions on the table" are one assertion rather than a source
|
|
228
|
+
* grep that a rename would walk straight past.
|
|
229
|
+
*/
|
|
230
|
+
jest.mock(
|
|
231
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/useBulkSnmpCredentialProfileActions",
|
|
232
|
+
() => {
|
|
233
|
+
return {
|
|
234
|
+
__esModule: true,
|
|
235
|
+
default: () => {
|
|
236
|
+
return {
|
|
237
|
+
bulkActions: [{ title: "Set SNMP Credential Profile" }],
|
|
238
|
+
modals: null,
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
jest.mock(
|
|
246
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/DeviceSummaryCards",
|
|
247
|
+
() => {
|
|
248
|
+
return {
|
|
249
|
+
__esModule: true,
|
|
250
|
+
default: () => {
|
|
251
|
+
return null;
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
},
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
type FormValuesLike = Record<string, unknown>;
|
|
258
|
+
|
|
259
|
+
type SetFormValuesFunction = (values: FormValuesLike) => void;
|
|
260
|
+
|
|
261
|
+
type CapturedFormField = {
|
|
262
|
+
field?: Record<string, unknown> | undefined;
|
|
263
|
+
overrideFieldKey?: string | undefined;
|
|
264
|
+
title?: string | undefined;
|
|
265
|
+
stepId?: string | undefined;
|
|
266
|
+
description?: string | undefined;
|
|
267
|
+
sectionTitle?: string | undefined;
|
|
268
|
+
sectionDescription?: string | undefined;
|
|
269
|
+
placeholder?: string | undefined;
|
|
270
|
+
fieldType?: FormFieldSchemaType | undefined;
|
|
271
|
+
defaultValue?: unknown;
|
|
272
|
+
dropdownModal?: { type: unknown } | undefined;
|
|
273
|
+
sideLink?: { text: string; url: unknown } | undefined;
|
|
274
|
+
required?: boolean | ((values: FormValuesLike) => boolean) | undefined;
|
|
275
|
+
showIf?: ((values: FormValuesLike) => boolean) | undefined;
|
|
276
|
+
onChange?:
|
|
277
|
+
| ((
|
|
278
|
+
value: unknown,
|
|
279
|
+
currentFormValues: FormValuesLike,
|
|
280
|
+
setNewFormValues: SetFormValuesFunction,
|
|
281
|
+
) => void)
|
|
282
|
+
| undefined;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
type CapturedFormStep = {
|
|
286
|
+
id: string;
|
|
287
|
+
title: string;
|
|
288
|
+
showIf?: ((values: FormValuesLike) => boolean) | undefined;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
type CapturedTableProps = {
|
|
292
|
+
formFields?: Array<CapturedFormField> | undefined;
|
|
293
|
+
formSteps?: Array<CapturedFormStep> | undefined;
|
|
294
|
+
bulkActions?:
|
|
295
|
+
| { buttons?: Array<{ title?: string | undefined }> | undefined }
|
|
296
|
+
| undefined;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
let capturedTableProps: CapturedTableProps | null = null;
|
|
300
|
+
|
|
301
|
+
jest.mock("../../../UI/Components/ModelTable/ModelTable", () => {
|
|
302
|
+
return {
|
|
303
|
+
__esModule: true,
|
|
304
|
+
default: (props: CapturedTableProps) => {
|
|
305
|
+
capturedTableProps = props;
|
|
306
|
+
return null;
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
import NetworkDevicesPage from "../../../../App/FeatureSet/Dashboard/src/Pages/NetworkDevice/Devices";
|
|
312
|
+
import PageComponentProps from "../../../../App/FeatureSet/Dashboard/src/Pages/PageComponentProps";
|
|
313
|
+
import {
|
|
314
|
+
PROBE_FIELD_DESCRIPTION,
|
|
315
|
+
SNMP_STEP_DESCRIPTION,
|
|
316
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/MonitoringMethodFormFields";
|
|
317
|
+
import Route from "../../../Types/API/Route";
|
|
318
|
+
|
|
319
|
+
const PAGE_PROPS: PageComponentProps = {
|
|
320
|
+
pageRoute: new Route("/dashboard/network-devices"),
|
|
321
|
+
currentProject: null,
|
|
322
|
+
hasPaymentMethod: true,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
async function renderDevicesPage(): Promise<CapturedTableProps> {
|
|
326
|
+
const Page: (props: PageComponentProps) => ReactElement =
|
|
327
|
+
NetworkDevicesPage as unknown as (
|
|
328
|
+
props: PageComponentProps,
|
|
329
|
+
) => ReactElement;
|
|
330
|
+
|
|
331
|
+
render(
|
|
332
|
+
<MemoryRouter>
|
|
333
|
+
<Page {...PAGE_PROPS} />
|
|
334
|
+
</MemoryRouter>,
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
await waitFor(() => {
|
|
338
|
+
expect(capturedTableProps).not.toBeNull();
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
return capturedTableProps!;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function fieldFor(props: CapturedTableProps, key: string): CapturedFormField {
|
|
345
|
+
const match: CapturedFormField | undefined = (props.formFields || []).find(
|
|
346
|
+
(field: CapturedFormField): boolean => {
|
|
347
|
+
return Object.keys(field.field || {})[0] === key;
|
|
348
|
+
},
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect({ key: key, found: Boolean(match) }).toEqual({
|
|
352
|
+
key: key,
|
|
353
|
+
found: true,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
return match!;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/** `required` the way FormField.tsx reads it: a boolean, or a callback. */
|
|
360
|
+
function isRequired(field: CapturedFormField, values: FormValuesLike): boolean {
|
|
361
|
+
if (typeof field.required === "function") {
|
|
362
|
+
return field.required(values);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return field.required === true;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function siteRow(probeId: string | undefined): NetworkSite {
|
|
369
|
+
const site: NetworkSite = new NetworkSite();
|
|
370
|
+
|
|
371
|
+
if (probeId) {
|
|
372
|
+
site.probeId = new ObjectID(probeId);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return site;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Pick a site the way the entity dropdown does — value first, then the form's
|
|
380
|
+
* own setFieldValue — and hand back whatever the field wrote afterwards.
|
|
381
|
+
*/
|
|
382
|
+
async function selectSite(data: {
|
|
383
|
+
props: CapturedTableProps;
|
|
384
|
+
siteId: string;
|
|
385
|
+
currentFormValues?: FormValuesLike | undefined;
|
|
386
|
+
expectWrite?: boolean | undefined;
|
|
387
|
+
}): Promise<Array<FormValuesLike>> {
|
|
388
|
+
const site: CapturedFormField = fieldFor(data.props, "site");
|
|
389
|
+
const writes: Array<FormValuesLike> = [];
|
|
390
|
+
|
|
391
|
+
expect(site.onChange).toBeDefined();
|
|
392
|
+
|
|
393
|
+
site.onChange!(
|
|
394
|
+
data.siteId,
|
|
395
|
+
data.currentFormValues || { name: "core-switch-01" },
|
|
396
|
+
(values: FormValuesLike): void => {
|
|
397
|
+
writes.push(values);
|
|
398
|
+
},
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
if (data.expectWrite === false) {
|
|
402
|
+
/*
|
|
403
|
+
* Nothing to wait FOR, so drain instead: a timer callback runs only once
|
|
404
|
+
* every queued microtask has, so the lookup and its handler have both
|
|
405
|
+
* finished by the time this resolves. Without it, "it wrote nothing"
|
|
406
|
+
* would pass simply by being asserted first.
|
|
407
|
+
*/
|
|
408
|
+
await new Promise<void>((resolve: () => void): void => {
|
|
409
|
+
setTimeout(resolve, 0);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
return writes;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
await waitFor(() => {
|
|
416
|
+
expect(writes.length).toBeGreaterThan(0);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
return writes;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
describe("the create form's Probe field", () => {
|
|
423
|
+
beforeEach(() => {
|
|
424
|
+
capturedTableProps = null;
|
|
425
|
+
mockGetItemCalls.length = 0;
|
|
426
|
+
mockProbeList = [{ _id: "probe-1", name: "Branch probe" }];
|
|
427
|
+
mockGetItem = (): Promise<unknown> => {
|
|
428
|
+
return Promise.resolve(siteRow(SITE_PROBE_ID));
|
|
429
|
+
};
|
|
430
|
+
window.localStorage.clear();
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
afterEach(() => {
|
|
434
|
+
cleanup();
|
|
435
|
+
jest.clearAllMocks();
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
/*
|
|
439
|
+
* The regression this file exists for. The probe used to be required only
|
|
440
|
+
* for an "SNMP" device and hidden for a monitor-backed one; this form
|
|
441
|
+
* creates neither kind of exception any more, so a device without a probe
|
|
442
|
+
* is simply a device nothing polls.
|
|
443
|
+
*/
|
|
444
|
+
test("is required for every device, and shown for every device", async () => {
|
|
445
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
446
|
+
const probe: CapturedFormField = fieldFor(props, "probe");
|
|
447
|
+
|
|
448
|
+
expect(isRequired(probe, { name: "core-switch-01" })).toBe(true);
|
|
449
|
+
// No showIf at all: there is no branch left that hides it.
|
|
450
|
+
expect(probe.showIf).toBeUndefined();
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
/*
|
|
454
|
+
* One sentence for the create form, the Settings page and the topology
|
|
455
|
+
* dialog. A private copy here is how "the probe polls this device via SNMP"
|
|
456
|
+
* survived on one surface after ping-first polling made it false.
|
|
457
|
+
*/
|
|
458
|
+
test("explains itself with the shared probe description", async () => {
|
|
459
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
460
|
+
|
|
461
|
+
expect(fieldFor(props, "probe").description).toBe(PROBE_FIELD_DESCRIPTION);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
test("defaults to the project's single custom probe", async () => {
|
|
465
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
466
|
+
|
|
467
|
+
expect(fieldFor(props, "probe").defaultValue).toBe("probe-1");
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
/*
|
|
471
|
+
* A global probe sits on the public internet and cannot reach an RFC1918
|
|
472
|
+
* address, so pre-selecting one would hand the operator a device guaranteed
|
|
473
|
+
* to read Down — worse than an empty box, because it looks answered.
|
|
474
|
+
*/
|
|
475
|
+
test("never defaults to a global probe, even as the only one", async () => {
|
|
476
|
+
mockProbeList = [{ _id: "global-1", name: "US East", isGlobalProbe: true }];
|
|
477
|
+
|
|
478
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
479
|
+
|
|
480
|
+
expect(fieldFor(props, "probe").defaultValue).toBe("");
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// Two custom probes is a real question, and the form must not answer it.
|
|
484
|
+
test("does not guess when the project has more than one custom probe", async () => {
|
|
485
|
+
mockProbeList = [
|
|
486
|
+
{ _id: "probe-1", name: "Branch probe" },
|
|
487
|
+
{ _id: "probe-2", name: "Datacenter probe" },
|
|
488
|
+
];
|
|
489
|
+
|
|
490
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
491
|
+
|
|
492
|
+
expect(fieldFor(props, "probe").defaultValue).toBe("");
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
describe("picking a site fills in the site's default probe", () => {
|
|
497
|
+
beforeEach(() => {
|
|
498
|
+
capturedTableProps = null;
|
|
499
|
+
mockGetItemCalls.length = 0;
|
|
500
|
+
mockProbeList = [{ _id: "probe-1", name: "Branch probe" }];
|
|
501
|
+
mockGetItem = (): Promise<unknown> => {
|
|
502
|
+
return Promise.resolve(siteRow(SITE_PROBE_ID));
|
|
503
|
+
};
|
|
504
|
+
window.localStorage.clear();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
afterEach(() => {
|
|
508
|
+
cleanup();
|
|
509
|
+
jest.clearAllMocks();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
test("reads the chosen site's probe and writes it into the probe box", async () => {
|
|
513
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
514
|
+
|
|
515
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
516
|
+
props: props,
|
|
517
|
+
siteId: SITE_ID,
|
|
518
|
+
currentFormValues: { name: "core-switch-01", probe: "probe-1" },
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
expect(mockGetItemCalls.length).toBe(1);
|
|
522
|
+
expect(mockGetItemCalls[0]!.modelType).toBe(NetworkSite);
|
|
523
|
+
expect(mockGetItemCalls[0]!.id.toString()).toBe(SITE_ID);
|
|
524
|
+
/*
|
|
525
|
+
* One column. The site row carries credentials-adjacent columns and a
|
|
526
|
+
* whole rollup; this lookup exists to answer one question.
|
|
527
|
+
*/
|
|
528
|
+
expect(mockGetItemCalls[0]!.select).toEqual({ probeId: true });
|
|
529
|
+
|
|
530
|
+
/*
|
|
531
|
+
* The site is written back beside the probe: this write lands AFTER the
|
|
532
|
+
* dropdown's own setFieldValue, and the values it spreads were snapshot
|
|
533
|
+
* before it — so a write that carried only the probe would undo the very
|
|
534
|
+
* selection that triggered it.
|
|
535
|
+
*/
|
|
536
|
+
expect(writes[writes.length - 1]).toEqual({
|
|
537
|
+
name: "core-switch-01",
|
|
538
|
+
site: SITE_ID,
|
|
539
|
+
probe: SITE_PROBE_ID,
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
/*
|
|
544
|
+
* "One getItem per site id", which is the whole reason the answers are
|
|
545
|
+
* cached: flipping between two sites while deciding, or opening the create
|
|
546
|
+
* form a second time, must not put a request on the wire per click.
|
|
547
|
+
*/
|
|
548
|
+
test("asks the server once per site id, however often the site is picked", async () => {
|
|
549
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
550
|
+
|
|
551
|
+
await selectSite({ props: props, siteId: SITE_ID });
|
|
552
|
+
expect(mockGetItemCalls.length).toBe(1);
|
|
553
|
+
|
|
554
|
+
await selectSite({
|
|
555
|
+
props: props,
|
|
556
|
+
siteId: SITE_ID,
|
|
557
|
+
currentFormValues: { probe: SITE_PROBE_ID },
|
|
558
|
+
// Same site, same probe already in the box: nothing left to write.
|
|
559
|
+
expectWrite: false,
|
|
560
|
+
});
|
|
561
|
+
expect(mockGetItemCalls.length).toBe(1);
|
|
562
|
+
|
|
563
|
+
mockGetItem = (): Promise<unknown> => {
|
|
564
|
+
return Promise.resolve(siteRow(OTHER_PROBE_ID));
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
568
|
+
props: props,
|
|
569
|
+
siteId: OTHER_SITE_ID,
|
|
570
|
+
currentFormValues: { probe: SITE_PROBE_ID },
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
// A second site is a second question, and gets asked.
|
|
574
|
+
expect(mockGetItemCalls.length).toBe(2);
|
|
575
|
+
expect(writes[writes.length - 1]!["probe"]).toBe(OTHER_PROBE_ID);
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
/*
|
|
579
|
+
* A site with no default probe is an ANSWER, and it is cached as one: the
|
|
580
|
+
* alternative is a lookup on every pick of the sites that have nothing to
|
|
581
|
+
* say.
|
|
582
|
+
*/
|
|
583
|
+
test("remembers a site that has no default probe, and leaves the box alone", async () => {
|
|
584
|
+
mockGetItem = (): Promise<unknown> => {
|
|
585
|
+
return Promise.resolve(siteRow(undefined));
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
589
|
+
|
|
590
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
591
|
+
props: props,
|
|
592
|
+
siteId: SITE_ID,
|
|
593
|
+
currentFormValues: { probe: "probe-1" },
|
|
594
|
+
expectWrite: false,
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
expect(writes).toEqual([]);
|
|
598
|
+
expect(mockGetItemCalls.length).toBe(1);
|
|
599
|
+
|
|
600
|
+
await selectSite({
|
|
601
|
+
props: props,
|
|
602
|
+
siteId: SITE_ID,
|
|
603
|
+
currentFormValues: { probe: "probe-1" },
|
|
604
|
+
expectWrite: false,
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
expect(mockGetItemCalls.length).toBe(1);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
* The site's probe is a DEFAULT, and a default may only replace a default.
|
|
612
|
+
* An operator who picked the one probe that can reach this particular
|
|
613
|
+
* device, and then recorded which site it stands in, must not have that
|
|
614
|
+
* quietly undone.
|
|
615
|
+
*/
|
|
616
|
+
test("never overwrites a probe the operator picked themselves", async () => {
|
|
617
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
618
|
+
|
|
619
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
620
|
+
props: props,
|
|
621
|
+
siteId: SITE_ID,
|
|
622
|
+
// Neither the form's default ("probe-1") nor anything it filled in.
|
|
623
|
+
currentFormValues: { probe: "probe-chosen-by-hand" },
|
|
624
|
+
expectWrite: false,
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
expect(writes).toEqual([]);
|
|
628
|
+
// Not even asked: the answer could not be used.
|
|
629
|
+
expect(mockGetItemCalls.length).toBe(0);
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
test("replaces the probe it filled in for a previously chosen site", async () => {
|
|
633
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
634
|
+
|
|
635
|
+
await selectSite({ props: props, siteId: SITE_ID });
|
|
636
|
+
|
|
637
|
+
mockGetItem = (): Promise<unknown> => {
|
|
638
|
+
return Promise.resolve(siteRow(OTHER_PROBE_ID));
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
642
|
+
props: props,
|
|
643
|
+
siteId: OTHER_SITE_ID,
|
|
644
|
+
// What the previous site's lookup put there, not an operator's choice.
|
|
645
|
+
currentFormValues: { probe: SITE_PROBE_ID },
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
expect(writes[writes.length - 1]!["probe"]).toBe(OTHER_PROBE_ID);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
// Clearing the site says nothing about which probe can reach the device.
|
|
652
|
+
test("clearing the site looks nothing up and changes nothing", async () => {
|
|
653
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
654
|
+
|
|
655
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
656
|
+
props: props,
|
|
657
|
+
siteId: "",
|
|
658
|
+
currentFormValues: { probe: "probe-1" },
|
|
659
|
+
expectWrite: false,
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
expect(writes).toEqual([]);
|
|
663
|
+
expect(mockGetItemCalls.length).toBe(0);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
/*
|
|
667
|
+
* A lookup that fails must cost one pick, not the form — and must not be
|
|
668
|
+
* remembered as "this site has no probe", which would make one bad response
|
|
669
|
+
* permanent for the life of the page.
|
|
670
|
+
*/
|
|
671
|
+
test("a failed lookup leaves the box alone and is not cached as an answer", async () => {
|
|
672
|
+
/*
|
|
673
|
+
* Rejected from a timer rather than immediately, so the handler is
|
|
674
|
+
* attached before the rejection happens and the run does not log a
|
|
675
|
+
* spurious unhandled-rejection warning for a case that is handled.
|
|
676
|
+
*/
|
|
677
|
+
mockGetItem = (): Promise<unknown> => {
|
|
678
|
+
return new Promise<unknown>(
|
|
679
|
+
(_resolve: (value: unknown) => void, reject: (err: Error) => void) => {
|
|
680
|
+
setTimeout(() => {
|
|
681
|
+
reject(new Error("Network error"));
|
|
682
|
+
}, 0);
|
|
683
|
+
},
|
|
684
|
+
);
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
688
|
+
|
|
689
|
+
const writes: Array<FormValuesLike> = await selectSite({
|
|
690
|
+
props: props,
|
|
691
|
+
siteId: SITE_ID,
|
|
692
|
+
currentFormValues: { probe: "probe-1" },
|
|
693
|
+
expectWrite: false,
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
expect(writes).toEqual([]);
|
|
697
|
+
|
|
698
|
+
mockGetItem = (): Promise<unknown> => {
|
|
699
|
+
return Promise.resolve(siteRow(SITE_PROBE_ID));
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
const retried: Array<FormValuesLike> = await selectSite({
|
|
703
|
+
props: props,
|
|
704
|
+
siteId: SITE_ID,
|
|
705
|
+
currentFormValues: { probe: "probe-1" },
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
expect(mockGetItemCalls.length).toBe(2);
|
|
709
|
+
expect(retried[retried.length - 1]!["probe"]).toBe(SITE_PROBE_ID);
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
describe("the create form's SNMP step", () => {
|
|
714
|
+
beforeEach(() => {
|
|
715
|
+
capturedTableProps = null;
|
|
716
|
+
mockGetItemCalls.length = 0;
|
|
717
|
+
mockProbeList = [{ _id: "probe-1", name: "Branch probe" }];
|
|
718
|
+
window.localStorage.clear();
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
afterEach(() => {
|
|
722
|
+
cleanup();
|
|
723
|
+
jest.clearAllMocks();
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
/*
|
|
727
|
+
* The step used to be hidden for a monitor-backed device, which is the only
|
|
728
|
+
* device that is never polled. This form creates no such device, so there
|
|
729
|
+
* is no branch left — and a step every device walks through is a step whose
|
|
730
|
+
* fields must all be skippable.
|
|
731
|
+
*/
|
|
732
|
+
test("is shown for every device and gated by nothing", async () => {
|
|
733
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
734
|
+
|
|
735
|
+
const snmp: CapturedFormStep | undefined = (props.formSteps || []).find(
|
|
736
|
+
(step: CapturedFormStep): boolean => {
|
|
737
|
+
return step.id === "snmp";
|
|
738
|
+
},
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
expect(snmp).toBeDefined();
|
|
742
|
+
expect(snmp!.showIf).toBeUndefined();
|
|
743
|
+
// The stepper is where an operator learns they may walk past it.
|
|
744
|
+
expect(snmp!.title.toLowerCase()).toContain("optional");
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
test("says what an empty community string means, in the shared words", async () => {
|
|
748
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
749
|
+
const profile: CapturedFormField = fieldFor(props, "snmpCredentialProfile");
|
|
750
|
+
|
|
751
|
+
/*
|
|
752
|
+
* The heading rides on the first field of the step, which is how BasicForm
|
|
753
|
+
* renders a section — sectionDescription is dropped unless a sectionTitle
|
|
754
|
+
* is set beside it.
|
|
755
|
+
*/
|
|
756
|
+
expect(profile.sectionTitle).toBe("SNMP");
|
|
757
|
+
expect(profile.sectionDescription).toBe(SNMP_STEP_DESCRIPTION);
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
test("credentials are optional: nothing on the step is required but the version", async () => {
|
|
761
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
762
|
+
|
|
763
|
+
const onSnmpStep: Array<CapturedFormField> = (
|
|
764
|
+
props.formFields || []
|
|
765
|
+
).filter((field: CapturedFormField): boolean => {
|
|
766
|
+
return field.stepId === "snmp";
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
expect(onSnmpStep.length).toBeGreaterThan(0);
|
|
770
|
+
|
|
771
|
+
const community: CapturedFormField = fieldFor(props, "snmpCommunityString");
|
|
772
|
+
const profile: CapturedFormField = fieldFor(props, "snmpCredentialProfile");
|
|
773
|
+
|
|
774
|
+
expect(isRequired(community, {})).toBe(false);
|
|
775
|
+
expect(isRequired(profile, {})).toBe(false);
|
|
776
|
+
/*
|
|
777
|
+
* The v3 fields ARE required, but only once V3 is chosen — they are
|
|
778
|
+
* revealed by showIf, so a device left on the defaulted V2c never meets
|
|
779
|
+
* them. The version itself is required and defaulted, which is why it is
|
|
780
|
+
* the one exception.
|
|
781
|
+
*/
|
|
782
|
+
expect(isRequired(fieldFor(props, "snmpVersion"), {})).toBe(true);
|
|
783
|
+
expect(fieldFor(props, "snmpVersion").defaultValue).toBe("V2c");
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
/*
|
|
787
|
+
* The either/or has to read the same here and on the Settings page, or a
|
|
788
|
+
* device created with a profile and a device switched to one afterwards are
|
|
789
|
+
* described by two different explanations of the same column.
|
|
790
|
+
*/
|
|
791
|
+
test("offers the credential profile beside the device's own credentials", async () => {
|
|
792
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
793
|
+
const profile: CapturedFormField = fieldFor(props, "snmpCredentialProfile");
|
|
794
|
+
|
|
795
|
+
expect(profile.stepId).toBe("snmp");
|
|
796
|
+
expect(profile.fieldType).toBe(FormFieldSchemaType.Dropdown);
|
|
797
|
+
expect(profile.dropdownModal?.type).toBe(NetworkSnmpCredentialProfile);
|
|
798
|
+
expect(profile.description).toContain("credentials below win");
|
|
799
|
+
expect(profile.placeholder?.toLowerCase()).toContain("no profile");
|
|
800
|
+
// Somewhere to go when the list is empty, which it is until one is made.
|
|
801
|
+
expect(profile.sideLink?.text).toBe("Manage credential profiles");
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
describe("the device list's bulk actions", () => {
|
|
806
|
+
beforeEach(() => {
|
|
807
|
+
capturedTableProps = null;
|
|
808
|
+
mockProbeList = [{ _id: "probe-1", name: "Branch probe" }];
|
|
809
|
+
window.localStorage.clear();
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
afterEach(() => {
|
|
813
|
+
cleanup();
|
|
814
|
+
jest.clearAllMocks();
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
/*
|
|
818
|
+
* A credential profile is only worth having if an EXISTING fleet can be
|
|
819
|
+
* moved onto it — the ping-only devices that need credentials were imported
|
|
820
|
+
* long before anybody wrote the profile down.
|
|
821
|
+
*/
|
|
822
|
+
test("include setting an SNMP credential profile on a selection", async () => {
|
|
823
|
+
const props: CapturedTableProps = await renderDevicesPage();
|
|
824
|
+
|
|
825
|
+
const titles: Array<string> = (props.bulkActions?.buttons || []).map(
|
|
826
|
+
(button: { title?: string | undefined }): string => {
|
|
827
|
+
return button.title || "";
|
|
828
|
+
},
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
expect(titles).toContain("Set SNMP Credential Profile");
|
|
832
|
+
});
|
|
833
|
+
});
|