@oneuptime/common 12.0.17 → 12.0.19
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/EnterpriseLicense.ts +23 -0
- package/Models/DatabaseModels/Index.ts +4 -2
- package/Models/DatabaseModels/Monitor.ts +39 -9
- package/Models/DatabaseModels/UserMicrosoftTeams.ts +344 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +144 -8
- package/Models/DatabaseModels/UserNotificationSetting.ts +34 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +95 -0
- package/Models/DatabaseModels/UserSlack.ts +341 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +9 -0
- package/Server/API/UserMicrosoftTeamsAPI.ts +127 -0
- package/Server/API/UserSlackAPI.ts +125 -0
- package/Server/EnvironmentConfig.ts +12 -107
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.ts +117 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.ts +197 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Queue.ts +7 -0
- package/Server/Services/BillingService.ts +8 -0
- package/Server/Services/EnterpriseLicenseService.ts +60 -0
- package/Server/Services/Index.ts +6 -2
- package/Server/Services/LlmLogService.ts +25 -9
- package/Server/Services/OnCallReadinessService.ts +86 -2
- package/Server/Services/ProjectService.ts +67 -0
- package/Server/Services/UserMicrosoftTeamsService.ts +208 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +167 -5
- package/Server/Services/UserNotificationRuleAdminService.ts +40 -6
- package/Server/Services/UserNotificationRuleService.ts +589 -11
- package/Server/Services/UserNotificationSettingService.ts +138 -0
- package/Server/Services/UserService.ts +28 -0
- package/Server/Services/UserSlackService.ts +218 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +67 -1
- package/Server/Services/WorkspaceUserAuthTokenService.ts +73 -0
- package/Server/Services/WorkspaceUserNotificationService.ts +190 -0
- package/Server/Utils/Marketing/MarketingEventUtil.ts +145 -0
- package/Server/Utils/Marketing/MarketingEventWebhook.ts +114 -0
- package/Server/Utils/Monitor/MonitorLogUtil.ts +14 -1
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +321 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +191 -4
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +22 -14
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +22 -11
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +37 -1
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +18 -10
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +17 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +27 -1
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +214 -0
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +145 -26
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +2 -2
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +11 -1
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +22 -8
- package/Tests/Server/Services/BillingService.test.ts +20 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +18 -2
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +5 -1
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +640 -0
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +246 -22
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +136 -8
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +191 -8
- package/Tests/Server/Services/OnCallReadinessService.test.ts +343 -18
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +5 -1
- package/Tests/Server/Services/UserMicrosoftTeamsService.test.ts +343 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +209 -8
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +22 -6
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +12 -6
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +37 -3
- package/Tests/Server/Services/UserNotificationRuleWorkspaceDelivery.test.ts +669 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +410 -0
- package/Tests/Server/Services/UserSlackService.test.ts +407 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenDisconnectCascade.test.ts +224 -0
- package/Tests/Server/Services/WorkspaceUserAuthTokenNotificationMethodCascade.test.ts +189 -0
- package/Tests/Server/Services/WorkspaceUserNotificationService.test.ts +496 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +30 -17
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +8 -3
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +72 -3
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +22 -18
- package/Tests/Server/Types/Database/Permissions/WorkspaceMethodStampedColumnCreate.test.ts +178 -0
- package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +259 -0
- package/Tests/Server/Utils/Marketing/MarketingEventWebhook.test.ts +257 -0
- package/Tests/Server/Utils/Monitor/MonitorLogUtilRedaction.test.ts +300 -0
- package/Tests/Server/Utils/Monitor/MonitorPayloadRedaction.test.ts +381 -0
- package/Tests/Server/Utils/Runbook/RunbookExecutePermission.test.ts +228 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayErasureTombstone.test.ts +189 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +205 -0
- package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +275 -0
- package/Tests/Server/Utils/Telemetry/TelemetryContext.test.ts +279 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +454 -0
- package/Tests/Types/Kubernetes/KubernetesObjectParsers.test.ts +794 -0
- package/Tests/Types/Kubernetes/KubernetesRightSizing.test.ts +53 -0
- package/Tests/Types/Measurement/MeasurementAggregationType.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +114 -0
- package/Tests/Types/Workspace/WorkspaceType.test.ts +53 -0
- package/Tests/UI/Utils/NotificationMethodUtil.test.ts +137 -9
- package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +257 -0
- package/Types/Billing/PayAsYouGoPricing.ts +1 -1
- package/Types/Marketing/MarketingEvent.ts +97 -0
- package/UI/Utils/NotificationMethodUtil.ts +41 -1
- package/UI/Utils/PermissionGate.ts +56 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +24 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -2
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +39 -9
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js +363 -0
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +145 -8
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +38 -0
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +96 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSlack.js +361 -0
- package/build/dist/Models/DatabaseModels/UserSlack.js.map +1 -0
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +82 -0
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -0
- package/build/dist/Server/API/UserSlackAPI.js +81 -0
- package/build/dist/Server/API/UserSlackAPI.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +10 -70
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js +106 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js +78 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +7 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +6 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +65 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +6 -2
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +25 -9
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallReadinessService.js +74 -2
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +56 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js +183 -0
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +138 -2
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +32 -4
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +499 -67
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +118 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +26 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSlackService.js +195 -0
- package/build/dist/Server/Services/UserSlackService.js.map +1 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +64 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +70 -0
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js +129 -0
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +94 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js +93 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +12 -1
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +233 -0
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +141 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Billing/PayAsYouGoPricing.js +1 -1
- package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingEvent.js +43 -0
- package/build/dist/Types/Marketing/MarketingEvent.js.map +1 -0
- package/build/dist/UI/Utils/NotificationMethodUtil.js +33 -1
- package/build/dist/UI/Utils/NotificationMethodUtil.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +32 -0
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/package.json +1 -1
- package/Models/DatabaseModels/MarketingConversion.ts +0 -410
- package/Server/Services/MarketingConversionService.ts +0 -10
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +0 -215
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +0 -22
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +0 -333
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +0 -185
- package/Server/Utils/Marketing/Providers/Meta.ts +0 -182
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +0 -223
- package/Server/Utils/Marketing/Providers/Reddit.ts +0 -208
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +0 -315
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +0 -300
- package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +0 -592
- package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +0 -282
- package/Tests/Server/Utils/Marketing/Meta.test.ts +0 -304
- package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +0 -263
- package/Tests/Server/Utils/Marketing/Reddit.test.ts +0 -259
- package/Types/Marketing/MarketingConversion.ts +0 -53
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +0 -445
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +0 -1
- package/build/dist/Server/Services/MarketingConversionService.js +0 -9
- package/build/dist/Server/Services/MarketingConversionService.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +0 -93
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +0 -20
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +0 -221
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +0 -137
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +0 -133
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +0 -143
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +0 -145
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +0 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +0 -52
- package/build/dist/Types/Marketing/MarketingConversion.js.map +0 -1
|
@@ -11,6 +11,7 @@ import SmsService from "../../../Server/Services/SmsService";
|
|
|
11
11
|
import CallService from "../../../Server/Services/CallService";
|
|
12
12
|
import WhatsAppService from "../../../Server/Services/WhatsAppService";
|
|
13
13
|
import TelegramService from "../../../Server/Services/TelegramService";
|
|
14
|
+
import WorkspaceUserNotificationService from "../../../Server/Services/WorkspaceUserNotificationService";
|
|
14
15
|
import WebhookService from "../../../Server/Services/WebhookService";
|
|
15
16
|
import PushNotificationService from "../../../Server/Services/PushNotificationService";
|
|
16
17
|
import logger from "../../../Server/Utils/Logger";
|
|
@@ -28,16 +29,20 @@ import BadDataException from "../../../Types/Exception/BadDataException";
|
|
|
28
29
|
import PushDeviceType from "../../../Types/PushNotification/PushDeviceType";
|
|
29
30
|
import UserNotificationEventType from "../../../Types/UserNotification/UserNotificationEventType";
|
|
30
31
|
import UserNotificationStatus from "../../../Types/UserNotification/UserNotificationStatus";
|
|
32
|
+
import WorkspaceType from "../../../Types/Workspace/WorkspaceType";
|
|
31
33
|
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
32
34
|
|
|
33
35
|
/*
|
|
34
36
|
* THE SHAPE OF THE BUG THIS FILE EXISTS TO CATCH.
|
|
35
37
|
*
|
|
36
|
-
* `deliverNotificationForRule` is
|
|
37
|
-
* after another - email, SMS, WhatsApp, Telegram,
|
|
38
|
-
* block is itself a stack of
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* `deliverNotificationForRule` is nine independent channel blocks stacked one
|
|
39
|
+
* after another - email, SMS, WhatsApp, Telegram, Slack, Microsoft Teams,
|
|
40
|
+
* webhook, call, push - and each block is itself a stack of
|
|
41
|
+
* `if (eventType === X && entity)` branches, one per UserNotificationEventType
|
|
42
|
+
* (the two workspace channels share one such ladder inside
|
|
43
|
+
* deliverWorkspaceDirectMessageForRule, but each still opens its own gate).
|
|
44
|
+
* That is a 9 x 4 grid written out by hand, thirty six times, with no compiler
|
|
45
|
+
* anywhere insisting the grid is full.
|
|
41
46
|
*
|
|
42
47
|
* It was not full. Gap F: `IncidentEpisodeCreated` was wired into the webhook
|
|
43
48
|
* and push blocks and nowhere else, so a responder whose rule pointed at their
|
|
@@ -51,9 +56,9 @@ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
|
51
56
|
* A test that checked "email works" and "SMS works" would not have caught it,
|
|
52
57
|
* because email and SMS did work - for three of the four event types. Only the
|
|
53
58
|
* CARTESIAN PRODUCT catches a hole in a grid. So this file is table-driven on
|
|
54
|
-
* purpose: it builds {
|
|
59
|
+
* purpose: it builds {nine channels} x {every member of UserNotificationEventType}
|
|
55
60
|
* and asserts every single cell hands a page to its provider and writes a
|
|
56
|
-
* timeline row. Adding
|
|
61
|
+
* timeline row. Adding a tenth channel or a fifth event type without filling
|
|
57
62
|
* in the new row or column fails here, loudly, in the cell that is missing.
|
|
58
63
|
*
|
|
59
64
|
* Two canaries keep the table honest, because a table that quietly stops
|
|
@@ -65,7 +70,7 @@ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
|
65
70
|
*
|
|
66
71
|
* Beyond the grid, three behaviours the grid depends on are pinned:
|
|
67
72
|
*
|
|
68
|
-
* 1. THE FELL-THROUGH GUARD. Phase 1 added a backstop after the
|
|
73
|
+
* 1. THE FELL-THROUGH GUARD. Phase 1 added a backstop after the channel blocks:
|
|
69
74
|
* if the rule could contact somebody and no branch claimed the event, write
|
|
70
75
|
* an Error row naming the event type and the channels. That converts the
|
|
71
76
|
* next Gap F from a silent hole into a visible failure - but only if it
|
|
@@ -122,6 +127,13 @@ const TELEGRAM_CHAT_ID: string = "987654321";
|
|
|
122
127
|
const WEBHOOK_URL: string = "https://hooks.example.com/on-call";
|
|
123
128
|
const DEVICE_TOKEN: string = "device-token";
|
|
124
129
|
const TELEGRAM_BODY: string = "<b>telegram body</b>";
|
|
130
|
+
const SLACK_USER_ID: string = "U0123ABCD";
|
|
131
|
+
const SLACK_USER_NAME: string = "alice";
|
|
132
|
+
const TEAMS_USER_ID: string = "aad-object-0123";
|
|
133
|
+
const TEAMS_USER_NAME: string = "Alice Example";
|
|
134
|
+
const WORKSPACE_BLOCKS: Array<Record<string, unknown>> = [
|
|
135
|
+
{ _type: "WorkspacePayloadMarkdown", text: "**workspace body**" },
|
|
136
|
+
];
|
|
125
137
|
|
|
126
138
|
/* The options bag `executeNotificationRuleItem` takes, without re-declaring it. */
|
|
127
139
|
type ExecuteOptions = Parameters<
|
|
@@ -146,13 +158,18 @@ interface TimelineRow {
|
|
|
146
158
|
methodIds: Record<string, ObjectID | undefined>;
|
|
147
159
|
}
|
|
148
160
|
|
|
149
|
-
/* Everything the
|
|
161
|
+
/* Everything the options bag handed to every sender has in common. */
|
|
150
162
|
interface SenderOptions {
|
|
151
163
|
projectId?: ObjectID | undefined;
|
|
152
164
|
userId?: ObjectID | undefined;
|
|
153
165
|
userOnCallLogTimelineId?: ObjectID | undefined;
|
|
154
166
|
alertEpisodeId?: ObjectID | undefined;
|
|
155
167
|
incidentEpisodeId?: ObjectID | undefined;
|
|
168
|
+
/*
|
|
169
|
+
* Only the shared workspace sender carries this: it is the ONE thing that
|
|
170
|
+
* says whether a call was a Slack page or a Microsoft Teams page.
|
|
171
|
+
*/
|
|
172
|
+
workspaceType?: WorkspaceType | undefined;
|
|
156
173
|
}
|
|
157
174
|
|
|
158
175
|
interface DeliverySpies {
|
|
@@ -174,6 +191,7 @@ interface DeliverySpies {
|
|
|
174
191
|
call: jest.SpyInstance;
|
|
175
192
|
whatsApp: jest.SpyInstance;
|
|
176
193
|
telegram: jest.SpyInstance;
|
|
194
|
+
workspace: jest.SpyInstance;
|
|
177
195
|
webhook: jest.SpyInstance;
|
|
178
196
|
push: jest.SpyInstance;
|
|
179
197
|
loggerError: jest.SpyInstance;
|
|
@@ -279,6 +297,20 @@ interface ChannelSpec {
|
|
|
279
297
|
unverifiedMessage: string;
|
|
280
298
|
/* The provider function the block must call. Read lazily: spies are per-test. */
|
|
281
299
|
sender: () => jest.SpyInstance;
|
|
300
|
+
/*
|
|
301
|
+
* Where the options bag sits in the sender's arguments. Every legacy
|
|
302
|
+
* provider takes (message, options); the workspace sender takes a single
|
|
303
|
+
* options bag as its only argument.
|
|
304
|
+
*/
|
|
305
|
+
senderOptionsArgIndex: number;
|
|
306
|
+
/*
|
|
307
|
+
* Slack and Microsoft Teams share ONE sender -
|
|
308
|
+
* WorkspaceUserNotificationService.sendDirectMessageToUser - so the spy
|
|
309
|
+
* alone cannot say which channel a call was for; the workspaceType argument
|
|
310
|
+
* can, and is asserted wherever the spec's is non-null. Null for channels
|
|
311
|
+
* with a provider of their own.
|
|
312
|
+
*/
|
|
313
|
+
workspaceType: WorkspaceType | null;
|
|
282
314
|
/* The timeline column that attributes the row to this method. */
|
|
283
315
|
timelineMethodIdField: string;
|
|
284
316
|
/*
|
|
@@ -316,6 +348,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
316
348
|
sender: (): jest.SpyInstance => {
|
|
317
349
|
return spies.mail;
|
|
318
350
|
},
|
|
351
|
+
senderOptionsArgIndex: 1,
|
|
352
|
+
workspaceType: null,
|
|
319
353
|
timelineMethodIdField: "userEmailId",
|
|
320
354
|
generatorPrefix: "generateEmailTemplateFor",
|
|
321
355
|
generatorTimelineIdArgIndex: 2,
|
|
@@ -345,6 +379,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
345
379
|
sender: (): jest.SpyInstance => {
|
|
346
380
|
return spies.sms;
|
|
347
381
|
},
|
|
382
|
+
senderOptionsArgIndex: 1,
|
|
383
|
+
workspaceType: null,
|
|
348
384
|
timelineMethodIdField: "userSmsId",
|
|
349
385
|
generatorPrefix: "generateSmsTemplateFor",
|
|
350
386
|
generatorTimelineIdArgIndex: 2,
|
|
@@ -374,6 +410,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
374
410
|
sender: (): jest.SpyInstance => {
|
|
375
411
|
return spies.whatsApp;
|
|
376
412
|
},
|
|
413
|
+
senderOptionsArgIndex: 1,
|
|
414
|
+
workspaceType: null,
|
|
377
415
|
timelineMethodIdField: "userWhatsAppId",
|
|
378
416
|
generatorPrefix: "generateWhatsAppTemplateFor",
|
|
379
417
|
generatorTimelineIdArgIndex: 2,
|
|
@@ -403,11 +441,88 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
403
441
|
sender: (): jest.SpyInstance => {
|
|
404
442
|
return spies.telegram;
|
|
405
443
|
},
|
|
444
|
+
senderOptionsArgIndex: 1,
|
|
445
|
+
workspaceType: null,
|
|
406
446
|
timelineMethodIdField: "userTelegramId",
|
|
407
447
|
/* Telegram's generator takes (entity, timelineId) - no `to` argument. */
|
|
408
448
|
generatorPrefix: "generateTelegramBodyFor",
|
|
409
449
|
generatorTimelineIdArgIndex: 1,
|
|
410
450
|
},
|
|
451
|
+
Slack: {
|
|
452
|
+
channel: "Slack",
|
|
453
|
+
verifiedMethod: (): Record<string, unknown> => {
|
|
454
|
+
return {
|
|
455
|
+
userSlack: {
|
|
456
|
+
id: METHOD_ID,
|
|
457
|
+
slackUserId: SLACK_USER_ID,
|
|
458
|
+
slackUserName: SLACK_USER_NAME,
|
|
459
|
+
isVerified: true,
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
},
|
|
463
|
+
unverifiedMethod: (): Record<string, unknown> => {
|
|
464
|
+
return {
|
|
465
|
+
userSlack: {
|
|
466
|
+
id: METHOD_ID,
|
|
467
|
+
slackUserId: SLACK_USER_ID,
|
|
468
|
+
slackUserName: SLACK_USER_NAME,
|
|
469
|
+
isVerified: false,
|
|
470
|
+
},
|
|
471
|
+
};
|
|
472
|
+
},
|
|
473
|
+
sendingMessage: "Sending Slack message.",
|
|
474
|
+
unverifiedMessage:
|
|
475
|
+
"Slack message not sent because the Slack account is not verified.",
|
|
476
|
+
sender: (): jest.SpyInstance => {
|
|
477
|
+
return spies.workspace;
|
|
478
|
+
},
|
|
479
|
+
/* The workspace sender takes ONE options bag, not (message, options). */
|
|
480
|
+
senderOptionsArgIndex: 0,
|
|
481
|
+
workspaceType: WorkspaceType.Slack,
|
|
482
|
+
timelineMethodIdField: "userSlackId",
|
|
483
|
+
/*
|
|
484
|
+
* One generator family serves BOTH workspace channels: the blocks are
|
|
485
|
+
* plain markdown, slackified or adaptive-carded by the send side. Like
|
|
486
|
+
* Telegram's, the generators take (entity, timelineId).
|
|
487
|
+
*/
|
|
488
|
+
generatorPrefix: "generateWorkspaceMessageBlocksFor",
|
|
489
|
+
generatorTimelineIdArgIndex: 1,
|
|
490
|
+
},
|
|
491
|
+
"Microsoft Teams": {
|
|
492
|
+
channel: "Microsoft Teams",
|
|
493
|
+
verifiedMethod: (): Record<string, unknown> => {
|
|
494
|
+
return {
|
|
495
|
+
userMicrosoftTeams: {
|
|
496
|
+
id: METHOD_ID,
|
|
497
|
+
microsoftTeamsUserId: TEAMS_USER_ID,
|
|
498
|
+
microsoftTeamsUserName: TEAMS_USER_NAME,
|
|
499
|
+
isVerified: true,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
},
|
|
503
|
+
unverifiedMethod: (): Record<string, unknown> => {
|
|
504
|
+
return {
|
|
505
|
+
userMicrosoftTeams: {
|
|
506
|
+
id: METHOD_ID,
|
|
507
|
+
microsoftTeamsUserId: TEAMS_USER_ID,
|
|
508
|
+
microsoftTeamsUserName: TEAMS_USER_NAME,
|
|
509
|
+
isVerified: false,
|
|
510
|
+
},
|
|
511
|
+
};
|
|
512
|
+
},
|
|
513
|
+
sendingMessage: "Sending Microsoft Teams message.",
|
|
514
|
+
unverifiedMessage:
|
|
515
|
+
"Microsoft Teams message not sent because the Microsoft Teams account is not verified.",
|
|
516
|
+
sender: (): jest.SpyInstance => {
|
|
517
|
+
return spies.workspace;
|
|
518
|
+
},
|
|
519
|
+
senderOptionsArgIndex: 0,
|
|
520
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
521
|
+
timelineMethodIdField: "userMicrosoftTeamsId",
|
|
522
|
+
/* Shared with Slack - see the note on that spec. */
|
|
523
|
+
generatorPrefix: "generateWorkspaceMessageBlocksFor",
|
|
524
|
+
generatorTimelineIdArgIndex: 1,
|
|
525
|
+
},
|
|
411
526
|
Webhook: {
|
|
412
527
|
channel: "Webhook",
|
|
413
528
|
verifiedMethod: (): Record<string, unknown> => {
|
|
@@ -430,6 +545,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
430
545
|
sender: (): jest.SpyInstance => {
|
|
431
546
|
return spies.webhook;
|
|
432
547
|
},
|
|
548
|
+
senderOptionsArgIndex: 1,
|
|
549
|
+
workspaceType: null,
|
|
433
550
|
timelineMethodIdField: "userWebhookId",
|
|
434
551
|
generatorPrefix: null,
|
|
435
552
|
generatorTimelineIdArgIndex: -1,
|
|
@@ -459,6 +576,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
459
576
|
sender: (): jest.SpyInstance => {
|
|
460
577
|
return spies.call;
|
|
461
578
|
},
|
|
579
|
+
senderOptionsArgIndex: 1,
|
|
580
|
+
workspaceType: null,
|
|
462
581
|
timelineMethodIdField: "userCallId",
|
|
463
582
|
generatorPrefix: "generateCallTemplateFor",
|
|
464
583
|
generatorTimelineIdArgIndex: 2,
|
|
@@ -490,6 +609,8 @@ const CHANNEL_SPECS: Record<string, ChannelSpec> = {
|
|
|
490
609
|
sender: (): jest.SpyInstance => {
|
|
491
610
|
return spies.push;
|
|
492
611
|
},
|
|
612
|
+
senderOptionsArgIndex: 1,
|
|
613
|
+
workspaceType: null,
|
|
493
614
|
timelineMethodIdField: "userPushId",
|
|
494
615
|
/* Push builds its payload through PushNotificationUtil, not a generator. */
|
|
495
616
|
generatorPrefix: null,
|
|
@@ -596,6 +717,8 @@ const CHANNEL_NAMES: Array<string> = [
|
|
|
596
717
|
"SMS",
|
|
597
718
|
"WhatsApp",
|
|
598
719
|
"Telegram",
|
|
720
|
+
"Slack",
|
|
721
|
+
"Microsoft Teams",
|
|
599
722
|
"Webhook",
|
|
600
723
|
"Call",
|
|
601
724
|
"Push",
|
|
@@ -614,6 +737,8 @@ const GENERATOR_CHANNEL_NAMES: Array<string> = [
|
|
|
614
737
|
"SMS",
|
|
615
738
|
"WhatsApp",
|
|
616
739
|
"Telegram",
|
|
740
|
+
"Slack",
|
|
741
|
+
"Microsoft Teams",
|
|
617
742
|
"Call",
|
|
618
743
|
];
|
|
619
744
|
|
|
@@ -623,6 +748,8 @@ const VERIFIABLE_CHANNEL_NAMES: Array<string> = [
|
|
|
623
748
|
"SMS",
|
|
624
749
|
"WhatsApp",
|
|
625
750
|
"Telegram",
|
|
751
|
+
"Slack",
|
|
752
|
+
"Microsoft Teams",
|
|
626
753
|
"Call",
|
|
627
754
|
"Push",
|
|
628
755
|
];
|
|
@@ -683,6 +810,7 @@ function everySender(): Array<jest.SpyInstance> {
|
|
|
683
810
|
spies.call,
|
|
684
811
|
spies.whatsApp,
|
|
685
812
|
spies.telegram,
|
|
813
|
+
spies.workspace,
|
|
686
814
|
spies.webhook,
|
|
687
815
|
spies.push,
|
|
688
816
|
];
|
|
@@ -696,9 +824,11 @@ function otherSenders(channel: ChannelSpec): Array<jest.SpyInstance> {
|
|
|
696
824
|
});
|
|
697
825
|
}
|
|
698
826
|
|
|
699
|
-
/* The options bag
|
|
700
|
-
function senderOptions(
|
|
701
|
-
return sender.mock.calls[0][
|
|
827
|
+
/* The options bag a sender was handed - the spec says which argument it is. */
|
|
828
|
+
function senderOptions(channel: ChannelSpec): SenderOptions {
|
|
829
|
+
return channel.sender().mock.calls[0][
|
|
830
|
+
channel.senderOptionsArgIndex
|
|
831
|
+
] as SenderOptions;
|
|
702
832
|
}
|
|
703
833
|
|
|
704
834
|
describe("UserNotificationRuleService channel x event coverage", () => {
|
|
@@ -731,6 +861,8 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
731
861
|
userCallId: data.userCallId,
|
|
732
862
|
userWhatsAppId: data.userWhatsAppId,
|
|
733
863
|
userTelegramId: data.userTelegramId,
|
|
864
|
+
userSlackId: data.userSlackId,
|
|
865
|
+
userMicrosoftTeamsId: data.userMicrosoftTeamsId,
|
|
734
866
|
userPushId: data.userPushId,
|
|
735
867
|
userWebhookId: data.userWebhookId,
|
|
736
868
|
},
|
|
@@ -814,6 +946,10 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
814
946
|
telegram: jest
|
|
815
947
|
.spyOn(TelegramService, "sendTelegramMessage")
|
|
816
948
|
.mockResolvedValue(undefined as never),
|
|
949
|
+
/* ONE sender for BOTH workspace channels - see ChannelSpec.workspaceType. */
|
|
950
|
+
workspace: jest
|
|
951
|
+
.spyOn(WorkspaceUserNotificationService, "sendDirectMessageToUser")
|
|
952
|
+
.mockResolvedValue(undefined as never),
|
|
817
953
|
webhook: jest
|
|
818
954
|
.spyOn(WebhookService, "sendWebhook")
|
|
819
955
|
.mockResolvedValue(undefined as never),
|
|
@@ -929,6 +1065,30 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
929
1065
|
"generateTelegramBodyForIncidentEpisodeCreated",
|
|
930
1066
|
)
|
|
931
1067
|
.mockResolvedValue(TELEGRAM_BODY as never),
|
|
1068
|
+
generateWorkspaceMessageBlocksForIncidentCreated: jest
|
|
1069
|
+
.spyOn(
|
|
1070
|
+
UserNotificationRuleService,
|
|
1071
|
+
"generateWorkspaceMessageBlocksForIncidentCreated",
|
|
1072
|
+
)
|
|
1073
|
+
.mockResolvedValue(WORKSPACE_BLOCKS as never),
|
|
1074
|
+
generateWorkspaceMessageBlocksForAlertCreated: jest
|
|
1075
|
+
.spyOn(
|
|
1076
|
+
UserNotificationRuleService,
|
|
1077
|
+
"generateWorkspaceMessageBlocksForAlertCreated",
|
|
1078
|
+
)
|
|
1079
|
+
.mockResolvedValue(WORKSPACE_BLOCKS as never),
|
|
1080
|
+
generateWorkspaceMessageBlocksForAlertEpisodeCreated: jest
|
|
1081
|
+
.spyOn(
|
|
1082
|
+
UserNotificationRuleService,
|
|
1083
|
+
"generateWorkspaceMessageBlocksForAlertEpisodeCreated",
|
|
1084
|
+
)
|
|
1085
|
+
.mockResolvedValue(WORKSPACE_BLOCKS as never),
|
|
1086
|
+
generateWorkspaceMessageBlocksForIncidentEpisodeCreated: jest
|
|
1087
|
+
.spyOn(
|
|
1088
|
+
UserNotificationRuleService,
|
|
1089
|
+
"generateWorkspaceMessageBlocksForIncidentEpisodeCreated",
|
|
1090
|
+
)
|
|
1091
|
+
.mockResolvedValue(WORKSPACE_BLOCKS as never),
|
|
932
1092
|
generateCallTemplateForIncidentCreated: jest
|
|
933
1093
|
.spyOn(
|
|
934
1094
|
UserNotificationRuleService,
|
|
@@ -999,7 +1159,7 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
999
1159
|
/*
|
|
1000
1160
|
* The canary for the next Gap F. Adding a fifth event type to the enum
|
|
1001
1161
|
* fails here until it is added to EVENT_SPECS, at which point the matrix
|
|
1002
|
-
* grows by
|
|
1162
|
+
* grows by nine cells and any channel that forgot the new branch fails.
|
|
1003
1163
|
*/
|
|
1004
1164
|
const members: Array<string> = Object.values(UserNotificationEventType);
|
|
1005
1165
|
|
|
@@ -1033,7 +1193,7 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1033
1193
|
expect(FULL_MATRIX).toHaveLength(
|
|
1034
1194
|
CHANNEL_NAMES.length * EVENT_NAMES.length,
|
|
1035
1195
|
);
|
|
1036
|
-
expect(FULL_MATRIX).toHaveLength(
|
|
1196
|
+
expect(FULL_MATRIX).toHaveLength(36);
|
|
1037
1197
|
});
|
|
1038
1198
|
});
|
|
1039
1199
|
|
|
@@ -1057,6 +1217,17 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1057
1217
|
* line with the provider untouched and the timeline empty.
|
|
1058
1218
|
*/
|
|
1059
1219
|
expect(channel.sender()).toHaveBeenCalledTimes(1);
|
|
1220
|
+
|
|
1221
|
+
/*
|
|
1222
|
+
* Slack and Microsoft Teams share that sender, so "the spy was called"
|
|
1223
|
+
* alone cannot tell a Slack page from a Teams page. The workspaceType
|
|
1224
|
+
* argument can, and must name THIS channel.
|
|
1225
|
+
*/
|
|
1226
|
+
if (channel.workspaceType) {
|
|
1227
|
+
expect(senderOptions(channel).workspaceType).toBe(
|
|
1228
|
+
channel.workspaceType,
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1060
1231
|
},
|
|
1061
1232
|
);
|
|
1062
1233
|
|
|
@@ -1071,6 +1242,20 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1071
1242
|
for (const sender of otherSenders(channel)) {
|
|
1072
1243
|
expect(sender).not.toHaveBeenCalled();
|
|
1073
1244
|
}
|
|
1245
|
+
|
|
1246
|
+
/*
|
|
1247
|
+
* otherSenders cannot separate the two channels that share the
|
|
1248
|
+
* workspace sender, so for those the "no other channel" claim is
|
|
1249
|
+
* finished by checking every call on the shared spy was for THIS
|
|
1250
|
+
* workspace and not its sibling.
|
|
1251
|
+
*/
|
|
1252
|
+
if (channel.workspaceType) {
|
|
1253
|
+
for (const call of channel.sender().mock.calls) {
|
|
1254
|
+
expect((call[0] as SenderOptions).workspaceType).toBe(
|
|
1255
|
+
channel.workspaceType,
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1074
1259
|
},
|
|
1075
1260
|
);
|
|
1076
1261
|
|
|
@@ -1129,7 +1314,7 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1129
1314
|
|
|
1130
1315
|
await deliverCell(channel, event);
|
|
1131
1316
|
|
|
1132
|
-
const options: SenderOptions = senderOptions(channel
|
|
1317
|
+
const options: SenderOptions = senderOptions(channel);
|
|
1133
1318
|
|
|
1134
1319
|
/*
|
|
1135
1320
|
* userOnCallLogTimelineId is how the provider's delivery callback finds
|
|
@@ -1335,7 +1520,16 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1335
1520
|
|
|
1336
1521
|
describe("episode ids on the sender options", () => {
|
|
1337
1522
|
test.each<[string, string]>(
|
|
1338
|
-
buildMatrix([
|
|
1523
|
+
buildMatrix([
|
|
1524
|
+
"Email",
|
|
1525
|
+
"SMS",
|
|
1526
|
+
"WhatsApp",
|
|
1527
|
+
"Telegram",
|
|
1528
|
+
"Slack",
|
|
1529
|
+
"Microsoft Teams",
|
|
1530
|
+
"Call",
|
|
1531
|
+
"Push",
|
|
1532
|
+
]),
|
|
1339
1533
|
)(
|
|
1340
1534
|
"%s links the alert episode it is paging about (%s is ignored unless it is the alert episode)",
|
|
1341
1535
|
async (channelName: string, eventName: string): Promise<void> => {
|
|
@@ -1344,7 +1538,7 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1344
1538
|
|
|
1345
1539
|
await deliverCell(channel, event);
|
|
1346
1540
|
|
|
1347
|
-
const options: SenderOptions = senderOptions(channel
|
|
1541
|
+
const options: SenderOptions = senderOptions(channel);
|
|
1348
1542
|
|
|
1349
1543
|
if (event.eventType === UserNotificationEventType.AlertEpisodeCreated) {
|
|
1350
1544
|
expect(options.alertEpisodeId?.toString()).toBe(
|
|
@@ -1371,11 +1565,39 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1371
1565
|
* without fixing the transport: every one of these services accepts
|
|
1372
1566
|
* incidentEpisodeId in its options type and then never serialises it
|
|
1373
1567
|
* onto the request body. Passing it would read as a link that exists.
|
|
1374
|
-
* Contrast with alertEpisodeId above, which does travel
|
|
1568
|
+
* Contrast with alertEpisodeId above, which does travel - and with the
|
|
1569
|
+
* workspace channels below, which send in-process and DO carry it.
|
|
1375
1570
|
*/
|
|
1376
|
-
expect(
|
|
1377
|
-
|
|
1378
|
-
|
|
1571
|
+
expect(senderOptions(channel).incidentEpisodeId).toBeUndefined();
|
|
1572
|
+
},
|
|
1573
|
+
);
|
|
1574
|
+
|
|
1575
|
+
test.each<[string, string]>(buildMatrix(["Slack", "Microsoft Teams"]))(
|
|
1576
|
+
"%s links the incident episode it is paging about (%s is ignored unless it is the incident episode)",
|
|
1577
|
+
async (channelName: string, eventName: string): Promise<void> => {
|
|
1578
|
+
const channel: ChannelSpec = channelSpec(channelName);
|
|
1579
|
+
const event: EventSpec = eventSpec(eventName);
|
|
1580
|
+
|
|
1581
|
+
await deliverCell(channel, event);
|
|
1582
|
+
|
|
1583
|
+
/*
|
|
1584
|
+
* The workspace sender is not an HTTP transport with a lossy request
|
|
1585
|
+
* body: it runs in-process and stamps whatever ids it is handed onto
|
|
1586
|
+
* the workspace notification log. So unlike the six channels above it
|
|
1587
|
+
* is given the incident episode id - and only when the incident
|
|
1588
|
+
* episode is what fired.
|
|
1589
|
+
*/
|
|
1590
|
+
const options: SenderOptions = senderOptions(channel);
|
|
1591
|
+
|
|
1592
|
+
if (
|
|
1593
|
+
event.eventType === UserNotificationEventType.IncidentEpisodeCreated
|
|
1594
|
+
) {
|
|
1595
|
+
expect(options.incidentEpisodeId?.toString()).toBe(
|
|
1596
|
+
INCIDENT_EPISODE_ID.toString(),
|
|
1597
|
+
);
|
|
1598
|
+
} else {
|
|
1599
|
+
expect(options.incidentEpisodeId).toBeUndefined();
|
|
1600
|
+
}
|
|
1379
1601
|
},
|
|
1380
1602
|
);
|
|
1381
1603
|
});
|
|
@@ -1472,7 +1694,7 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1472
1694
|
* ----------------------------------------------------------------------- *
|
|
1473
1695
|
* (G) The fell-through guard.
|
|
1474
1696
|
*
|
|
1475
|
-
* With all
|
|
1697
|
+
* With all thirty six cells wired, no rule reaches this guard today - which
|
|
1476
1698
|
* is exactly the state it is meant to police, and exactly why it needs a test
|
|
1477
1699
|
* of its own rather than incidental coverage. The precondition it fires on is
|
|
1478
1700
|
* "the channel census found somebody reachable, and then no block claimed the
|
|
@@ -1690,6 +1912,8 @@ describe("UserNotificationRuleService channel x event coverage", () => {
|
|
|
1690
1912
|
["SMS"],
|
|
1691
1913
|
["WhatsApp"],
|
|
1692
1914
|
["Telegram"],
|
|
1915
|
+
["Slack"],
|
|
1916
|
+
["Microsoft Teams"],
|
|
1693
1917
|
["Webhook"],
|
|
1694
1918
|
["Call"],
|
|
1695
1919
|
["Push"],
|