Skip to content

Commit bd5be16

Browse files
committed
Move customfilterregistry in wherebuilder constructor, add tests for filter-query.builder and relatin-query.builder
1 parent ffce78f commit bd5be16

File tree

8 files changed

+159
-96
lines changed

8 files changed

+159
-96
lines changed

packages/query-typeorm/__tests__/query/__snapshots__/filter-query.builder.spec.ts.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,34 @@ exports[`FilterQueryBuilder #delete with sorting should ignore sorting 1`] = `DE
1212

1313
exports[`FilterQueryBuilder #delete with sorting should ignore sorting 2`] = `Array []`;
1414

15+
exports[`FilterQueryBuilder #select with custom filter should add custom filters 1`] = `SELECT "TestEntity"."test_entity_pk" AS "TestEntity_test_entity_pk", "TestEntity"."string_type" AS "TestEntity_string_type", "TestEntity"."bool_type" AS "TestEntity_bool_type", "TestEntity"."number_type" AS "TestEntity_number_type", "TestEntity"."date_type" AS "TestEntity_date_type", "TestEntity"."oneTestRelationTestRelationPk" AS "TestEntity_oneTestRelationTestRelationPk" FROM "test_entity" "TestEntity" WHERE ("TestEntity"."number_type" >= ? OR "TestEntity"."number_type" <= ? OR ("TestEntity"."numberType" % ?) == 0) AND ((EXTRACT(EPOCH FROM "TestEntity"."dateType") / 3600 / 24) % ?) == 0) AND (ST_Distance("TestEntity"."fakePointType", ST_MakePoint(?,?)) <= ?)`;
16+
17+
exports[`FilterQueryBuilder #select with custom filter should add custom filters 2`] = `
18+
Array [
19+
1,
20+
10,
21+
5,
22+
3,
23+
45.3,
24+
9.5,
25+
50000,
26+
]
27+
`;
28+
29+
exports[`FilterQueryBuilder #select with custom filter should add custom filters with aggregate 1`] = `SELECT MAX("TestEntity"."number_type") AS "MAX_numberType" FROM "test_entity" "TestEntity" WHERE ("TestEntity"."number_type" >= ? OR "TestEntity"."number_type" <= ? OR ("TestEntity"."numberType" % ?) == 0) AND ((EXTRACT(EPOCH FROM "TestEntity"."dateType") / 3600 / 24) % ?) == 0) AND (ST_Distance("TestEntity"."fakePointType", ST_MakePoint(?,?)) <= ?)`;
30+
31+
exports[`FilterQueryBuilder #select with custom filter should add custom filters with aggregate 2`] = `
32+
Array [
33+
1,
34+
10,
35+
5,
36+
3,
37+
45.3,
38+
9.5,
39+
50000,
40+
]
41+
`;
42+
1543
exports[`FilterQueryBuilder #select with filter should call whereBuilder#build if there is a filter 1`] = `SELECT "TestEntity"."test_entity_pk" AS "TestEntity_test_entity_pk", "TestEntity"."string_type" AS "TestEntity_string_type", "TestEntity"."bool_type" AS "TestEntity_bool_type", "TestEntity"."number_type" AS "TestEntity_number_type", "TestEntity"."date_type" AS "TestEntity_date_type", "TestEntity"."oneTestRelationTestRelationPk" AS "TestEntity_oneTestRelationTestRelationPk" FROM "test_entity" "TestEntity" WHERE "TestEntity"."string_type" = 'foo'`;
1644

1745
exports[`FilterQueryBuilder #select with filter should call whereBuilder#build if there is a filter 2`] = `Array []`;

packages/query-typeorm/__tests__/query/__snapshots__/relation-query.builder.spec.ts.snap

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,18 @@ Array [
7272
]
7373
`;
7474

75-
exports[`RelationQueryBuilder #select with custom filters should accept custom filters 1`] = `SELECT "testEntityRelation"."test_relation_id" AS "testEntityRelation_test_relation_id", "testEntityRelation"."test_entity_id" AS "testEntityRelation_test_entity_id" FROM "test_entity_relation_entity" "testEntityRelation" WHERE ("testEntityRelation"."test_entity_id" = ?) AND (("testEntityRelation"."numberType" % ?) == 0)`;
75+
exports[`RelationQueryBuilder #select with custom filters should accept custom filters 1`] = `SELECT "testEntityRelation"."test_relation_id" AS "testEntityRelation_test_relation_id", "testEntityRelation"."test_entity_id" AS "testEntityRelation_test_entity_id" FROM "test_entity_relation_entity" "testEntityRelation" WHERE ("testEntityRelation"."test_entity_id" = ?) AND (testEntityRelation.numberType >= ? OR testEntityRelation.numberType <= ? OR ("testEntityRelation"."numberType" % ?) == 0) AND ((EXTRACT(EPOCH FROM "testEntityRelation"."dateType") / 3600 / 24) % ?) == 0) AND (ST_Distance("testEntityRelation"."fakePointType", ST_MakePoint(?,?)) <= ?)`;
7676

