Skip to content

Commit

Permalink
[cascading] from release/11.2 to release/11.3 (#2447)
Browse files Browse the repository at this point in the history
<!--
{"currentBranch":"release/11.2","targetBranch":"release/11.3","bypassReviewers":true,"isConflicting":false}
-->

## Cascading from release/11.2 to release/11.3


The configuration requests the cascading to bypass reviewer in case of
CI success.
To not bypass the reviewing process, please check the following
checkbox:

- [ ] <!-- !cancel bypass! --> 🚫 stop reviewing process
bypass for this Pull Request




---

<small>This Pull Request has been generated with ❤️ by the
[Otter](https://github.com/AmadeusITGroup/otter) cascading tool.</small>
  • Loading branch information
matthieu-crouzet authored Nov 12, 2024
2 parents c686dc6 + 156b9b4 commit 2c094a7
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EffectsModule } from '@ngrx/effects';
import { select, Store, StoreModule } from '@ngrx/store';
import { computeItemIdentifier } from '@o3r/core';
import { BehaviorSubject, firstValueFrom, Observable, of, Subject } from 'rxjs';
import { distinctUntilChanged, map, take } from 'rxjs/operators';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { jsonOneRulesetOneRuleNoCondPlaceholder } from '../../../testing/mocks/oneruleset-onerule-nocond-placeholder.mock';
import { jsonOneRulesetOneRuleNoCond } from '../../../testing/mocks/oneruleset-onerule-nocond.mock';
import { jsonOneRulesetOneRuleReexecution } from '../../../testing/mocks/oneruleset-onerule-reexecution.mock';
Expand Down Expand Up @@ -100,15 +100,25 @@ describe('Rules engine service', () => {
expect(actions[0].actionType).toBe('UPDATE_LOCALISATION');
});

it('should handle linked components and validity range properly', (done) => {
service.events$.pipe(take(1)).subscribe((actions) => {
expect(actions.length).toBe(1);
expect(actions[0].actionType).toBe('UPDATE_LOCALISATION');
done();
});
it('should handle linked components and validity range properly', async () => {
store.dispatch(setRulesetsEntities({entities: jsonOneRulesetValidOneRuleNoCond.ruleSets}));
});
const actions = await firstValueFrom(service.events$);
expect(actions.length).toBe(1);
expect(actions[0].actionType).toBe('UPDATE_LOCALISATION');
expect(actions[0].value).toBe('my.custom.ssci.loc.key2');
service.enableRuleSetFor(computeItemIdentifier('TestComponent', '@otter/comps'));
const nextActions = await firstValueFrom(service.events$);
expect(nextActions.length).toBe(2);
expect(nextActions[1].actionType).toBe('UPDATE_LOCALISATION');
expect(nextActions[1].value).toBe('my.custom.ssci.loc.key3');
// out of range validity for ruleset linked to TestComponent2
service.enableRuleSetFor(computeItemIdentifier('TestComponent2', '@otter/comps'));
const lastActions = await firstValueFrom(service.events$);
expect(lastActions.length).toBe(2);
expect(lastActions[1].actionType).toBe('UPDATE_LOCALISATION');
expect(lastActions[1].value).toBe('my.custom.ssci.loc.key3');

});

it('should have configuration updated in the store', async () => {
service.engine.upsertFacts<any>([{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,31 @@ describe('RuleSets Selector tests', () => {
}
};

const r9: RulesetsModel = {
id: 'r9',
name: 'r9_name',
rules: [],
validityRange: {
from: afterTomorrow.toISOString()
},
linkedComponent: {
library: '@mylibrary',
name: 'thisComponentWillBeIgnored'
},
linkedComponents: {
or: [
{
library: '@mylibrary',
name: 'mycomponent'
},
{
library: '@mylibrary',
name: 'mycomponent2'
}
]
}
};

it('should return the ruleset in range', () => {
const state: RulesetsState = {
ids: [r1.id, r2.id],
Expand All @@ -110,8 +135,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r1']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r1']);
});

it('should return the rulest with no validity or on demand', () => {
Expand All @@ -124,8 +150,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r3']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r3']);
});

it('should exclude the one not in validity range', () => {
Expand All @@ -138,8 +165,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r3']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r3']);
});

it('should not find valid rulesets', () => {
Expand All @@ -152,8 +180,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual([]);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual([]);
});

it('should find a ruleset valid starting from a date in the past', () => {
Expand All @@ -167,8 +196,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r5']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r5']);
});

