Skip to content

Commit

Permalink
fix(settings): fix merge logic for plugins update in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ananas7 committed Apr 12, 2024
1 parent b50c8a8 commit 69bc458
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 3 deletions.
76 changes: 75 additions & 1 deletion src/libs/settings/__tests__/settings.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {ChartKitPlugin} from 'src/types';

import {settings} from '../settings';

const resetSettings = () => settings.set({lang: 'en'});
const resetSettings = () => settings.set({lang: 'en', plugins: []});

describe('libs/settings', () => {
it('Default lang should be equal to en', () => {
Expand All @@ -18,6 +20,78 @@ describe('libs/settings', () => {
expect(result).toBe('ru');
});

// Order test is important because settings module is singleton
it('Update plugins when it is empty', () => {
const initialPlugins: ChartKitPlugin[] = [
{
type: 'highcharts',
renderer: 'highchartsInitial' as any,

Check warning on line 28 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
{
type: 'd3',
renderer: 'd3Initial' as any,

Check warning on line 32 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
];

settings.set({
plugins: initialPlugins,
});

expect(settings.get('plugins')).toEqual(initialPlugins);
});

it('Update existing plugin d3', () => {
settings.set({
plugins: [
{
type: 'd3',
renderer: 'd3Update' as any,

Check warning on line 48 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
],
});

const result = settings.get('plugins');

expect(result).toEqual([
{
type: 'highcharts',
renderer: 'highchartsInitial' as any,

Check warning on line 58 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
{
type: 'd3',
renderer: 'd3Update' as any,

Check warning on line 62 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
]);
});

it('Add new plugin', () => {
settings.set({
plugins: [
{
type: 'yagr',
renderer: 'yagrUpdate' as any,

Check warning on line 72 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
],
});

const result = settings.get('plugins');

expect(result).toEqual([
{
type: 'highcharts',
renderer: 'highchartsInitial' as any,

Check warning on line 82 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
{
type: 'd3',
renderer: 'd3Update' as any,

Check warning on line 86 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
{
type: 'yagr',
renderer: 'yagrUpdate' as any,

Check warning on line 90 in src/libs/settings/__tests__/settings.test.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
},
]);
});

beforeAll(resetSettings);
afterEach(resetSettings);
});
40 changes: 40 additions & 0 deletions src/libs/settings/mergeSettingStrategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import isObject from 'lodash/isObject';
import mergeWith from 'lodash/mergeWith';

import {ChartKitPlugin} from 'src/types';

export function mergeSettingStrategy(objValue: any, srcValue: any, key: string): any {
if (key === 'plugins') {
const currentPlugins: ChartKitPlugin[] = [...objValue];
const newPlugins: ChartKitPlugin[] = [...srcValue];
// modify existing plugins
let newSettingsPlugins = currentPlugins.map((currentPlugin) => {
const newPluginIndex = newPlugins.findIndex(({type}) => type === currentPlugin.type);

if (newPluginIndex !== -1) {
const newPlugin = newPlugins[newPluginIndex];
newPlugins.splice(newPluginIndex, 1);

return {
type: currentPlugin.type,
renderer: newPlugin.renderer,
};
}

return currentPlugin;
});

// add new plugins if it exist after modified
if (newPlugins.length > 0) {
newSettingsPlugins = [...newSettingsPlugins, ...newPlugins];
}

return newSettingsPlugins;
}

if (isObject(objValue)) {
return mergeWith(objValue, srcValue, mergeSettingStrategy);
}

return srcValue;
}
5 changes: 3 additions & 2 deletions src/libs/settings/settings.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {configure} from '@gravity-ui/uikit';
import get from 'lodash/get';
import merge from 'lodash/merge';
import mergeWith from 'lodash/mergeWith';

import {i18nFactory} from '../../i18n';
import type {ChartKitHolidays, ChartKitLang, ChartKitPlugin} from '../../types';

import {EventEmitter} from './eventEmitter';
import {mergeSettingStrategy} from './mergeSettingStrategy';

interface Settings {
plugins: ChartKitPlugin[];
Expand Down Expand Up @@ -54,7 +55,7 @@ class ChartKitSettings {
set(updates: Partial<Settings>) {
const filteredUpdates = removeUndefinedValues(updates);

this.settings = merge(this.settings, filteredUpdates);
this.settings = mergeWith(this.settings, filteredUpdates, mergeSettingStrategy);

if (filteredUpdates.lang) {
const lang = filteredUpdates.lang || this.get('lang');
Expand Down

0 comments on commit 69bc458

Please sign in to comment.