Skip to content

Commit

Permalink
AAE-22222 Fix JSON path doesn't work for square bracekts (#9611)
Browse files Browse the repository at this point in the history
* AAE-22222 Fix JSON path doesn't work for square bracekts

* remove comment

* remove test description duplications

* remove duplications
  • Loading branch information
tomgny committed Apr 26, 2024
1 parent 7ac7db4 commit a039367
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
});

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']);
});
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 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);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/

export class DataTablePathParserHelper {
private readonly splitPathRegEx = /\.(?![^[]*\])/g;
private readonly removeSquareBracketsRegEx = /^\[(.*)\]$/;

retrieveDataFromPath(data: any, path: string): any[] {
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [
{
Expand Down Expand Up @@ -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',
Expand Down

0 comments on commit a039367

Please sign in to comment.