Skip to content

Commit

Permalink
feat: minify URL query parameters
Browse files Browse the repository at this point in the history
- Added the object `minifiedParams` to map all the params to their
  minified forms.
- Added the function `minifyParmas` that return a object with the params
  minified based on the object `minifiedParams`
- Added the object `groupedMinifiedParams` that divide the minified
  params in five groups based on the depth of the nested objects in
  searchParams: general, df (for DiffFilter nested object), ti (for
  TreeInfo nested object), tf (for TableFilter nested object) and value
  (for minified values instead of keys). This was required to identify
  different attributes that were minified to the same value (e.g. 't'
  for treeInfo.treeName, TableFilter.testsTable and diffFilter.trees)
- Added the function `unminifyParams` that return a object with the
  original param names based on the object `groupedMinfiedParams`.
- Added `minifyParams` to `stringifySearch` so the processing steps
  are minify -> flatten -> stringify
- Added `unminifyParams` to `parseSearch` so the processing steps are
  parse -> unflatten -> unminify
- Added tests for the new functions and changed tests for the old
  functions

Closes #725
  • Loading branch information
murilx committed Jan 8, 2025
1 parent baacaf8 commit 1e27ebe
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 35 deletions.
16 changes: 8 additions & 8 deletions dashboard/src/types/tree/TreeDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,14 @@ export const zTableFilterInfoValidator = zTableFilterInfo
export type TableFilter = z.infer<typeof zTableFilterInfo>;

export const DEFAULT_TREE_INFO = {};
export const zTreeInformation = z
.object({
gitBranch: z.string().optional().catch(''),
gitUrl: z.string().optional().catch(''),
treeName: z.string().optional().catch(''),
commitName: z.string().optional().catch(''),
headCommitHash: z.string().optional().catch(undefined),
})
export const zTreeInformationObject = z.object({
gitBranch: z.string().optional().catch(''),
gitUrl: z.string().optional().catch(''),
treeName: z.string().optional().catch(''),
commitName: z.string().optional().catch(''),
headCommitHash: z.string().optional().catch(undefined),
});
export const zTreeInformation = zTreeInformationObject
.default(DEFAULT_TREE_INFO)
.catch(DEFAULT_TREE_INFO);

Expand Down
108 changes: 93 additions & 15 deletions dashboard/src/utils/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
parseSearch,
stringifySearch,
isEncodedJSONArrayParam,
minifyParams,
unminifyParams,
} from './search';

const KEY_FLAT_CHAR = '|';
Expand All @@ -19,8 +21,14 @@ const simpleObject = {
treeIndexes: [1, 2, 3],
};

const simpleObjectStringify =
'?origin=maestro&intervalInDays=7&treeIndexes[]=1,2,3';
const simpleObjectMinify = {
o: 'maestro',
i: 7,
// eslint-disable-next-line no-magic-numbers
x: [1, 2, 3],
};

const simpleObjectStringify = '?o=maestro&i=7&x[]=1,2,3';

