@webex/internal-plugin-feature 2.59.2 → 2.59.3-next.1
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/.eslintrc.js +6 -6
- package/README.md +42 -42
- package/babel.config.js +3 -3
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/feature.js +27 -27
- package/dist/feature.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +15 -14
- package/process +1 -1
- package/src/config.js +7 -7
- package/src/feature.js +145 -145
- package/src/index.js +15 -15
- package/test/integration/spec/feature.js +145 -145
- package/test/unit/spec/feature.js +145 -145
package/.eslintrc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
root: true,
|
|
3
|
-
extends: ['@webex/eslint-config-legacy'],
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
module.exports = config;
|
|
1
|
+
const config = {
|
|
2
|
+
root: true,
|
|
3
|
+
extends: ['@webex/eslint-config-legacy'],
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
module.exports = config;
|
package/README.md
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
# @webex/internal-plugin-feature
|
|
2
|
-
|
|
3
|
-
[](https://github.com/RichardLitt/standard-readme)
|
|
4
|
-
|
|
5
|
-
> Plugin for the Feature service
|
|
6
|
-
|
|
7
|
-
This is an internal Cisco Webex plugin. As such, it does not strictly adhere to semantic versioning. Use at your own risk. If you're not working on one of our first party clients, please look at our [developer api](https://developer.webex.com/) and stick to our public plugins.
|
|
8
|
-
|
|
9
|
-
- [Install](#install)
|
|
10
|
-
- [Usage](#usage)
|
|
11
|
-
- [Contribute](#contribute)
|
|
12
|
-
- [Maintainers](#maintainers)
|
|
13
|
-
- [License](#license)
|
|
14
|
-
|
|
15
|
-
## Install
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install --save @webex/internal-plugin-feature
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Usage
|
|
22
|
-
|
|
23
|
-
```js
|
|
24
|
-
import '@webex/internal-plugin-feature';
|
|
25
|
-
|
|
26
|
-
import WebexCore from '@webex/webex-core';
|
|
27
|
-
|
|
28
|
-
const webex = new WebexCore();
|
|
29
|
-
webex.internal.feature.WHATEVER;
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Maintainers
|
|
33
|
-
|
|
34
|
-
This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
|
|
35
|
-
|
|
36
|
-
## Contribute
|
|
37
|
-
|
|
38
|
-
Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
|
|
39
|
-
|
|
40
|
-
## License
|
|
41
|
-
|
|
42
|
-
© 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
|
|
1
|
+
# @webex/internal-plugin-feature
|
|
2
|
+
|
|
3
|
+
[](https://github.com/RichardLitt/standard-readme)
|
|
4
|
+
|
|
5
|
+
> Plugin for the Feature service
|
|
6
|
+
|
|
7
|
+
This is an internal Cisco Webex plugin. As such, it does not strictly adhere to semantic versioning. Use at your own risk. If you're not working on one of our first party clients, please look at our [developer api](https://developer.webex.com/) and stick to our public plugins.
|
|
8
|
+
|
|
9
|
+
- [Install](#install)
|
|
10
|
+
- [Usage](#usage)
|
|
11
|
+
- [Contribute](#contribute)
|
|
12
|
+
- [Maintainers](#maintainers)
|
|
13
|
+
- [License](#license)
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install --save @webex/internal-plugin-feature
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import '@webex/internal-plugin-feature';
|
|
25
|
+
|
|
26
|
+
import WebexCore from '@webex/webex-core';
|
|
27
|
+
|
|
28
|
+
const webex = new WebexCore();
|
|
29
|
+
webex.internal.feature.WHATEVER;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Maintainers
|
|
33
|
+
|
|
34
|
+
This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
|
|
35
|
+
|
|
36
|
+
## Contribute
|
|
37
|
+
|
|
38
|
+
Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
© 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
|
package/babel.config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const babelConfigLegacy = require('@webex/babel-config-legacy');
|
|
2
|
-
|
|
3
|
-
module.exports = babelConfigLegacy;
|
|
1
|
+
const babelConfigLegacy = require('@webex/babel-config-legacy');
|
|
2
|
+
|
|
3
|
+
module.exports = babelConfigLegacy;
|
package/dist/config.js
CHANGED
|
@@ -5,8 +5,8 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
|
-
/*!
|
|
9
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
8
|
+
/*!
|
|
9
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
10
10
|
*/
|
|
11
11
|
var _default = {
|
|
12
12
|
feature: {}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_default","feature","exports","default"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nexport default {\n feature: {},\n};\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AAFA,IAAAA,QAAA,GAIe;EACbC,OAAO,EAAE,CAAC;AACZ,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAH,QAAA"}
|
|
1
|
+
{"version":3,"names":["_default","feature","exports","default"],"sources":["config.js"],"sourcesContent":["/*!\r\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\r\n */\r\n\r\nexport default {\r\n feature: {},\r\n};\r\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AAFA,IAAAA,QAAA,GAIe;EACbC,OAAO,EAAE,CAAC;AACZ,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAH,QAAA"}
|
package/dist/feature.js
CHANGED
|
@@ -16,19 +16,19 @@ require("@webex/internal-plugin-device");
|
|
|
16
16
|
var WebexCore = _interopRequireWildcard(require("@webex/webex-core"));
|
|
17
17
|
function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
18
18
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
-
/*!
|
|
20
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
19
|
+
/*!
|
|
20
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
var Feature = WebexCore.WebexPlugin.extend({
|
|
24
24
|
namespace: 'Feature',
|
|
25
|
-
/**
|
|
26
|
-
* Returns the value of the requested feature toggle.
|
|
27
|
-
* @param {string} keyType <developer|user|entitlement>
|
|
28
|
-
* @param {string} key
|
|
29
|
-
* @param {Object} options
|
|
30
|
-
* @param {boolean} options.full to get full feature record including metadata.
|
|
31
|
-
* @returns {string|boolean|number|FeatureModel|null}
|
|
25
|
+
/**
|
|
26
|
+
* Returns the value of the requested feature toggle.
|
|
27
|
+
* @param {string} keyType <developer|user|entitlement>
|
|
28
|
+
* @param {string} key
|
|
29
|
+
* @param {Object} options
|
|
30
|
+
* @param {boolean} options.full to get full feature record including metadata.
|
|
31
|
+
* @returns {string|boolean|number|FeatureModel|null}
|
|
32
32
|
*/
|
|
33
33
|
getFeature: function getFeature(keyType, key, options) {
|
|
34
34
|
if (keyType !== 'developer' && keyType !== 'user' && keyType !== 'entitlement') {
|
|
@@ -44,10 +44,10 @@ var Feature = WebexCore.WebexPlugin.extend({
|
|
|
44
44
|
}
|
|
45
45
|
return _promise.default.resolve(feature.value);
|
|
46
46
|
},
|
|
47
|
-
/**
|
|
48
|
-
* Handles a feature toggle update from the server.
|
|
49
|
-
* @param {Object} envelope
|
|
50
|
-
* @returns {undefined}
|
|
47
|
+
/**
|
|
48
|
+
* Handles a feature toggle update from the server.
|
|
49
|
+
* @param {Object} envelope
|
|
50
|
+
* @returns {undefined}
|
|
51
51
|
*/
|
|
52
52
|
handleFeatureUpdate: function handleFeatureUpdate(envelope) {
|
|
53
53
|
if (envelope && envelope.data) {
|
|
@@ -60,20 +60,20 @@ var Feature = WebexCore.WebexPlugin.extend({
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
|
-
/**
|
|
64
|
-
* Register to listen for incoming feature events
|
|
65
|
-
* @instance
|
|
66
|
-
* @returns {undefined}
|
|
63
|
+
/**
|
|
64
|
+
* Register to listen for incoming feature events
|
|
65
|
+
* @instance
|
|
66
|
+
* @returns {undefined}
|
|
67
67
|
*/
|
|
68
68
|
listen: function listen() {
|
|
69
69
|
this.listenTo(this.webex.internal.mercury, 'event:featureToggle_update', this.handleFeatureUpdate);
|
|
70
70
|
},
|
|
71
|
-
/**
|
|
72
|
-
* Issues request to server to set a value for a feature toggle.
|
|
73
|
-
* @param {string} keyType <developer|user>
|
|
74
|
-
* @param {string} key
|
|
75
|
-
* @param {string} value
|
|
76
|
-
* @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.
|
|
71
|
+
/**
|
|
72
|
+
* Issues request to server to set a value for a feature toggle.
|
|
73
|
+
* @param {string} keyType <developer|user>
|
|
74
|
+
* @param {string} key
|
|
75
|
+
* @param {string} value
|
|
76
|
+
* @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.
|
|
77
77
|
*/
|
|
78
78
|
setFeature: function setFeature(keyType, key, value) {
|
|
79
79
|
var _this = this;
|
|
@@ -96,10 +96,10 @@ var Feature = WebexCore.WebexPlugin.extend({
|
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
},
|
|
99
|
-
/**
|
|
100
|
-
* Issues request to server to set a value for a feature toggle.
|
|
101
|
-
* @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`
|
|
102
|
-
* @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.
|
|
99
|
+
/**
|
|
100
|
+
* Issues request to server to set a value for a feature toggle.
|
|
101
|
+
* @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`
|
|
102
|
+
* @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.
|
|
103
103
|
*/
|
|
104
104
|
setBundledFeatures: function setBundledFeatures(featureList) {
|
|
105
105
|
var _this2 = this;
|
package/dist/feature.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["require","WebexCore","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","_WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","_typeof","default","cache","has","get","newObj","hasPropertyDescriptor","_Object$defineProperty","_Object$getOwnPropertyDescriptor","key","Object","prototype","hasOwnProperty","call","desc","set","Feature","WebexPlugin","extend","namespace","getFeature","keyType","options","_promise","reject","Error","feature","webex","internal","device","features","resolve","full","serialize","value","handleFeatureUpdate","envelope","data","featureToggle","type","toLowerCase","add","merge","listen","listenTo","mercury","setFeature","_this","request","method","api","resource","concat","userId","body","mutable","val","then","res","setBundledFeatures","featureList","_this2","forEach","item","partitionedToggles","_partition2","featureToggles","user","developer","initialize","_len","arguments","length","args","Array","_key","_apply","listenToAndRun","trigger","bind","_default","exports"],"sources":["feature.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-device';\nimport {partition} from 'lodash';\nimport * as WebexCore from '@webex/webex-core';\n\nconst Feature = WebexCore.WebexPlugin.extend({\n namespace: 'Feature',\n\n /**\n * Returns the value of the requested feature toggle.\n * @param {string} keyType <developer|user|entitlement>\n * @param {string} key\n * @param {Object} options\n * @param {boolean} options.full to get full feature record including metadata.\n * @returns {string|boolean|number|FeatureModel|null}\n */\n getFeature(keyType, key, options) {\n if (keyType !== 'developer' && keyType !== 'user' && keyType !== 'entitlement') {\n return Promise.reject(\n new Error(\n 'Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted.'\n )\n );\n }\n\n options = options || {};\n\n const feature = this.webex.internal.device.features[keyType].get(key);\n\n if (!feature) {\n return Promise.resolve(null);\n }\n\n if (options.full) {\n return Promise.resolve(feature.serialize());\n }\n\n return Promise.resolve(feature.value);\n },\n\n /**\n * Handles a feature toggle update from the server.\n * @param {Object} envelope\n * @returns {undefined}\n */\n handleFeatureUpdate(envelope) {\n if (envelope && envelope.data) {\n const feature = envelope.data.featureToggle;\n const keyType = feature.type.toLowerCase();\n\n if (keyType === 'user' || keyType === 'developer') {\n this.webex.internal.device.features[keyType].add([feature], {merge: true});\n }\n }\n },\n\n /**\n * Register to listen for incoming feature events\n * @instance\n * @returns {undefined}\n */\n listen() {\n this.listenTo(\n this.webex.internal.mercury,\n 'event:featureToggle_update',\n this.handleFeatureUpdate\n );\n },\n\n /**\n * Issues request to server to set a value for a feature toggle.\n * @param {string} keyType <developer|user>\n * @param {string} key\n * @param {string} value\n * @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.\n */\n setFeature(keyType, key, value) {\n // Limit only to developer feature toggles for now.\n if (keyType !== 'developer' && keyType !== 'user') {\n return Promise.reject(new Error('Only `developer` and `user` feature toggles can be set.'));\n }\n\n return this.request({\n method: 'POST',\n api: 'feature',\n resource: `features/users/${this.webex.internal.device.userId}/${keyType}`,\n body: {\n key,\n mutable: true,\n val: value,\n },\n }).then((res) => this.webex.internal.device.features[keyType].add(res.body, {merge: true}));\n },\n\n /**\n * Issues request to server to set a value for a feature toggle.\n * @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`\n * @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.\n */\n setBundledFeatures(featureList) {\n featureList.forEach((item) => {\n item.mutable = item.mutable || 'true';\n if (item.type !== 'USER' && item.type !== 'DEV') {\n item.type = 'USER';\n }\n });\n\n return this.request({\n method: 'POST',\n api: 'feature',\n resource: `features/users/${this.webex.internal.device.userId}/toggles`,\n body: featureList,\n }).then((res) => {\n const partitionedToggles = partition(res.body.featureToggles, {type: 'USER'});\n\n this.webex.internal.device.features.user.add(partitionedToggles[0], {merge: true});\n this.webex.internal.device.features.developer.add(partitionedToggles[1], {merge: true});\n });\n },\n\n initialize(...args) {\n Reflect.apply(WebexCore.WebexPlugin.prototype.initialize, this, args);\n\n this.listenToAndRun(\n this.webex,\n 'change:internal.device.features.developer',\n this.trigger.bind(this, 'change:developer')\n );\n this.listenToAndRun(\n this.webex,\n 'change:internal.device.features.entitlement',\n this.trigger.bind(this, 'change:entitlement')\n );\n this.listenToAndRun(\n this.webex,\n 'change:internal.device.features.user',\n this.trigger.bind(this, 'change:user')\n );\n },\n});\n\nexport default Feature;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["require","WebexCore","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","_WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","_typeof","default","cache","has","get","newObj","hasPropertyDescriptor","_Object$defineProperty","_Object$getOwnPropertyDescriptor","key","Object","prototype","hasOwnProperty","call","desc","set","Feature","WebexPlugin","extend","namespace","getFeature","keyType","options","_promise","reject","Error","feature","webex","internal","device","features","resolve","full","serialize","value","handleFeatureUpdate","envelope","data","featureToggle","type","toLowerCase","add","merge","listen","listenTo","mercury","setFeature","_this","request","method","api","resource","concat","userId","body","mutable","val","then","res","setBundledFeatures","featureList","_this2","forEach","item","partitionedToggles","_partition2","featureToggles","user","developer","initialize","_len","arguments","length","args","Array","_key","_apply","listenToAndRun","trigger","bind","_default","exports"],"sources":["feature.js"],"sourcesContent":["/*!\r\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\r\n */\r\n\r\nimport '@webex/internal-plugin-device';\r\nimport {partition} from 'lodash';\r\nimport * as WebexCore from '@webex/webex-core';\r\n\r\nconst Feature = WebexCore.WebexPlugin.extend({\r\n namespace: 'Feature',\r\n\r\n /**\r\n * Returns the value of the requested feature toggle.\r\n * @param {string} keyType <developer|user|entitlement>\r\n * @param {string} key\r\n * @param {Object} options\r\n * @param {boolean} options.full to get full feature record including metadata.\r\n * @returns {string|boolean|number|FeatureModel|null}\r\n */\r\n getFeature(keyType, key, options) {\r\n if (keyType !== 'developer' && keyType !== 'user' && keyType !== 'entitlement') {\r\n return Promise.reject(\r\n new Error(\r\n 'Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted.'\r\n )\r\n );\r\n }\r\n\r\n options = options || {};\r\n\r\n const feature = this.webex.internal.device.features[keyType].get(key);\r\n\r\n if (!feature) {\r\n return Promise.resolve(null);\r\n }\r\n\r\n if (options.full) {\r\n return Promise.resolve(feature.serialize());\r\n }\r\n\r\n return Promise.resolve(feature.value);\r\n },\r\n\r\n /**\r\n * Handles a feature toggle update from the server.\r\n * @param {Object} envelope\r\n * @returns {undefined}\r\n */\r\n handleFeatureUpdate(envelope) {\r\n if (envelope && envelope.data) {\r\n const feature = envelope.data.featureToggle;\r\n const keyType = feature.type.toLowerCase();\r\n\r\n if (keyType === 'user' || keyType === 'developer') {\r\n this.webex.internal.device.features[keyType].add([feature], {merge: true});\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Register to listen for incoming feature events\r\n * @instance\r\n * @returns {undefined}\r\n */\r\n listen() {\r\n this.listenTo(\r\n this.webex.internal.mercury,\r\n 'event:featureToggle_update',\r\n this.handleFeatureUpdate\r\n );\r\n },\r\n\r\n /**\r\n * Issues request to server to set a value for a feature toggle.\r\n * @param {string} keyType <developer|user>\r\n * @param {string} key\r\n * @param {string} value\r\n * @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.\r\n */\r\n setFeature(keyType, key, value) {\r\n // Limit only to developer feature toggles for now.\r\n if (keyType !== 'developer' && keyType !== 'user') {\r\n return Promise.reject(new Error('Only `developer` and `user` feature toggles can be set.'));\r\n }\r\n\r\n return this.request({\r\n method: 'POST',\r\n api: 'feature',\r\n resource: `features/users/${this.webex.internal.device.userId}/${keyType}`,\r\n body: {\r\n key,\r\n mutable: true,\r\n val: value,\r\n },\r\n }).then((res) => this.webex.internal.device.features[keyType].add(res.body, {merge: true}));\r\n },\r\n\r\n /**\r\n * Issues request to server to set a value for a feature toggle.\r\n * @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`\r\n * @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.\r\n */\r\n setBundledFeatures(featureList) {\r\n featureList.forEach((item) => {\r\n item.mutable = item.mutable || 'true';\r\n if (item.type !== 'USER' && item.type !== 'DEV') {\r\n item.type = 'USER';\r\n }\r\n });\r\n\r\n return this.request({\r\n method: 'POST',\r\n api: 'feature',\r\n resource: `features/users/${this.webex.internal.device.userId}/toggles`,\r\n body: featureList,\r\n }).then((res) => {\r\n const partitionedToggles = partition(res.body.featureToggles, {type: 'USER'});\r\n\r\n this.webex.internal.device.features.user.add(partitionedToggles[0], {merge: true});\r\n this.webex.internal.device.features.developer.add(partitionedToggles[1], {merge: true});\r\n });\r\n },\r\n\r\n initialize(...args) {\r\n Reflect.apply(WebexCore.WebexPlugin.prototype.initialize, this, args);\r\n\r\n this.listenToAndRun(\r\n this.webex,\r\n 'change:internal.device.features.developer',\r\n this.trigger.bind(this, 'change:developer')\r\n );\r\n this.listenToAndRun(\r\n this.webex,\r\n 'change:internal.device.features.entitlement',\r\n this.trigger.bind(this, 'change:entitlement')\r\n );\r\n this.listenToAndRun(\r\n this.webex,\r\n 'change:internal.device.features.user',\r\n this.trigger.bind(this, 'change:user')\r\n );\r\n },\r\n});\r\n\r\nexport default Feature;\r\n"],"mappings":";;;;;;;;;;;;;;AAIAA,OAAA;AAEA,IAAAC,SAAA,GAAAC,uBAAA,CAAAF,OAAA;AAA+C,SAAAG,yBAAAC,WAAA,eAAAC,QAAA,kCAAAC,iBAAA,OAAAD,QAAA,QAAAE,gBAAA,OAAAF,QAAA,YAAAF,wBAAA,YAAAA,yBAAAC,WAAA,WAAAA,WAAA,GAAAG,gBAAA,GAAAD,iBAAA,KAAAF,WAAA;AAAA,SAAAF,wBAAAM,GAAA,EAAAJ,WAAA,SAAAA,WAAA,IAAAI,GAAA,IAAAA,GAAA,CAAAC,UAAA,WAAAD,GAAA,QAAAA,GAAA,aAAAE,OAAA,CAAAF,GAAA,yBAAAA,GAAA,4BAAAG,OAAA,EAAAH,GAAA,UAAAI,KAAA,GAAAT,wBAAA,CAAAC,WAAA,OAAAQ,KAAA,IAAAA,KAAA,CAAAC,GAAA,CAAAL,GAAA,YAAAI,KAAA,CAAAE,GAAA,CAAAN,GAAA,SAAAO,MAAA,WAAAC,qBAAA,GAAAC,sBAAA,IAAAC,gCAAA,WAAAC,GAAA,IAAAX,GAAA,QAAAW,GAAA,kBAAAC,MAAA,CAAAC,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAf,GAAA,EAAAW,GAAA,SAAAK,IAAA,GAAAR,qBAAA,GAAAE,gCAAA,CAAAV,GAAA,EAAAW,GAAA,cAAAK,IAAA,KAAAA,IAAA,CAAAV,GAAA,IAAAU,IAAA,CAAAC,GAAA,KAAAR,sBAAA,CAAAF,MAAA,EAAAI,GAAA,EAAAK,IAAA,YAAAT,MAAA,CAAAI,GAAA,IAAAX,GAAA,CAAAW,GAAA,SAAAJ,MAAA,CAAAJ,OAAA,GAAAH,GAAA,MAAAI,KAAA,IAAAA,KAAA,CAAAa,GAAA,CAAAjB,GAAA,EAAAO,MAAA,YAAAA,MAAA;AAN/C;AACA;AACA;;AAMA,IAAMW,OAAO,GAAGzB,SAAS,CAAC0B,WAAW,CAACC,MAAM,CAAC;EAC3CC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,UAAU,WAAAA,WAACC,OAAO,EAAEZ,GAAG,EAAEa,OAAO,EAAE;IAChC,IAAID,OAAO,KAAK,WAAW,IAAIA,OAAO,KAAK,MAAM,IAAIA,OAAO,KAAK,aAAa,EAAE;MAC9E,OAAOE,QAAA,CAAAtB,OAAA,CAAQuB,MAAM,CACnB,IAAIC,KAAK,CACP,8GAA8G,CAC/G,CACF;IACH;IAEAH,OAAO,GAAGA,OAAO,IAAI,CAAC,CAAC;IAEvB,IAAMI,OAAO,GAAG,IAAI,CAACC,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACC,QAAQ,CAACT,OAAO,CAAC,CAACjB,GAAG,CAACK,GAAG,CAAC;IAErE,IAAI,CAACiB,OAAO,EAAE;MACZ,OAAOH,QAAA,CAAAtB,OAAA,CAAQ8B,OAAO,CAAC,IAAI,CAAC;IAC9B;IAEA,IAAIT,OAAO,CAACU,IAAI,EAAE;MAChB,OAAOT,QAAA,CAAAtB,OAAA,CAAQ8B,OAAO,CAACL,OAAO,CAACO,SAAS,EAAE,CAAC;IAC7C;IAEA,OAAOV,QAAA,CAAAtB,OAAA,CAAQ8B,OAAO,CAACL,OAAO,CAACQ,KAAK,CAAC;EACvC,CAAC;EAED;AACF;AACA;AACA;AACA;EACEC,mBAAmB,WAAAA,oBAACC,QAAQ,EAAE;IAC5B,IAAIA,QAAQ,IAAIA,QAAQ,CAACC,IAAI,EAAE;MAC7B,IAAMX,OAAO,GAAGU,QAAQ,CAACC,IAAI,CAACC,aAAa;MAC3C,IAAMjB,OAAO,GAAGK,OAAO,CAACa,IAAI,CAACC,WAAW,EAAE;MAE1C,IAAInB,OAAO,KAAK,MAAM,IAAIA,OAAO,KAAK,WAAW,EAAE;QACjD,IAAI,CAACM,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACC,QAAQ,CAACT,OAAO,CAAC,CAACoB,GAAG,CAAC,CAACf,OAAO,CAAC,EAAE;UAACgB,KAAK,EAAE;QAAI,CAAC,CAAC;MAC5E;IACF;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;EACEC,MAAM,WAAAA,OAAA,EAAG;IACP,IAAI,CAACC,QAAQ,CACX,IAAI,CAACjB,KAAK,CAACC,QAAQ,CAACiB,OAAO,EAC3B,4BAA4B,EAC5B,IAAI,CAACV,mBAAmB,CACzB;EACH,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACEW,UAAU,WAAAA,WAACzB,OAAO,EAAEZ,GAAG,EAAEyB,KAAK,EAAE;IAAA,IAAAa,KAAA;IAC9B;IACA,IAAI1B,OAAO,KAAK,WAAW,IAAIA,OAAO,KAAK,MAAM,EAAE;MACjD,OAAOE,QAAA,CAAAtB,OAAA,CAAQuB,MAAM,CAAC,IAAIC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7F;IAEA,OAAO,IAAI,CAACuB,OAAO,CAAC;MAClBC,MAAM,EAAE,MAAM;MACdC,GAAG,EAAE,SAAS;MACdC,QAAQ,oBAAAC,MAAA,CAAoB,IAAI,CAACzB,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACwB,MAAM,OAAAD,MAAA,CAAI/B,OAAO,CAAE;MAC1EiC,IAAI,EAAE;QACJ7C,GAAG,EAAHA,GAAG;QACH8C,OAAO,EAAE,IAAI;QACbC,GAAG,EAAEtB;MACP;IACF,CAAC,CAAC,CAACuB,IAAI,CAAC,UAACC,GAAG;MAAA,OAAKX,KAAI,CAACpB,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACC,QAAQ,CAACT,OAAO,CAAC,CAACoB,GAAG,CAACiB,GAAG,CAACJ,IAAI,EAAE;QAACZ,KAAK,EAAE;MAAI,CAAC,CAAC;IAAA,EAAC;EAC7F,CAAC;EAED;AACF;AACA;AACA;AACA;EACEiB,kBAAkB,WAAAA,mBAACC,WAAW,EAAE;IAAA,IAAAC,MAAA;IAC9BD,WAAW,CAACE,OAAO,CAAC,UAACC,IAAI,EAAK;MAC5BA,IAAI,CAACR,OAAO,GAAGQ,IAAI,CAACR,OAAO,IAAI,MAAM;MACrC,IAAIQ,IAAI,CAACxB,IAAI,KAAK,MAAM,IAAIwB,IAAI,CAACxB,IAAI,KAAK,KAAK,EAAE;QAC/CwB,IAAI,CAACxB,IAAI,GAAG,MAAM;MACpB;IACF,CAAC,CAAC;IAEF,OAAO,IAAI,CAACS,OAAO,CAAC;MAClBC,MAAM,EAAE,MAAM;MACdC,GAAG,EAAE,SAAS;MACdC,QAAQ,oBAAAC,MAAA,CAAoB,IAAI,CAACzB,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACwB,MAAM,aAAU;MACvEC,IAAI,EAAEM;IACR,CAAC,CAAC,CAACH,IAAI,CAAC,UAACC,GAAG,EAAK;MACf,IAAMM,kBAAkB,GAAG,IAAAC,WAAA,CAAAhE,OAAA,EAAUyD,GAAG,CAACJ,IAAI,CAACY,cAAc,EAAE;QAAC3B,IAAI,EAAE;MAAM,CAAC,CAAC;MAE7EsB,MAAI,CAAClC,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACC,QAAQ,CAACqC,IAAI,CAAC1B,GAAG,CAACuB,kBAAkB,CAAC,CAAC,CAAC,EAAE;QAACtB,KAAK,EAAE;MAAI,CAAC,CAAC;MAClFmB,MAAI,CAAClC,KAAK,CAACC,QAAQ,CAACC,MAAM,CAACC,QAAQ,CAACsC,SAAS,CAAC3B,GAAG,CAACuB,kBAAkB,CAAC,CAAC,CAAC,EAAE;QAACtB,KAAK,EAAE;MAAI,CAAC,CAAC;IACzF,CAAC,CAAC;EACJ,CAAC;EAED2B,UAAU,WAAAA,WAAA,EAAU;IAAA,SAAAC,IAAA,GAAAC,SAAA,CAAAC,MAAA,EAANC,IAAI,OAAAC,KAAA,CAAAJ,IAAA,GAAAK,IAAA,MAAAA,IAAA,GAAAL,IAAA,EAAAK,IAAA;MAAJF,IAAI,CAAAE,IAAA,IAAAJ,SAAA,CAAAI,IAAA;IAAA;IAChB,IAAAC,MAAA,CAAA3E,OAAA,EAAcV,SAAS,CAAC0B,WAAW,CAACN,SAAS,CAAC0D,UAAU,EAAE,IAAI,EAAEI,IAAI,CAAC;IAErE,IAAI,CAACI,cAAc,CACjB,IAAI,CAAClD,KAAK,EACV,2CAA2C,EAC3C,IAAI,CAACmD,OAAO,CAACC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC5C;IACD,IAAI,CAACF,cAAc,CACjB,IAAI,CAAClD,KAAK,EACV,6CAA6C,EAC7C,IAAI,CAACmD,OAAO,CAACC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAC9C;IACD,IAAI,CAACF,cAAc,CACjB,IAAI,CAAClD,KAAK,EACV,sCAAsC,EACtC,IAAI,CAACmD,OAAO,CAACC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CACvC;EACH;AACF,CAAC,CAAC;AAAC,IAAAC,QAAA,GAEYhE,OAAO;AAAAiE,OAAA,CAAAhF,OAAA,GAAA+E,QAAA"}
|
package/dist/index.js
CHANGED
|
@@ -15,8 +15,8 @@ require("@webex/internal-plugin-mercury");
|
|
|
15
15
|
var _webexCore = require("@webex/webex-core");
|
|
16
16
|
var _feature = _interopRequireDefault(require("./feature"));
|
|
17
17
|
var _config = _interopRequireDefault(require("./config"));
|
|
18
|
-
/*!
|
|
19
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
18
|
+
/*!
|
|
19
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
(0, _webexCore.registerInternalPlugin)('feature', _feature.default, {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["require","_webexCore","_feature","_interopRequireDefault","_config","registerInternalPlugin","Feature","config"],"sources":["index.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\nimport '@webex/internal-plugin-mercury';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Feature from './feature';\nimport config from './config';\n\nregisterInternalPlugin('feature', Feature, {\n config,\n});\n\nexport {default} from './feature';\n"],"mappings":";;;;;;;;;;;;;AAGAA,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AAEA,IAAAE,QAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAD,sBAAA,CAAAH,OAAA;AARA;AACA;AACA;;AAQA,IAAAK,iCAAsB,EAAC,SAAS,EAAEC,gBAAO,EAAE;EACzCC,MAAM,EAANA;AACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"names":["require","_webexCore","_feature","_interopRequireDefault","_config","registerInternalPlugin","Feature","config"],"sources":["index.js"],"sourcesContent":["/*!\r\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\r\n */\r\nimport '@webex/internal-plugin-mercury';\r\n\r\nimport {registerInternalPlugin} from '@webex/webex-core';\r\n\r\nimport Feature from './feature';\r\nimport config from './config';\r\n\r\nregisterInternalPlugin('feature', Feature, {\r\n config,\r\n});\r\n\r\nexport {default} from './feature';\r\n"],"mappings":";;;;;;;;;;;;;AAGAA,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AAEA,IAAAE,QAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAD,sBAAA,CAAAH,OAAA;AARA;AACA;AACA;;AAQA,IAAAK,iCAAsB,EAAC,SAAS,EAAEC,gBAAO,EAAE;EACzCC,MAAM,EAANA;AACF,CAAC,CAAC"}
|
package/jest.config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const config = require('@webex/jest-config-legacy');
|
|
2
|
-
|
|
3
|
-
module.exports = config;
|
|
1
|
+
const config = require('@webex/jest-config-legacy');
|
|
2
|
+
|
|
3
|
+
module.exports = config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-feature",
|
|
3
|
-
"version": "2.59.2",
|
|
4
3
|
"description": "",
|
|
5
4
|
"license": "MIT",
|
|
6
5
|
"author": "Aimee <aimma@cisco.com>",
|
|
@@ -17,6 +16,7 @@
|
|
|
17
16
|
"scripts": {
|
|
18
17
|
"build": "yarn build:src",
|
|
19
18
|
"build:src": "webex-legacy-tools build -dest \"./dist\" -src \"./src\" -js -ts -maps",
|
|
19
|
+
"deploy:npm": "yarn npm publish",
|
|
20
20
|
"test": "yarn test:style && yarn test:unit && yarn test:integration",
|
|
21
21
|
"test:browser": "webex-legacy-tools test --integration --unit --runner karma",
|
|
22
22
|
"test:integration": "webex-legacy-tools test --integration --runner mocha",
|
|
@@ -32,23 +32,24 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@babel/core": "^7.17.10",
|
|
34
34
|
"@types/mocha": "^10",
|
|
35
|
-
"@webex/babel-config-legacy": "
|
|
36
|
-
"@webex/eslint-config-legacy": "
|
|
37
|
-
"@webex/jest-config-legacy": "
|
|
38
|
-
"@webex/legacy-tools": "
|
|
39
|
-
"@webex/test-helper-chai": "2.59.
|
|
40
|
-
"@webex/test-helper-mocha": "2.59.
|
|
41
|
-
"@webex/test-helper-mock-webex": "2.59.
|
|
42
|
-
"@webex/test-helper-test-users": "2.59.
|
|
35
|
+
"@webex/babel-config-legacy": "^0.0.0",
|
|
36
|
+
"@webex/eslint-config-legacy": "^0.0.0",
|
|
37
|
+
"@webex/jest-config-legacy": "^0.0.0",
|
|
38
|
+
"@webex/legacy-tools": "^0.0.0",
|
|
39
|
+
"@webex/test-helper-chai": "^2.59.3-next.1",
|
|
40
|
+
"@webex/test-helper-mocha": "^2.59.3-next.1",
|
|
41
|
+
"@webex/test-helper-mock-webex": "^2.59.3-next.1",
|
|
42
|
+
"@webex/test-helper-test-users": "^2.59.3-next.1",
|
|
43
43
|
"eslint": "^8.24.0",
|
|
44
44
|
"mocha": "^10.2.0",
|
|
45
45
|
"prettier": "^2.7.1",
|
|
46
46
|
"sinon": "^9.2.4"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@webex/internal-plugin-device": "2.59.
|
|
50
|
-
"@webex/internal-plugin-mercury": "2.59.
|
|
51
|
-
"@webex/webex-core": "2.59.
|
|
49
|
+
"@webex/internal-plugin-device": "^2.59.3-next.1",
|
|
50
|
+
"@webex/internal-plugin-mercury": "^2.59.3-next.1",
|
|
51
|
+
"@webex/webex-core": "^2.59.3-next.1",
|
|
52
52
|
"lodash": "^4.17.21"
|
|
53
|
-
}
|
|
54
|
-
|
|
53
|
+
},
|
|
54
|
+
"version": "2.59.3-next.1"
|
|
55
|
+
}
|
package/process
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = {browser: true};
|
|
1
|
+
module.exports = {browser: true};
|
package/src/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
feature: {},
|
|
7
|
-
};
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
feature: {},
|
|
7
|
+
};
|
package/src/feature.js
CHANGED
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import '@webex/internal-plugin-device';
|
|
6
|
-
import {partition} from 'lodash';
|
|
7
|
-
import * as WebexCore from '@webex/webex-core';
|
|
8
|
-
|
|
9
|
-
const Feature = WebexCore.WebexPlugin.extend({
|
|
10
|
-
namespace: 'Feature',
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Returns the value of the requested feature toggle.
|
|
14
|
-
* @param {string} keyType <developer|user|entitlement>
|
|
15
|
-
* @param {string} key
|
|
16
|
-
* @param {Object} options
|
|
17
|
-
* @param {boolean} options.full to get full feature record including metadata.
|
|
18
|
-
* @returns {string|boolean|number|FeatureModel|null}
|
|
19
|
-
*/
|
|
20
|
-
getFeature(keyType, key, options) {
|
|
21
|
-
if (keyType !== 'developer' && keyType !== 'user' && keyType !== 'entitlement') {
|
|
22
|
-
return Promise.reject(
|
|
23
|
-
new Error(
|
|
24
|
-
'Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted.'
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
options = options || {};
|
|
30
|
-
|
|
31
|
-
const feature = this.webex.internal.device.features[keyType].get(key);
|
|
32
|
-
|
|
33
|
-
if (!feature) {
|
|
34
|
-
return Promise.resolve(null);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (options.full) {
|
|
38
|
-
return Promise.resolve(feature.serialize());
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return Promise.resolve(feature.value);
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Handles a feature toggle update from the server.
|
|
46
|
-
* @param {Object} envelope
|
|
47
|
-
* @returns {undefined}
|
|
48
|
-
*/
|
|
49
|
-
handleFeatureUpdate(envelope) {
|
|
50
|
-
if (envelope && envelope.data) {
|
|
51
|
-
const feature = envelope.data.featureToggle;
|
|
52
|
-
const keyType = feature.type.toLowerCase();
|
|
53
|
-
|
|
54
|
-
if (keyType === 'user' || keyType === 'developer') {
|
|
55
|
-
this.webex.internal.device.features[keyType].add([feature], {merge: true});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Register to listen for incoming feature events
|
|
62
|
-
* @instance
|
|
63
|
-
* @returns {undefined}
|
|
64
|
-
*/
|
|
65
|
-
listen() {
|
|
66
|
-
this.listenTo(
|
|
67
|
-
this.webex.internal.mercury,
|
|
68
|
-
'event:featureToggle_update',
|
|
69
|
-
this.handleFeatureUpdate
|
|
70
|
-
);
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Issues request to server to set a value for a feature toggle.
|
|
75
|
-
* @param {string} keyType <developer|user>
|
|
76
|
-
* @param {string} key
|
|
77
|
-
* @param {string} value
|
|
78
|
-
* @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.
|
|
79
|
-
*/
|
|
80
|
-
setFeature(keyType, key, value) {
|
|
81
|
-
// Limit only to developer feature toggles for now.
|
|
82
|
-
if (keyType !== 'developer' && keyType !== 'user') {
|
|
83
|
-
return Promise.reject(new Error('Only `developer` and `user` feature toggles can be set.'));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return this.request({
|
|
87
|
-
method: 'POST',
|
|
88
|
-
api: 'feature',
|
|
89
|
-
resource: `features/users/${this.webex.internal.device.userId}/${keyType}`,
|
|
90
|
-
body: {
|
|
91
|
-
key,
|
|
92
|
-
mutable: true,
|
|
93
|
-
val: value,
|
|
94
|
-
},
|
|
95
|
-
}).then((res) => this.webex.internal.device.features[keyType].add(res.body, {merge: true}));
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Issues request to server to set a value for a feature toggle.
|
|
100
|
-
* @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`
|
|
101
|
-
* @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.
|
|
102
|
-
*/
|
|
103
|
-
setBundledFeatures(featureList) {
|
|
104
|
-
featureList.forEach((item) => {
|
|
105
|
-
item.mutable = item.mutable || 'true';
|
|
106
|
-
if (item.type !== 'USER' && item.type !== 'DEV') {
|
|
107
|
-
item.type = 'USER';
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return this.request({
|
|
112
|
-
method: 'POST',
|
|
113
|
-
api: 'feature',
|
|
114
|
-
resource: `features/users/${this.webex.internal.device.userId}/toggles`,
|
|
115
|
-
body: featureList,
|
|
116
|
-
}).then((res) => {
|
|
117
|
-
const partitionedToggles = partition(res.body.featureToggles, {type: 'USER'});
|
|
118
|
-
|
|
119
|
-
this.webex.internal.device.features.user.add(partitionedToggles[0], {merge: true});
|
|
120
|
-
this.webex.internal.device.features.developer.add(partitionedToggles[1], {merge: true});
|
|
121
|
-
});
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
initialize(...args) {
|
|
125
|
-
Reflect.apply(WebexCore.WebexPlugin.prototype.initialize, this, args);
|
|
126
|
-
|
|
127
|
-
this.listenToAndRun(
|
|
128
|
-
this.webex,
|
|
129
|
-
'change:internal.device.features.developer',
|
|
130
|
-
this.trigger.bind(this, 'change:developer')
|
|
131
|
-
);
|
|
132
|
-
this.listenToAndRun(
|
|
133
|
-
this.webex,
|
|
134
|
-
'change:internal.device.features.entitlement',
|
|
135
|
-
this.trigger.bind(this, 'change:entitlement')
|
|
136
|
-
);
|
|
137
|
-
this.listenToAndRun(
|
|
138
|
-
this.webex,
|
|
139
|
-
'change:internal.device.features.user',
|
|
140
|
-
this.trigger.bind(this, 'change:user')
|
|
141
|
-
);
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
export default Feature;
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import '@webex/internal-plugin-device';
|
|
6
|
+
import {partition} from 'lodash';
|
|
7
|
+
import * as WebexCore from '@webex/webex-core';
|
|
8
|
+
|
|
9
|
+
const Feature = WebexCore.WebexPlugin.extend({
|
|
10
|
+
namespace: 'Feature',
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns the value of the requested feature toggle.
|
|
14
|
+
* @param {string} keyType <developer|user|entitlement>
|
|
15
|
+
* @param {string} key
|
|
16
|
+
* @param {Object} options
|
|
17
|
+
* @param {boolean} options.full to get full feature record including metadata.
|
|
18
|
+
* @returns {string|boolean|number|FeatureModel|null}
|
|
19
|
+
*/
|
|
20
|
+
getFeature(keyType, key, options) {
|
|
21
|
+
if (keyType !== 'developer' && keyType !== 'user' && keyType !== 'entitlement') {
|
|
22
|
+
return Promise.reject(
|
|
23
|
+
new Error(
|
|
24
|
+
'Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted.'
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
options = options || {};
|
|
30
|
+
|
|
31
|
+
const feature = this.webex.internal.device.features[keyType].get(key);
|
|
32
|
+
|
|
33
|
+
if (!feature) {
|
|
34
|
+
return Promise.resolve(null);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (options.full) {
|
|
38
|
+
return Promise.resolve(feature.serialize());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return Promise.resolve(feature.value);
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Handles a feature toggle update from the server.
|
|
46
|
+
* @param {Object} envelope
|
|
47
|
+
* @returns {undefined}
|
|
48
|
+
*/
|
|
49
|
+
handleFeatureUpdate(envelope) {
|
|
50
|
+
if (envelope && envelope.data) {
|
|
51
|
+
const feature = envelope.data.featureToggle;
|
|
52
|
+
const keyType = feature.type.toLowerCase();
|
|
53
|
+
|
|
54
|
+
if (keyType === 'user' || keyType === 'developer') {
|
|
55
|
+
this.webex.internal.device.features[keyType].add([feature], {merge: true});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Register to listen for incoming feature events
|
|
62
|
+
* @instance
|
|
63
|
+
* @returns {undefined}
|
|
64
|
+
*/
|
|
65
|
+
listen() {
|
|
66
|
+
this.listenTo(
|
|
67
|
+
this.webex.internal.mercury,
|
|
68
|
+
'event:featureToggle_update',
|
|
69
|
+
this.handleFeatureUpdate
|
|
70
|
+
);
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Issues request to server to set a value for a feature toggle.
|
|
75
|
+
* @param {string} keyType <developer|user>
|
|
76
|
+
* @param {string} key
|
|
77
|
+
* @param {string} value
|
|
78
|
+
* @returns {Promise} Refreshes the local device and resolves with the features endpoint's response.
|
|
79
|
+
*/
|
|
80
|
+
setFeature(keyType, key, value) {
|
|
81
|
+
// Limit only to developer feature toggles for now.
|
|
82
|
+
if (keyType !== 'developer' && keyType !== 'user') {
|
|
83
|
+
return Promise.reject(new Error('Only `developer` and `user` feature toggles can be set.'));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return this.request({
|
|
87
|
+
method: 'POST',
|
|
88
|
+
api: 'feature',
|
|
89
|
+
resource: `features/users/${this.webex.internal.device.userId}/${keyType}`,
|
|
90
|
+
body: {
|
|
91
|
+
key,
|
|
92
|
+
mutable: true,
|
|
93
|
+
val: value,
|
|
94
|
+
},
|
|
95
|
+
}).then((res) => this.webex.internal.device.features[keyType].add(res.body, {merge: true}));
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Issues request to server to set a value for a feature toggle.
|
|
100
|
+
* @param {array} featureList - in the form of `Array<{ type: 'USER' | 'DEV', key: string, val: any }>`
|
|
101
|
+
* @returns {Promise} Refreshes the local device and resolves with the features endpoint`s response.
|
|
102
|
+
*/
|
|
103
|
+
setBundledFeatures(featureList) {
|
|
104
|
+
featureList.forEach((item) => {
|
|
105
|
+
item.mutable = item.mutable || 'true';
|
|
106
|
+
if (item.type !== 'USER' && item.type !== 'DEV') {
|
|
107
|
+
item.type = 'USER';
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return this.request({
|
|
112
|
+
method: 'POST',
|
|
113
|
+
api: 'feature',
|
|
114
|
+
resource: `features/users/${this.webex.internal.device.userId}/toggles`,
|
|
115
|
+
body: featureList,
|
|
116
|
+
}).then((res) => {
|
|
117
|
+
const partitionedToggles = partition(res.body.featureToggles, {type: 'USER'});
|
|
118
|
+
|
|
119
|
+
this.webex.internal.device.features.user.add(partitionedToggles[0], {merge: true});
|
|
120
|
+
this.webex.internal.device.features.developer.add(partitionedToggles[1], {merge: true});
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
initialize(...args) {
|
|
125
|
+
Reflect.apply(WebexCore.WebexPlugin.prototype.initialize, this, args);
|
|
126
|
+
|
|
127
|
+
this.listenToAndRun(
|
|
128
|
+
this.webex,
|
|
129
|
+
'change:internal.device.features.developer',
|
|
130
|
+
this.trigger.bind(this, 'change:developer')
|
|
131
|
+
);
|
|
132
|
+
this.listenToAndRun(
|
|
133
|
+
this.webex,
|
|
134
|
+
'change:internal.device.features.entitlement',
|
|
135
|
+
this.trigger.bind(this, 'change:entitlement')
|
|
136
|
+
);
|
|
137
|
+
this.listenToAndRun(
|
|
138
|
+
this.webex,
|
|
139
|
+
'change:internal.device.features.user',
|
|
140
|
+
this.trigger.bind(this, 'change:user')
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export default Feature;
|
package/src/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
import '@webex/internal-plugin-mercury';
|
|
5
|
-
|
|
6
|
-
import {registerInternalPlugin} from '@webex/webex-core';
|
|
7
|
-
|
|
8
|
-
import Feature from './feature';
|
|
9
|
-
import config from './config';
|
|
10
|
-
|
|
11
|
-
registerInternalPlugin('feature', Feature, {
|
|
12
|
-
config,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export {default} from './feature';
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
import '@webex/internal-plugin-mercury';
|
|
5
|
+
|
|
6
|
+
import {registerInternalPlugin} from '@webex/webex-core';
|
|
7
|
+
|
|
8
|
+
import Feature from './feature';
|
|
9
|
+
import config from './config';
|
|
10
|
+
|
|
11
|
+
registerInternalPlugin('feature', Feature, {
|
|
12
|
+
config,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export {default} from './feature';
|
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import '@webex/internal-plugin-feature';
|
|
6
|
-
|
|
7
|
-
import {assert} from '@webex/test-helper-chai';
|
|
8
|
-
import WebexCore from '@webex/webex-core';
|
|
9
|
-
import testUsers from '@webex/test-helper-test-users';
|
|
10
|
-
import {expectEvent, flaky} from '@webex/test-helper-mocha';
|
|
11
|
-
import sinon from 'sinon';
|
|
12
|
-
|
|
13
|
-
describe('plugin-feature', function () {
|
|
14
|
-
this.timeout(30000);
|
|
15
|
-
let webex, spock;
|
|
16
|
-
|
|
17
|
-
describe('#setFeature()', () => {
|
|
18
|
-
before(() =>
|
|
19
|
-
testUsers.create({count: 1}).then(async (users) => {
|
|
20
|
-
spock = users[0];
|
|
21
|
-
|
|
22
|
-
// Pause for 5 seconds for CI
|
|
23
|
-
await new Promise((done) => setTimeout(done, 5000));
|
|
24
|
-
|
|
25
|
-
webex = new WebexCore({
|
|
26
|
-
credentials: {
|
|
27
|
-
authorization: spock.token,
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
return webex.internal.device.register();
|
|
32
|
-
})
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
['developer', 'user'].forEach((keyType) => {
|
|
36
|
-
it(`sets a value for a ${keyType} feature toggle`, () =>
|
|
37
|
-
webex.internal.feature.setFeature(keyType, 'testFeature', false).then((res) => {
|
|
38
|
-
assert.equal(res.key, 'testFeature');
|
|
39
|
-
assert.equal(res.val, 'false');
|
|
40
|
-
assert.equal(res.value, false);
|
|
41
|
-
assert.equal(res.type, 'boolean');
|
|
42
|
-
|
|
43
|
-
assert.equal(
|
|
44
|
-
webex.internal.device.features[keyType].get({key: 'testFeature'}).val,
|
|
45
|
-
'false'
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
return webex.internal.feature
|
|
49
|
-
.getFeature(keyType, 'testFeature')
|
|
50
|
-
.then((result) => assert.deepEqual(result, false));
|
|
51
|
-
}));
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe('#setBundledFeatures()', () => {
|
|
56
|
-
before(() =>
|
|
57
|
-
testUsers.create({count: 1}).then((users) => {
|
|
58
|
-
spock = users[0];
|
|
59
|
-
webex = new WebexCore({
|
|
60
|
-
credentials: {
|
|
61
|
-
authorization: spock.token,
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
return webex.internal.device.register();
|
|
66
|
-
})
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
const featureUpdateArray = [
|
|
70
|
-
{
|
|
71
|
-
key: 'key1',
|
|
72
|
-
val: 'value1',
|
|
73
|
-
type: 'USER',
|
|
74
|
-
mutable: 'true',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
key: 'key2',
|
|
78
|
-
val: 'value2',
|
|
79
|
-
mutable: 'false',
|
|
80
|
-
},
|
|
81
|
-
];
|
|
82
|
-
|
|
83
|
-
it('sets a value for two user feature toggle', () => {
|
|
84
|
-
webex.internal.feature.setFeature('user', 'key1', false);
|
|
85
|
-
|
|
86
|
-
return webex.internal.feature
|
|
87
|
-
.setBundledFeatures(featureUpdateArray)
|
|
88
|
-
.then(() =>
|
|
89
|
-
Promise.all([
|
|
90
|
-
webex.internal.feature
|
|
91
|
-
.getFeature('user', 'key1')
|
|
92
|
-
.then((result) => assert.deepEqual(result, 'value1')),
|
|
93
|
-
webex.internal.feature
|
|
94
|
-
.getFeature('user', 'key2')
|
|
95
|
-
.then((result) => assert.deepEqual(result, 'value2')),
|
|
96
|
-
])
|
|
97
|
-
);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('when feature toggle update event is received', () => {
|
|
102
|
-
before(() =>
|
|
103
|
-
testUsers.create({count: 1}).then(async (users) => {
|
|
104
|
-
spock = users[0];
|
|
105
|
-
|
|
106
|
-
// Pause for 5 seconds for CI
|
|
107
|
-
await new Promise((done) => setTimeout(done, 5000));
|
|
108
|
-
|
|
109
|
-
webex = new WebexCore({
|
|
110
|
-
credentials: {
|
|
111
|
-
authorization: spock.token,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
sinon.spy(webex.internal.feature, 'handleFeatureUpdate');
|
|
116
|
-
|
|
117
|
-
return webex.internal.device.register().then(() => webex.internal.mercury.connect());
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
after(() => webex.internal.mercury.disconnect());
|
|
122
|
-
|
|
123
|
-
flaky(it, process.env.SKIP_FLAKY_TESTS)('updates the feature toggle', () => {
|
|
124
|
-
const featureUpdateArray = [
|
|
125
|
-
{
|
|
126
|
-
key: 'mention-notifications',
|
|
127
|
-
val: false,
|
|
128
|
-
type: 'USER',
|
|
129
|
-
mutable: true,
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
webex.internal.feature.listen();
|
|
134
|
-
|
|
135
|
-
return webex.internal.feature
|
|
136
|
-
.getFeature('user', 'mention-notifications')
|
|
137
|
-
.then((result) => assert.deepEqual(result, true))
|
|
138
|
-
.then(() => webex.internal.feature.setBundledFeatures(featureUpdateArray))
|
|
139
|
-
.then(() => expectEvent(10000, 'event:featureToggle_update', webex.internal.mercury))
|
|
140
|
-
.then(() => assert.called(webex.internal.feature.handleFeatureUpdate))
|
|
141
|
-
.then(() => webex.internal.feature.getFeature('user', 'mention-notifications'))
|
|
142
|
-
.then((result) => assert.deepEqual(result, false));
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
});
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import '@webex/internal-plugin-feature';
|
|
6
|
+
|
|
7
|
+
import {assert} from '@webex/test-helper-chai';
|
|
8
|
+
import WebexCore from '@webex/webex-core';
|
|
9
|
+
import testUsers from '@webex/test-helper-test-users';
|
|
10
|
+
import {expectEvent, flaky} from '@webex/test-helper-mocha';
|
|
11
|
+
import sinon from 'sinon';
|
|
12
|
+
|
|
13
|
+
describe('plugin-feature', function () {
|
|
14
|
+
this.timeout(30000);
|
|
15
|
+
let webex, spock;
|
|
16
|
+
|
|
17
|
+
describe('#setFeature()', () => {
|
|
18
|
+
before(() =>
|
|
19
|
+
testUsers.create({count: 1}).then(async (users) => {
|
|
20
|
+
spock = users[0];
|
|
21
|
+
|
|
22
|
+
// Pause for 5 seconds for CI
|
|
23
|
+
await new Promise((done) => setTimeout(done, 5000));
|
|
24
|
+
|
|
25
|
+
webex = new WebexCore({
|
|
26
|
+
credentials: {
|
|
27
|
+
authorization: spock.token,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return webex.internal.device.register();
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
['developer', 'user'].forEach((keyType) => {
|
|
36
|
+
it(`sets a value for a ${keyType} feature toggle`, () =>
|
|
37
|
+
webex.internal.feature.setFeature(keyType, 'testFeature', false).then((res) => {
|
|
38
|
+
assert.equal(res.key, 'testFeature');
|
|
39
|
+
assert.equal(res.val, 'false');
|
|
40
|
+
assert.equal(res.value, false);
|
|
41
|
+
assert.equal(res.type, 'boolean');
|
|
42
|
+
|
|
43
|
+
assert.equal(
|
|
44
|
+
webex.internal.device.features[keyType].get({key: 'testFeature'}).val,
|
|
45
|
+
'false'
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return webex.internal.feature
|
|
49
|
+
.getFeature(keyType, 'testFeature')
|
|
50
|
+
.then((result) => assert.deepEqual(result, false));
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('#setBundledFeatures()', () => {
|
|
56
|
+
before(() =>
|
|
57
|
+
testUsers.create({count: 1}).then((users) => {
|
|
58
|
+
spock = users[0];
|
|
59
|
+
webex = new WebexCore({
|
|
60
|
+
credentials: {
|
|
61
|
+
authorization: spock.token,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return webex.internal.device.register();
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const featureUpdateArray = [
|
|
70
|
+
{
|
|
71
|
+
key: 'key1',
|
|
72
|
+
val: 'value1',
|
|
73
|
+
type: 'USER',
|
|
74
|
+
mutable: 'true',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: 'key2',
|
|
78
|
+
val: 'value2',
|
|
79
|
+
mutable: 'false',
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
it('sets a value for two user feature toggle', () => {
|
|
84
|
+
webex.internal.feature.setFeature('user', 'key1', false);
|
|
85
|
+
|
|
86
|
+
return webex.internal.feature
|
|
87
|
+
.setBundledFeatures(featureUpdateArray)
|
|
88
|
+
.then(() =>
|
|
89
|
+
Promise.all([
|
|
90
|
+
webex.internal.feature
|
|
91
|
+
.getFeature('user', 'key1')
|
|
92
|
+
.then((result) => assert.deepEqual(result, 'value1')),
|
|
93
|
+
webex.internal.feature
|
|
94
|
+
.getFeature('user', 'key2')
|
|
95
|
+
.then((result) => assert.deepEqual(result, 'value2')),
|
|
96
|
+
])
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('when feature toggle update event is received', () => {
|
|
102
|
+
before(() =>
|
|
103
|
+
testUsers.create({count: 1}).then(async (users) => {
|
|
104
|
+
spock = users[0];
|
|
105
|
+
|
|
106
|
+
// Pause for 5 seconds for CI
|
|
107
|
+
await new Promise((done) => setTimeout(done, 5000));
|
|
108
|
+
|
|
109
|
+
webex = new WebexCore({
|
|
110
|
+
credentials: {
|
|
111
|
+
authorization: spock.token,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
sinon.spy(webex.internal.feature, 'handleFeatureUpdate');
|
|
116
|
+
|
|
117
|
+
return webex.internal.device.register().then(() => webex.internal.mercury.connect());
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
after(() => webex.internal.mercury.disconnect());
|
|
122
|
+
|
|
123
|
+
flaky(it, process.env.SKIP_FLAKY_TESTS)('updates the feature toggle', () => {
|
|
124
|
+
const featureUpdateArray = [
|
|
125
|
+
{
|
|
126
|
+
key: 'mention-notifications',
|
|
127
|
+
val: false,
|
|
128
|
+
type: 'USER',
|
|
129
|
+
mutable: true,
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
webex.internal.feature.listen();
|
|
134
|
+
|
|
135
|
+
return webex.internal.feature
|
|
136
|
+
.getFeature('user', 'mention-notifications')
|
|
137
|
+
.then((result) => assert.deepEqual(result, true))
|
|
138
|
+
.then(() => webex.internal.feature.setBundledFeatures(featureUpdateArray))
|
|
139
|
+
.then(() => expectEvent(10000, 'event:featureToggle_update', webex.internal.mercury))
|
|
140
|
+
.then(() => assert.called(webex.internal.feature.handleFeatureUpdate))
|
|
141
|
+
.then(() => webex.internal.feature.getFeature('user', 'mention-notifications'))
|
|
142
|
+
.then((result) => assert.deepEqual(result, false));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {assert} from '@webex/test-helper-chai';
|
|
6
|
-
import Device from '@webex/internal-plugin-device';
|
|
7
|
-
import Feature from '@webex/internal-plugin-feature';
|
|
8
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
9
|
-
import sinon from 'sinon';
|
|
10
|
-
|
|
11
|
-
describe('plugin-feature', () => {
|
|
12
|
-
describe('Feature', () => {
|
|
13
|
-
let webex;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
webex = new MockWebex({
|
|
17
|
-
children: {
|
|
18
|
-
device: Device,
|
|
19
|
-
feature: Feature,
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe('#getFeature()', () => {
|
|
25
|
-
it('requires a valid keyType', () =>
|
|
26
|
-
assert.isRejected(
|
|
27
|
-
webex.internal.feature.getFeature('none', 'featureName', {}),
|
|
28
|
-
/Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted./
|
|
29
|
-
));
|
|
30
|
-
|
|
31
|
-
it('returns the full feature object', () => {
|
|
32
|
-
const key = 'featureName';
|
|
33
|
-
const keyType = 'developer';
|
|
34
|
-
const feature = {
|
|
35
|
-
key,
|
|
36
|
-
mutable: true,
|
|
37
|
-
type: 'boolean',
|
|
38
|
-
val: 'true',
|
|
39
|
-
value: true,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
webex.internal.device.features[keyType].add(feature);
|
|
43
|
-
|
|
44
|
-
return webex.internal.feature
|
|
45
|
-
.getFeature(keyType, key, {full: true})
|
|
46
|
-
.then((result) => assert.deepEqual(result, feature));
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('returns the feature value', () => {
|
|
50
|
-
const key = 'featureName';
|
|
51
|
-
const keyType = 'developer';
|
|
52
|
-
const feature = {
|
|
53
|
-
key,
|
|
54
|
-
mutable: true,
|
|
55
|
-
type: 'boolean',
|
|
56
|
-
val: 'true',
|
|
57
|
-
value: true,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
webex.internal.device.features[keyType].add(feature);
|
|
61
|
-
|
|
62
|
-
return webex.internal.feature
|
|
63
|
-
.getFeature(keyType, key)
|
|
64
|
-
.then((result) => assert.deepEqual(result, feature.value));
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('#setFeature()', () => {
|
|
69
|
-
beforeEach(() => {
|
|
70
|
-
webex.request = sinon.stub().returns(
|
|
71
|
-
Promise.resolve({
|
|
72
|
-
body: {},
|
|
73
|
-
statusCode: 200,
|
|
74
|
-
})
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
afterEach(() => {
|
|
78
|
-
webex.request.resetHistory();
|
|
79
|
-
});
|
|
80
|
-
it('does not allow entitlement keyType to be set', () =>
|
|
81
|
-
assert.isRejected(
|
|
82
|
-
webex.internal.feature.setFeature('entitlement', 'featureName', true),
|
|
83
|
-
/Only `developer` and `user` feature toggles can be set./
|
|
84
|
-
));
|
|
85
|
-
|
|
86
|
-
['developer', 'user'].forEach((keyType) => {
|
|
87
|
-
it(`sets a value for a ${keyType} feature toggle`, () => {
|
|
88
|
-
sinon.spy(webex.internal.device.features[keyType], 'add');
|
|
89
|
-
|
|
90
|
-
return webex.internal.feature.setFeature(keyType, 'featureName', true).then(() => {
|
|
91
|
-
assert.called(webex.internal.device.features[keyType].add);
|
|
92
|
-
assert.equal(
|
|
93
|
-
webex.request.getCall(0).args[0].resource,
|
|
94
|
-
`features/users/${webex.internal.device.userId}/${keyType}`
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('#handleFeatureUpdate', () => {
|
|
102
|
-
it('updates the feature toggle', () => {
|
|
103
|
-
const key = 'featureName';
|
|
104
|
-
const keyType = 'user';
|
|
105
|
-
const envelope = {
|
|
106
|
-
data: {
|
|
107
|
-
featureToggle: {
|
|
108
|
-
key,
|
|
109
|
-
mutable: true,
|
|
110
|
-
type: 'USER',
|
|
111
|
-
val: 'true',
|
|
112
|
-
value: true,
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
sinon.spy(webex.internal.device.features[keyType], 'add');
|
|
118
|
-
webex.internal.feature.handleFeatureUpdate(envelope);
|
|
119
|
-
assert.called(webex.internal.device.features[keyType].add);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
describe('when a feature is changed', () => {
|
|
124
|
-
['developer', 'entitlement', 'user'].forEach((keyType) => {
|
|
125
|
-
it(`emits \`change:${keyType}\` on ${keyType} feature change`, () => {
|
|
126
|
-
const mockEventHandler = sinon.spy();
|
|
127
|
-
|
|
128
|
-
webex.internal.feature.on(`change:${keyType}`, mockEventHandler);
|
|
129
|
-
const key = 'featureName';
|
|
130
|
-
const feature = {
|
|
131
|
-
key,
|
|
132
|
-
mutable: true,
|
|
133
|
-
type: 'boolean',
|
|
134
|
-
val: 'true',
|
|
135
|
-
value: true,
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
webex.internal.device.features[keyType].add(feature);
|
|
139
|
-
|
|
140
|
-
return assert.called(mockEventHandler);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
});
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {assert} from '@webex/test-helper-chai';
|
|
6
|
+
import Device from '@webex/internal-plugin-device';
|
|
7
|
+
import Feature from '@webex/internal-plugin-feature';
|
|
8
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
9
|
+
import sinon from 'sinon';
|
|
10
|
+
|
|
11
|
+
describe('plugin-feature', () => {
|
|
12
|
+
describe('Feature', () => {
|
|
13
|
+
let webex;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
webex = new MockWebex({
|
|
17
|
+
children: {
|
|
18
|
+
device: Device,
|
|
19
|
+
feature: Feature,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('#getFeature()', () => {
|
|
25
|
+
it('requires a valid keyType', () =>
|
|
26
|
+
assert.isRejected(
|
|
27
|
+
webex.internal.feature.getFeature('none', 'featureName', {}),
|
|
28
|
+
/Invalid feature keyType provided. Only `developer`, `user`, and `entitlement` feature toggles are permitted./
|
|
29
|
+
));
|
|
30
|
+
|
|
31
|
+
it('returns the full feature object', () => {
|
|
32
|
+
const key = 'featureName';
|
|
33
|
+
const keyType = 'developer';
|
|
34
|
+
const feature = {
|
|
35
|
+
key,
|
|
36
|
+
mutable: true,
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
val: 'true',
|
|
39
|
+
value: true,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
webex.internal.device.features[keyType].add(feature);
|
|
43
|
+
|
|
44
|
+
return webex.internal.feature
|
|
45
|
+
.getFeature(keyType, key, {full: true})
|
|
46
|
+
.then((result) => assert.deepEqual(result, feature));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('returns the feature value', () => {
|
|
50
|
+
const key = 'featureName';
|
|
51
|
+
const keyType = 'developer';
|
|
52
|
+
const feature = {
|
|
53
|
+
key,
|
|
54
|
+
mutable: true,
|
|
55
|
+
type: 'boolean',
|
|
56
|
+
val: 'true',
|
|
57
|
+
value: true,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
webex.internal.device.features[keyType].add(feature);
|
|
61
|
+
|
|
62
|
+
return webex.internal.feature
|
|
63
|
+
.getFeature(keyType, key)
|
|
64
|
+
.then((result) => assert.deepEqual(result, feature.value));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('#setFeature()', () => {
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
webex.request = sinon.stub().returns(
|
|
71
|
+
Promise.resolve({
|
|
72
|
+
body: {},
|
|
73
|
+
statusCode: 200,
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
afterEach(() => {
|
|
78
|
+
webex.request.resetHistory();
|
|
79
|
+
});
|
|
80
|
+
it('does not allow entitlement keyType to be set', () =>
|
|
81
|
+
assert.isRejected(
|
|
82
|
+
webex.internal.feature.setFeature('entitlement', 'featureName', true),
|
|
83
|
+
/Only `developer` and `user` feature toggles can be set./
|
|
84
|
+
));
|
|
85
|
+
|
|
86
|
+
['developer', 'user'].forEach((keyType) => {
|
|
87
|
+
it(`sets a value for a ${keyType} feature toggle`, () => {
|
|
88
|
+
sinon.spy(webex.internal.device.features[keyType], 'add');
|
|
89
|
+
|
|
90
|
+
return webex.internal.feature.setFeature(keyType, 'featureName', true).then(() => {
|
|
91
|
+
assert.called(webex.internal.device.features[keyType].add);
|
|
92
|
+
assert.equal(
|
|
93
|
+
webex.request.getCall(0).args[0].resource,
|
|
94
|
+
`features/users/${webex.internal.device.userId}/${keyType}`
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('#handleFeatureUpdate', () => {
|
|
102
|
+
it('updates the feature toggle', () => {
|
|
103
|
+
const key = 'featureName';
|
|
104
|
+
const keyType = 'user';
|
|
105
|
+
const envelope = {
|
|
106
|
+
data: {
|
|
107
|
+
featureToggle: {
|
|
108
|
+
key,
|
|
109
|
+
mutable: true,
|
|
110
|
+
type: 'USER',
|
|
111
|
+
val: 'true',
|
|
112
|
+
value: true,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
sinon.spy(webex.internal.device.features[keyType], 'add');
|
|
118
|
+
webex.internal.feature.handleFeatureUpdate(envelope);
|
|
119
|
+
assert.called(webex.internal.device.features[keyType].add);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('when a feature is changed', () => {
|
|
124
|
+
['developer', 'entitlement', 'user'].forEach((keyType) => {
|
|
125
|
+
it(`emits \`change:${keyType}\` on ${keyType} feature change`, () => {
|
|
126
|
+
const mockEventHandler = sinon.spy();
|
|
127
|
+
|
|
128
|
+
webex.internal.feature.on(`change:${keyType}`, mockEventHandler);
|
|
129
|
+
const key = 'featureName';
|
|
130
|
+
const feature = {
|
|
131
|
+
key,
|
|
132
|
+
mutable: true,
|
|
133
|
+
type: 'boolean',
|
|
134
|
+
val: 'true',
|
|
135
|
+
value: true,
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
webex.internal.device.features[keyType].add(feature);
|
|
139
|
+
|
|
140
|
+
return assert.called(mockEventHandler);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|