Skip to content

#4678: Converting strings to Date when schema.type is Date within agg… #4743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fa8c902
#4678: Converting strings to Date when schema.type is Date within agg…
cjbland Apr 30, 2018
9a12b7c
Added test cases to test new date match aggregate query
cjbland Apr 30, 2018
044453a
Added function to parse match aggregate arguments and convert necessa…
cjbland May 1, 2018
90b43ba
Merge branch 'master' into fix/4678
cjbland May 1, 2018
1714711
Added missing return value
cjbland May 2, 2018
867863e
Merge branch 'fix/4678' of https://github.com/cjbland/parse-server in…
cjbland May 2, 2018
d922a7a
Improved code quality based on suggestions and figured out why tests …
cjbland May 4, 2018
7261ba0
Added tests from @dplewis
cjbland May 19, 2018
beb54bb
Supporting project aggregation as well as exists operator
cjbland May 19, 2018
403e81b
Merge branch 'master' into fix/4678
cjbland May 19, 2018
9526c65
Merge branch 'master' into fix/4678
cjbland May 19, 2018
7993f45
Merge branch 'fix/4678' of https://github.com/cjbland/parse-server in…
cjbland May 19, 2018
f8c06d9
Merge branch 'master' into fix/4678
cjbland May 22, 2018
abf42d9
Excluding exists match for postgres
cjbland May 23, 2018
f7edfa5
Merge branch 'master' into fix/4678
cjbland Jun 16, 2018
cdc90e2
Merge branch 'master' into fix/4678
cjbland Jun 16, 2018
52b2f7f
Merge branch 'fix/4678' of https://github.com/cjbland/parse-server in…
cjbland Jun 16, 2018
ae3ce3b
Merge branch 'master' into fix/4678
cjbland Jun 18, 2018
da3afbb
Handling the $group operator similar to $match and $project
cjbland Jun 19, 2018
a7c428d
Added more tests for better code coverage
cjbland Jun 20, 2018
cc25079
Excluding certain tests from being run on postgres
cjbland Jun 20, 2018
1a51a82
Excluding one more test from postgres
cjbland Jun 21, 2018
af531c1
clean up
dplewis Jun 24, 2018
6b8fded
Merge branch 'master' into fix/4678
dplewis Jun 26, 2018
f8d7826
Merge branch 'master' into fix/4678
dplewis Jun 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions spec/ParseQuery.Aggregate.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,124 @@ describe('Parse.Query Aggregate testing', () => {
});
});

it('group by date object transform', (done) => {
const obj1 = new TestObject();
const obj2 = new TestObject();
const obj3 = new TestObject();
const pipeline = [{
group: {
objectId: { day: { $dayOfMonth: "$updatedAt" }, month: { $month: "$createdAt" }, year: { $year: "$createdAt" } },
count: { $sum: 1 }
}
}];
Parse.Object.saveAll([obj1, obj2, obj3]).then(() => {
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
const createdAt = new Date(obj1.createdAt);
expect(results[0].objectId.day).toEqual(createdAt.getUTCDate());
expect(results[0].objectId.month).toEqual(createdAt.getMonth() + 1);
expect(results[0].objectId.year).toEqual(createdAt.getUTCFullYear());
done();
});
});

it_exclude_dbs(['postgres'])('group and multiply transform', (done) => {
const obj1 = new TestObject({ name: 'item a', quantity: 2, price: 10 });
const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 });
const pipeline = [{
group: {
objectId: null,
total: { $sum: { $multiply: [ '$quantity', '$price' ] } }
}
}];
Parse.Object.saveAll([obj1, obj2]).then(() => {
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(1);
expect(results[0].total).toEqual(45);
done();
});
});

it_exclude_dbs(['postgres'])('project and multiply transform', (done) => {
const obj1 = new TestObject({ name: 'item a', quantity: 2, price: 10 });
const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 });
const pipeline = [
{
match: { quantity: { $exists: true } }
},
{
project: {
name: 1,
total: { $multiply: [ '$quantity', '$price' ] }
}
}
];
Parse.Object.saveAll([obj1, obj2]).then(() => {
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(2);
if (results[0].name === 'item a') {
expect(results[0].total).toEqual(20);
expect(results[1].total).toEqual(25);
}
else {
expect(results[0].total).toEqual(25);
expect(results[1].total).toEqual(20);
}
done();
});
});

it_exclude_dbs(['postgres'])('project without objectId transform', (done) => {
const obj1 = new TestObject({ name: 'item a', quantity: 2, price: 10 });
const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 });
const pipeline = [
{
match: { quantity: { $exists: true } }
},
{
project: {
objectId: 0,
total: { $multiply: [ '$quantity', '$price' ] }
}
},
{
sort: { total: 1 }
}
];
Parse.Object.saveAll([obj1, obj2]).then(() => {
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(2);
expect(results[0].total).toEqual(20);
expect(results[0].objectId).toEqual(undefined);
expect(results[1].total).toEqual(25);
expect(results[1].objectId).toEqual(undefined);
done();
});
});