const nestedObject = {
origin: 'maestro',
Expand All @@ -32,7 +40,7 @@ const nestedObject = {
},
treeInfo: {
treeName: 'android',
gitCommitHash: 'hash',
headCommitHash: 'hash',
},
diffFilter: {
configs: { defconfig: true },
Expand All @@ -42,26 +50,60 @@ const nestedObject = {
treeIndexes: [0, 1, 2],
};

const nestedObjectMinify = {
o: 'maestro',
i: 7,
tf: {
bt: 'a',
b: 'f',
t: 'a',
},
ti: {
t: 'android',
ch: 'hash',
},
df: {
c: { defconfig: true },
a: { arm: true },
tp: 'amlogic',
},
x: [0, 1, 2],
};

const nestedObjectStringify =
'?o=maestro&i=7' +
'&tf|bt=a&tf|b=f&tf|t=a' +
'&ti|t=android&ti|ch=hash' +
'&df|c|defconfig=true&df|a|arm=true&df|tp=amlogic' +
'&x[]=0,1,2';

const flatObject = {
origin: 'maestro',
intervalInDays: 7,
'tableFilter|bootsTable': 'all',
'tableFilter|buildsTable': 'failed',
'tableFilter|testsTable': 'all',
'treeInfo|treeName': 'android',
'treeInfo|gitCommitHash': 'hash',
'treeInfo|headCommitHash': 'hash',
'diffFilter|configs|defconfig': true,
'diffFilter|archs|arm': true,
'diffFilter|testPath': 'amlogic',
treeIndexes: [0, 1, 2],
};

const nestedObjectStringify =
'?origin=maestro&intervalInDays=7' +
'&tableFilter|bootsTable=all&tableFilter|buildsTable=failed&tableFilter|testsTable=all' +
'&treeInfo|treeName=android&treeInfo|gitCommitHash=hash' +
'&diffFilter|configs|defconfig=true&diffFilter|archs|arm=true&diffFilter|testPath=amlogic' +
'&treeIndexes[]=0,1,2';
const flatObjectMinify = {
o: 'maestro',
i: 7,
'tf|bt': 'a',
'tf|b': 'f',
'tf|t': 'a',
'ti|t': 'android',
'ti|ch': 'hash',
'df|c|defconfig': true,
'df|a|arm': true,
'df|tp': 'amlogic',
x: [0, 1, 2],
};

describe('isEncodedArrayParam', () => {
const emptyJSONArrayStr = 'treeIndexes=[]';
Expand Down Expand Up @@ -149,15 +191,50 @@ describe('unflattenObject', () => {
});
});

describe('minifyParams', () => {
it('Simple object with filled array', () => {
expect(minifyParams(simpleObject)).toStrictEqual(simpleObjectMinify);
});

it('Simple object with empty array', () => {
const simpleObjectEmptyArray = { ...simpleObject, treeIndexes: [] };
const simpleObjectEmptyArrayMinify = { ...simpleObjectMinify, x: [] };
expect(minifyParams(simpleObjectEmptyArray)).toStrictEqual(
simpleObjectEmptyArrayMinify,
);
});

it('Nested object', () => {
expect(minifyParams(nestedObject)).toStrictEqual(nestedObjectMinify);
});
});

describe('unminifyParams', () => {
it('Simple object with filled array', () => {
expect(unminifyParams(simpleObjectMinify)).toStrictEqual(simpleObject);
});

it('Simple object with empty array', () => {
const simpleObjectEmptyArray = { ...simpleObject, treeIndexes: [] };
const simpleObjectEmptyArrayMinify = { ...simpleObjectMinify, x: [] };
expect(unminifyParams(simpleObjectEmptyArrayMinify)).toStrictEqual(
simpleObjectEmptyArray,
);
});

it('Nested object', () => {
expect(unminifyParams(nestedObjectMinify)).toStrictEqual(nestedObject);
});
});

describe('parseSearch', () => {
it('Simple object with filled array', () => {
expect(parseSearch(simpleObjectStringify)).toStrictEqual(simpleObject);
});

it('Simple object with empty array', () => {
const simpleObjectEmptyArray = { ...simpleObject, treeIndexes: [] };
const simpleObjectEmptyArrayStringify =
'?origin=maestro&intervalInDays=7&treeIndexes[]';
const simpleObjectEmptyArrayStringify = '?o=maestro&i=7&x[]';
expect(parseSearch(simpleObjectEmptyArrayStringify)).toStrictEqual(
simpleObjectEmptyArray,
);
Expand Down Expand Up @@ -235,17 +312,18 @@ describe('stringifySearch', () => {

it('Simple object with filled array', () => {
const result = stringifySearch(simpleObject);
assertSearchParams(result, simpleObject);
assertSearchParams(result, simpleObjectMinify);
});

it('Simple object with empty array', () => {
const simpleObjectEmptyArray = { ...simpleObject, treeIndexes: [] };
const simpleObjectEmptyArrayMinify = { ...simpleObjectMinify, x: [] };
const result = stringifySearch(simpleObjectEmptyArray);
assertSearchParams(result, simpleObjectEmptyArray);
assertSearchParams(result, simpleObjectEmptyArrayMinify);
});

it('Nested object', () => {
const result = stringifySearch(nestedObject);
assertSearchParams(result, flatObject);
assertSearchParams(result, flatObjectMinify);
});
});
Loading

0 comments on commit 1e27ebe

Please sign in to comment.