@oneuptime/common 12.0.9 → 12.0.11

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 (262) hide show
  1. package/Models/DatabaseModels/NetworkDevice.ts +44 -0
  2. package/Models/DatabaseModels/NetworkDeviceLink.ts +116 -0
  3. package/Models/DatabaseModels/RunnerJob.ts +17 -2
  4. package/Server/API/LlmProviderAPI.ts +8 -0
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.ts +52 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  7. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +240 -0
  8. package/Server/Services/NetworkDeviceLinkService.ts +338 -2
  9. package/Server/Services/NetworkDeviceService.ts +265 -12
  10. package/Server/Services/RunnerJobService.ts +24 -1
  11. package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +19 -5
  12. package/Server/Types/Database/JSONColumnQuery.ts +42 -4
  13. package/Server/Utils/LLM/LLMService.ts +108 -19
  14. package/Server/Utils/Monitor/MonitorAlert.ts +22 -115
  15. package/Server/Utils/Monitor/MonitorIncident.ts +7 -337
  16. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +27 -2
  17. package/Server/Utils/Monitor/SeriesResourceLabels.ts +32 -0
  18. package/Server/Utils/Monitor/SeriesResourceLinker.ts +469 -0
  19. package/Server/Utils/SSRFProtection.ts +5 -4
  20. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +186 -38
  21. package/Tests/App/AdminDashboard/AdminUsersBulkAddToProject.test.tsx +955 -0
  22. package/Tests/App/AdminDashboard/BulkAddUsersToProject.test.ts +778 -0
  23. package/Tests/App/AdminDashboard/BulkAddUsersToProjectModal.test.tsx +1051 -0
  24. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +420 -112
  25. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +81 -6
  26. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +543 -0
  27. package/Tests/App/Dashboard/PayAsYouGoFreePlan.test.ts +125 -0
  28. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +612 -0
  29. package/Tests/App/Dashboard/SloWidgetChartRendering.test.tsx +536 -0
  30. package/Tests/App/Dashboard/UserElementEmail.test.tsx +447 -0
  31. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +284 -0
  32. package/Tests/Models/AnalyticsModels/CommonModel.test.ts +312 -0
  33. package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +250 -0
  34. package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +46 -18
  35. package/Tests/Server/Services/NetworkDeviceLabelRuleRun.test.ts +618 -0
  36. package/Tests/Server/Services/NetworkDeviceLinkParentValidation.test.ts +1043 -0
  37. package/Tests/Server/Services/NetworkSiteAssignmentRuleRun.test.ts +706 -0
  38. package/Tests/Server/Services/RunnerJobEnqueue.test.ts +412 -0
  39. package/Tests/Server/Types/Billing/PayAsYouGoMeteredPricing.test.ts +125 -0
  40. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +508 -0
  41. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +2 -2
  42. package/Tests/Server/Utils/AI/LLMServiceRetryPolicy.test.ts +450 -0
  43. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +556 -0
  44. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +547 -0
  45. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +30 -0
  46. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +699 -0
  47. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +55 -0
  48. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +668 -0
  49. package/Tests/Types/API/URLMalformedTolerance.test.ts +301 -0
  50. package/Tests/Types/API/URLTelScheme.test.ts +261 -0
  51. package/Tests/Types/API/URLUnsupportedScheme.test.ts +148 -0
  52. package/Tests/Types/Billing/PayAsYouGoPricing.test.ts +64 -0
  53. package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +107 -0
  54. package/Tests/Types/Monitor/MonitorType.test.ts +62 -0
  55. package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +184 -0
  56. package/Tests/Types/Runbook/RunbookStepType.test.ts +124 -0
  57. package/Tests/Types/Workflow/BaseModelComponents.test.ts +17 -0
  58. package/Tests/UI/Components/Button.test.tsx +279 -0
  59. package/Tests/UI/Components/Charts/ChartXAxisDataKey.test.tsx +256 -0
  60. package/Tests/UI/Components/Charts/DataPointUtil.test.ts +323 -0
  61. package/Tests/UI/Components/DictionaryValuePlaceholderAndSuggestions.test.tsx +595 -0
  62. package/Tests/UI/Components/Icon.test.tsx +57 -0
  63. package/Tests/UI/Components/List.test.tsx +20 -3
  64. package/Tests/UI/Components/LogsSavedViewsDropdown.test.tsx +304 -0
  65. package/Tests/UI/Components/LogsViewerClearSavedView.test.tsx +179 -0
  66. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +349 -1
  67. package/Tests/UI/Components/Pagination.test.tsx +721 -146
  68. package/Tests/UI/Components/PaginationIntegration.test.tsx +386 -0
  69. package/Tests/UI/Components/PaginationUtil.test.ts +417 -0
  70. package/Tests/UI/Components/TelemetrySavedViewsDropdown.test.tsx +343 -0
  71. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnControl.test.ts +289 -0
  72. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnOperators.test.ts +271 -0
  73. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRow.test.ts +119 -0
  74. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.test.ts +968 -0
  75. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +766 -0
  76. package/Tests/UI/Utils/RunNetworkRule.test.ts +320 -0
  77. package/Tests/Utils/APIRetryPolicy.test.ts +823 -0
  78. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +502 -0
  79. package/Tests/Utils/Monitor/NetworkTopologyDeclaredHierarchy.test.ts +759 -0
  80. package/Tests/Utils/NetworkAutomation/RuleRunSummary.test.ts +286 -0
  81. package/Tests/Utils/Schema/BaseSchema.test.ts +651 -0
  82. package/Types/API/Protocol.ts +9 -0
  83. package/Types/API/URL.ts +286 -20
  84. package/Types/Billing/PayAsYouGoPricing.ts +47 -0
  85. package/Types/CustomField/CustomFieldType.ts +28 -0
  86. package/Types/Monitor/MonitorType.ts +11 -0
  87. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
  88. package/Types/NetworkAutomation/RuleRunResult.ts +121 -0
  89. package/Types/Runbook/RunbookStepType.ts +23 -0
  90. package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +7 -0
  91. package/UI/Components/Button/Button.tsx +14 -22
  92. package/UI/Components/Charts/Area/AreaChart.tsx +4 -2
  93. package/UI/Components/Charts/Bar/BarChart.tsx +4 -2
  94. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +13 -0
  95. package/UI/Components/Charts/Line/LineChart.tsx +4 -2
  96. package/UI/Components/Charts/Types/XAxis/XAxis.ts +6 -0
  97. package/UI/Components/Charts/Utils/DataPoint.ts +15 -12
  98. package/UI/Components/Dictionary/Dictionary.tsx +4 -39
  99. package/UI/Components/Icon/Icon.tsx +1 -1
  100. package/UI/Components/LogsViewer/LogsViewer.tsx +5 -1
  101. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +8 -0
  102. package/UI/Components/LogsViewer/components/LogsPagination.tsx +29 -91
  103. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +2 -0
  104. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +66 -1
  105. package/UI/Components/ModelTable/CustomFieldColumns.tsx +55 -0
  106. package/UI/Components/Pagination/Pagination.tsx +373 -328
  107. package/UI/Components/Pagination/PaginationUtil.ts +263 -0
  108. package/UI/Components/Pagination/Screenshots/README.md +15 -0
  109. package/UI/Components/Pagination/Screenshots/pagination-before-after.png +0 -0
  110. package/UI/Components/Pagination/Screenshots/pagination-go-to-page-modal.png +0 -0
  111. package/UI/Components/Pagination/Screenshots/pagination-long-list.png +0 -0
  112. package/UI/Components/Pagination/Screenshots/pagination-mobile.png +0 -0
  113. package/UI/Components/Pagination/Screenshots/pagination-telemetry.png +0 -0
  114. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +66 -1
  115. package/UI/Components/TelemetryViewer/components/TelemetryPagination.tsx +38 -92
  116. package/UI/Components/TextArea/TextArea.tsx +3 -0
  117. package/UI/Components/Workflow/ArgumentsForm.tsx +18 -1
  118. package/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.tsx +177 -0
  119. package/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.tsx +243 -0
  120. package/UI/Components/Workflow/ColumnEditor/ColumnControl.ts +255 -0
  121. package/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.tsx +178 -0
  122. package/UI/Components/Workflow/ColumnEditor/ColumnOperators.ts +206 -0
  123. package/UI/Components/Workflow/ColumnEditor/ColumnRow.ts +157 -0
  124. package/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.ts +517 -0
  125. package/UI/Components/Workflow/ColumnEditor/ColumnValueInput.tsx +482 -0
  126. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +131 -0
  127. package/UI/Components/Workflow/ColumnEditor/ModelRecordForm.tsx +163 -0
  128. package/UI/Components/Workflow/ModelColumnEditor.tsx +284 -100
  129. package/UI/Utils/NetworkAutomation/RunNetworkRule.ts +122 -0
  130. package/Utils/API.ts +243 -36
  131. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +45 -0
  132. package/Utils/Monitor/NetworkTopologyUtil.ts +42 -2
  133. package/Utils/NetworkAutomation/RuleRunSummary.ts +147 -0
  134. package/build/dist/Models/DatabaseModels/NetworkDevice.js +45 -0
  135. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  136. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +115 -0
  137. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -1
  138. package/build/dist/Models/DatabaseModels/RunnerJob.js +17 -2
  139. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  140. package/build/dist/Server/API/LlmProviderAPI.js +9 -1
  141. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js +33 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js.map +1 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  146. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +202 -0
  147. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  148. package/build/dist/Server/Services/NetworkDeviceLinkService.js +253 -1
  149. package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -1
  150. package/build/dist/Server/Services/NetworkDeviceService.js +223 -12
  151. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  152. package/build/dist/Server/Services/RunnerJobService.js +20 -2
  153. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  154. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +12 -5
  155. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
  156. package/build/dist/Server/Types/Database/JSONColumnQuery.js +40 -4
  157. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -1
  158. package/build/dist/Server/Utils/LLM/LLMService.js +78 -22
  159. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  160. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -98
  161. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  162. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +7 -254
  163. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  164. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +14 -2
  165. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  166. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +27 -0
  167. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  168. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +285 -0
  169. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -0
  170. package/build/dist/Server/Utils/SSRFProtection.js +5 -4
  171. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  172. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +128 -35
  173. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  174. package/build/dist/Types/API/Protocol.js +9 -0
  175. package/build/dist/Types/API/Protocol.js.map +1 -1
  176. package/build/dist/Types/API/URL.js +241 -18
  177. package/build/dist/Types/API/URL.js.map +1 -1
  178. package/build/dist/Types/Billing/PayAsYouGoPricing.js +41 -0
  179. package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -0
  180. package/build/dist/Types/CustomField/CustomFieldType.js +26 -0
  181. package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
  182. package/build/dist/Types/Monitor/MonitorType.js +10 -0
  183. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  184. package/build/dist/Types/NetworkAutomation/RuleRunResult.js +39 -0
  185. package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -0
  186. package/build/dist/Types/Runbook/RunbookStepType.js +21 -0
  187. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  188. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
  189. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
  190. package/build/dist/UI/Components/Button/Button.js +10 -16
  191. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  192. package/build/dist/UI/Components/Charts/Area/AreaChart.js +2 -1
  193. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  194. package/build/dist/UI/Components/Charts/Bar/BarChart.js +2 -1
  195. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  196. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +12 -0
  197. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
  198. package/build/dist/UI/Components/Charts/Line/LineChart.js +2 -1
  199. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  200. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +17 -10
  201. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  202. package/build/dist/UI/Components/Dictionary/Dictionary.js +4 -18
  203. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  204. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  205. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  206. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +3 -3
  207. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  208. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +5 -1
  209. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  210. package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js +14 -44
  211. package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js.map +1 -1
  212. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  213. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  214. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +20 -2
  215. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  216. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +42 -0
  217. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  218. package/build/dist/UI/Components/Pagination/Pagination.js +174 -199
  219. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  220. package/build/dist/UI/Components/Pagination/PaginationUtil.js +160 -0
  221. package/build/dist/UI/Components/Pagination/PaginationUtil.js.map +1 -0
  222. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +20 -2
  223. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  224. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js +23 -47
  225. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js.map +1 -1
  226. package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
  227. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  228. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +14 -2
  229. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  230. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js +86 -0
  231. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js.map +1 -0
  232. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js +119 -0
  233. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js.map +1 -0
  234. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js +206 -0
  235. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js.map +1 -0
  236. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js +57 -0
  237. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js.map +1 -0
  238. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js +150 -0
  239. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js.map +1 -0
  240. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js +67 -0
  241. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js.map +1 -0
  242. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js +309 -0
  243. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js.map +1 -0
  244. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js +204 -0
  245. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js.map +1 -0
  246. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +66 -0
  247. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -0
  248. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js +83 -0
  249. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js.map +1 -0
  250. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +187 -68
  251. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
  252. package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js +75 -0
  253. package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js.map +1 -0
  254. package/build/dist/Utils/API.js +175 -34
  255. package/build/dist/Utils/API.js.map +1 -1
  256. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +37 -0
  257. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
  258. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +25 -3
  259. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  260. package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js +78 -0
  261. package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js.map +1 -0
  262. package/package.json +1 -1