it('should find a ruleset valid until a date in the future', () => {
Expand All @@ -182,8 +212,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r6']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r6']);
});

it('should consider valid a ruleset with validity empty', () => {
Expand All @@ -197,8 +228,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual(['r7']);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual(['r7']);
});

it('onDemand should take precedence over validity', () => {
Expand All @@ -212,8 +244,9 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectActiveRuleSets.projector(allRuleSetsArray)).toEqual([]);
expect(selectors.selectActiveRuleSets.projector(rulesetsInRange)).toEqual([]);
});

it('should select the linked components rulesets', () => {
Expand All @@ -227,11 +260,13 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

const componentsWithRulesets = {
[computeItemIdentifier('mycomponent', '@mylibrary')]: [r2.id, r8.id],
[computeItemIdentifier('mycomponent2', '@mylibrary')]: [r8.id]
};
expect(selectors.selectRuleSetLinkComponents.projector(allRuleSetsArray)).toEqual(componentsWithRulesets);
expect(selectors.selectRuleSetLinkComponents.projector(rulesetsInRange)).toEqual(componentsWithRulesets);
});

it('should select the map of rulesets linked components', () => {
Expand All @@ -245,6 +280,8 @@ describe('RuleSets Selector tests', () => {
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

const comp2 = computeItemIdentifier('mycomponent2', '@mylibrary');
const comp = computeItemIdentifier('mycomponent', '@mylibrary');
const componentsWithRulesets = {
Expand All @@ -253,7 +290,56 @@ describe('RuleSets Selector tests', () => {
[r8.id]: [comp, comp2]
}
};
expect(selectors.selectComponentsLinkedToRuleset.projector(allRuleSetsArray)).toEqual(componentsWithRulesets);
expect(selectors.selectComponentsLinkedToRuleset.projector(rulesetsInRange)).toEqual(componentsWithRulesets);
});

it('should filter out the linked components rulesets outside the validity range', () => {
const state: RulesetsState = {
ids: [r9.id],
entities: {
'r9': r9
},
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectRuleSetLinkComponents.projector(rulesetsInRange)).toEqual({});
});

it('should filter out the map of rulesets linked components outside the validity range', () => {
const state: RulesetsState = {
ids: [r9.id],
entities: {
'r9': r9
},
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);
const rulesetsInRange = selectors.selectRuleSetsInRange.projector(allRuleSetsArray);

expect(selectors.selectComponentsLinkedToRuleset.projector(rulesetsInRange)).toEqual({ or: {} });
});

it('selectRuleSetsInRange should filter out rulesets outside of the validity range', () => {
const state: RulesetsState = {
ids: [r1.id, r2.id, r3.id, r4.id, r5.id, r6.id, r7.id, r8.id, r9.id],
entities: {
'r1': r1,
'r2': r2,
'r3': r3,
'r4': r4,
'r5': r5,
'r6': r6,
'r7': r7,
'r8': r8,
'r9': r9
},
requestIds: []
};
const allRuleSetsArray = selectors.selectAllRulesets.projector(state);

expect(selectors.selectRuleSetsInRange.projector(allRuleSetsArray)).toEqual([r1, r2, r3, r5, r6, r7, r8]);
});

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,11 @@ export const selectRulesetsStorePendingStatus = createSelector(selectRulesetsSta
const isValidDate = (d: any) => !isNaN(d) && d instanceof Date;

/**
* Returns only the rulesets ids which are not onDemand and in the validity range
* OnDemand takes precedence over validity range.
* Only if the ruleset is NOT onDemand (this means it is taken into consideration for the runs), the validity is checked
* Returns the rulesets which are in the validity range, if provided
*/
export const selectActiveRuleSets = createSelector(
export const selectRuleSetsInRange = createSelector(
selectAllRulesets,
(ruleSets) => ruleSets.filter((ruleSet: Ruleset) => {

if (ruleSet.linkedComponents?.or?.length || ruleSet.linkedComponent) {
return false;
}

const validity = ruleSet.validityRange;
if (!validity || !validity.from && !validity.to) {
return true;
Expand All @@ -62,13 +55,22 @@ export const selectActiveRuleSets = createSelector(
if (from) {
return from.getTime() <= time;
}

return to && to.getTime() >= time;
}).map((ruleSet: Ruleset) => ruleSet.id));
})
);

/*
/**
* Returns the rulesets ids which are not onDemand and in the validity range
*/
export const selectActiveRuleSets = createSelector(
selectRuleSetsInRange,
(ruleSets) => ruleSets
.filter((ruleSet: Ruleset) => (!(ruleSet.linkedComponents?.or?.length || ruleSet.linkedComponent)))
.map((ruleSet: Ruleset) => ruleSet.id));

/**
* Assign rulesetId to a component
* @deprecated; It will be rmeoved in v12 with the selector using it
* @deprecated It will be removed in v12 with the selector using it
*/
function linkRulesetToComponent(compName: string, library: string, ruleSetId: string, acc: Record<string, string[]> = {}) {
const configName = computeItemIdentifier(compName, library);
Expand All @@ -89,7 +91,7 @@ function linkComponentToRuleset(compName: string, library: string, ruleSetId: st
* @deprecated use {@link selectComponentsLinkedToRuleset} instead. It will be removed in v12
*/
export const selectRuleSetLinkComponents = createSelector(
selectAllRulesets,
selectRuleSetsInRange,
(ruleSets) =>
ruleSets
.reduce((acc: Record<string, string[]>, ruleSet: Ruleset) => {
Expand All @@ -113,7 +115,7 @@ export const selectRuleSetLinkComponents = createSelector(
* Select the map of ruleSets to activate based on linked components
*/
export const selectComponentsLinkedToRuleset = createSelector(
selectAllRulesets,
selectRuleSetsInRange,
(ruleSets) =>
ruleSets
.reduce((acc: {or: {[key: string]: string[]}}, ruleSet: Ruleset) => {
Expand All @@ -132,4 +134,3 @@ export const selectComponentsLinkedToRuleset = createSelector(
return acc;
}, {or: {}})
);

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export const jsonOneRulesetValidOneRuleNoCond : {ruleSets: Ruleset[]} = {
{
'id': 'e5th46e84-5e4th-54eth65seth46se8th2',
'name': 'the second ruleset',
'validityRange': {
'to': '2025-07-23T18:25:43.511Z'
},
'linkedComponent': {
'library': '@otter/comps',
'name': 'TestComponent'
Expand All @@ -50,7 +53,7 @@ export const jsonOneRulesetValidOneRuleNoCond : {ruleSets: Ruleset[]} = {
'elementType': 'ACTION',
'actionType': 'UPDATE_LOCALISATION',
'key': 'my.ssci.loc.key',
'value': 'my.custom.ssci.loc.key2'
'value': 'my.custom.ssci.loc.key3'
}
],
'failureElements': []
Expand All @@ -64,6 +67,10 @@ export const jsonOneRulesetValidOneRuleNoCond : {ruleSets: Ruleset[]} = {
'validityRange': {
'from': '2100-07-23T18:25:43.511Z'
},
'linkedComponent': {
'library': '@otter/comps',
'name': 'TestComponent2'
},
'rules': [
{
'id': '6e8t54h6s4e-6erth46sre8th4-d46t8s13t5j1',
Expand Down

0 comments on commit 2c094a7

Please sign in to comment.