@oneuptime/common 12.0.14 → 12.0.15
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/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- package/Server/API/StatusPageAPI.ts +29 -4
- package/Server/EnvironmentConfig.ts +7 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/UserEmailService.ts +4 -4
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +34 -28
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +9 -59
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
- package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
- package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
- package/Tests/Utils/Analytics.test.ts +187 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- package/Utils/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.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/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +4 -4
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/Utils/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- package/package.json +1 -1
|
@@ -107,3 +107,190 @@ describe("Analytics Class", () => {
|
|
|
107
107
|
expect(posthog.capture).not.toHaveBeenCalled();
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
|
+
|
|
111
|
+
describe("Analytics.toGA4EventName", () => {
|
|
112
|
+
/*
|
|
113
|
+
* GA4 event names must start with a letter and contain only letters, digits
|
|
114
|
+
* and underscores, with a maximum length of 40 characters.
|
|
115
|
+
*/
|
|
116
|
+
const GA4_EVENT_NAME_REGEX: RegExp = /^[a-z][a-z0-9_]*$/;
|
|
117
|
+
|
|
118
|
+
it.each([
|
|
119
|
+
// Names product code sends today that GA4 would otherwise reject.
|
|
120
|
+
["Page View: Project > Home", "page_view_project_home"],
|
|
121
|
+
["FORM SUBMIT: Register", "form_submit_register"],
|
|
122
|
+
["accounts/login", "accounts_login"],
|
|
123
|
+
["accounts/register", "accounts_register"],
|
|
124
|
+
["dashboard/home", "dashboard_home"],
|
|
125
|
+
["dashboard/ai-copilot", "dashboard_ai_copilot"],
|
|
126
|
+
["dashboard/billing/plan-changed", "dashboard_billing_plan_changed"],
|
|
127
|
+
[
|
|
128
|
+
"dashboard/home/getting-started-task",
|
|
129
|
+
"dashboard_home_getting_started_task",
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"dashboard/home/getting-started-dismissed",
|
|
133
|
+
"dashboard_home_getting_started_dismissed",
|
|
134
|
+
],
|
|
135
|
+
// Leading and trailing separators are dropped rather than kept.
|
|
136
|
+
[" /accounts/login/ ", "accounts_login"],
|
|
137
|
+
// A name with no leading letter gets a prefix.
|
|
138
|
+
["404 page not found", "event_404_page_not_found"],
|
|
139
|
+
["_leading_underscore", "leading_underscore"],
|
|
140
|
+
// A name with nothing usable in it falls back entirely.
|
|
141
|
+
["***", "event"],
|
|
142
|
+
["", "event"],
|
|
143
|
+
// Casing is normalised.
|
|
144
|
+
["testEvent", "testevent"],
|
|
145
|
+
])("normalises %j to %j", (input: string, expected: string) => {
|
|
146
|
+
expect(Analytics.toGA4EventName(input)).toBe(expected);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("truncates to 40 characters without leaving a trailing underscore", () => {
|
|
150
|
+
const normalized: string = Analytics.toGA4EventName(
|
|
151
|
+
"Page View: Project > Settings > Notification > Email",
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
expect(normalized).toBe("page_view_project_settings_notification");
|
|
155
|
+
expect(normalized.length).toBeLessThanOrEqual(40);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("truncates a name that is exactly at the boundary", () => {
|
|
159
|
+
const normalized: string = Analytics.toGA4EventName(
|
|
160
|
+
"Page View: Project > Settings > Notifications > Email",
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
expect(normalized).toBe("page_view_project_settings_notifications");
|
|
164
|
+
expect(normalized).toHaveLength(40);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("leaves already GA4-compatible revenue event names untouched", () => {
|
|
168
|
+
for (const eventName of Object.values(RevenueEventName)) {
|
|
169
|
+
expect(Analytics.toGA4EventName(eventName)).toBe(eventName);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("always produces a GA4-valid name", () => {
|
|
174
|
+
const inputs: Array<string> = [
|
|
175
|
+
"Page View: Project > Home",
|
|
176
|
+
"FORM SUBMIT: Register",
|
|
177
|
+
"accounts/login",
|
|
178
|
+
"404",
|
|
179
|
+
"___",
|
|
180
|
+
"!!!",
|
|
181
|
+
"",
|
|
182
|
+
" ",
|
|
183
|
+
"a".repeat(200),
|
|
184
|
+
"1".repeat(200),
|
|
185
|
+
"Page View: " + "Very Long Breadcrumb > ".repeat(10),
|
|
186
|
+
];
|
|
187
|
+
|
|
188
|
+
for (const input of inputs) {
|
|
189
|
+
const normalized: string = Analytics.toGA4EventName(input);
|
|
190
|
+
|
|
191
|
+
expect(normalized).toMatch(GA4_EVENT_NAME_REGEX);
|
|
192
|
+
expect(normalized.length).toBeGreaterThan(0);
|
|
193
|
+
expect(normalized.length).toBeLessThanOrEqual(40);
|
|
194
|
+
// Normalising an already-normalised name must be a no-op.
|
|
195
|
+
expect(Analytics.toGA4EventName(normalized)).toBe(normalized);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe("Analytics dataLayer (GA4) branch", () => {
|
|
201
|
+
let dataLayer: Array<JSONObject>;
|
|
202
|
+
|
|
203
|
+
beforeEach(() => {
|
|
204
|
+
dataLayer = [];
|
|
205
|
+
(window as any).dataLayer = dataLayer;
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
afterEach(() => {
|
|
209
|
+
delete (window as any).dataLayer;
|
|
210
|
+
jest.clearAllMocks();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("pushes a normalised event name while PostHog keeps the original", () => {
|
|
214
|
+
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
|
215
|
+
|
|
216
|
+
analytics.capture("Page View: Project > Home");
|
|
217
|
+
|
|
218
|
+
expect(posthog.capture).toHaveBeenCalledWith(
|
|
219
|
+
"Page View: Project > Home",
|
|
220
|
+
undefined,
|
|
221
|
+
);
|
|
222
|
+
expect(dataLayer).toHaveLength(1);
|
|
223
|
+
expect(dataLayer[0]).toEqual({
|
|
224
|
+
event: "page_view_project_home",
|
|
225
|
+
eventCategory: "analytics",
|
|
226
|
+
eventAction: "Page View: Project > Home",
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("pushes to the dataLayer even when PostHog is not initialized", () => {
|
|
231
|
+
const analytics: Analytics = new Analytics("", "");
|
|
232
|
+
|
|
233
|
+
analytics.capture("FORM SUBMIT: Register");
|
|
234
|
+
|
|
235
|
+
expect(posthog.capture).not.toHaveBeenCalled();
|
|
236
|
+
expect(dataLayer).toHaveLength(1);
|
|
237
|
+
expect(dataLayer[0]).toMatchObject({
|
|
238
|
+
event: "form_submit_register",
|
|
239
|
+
eventAction: "FORM SUBMIT: Register",
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("includes event properties in the pushed payload", () => {
|
|
244
|
+
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
|
245
|
+
|
|
246
|
+
analytics.capture("dashboard/billing/plan-changed", {
|
|
247
|
+
plan_name: "growth",
|
|
248
|
+
is_paid_conversion: true,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
expect(dataLayer[0]).toEqual({
|
|
252
|
+
event: "dashboard_billing_plan_changed",
|
|
253
|
+
eventCategory: "analytics",
|
|
254
|
+
eventAction: "dashboard/billing/plan-changed",
|
|
255
|
+
plan_name: "growth",
|
|
256
|
+
is_paid_conversion: true,
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("does not let event properties override the GA4 event name", () => {
|
|
261
|
+
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
|
262
|
+
|
|
263
|
+
analytics.capture("accounts/login", { event: "Not A Valid GA4 Name" });
|
|
264
|
+
|
|
265
|
+
expect(dataLayer[0]).toMatchObject({ event: "accounts_login" });
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it("pushes revenue event names unchanged", () => {
|
|
269
|
+
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
|
270
|
+
|
|
271
|
+
analytics.captureRevenueEvent(RevenueEventName.WorkspaceCreated, {
|
|
272
|
+
funnel_stage: RevenueFunnelStage.Activation,
|
|
273
|
+
project_id: "project-123",
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
expect(dataLayer[0]).toEqual({
|
|
277
|
+
event: RevenueEventName.WorkspaceCreated,
|
|
278
|
+
eventCategory: "analytics",
|
|
279
|
+
eventAction: RevenueEventName.WorkspaceCreated,
|
|
280
|
+
funnel_stage: RevenueFunnelStage.Activation,
|
|
281
|
+
project_id: "project-123",
|
|
282
|
+
event_schema_version: REVENUE_EVENT_SCHEMA_VERSION,
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("does not throw when window.dataLayer is not defined", () => {
|
|
287
|
+
delete (window as any).dataLayer;
|
|
288
|
+
|
|
289
|
+
const analytics: Analytics = new Analytics(apiHost, apiKey);
|
|
290
|
+
|
|
291
|
+
expect(() => {
|
|
292
|
+
analytics.capture("accounts/login");
|
|
293
|
+
}).not.toThrow();
|
|
294
|
+
expect(posthog.capture).toHaveBeenCalledWith("accounts/login", undefined);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
@@ -398,3 +398,83 @@ describe("invariant: every probeable monitor type displays some metric", () => {
|
|
|
398
398
|
expect(typesWithoutMetrics).toEqual([]);
|
|
399
399
|
});
|
|
400
400
|
});
|
|
401
|
+
|
|
402
|
+
/*
|
|
403
|
+
* The null-returning variant exists because over-time evaluation asks "is
|
|
404
|
+
* there a series behind this CheckOn?" for every filter it sees. It used to
|
|
405
|
+
* ask by calling the throwing variant inside a try/catch that swallowed the
|
|
406
|
+
* error and quietly compared the instantaneous value instead - so "evaluate
|
|
407
|
+
* over time" was a silent no-op for every CheckOn missing from the map.
|
|
408
|
+
*/
|
|
409
|
+
describe("getMonitorMetricTypeByCheckOnOrNull", () => {
|
|
410
|
+
test("returns the same series as the throwing variant for mapped CheckOns", () => {
|
|
411
|
+
const mapped: Array<CheckOn> = [
|
|
412
|
+
CheckOn.ResponseTime,
|
|
413
|
+
CheckOn.ResponseStatusCode,
|
|
414
|
+
CheckOn.IsOnline,
|
|
415
|
+
CheckOn.CPUUsagePercent,
|
|
416
|
+
CheckOn.MemoryUsagePercent,
|
|
417
|
+
CheckOn.DiskUsagePercent,
|
|
418
|
+
CheckOn.PacketLossPercent,
|
|
419
|
+
CheckOn.Jitter,
|
|
420
|
+
CheckOn.PortDnsLookupTime,
|
|
421
|
+
CheckOn.PortTcpConnectTime,
|
|
422
|
+
];
|
|
423
|
+
|
|
424
|
+
for (const checkOn of mapped) {
|
|
425
|
+
expect(
|
|
426
|
+
MonitorMetricTypeUtil.getMonitorMetricTypeByCheckOnOrNull(checkOn),
|
|
427
|
+
).toBe(MonitorMetricTypeUtil.getMonitorMeticTypeByCheckOn(checkOn));
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
/*
|
|
432
|
+
* DNS, SNMP and External Status Page probes write into the shared online
|
|
433
|
+
* and response-time series like every other probe check, and the criteria
|
|
434
|
+
* UI advertises all six of these as over-time capable - but none of them
|
|
435
|
+
* had a mapping, so the window could never be read.
|
|
436
|
+
*/
|
|
437
|
+
test("maps the DNS / SNMP / status page online checks onto the online series", () => {
|
|
438
|
+
for (const checkOn of [
|
|
439
|
+
CheckOn.DnsIsOnline,
|
|
440
|
+
CheckOn.SnmpIsOnline,
|
|
441
|
+
CheckOn.ExternalStatusPageIsOnline,
|
|
442
|
+
]) {
|
|
443
|
+
expect(
|
|
444
|
+
MonitorMetricTypeUtil.getMonitorMetricTypeByCheckOnOrNull(checkOn),
|
|
445
|
+
).toBe(MonitorMetricType.IsOnline);
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
test("maps their response time checks onto the response time series", () => {
|
|
450
|
+
for (const checkOn of [
|
|
451
|
+
CheckOn.DnsResponseTime,
|
|
452
|
+
CheckOn.SnmpResponseTime,
|
|
453
|
+
CheckOn.ExternalStatusPageResponseTime,
|
|
454
|
+
]) {
|
|
455
|
+
expect(
|
|
456
|
+
MonitorMetricTypeUtil.getMonitorMetricTypeByCheckOnOrNull(checkOn),
|
|
457
|
+
).toBe(MonitorMetricType.ResponseTime);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
test("returns null instead of throwing for CheckOns no series records", () => {
|
|
462
|
+
for (const checkOn of [
|
|
463
|
+
CheckOn.ResponseBody,
|
|
464
|
+
CheckOn.ResponseHeader,
|
|
465
|
+
CheckOn.IsRequestTimeout,
|
|
466
|
+
CheckOn.JavaScriptExpression,
|
|
467
|
+
CheckOn.IncomingRequest,
|
|
468
|
+
]) {
|
|
469
|
+
expect(
|
|
470
|
+
MonitorMetricTypeUtil.getMonitorMetricTypeByCheckOnOrNull(checkOn),
|
|
471
|
+
).toBeNull();
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
test("the throwing variant still throws for those CheckOns", () => {
|
|
476
|
+
expect(() => {
|
|
477
|
+
MonitorMetricTypeUtil.getMonitorMeticTypeByCheckOn(CheckOn.ResponseBody);
|
|
478
|
+
}).toThrow();
|
|
479
|
+
});
|
|
480
|
+
});
|