@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.
Files changed (333) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +23 -15
  2. package/Models/DatabaseModels/GlobalConfig.ts +24 -0
  3. package/Models/DatabaseModels/Monitor.ts +3 -2
  4. package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
  5. package/Scripts/generate-service-worker.js +65 -4
  6. package/Server/API/BaseAPI.ts +26 -5
  7. package/Server/API/GlobalConfigAPI.ts +228 -462
  8. package/Server/API/ProjectOIDC.ts +25 -16
  9. package/Server/API/ProjectSSO.ts +24 -16
  10. package/Server/API/StatusPageAPI.ts +100 -42
  11. package/Server/API/TeamMemberAPI.ts +10 -1
  12. package/Server/Enterprise/EnterpriseEdition.ts +649 -0
  13. package/Server/Enterprise/EnterpriseFeature.ts +48 -0
  14. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
  15. package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
  16. package/Server/EnvironmentConfig.ts +147 -2
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  19. package/Server/Middleware/UserAuthorization.ts +38 -16
  20. package/Server/Services/AuditLogService.ts +84 -1079
  21. package/Server/Services/EnterpriseLicenseService.ts +38 -0
  22. package/Server/Services/GlobalConfigService.ts +80 -1
  23. package/Server/Services/MonitorProbeService.ts +116 -20
  24. package/Server/Services/MonitorService.ts +56 -4
  25. package/Server/Services/MonitorStatusTimelineService.ts +284 -0
  26. package/Server/Services/MonitorTemplateService.ts +26 -0
  27. package/Server/Services/ProjectService.ts +284 -0
  28. package/Server/Services/RumSessionPinService.ts +25 -6
  29. package/Server/Services/StatusPagePrivateUserService.ts +7 -3
  30. package/Server/Services/StatusPageService.ts +78 -1
  31. package/Server/Services/TeamMemberService.ts +11 -0
  32. package/Server/Services/TeamService.ts +10 -0
  33. package/Server/Services/UserService.ts +10 -17
  34. package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
  35. package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
  36. package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
  37. package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
  38. package/Server/Types/Markdown.ts +41 -0
  39. package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
  40. package/Server/Utils/EditionEnforcement.ts +233 -0
  41. package/Server/Utils/FrontendEnvironment.ts +41 -2
  42. package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
  43. package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
  44. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
  45. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
  46. package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
  47. package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
  48. package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
  49. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
  50. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
  51. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
  52. package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
  53. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
  54. package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
  55. package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
  56. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
  57. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
  58. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
  59. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
  60. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
  61. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
  62. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
  63. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
  64. package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
  65. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
  66. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
  67. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
  68. package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
  69. package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
  70. package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
  71. package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
  72. package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
  73. package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
  74. package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
  75. package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
  76. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
  77. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
  78. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
  79. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
  80. package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
  81. package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
  82. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
  83. package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
  84. package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
  85. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
  86. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
  87. package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
  88. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
  89. package/Tests/Server/Services/AuditLogService.test.ts +460 -990
  90. package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
  91. package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
  92. package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
  93. package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
  94. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
  95. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
  96. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
  97. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
  98. package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
  99. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
  100. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
  101. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
  102. package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
  103. package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
  104. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
  105. package/Tests/Server/Types/Markdown.test.ts +181 -0
  106. package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
  107. package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
  108. package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
  109. package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
  110. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
  111. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
  112. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
  113. package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
  114. package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
  115. package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
  116. package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
  117. package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
  118. package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
  119. package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
  120. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
  121. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
  122. package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
  123. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
  124. package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
  125. package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
  126. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
  127. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
  128. package/Tests/Utils/HostAddressUtil.test.ts +138 -0
  129. package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
  130. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
  131. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
  132. package/Types/API/Hostname.ts +63 -16
  133. package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
  134. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
  135. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
  136. package/Types/Database/CanonicalModelInstance.ts +102 -0
  137. package/Types/Database/TableColumn.ts +20 -6
  138. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
  139. package/Types/IP/IPv6.ts +6 -1
  140. package/Types/Monitor/MonitorStep.ts +6 -1
  141. package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
  142. package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
  143. package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
  144. package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
  145. package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
  146. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  147. package/UI/Components/ModelList/ModelList.tsx +11 -1
  148. package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
  149. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
  150. package/UI/esbuild-enterprise.js +263 -0
  151. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
  152. package/Utils/HostAddressUtil.ts +94 -0
  153. package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
  154. package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
  155. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
  156. package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
  157. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  158. package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
  159. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  160. package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
  161. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  162. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
  163. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  164. package/build/dist/Server/API/BaseAPI.js +26 -5
  165. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  166. package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
  167. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  168. package/build/dist/Server/API/ProjectOIDC.js +24 -16
  169. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  170. package/build/dist/Server/API/ProjectSSO.js +24 -16
  171. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  172. package/build/dist/Server/API/StatusPageAPI.js +93 -43
  173. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  174. package/build/dist/Server/API/TeamMemberAPI.js +8 -1
  175. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  176. package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
  177. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
  178. package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
  179. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
  180. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
  181. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
  182. package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
  183. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
  184. package/build/dist/Server/EnvironmentConfig.js +84 -2
  185. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  186. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
  187. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
  188. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  189. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  190. package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
  191. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  192. package/build/dist/Server/Services/AuditLogService.js +71 -740
  193. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  194. package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
  195. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  196. package/build/dist/Server/Services/GlobalConfigService.js +63 -0
  197. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  198. package/build/dist/Server/Services/MonitorProbeService.js +90 -17
  199. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  200. package/build/dist/Server/Services/MonitorService.js +45 -4
  201. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  202. package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
  203. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  204. package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
  205. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  206. package/build/dist/Server/Services/ProjectService.js +214 -0
  207. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  208. package/build/dist/Server/Services/RumSessionPinService.js +24 -6
  209. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  210. package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
  211. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  212. package/build/dist/Server/Services/StatusPageService.js +71 -0
  213. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  214. package/build/dist/Server/Services/TeamMemberService.js +10 -0
  215. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  216. package/build/dist/Server/Services/TeamService.js +9 -0
  217. package/build/dist/Server/Services/TeamService.js.map +1 -1
  218. package/build/dist/Server/Services/UserService.js +10 -16
  219. package/build/dist/Server/Services/UserService.js.map +1 -1
  220. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
  221. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  222. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
  223. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  224. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
  225. package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
  226. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
  227. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  228. package/build/dist/Server/Types/Markdown.js +31 -0
  229. package/build/dist/Server/Types/Markdown.js.map +1 -1
  230. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
  231. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
  232. package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
  233. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
  234. package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
  235. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
  236. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
  237. package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
  238. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
  239. package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
  240. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  241. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  242. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +449 -261
  243. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  244. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
  245. package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
  246. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
  247. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  248. package/build/dist/Types/API/Hostname.js +59 -11
  249. package/build/dist/Types/API/Hostname.js.map +1 -1
  250. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
  251. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  252. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
  253. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  254. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
  255. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
  256. package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
  257. package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
  258. package/build/dist/Types/Database/TableColumn.js +19 -6
  259. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  260. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
  261. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
  262. package/build/dist/Types/IP/IPv6.js +6 -1
  263. package/build/dist/Types/IP/IPv6.js.map +1 -1
  264. package/build/dist/Types/Monitor/MonitorStep.js +5 -0
  265. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  266. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
  267. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
  268. package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
  269. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
  270. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  271. package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
  272. package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
  273. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
  274. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  275. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  276. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  277. package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
  278. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  279. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
  280. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  281. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
  282. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  283. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
  284. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  285. package/build/dist/Utils/HostAddressUtil.js +80 -0
  286. package/build/dist/Utils/HostAddressUtil.js.map +1 -0
  287. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
  288. package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
  289. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
  290. package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
  291. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  292. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
  293. package/jest.config.json +3 -1
  294. package/package.json +1 -1
  295. package/test-setup.sh +103 -34
  296. package/tsconfig.json +13 -0
  297. package/Server/API/EnterpriseLicenseAPI.ts +0 -925
  298. package/Server/API/TeamComplianceAPI.ts +0 -158
  299. package/Server/Middleware/SCIMAuthorization.ts +0 -141
  300. package/Server/Services/TeamComplianceService.ts +0 -733
  301. package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
  302. package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
  303. package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
  304. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
  305. package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
  306. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
  307. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
  308. package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
  309. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
  310. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
  311. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
  312. package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
  313. package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
  314. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
  315. package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
  316. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
  317. package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
  318. package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
  319. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
  320. package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
  321. package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
  322. package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
  323. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
  324. package/build/dist/Server/Services/TeamComplianceService.js +0 -537
  325. package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
  326. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
  327. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
  328. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
  329. package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
  330. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
  331. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
  332. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
  333. 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
+ });