Skip to content

Commit

Permalink
feat: refacto actionList
Browse files Browse the repository at this point in the history
runActionlist now takes array of values as input and return array of values

Co-authored-by: emile <[email protected]>
  • Loading branch information
TdyP and evoiron authored Apr 22, 2024
1 parent 4e955b1 commit 8e5f6dc
Show file tree
Hide file tree
Showing 69 changed files with 2,256 additions and 6,162 deletions.
2 changes: 1 addition & 1 deletion apps/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"benchmark": "ts-node src/ benchmark",
"build": "scripts/build.js",
"tscheck": "tsc --noEmit -p .",
"tscheck:watch": "tsc -w --noEmit -p ."
"tscheck:watch": "tsc -w --noEmit -p tsconfig.json"
},
"main": "dist/index.js",
"author": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ describe('inheritanceCalculationAction', () => {
${simpleAttributeId}: property(attribute: "${simpleAttributeId}") {
...on Value {
value
isInherited
}
}
}
Expand All @@ -198,7 +199,9 @@ describe('inheritanceCalculationAction', () => {

expect(res.data.errors).toBeUndefined();
expect(res.status).toBe(200);
expect(res.data.data.records.list[0][simpleAttributeId][0].value).toBe('text value');

const inheritedValue = res.data.data.records.list[0][simpleAttributeId].find(v => v.isInherited);
expect(inheritedValue.value).toBe('text value');
});

test('Inherit values on advanced attribute', async () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/core/src/__tests__/e2e/api/trees/trees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ describe('Trees', () => {

expect(res.status).toBe(200);
expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeTruthy();
expect(res.data.data.saveValue.value.record.id).toBe(recordId1);
expect(res.data.data.saveValue[0].id_value).toBeTruthy();
expect(res.data.data.saveValue[0].value.record.id).toBe(recordId1);

// Get values of this attribute
const resGetValues = await makeGraphQlCall(`{
Expand Down
5 changes: 2 additions & 3 deletions apps/core/src/__tests__/e2e/api/values/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {gqlCreateRecord, gqlSaveAttribute, gqlSaveLibrary, makeGraphQlCall} from

describe('Values Metadata', () => {
const metadataLibId = 'metadata_test_lib';
const metadataLibGqlId = 'metadataTestLib';
const metaAttrId = 'metadata_simple_attribute';
const attrWithMetaId = 'metadata_attribute';
let recordId;
Expand Down Expand Up @@ -54,8 +53,8 @@ describe('Values Metadata', () => {

expect(resSaveValue.status).toBe(200);
expect(resSaveValue.data.errors).toBeUndefined();
expect(resSaveValue.data.data.saveValue.id_value).toBeDefined();
expect(resSaveValue.data.data.saveValue.metadata.find(({name}) => name === metaAttrId)).toBeDefined();
expect(resSaveValue.data.data.saveValue[0].id_value).toBeDefined();
expect(resSaveValue.data.data.saveValue[0].metadata.find(({name}) => name === metaAttrId)).toBeDefined();

// Read value
const queryGetVal = `{
Expand Down
44 changes: 22 additions & 22 deletions apps/core/src/__tests__/e2e/api/values/values.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeTruthy();
expect(res.data.data.saveValue.value.record.id).toBe(treeElemId);
expect(res.data.data.saveValue[0].id_value).toBeTruthy();
expect(res.data.data.saveValue[0].value.record.id).toBe(treeElemId);
});

test('Save value simple', async () => {
Expand All @@ -265,9 +265,9 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeNull();
expect(res.data.data.saveValue.attribute?.permissions.edit_value).toBeDefined();
expect(res.data.data.saveValue.value).toBe('TEST VAL');
expect(res.data.data.saveValue[0].id_value).toBeNull();
expect(res.data.data.saveValue[0].attribute?.permissions.edit_value).toBeDefined();
expect(res.data.data.saveValue[0].value).toBe('TEST VAL');
});

test('Save same value on unique attribute', async () => {
Expand Down Expand Up @@ -335,8 +335,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeNull();
expect(res.data.data.saveValue.value).toBeTruthy();
expect(res.data.data.saveValue[0].id_value).toBeNull();
expect(res.data.data.saveValue[0].value).toBeTruthy();
});

test("Don't save invalid simple extended", async () => {
Expand Down Expand Up @@ -385,8 +385,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeNull();
expect(res.data.data.saveValue.value.id).toBe(recordIdLinked);
expect(res.data.data.saveValue[0].id_value).toBeNull();
expect(res.data.data.saveValue[0].value.id).toBe(recordIdLinked);
});

test('Save value advanced', async () => {
Expand All @@ -407,10 +407,10 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeTruthy();
expect(res.data.data.saveValue.value).toBe('TEST VAL ADV');
expect(res.data.data.saveValue[0].id_value).toBeTruthy();
expect(res.data.data.saveValue[0].value).toBe('TEST VAL ADV');

advValueId = res.data.data.saveValue.id_value;
advValueId = res.data.data.saveValue[0].id_value;
});

test('Save value advanced link', async () => {
Expand All @@ -433,8 +433,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeTruthy();
expect(res.data.data.saveValue.value.id).toBe(recordIdLinked);
expect(res.data.data.saveValue[0].id_value).toBeTruthy();
expect(res.data.data.saveValue[0].value.id).toBe(recordIdLinked);
});

test('Save value advanced reverse link', async () => {
Expand All @@ -457,8 +457,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeTruthy();
expect(res.data.data.saveValue.value.id).toBe(recordIdLinked);
expect(res.data.data.saveValue[0].id_value).toBeTruthy();
expect(res.data.data.saveValue[0].value.id).toBe(recordIdLinked);
});

test('Save value advanced reverse link into simple link', async () => {
Expand All @@ -481,8 +481,8 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.id_value).toBeFalsy();
expect(res.data.data.saveValue.value.id).toBe(recordIdLinked);
expect(res.data.data.saveValue[0].id_value).toBeFalsy();
expect(res.data.data.saveValue[0].value.id).toBe(recordIdLinked);
});

test('Delete value advanced', async () => {
Expand All @@ -497,7 +497,7 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.deleteValue.id_value).toBeTruthy();
expect(res.data.data.deleteValue[0].id_value).toBeTruthy();
});

test('Delete value simple', async () => {
Expand All @@ -524,7 +524,7 @@ describe('Values', () => {
}
}`);

const idValue = saveValueRes.data.data.saveValue.id_value;
const idValue = saveValueRes.data.data.saveValue[0].id_value;

const res = await makeGraphQlCall(`mutation {
deleteValue(
Expand All @@ -537,7 +537,7 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.deleteValue.id_value).toBeTruthy();
expect(res.data.data.deleteValue[0].id_value).toBeTruthy();
});

test('Save value batch', async () => {
Expand Down Expand Up @@ -596,7 +596,7 @@ describe('Values', () => {
expect(res.status).toBe(200);

expect(res.data.errors).toBeUndefined();
expect(res.data.data.saveValue.value).toEqual({
expect(res.data.data.saveValue[0].value).toEqual({
from: '1970-01-01T00:16:40+00:00',
to: '1970-01-01T00:33:20+00:00'
});
Expand Down
6 changes: 3 additions & 3 deletions apps/core/src/__tests__/e2e/api/values/versions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ describe('Versions', () => {

expect(resSaveValue.status).toBe(200);
expect(resSaveValue.data.errors).toBeUndefined();
expect(resSaveValue.data.data.v1.version).toBeDefined();
expect(resSaveValue.data.data.v1.version[0].treeId).toBe(treeName);
expect(resSaveValue.data.data.v1.version[0].treeNode.id).toBe(nodeElement1);
expect(resSaveValue.data.data.v1[0].version).toBeDefined();
expect(resSaveValue.data.data.v1[0].version[0].treeId).toBe(treeName);
expect(resSaveValue.data.data.v1[0].version[0].treeNode.id).toBe(nodeElement1);

const resGetValues1 = await makeGraphQlCall(`{
r1: records(
Expand Down
13 changes: 11 additions & 2 deletions apps/core/src/_types/actionsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {IQueryInfos} from '_types/queryInfos';
import {IAttribute} from './attribute';
import {ISystemTranslation} from './systemTranslation';
import {IValue} from './value';
import {Errors} from './errors';

export enum ActionsListEvents {
SAVE_VALUE = 'saveValue',
Expand Down Expand Up @@ -46,6 +47,11 @@ export interface IActionsListParamsConfig {
default_value: string;
}

export interface IActionsListFunctionResult {
values: IValue[];
errors: Array<{errorType: Errors; attributeValue: IValue; message?: string}>;
}

export interface IActionsListFunction {
id: string;
name: string;
Expand All @@ -54,7 +60,11 @@ export interface IActionsListFunction {
output_types: ActionsListIOTypes[];
params?: IActionsListParamsConfig[];
error_message?: ISystemTranslation;
action: (value: ActionsListValueType, params: IActionsListParams, ctx: IActionsListContext) => ActionsListValueType;
action: (
values: IValue[],
params: IActionsListParams,
ctx: IActionsListContext
) => IActionsListFunctionResult | Promise<IActionsListFunctionResult>;
}

export interface IActionsListSavedAction {
Expand All @@ -69,5 +79,4 @@ export interface IRunActionsListCtx extends IQueryInfos {
attribute?: IAttribute;
recordId?: string;
library?: string;
value?: IValue;
}
2 changes: 2 additions & 0 deletions apps/core/src/_types/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum Errors {
ELEMENT_ALREADY_PRESENT_IN_ANCESTORS = 'ELEMENT_ALREADY_PRESENT_IN_ANCESTORS',
ELEMENT_NOT_IN_TREE = 'ELEMENT_NOT_IN_TREE',
ELEMENT_WITH_SAME_PATH_ALREADY_PRESENT = 'ELEMENT_WITH_SAME_PATH_ALREADY_PRESENT',
ENCRYPT_ERROR = 'ENCRYPT_ERROR',
ERROR = 'ERROR',
EXCEL_CALCULATION_ERROR = 'EXCEL_CALCULATION_ERROR',
FILE_ERROR = 'FILE_ERROR',
Expand All @@ -41,6 +42,7 @@ export enum Errors {
INVALID_ID_FORMAT = 'INVALID_ID_FORMAT',
INVALID_MAPPING = 'INVALID_MAPPING',
INVALID_PERMISSIONS_CONF_LIBRARIES = 'INVALID_PERMISSIONS_CONF_LIBRARIES',
INVALID_REGEXP = 'INVALID_REGEXP',
INVALID_SORT_FIELDS = 'INVALID_SORT_FIELDS',
INVALID_TREE_FILTER_FORMAT = 'INVALID_TREE_FILTER_FORMAT',
INVALID_URL = 'INVALID_URL',
Expand Down
2 changes: 1 addition & 1 deletion apps/core/src/app/auth/authApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface IDeps {
config?: IConfig;
}

export default function ({
export default function({
'core.domain.value': valueDomain = null,
'core.domain.record': recordDomain = null,
'core.domain.apiKey': apiKeyDomain = null,
Expand Down
1 change: 1 addition & 0 deletions apps/core/src/app/core/attributeApp/attributeApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export default function (deps: IDeps = {}): ICoreAttributeApp {
type: AttributeType!,
format: AttributeFormat,
system: Boolean!,
required: Boolean!,
readonly: Boolean!,
label(lang: [AvailableLanguage!]): SystemTranslation,
description(lang: [AvailableLanguage!]): SystemTranslationOptional,
Expand Down
12 changes: 6 additions & 6 deletions apps/core/src/app/core/valueApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default function ({
extend type Mutation {
# Save one value
saveValue(library: ID, recordId: ID, attribute: ID, value: ValueInput): GenericValue!
saveValue(library: ID, recordId: ID, attribute: ID, value: ValueInput): [GenericValue!]!
# Save values for several attributes at once.
# If deleteEmpty is true, empty values will be deleted
Expand All @@ -205,26 +205,26 @@ export default function ({
deleteEmpty: Boolean
): saveValueBatchResult!
deleteValue(library: ID!, recordId: ID!, attribute: ID!, value: ValueInput): GenericValue!
deleteValue(library: ID!, recordId: ID!, attribute: ID!, value: ValueInput): [GenericValue!]!
}
`,
resolvers: {
Mutation: {
async saveValue(_, {library, recordId, attribute, value}, ctx): Promise<IValue> {
async saveValue(_: never, {library, recordId, attribute, value}, ctx): Promise<IValue[]> {
const valToSave = {
...value,
version: convertVersionFromGqlFormat(value.version),
metadata: utils.nameValArrayToObj(value.metadata)
};
const savedVal = await valueDomain.saveValue({
const savedValues = await valueDomain.saveValue({
library,
recordId,
attribute,
value: valToSave,
ctx
});

return {...savedVal};
return savedValues;
},
async saveValueBatch(parent, {library, recordId, version, values, deleteEmpty}, ctx) {
// Convert version
Expand Down Expand Up @@ -256,7 +256,7 @@ export default function ({

return res;
},
async deleteValue(parent, {library, recordId, attribute, value}, ctx): Promise<IValue> {
async deleteValue(_: never, {library, recordId, attribute, value}, ctx): Promise<IValue[]> {
return valueDomain.deleteValue({
library,
recordId,
Expand Down
42 changes: 37 additions & 5 deletions apps/core/src/domain/actions/dateRangeToNumberAction.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright LEAV Solutions 2017
// This file is released under LGPL V3
// License text available at https://www.gnu.org/licenses/lgpl-3.0.txt
import {mockStandardValue} from '../../__tests__/mocks/value';
import {AttributeFormats, AttributeTypes, IAttribute} from '../../_types/attribute';
import dateRangeToNumberAction from './dateRangeToNumberAction';

Expand All @@ -9,10 +10,41 @@ describe('dateRangeToNumberAction', () => {
const attrText: IAttribute = {id: 'test_attr', format: AttributeFormats.DATE_RANGE, type: AttributeTypes.SIMPLE};
const ctx = {attribute: attrText};
test('dateRangeToNumberAction', async () => {
expect(action({from: 12345, to: 12346}, {}, ctx)).toEqual({from: 12345, to: 12346});
expect(action({from: '12345', to: '12346'}, {}, ctx)).toEqual({from: 12345, to: 12346});
expect(action({to: '12346'}, {}, ctx)).toEqual({from: 0, to: 12346});
expect(action({from: '12345'}, {}, ctx)).toEqual({from: 12345, to: 0});
expect(action('bad value', {}, ctx)).toEqual({from: 0, to: 0});
expect(action([{...mockStandardValue, value: {from: 12345, to: 12346}}], {}, ctx)).toEqual({
errors: [],
values: [{...mockStandardValue, value: {from: 12345, to: 12346}}]
});
expect(
action(
[
{...mockStandardValue, value: {from: 12345, to: 12346}},
{...mockStandardValue, value: {from: 654321, to: 654320}}
],
{},
ctx
)
).toEqual({
errors: [],
values: [
{...mockStandardValue, value: {from: 12345, to: 12346}},
{...mockStandardValue, value: {from: 654321, to: 654320}}
]
});
expect(action([{...mockStandardValue, value: {from: '12345', to: '12346'}}], {}, ctx)).toEqual({
errors: [],
values: [{...mockStandardValue, value: {from: 12345, to: 12346}}]
});
expect(action([{...mockStandardValue, value: {to: '12346'}}], {}, ctx)).toEqual({
errors: [],
values: [{...mockStandardValue, value: {from: 0, to: 12346}}]
});
expect(action([{...mockStandardValue, value: {from: '12345'}}], {}, ctx)).toEqual({
errors: [],
values: [{...mockStandardValue, value: {from: 12345, to: 0}}]
});
expect(action([{...mockStandardValue, value: 'bad value'}], {}, ctx)).toEqual({
errors: [],
values: [{...mockStandardValue, value: {from: 0, to: 0}}]
});
});
});
Loading

0 comments on commit 8e5f6dc

Please sign in to comment.