From 11434fc1c6230cf0257291d7d30baa151849e0cb Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Thu, 29 Feb 2024 17:36:22 +0100 Subject: [PATCH] Handle multiple orderBy sorting (#4246) Co-authored-by: Thomas Trompette --- .../__tests__/args-string.factory.spec.ts | 86 +++++++++++++++++++ .../factories/args-string.factory.ts | 19 +++- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 packages/twenty-server/src/workspace/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts new file mode 100644 index 000000000..c7eec0ac1 --- /dev/null +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/__tests__/args-string.factory.spec.ts @@ -0,0 +1,86 @@ +import { TestingModule, Test } from '@nestjs/testing'; + +import { ArgsAliasFactory } from 'src/workspace/workspace-query-builder/factories/args-alias.factory'; +import { ArgsStringFactory } from 'src/workspace/workspace-query-builder/factories/args-string.factory'; + +describe('ArgsStringFactory', () => { + let service: ArgsStringFactory; + const argsAliasCreate = jest.fn(); + + beforeEach(async () => { + jest.resetAllMocks(); + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ArgsStringFactory, + { + provide: ArgsAliasFactory, + useValue: { + create: argsAliasCreate, + }, + }, + ], + }).compile(); + + service = module.get(ArgsStringFactory); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); + + describe('create', () => { + it('should return null when args are missing', () => { + const args = undefined; + + const result = service.create(args, []); + + expect(result).toBeNull(); + }); + + it('should return a string with the args when args are present', () => { + const args = { + id: '1', + name: 'field_name', + }; + + argsAliasCreate.mockReturnValue(args); + + const result = service.create(args, []); + + expect(result).toEqual('id: "1", name: "field_name"'); + }); + + it('should return a string with the args when args are present and the value is an object', () => { + const args = { + id: '1', + name: { + firstName: 'test', + }, + }; + + argsAliasCreate.mockReturnValue(args); + + const result = service.create(args, []); + + expect(result).toEqual('id: "1", name: {firstName:"test"}'); + }); + + it('when orderBy is present, should return an array of objects', () => { + const args = { + orderBy: { + id: 'AscNullsFirst', + name: 'AscNullsFirst', + }, + }; + + argsAliasCreate.mockReturnValue(args); + + const result = service.create(args, []); + + expect(result).toEqual( + 'orderBy: [{id: AscNullsFirst}, {name: AscNullsFirst}]', + ); + }); + }); +}); diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/args-string.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/args-string.factory.ts index 35a116ac0..cb80f5b67 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/args-string.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/args-string.factory.ts @@ -37,7 +37,8 @@ export class ArgsStringFactory { computedArgs[key] !== null ) { // If it's an object (and not null), stringify it - argsString += `${key}: ${stringifyWithoutKeyQuote( + argsString += `${key}: ${this.buildStringifiedObject( + key, computedArgs[key], )}, `; } else { @@ -53,4 +54,20 @@ export class ArgsStringFactory { return argsString; } + + private buildStringifiedObject( + key: string, + obj: Record, + ): string { + // PgGraphql is expecting the orderBy argument to be an array of objects + if (key === 'orderBy') { + const orderByString = Object.keys(obj) + .map((orderByKey) => `{${orderByKey}: ${obj[orderByKey]}}`) + .join(', '); + + return `[${orderByString}]`; + } + + return stringifyWithoutKeyQuote(obj); + } }