@oneuptime/common 13.0.8 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/AuditLog.ts +23 -15
- package/Models/DatabaseModels/GlobalConfig.ts +24 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/BaseAPI.ts +26 -5
- package/Server/API/GlobalConfigAPI.ts +228 -462
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/StatusPageAPI.ts +100 -42
- package/Server/API/TeamMemberAPI.ts +10 -1
- package/Server/Enterprise/EnterpriseEdition.ts +649 -0
- package/Server/Enterprise/EnterpriseFeature.ts +48 -0
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
- package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
- package/Server/EnvironmentConfig.ts +147 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +56 -4
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
- package/Server/Utils/EditionEnforcement.ts +233 -0
- package/Server/Utils/FrontendEnvironment.ts +41 -2
- package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
- package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
- package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
- package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
- package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
- package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
- package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
- package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
- package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
- package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
- package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
- package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
- package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
- package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +181 -0
- package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
- package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
- package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
- package/Types/Database/CanonicalModelInstance.ts +102 -0
- package/Types/Database/TableColumn.ts +20 -6
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
- package/Types/IP/IPv6.ts +6 -1
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
- package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +26 -5
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectOIDC.js +24 -16
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +24 -16
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +93 -43
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +8 -1
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +84 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +71 -740
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +63 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +90 -17
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -4
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +214 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +24 -6
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +71 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +10 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -16
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +31 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
- package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.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/MonitorCriteriaEvaluator.js +449 -261
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +59 -11
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
- package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
- package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js +19 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
- package/build/dist/Types/IP/IPv6.js +6 -1
- package/build/dist/Types/IP/IPv6.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HostAddressUtil.js +80 -0
- package/build/dist/Utils/HostAddressUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
- package/jest.config.json +3 -1
- package/package.json +1 -1
- package/test-setup.sh +103 -34
- package/tsconfig.json +13 -0
- package/Server/API/EnterpriseLicenseAPI.ts +0 -925
- package/Server/API/TeamComplianceAPI.ts +0 -158
- package/Server/Middleware/SCIMAuthorization.ts +0 -141
- package/Server/Services/TeamComplianceService.ts +0 -733
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
- package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
- package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
- package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
- package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
- package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
- package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
- package/build/dist/Server/Services/TeamComplianceService.js +0 -537
- package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
|
@@ -0,0 +1,547 @@
|
|
|
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 { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
11
|
+
import React from "react";
|
|
12
|
+
import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* Who sees an enterprise feature and who sees its upsell - one tier-aware
|
|
16
|
+
* rule, shared by the enterprise card and the audit log card.
|
|
17
|
+
*
|
|
18
|
+
* OneUptime Cloud (billing on) compares the project's plan with the tier the
|
|
19
|
+
* feature's model is sold at: Scale for SSO / OIDC / SCIM / team compliance,
|
|
20
|
+
* Enterprise for audit logs. The Cloud runs the Enterprise image, so the
|
|
21
|
+
* edition flag is always true there and must not be consulted. Self-hosted
|
|
22
|
+
* (billing off) asks only whether this is the Enterprise Edition.
|
|
23
|
+
*
|
|
24
|
+
* Before this, both cards demanded the Enterprise plan: a Scale customer was
|
|
25
|
+
* walled off from SSO their plan includes. And the edition flag was checked
|
|
26
|
+
* first, which on an Enterprise-image Cloud would unlock everything for
|
|
27
|
+
* every plan.
|
|
28
|
+
*
|
|
29
|
+
* Both billing and the edition are pinned in every test: CI's config.env sets
|
|
30
|
+
* BILLING_ENABLED=true, so anything left to the environment tests the Cloud
|
|
31
|
+
* path only.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
let billingEnabledForTest: boolean = false;
|
|
35
|
+
let enterpriseEditionForTest: boolean = false;
|
|
36
|
+
let currentPlanForTest: string | null = null;
|
|
37
|
+
let currentPlanThrows: boolean = false;
|
|
38
|
+
let planEnvForTest: Record<string, string> = {};
|
|
39
|
+
|
|
40
|
+
// jsdom does not implement window.open; the call to action uses it.
|
|
41
|
+
const openMock: MockFunction = getJestMockFunction();
|
|
42
|
+
const originalOpen: typeof window.open = window.open;
|
|
43
|
+
|
|
44
|
+
const CLOUD_PLAN_ENV: Record<string, string> = {
|
|
45
|
+
SUBSCRIPTION_PLAN_BASIC: "Free,priceMonthlyId1,priceYearlyId1,0,0,1,0",
|
|
46
|
+
SUBSCRIPTION_PLAN_GROWTH: "Growth,priceMonthlyId2,priceYearlyId2,0,0,2,14",
|
|
47
|
+
SUBSCRIPTION_PLAN_SCALE: "Scale,priceMonthlyId3,priceYearlyId3,0,0,3,0",
|
|
48
|
+
SUBSCRIPTION_PLAN_ENTERPRISE:
|
|
49
|
+
"Enterprise,priceMonthlyId4,priceYearlyId4,-1,-1,4,14",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
jest.mock("../../../UI/Config", () => {
|
|
53
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
54
|
+
"../../../UI/Config",
|
|
55
|
+
) as Record<string, unknown>;
|
|
56
|
+
|
|
57
|
+
const mocked: Record<string, unknown> = { ...actual };
|
|
58
|
+
|
|
59
|
+
Object.defineProperty(mocked, "BILLING_ENABLED", {
|
|
60
|
+
get: (): boolean => {
|
|
61
|
+
return billingEnabledForTest;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
Object.defineProperty(mocked, "IS_ENTERPRISE_EDITION", {
|
|
66
|
+
get: (): boolean => {
|
|
67
|
+
return enterpriseEditionForTest;
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
mocked["getAllEnvVars"] = (): Record<string, string> => {
|
|
72
|
+
return planEnvForTest;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return mocked;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
jest.mock("../../../UI/Utils/Project", () => {
|
|
79
|
+
const actual: Record<string, any> = jest.requireActual(
|
|
80
|
+
"../../../UI/Utils/Project",
|
|
81
|
+
) as Record<string, any>;
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
__esModule: true,
|
|
85
|
+
...actual,
|
|
86
|
+
default: {
|
|
87
|
+
...actual["default"],
|
|
88
|
+
getCurrentPlan: (): string | null => {
|
|
89
|
+
if (currentPlanThrows) {
|
|
90
|
+
throw new Error("Plan ID is invalid");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return currentPlanForTest;
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
import EnterpriseFeatureUpgrade, {
|
|
100
|
+
EnterpriseUpgradeCopy,
|
|
101
|
+
EnterpriseUpgradeReason,
|
|
102
|
+
getDefaultUpgradeReason,
|
|
103
|
+
getEnterpriseUpgradeCopy,
|
|
104
|
+
isEnterpriseFeatureEligible as isEnterpriseFeatureEligibleFromCard,
|
|
105
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/EnterpriseEdition/EnterpriseFeatureUpgrade";
|
|
106
|
+
import AuditLogsEnterpriseUpgrade, {
|
|
107
|
+
isAuditLogsEnterpriseEligible,
|
|
108
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/AuditLogs/AuditLogsEnterpriseUpgrade";
|
|
109
|
+
import {
|
|
110
|
+
AUDIT_LOGS_REQUIRED_PLAN,
|
|
111
|
+
IDENTITY_REQUIRED_PLAN,
|
|
112
|
+
getCurrentPlanOrNull,
|
|
113
|
+
isEnterpriseFeatureEligible,
|
|
114
|
+
isPlanAtLeast,
|
|
115
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterpriseEligibility";
|
|
116
|
+
import { PlanType } from "../../../Types/Billing/SubscriptionPlan";
|
|
117
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
118
|
+
|
|
119
|
+
type Deployment = "cloud" | "self-hosted-enterprise" | "self-hosted-community";
|
|
120
|
+
|
|
121
|
+
const pinDeployment: (deployment: Deployment) => void = (
|
|
122
|
+
deployment: Deployment,
|
|
123
|
+
): void => {
|
|
124
|
+
billingEnabledForTest = deployment === "cloud";
|
|
125
|
+
/*
|
|
126
|
+
* The Cloud runs the Enterprise image, so its effective edition is true;
|
|
127
|
+
* pinning it true proves the plan check does not fall back to it.
|
|
128
|
+
*/
|
|
129
|
+
enterpriseEditionForTest = deployment !== "self-hosted-community";
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
billingEnabledForTest = false;
|
|
134
|
+
enterpriseEditionForTest = false;
|
|
135
|
+
currentPlanForTest = null;
|
|
136
|
+
currentPlanThrows = false;
|
|
137
|
+
planEnvForTest = CLOUD_PLAN_ENV;
|
|
138
|
+
openMock.mockReset();
|
|
139
|
+
window.open = openMock as unknown as typeof window.open;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
afterEach(() => {
|
|
143
|
+
cleanup();
|
|
144
|
+
window.open = originalOpen;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("which plan each enterprise feature needs", () => {
|
|
148
|
+
test("SSO, OIDC, SCIM and compliance are Scale; audit logs are Enterprise", () => {
|
|
149
|
+
expect(IDENTITY_REQUIRED_PLAN).toBe(PlanType.Scale);
|
|
150
|
+
expect(AUDIT_LOGS_REQUIRED_PLAN).toBe(PlanType.Enterprise);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe("isPlanAtLeast", () => {
|
|
155
|
+
test.each([
|
|
156
|
+
[PlanType.Scale, PlanType.Free, false],
|
|
157
|
+
[PlanType.Scale, PlanType.Growth, false],
|
|
158
|
+
[PlanType.Scale, PlanType.Scale, true],
|
|
159
|
+
[PlanType.Scale, PlanType.Enterprise, true],
|
|
160
|
+
[PlanType.Enterprise, PlanType.Growth, false],
|
|
161
|
+
[PlanType.Enterprise, PlanType.Scale, false],
|
|
162
|
+
[PlanType.Enterprise, PlanType.Enterprise, true],
|
|
163
|
+
])(
|
|
164
|
+
"needs %s, has %s -> %s",
|
|
165
|
+
(required: PlanType, current: PlanType, expected: boolean) => {
|
|
166
|
+
expect(isPlanAtLeast(required, current)).toBe(expected);
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
test("no plan is never enough", () => {
|
|
171
|
+
expect(isPlanAtLeast(PlanType.Scale, null)).toBe(false);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("plans that cannot be ordered count as not enough, except an exact match", () => {
|
|
175
|
+
/*
|
|
176
|
+
* With no SUBSCRIPTION_PLAN_* the order is unknown. The upsell check
|
|
177
|
+
* must not throw its way into an error boundary.
|
|
178
|
+
*/
|
|
179
|
+
planEnvForTest = {};
|
|
180
|
+
|
|
181
|
+
expect(isPlanAtLeast(PlanType.Scale, PlanType.Enterprise)).toBe(false);
|
|
182
|
+
expect(isPlanAtLeast(PlanType.Scale, PlanType.Scale)).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe("getCurrentPlanOrNull", () => {
|
|
187
|
+
test("passes the project's plan through", () => {
|
|
188
|
+
currentPlanForTest = PlanType.Growth;
|
|
189
|
+
expect(getCurrentPlanOrNull()).toBe(PlanType.Growth);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("turns an unknown plan id into no plan instead of throwing", () => {
|
|
193
|
+
currentPlanThrows = true;
|
|
194
|
+
expect(getCurrentPlanOrNull()).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
describe("isEnterpriseFeatureEligible on OneUptime Cloud", () => {
|
|
199
|
+
beforeEach(() => {
|
|
200
|
+
pinDeployment("cloud");
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test.each([
|
|
204
|
+
[PlanType.Free, false],
|
|
205
|
+
[PlanType.Growth, false],
|
|
206
|
+
[PlanType.Scale, true],
|
|
207
|
+
[PlanType.Enterprise, true],
|
|
208
|
+
])(
|
|
209
|
+
"a %s project gets the Scale-tier features: %s",
|
|
210
|
+
(plan: PlanType, expected: boolean) => {
|
|
211
|
+
currentPlanForTest = plan;
|
|
212
|
+
|
|
213
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(expected);
|
|
214
|
+
},
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
test.each([
|
|
218
|
+
[PlanType.Growth, false],
|
|
219
|
+
[PlanType.Scale, false],
|
|
220
|
+
[PlanType.Enterprise, true],
|
|
221
|
+
])(
|
|
222
|
+
"a %s project gets the Enterprise-tier features: %s",
|
|
223
|
+
(plan: PlanType, expected: boolean) => {
|
|
224
|
+
currentPlanForTest = plan;
|
|
225
|
+
|
|
226
|
+
expect(isEnterpriseFeatureEligible(PlanType.Enterprise)).toBe(expected);
|
|
227
|
+
},
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
test("defaults to the Scale tier, so existing callers fix the Scale-plan wall", () => {
|
|
231
|
+
currentPlanForTest = PlanType.Scale;
|
|
232
|
+
expect(isEnterpriseFeatureEligible()).toBe(true);
|
|
233
|
+
|
|
234
|
+
currentPlanForTest = PlanType.Growth;
|
|
235
|
+
expect(isEnterpriseFeatureEligible()).toBe(false);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("never falls back to the edition flag - the Cloud runs the Enterprise image", () => {
|
|
239
|
+
enterpriseEditionForTest = true;
|
|
240
|
+
currentPlanForTest = PlanType.Free;
|
|
241
|
+
|
|
242
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(false);
|
|
243
|
+
expect(isEnterpriseFeatureEligible(PlanType.Enterprise)).toBe(false);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
test("a project with no plan, or an unknown one, gets the upsell", () => {
|
|
247
|
+
currentPlanForTest = null;
|
|
248
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(false);
|
|
249
|
+
|
|
250
|
+
currentPlanThrows = true;
|
|
251
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(false);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("the card re-exports the same check under its old name", () => {
|
|
255
|
+
expect(isEnterpriseFeatureEligibleFromCard).toBe(
|
|
256
|
+
isEnterpriseFeatureEligible,
|
|
257
|
+
);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
describe("isEnterpriseFeatureEligible when self-hosted", () => {
|
|
262
|
+
test("the Enterprise Edition gets every feature, whatever the plan says", () => {
|
|
263
|
+
pinDeployment("self-hosted-enterprise");
|
|
264
|
+
currentPlanForTest = PlanType.Free;
|
|
265
|
+
|
|
266
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(true);
|
|
267
|
+
expect(isEnterpriseFeatureEligible(PlanType.Enterprise)).toBe(true);
|
|
268
|
+
expect(isEnterpriseFeatureEligible()).toBe(true);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test("the Community Edition gets none", () => {
|
|
272
|
+
pinDeployment("self-hosted-community");
|
|
273
|
+
currentPlanForTest = PlanType.Enterprise;
|
|
274
|
+
|
|
275
|
+
expect(isEnterpriseFeatureEligible(PlanType.Scale)).toBe(false);
|
|
276
|
+
expect(isEnterpriseFeatureEligible(PlanType.Enterprise)).toBe(false);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test("does not even ask for the plan", () => {
|
|
280
|
+
pinDeployment("self-hosted-enterprise");
|
|
281
|
+
currentPlanThrows = true;
|
|
282
|
+
|
|
283
|
+
expect(isEnterpriseFeatureEligible(PlanType.Enterprise)).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
describe("isAuditLogsEnterpriseEligible", () => {
|
|
288
|
+
test("needs the Enterprise plan on the Cloud - Scale is not enough", () => {
|
|
289
|
+
pinDeployment("cloud");
|
|
290
|
+
|
|
291
|
+
currentPlanForTest = PlanType.Scale;
|
|
292
|
+
expect(isAuditLogsEnterpriseEligible()).toBe(false);
|
|
293
|
+
|
|
294
|
+
currentPlanForTest = PlanType.Enterprise;
|
|
295
|
+
expect(isAuditLogsEnterpriseEligible()).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("follows the edition when self-hosted", () => {
|
|
299
|
+
pinDeployment("self-hosted-enterprise");
|
|
300
|
+
expect(isAuditLogsEnterpriseEligible()).toBe(true);
|
|
301
|
+
|
|
302
|
+
pinDeployment("self-hosted-community");
|
|
303
|
+
expect(isAuditLogsEnterpriseEligible()).toBe(false);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
describe("the upsell wording (getEnterpriseUpgradeCopy)", () => {
|
|
308
|
+
test("sells the Scale plan, and says the plans above include it", () => {
|
|
309
|
+
const copy: EnterpriseUpgradeCopy = getEnterpriseUpgradeCopy({
|
|
310
|
+
featureName: "SAML Single Sign On",
|
|
311
|
+
requiredPlan: PlanType.Scale,
|
|
312
|
+
reason: EnterpriseUpgradeReason.Plan,
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
expect(copy.ctaTitle).toBe("Upgrade to Scale");
|
|
316
|
+
expect(copy.badge).toBe(PlanType.Scale);
|
|
317
|
+
expect(copy.pitchLine).toBe(
|
|
318
|
+
"SAML Single Sign On is available on the Scale plan and above. Upgrade to enable it for this project.",
|
|
319
|
+
);
|
|
320
|
+
expect(copy.ctaUrl).toBe("https://oneuptime.com/pricing");
|
|
321
|
+
expect(copy.secondaryTitle).toBe("Compare plans");
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test("sells the Enterprise plan as the top plan", () => {
|
|
325
|
+
const copy: EnterpriseUpgradeCopy = getEnterpriseUpgradeCopy({
|
|
326
|
+
featureName: "Team Compliance Rules",
|
|
327
|
+
requiredPlan: PlanType.Enterprise,
|
|
328
|
+
reason: EnterpriseUpgradeReason.Plan,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
expect(copy.ctaTitle).toBe("Upgrade to Enterprise");
|
|
332
|
+
expect(copy.pitchLine).toBe(
|
|
333
|
+
"Team Compliance Rules is available on the Enterprise plan. Upgrade to enable it for this project.",
|
|
334
|
+
);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test("points at the Enterprise Edition when the plan is not the problem", () => {
|
|
338
|
+
const copy: EnterpriseUpgradeCopy = getEnterpriseUpgradeCopy({
|
|
339
|
+
featureName: "OIDC",
|
|
340
|
+
requiredPlan: PlanType.Scale,
|
|
341
|
+
reason: EnterpriseUpgradeReason.Edition,
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
expect(copy.ctaTitle).toBe("Learn about Enterprise Edition");
|
|
345
|
+
expect(copy.badge).toBe("Enterprise");
|
|
346
|
+
expect(copy.ctaUrl).toBe("https://oneuptime.com/enterprise/overview");
|
|
347
|
+
expect(copy.secondaryTitle).toBe("Read docs");
|
|
348
|
+
expect(copy.secondaryUrl).toBe(
|
|
349
|
+
"https://oneuptime.com/docs/self-hosted/enterprise",
|
|
350
|
+
);
|
|
351
|
+
expect(copy.pitchLine).toBe(
|
|
352
|
+
"OIDC is a OneUptime Enterprise Edition feature. Switch to the Enterprise Edition build to enable it.",
|
|
353
|
+
);
|
|
354
|
+
// Never a plan upgrade.
|
|
355
|
+
expect(copy.pitchLine).not.toContain("plan");
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("uses a caller's own sentence for each reason", () => {
|
|
359
|
+
expect(
|
|
360
|
+
getEnterpriseUpgradeCopy({
|
|
361
|
+
featureName: "Audit Logs",
|
|
362
|
+
requiredPlan: PlanType.Enterprise,
|
|
363
|
+
reason: EnterpriseUpgradeReason.Plan,
|
|
364
|
+
planPitchLine: "Plan sentence.",
|
|
365
|
+
editionPitchLine: "Edition sentence.",
|
|
366
|
+
}).pitchLine,
|
|
367
|
+
).toBe("Plan sentence.");
|
|
368
|
+
|
|
369
|
+
expect(
|
|
370
|
+
getEnterpriseUpgradeCopy({
|
|
371
|
+
featureName: "Audit Logs",
|
|
372
|
+
requiredPlan: PlanType.Enterprise,
|
|
373
|
+
reason: EnterpriseUpgradeReason.Edition,
|
|
374
|
+
planPitchLine: "Plan sentence.",
|
|
375
|
+
editionPitchLine: "Edition sentence.",
|
|
376
|
+
}).pitchLine,
|
|
377
|
+
).toBe("Edition sentence.");
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test("defaults the reason from billing", () => {
|
|
381
|
+
pinDeployment("cloud");
|
|
382
|
+
expect(getDefaultUpgradeReason()).toBe(EnterpriseUpgradeReason.Plan);
|
|
383
|
+
|
|
384
|
+
pinDeployment("self-hosted-community");
|
|
385
|
+
expect(getDefaultUpgradeReason()).toBe(EnterpriseUpgradeReason.Edition);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
describe("EnterpriseFeatureUpgrade", () => {
|
|
390
|
+
const renderCard: (
|
|
391
|
+
extra?: Partial<React.ComponentProps<typeof EnterpriseFeatureUpgrade>>,
|
|
392
|
+
) => void = (
|
|
393
|
+
extra?: Partial<React.ComponentProps<typeof EnterpriseFeatureUpgrade>>,
|
|
394
|
+
): void => {
|
|
395
|
+
render(
|
|
396
|
+
<EnterpriseFeatureUpgrade
|
|
397
|
+
title="Single Sign On (SSO)"
|
|
398
|
+
description="Configure SAML SSO for your project."
|
|
399
|
+
featureName="SAML Single Sign On"
|
|
400
|
+
featureDescription="Let team members sign in with your IdP."
|
|
401
|
+
benefits={[
|
|
402
|
+
{
|
|
403
|
+
icon: IconProp.Lock,
|
|
404
|
+
title: "Centralized auth",
|
|
405
|
+
subtitle: "Revoke access from one place.",
|
|
406
|
+
},
|
|
407
|
+
]}
|
|
408
|
+
{...(extra || {})}
|
|
409
|
+
/>,
|
|
410
|
+
);
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
test("on the Cloud, sells the Scale plan by default and opens pricing", () => {
|
|
414
|
+
pinDeployment("cloud");
|
|
415
|
+
|
|
416
|
+
renderCard();
|
|
417
|
+
|
|
418
|
+
expect(screen.getByText("Single Sign On (SSO)")).toBeInTheDocument();
|
|
419
|
+
expect(screen.getByText("SAML Single Sign On")).toBeInTheDocument();
|
|
420
|
+
expect(
|
|
421
|
+
screen.getByText("Let team members sign in with your IdP."),
|
|
422
|
+
).toBeInTheDocument();
|
|
423
|
+
expect(screen.getByText("Centralized auth")).toBeInTheDocument();
|
|
424
|
+
expect(
|
|
425
|
+
screen.getByText(
|
|
426
|
+
"SAML Single Sign On is available on the Scale plan and above. Upgrade to enable it for this project.",
|
|
427
|
+
),
|
|
428
|
+
).toBeInTheDocument();
|
|
429
|
+
expect(screen.getByText("Compare plans")).toBeInTheDocument();
|
|
430
|
+
expect(screen.queryByText("Read docs")).not.toBeInTheDocument();
|
|
431
|
+
|
|
432
|
+
// The header button and the body button carry the same call to action.
|
|
433
|
+
const ctas: Array<HTMLElement> = screen.getAllByText("Upgrade to Scale");
|
|
434
|
+
expect(ctas).toHaveLength(2);
|
|
435
|
+
|
|
436
|
+
fireEvent.click(ctas[0]!);
|
|
437
|
+
expect(openMock).toHaveBeenCalledWith(
|
|
438
|
+
"https://oneuptime.com/pricing",
|
|
439
|
+
"_blank",
|
|
440
|
+
);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test("on the Cloud, an Enterprise-tier feature sells Enterprise", () => {
|
|
444
|
+
pinDeployment("cloud");
|
|
445
|
+
|
|
446
|
+
renderCard({ requiredPlan: PlanType.Enterprise });
|
|
447
|
+
|
|
448
|
+
expect(screen.getAllByText("Upgrade to Enterprise")).toHaveLength(2);
|
|
449
|
+
expect(
|
|
450
|
+
screen.getByText(
|
|
451
|
+
"SAML Single Sign On is available on the Enterprise plan. Upgrade to enable it for this project.",
|
|
452
|
+
),
|
|
453
|
+
).toBeInTheDocument();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
test("self-hosted, points at the Enterprise Edition and its docs", () => {
|
|
457
|
+
pinDeployment("self-hosted-community");
|
|
458
|
+
|
|
459
|
+
renderCard();
|
|
460
|
+
|
|
461
|
+
expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
|
|
462
|
+
2,
|
|
463
|
+
);
|
|
464
|
+
expect(screen.queryByText("Compare plans")).not.toBeInTheDocument();
|
|
465
|
+
|
|
466
|
+
fireEvent.click(screen.getByText("Read docs"));
|
|
467
|
+
expect(openMock).toHaveBeenCalledWith(
|
|
468
|
+
"https://oneuptime.com/docs/self-hosted/enterprise",
|
|
469
|
+
"_blank",
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test("an explicit Edition reason wins over billing", () => {
|
|
474
|
+
pinDeployment("cloud");
|
|
475
|
+
|
|
476
|
+
renderCard({ reason: EnterpriseUpgradeReason.Edition });
|
|
477
|
+
|
|
478
|
+
expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
|
|
479
|
+
2,
|
|
480
|
+
);
|
|
481
|
+
expect(screen.queryByText("Upgrade to Scale")).not.toBeInTheDocument();
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
describe("AuditLogsEnterpriseUpgrade", () => {
|
|
486
|
+
test("on the Cloud, sells the Enterprise plan with the audit log wording", () => {
|
|
487
|
+
pinDeployment("cloud");
|
|
488
|
+
|
|
489
|
+
render(
|
|
490
|
+
<AuditLogsEnterpriseUpgrade
|
|
491
|
+
title="Audit Logs"
|
|
492
|
+
description="Every change made in this project."
|
|
493
|
+
/>,
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
expect(
|
|
497
|
+
screen.getByText(
|
|
498
|
+
"Audit Logs are available on the Enterprise plan. Upgrade to turn on audit logging for this project.",
|
|
499
|
+
),
|
|
500
|
+
).toBeInTheDocument();
|
|
501
|
+
expect(screen.getAllByText("Upgrade to Enterprise")).toHaveLength(2);
|
|
502
|
+
// The default feature description and the audit log benefits.
|
|
503
|
+
expect(
|
|
504
|
+
screen.getByText(
|
|
505
|
+
"Record every create, update and delete performed on this project's resources.",
|
|
506
|
+
),
|
|
507
|
+
).toBeInTheDocument();
|
|
508
|
+
expect(screen.getByText("Track every change")).toBeInTheDocument();
|
|
509
|
+
expect(screen.getByText("Configurable retention")).toBeInTheDocument();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
test("self-hosted, points at the Enterprise Edition", () => {
|
|
513
|
+
pinDeployment("self-hosted-community");
|
|
514
|
+
|
|
515
|
+
render(
|
|
516
|
+
<AuditLogsEnterpriseUpgrade
|
|
517
|
+
title="Audit Logs"
|
|
518
|
+
description="Every change made in this project."
|
|
519
|
+
featureDescription="A custom description."
|
|
520
|
+
/>,
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
expect(
|
|
524
|
+
screen.getByText(
|
|
525
|
+
"Audit Logs are a OneUptime Enterprise Edition feature. Switch to the Enterprise Edition build to enable audit logging.",
|
|
526
|
+
),
|
|
527
|
+
).toBeInTheDocument();
|
|
528
|
+
expect(screen.getByText("A custom description.")).toBeInTheDocument();
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
test("passes an explicit reason through", () => {
|
|
532
|
+
pinDeployment("cloud");
|
|
533
|
+
|
|
534
|
+
render(
|
|
535
|
+
<AuditLogsEnterpriseUpgrade
|
|
536
|
+
title="Audit Logs"
|
|
537
|
+
description="Every change made in this project."
|
|
538
|
+
reason={EnterpriseUpgradeReason.Edition}
|
|
539
|
+
/>,
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
expect(screen.getAllByText("Learn about Enterprise Edition")).toHaveLength(
|
|
543
|
+
2,
|
|
544
|
+
);
|
|
545
|
+
expect(screen.queryByText("Upgrade to Enterprise")).not.toBeInTheDocument();
|
|
546
|
+
});
|
|
547
|
+
});
|