7777
exports[`RelationQueryBuilder #select with custom filters should accept custom filters 2`] = `
7878
Array [
7979
test-entity-id-1,
80+
1,
81+
10,
8082
5,
83+
3,
84+
45.3,
85+
9.5,
86+
50000,
8187
]
8288
`;
8389

packages/query-typeorm/__tests__/query/filter-query.builder.spec.ts

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Class, Filter, Query, SortDirection, SortNulls } from '@nestjs-query/core';
1+
import { AggregateQuery, Class, Filter, Query, SortDirection, SortNulls } from '@nestjs-query/core';
22
import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito';
33
import { QueryBuilder, WhereExpression } from 'typeorm';
4-
import { CustomFilterRegistry, FilterQueryBuilder, WhereBuilder } from '../../src/query';
4+
import { FilterQueryBuilder, WhereBuilder } from '../../src/query';
55
import { closeTestConnection, createTestConnection, getTestConnection } from '../__fixtures__/connection.fixture';
66
import { TestSoftDeleteEntity } from '../__fixtures__/test-soft-delete.entity';
77
import { TestEntity } from '../__fixtures__/test.entity';
8+
import { getCustomFilterRegistry } from '../utils';
89

910
describe('FilterQueryBuilder', (): void => {
1011
beforeEach(createTestConnection);
@@ -94,53 +95,92 @@ describe('FilterQueryBuilder', (): void => {
9495
expectSQLSnapshot(selectQueryBuilder);
9596
};
9697

98+
const expectAggregateSQLSnapshot = (
99+
query: Query<TestEntity>,
100+
aggregate: AggregateQuery<TestEntity>,
101+
whereBuilder: WhereBuilder<TestEntity>,
102+
): void => {
103+
const aggregateQueryBuilder = getEntityQueryBuilder(TestEntity, whereBuilder).aggregate(query, aggregate);
104+
expectSQLSnapshot(aggregateQueryBuilder);
105+
};
106+
97107
describe('with filter', () => {
98108
it('should not call whereBuilder#build', () => {
99109
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
100110
expectSelectSQLSnapshot({}, instance(mockWhereBuilder));
101-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
111+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
102112
});
103113

104114
it('should call whereBuilder#build if there is a filter', () => {
105115
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
106116
const query = { filter: { stringType: { eq: 'foo' } } };
107-
when(
108-
mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, undefined, 'TestEntity'),
109-
).thenCall(
117+
when(mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, 'TestEntity')).thenCall(
110118
(
111119
where: WhereExpression,
112120
field: Filter<TestEntity>,
113121
relationNames: string[],
114122
klass: Class<any>,
115-
customFilters: CustomFilterRegistry,
116123
alias: string,
117124
) => where.andWhere(`${alias}.stringType = 'foo'`),
118125
);
119126
expectSelectSQLSnapshot(query, instance(mockWhereBuilder));
120127
});
121128
});
122129

130+
describe('with custom filter', () => {
131+
it('should add custom filters', () => {
132+
expectSelectSQLSnapshot(
133+
{
134+
filter: {
135+
// This has the global isMultipleOf filter
136+
numberType: { gte: 1, lte: 10, isMultipleOf: 5 },
137+
// Here, the isMultipleOf filter was overridden for dateType only
138+
dateType: { isMultipleOf: 3 },
139+
// This is a more complex filter involving geospatial queries
140+
fakePointType: { distanceFrom: { point: { lat: 45.3, lng: 9.5 }, radius: 50000 } },
141+
} as any, // TODO Fix any typing
142+
},
143+
new WhereBuilder({ customFilterRegistry: getCustomFilterRegistry() }),
144+
);
145+
});
146+
147+
it('should add custom filters with aggregate', () => {
148+
expectAggregateSQLSnapshot(
149+
{
150+
filter: {
151+
// This has the global isMultipleOf filter
152+
numberType: { gte: 1, lte: 10, isMultipleOf: 5 },
153+
// Here, the isMultipleOf filter was overridden for dateType only
154+
dateType: { isMultipleOf: 3 },
155+
// This is a more complex filter involving geospatial queries
156+
fakePointType: { distanceFrom: { point: { lat: 45.3, lng: 9.5 }, radius: 50000 } },
157+
} as any, // TODO Fix any typing
158+
},
159+
{
160+
max: ['numberType'],
161+
},
162+
new WhereBuilder({ customFilterRegistry: getCustomFilterRegistry() }),
163+
);
164+
});
165+
});
166+
123167
describe('with paging', () => {
124168
it('should apply empty paging args', () => {
125169
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
126170
expectSelectSQLSnapshot({}, instance(mockWhereBuilder));
127-
verify(
128-
mockWhereBuilder.build(anything(), anything(), deepEqual({}), TestEntity, undefined, 'TestEntity'),
129-
).never();
171+
verify(mockWhereBuilder.build(anything(), anything(), deepEqual({}), TestEntity, 'TestEntity')).never();
130172
});
131173

132174
it('should apply paging args going forward', () => {
133175
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
134176
expectSelectSQLSnapshot({ paging: { limit: 10, offset: 11 } }, instance(mockWhereBuilder));
135-
verify(
136-
mockWhereBuilder.build(anything(), anything(), deepEqual({}), TestEntity, undefined, 'TestEntity'),
137-
).never();
177+
verify(mockWhereBuilder.build(anything(), anything(), deepEqual({}), TestEntity, 'TestEntity')).never();
138178
});
139179

140180
it('should apply paging args going backward', () => {
141181
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
142182
expectSelectSQLSnapshot({ paging: { limit: 10, offset: 10 } }, instance(mockWhereBuilder));
143-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
183+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
144184
});
145185
});
146186

@@ -151,7 +191,7 @@ describe('FilterQueryBuilder', (): void => {
151191
{ sorting: [{ field: 'numberType', direction: SortDirection.ASC }] },
152192
instance(mockWhereBuilder),
153193
);
154-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
194+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
155195
});
156196

157197
it('should apply ASC NULLS_FIRST sorting', () => {
@@ -160,7 +200,7 @@ describe('FilterQueryBuilder', (): void => {
160200
{ sorting: [{ field: 'numberType', direction: SortDirection.ASC, nulls: SortNulls.NULLS_FIRST }] },
161201
instance(mockWhereBuilder),
162202
);
163-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
203+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
164204
});
165205

166206
it('should apply ASC NULLS_LAST sorting', () => {
@@ -169,7 +209,7 @@ describe('FilterQueryBuilder', (): void => {
169209
{ sorting: [{ field: 'numberType', direction: SortDirection.ASC, nulls: SortNulls.NULLS_LAST }] },
170210
instance(mockWhereBuilder),
171211
);
172-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
212+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
173213
});
174214

175215
it('should apply DESC sorting', () => {
@@ -178,7 +218,7 @@ describe('FilterQueryBuilder', (): void => {
178218
{ sorting: [{ field: 'numberType', direction: SortDirection.DESC }] },
179219
instance(mockWhereBuilder),
180220
);
181-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
221+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
182222
});
183223

184224
it('should apply DESC NULLS_FIRST sorting', () => {
@@ -195,7 +235,7 @@ describe('FilterQueryBuilder', (): void => {
195235
{ sorting: [{ field: 'numberType', direction: SortDirection.DESC, nulls: SortNulls.NULLS_LAST }] },
196236
instance(mockWhereBuilder),
197237
);
198-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
238+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
199239
});
200240

201241
it('should apply multiple sorts', () => {
@@ -211,7 +251,7 @@ describe('FilterQueryBuilder', (): void => {
211251
},
212252
instance(mockWhereBuilder),
213253
);
214-
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, undefined, 'TestEntity')).never();
254+
verify(mockWhereBuilder.build(anything(), anything(), {}, TestEntity, 'TestEntity')).never();
215255
});
216256
});
217257
});
@@ -226,9 +266,9 @@ describe('FilterQueryBuilder', (): void => {
226266
it('should call whereBuilder#build if there is a filter', () => {
227267
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
228268
const query = { filter: { stringType: { eq: 'foo' } } };
229-
when(
230-
mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, undefined, undefined),
231-
).thenCall((where: WhereExpression) => where.andWhere(`stringType = 'foo'`));
269+
when(mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, undefined)).thenCall(
270+
(where: WhereExpression) => where.andWhere(`stringType = 'foo'`),
271+
);
232272
expectUpdateSQLSnapshot(query, instance(mockWhereBuilder));
233273
});
234274
});
@@ -323,9 +363,9 @@ describe('FilterQueryBuilder', (): void => {
323363
it('should call whereBuilder#build if there is a filter', () => {
324364
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder);
325365
const query = { filter: { stringType: { eq: 'foo' } } };
326-
when(
327-
mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, undefined, undefined),
328-
).thenCall((where: WhereExpression) => where.andWhere(`stringType = 'foo'`));
366+
when(mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestEntity, undefined)).thenCall(
367+
(where: WhereExpression) => where.andWhere(`stringType = 'foo'`),
368+
);
329369
expectDeleteSQLSnapshot(query, instance(mockWhereBuilder));
330370
});
331371
});
@@ -369,9 +409,9 @@ describe('FilterQueryBuilder', (): void => {
369409
it('should call whereBuilder#build if there is a filter', () => {
370410
const mockWhereBuilder = mock<WhereBuilder<TestSoftDeleteEntity>>(WhereBuilder);
371411
const query = { filter: { stringType: { eq: 'foo' } } };
372-
when(
373-
mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestSoftDeleteEntity, undefined, undefined),
374-
).thenCall((where: WhereExpression) => where.andWhere(`stringType = 'foo'`));
412+
when(mockWhereBuilder.build(anything(), query.filter, deepEqual({}), TestSoftDeleteEntity, undefined)).thenCall(
413+
(where: WhereExpression) => where.andWhere(`stringType = 'foo'`),
414+
);
375415
expectSoftDeleteSQLSnapshot(query, instance(mockWhereBuilder));
376416
});
377417
});

