mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
AAE-22222 Fix JSON path doesn't work for square bracekts (#9611)
* AAE-22222 Fix JSON path doesn't work for square bracekts * remove comment * remove test description duplications * remove duplications
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
mockCountriesIncorrectData,
|
||||
mockInvalidSchemaDefinition,
|
||||
mockSchemaDefinition
|
||||
} from '../../../mocks/data-table-widget.mock';
|
||||
} from './mocks/data-table-widget.mock';
|
||||
import { ObjectDataRow } from '@alfresco/adf-core';
|
||||
|
||||
describe('WidgetDataTableAdapter', () => {
|
||||
|
@@ -35,7 +35,7 @@ import {
|
||||
mockJsonResponseFormVariable,
|
||||
mockJsonNestedResponseFormVariable,
|
||||
mockJsonNestedResponseEuropeCountriesData
|
||||
} from '../../../mocks/data-table-widget.mock';
|
||||
} from './mocks/data-table-widget.mock';
|
||||
|
||||
describe('DataTableWidgetComponent', () => {
|
||||
let widget: DataTableWidgetComponent;
|
||||
|
@@ -16,12 +16,7 @@
|
||||
*/
|
||||
|
||||
import { DataTablePathParserHelper } from './data-table-path-parser.helper';
|
||||
import {
|
||||
mockEuropeCountriesData,
|
||||
mockJsonNestedResponseEuropeCountriesDataWithSeparatorInPropertyName,
|
||||
mockJsonNestedResponseEuropeCountriesDataWithMultipleSpecialCharacters,
|
||||
mockJsonNestedResponseEuropeCountriesData
|
||||
} from '../../../../mocks/data-table-widget.mock';
|
||||
import { mockResponseResultData, mockResultData } from '../mocks/data-table-path-parser.helper.mock';
|
||||
|
||||
describe('DataTablePathParserHelper', () => {
|
||||
let helper: DataTablePathParserHelper;
|
||||
@@ -30,59 +25,89 @@ describe('DataTablePathParserHelper', () => {
|
||||
helper = new DataTablePathParserHelper();
|
||||
});
|
||||
|
||||
it('should return the correct data for path with separator in nested brackets', () => {
|
||||
const data = mockJsonNestedResponseEuropeCountriesDataWithSeparatorInPropertyName;
|
||||
const path = 'response.[my.data].[country[data].country]';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(mockEuropeCountriesData);
|
||||
});
|
||||
describe('should return the correct data for path', () => {
|
||||
const testCases = [
|
||||
{
|
||||
description: 'not existent',
|
||||
data: {},
|
||||
path: 'nonexistent.path',
|
||||
expected: []
|
||||
},
|
||||
{
|
||||
description: 'nested',
|
||||
data: { level1: { level2: { level3: { level4: ['parrot', 'fish'] } } } },
|
||||
propertyName: 'level4',
|
||||
path: 'level1.level2.level3.level4',
|
||||
expected: ['parrot', 'fish']
|
||||
},
|
||||
{
|
||||
description: 'NOT nested',
|
||||
data: { pets: ['cat', 'dog'] },
|
||||
propertyName: 'pets',
|
||||
path: 'pets',
|
||||
expected: ['cat', 'dog']
|
||||
},
|
||||
{
|
||||
description: 'NOT nested with separator (.) in property name',
|
||||
data: { 'my.pets': ['cat', 'dog'] },
|
||||
propertyName: 'my.pets',
|
||||
path: '[my.pets]',
|
||||
expected: ['cat', 'dog']
|
||||
},
|
||||
{
|
||||
description: 'with nested brackets followed by an additional part of property name',
|
||||
propertyName: 'file.file[data]file',
|
||||
path: 'response.[file.file[data]file]'
|
||||
},
|
||||
{
|
||||
description: 'with nested brackets',
|
||||
propertyName: 'file.file[data]',
|
||||
path: 'response.[file.file[data]]'
|
||||
},
|
||||
{
|
||||
description: 'with separator before nested brackets in property name',
|
||||
propertyName: 'file.[data]file',
|
||||
path: 'response.[file.[data]file]'
|
||||
},
|
||||
{
|
||||
description: 'with separator before and no separator after nested brackets in property name',
|
||||
propertyName: 'file.[data]',
|
||||
path: 'response.[file.[data]]'
|
||||
},
|
||||
{
|
||||
description: 'with separator after nested brackets',
|
||||
propertyName: 'file[data].file',
|
||||
path: 'response.[file[data].file]'
|
||||
},
|
||||
{
|
||||
description: 'with multiple brackets in property name',
|
||||
propertyName: 'file.file[data]file[data]',
|
||||
path: 'response.[file.file[data]file[data]]'
|
||||
},
|
||||
{
|
||||
description: 'with special characters except separator (.) in brackets',
|
||||
propertyName: 'xyz:abc,xyz-abc,xyz_abc,abc+xyz',
|
||||
path: 'response.[xyz:abc,xyz-abc,xyz_abc,abc+xyz]'
|
||||
},
|
||||
{
|
||||
description: 'with special characters except separator (.) without brackets',
|
||||
propertyName: 'xyz:abc,xyz-abc,xyz_abc,abc+xyz',
|
||||
path: 'response.xyz:abc,xyz-abc,xyz_abc,abc+xyz'
|
||||
},
|
||||
{
|
||||
description: 'without separator in brackets',
|
||||
propertyName: 'my-data',
|
||||
path: '[response].[my-data]'
|
||||
}
|
||||
];
|
||||
|
||||
it('should return the correct data for path with special characters except separator (.) in brackets', () => {
|
||||
const data = mockJsonNestedResponseEuropeCountriesDataWithMultipleSpecialCharacters;
|
||||
const path = 'response.[xyz:abc,xyz-abc,xyz_abc,abc+xyz]';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(mockEuropeCountriesData);
|
||||
});
|
||||
|
||||
it('should return the correct data for path with special characters except separator (.) without brackets', () => {
|
||||
const data = mockJsonNestedResponseEuropeCountriesDataWithMultipleSpecialCharacters;
|
||||
const path = 'response.xyz:abc,xyz-abc,xyz_abc,abc+xyz';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(mockEuropeCountriesData);
|
||||
});
|
||||
|
||||
it('should return the correct data for path without separator in brackets', () => {
|
||||
const data = mockJsonNestedResponseEuropeCountriesData;
|
||||
const path = '[response].[my-data]';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(mockEuropeCountriesData);
|
||||
});
|
||||
|
||||
it('should return an empty array if the path does not exist in the data', () => {
|
||||
const data = {};
|
||||
const path = 'nonexistent.path';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return the correct data if the path is nested', () => {
|
||||
const data = { level1: { level2: { level3: { level4: ['parrot', 'fish'] } } } };
|
||||
const path = 'level1.level2.level3.level4';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(['parrot', 'fish']);
|
||||
});
|
||||
|
||||
it('should return the correct data if the path is NOT nested', () => {
|
||||
const data = { pets: ['cat', 'dog'] };
|
||||
const path = 'pets';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(['cat', 'dog']);
|
||||
});
|
||||
|
||||
it('should return the correct data if the path is NOT nested with separator (.) in property name', () => {
|
||||
const data = { 'my.pets': ['cat', 'dog'] };
|
||||
const path = '[my.pets]';
|
||||
const result = helper.retrieveDataFromPath(data, path);
|
||||
expect(result).toEqual(['cat', 'dog']);
|
||||
testCases.forEach((testCase) => {
|
||||
it(testCase.description, () => {
|
||||
const data = testCase.data ?? mockResponseResultData(testCase.propertyName);
|
||||
const result = helper.retrieveDataFromPath(data, testCase.path);
|
||||
const expectedResult = testCase.expected ?? mockResultData;
|
||||
expect(result).toEqual(expectedResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
export class DataTablePathParserHelper {
|
||||
private readonly splitPathRegEx = /\.(?![^[]*\])/g;
|
||||
private readonly removeSquareBracketsRegEx = /^\[(.*)\]$/;
|
||||
|
||||
retrieveDataFromPath(data: any, path: string): any[] {
|
||||
@@ -37,11 +36,48 @@ export class DataTablePathParserHelper {
|
||||
}
|
||||
|
||||
private splitPathIntoProperties(path: string): string[] {
|
||||
return path.split(this.splitPathRegEx);
|
||||
const properties: string[] = [];
|
||||
const separator = '.';
|
||||
const openBracket = '[';
|
||||
const closeBracket = ']';
|
||||
|
||||
let currentPropertyBuffer = '';
|
||||
let bracketCount = 0;
|
||||
const isPropertySeparatorOutsideBrackets = () => bracketCount === 0;
|
||||
|
||||
for (const char of path) {
|
||||
switch (char) {
|
||||
case separator:
|
||||
if (isPropertySeparatorOutsideBrackets()) {
|
||||
properties.push(currentPropertyBuffer);
|
||||
currentPropertyBuffer = '';
|
||||
} else {
|
||||
currentPropertyBuffer += char;
|
||||
}
|
||||
break;
|
||||
case openBracket:
|
||||
bracketCount++;
|
||||
currentPropertyBuffer += char;
|
||||
break;
|
||||
case closeBracket:
|
||||
bracketCount--;
|
||||
currentPropertyBuffer += char;
|
||||
break;
|
||||
default:
|
||||
currentPropertyBuffer += char;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentPropertyBuffer) {
|
||||
properties.push(currentPropertyBuffer);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private removeSquareBracketsFromProperty(property: string): string {
|
||||
return property.replace(this.removeSquareBracketsRegEx, '$1');
|
||||
return property?.replace(this.removeSquareBracketsRegEx, '$1');
|
||||
}
|
||||
|
||||
private isPropertyExistsInData(data: any, property: string): boolean {
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const mockResultData = [
|
||||
{
|
||||
id: '1',
|
||||
decimal: '1.0',
|
||||
name: 'test1',
|
||||
date: '1-12-2023',
|
||||
amount: '0.12',
|
||||
data: '{ "result": "positive" }',
|
||||
trust: 'true',
|
||||
image: 'check_circle'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
decimal: '2.2',
|
||||
name: 'test2',
|
||||
date: '2-13-2023',
|
||||
amount: '2.2',
|
||||
data: '{ "result": "negative" }',
|
||||
trust: 'true',
|
||||
image: 'bookmark'
|
||||
}
|
||||
];
|
||||
|
||||
export const mockResponseResultData = (propertyName: string) => ({
|
||||
response: {
|
||||
[propertyName]: mockResultData
|
||||
}
|
||||
});
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { DataColumn } from '@alfresco/adf-core';
|
||||
import { TaskVariableCloud } from '../models/task-variable-cloud.model';
|
||||
import { TaskVariableCloud } from '../../../../models/task-variable-cloud.model';
|
||||
|
||||
export const mockSchemaDefinition: DataColumn[] = [
|
||||
{
|
||||
@@ -85,28 +85,6 @@ export const mockJsonNestedResponseEuropeCountriesData = {
|
||||
}
|
||||
};
|
||||
|
||||
export const mockJsonNestedResponseEuropeCountriesDataWithSeparatorInPropertyName = {
|
||||
response: {
|
||||
empty: [],
|
||||
'my.data': {
|
||||
'country[data].country': mockEuropeCountriesData
|
||||
},
|
||||
data: [
|
||||
{
|
||||
id: 'HR',
|
||||
name: 'Croatia'
|
||||
}
|
||||
],
|
||||
'no-array': {}
|
||||
}
|
||||
};
|
||||
|
||||
export const mockJsonNestedResponseEuropeCountriesDataWithMultipleSpecialCharacters = {
|
||||
response: {
|
||||
'xyz:abc,xyz-abc,xyz_abc,abc+xyz': mockEuropeCountriesData
|
||||
}
|
||||
};
|
||||
|
||||
export const mockAmericaCountriesData = [
|
||||
{
|
||||
id: 'CA',
|
Reference in New Issue
Block a user