Skip to content

Commit 9ad89fe

Browse files
realSpokNicolas MoreauSteveBunlon
authored
fix: allow filtering on exact date on flattened field (#1079)
* fix: allow filtering on exact date on flattened field [skip ci] * ci: force ci with empty commit * fix: use same separator in filter parser * ci: force ci with empty commit * test: fix unit tests * refactor: review suggestion Co-authored-by: SteveBunlon <SteveBunlon@users.noreply.github.com> --------- Co-authored-by: Nicolas Moreau <nicolas.moreau76@gmail.com> Co-authored-by: SteveBunlon <SteveBunlon@users.noreply.github.com>
1 parent 6fe7ba3 commit 9ad89fe

File tree

5 files changed

+26
-17
lines changed

5 files changed

+26
-17
lines changed

src/services/filters-parser.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Flattener from './flattener';
66

77
const AGGREGATOR_OPERATORS = ['and', 'or'];
88

9+
const { FLATTEN_SEPARATOR } = Flattener;
10+
911
function FiltersParser(model, timezone, options) {
1012
const modelSchema = Interface.Schemas.schemas[utils.getModelName(model)];
1113

@@ -95,7 +97,7 @@ function FiltersParser(model, timezone, options) {
9597
throw new InvalidFiltersFormatError(`Field '${fieldName}' not found on collection '${modelSchema.name}'`);
9698
}
9799

98-
const fieldPath = subfieldName ? `${fieldName}.${subfieldName}` : fieldName;
100+
const fieldPath = subfieldName ? `${fieldName}${FLATTEN_SEPARATOR}${subfieldName}` : fieldName;
99101

100102
// NOTICE: either nested or virtual, not both
101103
const fieldType = field.isVirtual

src/services/flattener.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module.exports = class Flattener {
1313
this.lianaOptions = lianaOptions;
1414
}
1515

16+
static FLATTEN_SEPARATOR = FLATTEN_SEPARATOR;
17+
1618
_removeWrongFlattenConfiguration(index) {
1719
this.flatten.splice(index, 1);
1820
}
@@ -146,6 +148,8 @@ module.exports = class Flattener {
146148
if (!_.isEmpty(request.query?.context)) {
147149
request.query.context.field = Flattener.unflattenFieldName(request.query.context.field);
148150
}
151+
// Note: filter and sorts are not unflattened here because
152+
// they are checked against forest schema later on
149153
return next();
150154
} catch (error) { return next(error); }
151155
}

src/utils/schema.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ exports.getModelName = (model) => model.modelName;
1414
// TODO: Remove nameOld attribute once the lianas versions older than 2.0.0 are minority
1515
exports.getModelNameOld = (model) => model.collection.name.replace(' ', '');
1616

17+
const { FLATTEN_SEPARATOR } = require('../services/flattener');
18+
1719
const getNestedFieldType = (mongooseSchema, nestedFieldPath) => {
1820
if (!mongooseSchema || !nestedFieldPath) return undefined;
1921

20-
const [currentFieldName, ...deepNestedFieldPath] = nestedFieldPath.split('.');
22+
const [currentFieldName, ...deepNestedFieldPath] = nestedFieldPath.split(FLATTEN_SEPARATOR);
2123

2224
let nestedFieldDeclaration;
2325

@@ -37,7 +39,7 @@ const getNestedFieldType = (mongooseSchema, nestedFieldPath) => {
3739
return nestedFieldDeclaration.type || nestedFieldDeclaration;
3840
}
3941

40-
return getNestedFieldType(nestedFieldDeclaration, deepNestedFieldPath?.join('.'));
42+
return getNestedFieldType(nestedFieldDeclaration, deepNestedFieldPath?.join(FLATTEN_SEPARATOR));
4143
};
4244

4345
exports.getNestedFieldType = getNestedFieldType;

test/tests/services/query-builder.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import loadFixture from 'mongoose-fixture-loader';
33
import Interface from 'forest-express';
44
import mongooseConnect from '../../utils/mongoose-connect';
55
import QueryBuilder from '../../../src/services/query-builder';
6+
import Flattener from '../../../src/services/flattener';
67

7-
const FLATTEN_SEPARATOR = '@@@';
8+
const { FLATTEN_SEPARATOR } = Flattener;
89

910
describe('service > query-builder', () => {
1011
let TreeModel;

test/tests/utils/schema.test.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,21 @@ describe('schema', () => {
4747
it('should correctly detect the type', () => {
4848
expect.assertions(2);
4949
expect(
50-
getNestedFieldType(nestedModelSchema, 'engineSubSchemaAndType._id'),
50+
getNestedFieldType(nestedModelSchema, 'engineSubSchemaAndType@@@_id'),
5151
).toStrictEqual(mongoose.Schema.Types.ObjectId);
5252
expect(
53-
getNestedFieldType(nestedModelSchema, 'engineSubSchemaAndType.horsePower'),
53+
getNestedFieldType(nestedModelSchema, 'engineSubSchemaAndType@@@horsePower'),
5454
).toStrictEqual(String);
5555
});
5656
});
5757
describe('when the nested field is not defined using a type', () => {
5858
it('should correctly detect the type', () => {
5959
expect.assertions(2);
6060
expect(
61-
getNestedFieldType(nestedModelSchema, 'engineSubSchema._id'),
61+
getNestedFieldType(nestedModelSchema, 'engineSubSchema@@@_id'),
6262
).toStrictEqual(mongoose.Schema.Types.ObjectId);
6363
expect(
64-
getNestedFieldType(nestedModelSchema, 'engineSubSchema.horsePower'),
64+
getNestedFieldType(nestedModelSchema, 'engineSubSchema@@@horsePower'),
6565
).toStrictEqual(String);
6666
});
6767
});
@@ -72,21 +72,21 @@ describe('schema', () => {
7272
it('should correctly detect the type', () => {
7373
expect.assertions(2);
7474
expect(
75-
getNestedFieldType(nestedModelSchema, 'engineNestedDocumentAndType._id'),
75+
getNestedFieldType(nestedModelSchema, 'engineNestedDocumentAndType@@@_id'),
7676
).toStrictEqual(mongoose.Schema.Types.ObjectId);
7777
expect(
78-
getNestedFieldType(nestedModelSchema, 'engineNestedDocumentAndType.horsePower'),
78+
getNestedFieldType(nestedModelSchema, 'engineNestedDocumentAndType@@@horsePower'),
7979
).toStrictEqual(String);
8080
});
8181
});
8282
describe('when the nested field is not defined using a type', () => {
8383
it('should correctly detect the type', () => {
8484
expect.assertions(2);
8585
expect(
86-
getNestedFieldType(nestedModelSchema, 'engineNestedDocument._id'),
86+
getNestedFieldType(nestedModelSchema, 'engineNestedDocument@@@_id'),
8787
).toStrictEqual(mongoose.Schema.Types.ObjectId);
8888
expect(
89-
getNestedFieldType(nestedModelSchema, 'engineNestedDocument.horsePower'),
89+
getNestedFieldType(nestedModelSchema, 'engineNestedDocument@@@horsePower'),
9090
).toStrictEqual(String);
9191
});
9292
});
@@ -98,21 +98,21 @@ describe('schema', () => {
9898
it('should correctly detect the type', () => {
9999
expect.assertions(2);
100100
expect(
101-
getNestedFieldType(nestedModelSchema, 'engineNestedPathAndType._id'),
101+
getNestedFieldType(nestedModelSchema, 'engineNestedPathAndType@@@_id'),
102102
).toStrictEqual(mongoose.Schema.Types.ObjectId);
103103
expect(
104-
getNestedFieldType(nestedModelSchema, 'engineNestedPathAndType.horsePower'),
104+
getNestedFieldType(nestedModelSchema, 'engineNestedPathAndType@@@horsePower'),
105105
).toStrictEqual(String);
106106
});
107107
});
108108
describe('when the nested field is not defined using a type', () => {
109109
it('should correctly detect the type', () => {
110110
expect.assertions(2);
111111
expect(
112-
getNestedFieldType(nestedModelSchema, 'engineNestedPath._id'),
112+
getNestedFieldType(nestedModelSchema, 'engineNestedPath@@@_id'),
113113
).toStrictEqual(mongoose.Schema.Types.ObjectId);
114114
expect(
115-
getNestedFieldType(nestedModelSchema, 'engineNestedPath.horsePower'),
115+
getNestedFieldType(nestedModelSchema, 'engineNestedPath@@@horsePower'),
116116
).toStrictEqual(String);
117117
});
118118
});
@@ -123,7 +123,7 @@ describe('schema', () => {
123123
expect.assertions(1);
124124

125125
expect(
126-
getNestedFieldType(nestedModelSchema, 'engineNestedPath.notExisting'),
126+
getNestedFieldType(nestedModelSchema, 'engineNestedPath@@@notExisting'),
127127
).toBeUndefined();
128128
});
129129
});

0 commit comments

Comments
 (0)