@dronedeploy/rocos-js-sdk 3.0.1-alpha.11 → 3.0.1-alpha.14
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/cjs/RocosSDK.d.ts +3 -1
- package/cjs/RocosSDK.js +1 -0
- package/cjs/api/streams/caller/CallerStream.js +5 -2
- package/cjs/api/streams/caller/CallerStreamNode.js +2 -1
- package/cjs/api/streams/command/CommandStream.js +5 -2
- package/cjs/api/streams/command/CommandStreamNode.js +2 -1
- package/cjs/api/streams/control/ControlStream.js +5 -2
- package/cjs/api/streams/control/ControlStreamAbstract.d.ts +1 -1
- package/cjs/api/streams/control/ControlStreamNode.js +2 -1
- package/cjs/api/streams/fileAccessor/FileAccessorStream.js +4 -1
- package/cjs/api/streams/fileAccessor/FileAccessorStreamNode.js +3 -1
- package/cjs/api/streams/search/SearchStream.js +5 -2
- package/cjs/api/streams/search/SearchStreamNode.js +2 -1
- package/cjs/api/streams/telemetry/TelemetryStream.js +4 -1
- package/cjs/api/streams/telemetry/TelemetryStreamAbstract.d.ts +1 -1
- package/cjs/api/streams/telemetry/TelemetryStreamNode.js +2 -1
- package/cjs/api/streams/webRTCSignalling/WebRTCSignallingStream.js +5 -2
- package/cjs/constants/api.d.ts +2 -0
- package/cjs/constants/api.js +4 -2
- package/cjs/helpers/getUniqueConfigKey.d.ts +6 -2
- package/cjs/helpers/getUniqueConfigKey.js +7 -2
- package/cjs/services/ProfileService.d.ts +23 -0
- package/cjs/services/ProfileService.js +28 -0
- package/cjs/services/RTPWebRTCService.d.ts +1 -1
- package/cjs/services/RTPWebRTCService.js +4 -2
- package/cjs/store/RocosStore.d.ts +1 -2
- package/esm/RocosSDK.d.ts +3 -1
- package/esm/RocosSDK.js +1 -0
- package/esm/api/streams/caller/CallerStream.js +5 -2
- package/esm/api/streams/caller/CallerStreamNode.js +2 -1
- package/esm/api/streams/command/CommandStream.js +5 -2
- package/esm/api/streams/command/CommandStreamNode.js +2 -1
- package/esm/api/streams/control/ControlStream.js +5 -2
- package/esm/api/streams/control/ControlStreamAbstract.d.ts +1 -1
- package/esm/api/streams/control/ControlStreamNode.js +2 -1
- package/esm/api/streams/fileAccessor/FileAccessorStream.js +4 -1
- package/esm/api/streams/fileAccessor/FileAccessorStreamNode.js +3 -1
- package/esm/api/streams/search/SearchStream.js +5 -2
- package/esm/api/streams/search/SearchStreamNode.js +2 -1
- package/esm/api/streams/telemetry/TelemetryStream.js +4 -1
- package/esm/api/streams/telemetry/TelemetryStreamAbstract.d.ts +1 -1
- package/esm/api/streams/telemetry/TelemetryStreamNode.js +2 -1
- package/esm/api/streams/webRTCSignalling/WebRTCSignallingStream.js +5 -2
- package/esm/constants/api.d.ts +2 -0
- package/esm/constants/api.js +2 -0
- package/esm/helpers/getUniqueConfigKey.d.ts +6 -2
- package/esm/helpers/getUniqueConfigKey.js +7 -2
- package/esm/services/ProfileService.d.ts +23 -0
- package/esm/services/ProfileService.js +29 -1
- package/esm/services/RTPWebRTCService.d.ts +1 -1
- package/esm/services/RTPWebRTCService.js +4 -2
- package/esm/store/RocosStore.d.ts +1 -2
- package/package.json +1 -1
- package/cjs/helpers/cleanObject.spec.d.ts +0 -1
- package/cjs/helpers/cleanObject.spec.js +0 -55
- package/cjs/helpers/flattenObject.spec.d.ts +0 -1
- package/cjs/helpers/flattenObject.spec.js +0 -31
- package/cjs/helpers/flattenOneOf.spec.d.ts +0 -1
- package/cjs/helpers/flattenOneOf.spec.js +0 -159
- package/cjs/helpers/formatServiceUrl.spec.d.ts +0 -1
- package/cjs/helpers/formatServiceUrl.spec.js +0 -18
- package/cjs/helpers/getSha256Hex.spec.d.ts +0 -1
- package/cjs/helpers/getSha256Hex.spec.js +0 -19
- package/cjs/helpers/getSha256HexNode.spec.d.ts +0 -1
- package/cjs/helpers/getSha256HexNode.spec.js +0 -10
- package/cjs/helpers/getURLSearchParams.spec.d.ts +0 -1
- package/cjs/helpers/getURLSearchParams.spec.js +0 -21
- package/cjs/helpers/nanosecondToMillisecond.spec.d.ts +0 -1
- package/cjs/helpers/nanosecondToMillisecond.spec.js +0 -22
- package/cjs/helpers/splitRobotTopic.spec.d.ts +0 -1
- package/cjs/helpers/splitRobotTopic.spec.js +0 -53
- package/cjs/helpers/standardDeviation.spec.d.ts +0 -1
- package/cjs/helpers/standardDeviation.spec.js +0 -13
- package/cjs/helpers/websandbox/frame/worker/manager.spec.d.ts +0 -4
- package/cjs/helpers/websandbox/frame/worker/manager.spec.js +0 -132
- package/cjs/models/Token.spec.d.ts +0 -1
- package/cjs/models/Token.spec.js +0 -110
- package/cjs/services/AuthService.spec.d.ts +0 -1
- package/cjs/services/AuthService.spec.js +0 -165
- package/cjs/services/CallerService.spec.d.ts +0 -1
- package/cjs/services/CallerService.spec.js +0 -229
- package/cjs/services/PlatformTimeService.spec.d.ts +0 -1
- package/cjs/services/PlatformTimeService.spec.js +0 -182
- package/cjs/services/RTPWebRTCService.spec.d.ts +0 -4
- package/cjs/services/RTPWebRTCService.spec.js +0 -171
- package/cjs/services/TelemetryService.spec.d.ts +0 -1
- package/cjs/services/TelemetryService.spec.js +0 -39
- package/esm/helpers/cleanObject.spec.d.ts +0 -1
- package/esm/helpers/cleanObject.spec.js +0 -53
- package/esm/helpers/flattenObject.spec.d.ts +0 -1
- package/esm/helpers/flattenObject.spec.js +0 -29
- package/esm/helpers/flattenOneOf.spec.d.ts +0 -1
- package/esm/helpers/flattenOneOf.spec.js +0 -157
- package/esm/helpers/formatServiceUrl.spec.d.ts +0 -1
- package/esm/helpers/formatServiceUrl.spec.js +0 -16
- package/esm/helpers/getSha256Hex.spec.d.ts +0 -1
- package/esm/helpers/getSha256Hex.spec.js +0 -14
- package/esm/helpers/getSha256HexNode.spec.d.ts +0 -1
- package/esm/helpers/getSha256HexNode.spec.js +0 -8
- package/esm/helpers/getURLSearchParams.spec.d.ts +0 -1
- package/esm/helpers/getURLSearchParams.spec.js +0 -19
- package/esm/helpers/nanosecondToMillisecond.spec.d.ts +0 -1
- package/esm/helpers/nanosecondToMillisecond.spec.js +0 -20
- package/esm/helpers/splitRobotTopic.spec.d.ts +0 -1
- package/esm/helpers/splitRobotTopic.spec.js +0 -51
- package/esm/helpers/standardDeviation.spec.d.ts +0 -1
- package/esm/helpers/standardDeviation.spec.js +0 -11
- package/esm/helpers/websandbox/frame/worker/manager.spec.d.ts +0 -4
- package/esm/helpers/websandbox/frame/worker/manager.spec.js +0 -127
- package/esm/models/Token.spec.d.ts +0 -1
- package/esm/models/Token.spec.js +0 -108
- package/esm/services/AuthService.spec.d.ts +0 -1
- package/esm/services/AuthService.spec.js +0 -163
- package/esm/services/CallerService.spec.d.ts +0 -1
- package/esm/services/CallerService.spec.js +0 -227
- package/esm/services/PlatformTimeService.spec.d.ts +0 -1
- package/esm/services/PlatformTimeService.spec.js +0 -180
- package/esm/services/RTPWebRTCService.spec.d.ts +0 -4
- package/esm/services/RTPWebRTCService.spec.js +0 -169
- package/esm/services/TelemetryService.spec.d.ts +0 -1
- package/esm/services/TelemetryService.spec.js +0 -37
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @jest-environment jsdom
|
|
4
|
-
*/
|
|
5
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const manager_1 = __importDefault(require("./manager"));
|
|
10
|
-
const WorkerMocks = {
|
|
11
|
-
postMessage: jest.fn(),
|
|
12
|
-
terminate: jest.fn(),
|
|
13
|
-
addEventListener: jest.fn(),
|
|
14
|
-
removeEventListener: jest.fn(),
|
|
15
|
-
onerror: jest.fn(),
|
|
16
|
-
onmessage: jest.fn(),
|
|
17
|
-
onmessageerror: jest.fn(),
|
|
18
|
-
dispatchEvent: jest.fn(),
|
|
19
|
-
clearAllMocks() {
|
|
20
|
-
this.postMessage.mockClear();
|
|
21
|
-
this.terminate.mockClear();
|
|
22
|
-
this.addEventListener.mockClear();
|
|
23
|
-
this.removeEventListener.mockClear();
|
|
24
|
-
this.onerror.mockClear();
|
|
25
|
-
this.onmessage.mockClear();
|
|
26
|
-
this.onmessageerror.mockClear();
|
|
27
|
-
this.dispatchEvent.mockClear();
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
class MockWorkerClass {
|
|
31
|
-
constructor() {
|
|
32
|
-
this.postMessage = WorkerMocks.postMessage;
|
|
33
|
-
this.terminate = WorkerMocks.terminate;
|
|
34
|
-
this.addEventListener = WorkerMocks.addEventListener;
|
|
35
|
-
this.removeEventListener = WorkerMocks.removeEventListener;
|
|
36
|
-
this.onerror = WorkerMocks.onerror;
|
|
37
|
-
this.onmessage = WorkerMocks.onmessage;
|
|
38
|
-
this.onmessageerror = WorkerMocks.onmessageerror;
|
|
39
|
-
this.dispatchEvent = WorkerMocks.dispatchEvent;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
Object.defineProperty(window, 'Worker', {
|
|
43
|
-
value: MockWorkerClass,
|
|
44
|
-
writable: true,
|
|
45
|
-
});
|
|
46
|
-
Object.defineProperty(window, 'URL', {
|
|
47
|
-
value: {
|
|
48
|
-
createObjectURL: jest.fn(),
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
// add mock to AbortSignal.timeout
|
|
52
|
-
Object.defineProperty(AbortSignal, 'timeout', {
|
|
53
|
-
value: jest.fn().mockImplementation((timeout) => {
|
|
54
|
-
return new AbortController().signal;
|
|
55
|
-
}),
|
|
56
|
-
});
|
|
57
|
-
const task = {
|
|
58
|
-
id: 'test',
|
|
59
|
-
code: '1',
|
|
60
|
-
timeout: 1000,
|
|
61
|
-
};
|
|
62
|
-
const response = {
|
|
63
|
-
data: {
|
|
64
|
-
id: 'test',
|
|
65
|
-
success: true,
|
|
66
|
-
result: 'test',
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
describe('WorkerManager', () => {
|
|
70
|
-
beforeEach(() => {
|
|
71
|
-
WorkerMocks.clearAllMocks();
|
|
72
|
-
});
|
|
73
|
-
it('should send a task to the worker', async () => {
|
|
74
|
-
const listeners = [];
|
|
75
|
-
WorkerMocks.addEventListener.mockImplementation((_, listener) => {
|
|
76
|
-
listeners.push(listener);
|
|
77
|
-
});
|
|
78
|
-
WorkerMocks.postMessage.mockImplementation((msg) => {
|
|
79
|
-
listeners.forEach((listener) => {
|
|
80
|
-
listener(response);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
const manager = new manager_1.default();
|
|
84
|
-
const result = await manager.execute(task);
|
|
85
|
-
expect(result).toEqual('test');
|
|
86
|
-
});
|
|
87
|
-
it('should handle listener for a single task', async () => {
|
|
88
|
-
const listeners = [];
|
|
89
|
-
WorkerMocks.addEventListener.mockImplementation((_, listener) => {
|
|
90
|
-
listeners.push(listener);
|
|
91
|
-
});
|
|
92
|
-
WorkerMocks.removeEventListener.mockImplementation((_, listener) => {
|
|
93
|
-
const index = listeners.indexOf(listener);
|
|
94
|
-
listeners.splice(index, 1);
|
|
95
|
-
});
|
|
96
|
-
const manager = new manager_1.default();
|
|
97
|
-
expect(listeners.length).toEqual(0);
|
|
98
|
-
const result = manager.execute(task);
|
|
99
|
-
expect(listeners.length).toEqual(1);
|
|
100
|
-
listeners[0](response);
|
|
101
|
-
await result;
|
|
102
|
-
expect(listeners.length).toEqual(0);
|
|
103
|
-
});
|
|
104
|
-
it('should handle listener for multiple simultaneous task', async () => {
|
|
105
|
-
const listeners = [];
|
|
106
|
-
WorkerMocks.addEventListener.mockImplementation((_, listener) => {
|
|
107
|
-
listeners.push(listener);
|
|
108
|
-
});
|
|
109
|
-
WorkerMocks.removeEventListener.mockImplementation((_, listener) => {
|
|
110
|
-
const index = listeners.indexOf(listener);
|
|
111
|
-
listeners.splice(index, 1);
|
|
112
|
-
});
|
|
113
|
-
const manager = new manager_1.default();
|
|
114
|
-
expect(listeners.length).toEqual(0);
|
|
115
|
-
const result1 = manager.execute(task);
|
|
116
|
-
const result2 = manager.execute(task);
|
|
117
|
-
expect(listeners.length).toEqual(2);
|
|
118
|
-
const result3 = manager.execute(task);
|
|
119
|
-
expect(listeners.length).toEqual(3);
|
|
120
|
-
const [listener1, listener2, listener3] = listeners;
|
|
121
|
-
listener1(response);
|
|
122
|
-
await result1;
|
|
123
|
-
expect(listeners.length).toEqual(2);
|
|
124
|
-
listener3(response);
|
|
125
|
-
await result3;
|
|
126
|
-
expect(listeners.length).toEqual(1);
|
|
127
|
-
listener2(response);
|
|
128
|
-
await result2;
|
|
129
|
-
expect(listeners.length).toEqual(0);
|
|
130
|
-
expect(WorkerMocks.removeEventListener).toHaveBeenCalledTimes(3);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/cjs/models/Token.spec.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const Token_1 = require("./Token");
|
|
4
|
-
const generateToken = (config) => {
|
|
5
|
-
const defaultPayload = {
|
|
6
|
-
iat: 1234567890,
|
|
7
|
-
exp: 9876543210,
|
|
8
|
-
iss: 'myissuer',
|
|
9
|
-
aud: 'myaudience',
|
|
10
|
-
sub: 'mysubject',
|
|
11
|
-
};
|
|
12
|
-
const encodedHeader = Buffer.from(JSON.stringify(config?.header ?? { alg: 'HS256', typ: 'JWT' })).toString('base64');
|
|
13
|
-
const encodedPayload = Buffer.from(JSON.stringify(config?.payload ?? defaultPayload)).toString('base64');
|
|
14
|
-
if (config?.signature === null) {
|
|
15
|
-
return `${encodedHeader}.${encodedPayload}`;
|
|
16
|
-
}
|
|
17
|
-
return `${encodedHeader}.${encodedPayload}.${config?.signature ?? 'signature'}`;
|
|
18
|
-
};
|
|
19
|
-
describe('Token', () => {
|
|
20
|
-
describe('constructor', () => {
|
|
21
|
-
it('can get information from a valid token', () => {
|
|
22
|
-
const token = new Token_1.Token(generateToken());
|
|
23
|
-
expect(token.issuedAt).toEqual(new Date(1234567890000));
|
|
24
|
-
expect(token.expires).toEqual(new Date(9876543210000));
|
|
25
|
-
expect(token.issuer).toEqual('myissuer');
|
|
26
|
-
expect(token.audience).toEqual('myaudience');
|
|
27
|
-
expect(token.subject).toEqual('mysubject');
|
|
28
|
-
});
|
|
29
|
-
it('should throw an error for a non-jwt', () => {
|
|
30
|
-
// completely invalid string
|
|
31
|
-
expect(() => new Token_1.Token('not a jwt')).toThrowError('Invalid token');
|
|
32
|
-
// invalid header
|
|
33
|
-
expect(() => {
|
|
34
|
-
new Token_1.Token(generateToken({
|
|
35
|
-
header: {
|
|
36
|
-
alg: 'HS256',
|
|
37
|
-
typ: 'Not-a-JWT',
|
|
38
|
-
},
|
|
39
|
-
}));
|
|
40
|
-
}).toThrowError('Invalid token');
|
|
41
|
-
// too many parts
|
|
42
|
-
expect(() => {
|
|
43
|
-
new Token_1.Token('a.b.c.d');
|
|
44
|
-
}).toThrowError('Invalid token');
|
|
45
|
-
});
|
|
46
|
-
it('should allow a token with no signature', () => {
|
|
47
|
-
const token = new Token_1.Token(generateToken({ signature: null }));
|
|
48
|
-
expect(token.issuedAt).toEqual(new Date(1234567890000));
|
|
49
|
-
expect(token.expires).toEqual(new Date(9876543210000));
|
|
50
|
-
expect(token.issuer).toEqual('myissuer');
|
|
51
|
-
expect(token.audience).toEqual('myaudience');
|
|
52
|
-
expect(token.subject).toEqual('mysubject');
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
describe('isExpired', () => {
|
|
56
|
-
const baseDate = new Date(2021, 0, 1, 0, 0, 0, 0);
|
|
57
|
-
beforeEach(() => {
|
|
58
|
-
jest.useFakeTimers();
|
|
59
|
-
jest.setSystemTime(baseDate);
|
|
60
|
-
});
|
|
61
|
-
afterEach(() => {
|
|
62
|
-
jest.useRealTimers();
|
|
63
|
-
});
|
|
64
|
-
const expiredDate = (baseDate.getTime() - 1000 * 60 * 5) / 1000; // 5 minutes ago
|
|
65
|
-
const notExpiredDate = (baseDate.getTime() + 1000 * 60 * 60 * 24) / 1000; // 1 day from now
|
|
66
|
-
it('should return true if the token is expired', () => {
|
|
67
|
-
const token = new Token_1.Token(generateToken({ payload: { exp: expiredDate } }));
|
|
68
|
-
expect(token.isExpired()).toEqual(true);
|
|
69
|
-
});
|
|
70
|
-
it('should return false if the token is not expired', () => {
|
|
71
|
-
const token = new Token_1.Token(generateToken({ payload: { exp: notExpiredDate } }));
|
|
72
|
-
expect(token.isExpired()).toEqual(false);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('isExpiredIn', () => {
|
|
76
|
-
const baseDate = new Date(2021, 0, 1, 0, 0, 0, 0);
|
|
77
|
-
beforeEach(() => {
|
|
78
|
-
jest.useFakeTimers();
|
|
79
|
-
jest.setSystemTime(baseDate);
|
|
80
|
-
});
|
|
81
|
-
afterEach(() => {
|
|
82
|
-
jest.useRealTimers();
|
|
83
|
-
});
|
|
84
|
-
const expiredDate = (baseDate.getTime() - 1000 * 60 * 5) / 1000; // 5 minutes ago
|
|
85
|
-
const expiredIn5MinsDate = (baseDate.getTime() + 1000 * 60 * 5) / 1000; // 5 minutes from now
|
|
86
|
-
const expiredIn25MinsDate = (baseDate.getTime() + 1000 * 60 * 25) / 1000; // 25 minutes from now
|
|
87
|
-
const expiredIn2HoursDate = (baseDate.getTime() + 1000 * 60 * 60 * 2) / 1000; // 2 hours from now
|
|
88
|
-
it('should return true if the token is expired in the given time', () => {
|
|
89
|
-
const token = new Token_1.Token(generateToken({ payload: { exp: expiredIn5MinsDate } }));
|
|
90
|
-
expect(token.isExpiredIn(5, 'minutes')).toEqual(true);
|
|
91
|
-
expect(token.isExpiredIn(25, 'minutes')).toEqual(true);
|
|
92
|
-
expect(token.isExpiredIn(2, 'hours')).toEqual(true);
|
|
93
|
-
const token2 = new Token_1.Token(generateToken({ payload: { exp: expiredIn25MinsDate } }));
|
|
94
|
-
expect(token2.isExpiredIn(25, 'minutes')).toEqual(true);
|
|
95
|
-
expect(token2.isExpiredIn(2, 'hours')).toEqual(true);
|
|
96
|
-
const token3 = new Token_1.Token(generateToken({ payload: { exp: expiredDate } }));
|
|
97
|
-
expect(token3.isExpiredIn(5, 'minutes')).toEqual(true);
|
|
98
|
-
expect(token3.isExpiredIn(25, 'minutes')).toEqual(true);
|
|
99
|
-
expect(token3.isExpiredIn(2, 'hours')).toEqual(true);
|
|
100
|
-
});
|
|
101
|
-
it('should return false if the token is not expired in the given time', () => {
|
|
102
|
-
const token = new Token_1.Token(generateToken({ payload: { exp: expiredIn5MinsDate } }));
|
|
103
|
-
expect(token.isExpiredIn(4, 'minutes')).toEqual(false);
|
|
104
|
-
const token2 = new Token_1.Token(generateToken({ payload: { exp: expiredIn25MinsDate } }));
|
|
105
|
-
expect(token2.isExpiredIn(24, 'minutes')).toEqual(false);
|
|
106
|
-
const token3 = new Token_1.Token(generateToken({ payload: { exp: expiredIn2HoursDate } }));
|
|
107
|
-
expect(token3.isExpiredIn(1, 'hours')).toEqual(false);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const auth_1 = require("../constants/auth");
|
|
4
|
-
const AuthService_1 = require("./AuthService");
|
|
5
|
-
const models_1 = require("../models");
|
|
6
|
-
describe('authService', () => {
|
|
7
|
-
const baseDate = new Date(2021, 0, 1, 0, 0, 0, 0);
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
jest.useFakeTimers();
|
|
10
|
-
jest.setSystemTime(baseDate);
|
|
11
|
-
});
|
|
12
|
-
const expiredDate = new Date(baseDate.getTime() - 1000 * 60 * 5); // 5 minutes ago
|
|
13
|
-
const almostExpiredDate = new Date(baseDate.getTime() + 1000 * 60 * 5); // 5 minutes from now
|
|
14
|
-
const almostAlmostExpiredDate = new Date(baseDate.getTime() + 1000 * 60 * 25); // 35 minutes from now
|
|
15
|
-
const notExpiredDate = new Date(baseDate.getTime() + 1000 * 60 * 60 * 24); // 1 day from now
|
|
16
|
-
const getToken = (config) => {
|
|
17
|
-
const header = {
|
|
18
|
-
alg: 'HS256',
|
|
19
|
-
typ: 'JWT',
|
|
20
|
-
};
|
|
21
|
-
const payload = {
|
|
22
|
-
iat: Math.floor((config.iat ?? expiredDate).getTime() / 1000),
|
|
23
|
-
exp: Math.floor((config.exp ?? notExpiredDate).getTime() / 1000),
|
|
24
|
-
iss: config.iss ?? auth_1.issuer,
|
|
25
|
-
aud: config.aud ?? 'myaudience',
|
|
26
|
-
sub: config.sub ?? 'mysubject',
|
|
27
|
-
};
|
|
28
|
-
const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64');
|
|
29
|
-
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64');
|
|
30
|
-
if (config.signature === false) {
|
|
31
|
-
return `${encodedHeader}.${encodedPayload}`;
|
|
32
|
-
}
|
|
33
|
-
return `${encodedHeader}.${encodedPayload}.signature`;
|
|
34
|
-
};
|
|
35
|
-
afterAll(() => jest.useRealTimers());
|
|
36
|
-
describe('getToken', () => {
|
|
37
|
-
it('should return the current token if it is not expired', async () => {
|
|
38
|
-
// Arrange
|
|
39
|
-
const token = getToken({ exp: notExpiredDate });
|
|
40
|
-
const service = new AuthService_1.AuthService({
|
|
41
|
-
token,
|
|
42
|
-
url: 'http://localhost:0',
|
|
43
|
-
});
|
|
44
|
-
service.setToken(token);
|
|
45
|
-
// Act
|
|
46
|
-
const newToken = await service.getToken();
|
|
47
|
-
// Assert
|
|
48
|
-
expect(newToken.value).toEqual(token);
|
|
49
|
-
});
|
|
50
|
-
it('should refresh the token if it is about to expire', async () => {
|
|
51
|
-
// Arrange
|
|
52
|
-
const token = getToken({ exp: almostExpiredDate });
|
|
53
|
-
const service = new AuthService_1.AuthService({
|
|
54
|
-
token,
|
|
55
|
-
url: 'http://localhost:0',
|
|
56
|
-
});
|
|
57
|
-
service.setToken(token);
|
|
58
|
-
const expected = getToken({ signature: false });
|
|
59
|
-
jest.spyOn(AuthService_1.AuthService.prototype, 'refreshToken').mockResolvedValue(new models_1.Token(expected));
|
|
60
|
-
// Act
|
|
61
|
-
const newToken = await service.getToken();
|
|
62
|
-
// Assert
|
|
63
|
-
expect(newToken.value).not.toEqual(token);
|
|
64
|
-
expect(newToken.value).toEqual(expected);
|
|
65
|
-
expect(AuthService_1.AuthService.prototype.refreshToken).toHaveBeenCalled();
|
|
66
|
-
});
|
|
67
|
-
it('should get a new token if there is no current token', async () => {
|
|
68
|
-
// Arrange
|
|
69
|
-
const token = getToken({ signature: false });
|
|
70
|
-
const service = new AuthService_1.AuthService({
|
|
71
|
-
url: 'http://localhost:0',
|
|
72
|
-
token,
|
|
73
|
-
});
|
|
74
|
-
service.clearToken();
|
|
75
|
-
const expected = getToken({ signature: false });
|
|
76
|
-
jest.spyOn(AuthService_1.AuthService.prototype, 'getNewUserToken').mockResolvedValue(new models_1.Token(expected));
|
|
77
|
-
// Act
|
|
78
|
-
const newToken = await service.getToken();
|
|
79
|
-
// Assert
|
|
80
|
-
expect(newToken.value).toEqual(expected);
|
|
81
|
-
expect(AuthService_1.AuthService.prototype.getNewUserToken).toHaveBeenCalled();
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('tokenRefreshLoop', () => {
|
|
85
|
-
jest.spyOn(AuthService_1.AuthService.prototype, 'refreshTokenIfExpired').mockImplementation(() => {
|
|
86
|
-
// make sure the promise is resolved synchronously
|
|
87
|
-
return {
|
|
88
|
-
catch: () => {
|
|
89
|
-
return {
|
|
90
|
-
finally(onfinally) {
|
|
91
|
-
onfinally?.();
|
|
92
|
-
return Promise.resolve();
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
beforeEach(() => {
|
|
99
|
-
jest.clearAllTimers();
|
|
100
|
-
jest.clearAllMocks();
|
|
101
|
-
jest.useFakeTimers();
|
|
102
|
-
jest.setSystemTime(baseDate);
|
|
103
|
-
});
|
|
104
|
-
it('should check the token every 10 minutes', async () => {
|
|
105
|
-
// Arrange
|
|
106
|
-
const token = getToken({ exp: almostAlmostExpiredDate });
|
|
107
|
-
const service = new AuthService_1.AuthService({
|
|
108
|
-
token,
|
|
109
|
-
url: 'http://localhost:0',
|
|
110
|
-
});
|
|
111
|
-
service.setToken(token);
|
|
112
|
-
// Act
|
|
113
|
-
service.startTokenRefreshChecker();
|
|
114
|
-
expect(AuthService_1.AuthService.prototype.refreshTokenIfExpired).toHaveBeenCalledTimes(1);
|
|
115
|
-
jest.advanceTimersByTime(1000 * 60 * 10); // 10 minutes
|
|
116
|
-
expect(AuthService_1.AuthService.prototype.refreshTokenIfExpired).toHaveBeenCalledTimes(2);
|
|
117
|
-
jest.advanceTimersByTime(1000 * 60); // 1 minutes - 24 minutes left
|
|
118
|
-
expect(AuthService_1.AuthService.prototype.refreshTokenIfExpired).toHaveBeenCalledTimes(3);
|
|
119
|
-
jest.advanceTimersByTime(1000 * 60 * 10); // 10 minutes - 14 minutes left
|
|
120
|
-
jest.runOnlyPendingTimers(); // wait for the next timer to run
|
|
121
|
-
service.stopTokenRefreshChecker();
|
|
122
|
-
});
|
|
123
|
-
it('should not run again when cancelled', () => {
|
|
124
|
-
// Arrange
|
|
125
|
-
const token = getToken({ exp: notExpiredDate });
|
|
126
|
-
const service = new AuthService_1.AuthService({
|
|
127
|
-
token,
|
|
128
|
-
url: 'http://localhost:0',
|
|
129
|
-
});
|
|
130
|
-
service.setToken(token);
|
|
131
|
-
// Act
|
|
132
|
-
service.startTokenRefreshChecker();
|
|
133
|
-
expect(AuthService_1.AuthService.prototype.refreshTokenIfExpired).toHaveBeenCalledTimes(1);
|
|
134
|
-
service.stopTokenRefreshChecker();
|
|
135
|
-
jest.runOnlyPendingTimers();
|
|
136
|
-
expect(AuthService_1.AuthService.prototype.refreshTokenIfExpired).toHaveBeenCalledTimes(1);
|
|
137
|
-
});
|
|
138
|
-
it('should correctly report running status', () => {
|
|
139
|
-
const token = getToken({ exp: notExpiredDate });
|
|
140
|
-
const service = new AuthService_1.AuthService({
|
|
141
|
-
token,
|
|
142
|
-
url: 'http://localhost:0',
|
|
143
|
-
});
|
|
144
|
-
service.setToken(token);
|
|
145
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(false);
|
|
146
|
-
service.startTokenRefreshChecker();
|
|
147
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(true);
|
|
148
|
-
service.stopTokenRefreshChecker();
|
|
149
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(false);
|
|
150
|
-
});
|
|
151
|
-
it('should correctly report running status', () => {
|
|
152
|
-
const token = getToken({ exp: notExpiredDate });
|
|
153
|
-
const service = new AuthService_1.AuthService({
|
|
154
|
-
token,
|
|
155
|
-
url: 'http://localhost:0',
|
|
156
|
-
});
|
|
157
|
-
service.setToken(token);
|
|
158
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(false);
|
|
159
|
-
service.startTokenRefreshChecker();
|
|
160
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(true);
|
|
161
|
-
service.stopTokenRefreshChecker();
|
|
162
|
-
expect(service.isTokenRefreshCheckerRunning()).toBe(false);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const models_1 = require("../models");
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
|
-
const CallerService_1 = require("./CallerService");
|
|
6
|
-
const testing_1 = require("rxjs/testing");
|
|
7
|
-
const makeCallerMessage = (responses) => ({
|
|
8
|
-
responses: {
|
|
9
|
-
responses: responses ?? [],
|
|
10
|
-
},
|
|
11
|
-
});
|
|
12
|
-
const makeCallerChunkedMessage = (responses) => {
|
|
13
|
-
return responses.map((response, index) => {
|
|
14
|
-
if ('return' in response) {
|
|
15
|
-
throw new Error('Cannot create chunked message with return');
|
|
16
|
-
}
|
|
17
|
-
const chunk = response;
|
|
18
|
-
chunk.chunkIndex = index;
|
|
19
|
-
chunk.chunkCount = responses.length;
|
|
20
|
-
chunk.header = {
|
|
21
|
-
created: '0',
|
|
22
|
-
meta: {},
|
|
23
|
-
};
|
|
24
|
-
return {
|
|
25
|
-
chunks: {
|
|
26
|
-
chunks: [chunk],
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
const uid = {
|
|
32
|
-
hash: 'hash',
|
|
33
|
-
version: models_1.UIDVersion.HEADER_HASH_RAND,
|
|
34
|
-
};
|
|
35
|
-
const ack = (id) => ({
|
|
36
|
-
uid,
|
|
37
|
-
ack: {
|
|
38
|
-
status: models_1.AckStatus.PROGRESS,
|
|
39
|
-
message: id,
|
|
40
|
-
stage: models_1.Stage.AGENT,
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
const ret = (id) => {
|
|
44
|
-
const encoder = new TextEncoder();
|
|
45
|
-
const payload = encoder.encode(JSON.stringify({ id }));
|
|
46
|
-
return {
|
|
47
|
-
uid,
|
|
48
|
-
return: {
|
|
49
|
-
payload,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
const chunkRet = (payload) => {
|
|
54
|
-
const array = new TextEncoder().encode(payload);
|
|
55
|
-
return {
|
|
56
|
-
uid,
|
|
57
|
-
payload: array,
|
|
58
|
-
chunkIndex: 0,
|
|
59
|
-
chunkCount: 1,
|
|
60
|
-
header: {
|
|
61
|
-
created: '0',
|
|
62
|
-
meta: {},
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
const res = (ok) => ({
|
|
67
|
-
uid,
|
|
68
|
-
result: {
|
|
69
|
-
status: ok ? models_1.ResultStatus.COMPLETE_SUCCESS : models_1.ResultStatus.FATAL,
|
|
70
|
-
message: ok ? 'everything is fine' : 'nothing is fine',
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
let testScheduler;
|
|
74
|
-
let service;
|
|
75
|
-
describe('CallerService', () => {
|
|
76
|
-
beforeEach(() => {
|
|
77
|
-
service = new CallerService_1.CallerService({
|
|
78
|
-
url: 'http://localhost:8080',
|
|
79
|
-
token: 'token',
|
|
80
|
-
});
|
|
81
|
-
testScheduler = new testing_1.TestScheduler((actual, expected) => {
|
|
82
|
-
expect(actual).toEqual(expected);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
describe('callRaw', () => {
|
|
86
|
-
it('should handle a successful call', () => {
|
|
87
|
-
// Arrange
|
|
88
|
-
jest.spyOn(service, 'invokeRequest').mockImplementation(() => {
|
|
89
|
-
return (0, rxjs_1.from)([
|
|
90
|
-
makeCallerMessage([ack('a')]),
|
|
91
|
-
makeCallerMessage([ack('b')]),
|
|
92
|
-
makeCallerMessage([ack('c'), ret(1)]),
|
|
93
|
-
makeCallerMessage([ret(2)]),
|
|
94
|
-
makeCallerMessage([ret(3), ret(4)]),
|
|
95
|
-
makeCallerMessage([ack('d')]),
|
|
96
|
-
makeCallerMessage([ack('e')]),
|
|
97
|
-
makeCallerMessage([ack('f')]),
|
|
98
|
-
makeCallerMessage([ack('g'), res(true)]),
|
|
99
|
-
makeCallerMessage([ack('h')]),
|
|
100
|
-
]).pipe((0, rxjs_1.concatMap)((item) => (0, rxjs_1.of)(item).pipe((0, rxjs_1.delay)(1))));
|
|
101
|
-
});
|
|
102
|
-
testScheduler.run(({ expectObservable }) => {
|
|
103
|
-
// Act
|
|
104
|
-
const call = service.call({
|
|
105
|
-
callsign: 'callsign',
|
|
106
|
-
projectId: 'project',
|
|
107
|
-
source: '/test',
|
|
108
|
-
});
|
|
109
|
-
// Assert
|
|
110
|
-
const expectedAckMarbles = '-abc--def|';
|
|
111
|
-
const expectedRetMarbles = '---ab(cd)|';
|
|
112
|
-
const expectedResMarbles = '---------(a|)';
|
|
113
|
-
const expectedAckValues = {
|
|
114
|
-
a: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'a' },
|
|
115
|
-
b: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'b' },
|
|
116
|
-
c: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'c' },
|
|
117
|
-
d: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'd' },
|
|
118
|
-
e: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'e' },
|
|
119
|
-
f: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'f' },
|
|
120
|
-
};
|
|
121
|
-
const expectedReturnValues = {
|
|
122
|
-
a: { id: 1 },
|
|
123
|
-
b: { id: 2 },
|
|
124
|
-
c: { id: 3 },
|
|
125
|
-
d: { id: 4 },
|
|
126
|
-
};
|
|
127
|
-
const expectedResultValues = {
|
|
128
|
-
a: { status: models_1.ResultStatus.COMPLETE_SUCCESS, message: 'everything is fine' },
|
|
129
|
-
};
|
|
130
|
-
expectObservable(call.ack$).toBe(expectedAckMarbles, expectedAckValues);
|
|
131
|
-
expectObservable(call.return$).toBe(expectedRetMarbles, expectedReturnValues);
|
|
132
|
-
expectObservable(call.result$).toBe(expectedResMarbles, expectedResultValues);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
it('should handle a failed call', () => {
|
|
136
|
-
// Arrange
|
|
137
|
-
jest.spyOn(service, 'invokeRequest').mockImplementation(() => {
|
|
138
|
-
return (0, rxjs_1.from)([
|
|
139
|
-
makeCallerMessage([ack('a')]),
|
|
140
|
-
makeCallerMessage([ack('b')]),
|
|
141
|
-
makeCallerMessage([ack('c'), ret(1)]),
|
|
142
|
-
makeCallerMessage([ret(2)]),
|
|
143
|
-
makeCallerMessage([ret(3), ret(4)]),
|
|
144
|
-
makeCallerMessage([ack('d')]),
|
|
145
|
-
makeCallerMessage([ack('e')]),
|
|
146
|
-
makeCallerMessage([ack('f')]),
|
|
147
|
-
makeCallerMessage([ack('g'), res(false)]),
|
|
148
|
-
makeCallerMessage([ack('h')]),
|
|
149
|
-
]).pipe((0, rxjs_1.concatMap)((item) => (0, rxjs_1.of)(item).pipe((0, rxjs_1.delay)(1))));
|
|
150
|
-
});
|
|
151
|
-
testScheduler.run(({ expectObservable }) => {
|
|
152
|
-
// Act
|
|
153
|
-
const call = service.call({
|
|
154
|
-
callsign: 'callsign',
|
|
155
|
-
projectId: 'project',
|
|
156
|
-
source: '/test',
|
|
157
|
-
});
|
|
158
|
-
// Assert
|
|
159
|
-
const expectedAckMarbles = '-abc--def#';
|
|
160
|
-
const expectedRetMarbles = '---ab(cd)#';
|
|
161
|
-
const expectedResMarbles = '---------(a|)';
|
|
162
|
-
const expectedAckValues = {
|
|
163
|
-
a: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'a' },
|
|
164
|
-
b: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'b' },
|
|
165
|
-
c: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'c' },
|
|
166
|
-
d: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'd' },
|
|
167
|
-
e: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'e' },
|
|
168
|
-
f: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'f' },
|
|
169
|
-
};
|
|
170
|
-
const expectedReturnValues = {
|
|
171
|
-
a: { id: 1 },
|
|
172
|
-
b: { id: 2 },
|
|
173
|
-
c: { id: 3 },
|
|
174
|
-
d: { id: 4 },
|
|
175
|
-
};
|
|
176
|
-
const expectedResultValues = {
|
|
177
|
-
a: { status: models_1.ResultStatus.FATAL, message: 'nothing is fine' },
|
|
178
|
-
};
|
|
179
|
-
expectObservable(call.ack$).toBe(expectedAckMarbles, expectedAckValues, res(false).result);
|
|
180
|
-
expectObservable(call.return$).toBe(expectedRetMarbles, expectedReturnValues, res(false).result);
|
|
181
|
-
expectObservable(call.result$).toBe(expectedResMarbles, expectedResultValues);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
it('should handle a successful chunked call', () => {
|
|
185
|
-
// Arrange
|
|
186
|
-
jest.spyOn(service, 'invokeRequest').mockImplementation(() => {
|
|
187
|
-
return (0, rxjs_1.from)([
|
|
188
|
-
...makeCallerChunkedMessage([
|
|
189
|
-
chunkRet('[{"'),
|
|
190
|
-
chunkRet('id":1},'),
|
|
191
|
-
ack('a'),
|
|
192
|
-
chunkRet('{"id":2}'),
|
|
193
|
-
ack('b'),
|
|
194
|
-
chunkRet(']'),
|
|
195
|
-
]),
|
|
196
|
-
makeCallerMessage([ack('c'), ret(3)]),
|
|
197
|
-
makeCallerMessage([res(true)]),
|
|
198
|
-
]).pipe((0, rxjs_1.concatMap)((item) => (0, rxjs_1.of)(item).pipe((0, rxjs_1.delay)(1))));
|
|
199
|
-
});
|
|
200
|
-
testScheduler.run(({ expectObservable }) => {
|
|
201
|
-
// Act
|
|
202
|
-
const call = service.call({
|
|
203
|
-
callsign: 'callsign',
|
|
204
|
-
projectId: 'project',
|
|
205
|
-
source: '/test',
|
|
206
|
-
});
|
|
207
|
-
// Assert
|
|
208
|
-
const expectedAckMarbles = '---a-b-c|';
|
|
209
|
-
const expectedRetMarbles = '------ab|';
|
|
210
|
-
const expectedResMarbles = '--------(a|)';
|
|
211
|
-
const expectedAckValues = {
|
|
212
|
-
a: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'a' },
|
|
213
|
-
b: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'b' },
|
|
214
|
-
c: { stage: models_1.Stage.AGENT, status: models_1.AckStatus.PROGRESS, message: 'c' },
|
|
215
|
-
};
|
|
216
|
-
const expectedReturnValues = {
|
|
217
|
-
a: [{ id: 1 }, { id: 2 }],
|
|
218
|
-
b: { id: 3 },
|
|
219
|
-
};
|
|
220
|
-
const expectedResultValues = {
|
|
221
|
-
a: { status: models_1.ResultStatus.COMPLETE_SUCCESS, message: 'everything is fine' },
|
|
222
|
-
};
|
|
223
|
-
expectObservable(call.ack$).toBe(expectedAckMarbles, expectedAckValues);
|
|
224
|
-
expectObservable(call.return$).toBe(expectedRetMarbles, expectedReturnValues);
|
|
225
|
-
expectObservable(call.result$).toBe(expectedResMarbles, expectedResultValues);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|