@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
@@ -1,598 +0,0 @@
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 { act, cleanup, render, screen, within } from "@testing-library/react";
11
- import * as React from "react";
12
- import { MemoryRouter } from "react-router-dom";
13
- import getJestMockFunction, { MockFunction } from "../../MockType";
14
-
15
- /*
16
- * ---------------------------------------------------------------------------
17
- * The shared audit log table: the "logging is off" notice and its filters
18
- * ---------------------------------------------------------------------------
19
- *
20
- * Audit logging is off by default and switched on only in Settings, so for
21
- * most projects an empty audit page means "nothing is being recorded", not
22
- * "nothing changed" - and the table used to say the latter. It now reads the
23
- * project's switch (after the Enterprise check, so a project that cannot have
24
- * audit logs still gets the upsell card) and, when it is off, shows a compact
25
- * notice that links to the setting.
26
- *
27
- * Also pinned: the query each page asks for - a resource page that shows its
28
- * children filters on rootResourceId alone - and where each entry links.
29
- *
30
- * AnalyticsModelTable is mocked to capture its props (the real one fetches on
31
- * mount); the card's right element and empty state it would render are
32
- * rendered by the mock so the notice can be found in the DOM.
33
- */
34
-
35
- type CapturedColumn = {
36
- title: string;
37
- getElement?: ((item: AuditLog) => React.ReactElement) | undefined;
38
- };
39
-
40
- type CapturedTableProps = {
41
- query?: Record<string, unknown>;
42
- selectMoreFields?: Record<string, boolean>;
43
- cardProps?: {
44
- title?: string;
45
- description?: string;
46
- rightElement?: React.ReactElement | undefined;
47
- };
48
- noItemsMessage?: React.ReactElement;
49
- columns?: Array<CapturedColumn>;
50
- };
51
-
52
- let capturedTableProps: CapturedTableProps | null = null;
53
- let isEligibleForTest: boolean = true;
54
- const getItemMock: MockFunction = getJestMockFunction();
55
-
56
- jest.mock("../../../UI/Components/ModelTable/AnalyticsModelTable", () => {
57
- return {
58
- __esModule: true,
59
- default: (props: CapturedTableProps): React.ReactElement => {
60
- capturedTableProps = props;
61
- const react: typeof React = jest.requireActual("react") as typeof React;
62
-
63
- return react.createElement(
64
- "div",
65
- { "data-testid": "audit-logs-analytics-table" },
66
- props.cardProps?.rightElement || null,
67
- props.noItemsMessage || null,
68
- );
69
- },
70
- };
71
- });
72
-
73
- jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
74
- return {
75
- __esModule: true,
76
- default: {
77
- getItem: (...args: Array<unknown>): unknown => {
78
- return getItemMock(...args);
79
- },
80
- },
81
- };
82
- });
83
-
84
- jest.mock(
85
- "../../../../App/FeatureSet/Dashboard/src/Components/AuditLogs/AuditLogsEnterpriseUpgrade",
86
- () => {
87
- return {
88
- __esModule: true,
89
- isAuditLogsEnterpriseEligible: (): boolean => {
90
- return isEligibleForTest;
91
- },
92
- default: (props: { title: string }): React.ReactElement => {
93
- const react: typeof React = jest.requireActual("react") as typeof React;
94
-
95
- return react.createElement(
96
- "div",
97
- { "data-testid": "audit-logs-upsell" },
98
- props.title,
99
- );
100
- },
101
- };
102
- },
103
- );
104
-
105
- import AuditLogsTable, {
106
- ComponentProps,
107
- } from "../../../../App/FeatureSet/Dashboard/src/Components/AuditLogs/AuditLogsTable";
108
- import {
109
- RESOURCE_META,
110
- ResourceMeta,
111
- } from "../../../../App/FeatureSet/Dashboard/src/Components/AuditLogs/AuditLogsTableUtils";
112
- import PageMap from "../../../../App/FeatureSet/Dashboard/src/Utils/PageMap";
113
- import RouteMap, {
114
- RouteUtil,
115
- } from "../../../../App/FeatureSet/Dashboard/src/Utils/RouteMap";
116
- import RouteParams from "../../../../App/FeatureSet/Dashboard/src/Utils/RouteParams";
117
- import AuditLog from "../../../Models/AnalyticsModels/AuditLog";
118
- import Project from "../../../Models/DatabaseModels/Project";
119
- import Route from "../../../Types/API/Route";
120
- import ObjectID from "../../../Types/ObjectID";
121
- import ProjectUtil from "../../../UI/Utils/Project";
122
-
123
- const PROJECT_ID: ObjectID = new ObjectID(
124
- "11111111-1111-4111-8111-111111111111",
125
- );
126
- const SLO_ID: ObjectID = new ObjectID("33333333-3333-4333-8333-333333333333");
127
- const RULE_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
128
-
129
- type RenderTableFunction = (props?: Partial<ComponentProps>) => void;
130
-
131
- const renderTable: RenderTableFunction = (
132
- props?: Partial<ComponentProps>,
133
- ): void => {
134
- render(
135
- <MemoryRouter>
136
- <AuditLogsTable
137
- title="SLO Audit Logs"
138
- description="Changes people made to this SLO."
139
- {...(props || {})}
140
- />
141
- </MemoryRouter>,
142
- );
143
- };
144
-
145
- type ProjectWithFunction = (enableAuditLogs: boolean | undefined) => Project;
146
-
147
- const projectWith: ProjectWithFunction = (
148
- enableAuditLogs: boolean | undefined,
149
- ): Project => {
150
- const project: Project = new Project();
151
- project._id = PROJECT_ID.toString();
152
- if (enableAuditLogs !== undefined) {
153
- project.enableAuditLogs = enableAuditLogs;
154
- }
155
- return project;
156
- };
157
-
158
- type RouteHrefFunction = (
159
- page: PageMap,
160
- modelId?: ObjectID,
161
- subModelId?: ObjectID,
162
- ) => string;
163
-
164
- const routeHref: RouteHrefFunction = (
165
- page: PageMap,
166
- modelId?: ObjectID,
167
- subModelId?: ObjectID,
168
- ): string => {
169
- return RouteUtil.populateRouteParams(
170
- RouteMap[page] as Route,
171
- modelId ? { modelId, subModelId } : undefined,
172
- ).toString();
173
- };
174
-
175
- // Lets the settings read resolve and its state update land.
176
- type FlushFunction = () => Promise<void>;
177
-
178
- const flushSettingsRead: FlushFunction = async (): Promise<void> => {
179
- await act(async () => {
180
- await Promise.resolve();
181
- await Promise.resolve();
182
- });
183
- };
184
-
185
- beforeEach(() => {
186
- capturedTableProps = null;
187
- isEligibleForTest = true;
188
- getItemMock.mockReset();
189
- jest.spyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(PROJECT_ID);
190
- });
191
-
192
- afterEach(() => {
193
- cleanup();
194
- jest.restoreAllMocks();
195
- });
196
-
197
- describe("the audit logging switch", () => {
198
- test("a project that cannot have audit logs gets the upsell card, and no settings read", async () => {
199
- isEligibleForTest = false;
200
- getItemMock.mockResolvedValue(projectWith(false));
201
-
202
- renderTable({ rootResourceId: SLO_ID });
203
- await flushSettingsRead();
204
-
205
- expect(screen.getByTestId("audit-logs-upsell")).toHaveTextContent(
206
- "SLO Audit Logs",
207
- );
208
- expect(screen.queryByTestId("audit-logs-analytics-table")).toBeNull();
209
- expect(screen.queryByTestId("audit-logging-disabled-notice")).toBeNull();
210
- expect(getItemMock).not.toHaveBeenCalled();
211
- });
212
-
213
- test("when logging is off, a compact notice links to the Audit Logs settings", async () => {
214
- getItemMock.mockResolvedValue(projectWith(false));
215
-
216
- renderTable({ rootResourceId: SLO_ID });
217
-
218
- const notice: HTMLElement = await screen.findByTestId(
219
- "audit-logging-disabled-notice",
220
- );
221
- const settingsHref: string = routeHref(
222
- PageMap.SETTINGS_AUDIT_LOGS_SETTINGS,
223
- );
224
-
225
- expect(settingsHref).toContain(PROJECT_ID.toString());
226
- expect(notice).toHaveTextContent("Audit logging is off");
227
- expect(within(notice).getByRole("link")).toHaveAttribute(
228
- "href",
229
- settingsHref,
230
- );
231
-
232
- // It sits in the card header, not above the page as a banner.
233
- expect(capturedTableProps?.cardProps?.rightElement).toBeDefined();
234
-
235
- const emptyState: HTMLElement = screen.getByTestId(
236
- "audit-logging-disabled-empty-state",
237
- );
238
- expect(emptyState).toHaveTextContent("Audit logging is turned off");
239
- expect(within(emptyState).getByRole("link")).toHaveAttribute(
240
- "href",
241
- settingsHref,
242
- );
243
-
244
- expect(getItemMock).toHaveBeenCalledTimes(1);
245
- expect(getItemMock.mock.calls[0]![0]).toEqual({
246
- modelType: Project,
247
- id: PROJECT_ID,
248
- select: { enableAuditLogs: true },
249
- });
250
- });
251
-
252
- test("when logging is on, there is no notice and the empty state is the ordinary one", async () => {
253
- getItemMock.mockResolvedValue(projectWith(true));
254
-
255
- renderTable({ rootResourceId: SLO_ID });
256
- await flushSettingsRead();
257
-
258
- expect(getItemMock).toHaveBeenCalledTimes(1);
259
- expect(screen.queryByTestId("audit-logging-disabled-notice")).toBeNull();
260
- expect(
261
- screen.queryByTestId("audit-logging-disabled-empty-state"),
262
- ).toBeNull();
263
- expect(screen.getByText("No audit entries yet")).toBeInTheDocument();
264
- });
265
-
266
- test.each([
267
- {
268
- name: "the read fails",
269
- respond: (): void => {
270
- getItemMock.mockRejectedValue(new Error("403"));
271
- },
272
- },
273
- {
274
- name: "the project is not returned",
275
- respond: (): void => {
276
- getItemMock.mockResolvedValue(null);
277
- },
278
- },
279
- {
280
- name: "the switch was not readable",
281
- respond: (): void => {
282
- getItemMock.mockResolvedValue(projectWith(undefined));
283
- },
284
- },
285
- ])(
286
- "no notice is guessed when $name",
287
- async (data: { respond: () => void }) => {
288
- data.respond();
289
-
290
- renderTable({ rootResourceId: SLO_ID });
291
- await flushSettingsRead();
292
-
293
- expect(getItemMock).toHaveBeenCalledTimes(1);
294
- expect(screen.queryByTestId("audit-logging-disabled-notice")).toBeNull();
295
- expect(screen.getByText("No audit entries yet")).toBeInTheDocument();
296
- },
297
- );
298
-
299
- test("outside a project there is nothing to read", async () => {
300
- jest.spyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(null);
301
-
302
- renderTable();
303
- await flushSettingsRead();
304
-
305
- expect(getItemMock).not.toHaveBeenCalled();
306
- });
307
- });
308
-
309
- describe("the rows a table asks for", () => {
310
- beforeEach(() => {
311
- getItemMock.mockResolvedValue(projectWith(true));
312
- });
313
-
314
- test("a resource page with children filters on the root pointer alone", async () => {
315
- renderTable({ rootResourceId: SLO_ID });
316
- await flushSettingsRead();
317
-
318
- expect(capturedTableProps?.query).toEqual({
319
- projectId: PROJECT_ID,
320
- rootResourceId: SLO_ID,
321
- });
322
- expect(capturedTableProps?.selectMoreFields?.["rootResourceId"]).toBe(true);
323
- });
324
-
325
- test("a resource page without children still filters on its own type and id", async () => {
326
- renderTable({ resourceType: "Monitor", resourceId: RULE_ID });
327
- await flushSettingsRead();
328
-
329
- expect(capturedTableProps?.query).toEqual({
330
- projectId: PROJECT_ID,
331
- resourceType: "Monitor",
332
- resourceId: RULE_ID,
333
- });
334
- });
335
-
336
- test("the project-wide log filters on the project only", async () => {
337
- renderTable();
338
- await flushSettingsRead();
339
-
340
- expect(capturedTableProps?.query).toEqual({ projectId: PROJECT_ID });
341
- });
342
- });
343
-
344
- describe("where an entry links to", () => {
345
- type RenderResourceCellFunction = (item: AuditLog) => void;
346
-
347
- const renderResourceCell: RenderResourceCellFunction = (
348
- item: AuditLog,
349
- ): void => {
350
- const column: CapturedColumn | undefined =
351
- capturedTableProps?.columns?.find((candidate: CapturedColumn) => {
352
- return candidate.title === "Resource";
353
- });
354
-
355
- expect(column?.getElement).toBeDefined();
356
-
357
- render(
358
- <MemoryRouter>
359
- <div data-testid="resource-cell">{column!.getElement!(item)}</div>
360
- </MemoryRouter>,
361
- );
362
- };
363
-
364
- type MakeEntryFunction = (data: {
365
- resourceType: string;
366
- resourceId: ObjectID;
367
- rootResourceId?: ObjectID | undefined;
368
- action: string;
369
- resourceName: string;
370
- }) => AuditLog;
371
-
372
- const makeEntry: MakeEntryFunction = (data: {
373
- resourceType: string;
374
- resourceId: ObjectID;
375
- rootResourceId?: ObjectID | undefined;
376
- action: string;
377
- resourceName: string;
378
- }): AuditLog => {
379
- const entry: AuditLog = new AuditLog();
380
- entry.resourceType = data.resourceType;
381
- entry.resourceId = data.resourceId;
382
- entry.rootResourceId = data.rootResourceId;
383
- entry.action = data.action;
384
- entry.resourceName = data.resourceName;
385
- return entry;
386
- };
387
-
388
- beforeEach(async () => {
389
- getItemMock.mockResolvedValue(projectWith(true));
390
- renderTable({ rootResourceId: SLO_ID });
391
- await flushSettingsRead();
392
- cleanup();
393
- });
394
-
395
- test("an SLO's own entry opens the SLO", () => {
396
- renderResourceCell(
397
- makeEntry({
398
- resourceType: "Service Level Objective",
399
- resourceId: SLO_ID,
400
- rootResourceId: SLO_ID,
401
- action: "Update",
402
- resourceName: "Checkout availability",
403
- }),
404
- );
405
-
406
- expect(screen.getByRole("link")).toHaveAttribute(
407
- "href",
408
- routeHref(PageMap.SLO_VIEW, SLO_ID),
409
- );
410
- });
411
-
412
- test("a deleted SLO's entry opens nothing", () => {
413
- renderResourceCell(
414
- makeEntry({
415
- resourceType: "Service Level Objective",
416
- resourceId: SLO_ID,
417
- rootResourceId: SLO_ID,
418
- action: "Delete",
419
- resourceName: "Checkout availability",
420
- }),
421
- );
422
-
423
- expect(screen.getByTestId("resource-cell")).toHaveTextContent(
424
- "Checkout availability",
425
- );
426
- expect(screen.queryByRole("link")).toBeNull();
427
- });
428
-
429
- test("a burn-rate rule's entry opens its SLO's Burn Rate Rules tab, even once the rule is deleted", () => {
430
- renderResourceCell(
431
- makeEntry({
432
- resourceType: "SLO Burn Rate Rule",
433
- resourceId: RULE_ID,
434
- rootResourceId: SLO_ID,
435
- action: "Delete",
436
- resourceName: "Fast burn",
437
- }),
438
- );
439
-
440
- expect(screen.getByRole("link")).toHaveAttribute(
441
- "href",
442
- routeHref(PageMap.SLO_VIEW_BURN_RATE_RULES, SLO_ID),
443
- );
444
- expect(screen.getByTestId("resource-cell")).toHaveTextContent(
445
- "SLO Burn Rate Rule",
446
- );
447
- });
448
-
449
- test("an owner entry opens its SLO's Owners tab", () => {
450
- renderResourceCell(
451
- makeEntry({
452
- resourceType: "Service Level Objective Team Owner",
453
- resourceId: RULE_ID,
454
- rootResourceId: SLO_ID,
455
- action: "Create",
456
- resourceName: "Site Reliability",
457
- }),
458
- );
459
-
460
- expect(screen.getByRole("link")).toHaveAttribute(
461
- "href",
462
- routeHref(PageMap.SLO_VIEW_OWNERS, SLO_ID),
463
- );
464
- });
465
-
466
- test.each(["Create", "Update"])(
467
- "a monitor rule's %s entry opens the rule's own page under its SLO",
468
- (action: string) => {
469
- renderResourceCell(
470
- makeEntry({
471
- resourceType: "SLO Monitor Rule",
472
- resourceId: RULE_ID,
473
- rootResourceId: SLO_ID,
474
- action,
475
- resourceName: "Production APIs",
476
- }),
477
- );
478
-
479
- const ruleHref: string = routeHref(
480
- PageMap.SLO_VIEW_MONITOR_RULE_VIEW,
481
- SLO_ID,
482
- RULE_ID,
483
- );
484
-
485
- // Both ids really land in the path: the SLO's, then the rule's.
486
- expect(ruleHref).toContain(
487
- `/slos/${SLO_ID.toString()}/monitor-rules/${RULE_ID.toString()}`,
488
- );
489
- expect(screen.getByRole("link")).toHaveAttribute("href", ruleHref);
490
- },
491
- );
492
-
493
- test("a deleted monitor rule's entry opens its SLO's Monitor Rules tab, not the rule's page that is gone", () => {
494
- renderResourceCell(
495
- makeEntry({
496
- resourceType: "SLO Monitor Rule",
497
- resourceId: RULE_ID,
498
- rootResourceId: SLO_ID,
499
- action: "Delete",
500
- resourceName: "Production APIs",
501
- }),
502
- );
503
-
504
- const link: HTMLElement = screen.getByRole("link");
505
-
506
- expect(link).toHaveAttribute(
507
- "href",
508
- routeHref(PageMap.SLO_VIEW_MONITOR_RULES, SLO_ID),
509
- );
510
- expect(link.getAttribute("href")).not.toContain(RULE_ID.toString());
511
- });
512
-
513
- test.each(["SLO Monitor Rule", "SLO Burn Rate Rule"])(
514
- "an %s entry rooted at itself (the root backfill's fallback) opens nothing, rather than a page keyed by the rule's own id",
515
- (resourceType: string) => {
516
- renderResourceCell(
517
- makeEntry({
518
- resourceType,
519
- resourceId: RULE_ID,
520
- rootResourceId: new ObjectID(RULE_ID.toString()),
521
- action: "Update",
522
- resourceName: "Production APIs",
523
- }),
524
- );
525
-
526
- expect(screen.getByTestId("resource-cell")).toHaveTextContent(
527
- "Production APIs",
528
- );
529
- expect(screen.queryByRole("link")).toBeNull();
530
- },
531
- );
532
-
533
- test("a burn-rate rule has no page of its own, so even a live rule's entry opens its SLO's tab", () => {
534
- renderResourceCell(
535
- makeEntry({
536
- resourceType: "SLO Burn Rate Rule",
537
- resourceId: RULE_ID,
538
- rootResourceId: SLO_ID,
539
- action: "Update",
540
- resourceName: "Fast burn",
541
- }),
542
- );
543
-
544
- expect(screen.getByRole("link")).toHaveAttribute(
545
- "href",
546
- routeHref(PageMap.SLO_VIEW_BURN_RATE_RULES, SLO_ID),
547
- );
548
- });
549
-
550
- test("every page of a child's own that an entry can open is a real route keyed by the root and the child", () => {
551
- const childPages: Array<PageMap> = [];
552
-
553
- for (const meta of Object.values(RESOURCE_META)) {
554
- const typedMeta: ResourceMeta = meta;
555
-
556
- if (typedMeta.childViewRoute) {
557
- childPages.push(typedMeta.childViewRoute);
558
- }
559
- }
560
-
561
- expect(childPages).toContain(PageMap.SLO_VIEW_MONITOR_RULE_VIEW);
562
-
563
- for (const page of childPages) {
564
- const route: Route | undefined = RouteMap[page];
565
-
566
- expect(route).toBeDefined();
567
- expect(route!.toString()).toContain(`/${RouteParams.ModelID}/`);
568
- expect(route!.toString()).toContain(`/${RouteParams.SubModelID}`);
569
- }
570
- });
571
-
572
- test("a child entry with no root pointer (written before the backfill) opens nothing", () => {
573
- renderResourceCell(
574
- makeEntry({
575
- resourceType: "SLO Monitor Rule",
576
- resourceId: RULE_ID,
577
- action: "Update",
578
- resourceName: "Production APIs",
579
- }),
580
- );
581
-
582
- expect(screen.queryByRole("link")).toBeNull();
583
- });
584
-
585
- test("an unknown resource type opens nothing", () => {
586
- renderResourceCell(
587
- makeEntry({
588
- resourceType: "Something New",
589
- resourceId: RULE_ID,
590
- rootResourceId: RULE_ID,
591
- action: "Update",
592
- resourceName: "Mystery",
593
- }),
594
- );
595
-
596
- expect(screen.queryByRole("link")).toBeNull();
597
- });
598
- });