Skip to content

Commit

Permalink
feat: Remove deprecation DEPPS1: Native MongoDB syntax in aggregati…
Browse files Browse the repository at this point in the history
…on pipeline (parse-community#8362)

BREAKING CHANGE: The MongoDB aggregation pipeline requires native MongoDB syntax instead of the custom Parse Server syntax; for example pipeline stage names require a leading dollar sign like `$match` and the MongoDB document ID is referenced using `_id` instead of `objectId` (parse-community#8362)
  • Loading branch information
dblythy committed Feb 15, 2023
1 parent e364c11 commit 48f1bc6
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 148 deletions.
2 changes: 1 addition & 1 deletion DEPRECATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h

| ID | Change | Issue | Deprecation [ℹ️][i_deprecation] | Planned Removal [ℹ️][i_removal] | Status [ℹ️][i_status] | Notes |
|--------|-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------|
| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - |
| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
| DEPPS2 | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
| DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
| DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
Expand Down
74 changes: 42 additions & 32 deletions spec/AggregateRouter.spec.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
const AggregateRouter = require('../lib/Routers/AggregateRouter').AggregateRouter;

describe('AggregateRouter', () => {
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Array', () => {
const body = [
{
group: { objectId: {} },
$group: { _id: {} },
},
];
const expected = [{ $group: { _id: {} } }];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Object', () => {
const body = {
group: { objectId: {} },
$group: { _id: {} },
};
const expected = [{ $group: { _id: {} } }];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Pipeline Operator (Array)', () => {
const body = {
pipeline: [
{
group: { objectId: {} },
$group: { _id: {} },
},
],
};
Expand All @@ -37,55 +34,53 @@ describe('AggregateRouter', () => {
expect(result).toEqual(expected);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Pipeline Operator (Object)', () => {
const body = {
pipeline: {
group: { objectId: {} },
$group: { _id: {} },
},
};
const expected = [{ $group: { _id: {} } }];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline fails multiple keys in Array stage ', () => {
const body = [
{
group: { objectId: {} },
match: { name: 'Test' },
$group: { _id: {} },
$match: { name: 'Test' },
},
];
try {
AggregateRouter.getPipeline(body);
} catch (e) {
expect(e.message).toBe('Pipeline stages should only have one key found group, match');
}
expect(() => AggregateRouter.getPipeline(body)).toThrow(
new Parse.Error(
Parse.Error.INVALID_QUERY,
'Pipeline stages should only have one key but found $group, $match.'
)
);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline fails multiple keys in Pipeline Operator Array stage ', () => {
const body = {
pipeline: [
{
group: { objectId: {} },
match: { name: 'Test' },
$group: { _id: {} },
$match: { name: 'Test' },
},
],
};
try {
AggregateRouter.getPipeline(body);
} catch (e) {
expect(e.message).toBe('Pipeline stages should only have one key found group, match');
}
expect(() => AggregateRouter.getPipeline(body)).toThrow(
new Parse.Error(
Parse.Error.INVALID_QUERY,
'Pipeline stages should only have one key but found $group, $match.'
)
);
});

// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get search pipeline from Pipeline Operator (Array)', () => {
const body = {
pipeline: {
search: {},
$search: {},
},
};
const expected = [{ $search: {} }];
Expand All @@ -105,7 +100,7 @@ describe('AggregateRouter', () => {
it('support nested stage names starting with `$`', () => {
const body = [
{
lookup: {
$lookup: {
from: 'ACollection',
let: { id: '_id' },
as: 'results',
Expand Down Expand Up @@ -145,11 +140,11 @@ describe('AggregateRouter', () => {

it('support the use of `_id` in stages', () => {
const body = [
{ match: { _id: 'randomId' } },
{ sort: { _id: -1 } },
{ addFields: { _id: 1 } },
{ group: { _id: {} } },
{ project: { _id: 0 } },
{ $match: { _id: 'randomId' } },
{ $sort: { _id: -1 } },
{ $addFields: { _id: 1 } },
{ $group: { _id: {} } },
{ $project: { _id: 0 } },
];
const expected = [
{ $match: { _id: 'randomId' } },
Expand All @@ -161,4 +156,19 @@ describe('AggregateRouter', () => {
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});

it('should throw with invalid stage', () => {
expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow(
new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`)
);
});

it('should throw with invalid group', () => {
expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow(
new Parse.Error(
Parse.Error.INVALID_QUERY,
`Cannot use 'objectId' in aggregation stage $group.`
)
);
});
});
2 changes: 1 addition & 1 deletion spec/CloudCode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2774,7 +2774,7 @@ describe('afterFind hooks', () => {
const obj = new Parse.Object('MyObject');
const pipeline = [
{
group: { objectId: {} },
$group: { _id: {} },
},
];
obj
Expand Down
Loading

0 comments on commit 48f1bc6

Please sign in to comment.