@shopgate/pwa-core 7.30.0-alpha.7 → 7.30.0-alpha.9
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/classes/AppCommand/index.js +115 -11
- package/classes/AppCommand/spec.js +260 -6
- package/classes/AppCommandRequest/index.js +129 -20
- package/classes/AppPermissionsRequest/AppPermissionsRequest.js +45 -7
- package/classes/AppPermissionsRequest/GetAppPermissionsRequest.js +48 -9
- package/classes/AppPermissionsRequest/RequestAppPermissionsRequest.js +54 -9
- package/classes/Bridge/index.js +34 -4
- package/classes/Bridge/spec.js +24 -1
- package/classes/BrightnessRequest/index.js +59 -10
- package/classes/BrightnessRequest/spec.js +111 -6
- package/classes/BrowserConnector/index.js +180 -26
- package/classes/Conditioner/index.js +74 -8
- package/classes/Conditioner/spec.js +75 -1
- package/classes/DataRequest/index.js +116 -13
- package/classes/DevServerBridge/index.js +85 -9
- package/classes/DevServerBridge/spec.js +230 -14
- package/classes/ErrorManager/index.js +144 -20
- package/classes/ErrorManager/spec.js +244 -2
- package/classes/Event/index.js +101 -15
- package/classes/HttpRequest/index.js +182 -21
- package/classes/PipelineDependencies/index.js +42 -6
- package/classes/PipelineDependencies/spec.js +46 -3
- package/classes/PipelineManager/index.js +517 -71
- package/classes/PipelineManager/spec.js +733 -15
- package/classes/PipelineRequest/index.js +167 -19
- package/classes/PipelineRequest/mock.js +118 -21
- package/classes/PipelineRequest/spec.js +333 -2
- package/classes/PipelineSequence/index.js +34 -6
- package/classes/Request/index.js +61 -13
- package/classes/RequestBuffer/index.js +43 -6
- package/classes/RequestManager/index.js +216 -33
- package/classes/RequestManager/spec.js +188 -1
- package/classes/Scanner/index.js +246 -67
- package/classes/ScannerEvent/index.js +23 -9
- package/classes/ScannerEventHandler/index.js +39 -16
- package/classes/ScannerEventListener/index.js +84 -24
- package/classes/ScannerManager/ScanProcessingError.js +11 -3
- package/classes/ScannerManager/index.js +133 -21
- package/classes/WebStorageRequest/index.js +76 -9
- package/commands/analyticsSetCustomValues.js +8 -2
- package/commands/appPermissions.js +10 -3
- package/commands/brightness.js +33 -5
- package/commands/broadcastEvent.js +8 -2
- package/commands/cleanTab.js +11 -3
- package/commands/closeInAppBrowser.js +22 -2
- package/commands/flushTab.js +8 -2
- package/commands/getWebStorageEntry.js +11 -2
- package/commands/hideMenuBar.js +8 -2
- package/commands/hideNavigationBar.js +8 -2
- package/commands/hideSplashScreen.js +8 -2
- package/commands/onload.js +13 -3
- package/commands/openAppSettings.js +8 -2
- package/commands/openPage.js +8 -2
- package/commands/openPageExtern.js +8 -2
- package/commands/performCommandsAfterDelay.js +11 -3
- package/commands/plotProjects.js +65 -7
- package/commands/popTabToRoot.js +11 -3
- package/commands/registerEvents.js +10 -2
- package/commands/scanner.js +76 -7
- package/commands/setCookie.js +8 -2
- package/commands/setDebugLoggingEnabled.js +8 -2
- package/commands/setScrollingEnabled.js +7 -2
- package/commands/setWebStorageEntry.js +8 -2
- package/commands/shareItem.js +18 -2
- package/commands/showNavigationBar.js +8 -2
- package/commands/showTab.js +13 -2
- package/commands/unifiedTracking.js +128 -30
- package/constants/AppCommands.js +6 -1
- package/constants/AppEvents.js +9 -1
- package/constants/AppPermissions.js +57 -13
- package/constants/Command.js +1 -1
- package/constants/ErrorHandleTypes.js +2 -1
- package/constants/ErrorManager.js +15 -1
- package/constants/Pipeline.js +52 -17
- package/constants/ProcessTypes.js +3 -1
- package/constants/RequestManagerModes.js +19 -7
- package/constants/RequestTypes.js +2 -1
- package/constants/Scanner.js +39 -10
- package/constants/Trilean.js +6 -1
- package/emitters/ui.js +2 -1
- package/helpers/index.js +66 -8
- package/helpers/logGroup.js +56 -8
- package/helpers/version.js +216 -22
- package/index.js +60 -5
- package/package.json +1 -2
|
@@ -1,33 +1,137 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { logger, hasSGJavaScriptBridge } from "../../helpers";
|
|
2
|
+
import { isValidVersion, getLibVersion, isVersionAtLeast } from "../../helpers/version";
|
|
3
|
+
import logGroup from "../../helpers/logGroup";
|
|
4
|
+
import * as appCommands from "../../constants/AppCommands";
|
|
5
|
+
import Bridge from "../Bridge";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* The app command class.
|
|
3
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
class AppCommand {
|
|
11
|
+
/**
|
|
4
12
|
* @param {boolean} log Whether the command will be logged.
|
|
5
13
|
* @param {boolean} checkLibVersion Whether the lib version will be checked before dispatch.
|
|
6
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
constructor(log = true, checkLibVersion = hasSGJavaScriptBridge()) {
|
|
16
|
+
this.log = log;
|
|
17
|
+
this.checkLibVersion = checkLibVersion;
|
|
18
|
+
this.name = '';
|
|
19
|
+
this.params = null;
|
|
20
|
+
this.libVersion = '9.0';
|
|
21
|
+
this.commandsWithoutLog = [appCommands.COMMAND_SEND_PIPELINE_REQUEST, appCommands.COMMAND_SEND_HTTP_REQUEST, appCommands.COMMAND_GET_WEBSTORAGE_ENTRY];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
7
25
|
* Sets the command name.
|
|
8
26
|
* @param {string} name The command name.
|
|
9
27
|
* @return {AppCommand}
|
|
10
|
-
*/
|
|
28
|
+
*/
|
|
29
|
+
setCommandName(name) {
|
|
30
|
+
if (typeof name === 'string') {
|
|
31
|
+
this.name = name;
|
|
32
|
+
} else {
|
|
33
|
+
logger.error('Invalid command name', name);
|
|
34
|
+
}
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
11
39
|
* Sets the command params.
|
|
12
40
|
* @param {Object} [params=null] The command params.
|
|
13
41
|
* @return {AppCommand}
|
|
14
|
-
*/
|
|
42
|
+
*/
|
|
43
|
+
setCommandParams(params) {
|
|
44
|
+
if (params && typeof params === 'object' && params.constructor === Object) {
|
|
45
|
+
this.params = params;
|
|
46
|
+
} else {
|
|
47
|
+
logger.error('Invalid command params', params);
|
|
48
|
+
}
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
15
53
|
* Sets the minimum required shopgate lib version for the command.
|
|
16
54
|
* @param {string} libVersion The library version.
|
|
17
55
|
* @return {AppCommand}
|
|
18
|
-
*/
|
|
56
|
+
*/
|
|
57
|
+
setLibVersion(libVersion) {
|
|
58
|
+
if (isValidVersion(libVersion)) {
|
|
59
|
+
this.libVersion = libVersion;
|
|
60
|
+
} else {
|
|
61
|
+
logger.error('Invalid lib version', libVersion);
|
|
62
|
+
}
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
19
67
|
* Logs the command to the console.
|
|
20
68
|
* @private
|
|
21
69
|
* @return {AppCommand}
|
|
22
|
-
*/
|
|
70
|
+
*/
|
|
71
|
+
logCommand() {
|
|
72
|
+
if (this.log && !this.commandsWithoutLog.includes(this.name)) {
|
|
73
|
+
const title = `AppCommand %c${this.name}`;
|
|
74
|
+
logGroup(title, this.params || {}, '#8e44ad');
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
23
80
|
* Creates the command object which will be dispatched through the JavaScript bridge.
|
|
24
81
|
* @return {Object|null}
|
|
25
|
-
*/
|
|
82
|
+
*/
|
|
83
|
+
buildCommand() {
|
|
84
|
+
const command = this.name ? {
|
|
85
|
+
c: this.name,
|
|
86
|
+
...(this.params && {
|
|
87
|
+
p: this.params
|
|
88
|
+
})
|
|
89
|
+
} : null;
|
|
90
|
+
return command;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
26
94
|
* Dispatches the command to the app.
|
|
27
95
|
* The returned promise will not be rejected for now in error cases to avoid the necessity
|
|
28
96
|
* of refactoring within existing code. But it resolves with FALSE in those cases.
|
|
29
97
|
* @param {Object} [params] The command params.
|
|
30
98
|
* @return {Promise<boolean>}
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
if
|
|
99
|
+
*/
|
|
100
|
+
async dispatch(params) {
|
|
101
|
+
if (params) {
|
|
102
|
+
this.setCommandParams(params);
|
|
103
|
+
}
|
|
104
|
+
const command = this.buildCommand();
|
|
105
|
+
|
|
106
|
+
// Only proceed if the command is valid.
|
|
107
|
+
if (command === null) {
|
|
108
|
+
logger.error(`Dispatch aborted for invalid command. name: "${this.name}" | params:`, this.params);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
let appLibVersion = this.libVersion;
|
|
112
|
+
let appHasSupport = true;
|
|
113
|
+
|
|
114
|
+
// Perform a libVersion check if the flag is active.
|
|
115
|
+
if (this.checkLibVersion) {
|
|
116
|
+
// Gather the libVersion of the app and check if it supports the command.
|
|
117
|
+
appLibVersion = await getLibVersion();
|
|
118
|
+
appHasSupport = isVersionAtLeast(this.libVersion, appLibVersion);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Only proceed if the command is supported by the app.
|
|
122
|
+
if (!appHasSupport) {
|
|
123
|
+
logger.warn(`The command "${this.name}" is not supported by LibVersion (required ${this.libVersion} | current ${appLibVersion})`);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const bridge = new Bridge();
|
|
127
|
+
try {
|
|
128
|
+
bridge.dispatchCommand(command, appLibVersion);
|
|
129
|
+
this.logCommand();
|
|
130
|
+
} catch (exception) {
|
|
131
|
+
logger.error(exception);
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export default AppCommand;
|
|
@@ -1,8 +1,262 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { hasSGJavaScriptBridge } from "../../helpers";
|
|
2
|
+
import { defaultClientInformation } from "../../helpers/version";
|
|
3
|
+
import AppCommand from "./index";
|
|
4
|
+
jest.unmock("./index.js");
|
|
5
|
+
|
|
6
|
+
// Mocks for the logger.
|
|
7
|
+
const mockedLoggerError = jest.fn();
|
|
8
|
+
const mockedLoggerWarn = jest.fn();
|
|
9
|
+
jest.mock("../../helpers", () => ({
|
|
10
|
+
logger: {
|
|
11
|
+
error: (...args) => {
|
|
12
|
+
mockedLoggerError(...args);
|
|
13
|
+
},
|
|
14
|
+
warn: (...args) => {
|
|
15
|
+
mockedLoggerWarn(...args);
|
|
16
|
+
},
|
|
17
|
+
log: () => {}
|
|
18
|
+
},
|
|
19
|
+
hasSGJavaScriptBridge: jest.fn().mockReturnValue(false),
|
|
20
|
+
useBrowserConnector: () => false
|
|
21
|
+
}));
|
|
22
|
+
const mockedLogGroup = jest.fn();
|
|
23
|
+
// eslint-disable-next-line extra-rules/potential-point-free
|
|
24
|
+
jest.mock("../../helpers/logGroup", () => function logGroup(...args) {
|
|
25
|
+
mockedLogGroup(...args);
|
|
26
|
+
});
|
|
27
|
+
let mockedBridgeDispatch = jest.fn();
|
|
28
|
+
|
|
29
|
+
/* eslint-disable require-jsdoc, class-methods-use-this */
|
|
30
|
+
jest.mock("../DevServerBridge", () => {
|
|
31
|
+
class DevServerBridge {
|
|
32
|
+
dispatchCommandsForVersion(...args) {
|
|
33
|
+
return mockedBridgeDispatch(...args);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
__esModule: true,
|
|
38
|
+
default: DevServerBridge
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
/* eslint-enable require-jsdoc, class-methods-use-this */
|
|
42
|
+
|
|
43
|
+
// Mock of the client information web storage.
|
|
44
|
+
let mockedClientInformation = null;
|
|
45
|
+
jest.mock("../../commands/getWebStorageEntry", () => jest.fn().mockImplementation(() => ({
|
|
46
|
+
then(cb) {
|
|
47
|
+
cb({
|
|
48
|
+
value: mockedClientInformation
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
})));
|
|
52
|
+
const defaultLibVersion = defaultClientInformation.libVersion;
|
|
53
|
+
|
|
54
|
+
/**
|
|
6
55
|
* Updates the mocked client information.
|
|
7
56
|
* @param {string} libVersion The libVersion.
|
|
8
|
-
*/
|
|
57
|
+
*/
|
|
58
|
+
const setClientInformation = (libVersion = defaultLibVersion) => {
|
|
59
|
+
mockedClientInformation = {
|
|
60
|
+
libVersion
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
describe('AppCommand', () => {
|
|
64
|
+
let instance;
|
|
65
|
+
beforeEach(() => {
|
|
66
|
+
setClientInformation();
|
|
67
|
+
mockedLoggerError.mockClear();
|
|
68
|
+
mockedLoggerWarn.mockClear();
|
|
69
|
+
mockedLogGroup.mockClear();
|
|
70
|
+
mockedBridgeDispatch.mockClear();
|
|
71
|
+
instance = new AppCommand(true, true);
|
|
72
|
+
});
|
|
73
|
+
describe('.constructor()', () => {
|
|
74
|
+
it('should construct as expected without parameters', () => {
|
|
75
|
+
instance = new AppCommand();
|
|
76
|
+
expect(instance.log).toBe(true);
|
|
77
|
+
expect(instance.checkLibVersion).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
it('should construct as expected when the SGJavaScriptBridge was detected', () => {
|
|
80
|
+
hasSGJavaScriptBridge.mockReturnValueOnce(true);
|
|
81
|
+
instance = new AppCommand();
|
|
82
|
+
expect(instance.log).toBe(true);
|
|
83
|
+
expect(instance.checkLibVersion).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('should construct as expected when log parameter is false', () => {
|
|
86
|
+
instance = new AppCommand(false, true);
|
|
87
|
+
expect(instance.log).toBe(false);
|
|
88
|
+
expect(instance.checkLibVersion).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('.setCommandName()', () => {
|
|
92
|
+
it('should set a valid value', () => {
|
|
93
|
+
const value = 'sendPipelineRequest';
|
|
94
|
+
const command = instance.setCommandName(value);
|
|
95
|
+
expect(command).toEqual(instance);
|
|
96
|
+
expect(command.name).toEqual(value);
|
|
97
|
+
});
|
|
98
|
+
it('should not set an invalid value', () => {
|
|
99
|
+
const initial = instance.name;
|
|
100
|
+
const command = instance.setCommandName(17.3);
|
|
101
|
+
expect(command).toEqual(instance);
|
|
102
|
+
expect(command.name).toEqual(initial);
|
|
103
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(1);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('.setCommandParams()', () => {
|
|
107
|
+
it('should set a valid value', () => {
|
|
108
|
+
const value = {
|
|
109
|
+
paramOne: 'foo',
|
|
110
|
+
paramTwo: 1337
|
|
111
|
+
};
|
|
112
|
+
const command = instance.setCommandParams(value);
|
|
113
|
+
expect(command).toEqual(instance);
|
|
114
|
+
expect(command.params).toEqual(value);
|
|
115
|
+
});
|
|
116
|
+
it('should not set an invalid value', () => {
|
|
117
|
+
const initial = instance.params;
|
|
118
|
+
const command = instance.setCommandParams('sendPipelineRequest');
|
|
119
|
+
expect(command).toEqual(instance);
|
|
120
|
+
expect(command.params).toEqual(initial);
|
|
121
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(1);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe('.setLibVersion()', () => {
|
|
125
|
+
it('should set a valid value', () => {
|
|
126
|
+
const value = '17.2';
|
|
127
|
+
const command = instance.setLibVersion(value);
|
|
128
|
+
expect(command).toEqual(instance);
|
|
129
|
+
expect(command.libVersion).toEqual(value);
|
|
130
|
+
});
|
|
131
|
+
it('should not set an invalid value', () => {
|
|
132
|
+
const initial = instance.libVersion;
|
|
133
|
+
const command = instance.setLibVersion('sendPipelineRequest');
|
|
134
|
+
expect(command).toEqual(instance);
|
|
135
|
+
expect(command.libVersion).toEqual(initial);
|
|
136
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(1);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('.logCommand', () => {
|
|
140
|
+
it('should log a command', () => {
|
|
141
|
+
instance.setCommandName('openPage');
|
|
142
|
+
const command = instance.logCommand();
|
|
143
|
+
expect(command).toEqual(instance);
|
|
144
|
+
expect(mockedLogGroup).toHaveBeenCalledTimes(1);
|
|
145
|
+
});
|
|
146
|
+
it('should not log a command when logging is turned off', () => {
|
|
147
|
+
instance = new AppCommand(false);
|
|
148
|
+
instance.setCommandName('openPage');
|
|
149
|
+
const command = instance.logCommand();
|
|
150
|
+
expect(command).toEqual(instance);
|
|
151
|
+
expect(mockedLogGroup).toHaveBeenCalledTimes(0);
|
|
152
|
+
});
|
|
153
|
+
it('should not log a command when it is blacklisted', () => {
|
|
154
|
+
instance.setCommandName('sendPipelineRequest');
|
|
155
|
+
const command = instance.logCommand();
|
|
156
|
+
expect(command).toEqual(instance);
|
|
157
|
+
expect(mockedLogGroup).toHaveBeenCalledTimes(0);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe('.buildCommand()', () => {
|
|
161
|
+
it('should build a command when name and params are set', () => {
|
|
162
|
+
const name = 'sendPipelineRequest';
|
|
163
|
+
const params = {
|
|
164
|
+
paramOne: 'foo',
|
|
165
|
+
paramTwo: 1337
|
|
166
|
+
};
|
|
167
|
+
const expected = {
|
|
168
|
+
c: name,
|
|
169
|
+
p: params
|
|
170
|
+
};
|
|
171
|
+
instance.setCommandName(name);
|
|
172
|
+
instance.setCommandParams(params);
|
|
173
|
+
const result = instance.buildCommand();
|
|
174
|
+
expect(result).toEqual(expected);
|
|
175
|
+
});
|
|
176
|
+
it('should build a command when only the name is set', () => {
|
|
177
|
+
const name = 'sendPipelineRequest';
|
|
178
|
+
const expected = {
|
|
179
|
+
c: name
|
|
180
|
+
};
|
|
181
|
+
instance.setCommandName(name);
|
|
182
|
+
const result = instance.buildCommand();
|
|
183
|
+
expect(result).toEqual(expected);
|
|
184
|
+
});
|
|
185
|
+
it('should not build a command when no name is set', () => {
|
|
186
|
+
const params = {
|
|
187
|
+
paramOne: 'foo',
|
|
188
|
+
paramTwo: 1337
|
|
189
|
+
};
|
|
190
|
+
instance.setCommandParams(params);
|
|
191
|
+
const result = instance.buildCommand();
|
|
192
|
+
expect(result).toEqual(null);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
describe('.dispatch()', () => {
|
|
196
|
+
it('should dispatch as expected', async () => {
|
|
197
|
+
const name = 'sendPipelineRequest';
|
|
198
|
+
instance.setCommandName(name);
|
|
199
|
+
const result = await instance.dispatch();
|
|
200
|
+
expect(result).toBe(true);
|
|
201
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(1);
|
|
202
|
+
expect(mockedBridgeDispatch.mock.calls[0][0][0].c).toBe(name);
|
|
203
|
+
expect(mockedBridgeDispatch.mock.calls[0][1]).toBe(defaultLibVersion);
|
|
204
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(0);
|
|
205
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(0);
|
|
206
|
+
});
|
|
207
|
+
it('should set the params if passed to dispatch', async () => {
|
|
208
|
+
const params = {
|
|
209
|
+
paramOne: 'foo',
|
|
210
|
+
paramTwo: 1337
|
|
211
|
+
};
|
|
212
|
+
instance.setCommandName('sendPipelineRequest');
|
|
213
|
+
const result = await instance.dispatch(params);
|
|
214
|
+
expect(result).toBe(true);
|
|
215
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(1);
|
|
216
|
+
expect(mockedBridgeDispatch.mock.calls[0][0][0].p).toEqual(params);
|
|
217
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(0);
|
|
218
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(0);
|
|
219
|
+
});
|
|
220
|
+
it('should not dispatch when no command was set up', async () => {
|
|
221
|
+
const result = await instance.dispatch();
|
|
222
|
+
expect(result).toBe(false);
|
|
223
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(0);
|
|
224
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(1);
|
|
225
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(0);
|
|
226
|
+
});
|
|
227
|
+
it('should not dispatch when the command is not supported by the app', async () => {
|
|
228
|
+
const libVersion = (Number.parseFloat(defaultLibVersion) + 1).toFixed(1);
|
|
229
|
+
instance.setCommandName('sendPipelineRequest');
|
|
230
|
+
instance.setLibVersion(libVersion);
|
|
231
|
+
const result = await instance.dispatch();
|
|
232
|
+
expect(result).toBe(false);
|
|
233
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(0);
|
|
234
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(0);
|
|
235
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(1);
|
|
236
|
+
});
|
|
237
|
+
it('should dispatch when the command is not supported by the app but the check is off', async () => {
|
|
238
|
+
const libVersion = (Number.parseFloat(defaultLibVersion) + 1).toFixed(1);
|
|
239
|
+
instance = new AppCommand(true, false);
|
|
240
|
+
instance.setCommandName('sendPipelineRequest');
|
|
241
|
+
instance.setLibVersion(libVersion);
|
|
242
|
+
const result = await instance.dispatch();
|
|
243
|
+
expect(result).toBe(true);
|
|
244
|
+
expect(mockedBridgeDispatch.mock.calls[0][1]).toBe(libVersion);
|
|
245
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(1);
|
|
246
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(0);
|
|
247
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(0);
|
|
248
|
+
});
|
|
249
|
+
it('should handle errors during bridge dispatch', async () => {
|
|
250
|
+
mockedBridgeDispatch = jest.fn().mockImplementation(() => {
|
|
251
|
+
throw new Error();
|
|
252
|
+
});
|
|
253
|
+
const name = 'sendPipelineRequest';
|
|
254
|
+
instance.setCommandName(name);
|
|
255
|
+
const result = await instance.dispatch();
|
|
256
|
+
expect(result).toBe(false);
|
|
257
|
+
expect(mockedBridgeDispatch).toHaveBeenCalledTimes(1);
|
|
258
|
+
expect(mockedLoggerError).toHaveBeenCalledTimes(1);
|
|
259
|
+
expect(mockedLoggerWarn).toHaveBeenCalledTimes(0);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
@@ -1,47 +1,105 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable class-methods-use-this */
|
|
2
|
+
import Request from "../Request";
|
|
3
|
+
import AppCommand from "../AppCommand";
|
|
4
|
+
import event from "../Event";
|
|
5
|
+
import requestBuffer from "../RequestBuffer";
|
|
6
|
+
import { logger } from "../../helpers";
|
|
7
|
+
import logGroup from "../../helpers/logGroup";
|
|
8
|
+
const DEFAULT_LIB_VERSION = '25.0';
|
|
9
|
+
|
|
10
|
+
/**
|
|
2
11
|
* The AppCommandRequest class is the base class to implement request like app commands that have a
|
|
3
12
|
* corresponding app event that delivers response data.
|
|
4
13
|
* It contains the logic which in necessary to establish the process of sending an
|
|
5
14
|
* app command and receiving an associated event.
|
|
6
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
class AppCommandRequest extends Request {
|
|
17
|
+
/**
|
|
7
18
|
* The constructor.
|
|
8
19
|
* @param {string} commandName The name of the command which is dispatched to the app.
|
|
9
20
|
* @param {string} eventName The event name which is called by the app to deliver the data.
|
|
10
|
-
*/
|
|
21
|
+
*/
|
|
22
|
+
constructor(commandName, eventName) {
|
|
23
|
+
super();
|
|
24
|
+
this.commandName = commandName;
|
|
25
|
+
this.eventName = eventName || `${commandName}Response`;
|
|
26
|
+
this.commandParams = null;
|
|
27
|
+
this.libVersion = DEFAULT_LIB_VERSION;
|
|
28
|
+
this.logColor = '#9a9800';
|
|
29
|
+
event.registerEvent(this.eventName);
|
|
30
|
+
this.createSerial(this.commandName);
|
|
31
|
+
this.createEventCallbackName(this.eventName);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
11
35
|
* Sets the parameters for the app command.
|
|
12
36
|
* @param {Object} [commandParams=null] The parameters.
|
|
13
37
|
* @return {AppCommandRequest}
|
|
14
|
-
*/
|
|
38
|
+
*/
|
|
39
|
+
setCommandParams(commandParams = null) {
|
|
40
|
+
this.commandParams = commandParams;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
15
45
|
* Sets the minimum lib version for the app command.
|
|
16
46
|
* @param {string} [libVersion="25.0"] The lib version.
|
|
17
47
|
* @return {AppCommandRequest}
|
|
18
|
-
*/
|
|
48
|
+
*/
|
|
49
|
+
setLibVersion(libVersion = DEFAULT_LIB_VERSION) {
|
|
50
|
+
this.libVersion = libVersion;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
19
55
|
* Cleans up the instance after a successful or failed request.
|
|
20
56
|
* @private
|
|
21
57
|
* @param {Function} requestCallback The event callback that processes the response.
|
|
22
58
|
* @return {AppCommandRequest}
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
|
|
59
|
+
*/
|
|
60
|
+
cleanUpRequest(requestCallback) {
|
|
61
|
+
// Remove the event listener entry.
|
|
62
|
+
event.removeCallback(this.getEventCallbackName(), requestCallback);
|
|
63
|
+
// Remove the request from the buffer.
|
|
64
|
+
requestBuffer.remove(this.serial);
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
26
69
|
* Validates the command params before dispatch.
|
|
27
70
|
*
|
|
28
71
|
* This method is supposed to be overwritten by an inheriting class. It's invoked with the
|
|
29
72
|
* currently configured command params object.
|
|
30
73
|
* @param {Object} commandParams The params of the command to be dispatched
|
|
31
74
|
* @return {boolean}
|
|
32
|
-
*/
|
|
75
|
+
*/
|
|
76
|
+
validateCommandParams() {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
33
81
|
* Creates a title for the app command request log.
|
|
34
82
|
*
|
|
35
83
|
* This method is supposed to be overwritten by an inheriting class to enable customization of
|
|
36
84
|
* log output.
|
|
37
85
|
* @returns {string}
|
|
38
|
-
*/
|
|
86
|
+
*/
|
|
87
|
+
getRequestLogTitle() {
|
|
88
|
+
return `AppCommandRequest %c${this.commandName}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
39
92
|
* Creates a title for the app command response log.
|
|
40
93
|
*
|
|
41
94
|
* This method is supposed to be overwritten by an inheriting class to enable customization of
|
|
42
95
|
* log output.
|
|
43
96
|
* @returns {string}
|
|
44
|
-
*/
|
|
97
|
+
*/
|
|
98
|
+
getResponseLogTitle() {
|
|
99
|
+
return `AppCommandResponse %c${this.commandName}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
45
103
|
* Creates payload for the app command response log.
|
|
46
104
|
*
|
|
47
105
|
* This default handler expects the command serial as first and the request response as
|
|
@@ -50,7 +108,12 @@ requestBuffer.remove(this.serial);return this;}/**
|
|
|
50
108
|
* @param {string} serial The serial that was used to identify the response callback.
|
|
51
109
|
* @param {Object} response The response object for the request
|
|
52
110
|
* @returns {Object}
|
|
53
|
-
*/
|
|
111
|
+
*/
|
|
112
|
+
getResponseLogPayload(serial, response) {
|
|
113
|
+
return response;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
54
117
|
* App command response handler. Can be used to implement custom logic for handling the incoming
|
|
55
118
|
* data.
|
|
56
119
|
*
|
|
@@ -63,16 +126,62 @@ requestBuffer.remove(this.serial);return this;}/**
|
|
|
63
126
|
* of the AppCommandRequest instance.
|
|
64
127
|
* @param {string} serial The serial that was used to identify the response callback.
|
|
65
128
|
* @param {Object} response The response object for the request
|
|
66
|
-
*/
|
|
129
|
+
*/
|
|
130
|
+
onResponse(resolve, reject, serial, response) {
|
|
131
|
+
resolve(response);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
67
135
|
* Dispatches the app request command.
|
|
68
136
|
* @private
|
|
69
137
|
* @param {Function} resolve The resolve() callback of the dispatch promise.
|
|
70
138
|
* @param {Function} reject The reject() callback of the dispatch promise.
|
|
71
|
-
*/
|
|
72
|
-
|
|
139
|
+
*/
|
|
140
|
+
async onDispatch(resolve, reject) {
|
|
141
|
+
// Validate the command parameters.
|
|
142
|
+
if (this.validateCommandParams(this.commandParams) === false) {
|
|
143
|
+
// In case of an error log a message and reject the request promise.
|
|
144
|
+
const message = `${this.commandName} - invalid command parameters passed`;
|
|
145
|
+
logger.error(message, this.commandParams);
|
|
146
|
+
reject(new Error(message));
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
73
151
|
* The event callback for the command response.
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
152
|
+
*/
|
|
153
|
+
const requestCallback = (...params) => {
|
|
154
|
+
logGroup(this.getResponseLogTitle(), this.getResponseLogPayload(...params) || {}, this.logColor);
|
|
155
|
+
this.cleanUpRequest(requestCallback);
|
|
156
|
+
this.onResponse(resolve, reject, ...params);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Add the request to the buffer.
|
|
160
|
+
requestBuffer.add(this, this.serial);
|
|
161
|
+
// Add the event callback for the response.
|
|
162
|
+
event.addCallback(this.getEventCallbackName(), requestCallback);
|
|
163
|
+
|
|
164
|
+
// Prepare the command.
|
|
165
|
+
const command = new AppCommand().setCommandName(this.commandName).setLibVersion(this.libVersion).setCommandParams({
|
|
166
|
+
serial: this.serial,
|
|
167
|
+
...(this.commandParams && {
|
|
168
|
+
...this.commandParams
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Try to dispatch the command.
|
|
173
|
+
const success = await command.dispatch();
|
|
174
|
+
|
|
175
|
+
// If the dispatch of the command failed revert everything and reject the promise.
|
|
176
|
+
if (success === false) {
|
|
177
|
+
this.cleanUpRequest(requestCallback);
|
|
178
|
+
reject(new Error(`${this.commandName} command dispatch failed`));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
logGroup(this.getRequestLogTitle(), this.commandParams || {}, this.logColor);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* eslint-enable class-methods-use-this */
|
|
186
|
+
|
|
187
|
+
export default AppCommandRequest;
|