Skip to content

Commit b444730

Browse files
Merge master into feature/emr
2 parents f8009d2 + 988dea0 commit b444730

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

packages/core/src/notifications/rules.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as semver from 'semver'
88
import globals from '../shared/extensionGlobals'
99
import { ConditionalClause, RuleContext, DisplayIf, CriteriaCondition, ToolkitNotification, AuthState } from './types'
1010
import { getComputeEnvType, getOperatingSystem } from '../shared/telemetry/util'
11+
import { isAutomation } from '../shared/vscode/env'
1112
import { AuthFormId } from '../login/webview/vue/types'
1213
import { getLogger } from '../shared/logger/logger'
1314
import { ToolkitError } from '../shared/errors'
@@ -79,7 +80,8 @@ export class RuleEngine {
7980

8081
private evaluate(id: string, condition: DisplayIf): boolean {
8182
const currentExt = globals.context.extension.id
82-
if (condition.extensionId !== currentExt) {
83+
// if in test, skip the extension id check since its fake
84+
if (condition.extensionId !== currentExt && !isAutomation()) {
8385
logger.verbose(
8486
'notification id: (%s) did NOT pass extension id check, actual ext id: (%s), expected ext id: (%s)',
8587
id,
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0 fort
4+
*/
5+
6+
import { RemoteFetcher } from '../../notifications/controller'
7+
import { NotificationsController } from '../../notifications/controller'
8+
import { NotificationsNode } from '../../notifications/panelNode'
9+
import { RuleEngine } from '../../notifications/rules'
10+
import { NotificationsState, RuleContext } from '../../notifications/types'
11+
import globals from '../../shared/extensionGlobals'
12+
import assert from 'assert'
13+
import { VSCODE_EXTENSION_ID } from '../../shared/extensions'
14+
import sinon from 'sinon'
15+
16+
describe('Notifications Integration Test', function () {
17+
let fetcher: RemoteFetcher
18+
let panelNode: NotificationsNode
19+
let controller: NotificationsController
20+
21+
function getEngine(activeExtensions: string[], connected: boolean): RuleEngine {
22+
const authState = connected ? 'connected' : 'notConnected'
23+
24+
const ruleContext: RuleContext = {
25+
ideVersion: '1.83.0',
26+
extensionVersion: '1.20.0',
27+
os: 'LINUX',
28+
computeEnv: 'local',
29+
authTypes: ['builderId'],
30+
authRegions: ['us-east-2'],
31+
authStates: [authState],
32+
authScopes: ['codewhisperer:completions', 'codewhisperer:analysis'],
33+
activeExtensions: activeExtensions,
34+
}
35+
36+
return new RuleEngine(ruleContext)
37+
}
38+
39+
beforeEach(async function () {
40+
panelNode = NotificationsNode.instance
41+
// fetch from test host file folder
42+
fetcher = new RemoteFetcher(
43+
'https://idetoolkits-hostedfiles.amazonaws.com/Notifications/integ/VSCode/startup/1.x.json',
44+
'https://idetoolkits-hostedfiles.amazonaws.com/Notifications/integ/VSCode/emergency/1.x.json'
45+
)
46+
controller = new NotificationsController(panelNode, fetcher)
47+
})
48+
49+
// Clear all global states after each test
50+
afterEach(async function () {
51+
await globals.globalState.update(controller.storageKey, undefined)
52+
})
53+
54+
it('Receive notifications polling from endpoint', async function () {
55+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], true)
56+
57+
await controller.pollForStartUp(engine)
58+
await controller.pollForEmergencies(engine)
59+
60+
// Verify that notifications are stored in the state
61+
const state = globals.globalState.get<NotificationsState>(controller.storageKey)
62+
assert.ok(state, 'State should be defined')
63+
assert.ok(state.startUp.payload?.notifications, 'StartUp received')
64+
assert.strictEqual(
65+
state?.startUp.payload?.notifications.length,
66+
2,
67+
'There should be 2 startup notifications stored'
68+
)
69+
assert.ok(state?.emergency.payload?.notifications, 'Emergency received')
70+
assert.strictEqual(
71+
state?.emergency.payload?.notifications.length,
72+
2,
73+
'There should be 2 emergency notifications stored'
74+
)
75+
})
76+
77+
it('Display notification according to criterias', async function () {
78+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], false)
79+
await controller.pollForEmergencies(engine)
80+
81+
// Verify that only the not authed notification is displayed
82+
const displayedNotifications = panelNode.emergencyNotifications
83+
assert.strictEqual(displayedNotifications.length, 1, 'Only one notification displayed"')
84+
assert.strictEqual(
85+
displayedNotifications[0].id,
86+
'emergency1',
87+
'The displayed notification have the ID "emergency1"'
88+
)
89+
})
90+
91+
it('Should trigger onReceive only for newly received notifications', async function () {
92+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], true)
93+
const onReceiveSpy = sinon.spy(panelNode, 'onReceiveNotifications')
94+
95+
// Simulate alreadying receving a notification
96+
const existingNotificationID = 'startup1'
97+
const state = globals.globalState.get<NotificationsState>(controller.storageKey)
98+
if (state) {
99+
state.newlyReceived.push(existingNotificationID)
100+
await globals.globalState.update(controller.storageKey, state)
101+
}
102+
103+
// Poll for new notification
104+
await controller.pollForStartUp(engine)
105+
106+
/**
107+
* Since we simulated startup1 is already received
108+
* onReceived should be called exactly once for startup2
109+
*/
110+
assert.ok(onReceiveSpy.calledOnce, 'only one new notification received')
111+
112+
onReceiveSpy.restore()
113+
})
114+
})

0 commit comments

Comments
 (0)