Skip to content

Commit f88aa2a

Browse files
authored
feat: upgrade to MongoDB Node.js driver 4.x for MongoDB 5.0 support (#7794)
BREAKING CHANGE: The MongoDB GridStore adapter has been removed. By default, Parse Server already uses GridFS, so if you do not manually use the GridStore adapter, you can ignore this change.
1 parent 1299f06 commit f88aa2a

13 files changed

+393
-669
lines changed

package-lock.json

+115-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"lodash": "4.17.21",
4646
"lru-cache": "5.1.1",
4747
"mime": "3.0.0",
48-
"mongodb": "3.6.11",
48+
"mongodb": "4.3.1",
4949
"mustache": "4.2.0",
5050
"parse": "3.4.1",
5151
"pg-monitor": "1.4.1",
@@ -118,12 +118,13 @@
118118
"test:mongodb:4.0.27": "npm run test:mongodb --dbversion=4.0.27",
119119
"test:mongodb:4.2.17": "npm run test:mongodb --dbversion=4.2.17",
120120
"test:mongodb:4.4.10": "npm run test:mongodb --dbversion=4.4.10",
121+
"test:mongodb:5.0.5": "npm run test:mongodb --dbversion=5.0.5",
121122
"posttest:mongodb": "mongodb-runner stop",
122-
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.4.10} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start",
123-
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.4.10} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine",
123+
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.0.5} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start",
124+
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.0.5} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine",
124125
"test": "npm run testonly",
125-
"posttest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.4.10} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner stop",
126-
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.4.10} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 nyc jasmine",
126+
"posttest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.0.5} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner stop",
127+
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.0.5} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 nyc jasmine",
127128
"start": "node ./bin/parse-server",
128129
"prettier": "prettier --write {src,spec}/{**/*,*}.js",
129130
"prepare": "npm run build",

spec/AudienceRouter.spec.js

+15-14
Original file line numberDiff line numberDiff line change
@@ -326,22 +326,24 @@ describe('AudiencesRouter', () => {
326326
{ name: 'My Audience', query: JSON.stringify({ deviceType: 'ios' }) },
327327
{ useMasterKey: true }
328328
).then(audience => {
329-
database.collection('test__Audience').updateOne(
330-
{ _id: audience.objectId },
331-
{
332-
$set: {
333-
times_used: 1,
334-
_last_used: now,
335-
},
336-
},
337-
{},
338-
error => {
339-
expect(error).toEqual(null);
329+
database
330+
.collection('test__Audience')
331+
.updateOne(
332+
{ _id: audience.objectId },
333+
{
334+
$set: {
335+
times_used: 1,
336+
_last_used: now,
337+
},
338+
}
339+
)
340+
.then(result => {
341+
expect(result).toBeTruthy();
340342
database
341343
.collection('test__Audience')
342344
.find({ _id: audience.objectId })
343345
.toArray((error, rows) => {
344-
expect(error).toEqual(null);
346+
expect(error).toEqual(undefined);
345347
expect(rows[0]['times_used']).toEqual(1);
346348
expect(rows[0]['_last_used']).toEqual(now);
347349
Parse._request(
@@ -361,8 +363,7 @@ describe('AudiencesRouter', () => {
361363
done.fail(error);
362364
});
363365
});
364-
}
365-
);
366+
});
366367
});
367368
});
368369

spec/FilesController.spec.js

