@oneuptime/common 12.0.13 → 12.0.14

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 (376) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  2. package/Models/DatabaseModels/UserCall.ts +94 -3
  3. package/Models/DatabaseModels/UserEmail.ts +94 -3
  4. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  5. package/Models/DatabaseModels/UserPush.ts +37 -0
  6. package/Models/DatabaseModels/UserSMS.ts +94 -3
  7. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  8. package/Server/API/BaseAPI.ts +79 -14
  9. package/Server/API/UserCallAPI.ts +53 -45
  10. package/Server/API/UserEmailAPI.ts +53 -44
  11. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  12. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  13. package/Server/API/UserPushAPI.ts +126 -2
  14. package/Server/API/UserSmsAPI.ts +53 -44
  15. package/Server/API/UserWhatsAppAPI.ts +53 -50
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  21. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  22. package/Server/Services/DatabaseService.ts +101 -0
  23. package/Server/Services/LogAggregationService.ts +5 -0
  24. package/Server/Services/PushNotificationService.ts +127 -12
  25. package/Server/Services/TeamMemberService.ts +53 -13
  26. package/Server/Services/UserCallService.ts +55 -24
  27. package/Server/Services/UserEmailService.ts +83 -17
  28. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  29. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  30. package/Server/Services/UserNotificationRuleService.ts +26 -0
  31. package/Server/Services/UserPushService.ts +89 -0
  32. package/Server/Services/UserSmsService.ts +50 -17
  33. package/Server/Services/UserWhatsAppService.ts +48 -15
  34. package/Server/Types/Database/QueryHelper.ts +30 -0
  35. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  36. package/Server/Utils/ChannelVerification.ts +510 -0
  37. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  38. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  39. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  40. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  41. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  42. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  43. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  44. package/Server/Utils/TotpAuth.ts +137 -9
  45. package/Server/Utils/UserRegistrationToken.ts +182 -0
  46. package/Server/Utils/VerificationCode.ts +134 -0
  47. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  48. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  49. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  50. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  51. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  52. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  53. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  54. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  55. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  56. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  57. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  58. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  59. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  60. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  61. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  62. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  63. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  64. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  65. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  66. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  67. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  68. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  69. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  70. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  71. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  72. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  73. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  74. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  75. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  76. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  77. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  78. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  79. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  80. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  81. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  82. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  83. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  84. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  85. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  86. package/Tests/Server/Utils/Browser.test.ts +162 -0
  87. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  88. package/Tests/Server/Utils/Express.test.ts +371 -0
  89. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  91. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  92. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  93. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  94. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  95. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  96. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  97. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  98. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  99. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  100. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  101. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  102. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  103. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  104. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  105. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  106. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  107. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  108. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  109. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  110. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  111. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  112. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  113. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  114. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  115. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  116. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  117. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  118. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  119. package/Tests/UI/Components/Button.test.tsx +175 -1
  120. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  121. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  122. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  123. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  124. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  125. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  126. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  127. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  128. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  129. package/Tests/UI/Components/List.test.tsx +9 -2
  130. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  131. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  132. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  133. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  134. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  135. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  136. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  137. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  138. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  139. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  140. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  141. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  142. package/Tests/UI/Components/Toast.test.tsx +130 -7
  143. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  144. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  145. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  146. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  147. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  148. package/Tests/Utils/API.test.ts +16 -2
  149. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  150. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  151. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  152. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  153. package/Types/Email/EmailTemplateType.ts +1 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  155. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  156. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  157. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  158. package/Types/Permission.ts +35 -0
  159. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  160. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  161. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  162. package/Types/Service/ServiceLanguage.ts +144 -0
  163. package/Types/Text.ts +111 -19
  164. package/UI/Components/Button/Button.tsx +27 -14
  165. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  166. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  167. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  168. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  169. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  170. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  171. package/UI/Components/CommandPalette/Types.ts +49 -0
  172. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  173. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  174. package/UI/Components/Feed/FeedItem.tsx +1 -1
  175. package/UI/Components/List/List.tsx +37 -5
  176. package/UI/Components/List/ListSkeleton.tsx +54 -0
  177. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  178. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  179. package/UI/Components/Modal/Modal.tsx +2 -2
  180. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  181. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  182. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  183. package/UI/Components/Navbar/NavBar.tsx +14 -1
  184. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  185. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  186. package/UI/Components/SideOver/SideOver.tsx +37 -2
  187. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  188. package/UI/Components/Table/Table.tsx +74 -44
  189. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  190. package/UI/Components/Tabs/Tab.tsx +1 -1
  191. package/UI/Components/Toast/Toast.tsx +118 -53
  192. package/UI/Components/Toast/ToastInit.tsx +82 -32
  193. package/UI/Styles/Theme.css +40 -0
  194. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  195. package/UI/Utils/ModelListCache.ts +188 -0
  196. package/UI/Utils/Project.ts +29 -0
  197. package/Utils/API.ts +6 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  201. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  203. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  205. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  207. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  209. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  211. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  212. package/build/dist/Server/API/BaseAPI.js +69 -13
  213. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  214. package/build/dist/Server/API/UserCallAPI.js +42 -38
  215. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  216. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  217. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  218. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  219. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  220. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  221. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  222. package/build/dist/Server/API/UserPushAPI.js +95 -2
  223. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  224. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  225. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  226. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  227. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  236. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  237. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  239. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  240. package/build/dist/Server/Services/DatabaseService.js +74 -0
  241. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  245. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  246. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  247. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  248. package/build/dist/Server/Services/UserCallService.js +54 -22
  249. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  250. package/build/dist/Server/Services/UserEmailService.js +78 -17
  251. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  252. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  253. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  254. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  255. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  256. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  257. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  258. package/build/dist/Server/Services/UserPushService.js +77 -0
  259. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  260. package/build/dist/Server/Services/UserSmsService.js +50 -17
  261. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  262. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  263. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  264. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  265. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  266. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  267. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  268. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  269. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  270. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  271. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  272. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  273. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  274. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  275. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  276. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  277. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  278. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  279. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  280. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  281. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  282. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  283. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  284. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  285. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  286. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  287. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  288. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  289. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  290. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  291. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  292. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  293. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  294. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  295. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  296. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  297. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  298. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  299. package/build/dist/Types/Permission.js +33 -0
  300. package/build/dist/Types/Permission.js.map +1 -1
  301. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  302. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  303. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  304. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  305. package/build/dist/Types/Text.js +82 -17
  306. package/build/dist/Types/Text.js.map +1 -1
  307. package/build/dist/UI/Components/Button/Button.js +22 -14
  308. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  309. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  310. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  311. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  312. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  313. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  314. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  315. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  316. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  317. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  318. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  319. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  320. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  321. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  322. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  323. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  324. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  325. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  326. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  327. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  328. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  329. package/build/dist/UI/Components/List/List.js +19 -5
  330. package/build/dist/UI/Components/List/List.js.map +1 -1
  331. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  332. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  333. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  334. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  335. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  338. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  340. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  343. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  344. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  345. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  346. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  347. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  348. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  349. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  350. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  351. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  352. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  353. package/build/dist/UI/Components/Table/Table.js +35 -24
  354. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  355. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  356. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  357. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  358. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  359. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  360. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  361. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  362. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  363. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  364. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  365. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  366. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  367. package/build/dist/UI/Utils/Project.js +24 -1
  368. package/build/dist/UI/Utils/Project.js.map +1 -1
  369. package/build/dist/Utils/API.js +6 -1
  370. package/build/dist/Utils/API.js.map +1 -1
  371. package/jest.config.json +1 -1
  372. package/package.json +2 -3
  373. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  374. package/Tests/__mocks__/otpauth.js +0 -30
  375. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  376. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -36,8 +36,9 @@ import SeriesResourceLinker, {
36
36
  } from "../../../../Server/Utils/Monitor/SeriesResourceLinker";
