Skip to content

Commit af5b318

Browse files
committed
test(notifications): integ test from hosted endpoints
1 parent 4235561 commit af5b318

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-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

1213
/**
1314
* Evaluates if a given version fits into the parameters specified by a notification, e.g:
@@ -69,7 +70,8 @@ export class RuleEngine {
6970

7071
private evaluate(condition: DisplayIf): boolean {
7172
const currentExt = globals.context.extension.id
72-
if (condition.extensionId !== currentExt) {
73+
// if in test, skip the extension id check since its fake
74+
if (condition.extensionId !== currentExt && !isAutomation()) {
7375
return false
7476
}
7577

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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+
installedExtensions: Object.keys(VSCODE_EXTENSION_ID),
34+
activeExtensions: activeExtensions,
35+
}
36+
37+
return new RuleEngine(ruleContext)
38+
}
39+
40+
beforeEach(async function () {
41+
panelNode = NotificationsNode.instance
42+
// fetch from test host file folder
43+
fetcher = new RemoteFetcher(
44+
'https://idetoolkits-hostedfiles.amazonaws.com/Notifications/integ/VSCode/startup/1.x.json',
45+
'https://idetoolkits-hostedfiles.amazonaws.com/Notifications/integ/VSCode/emergency/1.x.json'
46+
)
47+
controller = new NotificationsController(panelNode, fetcher)
48+
})
49+
50+
// Clear all global states after each test
51+
afterEach(async function () {
52+
await globals.globalState.update(controller.storageKey, undefined)
53+
})
54+
55+
it('Receive notifications polling from endpoint', async function () {
56+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], true)
57+
58+
await controller.pollForStartUp(engine)
59+
await controller.pollForEmergencies(engine)
60+
61+
// Verify that notifications are stored in the state
62+
const state = globals.globalState.get<NotificationsState>(controller.storageKey)
63+
assert.ok(state, 'State should be defined')
64+
assert.ok(state.startUp.payload?.notifications, 'StartUp received')
65+
assert.strictEqual(
66+
state?.startUp.payload?.notifications.length,
67+
2,
68+
'There should be 2 startup notifications stored'
69+
)
70+
assert.ok(state?.emergency.payload?.notifications, 'Emergency received')
71+
assert.strictEqual(
72+
state?.emergency.payload?.notifications.length,
73+
2,
74+
'There should be 2 emergency notifications stored'
75+
)
76+
})
77+
78+
it('Display notification according to criterias', async function () {
79+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], false)
80+
await controller.pollForEmergencies(engine)
81+
82+
// Verify that only the not authed notification is displayed
83+
const displayedNotifications = panelNode.emergencyNotifications
84+
assert.strictEqual(displayedNotifications.length, 1, 'Only one notification displayed"')
85+
assert.strictEqual(
86+
displayedNotifications[0].id,
87+
'emergency1',
88+
'The displayed notification have the ID "emergency1"'
89+
)
90+
})
91+
92+
it('Should trigger onReceive only for newly received notifications', async function () {
93+
const engine = getEngine([VSCODE_EXTENSION_ID.amazonq], true)
94+
const onReceiveSpy = sinon.spy(panelNode, 'onReceiveNotifications')
95+
96+
// Simulate alreadying receving a notification
97+
const existingNotificationID = 'startup1'
98+
const state = globals.globalState.get<NotificationsState>(controller.storageKey)
99+
if (state) {
100+
state.newlyReceived.push(existingNotificationID)
101+
await globals.globalState.update(controller.storageKey, state)
102+
}
103+
104+
// Poll for new notification
105+
await controller.pollForStartUp(engine)
106+
107+
/**
108+
* Since we simulated startup1 is already received
109+
* onReceived should be called exactly once for startup2
110+
*/
111+
assert.ok(onReceiveSpy.calledOnce, 'only one new notification received')
112+
113+
onReceiveSpy.restore()
114+
})
115+
})

0 commit comments

Comments
 (0)