Skip to content

Commit a421015

Browse files
authored
Silences warnings from mongodb client (#5025)
* Silences warnings from mongodb client * Update count, delete and finds to recommended implementations * With new parser, readPref will be null by default * Update flaky specs wih async/await style * Adds gridstore adapter spec * Use GridFSBucketStorage adapter
1 parent d83a0b6 commit a421015

14 files changed

+270
-114
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,11 @@ You can also find more adapters maintained by the community by searching on [npm
375375

376376
Parse Server allows developers to choose from several options when hosting files:
377377

378-
* `GridStoreAdapter`, which is backed by MongoDB;
378+
* `GridFSBucketAdapter`, which is backed by MongoDB;
379379
* `S3Adapter`, which is backed by [Amazon S3](https://aws.amazon.com/s3/); or
380380
* `GCSAdapter`, which is backed by [Google Cloud Storage](https://cloud.google.com/storage/)
381381

382-
`GridStoreAdapter` is used by default and requires no setup, but if you're interested in using S3 or Google Cloud Storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters).
382+
`GridFSBucketAdapter` is used by default and requires no setup, but if you're interested in using S3 or Google Cloud Storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters).
383383

384384
# Upgrading to 3.0.0
385385

spec/FilesController.spec.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ const LoggerController = require('../lib/Controllers/LoggerController')
22
.LoggerController;
33
const WinstonLoggerAdapter = require('../lib/Adapters/Logger/WinstonLoggerAdapter')
44
.WinstonLoggerAdapter;
5-
const GridStoreAdapter = require('../lib/Adapters/Files/GridStoreAdapter')
6-
.GridStoreAdapter;
5+
const GridFSBucketAdapter = require('../lib/Adapters/Files/GridFSBucketAdapter')
6+
.GridFSBucketAdapter;
77
const Config = require('../lib/Config');
88
const FilesController = require('../lib/Controllers/FilesController').default;
99

@@ -20,7 +20,7 @@ const mockAdapter = {
2020
describe('FilesController', () => {
2121
it('should properly expand objects', done => {
2222
const config = Config.get(Parse.applicationId);
23-
const gridStoreAdapter = new GridStoreAdapter(
23+
const gridStoreAdapter = new GridFSBucketAdapter(
2424
'mongodb://localhost:27017/parse'
2525
);
2626
const filesController = new FilesController(gridStoreAdapter);
@@ -72,7 +72,7 @@ describe('FilesController', () => {
7272

7373
it('should add a unique hash to the file name when the preserveFileName option is false', done => {
7474
const config = Config.get(Parse.applicationId);
75-
const gridStoreAdapter = new GridStoreAdapter(
75+
const gridStoreAdapter = new GridFSBucketAdapter(
7676
'mongodb://localhost:27017/parse'
7777
);
7878
spyOn(gridStoreAdapter, 'createFile');
@@ -95,7 +95,7 @@ describe('FilesController', () => {
9595

9696
it('should not add a unique hash to the file name when the preserveFileName option is true', done => {
9797
const config = Config.get(Parse.applicationId);
98-
const gridStoreAdapter = new GridStoreAdapter(
98+
const gridStoreAdapter = new GridFSBucketAdapter(
9999
'mongodb://localhost:27017/parse'
100100
);
101101
spyOn(gridStoreAdapter, 'createFile');
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const GridStoreAdapter = require('../lib/Adapters/Files/GridStoreAdapter')
2+
.GridStoreAdapter;
3+
const GridFSBucketAdapter = require('../lib/Adapters/Files/GridFSBucketAdapter')
4+
.GridFSBucketAdapter;
5+
const { randomString } = require('../lib/cryptoUtils');
6+
const databaseURI = 'mongodb://localhost:27017/parse';
7+
8+
async function expectMissingFile(gfsAdapter, name) {
9+
try {
10+
await gfsAdapter.getFileData(name);
11+
fail('should have thrown');
12+
} catch (e) {
13+
expect(e.message).toEqual('FileNotFound: file myFileName was not found');
14+
}
15+
}
16+
17+
describe('GridFSBucket and GridStore interop', () => {
18+
beforeEach(async () => {
19+
const gsAdapter = new GridStoreAdapter(databaseURI);
20+
const db = await gsAdapter._connect();
21+
db.dropDatabase();
22+
});
23+
24+
it('a file created in GridStore should be available in GridFS', async () => {
25+
const gsAdapter = new GridStoreAdapter(databaseURI);
26+
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
27+
await expectMissingFile(gfsAdapter, 'myFileName');
28+
const originalString = 'abcdefghi';
29+
await gsAdapter.createFile('myFileName', originalString);
30+
const gsResult = await gsAdapter.getFileData('myFileName');
31+
expect(gsResult.toString('utf8')).toBe(originalString);
32+
const gfsResult = await gfsAdapter.getFileData('myFileName');
33+
expect(gfsResult.toString('utf8')).toBe(originalString);
34+
});
35+
36+
it('properly fetches a large file from GridFS', async () => {
37+
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
38+
const twoMegabytesFile = randomString(2048 * 1024);
39+
await gfsAdapter.createFile('myFileName', twoMegabytesFile);
40+
const gfsResult = await gfsAdapter.getFileData('myFileName');
41+
expect(gfsResult.toString('utf8')).toBe(twoMegabytesFile);
42+
});
43+
44+
it(
45+
'properly deletes a file from GridFS',
46+
async () => {
47+
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
48+
await gfsAdapter.createFile('myFileName', 'a simple file');
49+
await gfsAdapter.deleteFile('myFileName');
50+
await expectMissingFile(gfsAdapter, 'myFileName');
51+
},
52+
1000000
53+
);
54+
55+
it('properly overrides files', async () => {
56+
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
57+
await gfsAdapter.createFile('myFileName', 'a simple file');
58+
await gfsAdapter.createFile('myFileName', 'an overrided simple file');
59+
const data = await gfsAdapter.getFileData('myFileName');
60+
expect(data.toString('utf8')).toBe('an overrided simple file');
61+
const bucket = await gfsAdapter._getBucket();
62+
const documents = await bucket.find({ filename: 'myFileName' }).toArray();
63+
expect(documents.length).toBe(2);
64+
await gfsAdapter.deleteFile('myFileName');
65+
await expectMissingFile(gfsAdapter, 'myFileName');
66+
});
67+
});

spec/GridStoreAdapter.js spec/GridStoreAdapter.spec.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ const FilesController = require('../lib/Controllers/FilesController').default;
88

99
// Small additional tests to improve overall coverage
1010
describe_only_db('mongo')('GridStoreAdapter', () => {
11-
it('should properly instanciate the GridStore when deleting a file', done => {
11+
it('should properly instanciate the GridStore when deleting a file', async done => {
1212
const databaseURI = 'mongodb://localhost:27017/parse';
1313
const config = Config.get(Parse.applicationId);
1414
const gridStoreAdapter = new GridStoreAdapter(databaseURI);
15-
const filesController = new FilesController(gridStoreAdapter);
15+
const db = await gridStoreAdapter._connect();
16+
db.dropDatabase();
17+
const filesController = new FilesController(
18+
gridStoreAdapter,
19+
Parse.applicationId,
20+
{}
21+
);
1622

1723
// save original unlink before redefinition
1824
const originalUnlink = GridStore.prototype.unlink;
@@ -33,24 +39,25 @@ describe_only_db('mongo')('GridStoreAdapter', () => {
3339
.createFile(config, 'myFilename.txt', 'my file content', 'text/plain')
3440
.then(myFile => {
3541
return MongoClient.connect(databaseURI)
36-
.then(database => {
42+
.then(client => {
43+
const database = client.db(client.s.options.dbName);
3744
// Verify the existance of the fs.files document
3845
return database
3946
.collection('fs.files')
4047
.count()
4148
.then(count => {
4249
expect(count).toEqual(1);
43-
return database;
50+
return { database, client };
4451
});
4552
})
46-
.then(database => {
53+
.then(({ database, client }) => {
4754
// Verify the existance of the fs.files document
4855
return database
4956
.collection('fs.chunks')
5057
.count()
5158
.then(count => {
5259
expect(count).toEqual(1);
53-
return database.close();
60+
return client.close();
5461
});
5562
})
5663
.then(() => {
@@ -59,24 +66,25 @@ describe_only_db('mongo')('GridStoreAdapter', () => {
5966
})
6067
.then(() => {
6168
return MongoClient.connect(databaseURI)
62-
.then(database => {
69+
.then(client => {
70+
const database = client.db(client.s.options.dbName);
6371
// Verify the existance of the fs.files document
6472
return database
6573
.collection('fs.files')
6674
.count()
6775
.then(count => {
6876
expect(count).toEqual(0);
69-
return database;
77+
return { database, client };
7078
});
7179
})
72-
.then(database => {
80+
.then(({ database, client }) => {
7381
// Verify the existance of the fs.files document
7482
return database
7583
.collection('fs.chunks')
7684
.count()
7785
.then(count => {
7886
expect(count).toEqual(0);
79-
return database.close();
87+
return client.close();
8088
});
8189
});
8290
})

spec/ParseFile.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ describe('Parse.File testing', () => {
689689
);
690690
});
691691

692-
describe_only_db('mongo')('Gridstore Range tests', () => {
692+
xdescribe('Gridstore Range tests', () => {
693693
it('supports range requests', done => {
694694
const headers = {
695695
'Content-Type': 'application/octet-stream',
@@ -796,7 +796,7 @@ describe('Parse.File testing', () => {
796796
);
797797
});
798798

799-
it('supports getting last n bytes', done => {
799+
xit('supports getting last n bytes', done => {
800800
const headers = {
801801
'Content-Type': 'application/octet-stream',
802802
'X-Parse-Application-Id': 'test',

spec/ParseUser.spec.js

+28-40
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,8 @@ describe('Parse.User testing', () => {
277277
expect(newUser).not.toBeUndefined();
278278
});
279279

280-
it('should be let masterKey lock user out with authData', done => {
281-
let objectId;
282-
let sessionToken;
283-
284-
rp.post({
280+
it('should be let masterKey lock user out with authData', async () => {
281+
const body = await rp.post({
285282
url: 'http://localhost:8378/1/classes/_User',
286283
headers: {
287284
'X-Parse-Application-Id': Parse.applicationId,
@@ -291,41 +288,32 @@ describe('Parse.User testing', () => {
291288
key: 'value',
292289
authData: { anonymous: { id: '00000000-0000-0000-0000-000000000001' } },
293290
},
294-
})
295-
.then(body => {
296-
objectId = body.objectId;
297-
sessionToken = body.sessionToken;
298-
expect(sessionToken).toBeDefined();
299-
expect(objectId).toBeDefined();
300-
const user = new Parse.User();
301-
user.id = objectId;
302-
const ACL = new Parse.ACL();
303-
user.setACL(ACL);
304-
return user.save(null, { useMasterKey: true });
305-
})
306-
.then(() => {
307-
// update the user
308-
const options = {
309-
url: `http://localhost:8378/1/classes/_User/`,
310-
headers: {
311-
'X-Parse-Application-Id': Parse.applicationId,
312-
'X-Parse-REST-API-Key': 'rest',
313-
},
314-
json: {
315-
key: 'otherValue',
316-
authData: {
317-
anonymous: { id: '00000000-0000-0000-0000-000000000001' },
318-
},
319-
},
320-
};
321-
return rp.post(options);
322-
})
323-
.then(res => {
324-
// Because the user is locked out, this should behave as creating a new user
325-
expect(res.objectId).not.toEqual(objectId);
326-
})
327-
.then(done)
328-
.catch(done.fail);
291+
});
292+
const objectId = body.objectId;
293+
const sessionToken = body.sessionToken;
294+
expect(sessionToken).toBeDefined();
295+
expect(objectId).toBeDefined();
296+
const user = new Parse.User();
297+
user.id = objectId;
298+
const ACL = new Parse.ACL();
299+
user.setACL(ACL);
300+
await user.save(null, { useMasterKey: true });
301+
// update the user
302+
const options = {
303+
url: `http://localhost:8378/1/classes/_User/`,
304+
headers: {
305+
'X-Parse-Application-Id': Parse.applicationId,
306+
'X-Parse-REST-API-Key': 'rest',
307+
},
308+
json: {
309+
key: 'otherValue',
310+
authData: {
311+
anonymous: { id: '00000000-0000-0000-0000-000000000001' },
312+
},
313+
},
314+
};
315+
const res = await rp.post(options);
316+
expect(res.objectId).not.toEqual(objectId);
329317
});
330318

331319
it('user login with files', done => {

0 commit comments

Comments
 (0)