packages/query-typeorm/__tests__/query/relation-query.builder.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,16 @@ describe('RelationQueryBuilder', (): void => {
167167
describe('with custom filters', () => {
168168
// TODO Fix typings to avoid usage of any
169169
it('should accept custom filters', (): void => {
170-
const query: Query<TestRelation> = { filter: { numberType: { isMultipleOf: 5 } } } as any;
170+
const query: Query<TestRelation> = {
171+
filter: {
172+
// This has the global isMultipleOf filter
173+
numberType: { gte: 1, lte: 10, isMultipleOf: 5 },
174+
// Here, the isMultipleOf filter was overridden for dateType only
175+
dateType: { isMultipleOf: 3 },
176+
// This is a more complex filter involving geospatial queries
177+
fakePointType: { distanceFrom: { point: { lat: 45.3, lng: 9.5 }, radius: 50000 } },
178+
} as any, // TODO Fix any typing
179+
};
171180
expectSQLSnapshot(TestEntity, testEntity, 'testEntityRelation', query);
172181
});
173182
});

packages/query-typeorm/__tests__/query/where.builder.spec.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,13 @@ describe('WhereBuilder', (): void => {
1010

1111
const getRepo = () => getTestConnection().getRepository(TestEntity);
1212
const getQueryBuilder = () => getRepo().createQueryBuilder();
13-
const createWhereBuilder = () => new WhereBuilder<TestEntity>();
14-
15-
const customFilterRegistry = getCustomFilterRegistry();
13+
const createWhereBuilder = () =>
14+
new WhereBuilder<TestEntity>({
15+
customFilterRegistry: getCustomFilterRegistry(),
16+
});
1617

1718
const expectSQLSnapshot = (filter: Filter<TestEntity>): void => {
18-
const selectQueryBuilder = createWhereBuilder().build(
19-
getQueryBuilder(),
20-
filter,
21-
{},
22-
TestEntity,
23-
customFilterRegistry,
24-
'TestEntity',
25-
);
19+
const selectQueryBuilder = createWhereBuilder().build(getQueryBuilder(), filter, {}, TestEntity, 'TestEntity');
2620
const [sql, params] = selectQueryBuilder.getQueryAndParameters();
2721
expect(sql).toMatchSnapshot();
2822
expect(params).toMatchSnapshot();

0 commit comments

Comments
 (0)