it_exclude_dbs(['postgres'])('project updatedAt only transform', (done) => {
const pipeline = [{
project: { objectId: 0, updatedAt: 1 }
}];
const query = new Parse.Query(TestObject);
query.aggregate(pipeline).then((results) => {
expect(results.length).toEqual(4);
for (let i = 0; i < results.length; i++) {
const item = results[i];
expect(item.hasOwnProperty('updatedAt')).toEqual(true);
expect(item.hasOwnProperty('objectId')).toEqual(false);
}
done();
});
});

it_exclude_dbs(['postgres'])('cannot group by date field (excluding createdAt and updatedAt)', (done) => {
const obj1 = new TestObject({ dateField: new Date(1990, 11, 1) });
const obj2 = new TestObject({ dateField: new Date(1990, 5, 1) });
Expand Down Expand Up @@ -339,6 +457,27 @@ describe('Parse.Query Aggregate testing', () => {
}).catch(done.fail);
});

it('match comparison date query', (done) => {
const today = new Date();
const yesterday = new Date();
const tomorrow = new Date();
yesterday.setDate(today.getDate() - 1);
tomorrow.setDate(today.getDate() + 1);
const obj1 = new TestObject({ dateField: yesterday });
const obj2 = new TestObject({ dateField: today });
const obj3 = new TestObject({ dateField: tomorrow });
const pipeline = [
{ match: { dateField: { $lt: tomorrow } } }
];
Parse.Object.saveAll([obj1, obj2, obj3]).then(() => {
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toBe(2);
done();
});
});

it('match comparison query', (done) => {
const options = Object.assign({}, masterKeyOptions, {
body: {
Expand Down Expand Up @@ -474,6 +613,96 @@ describe('Parse.Query Aggregate testing', () => {
});
});

it_exclude_dbs(['postgres'])('match exists query', (done) => {
const pipeline = [
{ match: { score: { $exists: true } } }
];
const query = new Parse.Query(TestObject);
query.aggregate(pipeline).then((results) => {
expect(results.length).toEqual(4);
done();
});
});

it('match date query - createdAt', (done) => {
const obj1 = new TestObject();
const obj2 = new TestObject();

Parse.Object.saveAll([obj1, obj2]).then(() => {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const pipeline = [
{ match: { 'createdAt': { $gte: today } } }
];
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
// Four objects were created initially, we added two more.
expect(results.length).toEqual(6);
done();
});
});

it('match date query - updatedAt', (done) => {
const obj1 = new TestObject();
const obj2 = new TestObject();

Parse.Object.saveAll([obj1, obj2]).then(() => {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const pipeline = [
{ match: { 'updatedAt': { $gte: today } } }
];
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
// Four objects were added initially, we added two more.
expect(results.length).toEqual(6);
done();
});
});

it('match date query - empty', (done) => {
const obj1 = new TestObject();
const obj2 = new TestObject();

Parse.Object.saveAll([obj1, obj2]).then(() => {
const now = new Date();
const future = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate());
const pipeline = [
{ match: { 'createdAt': future } }
];
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(0);
done();
});
});

it_exclude_dbs(['postgres'])('match pointer with operator query', (done) => {
const pointer = new PointerObject();

const obj1 = new TestObject({ pointer });
const obj2 = new TestObject({ pointer });
const obj3 = new TestObject();

Parse.Object.saveAll([pointer, obj1, obj2, obj3]).then(() => {
const pipeline = [
{ match: { pointer: { $exists: true } } }
];
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(2);
expect(results[0].pointer.objectId).toEqual(pointer.id);
expect(results[1].pointer.objectId).toEqual(pointer.id);
expect(results.some(result => result.objectId === obj1.id)).toEqual(true);
expect(results.some(result => result.objectId === obj2.id)).toEqual(true);
done();
});
});

it('project query', (done) => {
const options = Object.assign({}, masterKeyOptions, {
body: {
Expand Down Expand Up @@ -512,6 +741,26 @@ describe('Parse.Query Aggregate testing', () => {
}).catch(done.fail);
});

it('project pointer query', (done) => {
const pointer = new PointerObject();
const obj = new TestObject({ pointer, name: 'hello' });

obj.save().then(() => {
const pipeline = [
{ match: { objectId: obj.id } },
{ project: { pointer: 1, name: 1, createdAt: 1 } }
];
const query = new Parse.Query(TestObject);
return query.aggregate(pipeline);
}).then((results) => {
expect(results.length).toEqual(1);
expect(results[0].name).toEqual('hello');
expect(results[0].createdAt).not.toBe(undefined);
expect(results[0].pointer.objectId).toEqual(pointer.id);
done();
});
});

it('project with group query', (done) => {
const options = Object.assign({}, masterKeyOptions, {
body: {
Expand Down
Loading