Skip to content

Commit

Permalink
feat(mongoose): Update to support new aggregate with groupBy
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-martin committed Mar 31, 2021
1 parent 922e696 commit ccd0438
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 191 deletions.
98 changes: 50 additions & 48 deletions packages/query-mongoose/__tests__/query/aggregate.builder.spec.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,72 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { AggregateQuery } from '@nestjs-query/core';
import { TestEntity } from '../__fixtures__/test.entity';
import { AggregateBuilder, MongooseAggregate } from '../../src/query';
import { AggregateBuilder } from '../../src/query';

describe('AggregateBuilder', (): void => {
const createAggregateBuilder = () => new AggregateBuilder<TestEntity>();

const assertQuery = (agg: AggregateQuery<TestEntity>, expected: MongooseAggregate): void => {
const actual = createAggregateBuilder().build(agg);
expect(actual).toEqual(expected);
};

it('should throw an error if no selects are generated', (): void => {
expect(() => createAggregateBuilder().build({})).toThrow('No aggregate fields found.');
});

it('or multiple operators for a single field together', (): void => {
assertQuery(
{
count: ['id', 'stringType'],
avg: ['numberType'],
sum: ['numberType'],
max: ['stringType', 'dateType', 'numberType'],
min: ['stringType', 'dateType', 'numberType'],
},
{
avg_numberType: { $avg: '$numberType' },
count_id: { $sum: { $cond: { else: 1, if: { $in: [{ $type: '$_id' }, ['missing', 'null']] }, then: 0 } } },
count_stringType: {
$sum: { $cond: { else: 1, if: { $in: [{ $type: '$stringType' }, ['missing', 'null']] }, then: 0 } },
},
max_dateType: { $max: '$dateType' },
max_numberType: { $max: '$numberType' },
max_stringType: { $max: '$stringType' },
min_dateType: { $min: '$dateType' },
min_numberType: { $min: '$numberType' },
min_stringType: { $min: '$stringType' },
sum_numberType: { $sum: '$numberType' },
it('should create an aggregate query', (): void => {
const agg: AggregateQuery<TestEntity> = {
count: ['id', 'stringType'],
avg: ['numberType'],
sum: ['numberType'],
max: ['stringType', 'dateType', 'numberType'],
min: ['stringType', 'dateType', 'numberType'],
};
expect(createAggregateBuilder().build(agg)).toEqual({
_id: null,
avg_numberType: { $avg: '$numberType' },
count_id: { $sum: { $cond: { else: 1, if: { $in: [{ $type: '$_id' }, ['missing', 'null']] }, then: 0 } } },
count_stringType: {
$sum: { $cond: { else: 1, if: { $in: [{ $type: '$stringType' }, ['missing', 'null']] }, then: 0 } },
},
);
max_dateType: { $max: '$dateType' },
max_numberType: { $max: '$numberType' },
max_stringType: { $max: '$stringType' },
min_dateType: { $min: '$dateType' },
min_numberType: { $min: '$numberType' },
min_stringType: { $min: '$stringType' },
sum_numberType: { $sum: '$numberType' },
});
});

describe('.convertToAggregateResponse', () => {
it('should convert a flat response into an Aggregtate response', () => {
const dbResult = {
count_id: 10,
sum_numberType: 55,
avg_numberType: 5,
max_stringType: 'z',
max_numberType: 10,
min_stringType: 'a',
min_numberType: 1,
};
expect(AggregateBuilder.convertToAggregateResponse<TestEntity>(dbResult)).toEqual({
count: { id: 10 },
sum: { numberType: 55 },
avg: { numberType: 5 },
max: { stringType: 'z', numberType: 10 },
min: { stringType: 'a', numberType: 1 },
});
const dbResult = [
{
_id: { group_by_stringType: 'z' },
count_id: 10,
sum_numberType: 55,
avg_numberType: 5,
max_stringType: 'z',
max_numberType: 10,
min_stringType: 'a',
min_numberType: 1,
},
];
expect(AggregateBuilder.convertToAggregateResponse<TestEntity>(dbResult)).toEqual([
{
groupBy: { stringType: 'z' },
count: { id: 10 },
sum: { numberType: 55 },
avg: { numberType: 5 },
max: { stringType: 'z', numberType: 10 },
min: { stringType: 'a', numberType: 1 },
},
]);
});

it('should throw an error if a column is not expected', () => {
const dbResult = {
COUNTtestEntityPk: 10,
};
const dbResult = [
{
COUNTtestEntityPk: 10,
},
];
expect(() => AggregateBuilder.convertToAggregateResponse<TestEntity>(dbResult)).toThrow(
'Unknown aggregate column encountered.',
);
Expand Down

0 comments on commit ccd0438

Please sign in to comment.