Skip to content

Commit

Permalink
fix(FEC-9716): An array doesn't merged into plugin config (#524)
Browse files Browse the repository at this point in the history
If an array in plugin config contains an object item, call removeUnevaluatedExpression on it instead of filtering it out
  • Loading branch information
SivanA-Kaltura committed Feb 8, 2022
1 parent 70c6a56 commit 773171d
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 15 deletions.
33 changes: 31 additions & 2 deletions src/common/plugins/plugins-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,35 @@ const isValueEvaluated = (value: any): boolean =>
Utils.Object.isClassInstance(value)) &&
!templateRegex.test(value.toString());

/**
* returns whether the value is a simple object (not a function or class instance)
* @private
* @param {*} value - the value to be checked
* @returns {boolean} - whether the value is a simple object or not
*/
const isSimpleObject = (value: any): boolean => Utils.Object.isObject(value) && typeof value !== 'function' && !Utils.Object.isClassInstance(value);

/**
* filters out unevaluated expressions in an array
* @private
* @param {Array} value - the array to be checked
* @returns {Array} - the array with unevaluated expressions filtered out
*/
const filterUnevaluatedExpressions = (value: $ReadOnlyArray<any>): $ReadOnlyArray<any> => {
return value
.map(item => {
if (isSimpleObject(item)) {
const updatedItem = removeUnevaluatedExpression(item);
return Utils.Object.isEmptyObject(updatedItem) ? null : updatedItem;
} else if (isValueEvaluated(item)) {
return item;
} else {
return null;
}
})
.filter(item => item !== null);
};

/**
* remove unevaluated expressions form object
* @private
Expand All @@ -27,10 +56,10 @@ const isValueEvaluated = (value: any): boolean =>
*/
const removeUnevaluatedExpression = (obj: Object = {}): Object =>
Object.entries(obj).reduce((product, [key, value]): Object => {
if (Utils.Object.isObject(value) && typeof value !== 'function' && !Utils.Object.isClassInstance(value)) {
if (isSimpleObject(value)) {
product[key] = removeUnevaluatedExpression(value);
} else if (Array.isArray(value)) {
product[key] = value.filter(index => isValueEvaluated(index));
product[key] = filterUnevaluatedExpressions(value);
} else if (isValueEvaluated(value)) {
product[key] = value;
}
Expand Down
101 changes: 88 additions & 13 deletions test/src/common/plugin/plugins-config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import {ConfigEvaluator, getEncodedReferrer} from '../../../../src/common/plugin

let sandbox = sinon.createSandbox();

describe('evaluatePluginsConfig', function () {
describe('evaluatePluginsConfig', () => {
let playerConfig, pluginsConfig, configEvaluator;
beforeEach(function () {

const updatedArrayValue = [1, 'value', 0, true, false];
const arrayValue = [...updatedArrayValue, '{{value}}'];

beforeEach(() => {
playerConfig = {
targetId: 'myTargetId',
provider: {
Expand All @@ -13,54 +17,125 @@ describe('evaluatePluginsConfig', function () {
};
pluginsConfig = {
kava: {
myHandler: function () {},
myHandler: () => {},
myUnevaluatedConfig: '{{abc}}',
myArray: [1, 'value', 0, true, '{{value}}', false]
myArray: arrayValue
}
};

configEvaluator = new ConfigEvaluator();
});

it('should save the function after evaluatePluginsConfig called', function () {
it('should save the function after evaluatePluginsConfig called', () => {
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myHandler.should.exist;
pluginsConfig.kava.myHandler.should.be.instanceof(Function);
});

it('should evaluate plugins config', function () {
it('should evaluate plugins config', () => {
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.partnerId.should.exist;
pluginsConfig.kava.partnerId.should.equal(1234);
});

it('should remove unevaluated plugins config', function () {
it('should remove unevaluated plugins config', () => {
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.should.not.have.property('myUnevaluatedConfig');
});

it('should remove unevaluated plugins config from array', function () {
it('should remove unevaluated plugins config from array', () => {
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.should.deep.equal(updatedArrayValue);
});

it('should handle class instances in plugin config', () => {
const map = new Map();

pluginsConfig.kava.myInstance = map;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myInstance.should.deep.equal(map);
});

it('should handle class instances inside array in plugin config', () => {
const map1 = new Map();
const map2 = new Map();
const instanceArrayValue = [map1, map2];

pluginsConfig.kava.myArray = instanceArrayValue;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.should.deep.equal(instanceArrayValue);
});

it('should handle functions arrays in plugin config', () => {
function function1() {}
function function2() {}
const functionArray = [function1, function2];

pluginsConfig.kava.myArray = [function1, function2];
pluginsConfig.kava.myArray.should.deep.equal(functionArray);
});

it('should handle object arrays in plugin config', () => {
const objectArrayValue = arrayValue.map(item => {
return {
value: item
};
});
pluginsConfig.kava.myArray = objectArrayValue;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.length.should.equal(updatedArrayValue.length);
});

it('should handle nested arrays inside object array in plugin config', () => {
const objectArrayValue = [
{
value: arrayValue
}
];

pluginsConfig.kava.myArray = objectArrayValue;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.length.should.equal(1);
pluginsConfig.kava.myArray[0].value.length.should.equal(updatedArrayValue.length);
});

it('should handle nested functions inside object array in plugin config', () => {
function function1() {}
function function2() {}
const functionArray = [function1, function2];

pluginsConfig.kava.myArray = functionArray;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.should.deep.equal(functionArray);
});

it('should handle nested class instances inside object array in plugin config', () => {
const map1 = new Map();
const map2 = new Map();
const instanceArrayValue = [map1, map2];

pluginsConfig.kava.myArray = instanceArrayValue;
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.myArray.should.deep.equal([1, 'value', 0, true, false]);
pluginsConfig.kava.myArray.should.deep.equal(instanceArrayValue);
});

it('should set playerVersion as productVersion from server', function () {
it('should set playerVersion as productVersion from server', () => {
window.__kalturaplayerdata = {productVersion: '7.43.1'};
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.should.have.property('playerVersion');
pluginsConfig.kava.playerVersion.should.equal('7.43.1');
});

it('should set playerVersion as playerVersion', function () {
it('should set playerVersion as playerVersion', () => {
window.__kalturaplayerdata = {};
configEvaluator.evaluatePluginsConfig(pluginsConfig, playerConfig);
pluginsConfig.kava.should.have.property('playerVersion');
pluginsConfig.kava.playerVersion.should.equal(__VERSION__);
});
});

describe('getEncodedReferrer', function () {
it('should encode the referrer', function () {
describe('getEncodedReferrer', () => {
it('should encode the referrer', () => {
sandbox.stub(window.parent.document, 'URL').get(() => {
return 'http://localhost:3000/?debugKalturaPlayer';
});
Expand Down

0 comments on commit 773171d

Please sign in to comment.