37
37
  import Includes from "../../../../Types/BaseDatabase/Includes";
38
38
  import { JSONObject } from "../../../../Types/JSON";
39
+ import MonitorType from "../../../../Types/Monitor/MonitorType";
39
40
  import ObjectID from "../../../../Types/ObjectID";
40
- import { MonitorClusterContext } from "../../../../Server/Utils/Monitor/MonitorClusterContext";
41
+
41
42
  import {
42
43
  afterEach,
43
44
  beforeEach,
@@ -176,8 +177,13 @@ function includesValues(value: unknown): Array<string> {
176
177
  });
177
178
  }
178
179
 
179
- function emptyClusterContext(): MonitorClusterContext {
180
+ function emptyResourceContext(): SeriesResolvedResourceIds {
180
181
  return {
182
+ hostIds: [],
183
+ dockerHostIds: [],
184
+ podmanHostIds: [],
185
+ kubernetesClusterIds: [],
186
+ serviceIds: [],
181
187
  proxmoxClusterIds: [],
182
188
  cephClusterIds: [],
183
189
  dockerSwarmClusterIds: [],
@@ -356,6 +362,73 @@ describe("SeriesResourceLinker.linkSeriesResourcesToModel", () => {
356
362
  },
357
363
  );
358
364
 
365
+ test.each([[MonitorType.Docker], [MonitorType.Podman]])(
366
+ "a %s monitor's host.name label links no Host",
367
+ async (monitorType: MonitorType) => {
368
+ /*
369
+ * The container agents stamp the box their containers run on under
370
+ * the generic `resource.host.name`, which the label key map hands
371
+ * to Host. On a Docker/Podman monitor that value names a
372
+ * DockerHost / PodmanHost row, so honouring the map would attach an
373
+ * unrelated Host and surface the event on that host's Activity tab.
374
+ * The step-config path (MonitorStepResourceIdentity) links the
375
+ * right model instead.
376
+ */
377
+ rowsByRelation.set("hosts", [{ _id: "host-1" }]);
378
+
379
+ const alert: Alert = new Alert();
380
+
381
+ await SeriesResourceLinker.linkSeriesResourcesToModel({
382
+ model: alert,
383
+ seriesLabels: { "host.name": "docker-prod-01" },
384
+ projectId: PROJECT_ID,
385
+ monitorType: monitorType,
386
+ });
387
+
388
+ expect(alert.hosts).toBeUndefined();
389
+ expect(HostService.findBy).not.toHaveBeenCalled();
390
+ },
391
+ );
392
+
393
+ test("a host.name label still links a Host for every other monitor type", async () => {
394
+ // The suppression must be scoped to the two container types only.
395
+ rowsByRelation.set("hosts", [{ _id: "host-1" }]);
396
+
397
+ const alert: Alert = new Alert();
398
+
399
+ await SeriesResourceLinker.linkSeriesResourcesToModel({
400
+ model: alert,
401
+ seriesLabels: { "host.name": "prod-01" },
402
+ projectId: PROJECT_ID,
403
+ monitorType: MonitorType.Host,
404
+ });
405
+
406
+ expect(idsOn(alert, "hosts")).toEqual(["host-1"]);
407
+ });
408
+
409
+ test("a Docker monitor still links the docker host its labels name", async () => {
410
+ /*
411
+ * Suppression must drop ONLY the host refs — the DockerHost the
412
+ * series actually identifies has to survive.
413
+ */
414
+ rowsByRelation.set("dockerHosts", [{ _id: "docker-1" }]);
415
+
416
+ const alert: Alert = new Alert();
417
+
418
+ await SeriesResourceLinker.linkSeriesResourcesToModel({
419
+ model: alert,
420
+ seriesLabels: {
421
+ "host.name": "docker-prod-01",
422
+ "oneuptime.docker.host.name": "docker-prod-01",
423
+ },
424
+ projectId: PROJECT_ID,
425
+ monitorType: MonitorType.Docker,
426
+ });
427
+
428
+ expect(alert.hosts).toBeUndefined();
429
+ expect(idsOn(alert, "dockerHosts")).toEqual(["docker-1"]);
430
+ });
431
+
359
432
  test("a bare host name never resolves a docker or podman host", async () => {
360
433
  /*
361
434
  * Docker/Podman hosts are deliberately addressed only by their own
@@ -596,13 +669,14 @@ describe("SeriesResourceLinker.resolveResourcesFromSeriesLabels", () => {
596
669
  });
597
670
  });
598
671
 
599
- describe("SeriesResourceLinker.attachClusterContext", () => {
600
- test("attaches the monitor-step clusters", () => {
672
+ describe("SeriesResourceLinker.attachResolvedResources", () => {
673
+ test("attaches the monitor-step resources", () => {
601
674
  const alert: Alert = new Alert();
602
675
 
603
- SeriesResourceLinker.attachClusterContext({
676
+ SeriesResourceLinker.attachResolvedResources({
604
677
  model: alert,
605
- clusterContext: {
678
+ resolved: {
679
+ ...emptyResourceContext(),
606
680
  proxmoxClusterIds: ["pve-1"],
607
681
  cephClusterIds: ["ceph-1"],
608
682
  dockerSwarmClusterIds: ["swarm-1"],
@@ -633,10 +707,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
633
707
  projectId: PROJECT_ID,
634
708
  });
635
709
 
636
- SeriesResourceLinker.attachClusterContext({
710
+ SeriesResourceLinker.attachResolvedResources({
637
711
  model: alert,
638
- clusterContext: {
639
- ...emptyClusterContext(),
712
+ resolved: {
713
+ ...emptyResourceContext(),
640
714
  proxmoxClusterIds: ["pve-from-step-config"],
641
715
  },
642
716
  });
@@ -658,10 +732,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
658
732
  projectId: PROJECT_ID,
659
733
  });
660
734
 
661
- SeriesResourceLinker.attachClusterContext({
735
+ SeriesResourceLinker.attachResolvedResources({
662
736
  model: alert,
663
- clusterContext: {
664
- ...emptyClusterContext(),
737
+ resolved: {
738
+ ...emptyResourceContext(),
665
739
  cephClusterIds: ["ceph-1"],
666
740
  },
667
741
  });
@@ -669,12 +743,12 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
669
743
  expect(idsOn(alert, "cephClusters")).toEqual(["ceph-1"]);
670
744
  });
671
745
 
672
- test("leaves every relation untouched when the monitor has no clusters", () => {
746
+ test("leaves every relation untouched when the monitor names no resource", () => {
673
747
  const alert: Alert = new Alert();
674
748
 
675
- SeriesResourceLinker.attachClusterContext({
749
+ SeriesResourceLinker.attachResolvedResources({
676
750
  model: alert,
677
- clusterContext: emptyClusterContext(),
751
+ resolved: emptyResourceContext(),
678
752
  });
679
753
 
680
754
  expect(alert.proxmoxClusters).toBeUndefined();
@@ -686,10 +760,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
686
760
  test("attaches to an incident the same way", () => {
687
761
  const incident: Incident = new Incident();
688
762
 
689
- SeriesResourceLinker.attachClusterContext({
763
+ SeriesResourceLinker.attachResolvedResources({
690
764
  model: incident,
691
- clusterContext: {
692
- ...emptyClusterContext(),
765
+ resolved: {
766
+ ...emptyResourceContext(),
693
767
  dockerSwarmClusterIds: ["swarm-1"],
694
768
  },
695
769
  });
@@ -0,0 +1,267 @@
1
+ import PushNotificationUtil from "../../../Server/Utils/PushNotificationUtil";
2
+ import PushNotificationMessage from "../../../Types/PushNotification/PushNotificationMessage";
3
+ import { describe, expect, test } from "@jest/globals";
4
+
5
+ /*
6
+ * Behavioural coverage for the PushNotificationUtil creators that the sibling
7
+ * PushNotificationUtil.test.ts does not touch. Each creator is a pure builder,
8
+ * but each carries real display logic a responder sees on a locked screen:
9
+ * which identifier the title shows (a prefixed number, a bare #number, or just
10
+ * the title), whether a note reads as Private or Public, and whether a click
11
+ * target is wired through. A regression in any of these is a page that opens
12
+ * the wrong thing or leaks the wrong label, so they are pinned here.
13
+ */
14
+
15
+ describe("PushNotificationUtil untested creators", () => {
16
+ describe("defaults are applied to every creator", () => {
17
+ test("icon and badge are stamped on by applyDefaults", () => {
18
+ const message: PushNotificationMessage =
19
+ PushNotificationUtil.createOnCallPolicyAddedNotification({
20
+ policyName: "Primary",
21
+ });
22
+
23
+ expect(message.icon).toBe(PushNotificationUtil.DEFAULT_ICON);
24
+ expect(message.badge).toBe(PushNotificationUtil.DEFAULT_BADGE);
25
+ });
26
+ });
27
+
28
+ describe("createAlertCreatedNotification - display number precedence", () => {
29
+ test("a prefixed number wins over a bare number in title and body", () => {
30
+ const message: PushNotificationMessage =
31
+ PushNotificationUtil.createAlertCreatedNotification({
32
+ alertTitle: "Disk full",
33
+ projectName: "Acme",
34
+ alertViewLink: "https://x/alert/1",
35
+ alertNumber: 12,
36
+ alertNumberWithPrefix: "ALERT-12",
37
+ alertId: "a1",
38
+ projectId: "p1",
39
+ });
40
+
41
+ expect(message.title).toBe("New Alert ALERT-12: Disk full");
42
+ expect(message.body).toContain("ALERT-12 (Disk full)");
43
+ expect(message.body).toContain("in Acme");
44
+ });
45
+
46
+ test("a bare number is rendered as #number when no prefix is given", () => {
47
+ const message: PushNotificationMessage =
48
+ PushNotificationUtil.createAlertCreatedNotification({
49
+ alertTitle: "Disk full",
50
+ projectName: "Acme",
51
+ alertViewLink: "https://x/alert/1",
52
+ alertNumber: 12,
53
+ });
54
+
55
+ expect(message.title).toBe("New Alert #12: Disk full");
56
+ expect(message.body).toContain("#12 (Disk full)");
57
+ });
58
+
59
+ test("with neither number the identifier is just the title", () => {
60
+ const message: PushNotificationMessage =
61
+ PushNotificationUtil.createAlertCreatedNotification({
62
+ alertTitle: "Disk full",
63
+ projectName: "Acme",
64
+ alertViewLink: "https://x/alert/1",
65
+ });
66
+
67
+ expect(message.title).toBe("New Alert: Disk full");
68
+ // No leading space and no parenthesised number when there is no number.
69
+ expect(message.body).toContain("created: Disk full in Acme");
70
+ expect(message.title).not.toContain(" ");
71
+ });
72
+
73
+ test("wires clickAction, url and requireInteraction, and carries the payload", () => {
74
+ const link: string = "https://dashboard/alert/42";
75
+ const message: PushNotificationMessage =
76
+ PushNotificationUtil.createAlertCreatedNotification({
77
+ alertTitle: "Disk full",
78
+ projectName: "Acme",
79
+ alertViewLink: link,
80
+ alertId: "a42",
81
+ projectId: "p9",
82
+ });
83
+
84
+ expect(message.clickAction).toBe(link);
85
+ expect(message.url).toBe(link);
86
+ expect(message.requireInteraction).toBe(true);
87
+ expect(message.tag).toBe("alert-created");
88
+ expect(message.data).toMatchObject({
89
+ type: "alert-created",
90
+ entityType: "alert",
91
+ entityId: "a42",
92
+ projectId: "p9",
93
+ url: link,
94
+ });
95
+ });
96
+ });
97
+
98
+ describe("createAlertEpisodeCreatedNotification", () => {
99
+ test("uses the alert-episode tag, title and payload type", () => {
100
+ const message: PushNotificationMessage =
101
+ PushNotificationUtil.createAlertEpisodeCreatedNotification({
102
+ alertEpisodeTitle: "Cascade",
103
+ projectName: "Acme",
104
+ alertEpisodeViewLink: "https://x/ep/1",
105
+ episodeNumberWithPrefix: "EP-3",
106
+ });
107
+
108
+ expect(message.title).toBe("New Alert Episode EP-3: Cascade");
109
+ expect(message.tag).toBe("alert-episode-created");
110
+ expect(message.data).toMatchObject({
111
+ type: "alert-episode-created",
112
+ entityType: "alert-episode",
113
+ });
114
+ });
115
+ });
116
+
117
+ describe("createIncidentEpisodeCreatedNotification", () => {
118
+ test("uses the incident-episode tag and title", () => {
119
+ const message: PushNotificationMessage =
120
+ PushNotificationUtil.createIncidentEpisodeCreatedNotification({
121
+ incidentEpisodeTitle: "Cascade",
122
+ projectName: "Acme",
123
+ incidentEpisodeViewLink: "https://x/ep/1",
124
+ episodeNumber: 7,
125
+ });
126
+
127
+ expect(message.title).toBe("New Incident Episode #7: Cascade");
128
+ expect(message.tag).toBe("incident-episode-created");
129
+ expect(message.data).toMatchObject({
130
+ type: "incident-episode-created",
131
+ entityType: "incident-episode",
132
+ });
133
+ });
134
+ });
135
+
136
+ describe("createIncidentNotePostedNotification - note visibility", () => {
137
+ test("a private note reads as Private in title, body and payload", () => {
138
+ const message: PushNotificationMessage =
139
+ PushNotificationUtil.createIncidentNotePostedNotification({
140
+ incidentTitle: "API down",
141
+ projectName: "Acme",
142
+ isPrivateNote: true,
143
+ incidentViewLink: "https://x/i/1",
144
+ incidentNumberWithPrefix: "INC-5",
145
+ });
146
+
147
+ expect(message.title).toBe(
148
+ "Private Note Added: Incident INC-5 - API down",
149
+ );
150
+ expect(message.body).toContain("A private note has been posted");
151
+ expect(message.data).toMatchObject({ isPrivateNote: true });
152
+ });
153
+
154
+ test("a public note reads as Public - the visibility is not swapped", () => {
155
+ const message: PushNotificationMessage =
156
+ PushNotificationUtil.createIncidentNotePostedNotification({
157
+ incidentTitle: "API down",
158
+ projectName: "Acme",
159
+ isPrivateNote: false,
160
+ incidentViewLink: "https://x/i/1",
161
+ });
162
+
163
+ expect(message.title).toContain("Public Note Added");
164
+ expect(message.body).toContain("A public note has been posted");
165
+ expect(message.data).toMatchObject({ isPrivateNote: false });
166
+ });
167
+ });
168
+
169
+ describe("on-call policy membership notifications", () => {
170
+ test("added names the policy and uses the added tag", () => {
171
+ const message: PushNotificationMessage =
172
+ PushNotificationUtil.createOnCallPolicyAddedNotification({
173
+ policyName: "Primary",
174
+ });
175
+
176
+ expect(message.title).toBe("Added to On-Call Policy");
177
+ expect(message.body).toContain(
178
+ "added to the on-call duty policy Primary",
179
+ );
180
+ expect(message.tag).toBe("on-call-policy-added");
181
+ expect(message.requireInteraction).toBe(false);
182
+ });
183
+
184
+ test("removed names the policy and uses the removed tag", () => {
185
+ const message: PushNotificationMessage =
186
+ PushNotificationUtil.createOnCallPolicyRemovedNotification({
187
+ policyName: "Primary",
188
+ });
189
+
190
+ expect(message.title).toBe("Removed from On-Call Policy");
191
+ expect(message.body).toContain(
192
+ "removed from the on-call duty policy Primary",
193
+ );
194
+ expect(message.tag).toBe("on-call-policy-removed");
195
+ });
196
+
197
+ test("added and removed are distinguishable - different title, body and tag", () => {
198
+ const added: PushNotificationMessage =
199
+ PushNotificationUtil.createOnCallPolicyAddedNotification({
200
+ policyName: "Primary",
201
+ });
202
+ const removed: PushNotificationMessage =
203
+ PushNotificationUtil.createOnCallPolicyRemovedNotification({
204
+ policyName: "Primary",
205
+ });
206
+
207
+ expect(added.title).not.toBe(removed.title);
208
+ expect(added.body).not.toBe(removed.body);
209
+ expect(added.tag).not.toBe(removed.tag);
210
+ });
211
+ });
212
+
213
+ describe("createProbeStatusChangedNotification - the conditional click target", () => {
214
+ test("without a clickAction, no url/clickAction is wired", () => {
215
+ const message: PushNotificationMessage =
216
+ PushNotificationUtil.createProbeStatusChangedNotification({
217
+ probeName: "eu-west",
218
+ projectName: "Acme",
219
+ connectionStatus: "connected",
220
+ });
221
+
222
+ expect(message.title).toBe("Probe connected: eu-west");
223
+ expect(message.clickAction).toBeUndefined();
224
+ expect(message.url).toBeUndefined();
225
+ expect(message.data).not.toHaveProperty("url");
226
+ });
227
+
228
+ test("with a clickAction, it is mirrored onto url and into the payload", () => {
229
+ const link: string = "https://dashboard/probe/eu-west";
230
+ const message: PushNotificationMessage =
231
+ PushNotificationUtil.createProbeStatusChangedNotification({
232
+ probeName: "eu-west",
233
+ projectName: "Acme",
234
+ connectionStatus: "disconnected",
235
+ clickAction: link,
236
+ });
237
+
238
+ expect(message.title).toBe("Probe disconnected: eu-west");
239
+ expect(message.clickAction).toBe(link);
240
+ expect(message.url).toBe(link);
241
+ expect(message.data).toMatchObject({ url: link });
242
+ });
243
+ });
244
+
245
+ describe("createMonitorProbeStatusNotification", () => {
246
+ test("passes title/body/tag straight through and stamps the type", () => {
247
+ const message: PushNotificationMessage =
248
+ PushNotificationUtil.createMonitorProbeStatusNotification({
249
+ title: "Monitor degraded",
250
+ body: "eu-west probe cannot reach API",
251
+ tag: "monitor-probe-status-degraded",
252
+ monitorId: "m1",
253
+ monitorName: "API",
254
+ });
255
+
256
+ expect(message.title).toBe("Monitor degraded");
257
+ expect(message.body).toBe("eu-west probe cannot reach API");
258
+ expect(message.tag).toBe("monitor-probe-status-degraded");
259
+ expect(message.requireInteraction).toBe(false);
260
+ expect(message.data).toMatchObject({
261
+ type: "monitor-probe-status",
262
+ monitorId: "m1",
263
+ monitorName: "API",
264
+ });
265
+ });
266
+ });
267
+ });