+21-22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ const WinstonLoggerAdapter = require('../lib/Adapters/Logger/WinstonLoggerAdapte
33
.WinstonLoggerAdapter;
44
const GridFSBucketAdapter = require('../lib/Adapters/Files/GridFSBucketAdapter')
55
.GridFSBucketAdapter;
6-
const GridStoreAdapter = require('../lib/Adapters/Files/GridStoreAdapter').GridStoreAdapter;
76
const Config = require('../lib/Config');
87
const FilesController = require('../lib/Controllers/FilesController').default;
98
const databaseURI = 'mongodb://localhost:27017/parse';
@@ -24,8 +23,8 @@ const mockAdapter = {
2423
describe('FilesController', () => {
2524
it('should properly expand objects', done => {
2625
const config = Config.get(Parse.applicationId);
27-
const gridStoreAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
28-
const filesController = new FilesController(gridStoreAdapter);
26+
const gridFSAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
27+
const filesController = new FilesController(gridFSAdapter);
2928
const result = filesController.expandFilesInObject(config, function () {});
3029

3130
expect(result).toBeUndefined();
@@ -88,19 +87,19 @@ describe('FilesController', () => {
8887

8988
it('should add a unique hash to the file name when the preserveFileName option is false', done => {
9089
const config = Config.get(Parse.applicationId);
91-
const gridStoreAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
92-
spyOn(gridStoreAdapter, 'createFile');
93-
gridStoreAdapter.createFile.and.returnValue(Promise.resolve());
90+
const gridFSAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
91+
spyOn(gridFSAdapter, 'createFile');
92+
gridFSAdapter.createFile.and.returnValue(Promise.resolve());
9493
const fileName = 'randomFileName.pdf';
9594
const regexEscapedFileName = fileName.replace(/\./g, '\\$&');
96-
const filesController = new FilesController(gridStoreAdapter, null, {
95+
const filesController = new FilesController(gridFSAdapter, null, {
9796
preserveFileName: false,
9897
});
9998

10099
filesController.createFile(config, fileName);
101100

102-
expect(gridStoreAdapter.createFile).toHaveBeenCalledTimes(1);
103-
expect(gridStoreAdapter.createFile.calls.mostRecent().args[0]).toMatch(
101+
expect(gridFSAdapter.createFile).toHaveBeenCalledTimes(1);
102+
expect(gridFSAdapter.createFile.calls.mostRecent().args[0]).toMatch(
104103
`^.{32}_${regexEscapedFileName}$`
105104
);
106105

@@ -109,42 +108,42 @@ describe('FilesController', () => {
109108

110109
it('should not add a unique hash to the file name when the preserveFileName option is true', done => {
111110
const config = Config.get(Parse.applicationId);
112-
const gridStoreAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
113-
spyOn(gridStoreAdapter, 'createFile');
114-
gridStoreAdapter.createFile.and.returnValue(Promise.resolve());
111+
const gridFSAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
112+
spyOn(gridFSAdapter, 'createFile');
113+
gridFSAdapter.createFile.and.returnValue(Promise.resolve());
115114
const fileName = 'randomFileName.pdf';
116-
const filesController = new FilesController(gridStoreAdapter, null, {
115+
const filesController = new FilesController(gridFSAdapter, null, {
117116
preserveFileName: true,
118117
});
119118

120119
filesController.createFile(config, fileName);
121120

122-
expect(gridStoreAdapter.createFile).toHaveBeenCalledTimes(1);
123-
expect(gridStoreAdapter.createFile.calls.mostRecent().args[0]).toEqual(fileName);
121+
expect(gridFSAdapter.createFile).toHaveBeenCalledTimes(1);
122+
expect(gridFSAdapter.createFile.calls.mostRecent().args[0]).toEqual(fileName);
124123

125124
done();
126125
});
127126

128127
it('should handle adapter without getMetadata', async () => {
129-
const gridStoreAdapter = new GridFSBucketAdapter(databaseURI);
130-
gridStoreAdapter.getMetadata = null;
131-
const filesController = new FilesController(gridStoreAdapter);
128+
const gridFSAdapter = new GridFSBucketAdapter(databaseURI);
129+
gridFSAdapter.getMetadata = null;
130+
const filesController = new FilesController(gridFSAdapter);
132131

133132
const result = await filesController.getMetadata();
134133
expect(result).toEqual({});
135134
});
136135

137136
it('should reject slashes in file names', done => {
138-
const gridStoreAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
137+
const gridFSAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
139138
const fileName = 'foo/randomFileName.pdf';
140-
expect(gridStoreAdapter.validateFilename(fileName)).not.toBe(null);
139+
expect(gridFSAdapter.validateFilename(fileName)).not.toBe(null);
141140
done();
142141
});
143142

144143
it('should also reject slashes in file names', done => {
145-
const gridStoreAdapter = new GridStoreAdapter('mongodb://localhost:27017/parse');
144+
const gridFSAdapter = new GridFSBucketAdapter('mongodb://localhost:27017/parse');
146145
const fileName = 'foo/randomFileName.pdf';
147-
expect(gridStoreAdapter.validateFilename(fileName)).not.toBe(null);
146+
expect(gridFSAdapter.validateFilename(fileName)).not.toBe(null);
148147
done();
149148
});
150149
});

0 commit comments

Comments
 (0)