1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
import { expect } from 'chai';
import { it, describe } from 'mocha';
import sinon from 'sinon';
import {
UnsupportedVersionNotificationProvider, UpdateAvailableNotificationProvider,
// UpdateAvailableNotificationProvider,
} from '../../src/shared/notifications/notification';
import NotificationController from '../../src/main/notification-controller';
import { TunnelState } from '../../src/shared/daemon-rpc-types';
import { ErrorStateCause } from '../../src/shared/daemon-rpc-types';
import { FirewallPolicyErrorType } from '../../src/shared/daemon-rpc-types';
function createController() {
return new NotificationController({
openApp: () => { /* no-op */ },
openLink: (_url: string, _withAuth?: boolean) => Promise.resolve(),
showNotificationIcon: (_value: boolean) => { /* no-op */ },
});
}
describe('System notifications', () => {
let sandbox: sinon.SinonSandbox;
before(() => {
sandbox = sinon.createSandbox();
// @ts-ignore
sandbox.stub(NotificationController.prototype, 'createElectronNotification').returns({
show: () => { /* no-op */ },
close: () => { /* no-op */ },
on: () => { /* no-op */ },
removeAllListeners: () => { /* no-op */ },
});
});
it('should evaluate unspupported version notification to show', () => {
const controller1 = createController();
const controller2 = createController();
const notification = new UnsupportedVersionNotificationProvider({
supported: false,
consistent: true,
suggestedUpgrade: '2100.1',
suggestedIsBeta: false,
});
expect(notification.mayDisplay()).to.be.true;
const systemNotification = notification.getSystemNotification();
const result1 = controller1.notify(systemNotification, false, true);
const result2 = controller2.notify(systemNotification, false, false);
expect(result1).to.be.true;
expect(result2).to.be.true;
});
it('should evaluate update available notification to show', () => {
const controller1 = createController();
const controller2 = createController();
const notification = new UpdateAvailableNotificationProvider({
suggestedUpgrade: '2100.1',
suggestedIsBeta: false,
});
expect(notification.mayDisplay()).to.be.true;
const systemNotification = notification.getSystemNotification();
const result1 = controller1.notify(systemNotification, false, true);
const result2 = controller2.notify(systemNotification, false, false);
expect(result1).to.be.true;
expect(result2).to.be.true;
});
it('should show unsupported version notification only once', () => {
const controller = createController();
const notification = new UnsupportedVersionNotificationProvider({
supported: false,
consistent: true,
suggestedUpgrade: '2100.1',
suggestedIsBeta: false,
});
const systemNotification = notification.getSystemNotification();
const result1 = controller.notify(systemNotification, false, true);
const result2 = controller.notify(systemNotification, false, true);
expect(result1).to.be.true;
expect(result2).to.be.false;
});
it('should not show notification when window is open', () => {
const controller = createController();
const notification = new UnsupportedVersionNotificationProvider({
supported: false,
consistent: true,
suggestedUpgrade: '2100.1',
suggestedIsBeta: false,
});
const systemNotification = notification.getSystemNotification();
const result = controller.notify(systemNotification, true, true);
expect(result).to.be.false;
});
it('Tunnel state notifications should respect notification setting', () => {
const controller = createController();
const disconnectedState: TunnelState = { state: 'disconnected' };
const connectingState: TunnelState = { state: 'connecting' };
const result1 = controller.notifyTunnelState(disconnectedState, false, false, false, true);
const result2 = controller.notifyTunnelState(disconnectedState, false, false, false, false);
const result3 = controller.notifyTunnelState(connectingState, false, false, false, true);
const result4 = controller.notifyTunnelState(connectingState, false, false, false, false);
expect(result1).to.be.true;
expect(result2).to.be.false;
expect(result3).to.be.true;
expect(result4).to.be.false;
const blockingErrorState: TunnelState = {
state: 'error',
details: {
cause: ErrorStateCause.isOffline,
},
};
const result5 = controller.notifyTunnelState(blockingErrorState, false, false, false, false);
expect(result5).to.be.false;
const nonBlockingErrorState: TunnelState = {
state: 'error',
details: {
cause: ErrorStateCause.isOffline,
blockingError: {
type: FirewallPolicyErrorType.generic,
}
},
};
const result6 = controller.notifyTunnelState(nonBlockingErrorState, false, false, false, false);
expect(result6).to.be.true;
});
});
|