@oneuptime/common 12.0.32 → 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/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +176 -1
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- 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/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 +12 -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/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/Index.ts +10 -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/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 +105 -48
- 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 -25
- 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 +134 -33
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -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/MonitorTypePicker.test.tsx +4 -2
- 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 +41 -5
- 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/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/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/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/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/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/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -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/UserNotificationSettingRollupRouting.test.ts +856 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
- 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/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/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/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/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/SideMenuItem.test.tsx +226 -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/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/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/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/Telemetry/CaptureSpanExportGating.test.ts +145 -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/SqlConnectionConfig.ts +31 -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 +90 -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/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/SideMenu.tsx +123 -5
- package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
- package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
- 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/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- 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/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.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/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.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/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- 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/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/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 +12 -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/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 +10 -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/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 +66 -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 -20
- 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/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 +80 -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/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/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.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/SideMenu.js +67 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
- 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/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/NetworkTopologyUtil.js +8 -3
- 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/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/package.json +2 -2
|
@@ -0,0 +1,899 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {
|
|
3
|
+
afterEach,
|
|
4
|
+
beforeEach,
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
jest,
|
|
8
|
+
test,
|
|
9
|
+
} from "@jest/globals";
|
|
10
|
+
import {
|
|
11
|
+
cleanup,
|
|
12
|
+
fireEvent,
|
|
13
|
+
render,
|
|
14
|
+
screen,
|
|
15
|
+
waitFor,
|
|
16
|
+
} from "@testing-library/react";
|
|
17
|
+
import * as React from "react";
|
|
18
|
+
import { FunctionComponent, ReactElement } from "react";
|
|
19
|
+
import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* The device list's bulk "Create Ping Monitors" action.
|
|
23
|
+
*
|
|
24
|
+
* A monitor-backed NetworkDevice with nothing bound reads "Pending / No
|
|
25
|
+
* monitor" forever - nothing polls it, and only a bound monitor can say
|
|
26
|
+
* whether it is up. Discovery import creates these by the dozen with the
|
|
27
|
+
* "create Ping monitors" opt-in off, so this action is the fleet-wide fix.
|
|
28
|
+
* What has to hold, and what a refactor drops silently:
|
|
29
|
+
*
|
|
30
|
+
* - the action is withheld from an all-SNMP selection and gated on BOTH
|
|
31
|
+
* permissions it needs (it creates a Monitor and updates a device);
|
|
32
|
+
* - probes are fetched when the modal opens, not on mount - the Devices
|
|
33
|
+
* page is mounted by other tests with no probe mock in place;
|
|
34
|
+
* - every device is re-read before anything is created, and SNMP or
|
|
35
|
+
* already-bound devices are reported as skipped, never provisioned;
|
|
36
|
+
* - an eligible device gets one Monitor create (with the chosen probes,
|
|
37
|
+
* or no `probes` key at all when none were chosen) and one bind;
|
|
38
|
+
* - a bind that fails deletes the monitor again;
|
|
39
|
+
* - the seed ids are resolved once per run, not once per device;
|
|
40
|
+
* - nothing in the copy claims the device was verified reachable.
|
|
41
|
+
*
|
|
42
|
+
* The provisioning sequence itself is PingMonitorProvisioning's; it is driven
|
|
43
|
+
* for real here, against a mocked ModelAPI, so the calls asserted are the
|
|
44
|
+
* ones the server would see.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
jest.mock("react-i18next", () => {
|
|
48
|
+
return {
|
|
49
|
+
useTranslation: () => {
|
|
50
|
+
return {
|
|
51
|
+
t: (key: string, opts?: { defaultValue?: string }): string => {
|
|
52
|
+
return opts?.defaultValue ?? key;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const getItemMock: MockFunction = getJestMockFunction();
|
|
60
|
+
const createMock: MockFunction = getJestMockFunction();
|
|
61
|
+
const updateByIdMock: MockFunction = getJestMockFunction();
|
|
62
|
+
const deleteItemMock: MockFunction = getJestMockFunction();
|
|
63
|
+
const getAllProbesMock: MockFunction = getJestMockFunction();
|
|
64
|
+
const resolveSeedIdsMock: MockFunction = getJestMockFunction();
|
|
65
|
+
const permissionCheckMock: MockFunction = getJestMockFunction();
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* The arrow wrappers are load bearing: jest.mock is hoisted above the compiled
|
|
69
|
+
* requires, so naming the mocks directly would capture them before their
|
|
70
|
+
* initializers have run.
|
|
71
|
+
*/
|
|
72
|
+
jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
73
|
+
return {
|
|
74
|
+
__esModule: true,
|
|
75
|
+
default: {
|
|
76
|
+
getItem: (...args: Array<any>) => {
|
|
77
|
+
return getItemMock(...args);
|
|
78
|
+
},
|
|
79
|
+
create: (...args: Array<any>) => {
|
|
80
|
+
return createMock(...args);
|
|
81
|
+
},
|
|
82
|
+
updateById: (...args: Array<any>) => {
|
|
83
|
+
return updateByIdMock(...args);
|
|
84
|
+
},
|
|
85
|
+
deleteItem: (...args: Array<any>) => {
|
|
86
|
+
return deleteItemMock(...args);
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
jest.mock("../../../../App/FeatureSet/Dashboard/src/Utils/Probe", () => {
|
|
93
|
+
return {
|
|
94
|
+
__esModule: true,
|
|
95
|
+
default: {
|
|
96
|
+
getAllProbes: (...args: Array<any>) => {
|
|
97
|
+
return getAllProbesMock(...args);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/*
|
|
104
|
+
* Keeps the real PingMonitorSeedIdsUnavailableError so the "project is
|
|
105
|
+
* missing a status" path throws the same class the hook sees in production.
|
|
106
|
+
*/
|
|
107
|
+
jest.mock(
|
|
108
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/PingMonitorSeedIds",
|
|
109
|
+
() => {
|
|
110
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
111
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/PingMonitorSeedIds",
|
|
112
|
+
) as Record<string, unknown>;
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
...actual,
|
|
116
|
+
__esModule: true,
|
|
117
|
+
default: {
|
|
118
|
+
resolve: (...args: Array<any>) => {
|
|
119
|
+
return resolveSeedIdsMock(...args);
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
jest.mock("../../../UI/Utils/PermissionGate", () => {
|
|
127
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
128
|
+
"../../../UI/Utils/PermissionGate",
|
|
129
|
+
) as Record<string, unknown>;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
...actual,
|
|
133
|
+
__esModule: true,
|
|
134
|
+
default: {
|
|
135
|
+
check: (...args: Array<any>) => {
|
|
136
|
+
return permissionCheckMock(...args);
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
jest.mock("../../../UI/Utils/Project", () => {
|
|
143
|
+
return {
|
|
144
|
+
__esModule: true,
|
|
145
|
+
default: {
|
|
146
|
+
getCurrentProjectId: () => {
|
|
147
|
+
const ObjectIDClass: any = (
|
|
148
|
+
jest.requireActual("../../../Types/ObjectID") as { default: any }
|
|
149
|
+
).default;
|
|
150
|
+
return new ObjectIDClass("11111111-1111-4111-8111-111111111111");
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
import useBulkCreatePingMonitors, {
|
|
157
|
+
BulkCreatePingMonitorsResult,
|
|
158
|
+
SKIPPED_ALREADY_BOUND_MESSAGE,
|
|
159
|
+
SKIPPED_SNMP_DEVICE_MESSAGE,
|
|
160
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/useBulkCreatePingMonitors";
|
|
161
|
+
import { pingMonitorProvisionedMessage } from "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/PingMonitorProvisioning";
|
|
162
|
+
import { PingMonitorSeedIdsUnavailableError } from "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/PingMonitorSeedIds";
|
|
163
|
+
import {
|
|
164
|
+
BulkActionButtonSchema,
|
|
165
|
+
BulkActionFailed,
|
|
166
|
+
BulkActionOnClickProps,
|
|
167
|
+
ProgressInfo,
|
|
168
|
+
} from "../../../UI/Components/BulkUpdate/BulkUpdateForm";
|
|
169
|
+
import { ModelAction } from "../../../UI/Utils/PermissionGate";
|
|
170
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
171
|
+
import NetworkDevice from "../../../Models/DatabaseModels/NetworkDevice";
|
|
172
|
+
import Probe from "../../../Models/DatabaseModels/Probe";
|
|
173
|
+
import MonitorType from "../../../Types/Monitor/MonitorType";
|
|
174
|
+
import NetworkDeviceMonitoringMethod from "../../../Types/NetworkDevice/NetworkDeviceMonitoringMethod";
|
|
175
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
* These tests drive a real Formik + react-select tree behind a modal, so the
|
|
179
|
+
* testing-library default of 1s flakes on a loaded box.
|
|
180
|
+
*/
|
|
181
|
+
const WAIT_TIMEOUT: number = 20000;
|
|
182
|
+
|
|
183
|
+
const ACTION_TITLE: string = "Create Ping Monitors";
|
|
184
|
+
|
|
185
|
+
const DEVICE_ONE_ID: string = "22222222-2222-4222-8222-222222222221";
|
|
186
|
+
const DEVICE_TWO_ID: string = "22222222-2222-4222-8222-222222222222";
|
|
187
|
+
const DEVICE_THREE_ID: string = "22222222-2222-4222-8222-222222222223";
|
|
188
|
+
const EXISTING_MONITOR_ID: string = "33333333-3333-4333-8333-333333333331";
|
|
189
|
+
const CREATED_MONITOR_ID: string = "33333333-3333-4333-8333-333333333332";
|
|
190
|
+
const PROBE_A_ID: string = "44444444-4444-4444-8444-444444444441";
|
|
191
|
+
const PROBE_B_ID: string = "44444444-4444-4444-8444-444444444442";
|
|
192
|
+
|
|
193
|
+
const ONLINE_STATUS_ID: string = "55555555-5555-4555-8555-555555555551";
|
|
194
|
+
const OFFLINE_STATUS_ID: string = "55555555-5555-4555-8555-555555555552";
|
|
195
|
+
const INCIDENT_SEVERITY_ID: string = "55555555-5555-4555-8555-555555555553";
|
|
196
|
+
const ALERT_SEVERITY_ID: string = "55555555-5555-4555-8555-555555555554";
|
|
197
|
+
|
|
198
|
+
const DEVICE_UPDATE_REASON: string =
|
|
199
|
+
"You need the Edit Network Device permission to do this.";
|
|
200
|
+
const MONITOR_CREATE_REASON: string =
|
|
201
|
+
"You need the Create Monitor permission to do this.";
|
|
202
|
+
|
|
203
|
+
interface DeviceFixture {
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
hostname: string;
|
|
207
|
+
method: NetworkDeviceMonitoringMethod;
|
|
208
|
+
monitorId?: string | undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
type MakeDeviceFunction = (fixture: DeviceFixture) => NetworkDevice;
|
|
212
|
+
|
|
213
|
+
const makeDevice: MakeDeviceFunction = (
|
|
214
|
+
fixture: DeviceFixture,
|
|
215
|
+
): NetworkDevice => {
|
|
216
|
+
const device: NetworkDevice = new NetworkDevice();
|
|
217
|
+
device._id = fixture.id;
|
|
218
|
+
device.name = fixture.name;
|
|
219
|
+
device.hostname = fixture.hostname;
|
|
220
|
+
device.monitoringMethod = fixture.method;
|
|
221
|
+
|
|
222
|
+
if (fixture.monitorId) {
|
|
223
|
+
device.monitorId = new ObjectID(fixture.monitorId);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return device;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* What the list row carries is only what DEVICE_STATUS_SELECT selects; the
|
|
231
|
+
* fresh read the hook makes is what carries the columns it decides on. The
|
|
232
|
+
* two are kept as separate fixtures so a test can make them disagree.
|
|
233
|
+
*/
|
|
234
|
+
const SNMP_DEVICE: DeviceFixture = {
|
|
235
|
+
id: DEVICE_ONE_ID,
|
|
236
|
+
name: "core-switch-01",
|
|
237
|
+
hostname: "10.0.0.1",
|
|
238
|
+
method: NetworkDeviceMonitoringMethod.Probe,
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const BOUND_DEVICE: DeviceFixture = {
|
|
242
|
+
id: DEVICE_TWO_ID,
|
|
243
|
+
name: "lobby-ap",
|
|
244
|
+
hostname: "10.0.0.2",
|
|
245
|
+
method: NetworkDeviceMonitoringMethod.Monitor,
|
|
246
|
+
monitorId: EXISTING_MONITOR_ID,
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const UNBOUND_DEVICE: DeviceFixture = {
|
|
250
|
+
id: DEVICE_THREE_ID,
|
|
251
|
+
name: "rack-pdu",
|
|
252
|
+
hostname: "10.0.0.3",
|
|
253
|
+
method: NetworkDeviceMonitoringMethod.Monitor,
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
type MakeProbeFunction = (id: string, name: string) => Probe;
|
|
257
|
+
|
|
258
|
+
const makeProbe: MakeProbeFunction = (id: string, name: string): Probe => {
|
|
259
|
+
const probe: Probe = new Probe();
|
|
260
|
+
probe._id = id;
|
|
261
|
+
probe.name = name;
|
|
262
|
+
return probe;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
interface ProgressSnapshot {
|
|
266
|
+
inProgressIds: Array<string>;
|
|
267
|
+
successIds: Array<string>;
|
|
268
|
+
failedIds: Array<string>;
|
|
269
|
+
failedMessages: Array<string>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
type IdsOfFunction = (items: Array<NetworkDevice>) => Array<string>;
|
|
273
|
+
|
|
274
|
+
const idsOf: IdsOfFunction = (items: Array<NetworkDevice>): Array<string> => {
|
|
275
|
+
return items.map((item: NetworkDevice) => {
|
|
276
|
+
return item._id || "";
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
/*
|
|
281
|
+
* The hook hands the same four arrays to every onProgressInfo call, so
|
|
282
|
+
* anything held by reference mutates retroactively into the final state.
|
|
283
|
+
* Copy out of them on arrival.
|
|
284
|
+
*/
|
|
285
|
+
type SnapshotProgressFunction = (
|
|
286
|
+
progressInfo: ProgressInfo<NetworkDevice>,
|
|
287
|
+
) => ProgressSnapshot;
|
|
288
|
+
|
|
289
|
+
const snapshotProgress: SnapshotProgressFunction = (
|
|
290
|
+
progressInfo: ProgressInfo<NetworkDevice>,
|
|
291
|
+
): ProgressSnapshot => {
|
|
292
|
+
return {
|
|
293
|
+
inProgressIds: idsOf(progressInfo.inProgressItems),
|
|
294
|
+
successIds: idsOf(progressInfo.successItems),
|
|
295
|
+
failedIds: idsOf(
|
|
296
|
+
progressInfo.failed.map((failure: BulkActionFailed<NetworkDevice>) => {
|
|
297
|
+
return failure.item;
|
|
298
|
+
}),
|
|
299
|
+
),
|
|
300
|
+
failedMessages: progressInfo.failed.map(
|
|
301
|
+
(failure: BulkActionFailed<NetworkDevice>) => {
|
|
302
|
+
return String(failure.failedMessage);
|
|
303
|
+
},
|
|
304
|
+
),
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const onProgressInfoMock: MockFunction = getJestMockFunction();
|
|
309
|
+
const onBulkActionStartMock: MockFunction = getJestMockFunction();
|
|
310
|
+
const onBulkActionEndMock: MockFunction = getJestMockFunction();
|
|
311
|
+
|
|
312
|
+
let progressSnapshots: Array<ProgressSnapshot> = [];
|
|
313
|
+
let capturedActions: Array<BulkActionButtonSchema<NetworkDevice>> = [];
|
|
314
|
+
|
|
315
|
+
/*
|
|
316
|
+
* What the fresh read answers for each device id. A test that wants the row
|
|
317
|
+
* and the server to disagree sets these independently of the items it
|
|
318
|
+
* hands the action.
|
|
319
|
+
*/
|
|
320
|
+
let devicesOnServer: Record<string, NetworkDevice | null> = {};
|
|
321
|
+
|
|
322
|
+
/*
|
|
323
|
+
* What PermissionGate.check answers, keyed on the model's singular name and
|
|
324
|
+
* the action. Anything not listed is allowed.
|
|
325
|
+
*/
|
|
326
|
+
let gateResults: Record<
|
|
327
|
+
string,
|
|
328
|
+
{ isAllowed: boolean; disabledReason?: string | undefined }
|
|
329
|
+
> = {};
|
|
330
|
+
|
|
331
|
+
type MakeActionPropsFunction = (
|
|
332
|
+
items: Array<NetworkDevice>,
|
|
333
|
+
) => BulkActionOnClickProps<NetworkDevice>;
|
|
334
|
+
|
|
335
|
+
const makeActionProps: MakeActionPropsFunction = (
|
|
336
|
+
items: Array<NetworkDevice>,
|
|
337
|
+
): BulkActionOnClickProps<NetworkDevice> => {
|
|
338
|
+
return {
|
|
339
|
+
items: items,
|
|
340
|
+
onProgressInfo:
|
|
341
|
+
onProgressInfoMock as unknown as BulkActionOnClickProps<NetworkDevice>["onProgressInfo"],
|
|
342
|
+
onBulkActionStart: onBulkActionStartMock as unknown as () => void,
|
|
343
|
+
onBulkActionEnd: onBulkActionEndMock as unknown as () => void,
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
interface HarnessProps {
|
|
348
|
+
items: Array<NetworkDevice>;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/*
|
|
352
|
+
* `modals` has to be mounted for the modal to exist, which renderHook cannot
|
|
353
|
+
* do, so the hook is driven through a component that renders a plain trigger
|
|
354
|
+
* per action - the same harness BulkLabelActions.test.tsx uses.
|
|
355
|
+
*/
|
|
356
|
+
const Harness: FunctionComponent<HarnessProps> = (
|
|
357
|
+
props: HarnessProps,
|
|
358
|
+
): ReactElement => {
|
|
359
|
+
const { bulkActions, modals }: BulkCreatePingMonitorsResult =
|
|
360
|
+
useBulkCreatePingMonitors();
|
|
361
|
+
|
|
362
|
+
capturedActions = bulkActions;
|
|
363
|
+
|
|
364
|
+
return (
|
|
365
|
+
<div>
|
|
366
|
+
{bulkActions.map((action: BulkActionButtonSchema<NetworkDevice>) => {
|
|
367
|
+
return (
|
|
368
|
+
<button
|
|
369
|
+
key={action.title}
|
|
370
|
+
type="button"
|
|
371
|
+
onClick={() => {
|
|
372
|
+
void action.onClick(makeActionProps(props.items));
|
|
373
|
+
}}
|
|
374
|
+
>
|
|
375
|
+
{`Trigger ${action.title}`}
|
|
376
|
+
</button>
|
|
377
|
+
);
|
|
378
|
+
})}
|
|
379
|
+
{modals}
|
|
380
|
+
</div>
|
|
381
|
+
);
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
type FindActionFunction = () => BulkActionButtonSchema<NetworkDevice>;
|
|
385
|
+
|
|
386
|
+
const findAction: FindActionFunction =
|
|
387
|
+
(): BulkActionButtonSchema<NetworkDevice> => {
|
|
388
|
+
const action: BulkActionButtonSchema<NetworkDevice> | undefined =
|
|
389
|
+
capturedActions.find(
|
|
390
|
+
(candidate: BulkActionButtonSchema<NetworkDevice>) => {
|
|
391
|
+
return candidate.title === ACTION_TITLE;
|
|
392
|
+
},
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
if (!action) {
|
|
396
|
+
throw new Error(`No "${ACTION_TITLE}" action was returned.`);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return action;
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
type OpenModalFunction = (items: Array<NetworkDevice>) => Promise<void>;
|
|
403
|
+
|
|
404
|
+
/*
|
|
405
|
+
* Renders the harness, opens the modal and waits for its form to be on
|
|
406
|
+
* screen - the probe fetch has settled by the time the combobox exists.
|
|
407
|
+
*/
|
|
408
|
+
const openModal: OpenModalFunction = async (
|
|
409
|
+
items: Array<NetworkDevice>,
|
|
410
|
+
): Promise<void> => {
|
|
411
|
+
render(<Harness items={items} />);
|
|
412
|
+
|
|
413
|
+
fireEvent.click(screen.getByText(`Trigger ${ACTION_TITLE}`));
|
|
414
|
+
|
|
415
|
+
await waitFor(
|
|
416
|
+
() => {
|
|
417
|
+
expect(screen.getByTestId("modal-title")).toHaveTextContent(ACTION_TITLE);
|
|
418
|
+
},
|
|
419
|
+
{ timeout: WAIT_TIMEOUT },
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
await screen.findByRole("combobox", undefined, { timeout: WAIT_TIMEOUT });
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
type SelectProbeFunction = (name: string) => Promise<void>;
|
|
426
|
+
|
|
427
|
+
/*
|
|
428
|
+
* react-select renders its menu lazily; ArrowDown on the combobox is the only
|
|
429
|
+
* interaction that mounts the option list.
|
|
430
|
+
*/
|
|
431
|
+
const selectProbe: SelectProbeFunction = async (
|
|
432
|
+
name: string,
|
|
433
|
+
): Promise<void> => {
|
|
434
|
+
const combobox: HTMLElement = await screen.findByRole("combobox", undefined, {
|
|
435
|
+
timeout: WAIT_TIMEOUT,
|
|
436
|
+
});
|
|
437
|
+
fireEvent.keyDown(combobox, { key: "ArrowDown", code: "ArrowDown" });
|
|
438
|
+
fireEvent.click(
|
|
439
|
+
await screen.findByText(name, undefined, { timeout: WAIT_TIMEOUT }),
|
|
440
|
+
);
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
type SubmitAndWaitFunction = () => Promise<void>;
|
|
444
|
+
|
|
445
|
+
const submitAndWaitForEnd: SubmitAndWaitFunction = async (): Promise<void> => {
|
|
446
|
+
fireEvent.click(screen.getByTestId("modal-footer-submit-button"));
|
|
447
|
+
|
|
448
|
+
await waitFor(
|
|
449
|
+
() => {
|
|
450
|
+
expect(onBulkActionEndMock).toHaveBeenCalledTimes(1);
|
|
451
|
+
},
|
|
452
|
+
{ timeout: WAIT_TIMEOUT },
|
|
453
|
+
);
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
type LastSnapshotFunction = () => ProgressSnapshot;
|
|
457
|
+
|
|
458
|
+
const lastSnapshot: LastSnapshotFunction = (): ProgressSnapshot => {
|
|
459
|
+
const snapshot: ProgressSnapshot | undefined =
|
|
460
|
+
progressSnapshots[progressSnapshots.length - 1];
|
|
461
|
+
|
|
462
|
+
if (!snapshot) {
|
|
463
|
+
throw new Error("No progress was reported.");
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return snapshot;
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
describe("useBulkCreatePingMonitors", () => {
|
|
470
|
+
beforeEach(() => {
|
|
471
|
+
progressSnapshots = [];
|
|
472
|
+
capturedActions = [];
|
|
473
|
+
devicesOnServer = {
|
|
474
|
+
[DEVICE_ONE_ID]: makeDevice(SNMP_DEVICE),
|
|
475
|
+
[DEVICE_TWO_ID]: makeDevice(BOUND_DEVICE),
|
|
476
|
+
[DEVICE_THREE_ID]: makeDevice(UNBOUND_DEVICE),
|
|
477
|
+
};
|
|
478
|
+
gateResults = {};
|
|
479
|
+
|
|
480
|
+
onProgressInfoMock.mockImplementation(
|
|
481
|
+
(progressInfo: ProgressInfo<NetworkDevice>): void => {
|
|
482
|
+
progressSnapshots.push(snapshotProgress(progressInfo));
|
|
483
|
+
},
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
permissionCheckMock.mockImplementation(
|
|
487
|
+
(
|
|
488
|
+
model: { singularName: string | null },
|
|
489
|
+
action: ModelAction,
|
|
490
|
+
): { isAllowed: boolean; disabledReason?: string | undefined } => {
|
|
491
|
+
return (
|
|
492
|
+
gateResults[`${model.singularName}:${action}`] || {
|
|
493
|
+
isAllowed: true,
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
},
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
getItemMock.mockImplementation(
|
|
500
|
+
(request: { id: ObjectID }): Promise<NetworkDevice | null> => {
|
|
501
|
+
return Promise.resolve(devicesOnServer[request.id.toString()] ?? null);
|
|
502
|
+
},
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
getAllProbesMock.mockImplementation((): Promise<Array<Probe>> => {
|
|
506
|
+
return Promise.resolve([
|
|
507
|
+
makeProbe(PROBE_A_ID, "Branch probe"),
|
|
508
|
+
makeProbe(PROBE_B_ID, "Datacenter probe"),
|
|
509
|
+
]);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
resolveSeedIdsMock.mockImplementation(() => {
|
|
513
|
+
return Promise.resolve({
|
|
514
|
+
onlineMonitorStatusId: new ObjectID(ONLINE_STATUS_ID),
|
|
515
|
+
offlineMonitorStatusId: new ObjectID(OFFLINE_STATUS_ID),
|
|
516
|
+
defaultIncidentSeverityId: new ObjectID(INCIDENT_SEVERITY_ID),
|
|
517
|
+
defaultAlertSeverityId: new ObjectID(ALERT_SEVERITY_ID),
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
createMock.mockImplementation((): Promise<{ data: Monitor }> => {
|
|
522
|
+
const created: Monitor = new Monitor();
|
|
523
|
+
created._id = CREATED_MONITOR_ID;
|
|
524
|
+
return Promise.resolve({ data: created });
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
updateByIdMock.mockImplementation((): Promise<void> => {
|
|
528
|
+
return Promise.resolve();
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
deleteItemMock.mockImplementation((): Promise<void> => {
|
|
532
|
+
return Promise.resolve();
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
afterEach(() => {
|
|
537
|
+
cleanup();
|
|
538
|
+
jest.clearAllMocks();
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
describe("where the action is offered", () => {
|
|
542
|
+
test("is withheld from an all-SNMP selection and offered to a mixed one", () => {
|
|
543
|
+
render(<Harness items={[]} />);
|
|
544
|
+
|
|
545
|
+
const action: BulkActionButtonSchema<NetworkDevice> = findAction();
|
|
546
|
+
|
|
547
|
+
expect(action.isVisible!([makeDevice(SNMP_DEVICE)])).toBe(false);
|
|
548
|
+
expect(
|
|
549
|
+
action.isVisible!([
|
|
550
|
+
makeDevice(SNMP_DEVICE),
|
|
551
|
+
makeDevice(UNBOUND_DEVICE),
|
|
552
|
+
]),
|
|
553
|
+
).toBe(true);
|
|
554
|
+
// The convention every bulk hook here follows - the bar is not drawn for one anyway.
|
|
555
|
+
expect(action.isVisible!([])).toBe(true);
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
test("is disabled with the device-update reason before the monitor-create reason", () => {
|
|
559
|
+
gateResults = {
|
|
560
|
+
[`Network Device:${ModelAction.Update}`]: {
|
|
561
|
+
isAllowed: false,
|
|
562
|
+
disabledReason: DEVICE_UPDATE_REASON,
|
|
563
|
+
},
|
|
564
|
+
[`Monitor:${ModelAction.Create}`]: {
|
|
565
|
+
isAllowed: false,
|
|
566
|
+
disabledReason: MONITOR_CREATE_REASON,
|
|
567
|
+
},
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
render(<Harness items={[]} />);
|
|
571
|
+
|
|
572
|
+
expect(findAction().disabled).toBe(true);
|
|
573
|
+
expect(findAction().tooltip).toBe(DEVICE_UPDATE_REASON);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
test("is disabled with the monitor-create reason when only that one is missing", () => {
|
|
577
|
+
gateResults = {
|
|
578
|
+
[`Monitor:${ModelAction.Create}`]: {
|
|
579
|
+
isAllowed: false,
|
|
580
|
+
disabledReason: MONITOR_CREATE_REASON,
|
|
581
|
+
},
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
render(<Harness items={[]} />);
|
|
585
|
+
|
|
586
|
+
expect(findAction().disabled).toBe(true);
|
|
587
|
+
expect(findAction().tooltip).toBe(MONITOR_CREATE_REASON);
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
test("is offered plainly when both permissions are held", () => {
|
|
591
|
+
render(<Harness items={[]} />);
|
|
592
|
+
|
|
593
|
+
expect(findAction().disabled).toBeUndefined();
|
|
594
|
+
expect(findAction().tooltip).toBeUndefined();
|
|
595
|
+
});
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
describe("the probe list", () => {
|
|
599
|
+
/*
|
|
600
|
+
* The Devices page is mounted by other tests with ModelTable mocked and
|
|
601
|
+
* no probe mock for this hook; a mount-time fetch would throw there.
|
|
602
|
+
*/
|
|
603
|
+
test("is not fetched until the modal opens", async () => {
|
|
604
|
+
render(<Harness items={[makeDevice(UNBOUND_DEVICE)]} />);
|
|
605
|
+
|
|
606
|
+
expect(getAllProbesMock).not.toHaveBeenCalled();
|
|
607
|
+
|
|
608
|
+
fireEvent.click(screen.getByText(`Trigger ${ACTION_TITLE}`));
|
|
609
|
+
|
|
610
|
+
await waitFor(() => {
|
|
611
|
+
expect(getAllProbesMock).toHaveBeenCalledTimes(1);
|
|
612
|
+
});
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
test("still opens the modal, without options, when it cannot be loaded", async () => {
|
|
616
|
+
getAllProbesMock.mockImplementation((): Promise<Array<Probe>> => {
|
|
617
|
+
return Promise.reject(new Error("probe list unavailable"));
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
621
|
+
|
|
622
|
+
// The field says so, rather than offering an empty dropdown in silence.
|
|
623
|
+
expect(
|
|
624
|
+
screen.getByText(/could not be loaded just now/),
|
|
625
|
+
).toBeInTheDocument();
|
|
626
|
+
|
|
627
|
+
await submitAndWaitForEnd();
|
|
628
|
+
|
|
629
|
+
expect(createMock).toHaveBeenCalledTimes(1);
|
|
630
|
+
expect((createMock.mock.calls[0] as Array<any>)[0].miscDataProps).toEqual(
|
|
631
|
+
{},
|
|
632
|
+
);
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
describe("what is provisioned", () => {
|
|
637
|
+
test("skips SNMP and already-bound devices without creating anything", async () => {
|
|
638
|
+
await openModal([makeDevice(SNMP_DEVICE), makeDevice(BOUND_DEVICE)]);
|
|
639
|
+
|
|
640
|
+
await submitAndWaitForEnd();
|
|
641
|
+
|
|
642
|
+
expect(onBulkActionStartMock).toHaveBeenCalledTimes(1);
|
|
643
|
+
expect(createMock).not.toHaveBeenCalled();
|
|
644
|
+
expect(updateByIdMock).not.toHaveBeenCalled();
|
|
645
|
+
|
|
646
|
+
const snapshot: ProgressSnapshot = lastSnapshot();
|
|
647
|
+
expect(snapshot.successIds).toEqual([]);
|
|
648
|
+
expect(snapshot.failedIds).toEqual([DEVICE_ONE_ID, DEVICE_TWO_ID]);
|
|
649
|
+
expect(snapshot.failedMessages).toEqual([
|
|
650
|
+
SKIPPED_SNMP_DEVICE_MESSAGE,
|
|
651
|
+
SKIPPED_ALREADY_BOUND_MESSAGE,
|
|
652
|
+
]);
|
|
653
|
+
expect(SKIPPED_SNMP_DEVICE_MESSAGE.startsWith("Skipped:")).toBe(true);
|
|
654
|
+
expect(SKIPPED_ALREADY_BOUND_MESSAGE.startsWith("Skipped:")).toBe(true);
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
/*
|
|
658
|
+
* The row is what the list selected when the page loaded; the decision
|
|
659
|
+
* has to be made on what the server says now, or a device bound in
|
|
660
|
+
* another tab since gets a second, billable monitor.
|
|
661
|
+
*/
|
|
662
|
+
test("decides on a fresh read of the device, not on the row", async () => {
|
|
663
|
+
const staleRow: NetworkDevice = makeDevice({
|
|
664
|
+
...UNBOUND_DEVICE,
|
|
665
|
+
monitorId: undefined,
|
|
666
|
+
});
|
|
667
|
+
devicesOnServer[DEVICE_THREE_ID] = makeDevice({
|
|
668
|
+
...UNBOUND_DEVICE,
|
|
669
|
+
monitorId: EXISTING_MONITOR_ID,
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
await openModal([staleRow]);
|
|
673
|
+
|
|
674
|
+
await submitAndWaitForEnd();
|
|
675
|
+
|
|
676
|
+
expect(getItemMock).toHaveBeenCalledTimes(1);
|
|
677
|
+
expect((getItemMock.mock.calls[0] as Array<any>)[0].select).toEqual({
|
|
678
|
+
_id: true,
|
|
679
|
+
name: true,
|
|
680
|
+
hostname: true,
|
|
681
|
+
monitoringMethod: true,
|
|
682
|
+
monitorId: true,
|
|
683
|
+
});
|
|
684
|
+
expect(createMock).not.toHaveBeenCalled();
|
|
685
|
+
expect(lastSnapshot().failedMessages).toEqual([
|
|
686
|
+
SKIPPED_ALREADY_BOUND_MESSAGE,
|
|
687
|
+
]);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
test("creates a Ping monitor on the device's hostname and binds it, on the project's default probes when none were picked", async () => {
|
|
691
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
692
|
+
|
|
693
|
+
await submitAndWaitForEnd();
|
|
694
|
+
|
|
695
|
+
expect(createMock).toHaveBeenCalledTimes(1);
|
|
696
|
+
|
|
697
|
+
const createRequest: any = (createMock.mock.calls[0] as Array<any>)[0];
|
|
698
|
+
expect(createRequest.modelType).toBe(Monitor);
|
|
699
|
+
/*
|
|
700
|
+
* No `probes` key at all: the server treats an explicit empty
|
|
701
|
+
* selection as "attach nothing", which would create a monitor nothing
|
|
702
|
+
* ever evaluates.
|
|
703
|
+
*/
|
|
704
|
+
expect(createRequest.miscDataProps).toEqual({});
|
|
705
|
+
|
|
706
|
+
const monitor: Monitor = createRequest.model as Monitor;
|
|
707
|
+
expect(monitor.name).toBe("Ping rack-pdu");
|
|
708
|
+
expect(monitor.monitorType).toBe(MonitorType.Ping);
|
|
709
|
+
expect(monitor.description).toContain("10.0.0.3");
|
|
710
|
+
expect(monitor.description).toContain("Create Ping Monitors");
|
|
711
|
+
|
|
712
|
+
expect(updateByIdMock).toHaveBeenCalledTimes(1);
|
|
713
|
+
const bindRequest: any = (updateByIdMock.mock.calls[0] as Array<any>)[0];
|
|
714
|
+
expect(bindRequest.modelType).toBe(NetworkDevice);
|
|
715
|
+
expect(bindRequest.id.toString()).toBe(DEVICE_THREE_ID);
|
|
716
|
+
expect(bindRequest.data).toEqual({ monitorId: CREATED_MONITOR_ID });
|
|
717
|
+
|
|
718
|
+
expect(deleteItemMock).not.toHaveBeenCalled();
|
|
719
|
+
|
|
720
|
+
const snapshot: ProgressSnapshot = lastSnapshot();
|
|
721
|
+
expect(snapshot.successIds).toEqual([DEVICE_THREE_ID]);
|
|
722
|
+
expect(snapshot.failedIds).toEqual([]);
|
|
723
|
+
expect(snapshot.inProgressIds).toEqual([]);
|
|
724
|
+
expect(onBulkActionStartMock).toHaveBeenCalledTimes(1);
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
test("attaches the probes the operator picked", async () => {
|
|
728
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
729
|
+
|
|
730
|
+
await selectProbe("Branch probe");
|
|
731
|
+
|
|
732
|
+
await submitAndWaitForEnd();
|
|
733
|
+
|
|
734
|
+
expect(createMock).toHaveBeenCalledTimes(1);
|
|
735
|
+
expect((createMock.mock.calls[0] as Array<any>)[0].miscDataProps).toEqual(
|
|
736
|
+
{
|
|
737
|
+
probes: [PROBE_A_ID],
|
|
738
|
+
},
|
|
739
|
+
);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
/*
|
|
743
|
+
* A monitor is billable and plan-limited; one that reports on nothing is
|
|
744
|
+
* exactly the orphan an operator cannot see the reason for.
|
|
745
|
+
*/
|
|
746
|
+
test("deletes the monitor again when the bind fails, and reports the device as failed", async () => {
|
|
747
|
+
updateByIdMock.mockImplementation((): Promise<void> => {
|
|
748
|
+
return Promise.reject(new Error("device is read-only"));
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
752
|
+
|
|
753
|
+
await submitAndWaitForEnd();
|
|
754
|
+
|
|
755
|
+
expect(createMock).toHaveBeenCalledTimes(1);
|
|
756
|
+
expect(deleteItemMock).toHaveBeenCalledTimes(1);
|
|
757
|
+
|
|
758
|
+
const deleteRequest: any = (
|
|
759
|
+
deleteItemMock.mock.calls[0] as Array<any>
|
|
760
|
+
)[0];
|
|
761
|
+
expect(deleteRequest.modelType).toBe(Monitor);
|
|
762
|
+
expect(deleteRequest.id.toString()).toBe(CREATED_MONITOR_ID);
|
|
763
|
+
|
|
764
|
+
const snapshot: ProgressSnapshot = lastSnapshot();
|
|
765
|
+
expect(snapshot.successIds).toEqual([]);
|
|
766
|
+
expect(snapshot.failedIds).toEqual([DEVICE_THREE_ID]);
|
|
767
|
+
expect(snapshot.failedMessages[0]).toContain("could not be bound");
|
|
768
|
+
expect(snapshot.failedMessages[0]).toContain("device is read-only");
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
test("reports progress after every device, and ends the action once", async () => {
|
|
772
|
+
await openModal([
|
|
773
|
+
makeDevice(SNMP_DEVICE),
|
|
774
|
+
makeDevice(BOUND_DEVICE),
|
|
775
|
+
makeDevice(UNBOUND_DEVICE),
|
|
776
|
+
]);
|
|
777
|
+
|
|
778
|
+
await submitAndWaitForEnd();
|
|
779
|
+
|
|
780
|
+
expect(progressSnapshots).toHaveLength(3);
|
|
781
|
+
expect(progressSnapshots[0]!.inProgressIds).toEqual([
|
|
782
|
+
DEVICE_TWO_ID,
|
|
783
|
+
DEVICE_THREE_ID,
|
|
784
|
+
]);
|
|
785
|
+
expect(progressSnapshots[1]!.inProgressIds).toEqual([DEVICE_THREE_ID]);
|
|
786
|
+
expect(progressSnapshots[2]!.inProgressIds).toEqual([]);
|
|
787
|
+
expect(progressSnapshots[2]!.successIds).toEqual([DEVICE_THREE_ID]);
|
|
788
|
+
expect(progressSnapshots[2]!.failedIds).toEqual([
|
|
789
|
+
DEVICE_ONE_ID,
|
|
790
|
+
DEVICE_TWO_ID,
|
|
791
|
+
]);
|
|
792
|
+
expect(onBulkActionStartMock).toHaveBeenCalledTimes(1);
|
|
793
|
+
expect(onBulkActionEndMock).toHaveBeenCalledTimes(1);
|
|
794
|
+
});
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
describe("the seed ids", () => {
|
|
798
|
+
/*
|
|
799
|
+
* They describe the project, not any one device: a 200-device selection
|
|
800
|
+
* must not make 200 copies of the same three list requests.
|
|
801
|
+
*/
|
|
802
|
+
test("are resolved once for the whole selection", async () => {
|
|
803
|
+
devicesOnServer = {
|
|
804
|
+
[DEVICE_ONE_ID]: makeDevice({ ...UNBOUND_DEVICE, id: DEVICE_ONE_ID }),
|
|
805
|
+
[DEVICE_TWO_ID]: makeDevice({ ...UNBOUND_DEVICE, id: DEVICE_TWO_ID }),
|
|
806
|
+
[DEVICE_THREE_ID]: makeDevice(UNBOUND_DEVICE),
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
await openModal([
|
|
810
|
+
makeDevice({ ...UNBOUND_DEVICE, id: DEVICE_ONE_ID }),
|
|
811
|
+
makeDevice({ ...UNBOUND_DEVICE, id: DEVICE_TWO_ID }),
|
|
812
|
+
makeDevice(UNBOUND_DEVICE),
|
|
813
|
+
]);
|
|
814
|
+
|
|
815
|
+
await submitAndWaitForEnd();
|
|
816
|
+
|
|
817
|
+
expect(resolveSeedIdsMock).toHaveBeenCalledTimes(1);
|
|
818
|
+
expect(createMock).toHaveBeenCalledTimes(3);
|
|
819
|
+
expect(lastSnapshot().successIds).toEqual([
|
|
820
|
+
DEVICE_ONE_ID,
|
|
821
|
+
DEVICE_TWO_ID,
|
|
822
|
+
DEVICE_THREE_ID,
|
|
823
|
+
]);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
/*
|
|
827
|
+
* A project with no offline status cannot get ANY monitor, and the
|
|
828
|
+
* reason is not about a device - so it is said once, in its own modal,
|
|
829
|
+
* and the action never starts. Starting it and filing every device
|
|
830
|
+
* under "failed" with the same sentence would bury the fix under the
|
|
831
|
+
* list.
|
|
832
|
+
*/
|
|
833
|
+
test("report a project-level failure once, without starting the action", async () => {
|
|
834
|
+
const reason: string =
|
|
835
|
+
"This project needs both an operational and an offline monitor status before Ping monitors can be created.";
|
|
836
|
+
|
|
837
|
+
resolveSeedIdsMock.mockImplementation(() => {
|
|
838
|
+
return Promise.reject(new PingMonitorSeedIdsUnavailableError(reason));
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
await openModal([makeDevice(UNBOUND_DEVICE), makeDevice(BOUND_DEVICE)]);
|
|
842
|
+
|
|
843
|
+
fireEvent.click(screen.getByTestId("modal-footer-submit-button"));
|
|
844
|
+
|
|
845
|
+
await waitFor(
|
|
846
|
+
() => {
|
|
847
|
+
expect(screen.getByTestId("modal-title")).toHaveTextContent(
|
|
848
|
+
"Ping Monitors Could Not Be Created",
|
|
849
|
+
);
|
|
850
|
+
},
|
|
851
|
+
{ timeout: WAIT_TIMEOUT },
|
|
852
|
+
);
|
|
853
|
+
|
|
854
|
+
expect(screen.getByText(reason)).toBeInTheDocument();
|
|
855
|
+
expect(onBulkActionStartMock).not.toHaveBeenCalled();
|
|
856
|
+
expect(onBulkActionEndMock).not.toHaveBeenCalled();
|
|
857
|
+
expect(getItemMock).not.toHaveBeenCalled();
|
|
858
|
+
expect(createMock).not.toHaveBeenCalled();
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
describe("the copy", () => {
|
|
863
|
+
/*
|
|
864
|
+
* A fresh monitor is stamped with the project's operational status
|
|
865
|
+
* before any probe has checked the address, so the device reads Up the
|
|
866
|
+
* moment it is bound. Nothing here may dress that up as a verdict.
|
|
867
|
+
*/
|
|
868
|
+
test("never claims the device was verified reachable", async () => {
|
|
869
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
870
|
+
|
|
871
|
+
const modalText: string = (
|
|
872
|
+
screen.getByTestId("modal").textContent || ""
|
|
873
|
+
).toLowerCase();
|
|
874
|
+
|
|
875
|
+
expect(modalText).toContain("bound");
|
|
876
|
+
expect(modalText).not.toContain("verified");
|
|
877
|
+
expect(modalText).not.toMatch(/\breachable\b/);
|
|
878
|
+
|
|
879
|
+
const provisionedMessage: string =
|
|
880
|
+
pingMonitorProvisionedMessage("Ping rack-pdu").toLowerCase();
|
|
881
|
+
|
|
882
|
+
expect(provisionedMessage).not.toContain("verified");
|
|
883
|
+
expect(provisionedMessage).not.toMatch(/\breachable\b/);
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
test("says what is skipped and that monitors count towards the plan", async () => {
|
|
887
|
+
await openModal([makeDevice(UNBOUND_DEVICE)]);
|
|
888
|
+
|
|
889
|
+
const description: string =
|
|
890
|
+
screen.getByTestId("modal-description").textContent || "";
|
|
891
|
+
|
|
892
|
+
expect(description).toContain("already have a monitor bound");
|
|
893
|
+
// Probe-polled devices are pinged by their probe already, so they are skipped.
|
|
894
|
+
expect(description).toContain("probe-polled devices");
|
|
895
|
+
expect(description).toContain("plan");
|
|
896
|
+
expect(description).toContain("Incidents are off");
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
});
|