@@ -0,0 +1,320 @@
1
+ import API from "../../../UI/Utils/API/API";
2
+ import RunNetworkRule, {
3
+ NetworkRuleKind,
4
+ NetworkRuleRunOutcome,
5
+ } from "../../../UI/Utils/NetworkAutomation/RunNetworkRule";
6
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
7
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
8
+ import URL from "../../../Types/API/URL";
9
+ import { JSONObject } from "../../../Types/JSON";
10
+ import { afterEach, describe, expect, it, jest } from "@jest/globals";
11
+
12
+ /*
13
+ * Contract under test - the dashboard half of "Run now"
14
+ * (OneUptime/oneuptime#3191).
15
+ *
16
+ * Three things can only go wrong here, and all three are invisible from the
17
+ * server: posting to the wrong route (nothing runs and the user sees a 404),
18
+ * sending the overwrite flag as anything other than a real boolean (the
19
+ * endpoint reads only a literal true, so a run silently declines to do what
20
+ * the checkbox promised), and turning a failure into a blank modal.
21
+ */
22
+
23
+ const RULE_ID: string = "44444444-4444-4444-8444-444444444444";
24
+
25
+ function successResponse(body: JSONObject): HTTPResponse<JSONObject> {
26
+ return new HTTPResponse<JSONObject>(200, body, {});
27
+ }
28
+
29
+ function mockPost(
30
+ response: HTTPResponse<JSONObject> | HTTPErrorResponse,
31
+ ): jest.SpiedFunction<typeof API.post> {
32
+ return jest.spyOn(API, "post").mockResolvedValue(response as never) as any;
33
+ }
34
+
35
+ function lastPostArgs(spy: jest.SpiedFunction<typeof API.post>): {
36
+ url: URL;
37
+ data: JSONObject;
38
+ headers?: Record<string, string> | undefined;
39
+ } {
40
+ return (spy.mock.calls[0] as Array<unknown>)[0] as {
41
+ url: URL;
42
+ data: JSONObject;
43
+ headers?: Record<string, string> | undefined;
44
+ };
45
+ }
46
+
47
+ const SITE_RUN_RESULT: JSONObject = {
48
+ devicesEvaluated: 40,
49
+ devicesMatched: 12,
50
+ devicesAssigned: 12,
51
+ devicesAlreadyInRuleSite: 0,
52
+ devicesSkippedAlreadyInAnotherSite: 0,
53
+ devicesClaimedByHigherPriorityRule: 0,
54
+ devicesFailed: 0,
55
+ isTruncated: false,
56
+ };
57
+
58
+ const LABEL_RUN_RESULT: JSONObject = {
59
+ devicesEvaluated: 40,
60
+ devicesMatched: 12,
61
+ devicesLabeled: 12,
62
+ labelsAttached: 24,
63
+ labelsFailed: 0,
64
+ isTruncated: false,
65
+ };
66
+
67
+ describe("RunNetworkRule.getRunRoute", () => {
68
+ it("routes a site assignment rule to its own endpoint", () => {
69
+ expect(
70
+ RunNetworkRule.getRunRoute({
71
+ ruleKind: NetworkRuleKind.SiteAssignment,
72
+ ruleId: RULE_ID,
73
+ }),
74
+ ).toBe(`/network-site-assignment-rule/${RULE_ID}/run`);
75
+ });
76
+
77
+ it("routes a label rule to its own endpoint", () => {
78
+ expect(
79
+ RunNetworkRule.getRunRoute({
80
+ ruleKind: NetworkRuleKind.DeviceLabel,
81
+ ruleId: RULE_ID,
82
+ }),
83
+ ).toBe(`/network-device-label-rule/${RULE_ID}/run`);
84
+ });
85
+ });
86
+
87
+ describe("RunNetworkRule.run", () => {
88
+ afterEach(() => {
89
+ jest.restoreAllMocks();
90
+ });
91
+
92
+ describe("the request", () => {
93
+ it("posts to the site assignment endpoint for that rule kind", async () => {
94
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
95
+ successResponse(SITE_RUN_RESULT),
96
+ );
97
+
98
+ await RunNetworkRule.run({
99
+ ruleKind: NetworkRuleKind.SiteAssignment,
100
+ ruleId: RULE_ID,
101
+ });
102
+
103
+ expect(lastPostArgs(spy).url.toString()).toContain(
104
+ `/network-site-assignment-rule/${RULE_ID}/run`,
105
+ );
106
+ });
107
+
108
+ it("posts to the label rule endpoint for that rule kind", async () => {
109
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
110
+ successResponse(LABEL_RUN_RESULT),
111
+ );
112
+
113
+ await RunNetworkRule.run({
114
+ ruleKind: NetworkRuleKind.DeviceLabel,
115
+ ruleId: RULE_ID,
116
+ });
117
+
118
+ expect(lastPostArgs(spy).url.toString()).toContain(
119
+ `/network-device-label-rule/${RULE_ID}/run`,
120
+ );
121
+ });
122
+
123
+ /*
124
+ * The tenantid header is what scopes the run to the current project. A
125
+ * request without it is refused by the endpoint, so the caller's headers
126
+ * have to survive this hop.
127
+ */
128
+ it("passes the caller's headers through", async () => {
129
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
130
+ successResponse(SITE_RUN_RESULT),
131
+ );
132
+
133
+ await RunNetworkRule.run({
134
+ ruleKind: NetworkRuleKind.SiteAssignment,
135
+ ruleId: RULE_ID,
136
+ headers: { tenantid: "project-1" },
137
+ });
138
+
139
+ expect(lastPostArgs(spy).headers).toEqual({ tenantid: "project-1" });
140
+ });
141
+
142
+ it("sends the overwrite flag off unless it was asked for", async () => {
143
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
144
+ successResponse(SITE_RUN_RESULT),
145
+ );
146
+
147
+ await RunNetworkRule.run({
148
+ ruleKind: NetworkRuleKind.SiteAssignment,
149
+ ruleId: RULE_ID,
150
+ });
151
+
152
+ expect(lastPostArgs(spy).data).toEqual({
153
+ reassignDevicesAlreadyInASite: false,
154
+ });
155
+ });
156
+
157
+ /*
158
+ * A real boolean, not a truthy value: the endpoint reads only a literal
159
+ * true, so anything else would leave the checkbox looking broken.
160
+ */
161
+ it("sends the overwrite flag as a literal boolean", async () => {
162
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
163
+ successResponse(SITE_RUN_RESULT),
164
+ );
165
+
166
+ await RunNetworkRule.run({
167
+ ruleKind: NetworkRuleKind.SiteAssignment,
168
+ ruleId: RULE_ID,
169
+ reassignDevicesAlreadyInASite: true,
170
+ });
171
+
172
+ expect(lastPostArgs(spy).data["reassignDevicesAlreadyInASite"]).toBe(
173
+ true,
174
+ );
175
+ });
176
+
177
+ // A label run has nothing to overwrite, so it must not carry the flag.
178
+ it("never sends the overwrite flag for a label rule", async () => {
179
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
180
+ successResponse(LABEL_RUN_RESULT),
181
+ );
182
+
183
+ await RunNetworkRule.run({
184
+ ruleKind: NetworkRuleKind.DeviceLabel,
185
+ ruleId: RULE_ID,
186
+ reassignDevicesAlreadyInASite: true,
187
+ });
188
+
189
+ expect(lastPostArgs(spy).data).toEqual({});
190
+ });
191
+
192
+ /*
193
+ * An empty id would post to `/…//run`, which matches no route and comes
194
+ * back as a 404 that says nothing about the real problem.
195
+ */
196
+ it("refuses to post a rule with no id", async () => {
197
+ const spy: jest.SpiedFunction<typeof API.post> = mockPost(
198
+ successResponse(SITE_RUN_RESULT),
199
+ );
200
+
201
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
202
+ ruleKind: NetworkRuleKind.SiteAssignment,
203
+ ruleId: "",
204
+ });
205
+
206
+ expect(spy).not.toHaveBeenCalled();
207
+ expect(outcome.isSuccess).toBe(false);
208
+ expect(outcome.message).toContain("no id");
209
+ });
210
+ });
211
+
212
+ describe("the answer", () => {
213
+ it("summarises a site assignment run", async () => {
214
+ mockPost(successResponse(SITE_RUN_RESULT));
215
+
216
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
217
+ ruleKind: NetworkRuleKind.SiteAssignment,
218
+ ruleId: RULE_ID,
219
+ });
220
+
221
+ expect(outcome.isSuccess).toBe(true);
222
+ expect(outcome.message).toContain(
223
+ "Assigned 12 devices to this rule's site.",
224
+ );
225
+ });
226
+
227
+ it("summarises a label rule run", async () => {
228
+ mockPost(successResponse(LABEL_RUN_RESULT));
229
+
230
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
231
+ ruleKind: NetworkRuleKind.DeviceLabel,
232
+ ruleId: RULE_ID,
233
+ });
234
+
235
+ expect(outcome.isSuccess).toBe(true);
236
+ expect(outcome.message).toContain("Labelled 12 devices");
237
+ });
238
+
239
+ /*
240
+ * The kinds must not be summarised with each other's sentences - a label
241
+ * run reported as "assigned 0 devices" would read as a failure.
242
+ */
243
+ it("does not describe a label run in site assignment terms", async () => {
244
+ mockPost(successResponse(LABEL_RUN_RESULT));
245
+
246
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
247
+ ruleKind: NetworkRuleKind.DeviceLabel,
248
+ ruleId: RULE_ID,
249
+ });
250
+
251
+ expect(outcome.message).not.toContain("Assigned");
252
+ });
253
+
254
+ it("explains a run that changed nothing rather than reporting success blankly", async () => {
255
+ mockPost(
256
+ successResponse({
257
+ ...SITE_RUN_RESULT,
258
+ devicesAssigned: 0,
259
+ devicesSkippedAlreadyInAnotherSite: 12,
260
+ }),
261
+ );
262
+
263
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
264
+ ruleKind: NetworkRuleKind.SiteAssignment,
265
+ ruleId: RULE_ID,
266
+ });
267
+
268
+ expect(outcome.isSuccess).toBe(true);
269
+ expect(outcome.message).toContain("No devices were reassigned.");
270
+ expect(outcome.message).toContain("already belong to another site");
271
+ });
272
+
273
+ /*
274
+ * An empty body still has to produce a sentence. A server that answered
275
+ * with nothing must not leave the modal blank.
276
+ */
277
+ it("survives a response carrying no counters", async () => {
278
+ mockPost(successResponse({}));
279
+
280
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
281
+ ruleKind: NetworkRuleKind.SiteAssignment,
282
+ ruleId: RULE_ID,
283
+ });
284
+
285
+ expect(outcome.isSuccess).toBe(true);
286
+ expect(outcome.message).toContain("No devices were reassigned.");
287
+ });
288
+ });
289
+
290
+ describe("failures", () => {
291
+ it("reports a failure response as a message, not a success", async () => {
292
+ mockPost(
293
+ new HTTPErrorResponse(400, { message: "Label rule not found." }, {}),
294
+ );
295
+
296
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
297
+ ruleKind: NetworkRuleKind.DeviceLabel,
298
+ ruleId: RULE_ID,
299
+ });
300
+
301
+ expect(outcome.isSuccess).toBe(false);
302
+ expect(outcome.message).toContain("Label rule not found.");
303
+ });
304
+
305
+ // A thrown request (offline, DNS, an aborted fetch) must not escape.
306
+ it("reports a thrown request as a message", async () => {
307
+ jest
308
+ .spyOn(API, "post")
309
+ .mockRejectedValue(new Error("Network request failed") as never);
310
+
311
+ const outcome: NetworkRuleRunOutcome = await RunNetworkRule.run({
312
+ ruleKind: NetworkRuleKind.SiteAssignment,
313
+ ruleId: RULE_ID,
314
+ });
315
+
316
+ expect(outcome.isSuccess).toBe(false);
317
+ expect(outcome.message).toContain("Network request failed");
318
+ });
319
+ });
320
+ });