mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
fix: add sort to deep diff (#5084)
Sort array items before running compare. Feature flag certain properties of strategy that were previously not present in the /api/admin/features endpoint.
This commit is contained in:
parent
1f8d12bcdc
commit
cd864ed09e
@ -123,6 +123,8 @@
|
||||
"knex": "^2.4.2",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.groupby": "^4.6.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.sortby": "^4.7.0",
|
||||
"log4js": "^6.0.0",
|
||||
"make-fetch-happen": "^11.0.0",
|
||||
"memoizee": "^0.4.15",
|
||||
|
@ -49,7 +49,12 @@ export const createStores = (
|
||||
|
||||
return {
|
||||
eventStore,
|
||||
featureToggleStore: new FeatureToggleStore(db, eventBus, getLogger),
|
||||
featureToggleStore: new FeatureToggleStore(
|
||||
db,
|
||||
eventBus,
|
||||
getLogger,
|
||||
config.flagResolver,
|
||||
),
|
||||
featureTypeStore: new FeatureTypeStore(db, getLogger),
|
||||
strategyStore: new StrategyStore(db, getLogger),
|
||||
clientApplicationsStore: new ClientApplicationsStore(
|
||||
|
@ -157,6 +157,7 @@ export const deferredExportImportTogglesService = (
|
||||
db,
|
||||
eventBus,
|
||||
getLogger,
|
||||
flagResolver,
|
||||
);
|
||||
const tagStore = new TagStore(db, eventBus, getLogger);
|
||||
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
|
||||
|
@ -5,12 +5,19 @@ import {
|
||||
FeatureToggle,
|
||||
IFeatureToggleQuery,
|
||||
ITag,
|
||||
IFlagResolver,
|
||||
} from '../../../types';
|
||||
|
||||
import { mapValues, ensureStringValue } from '../../../util';
|
||||
import { FeatureConfigurationClient } from '../types/feature-toggle-strategies-store-type';
|
||||
|
||||
export class FeatureToggleRowConverter {
|
||||
private flagResolver: IFlagResolver;
|
||||
|
||||
constructor(flagResolver: IFlagResolver) {
|
||||
this.flagResolver = flagResolver;
|
||||
}
|
||||
|
||||
isUnseenStrategyRow = (
|
||||
feature: PartialDeep<IFeatureToggleClient>,
|
||||
row: Record<string, any>,
|
||||
@ -63,15 +70,27 @@ export class FeatureToggleRowConverter {
|
||||
};
|
||||
|
||||
rowToStrategy = (row: Record<string, any>): IStrategyConfig => {
|
||||
const strategy: IStrategyConfig = {
|
||||
id: row.strategy_id,
|
||||
name: row.strategy_name,
|
||||
title: row.strategy_title,
|
||||
constraints: row.constraints || [],
|
||||
parameters: mapValues(row.parameters || {}, ensureStringValue),
|
||||
sortOrder: row.sort_order,
|
||||
disabled: row.strategy_disabled,
|
||||
};
|
||||
let strategy: IStrategyConfig;
|
||||
if (this.flagResolver.isEnabled('playgroundImprovements')) {
|
||||
strategy = {
|
||||
id: row.strategy_id,
|
||||
name: row.strategy_name,
|
||||
title: row.strategy_title,
|
||||
constraints: row.constraints || [],
|
||||
parameters: mapValues(row.parameters || {}, ensureStringValue),
|
||||
sortOrder: row.sort_order,
|
||||
disabled: row.strategy_disabled,
|
||||
};
|
||||
} else {
|
||||
strategy = {
|
||||
id: row.strategy_id,
|
||||
name: row.strategy_name,
|
||||
constraints: row.constraints || [],
|
||||
parameters: mapValues(row.parameters || {}, ensureStringValue),
|
||||
sortOrder: row.sort_order,
|
||||
};
|
||||
}
|
||||
|
||||
strategy.variants = row.strategy_variants || [];
|
||||
return strategy;
|
||||
};
|
||||
|
@ -64,7 +64,12 @@ export const createFeatureToggleService = (
|
||||
getLogger,
|
||||
flagResolver,
|
||||
);
|
||||
const featureToggleStore = new FeatureToggleStore(db, eventBus, getLogger);
|
||||
const featureToggleStore = new FeatureToggleStore(
|
||||
db,
|
||||
eventBus,
|
||||
getLogger,
|
||||
flagResolver,
|
||||
);
|
||||
const featureToggleClientStore = new FeatureToggleClientStore(
|
||||
db,
|
||||
eventBus,
|
||||
|
@ -1,3 +1,5 @@
|
||||
import sortBy from 'lodash.sortby';
|
||||
|
||||
interface Difference {
|
||||
index: (string | number)[];
|
||||
reason: string;
|
||||
@ -18,8 +20,11 @@ export function deepDiff(arr1: any[], arr2: any[]): Difference[] | null {
|
||||
valueB: b,
|
||||
});
|
||||
} else {
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
compare(a[i], b[i], parentIndex.concat(i));
|
||||
const sortedA = sortBy(a, 'name');
|
||||
const sortedB = sortBy(b, 'name');
|
||||
|
||||
for (let i = 0; i < sortedA.length; i++) {
|
||||
compare(sortedA[i], sortedB[i], parentIndex.concat(i));
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
@ -31,7 +36,10 @@ export function deepDiff(arr1: any[], arr2: any[]): Difference[] | null {
|
||||
const keysA = Object.keys(a);
|
||||
const keysB = Object.keys(b);
|
||||
|
||||
if (!arraysEqual(keysA, keysB)) {
|
||||
if (
|
||||
keysA.length !== keysB.length ||
|
||||
!keysA.every((key) => keysB.includes(key))
|
||||
) {
|
||||
diff.push({
|
||||
index: parentIndex,
|
||||
reason: 'Different keys',
|
||||
@ -53,13 +61,6 @@ export function deepDiff(arr1: any[], arr2: any[]): Difference[] | null {
|
||||
}
|
||||
}
|
||||
|
||||
function arraysEqual(a: any[], b: any[]): boolean {
|
||||
return (
|
||||
a.length === b.length &&
|
||||
a.sort().every((val, index) => val === b.sort()[index])
|
||||
);
|
||||
}
|
||||
|
||||
compare(arr1, arr2, []);
|
||||
|
||||
return diff.length > 0 ? diff : null;
|
||||
|
@ -64,10 +64,19 @@ export default class FeatureToggleStore implements IFeatureToggleStore {
|
||||
|
||||
private featureToggleRowConverter: FeatureToggleRowConverter;
|
||||
|
||||
constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) {
|
||||
private flagResolver: IFlagResolver;
|
||||
|
||||
constructor(
|
||||
db: Db,
|
||||
eventBus: EventEmitter,
|
||||
getLogger: LogProvider,
|
||||
flagResolver: IFlagResolver,
|
||||
) {
|
||||
this.db = db;
|
||||
this.logger = getLogger('feature-toggle-store.ts');
|
||||
this.featureToggleRowConverter = new FeatureToggleRowConverter();
|
||||
this.featureToggleRowConverter = new FeatureToggleRowConverter(
|
||||
flagResolver,
|
||||
);
|
||||
this.timer = (action) =>
|
||||
metricsHelper.wrapTimer(eventBus, DB_TIME, {
|
||||
store: 'feature-toggle',
|
||||
|
@ -1,6 +1,24 @@
|
||||
import { deepDiff } from '../deep-diff'; // Import the deepDiff function
|
||||
|
||||
describe('deepDiff', () => {
|
||||
test('should sort arrays by name before comparing', () => {
|
||||
// Define two arrays that are identical except for the order of elements
|
||||
const array1 = [
|
||||
{ name: 'b', value: 2 },
|
||||
{ name: 'a', value: 1 },
|
||||
];
|
||||
const array2 = [
|
||||
{ name: 'a', value: 1 },
|
||||
{ name: 'b', value: 2 },
|
||||
];
|
||||
|
||||
// If the function correctly sorts before comparing, there should be no differences
|
||||
const result = deepDiff(array1, array2);
|
||||
|
||||
// Assert that there is no difference
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null for equal arrays', () => {
|
||||
const arr1 = [1, 2, 3];
|
||||
const arr2 = [1, 2, 3];
|
||||
|
@ -57,7 +57,12 @@ export const createProjectService = (
|
||||
flagResolver,
|
||||
);
|
||||
const groupStore = new GroupStore(db);
|
||||
const featureToggleStore = new FeatureToggleStore(db, eventBus, getLogger);
|
||||
const featureToggleStore = new FeatureToggleStore(
|
||||
db,
|
||||
eventBus,
|
||||
getLogger,
|
||||
flagResolver,
|
||||
);
|
||||
const featureTypeStore = new FeatureTypeStore(db, getLogger);
|
||||
const accountStore = new AccountStore(db, getLogger);
|
||||
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
|
||||
|
@ -19,6 +19,7 @@ export const createLastSeenService = (
|
||||
db,
|
||||
config.eventBus,
|
||||
config.getLogger,
|
||||
config.flagResolver,
|
||||
);
|
||||
|
||||
return new LastSeenService({ lastSeenStore, featureToggleStore }, config);
|
||||
|
Loading…
Reference in New Issue
Block a user