@oneuptime/common 12.0.12 → 12.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +17 -6
- package/Server/Services/LogAggregationService.ts +34 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +300 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +332 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +17 -1
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +15 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +2 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/package.json +1 -1
|
@@ -54,9 +54,44 @@ describe("MasterPage", () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
it("should render correctly with makeTopSectionUnstick", () => {
|
|
57
|
-
render(
|
|
57
|
+
render(
|
|
58
|
+
<MasterPage
|
|
59
|
+
{...defaultProps}
|
|
60
|
+
header={<div>Header</div>}
|
|
61
|
+
makeTopSectionUnstick
|
|
62
|
+
/>,
|
|
63
|
+
);
|
|
58
64
|
|
|
59
65
|
const topSection: HTMLElement = screen.getByRole("banner").parentElement!;
|
|
60
66
|
expect(topSection).not.toHaveClass("sticky");
|
|
61
67
|
});
|
|
68
|
+
|
|
69
|
+
it("should render the top section when it has a header or a navbar", () => {
|
|
70
|
+
const { rerender } = render(
|
|
71
|
+
<MasterPage {...defaultProps} header={<div>Header</div>} />,
|
|
72
|
+
);
|
|
73
|
+
expect(screen.getByRole("banner")).toBeInTheDocument();
|
|
74
|
+
|
|
75
|
+
rerender(<MasterPage {...defaultProps} navBar={<div>NavBar</div>} />);
|
|
76
|
+
expect(screen.getByRole("banner")).toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* The status page renders its own header and navbar inside children and
|
|
81
|
+
* passes neither prop. Rendering the top section anyway left an empty white
|
|
82
|
+
* bar with a drop shadow above the content.
|
|
83
|
+
*/
|
|
84
|
+
it("should not render an empty top section when it has neither", () => {
|
|
85
|
+
render(<MasterPage {...defaultProps} />);
|
|
86
|
+
|
|
87
|
+
expect(screen.queryByRole("banner")).not.toBeInTheDocument();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should not render the top section when its only header is hidden", () => {
|
|
91
|
+
render(
|
|
92
|
+
<MasterPage {...defaultProps} header={<div>Header</div>} hideHeader />,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(screen.queryByRole("banner")).not.toBeInTheDocument();
|
|
96
|
+
});
|
|
62
97
|
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import AggregationType from "../../../Types/BaseDatabase/AggregationType";
|
|
2
2
|
import { CheckOn } from "../../../Types/Monitor/CriteriaFilter";
|
|
3
3
|
import MonitorMetricType from "../../../Types/Monitor/MonitorMetricType";
|
|
4
|
-
import MonitorType
|
|
4
|
+
import MonitorType, {
|
|
5
|
+
MonitorTypeHelper,
|
|
6
|
+
} from "../../../Types/Monitor/MonitorType";
|
|
5
7
|
import MonitorMetricTypeUtil, {
|
|
6
8
|
MonitorMetricCategory,
|
|
7
9
|
} from "../../../Utils/Monitor/MonitorMetricType";
|
|
@@ -333,3 +335,66 @@ describe("invariant: every displayed metric resolves its metadata", () => {
|
|
|
333
335
|
}
|
|
334
336
|
});
|
|
335
337
|
});
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
* Regression suite for https://github.com/OneUptime/oneuptime/issues/3225.
|
|
341
|
+
*
|
|
342
|
+
* SSLCertificate was missing from getMonitorMetricTypesByMonitorType, so it
|
|
343
|
+
* fell through to `return []`. getMonitorMetricCategoriesByMonitorType
|
|
344
|
+
* short-circuits on an empty metric list and the dashboard hides the whole
|
|
345
|
+
* Monitor Metrics tab when there are no categories - so an SSL monitor
|
|
346
|
+
* showed no charts at all, even though IsOnline rows were being written to
|
|
347
|
+
* ClickHouse on every single check. An operator therefore had no way to see
|
|
348
|
+
* that their monitor was running, which is a large part of why the issue was
|
|
349
|
+
* reported as "the monitor never executes".
|
|
350
|
+
*
|
|
351
|
+
* The invariant test above cannot catch this: it iterates the metrics a type
|
|
352
|
+
* already lists, so an empty list passes vacuously.
|
|
353
|
+
*/
|
|
354
|
+
describe("SSL Certificate monitor metrics (issue #3225)", () => {
|
|
355
|
+
test("SSLCertificate reports IsOnline and ResponseTime", () => {
|
|
356
|
+
const metrics: Array<MonitorMetricType> =
|
|
357
|
+
MonitorMetricTypeUtil.getMonitorMetricTypesByMonitorType(
|
|
358
|
+
MonitorType.SSLCertificate,
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
expect(metrics).toContain(MonitorMetricType.IsOnline);
|
|
362
|
+
expect(metrics).toContain(MonitorMetricType.ResponseTime);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test("SSLCertificate produces at least one display category", () => {
|
|
366
|
+
const categories: Array<MonitorMetricCategory> =
|
|
367
|
+
MonitorMetricTypeUtil.getMonitorMetricCategoriesByMonitorType(
|
|
368
|
+
MonitorType.SSLCertificate,
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
// An empty list is what made the dashboard hide the metrics tab.
|
|
372
|
+
expect(categories.length).toBeGreaterThan(0);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
describe("invariant: every probeable monitor type displays some metric", () => {
|
|
377
|
+
test("no probeable type falls through to an empty metric list", () => {
|
|
378
|
+
const typesWithoutMetrics: Array<MonitorType> = [];
|
|
379
|
+
|
|
380
|
+
for (const monitorType of ALL_MONITOR_TYPES) {
|
|
381
|
+
if (!MonitorTypeHelper.isProbableMonitor(monitorType)) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const metrics: Array<MonitorMetricType> =
|
|
386
|
+
MonitorMetricTypeUtil.getMonitorMetricTypesByMonitorType(monitorType);
|
|
387
|
+
|
|
388
|
+
if (metrics.length === 0) {
|
|
389
|
+
typesWithoutMetrics.push(monitorType);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/*
|
|
394
|
+
* Asserting on the collected list rather than per-type so a failure
|
|
395
|
+
* names every offender at once - this is the structural hole that let
|
|
396
|
+
* SSLCertificate ship with no charts.
|
|
397
|
+
*/
|
|
398
|
+
expect(typesWithoutMetrics).toEqual([]);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
@@ -13,6 +13,12 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
13
13
|
const now: Date = new Date("2026-07-22T12:00:00Z");
|
|
14
14
|
const fresh: Date = new Date("2026-07-22T11:55:00Z");
|
|
15
15
|
const stale: Date = new Date("2026-07-22T11:30:00Z");
|
|
16
|
+
/*
|
|
17
|
+
* Past the shared staleness window (an hour at the default interval), so
|
|
18
|
+
* "we have stopped polling this entirely" rather than "the probe is a bit
|
|
19
|
+
* behind" — the distinction issue #3220 turned on.
|
|
20
|
+
*/
|
|
21
|
+
const outOfContact: Date = new Date("2026-07-22T09:00:00Z");
|
|
16
22
|
|
|
17
23
|
const makeDevice: (
|
|
18
24
|
id: string,
|
|
@@ -155,12 +161,24 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
155
161
|
expect(nodeById(result, "d3")!.status).toBe("up");
|
|
156
162
|
});
|
|
157
163
|
|
|
158
|
-
it("derives device status from
|
|
164
|
+
it("derives device status from the outcome of the last poll", () => {
|
|
159
165
|
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
160
166
|
[
|
|
161
|
-
makeDevice("d1", "
|
|
162
|
-
|
|
163
|
-
|
|
167
|
+
makeDevice("d1", "answered", {
|
|
168
|
+
isReachable: true,
|
|
169
|
+
lastPolledAt: fresh,
|
|
170
|
+
lastSeenAt: fresh,
|
|
171
|
+
}),
|
|
172
|
+
makeDevice("d2", "did-not-answer", {
|
|
173
|
+
isReachable: false,
|
|
174
|
+
lastPolledAt: fresh,
|
|
175
|
+
lastSeenAt: outOfContact,
|
|
176
|
+
}),
|
|
177
|
+
makeDevice("d3", "never-polled", {
|
|
178
|
+
isReachable: undefined,
|
|
179
|
+
lastPolledAt: undefined,
|
|
180
|
+
lastSeenAt: undefined,
|
|
181
|
+
}),
|
|
164
182
|
],
|
|
165
183
|
now,
|
|
166
184
|
);
|
|
@@ -170,6 +188,75 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
170
188
|
expect(nodeById(result, "d3")!.status).toBe("unknown");
|
|
171
189
|
});
|
|
172
190
|
|
|
191
|
+
/*
|
|
192
|
+
* Issue #3220: the map drew a whole fleet red because its probe could
|
|
193
|
+
* not get round every device inside the old fixed 15-minute freshness
|
|
194
|
+
* window. A device that answered its last poll is up on the map however
|
|
195
|
+
* far behind the schedule has fallen.
|
|
196
|
+
*/
|
|
197
|
+
it("issue #3220: a device that answered 30 minutes ago is still up on the map", () => {
|
|
198
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
199
|
+
[
|
|
200
|
+
makeDevice("d1", "behind-schedule", {
|
|
201
|
+
isReachable: true,
|
|
202
|
+
lastPolledAt: stale,
|
|
203
|
+
lastSeenAt: stale,
|
|
204
|
+
}),
|
|
205
|
+
],
|
|
206
|
+
now,
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
expect(nodeById(result, "d1")!.status).toBe("up");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
/*
|
|
213
|
+
* A device nothing has polled for hours keeps its last known colour
|
|
214
|
+
* rather than being drawn as an outage. Repainting a whole map red
|
|
215
|
+
* because its probe stopped is the false-positive storm this change
|
|
216
|
+
* exists to remove; the staleness signal belongs on the device page,
|
|
217
|
+
* not in the graph's only three colours.
|
|
218
|
+
*/
|
|
219
|
+
it("a device nothing has polled for hours keeps its last known colour", () => {
|
|
220
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
221
|
+
[
|
|
222
|
+
makeDevice("d1", "out-of-contact", {
|
|
223
|
+
isReachable: true,
|
|
224
|
+
lastPolledAt: outOfContact,
|
|
225
|
+
lastSeenAt: outOfContact,
|
|
226
|
+
}),
|
|
227
|
+
makeDevice("d2", "out-of-contact-and-failing", {
|
|
228
|
+
isReachable: false,
|
|
229
|
+
lastPolledAt: outOfContact,
|
|
230
|
+
lastSeenAt: outOfContact,
|
|
231
|
+
}),
|
|
232
|
+
],
|
|
233
|
+
now,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expect(nodeById(result, "d1")!.status).toBe("up");
|
|
237
|
+
expect(nodeById(result, "d2")!.status).toBe("down");
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
/*
|
|
241
|
+
* Rows written before the reachability columns existed carry only
|
|
242
|
+
* lastSeenAt; the map must keep drawing them from that until their next
|
|
243
|
+
* walk fills the rest in.
|
|
244
|
+
*/
|
|
245
|
+
it("falls back to lastSeenAt for rows with no recorded poll outcome", () => {
|
|
246
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
247
|
+
[
|
|
248
|
+
makeDevice("d1", "legacy-fresh", { lastSeenAt: fresh }),
|
|
249
|
+
makeDevice("d2", "legacy-out-of-contact", {
|
|
250
|
+
lastSeenAt: outOfContact,
|
|
251
|
+
}),
|
|
252
|
+
],
|
|
253
|
+
now,
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
expect(nodeById(result, "d1")!.status).toBe("up");
|
|
257
|
+
expect(nodeById(result, "d2")!.status).toBe("down");
|
|
258
|
+
});
|
|
259
|
+
|
|
173
260
|
it("merges the same link reported from both ends by both protocols", () => {
|
|
174
261
|
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
175
262
|
[
|
|
@@ -762,7 +849,13 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
762
849
|
expect(nodeById(result, "endpoint:ep-4")!.name).toBe("aa:00:00:00:00:04");
|
|
763
850
|
});
|
|
764
851
|
|
|
765
|
-
|
|
852
|
+
/*
|
|
853
|
+
* Endpoints are ARP/FDB-learned hosts with no poll of their own, so
|
|
854
|
+
* freshness really is all there is. The window is the shared staleness
|
|
855
|
+
* one (an hour) rather than the old 15 minutes, so a host behind a
|
|
856
|
+
* switch its probe polls slowly does not blink out between walks.
|
|
857
|
+
*/
|
|
858
|
+
it("derives endpoint status from lastSeenAt freshness", () => {
|
|
766
859
|
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
767
860
|
[makeDevice("d1", "edge-1")],
|
|
768
861
|
now,
|
|
@@ -774,7 +867,7 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
774
867
|
}),
|
|
775
868
|
makeEndpoint("ep-2", "aa:00:00:00:00:02", {
|
|
776
869
|
attachedNetworkDeviceId: "d1",
|
|
777
|
-
lastSeenAt:
|
|
870
|
+
lastSeenAt: outOfContact,
|
|
778
871
|
}),
|
|
779
872
|
makeEndpoint("ep-3", "aa:00:00:00:00:03", {
|
|
780
873
|
attachedNetworkDeviceId: "d1",
|
|
@@ -788,6 +881,22 @@ describe("NetworkTopologyUtil.buildTopology", () => {
|
|
|
788
881
|
expect(nodeById(result, "endpoint:ep-3")!.status).toBe("unknown");
|
|
789
882
|
});
|
|
790
883
|
|
|
884
|
+
it("an endpoint seen half an hour ago is still up, not blinked out", () => {
|
|
885
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
886
|
+
[makeDevice("d1", "edge-1")],
|
|
887
|
+
now,
|
|
888
|
+
[],
|
|
889
|
+
[
|
|
890
|
+
makeEndpoint("ep-1", "aa:00:00:00:00:01", {
|
|
891
|
+
attachedNetworkDeviceId: "d1",
|
|
892
|
+
lastSeenAt: stale,
|
|
893
|
+
}),
|
|
894
|
+
],
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
expect(nodeById(result, "endpoint:ep-1")!.status).toBe("up");
|
|
898
|
+
});
|
|
899
|
+
|
|
791
900
|
it("labels the port from the interface row, then falls back to if<index>", () => {
|
|
792
901
|
const interfaces: Array<TopologyInterfaceInput> = [
|
|
793
902
|
{ networkDeviceId: "d1", interfaceIndex: 9, name: "Fa0/9" },
|