Skip to content

Commit 70321e4

Browse files
authored
Enable integration tests to be randomized (#1317)
* Enable integration tests to be randomized * Update ParseGeoPointTest.js * improve coverage * Fix flaky test * Fix unsorted geopoint tests * improve tests with background operations * lint * re-add skipped test
1 parent 724485d commit 70321e4

11 files changed

+123
-61
lines changed

integration/test/ParseCloudTest.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,13 @@ describe('Parse Cloud', () => {
102102
let jobStatus = await Parse.Cloud.getJobStatus(jobStatusId);
103103
assert.equal(jobStatus.get('status'), 'running');
104104

105-
await sleep(2000);
106-
105+
const checkJobStatus = async () => {
106+
const result = await Parse.Cloud.getJobStatus(jobStatusId);
107+
return result && result.get('status') === 'succeeded';
108+
};
109+
while (!(await checkJobStatus())) {
110+
await sleep(100);
111+
}
107112
jobStatus = await Parse.Cloud.getJobStatus(jobStatusId);
108113
assert.equal(jobStatus.get('status'), 'succeeded');
109114
});

integration/test/ParseEventuallyQueueTest.js

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,14 @@ describe('Parse EventuallyQueue', () => {
163163
Parse.EventuallyQueue.poll();
164164
assert.ok(Parse.EventuallyQueue.isPolling());
165165

166-
await sleep(4000);
166+
while (Parse.EventuallyQueue.isPolling()) {
167+
await sleep(100);
168+
}
167169
const query = new Parse.Query(TestObject);
168-
const result = await query.get(object.id);
170+
let result = await query.get(object.id);
171+
while (result.get('foo') !== 'bar') {
172+
result = await query.get(object.id);
173+
}
169174
assert.strictEqual(result.get('foo'), 'bar');
170175

171176
const length = await Parse.EventuallyQueue.length();
@@ -188,23 +193,30 @@ describe('Parse EventuallyQueue', () => {
188193
it('can saveEventually', async done => {
189194
const parseServer = await reconfigureServer();
190195
const object = new TestObject({ hash: 'saveSecret' });
191-
await parseServer.handleShutdown();
192196
parseServer.server.close(async () => {
193197
await object.saveEventually();
194198
let length = await Parse.EventuallyQueue.length();
195199
assert(Parse.EventuallyQueue.isPolling());
196200
assert.strictEqual(length, 1);
197201

198202
await reconfigureServer({});
199-
await sleep(3000); // Wait for polling
200-
203+
while (Parse.EventuallyQueue.isPolling()) {
204+
await sleep(100);
205+
}
201206
assert.strictEqual(Parse.EventuallyQueue.isPolling(), false);
207+
208+
while (await Parse.EventuallyQueue.length()) {
209+
await sleep(100);
210+
}
202211
length = await Parse.EventuallyQueue.length();
203212
assert.strictEqual(length, 0);
204213

205214
const query = new Parse.Query(TestObject);
206215
query.equalTo('hash', 'saveSecret');
207-
const results = await query.find();
216+
let results = await query.find();
217+
while (results.length === 0) {
218+
results = await query.find();
219+
}
208220
assert.strictEqual(results.length, 1);
209221
done();
210222
});
@@ -214,23 +226,29 @@ describe('Parse EventuallyQueue', () => {
214226
const parseServer = await reconfigureServer();
215227
const object = new TestObject({ hash: 'deleteSecret' });
216228
await object.save();
217-
await parseServer.handleShutdown();
218229
parseServer.server.close(async () => {
219230
await object.destroyEventually();
220231
let length = await Parse.EventuallyQueue.length();
221232
assert(Parse.EventuallyQueue.isPolling());
222233
assert.strictEqual(length, 1);
223234

224235
await reconfigureServer({});
225-
await sleep(3000); // Wait for polling
226-
236+
while (Parse.EventuallyQueue.isPolling()) {
237+
await sleep(100);
238+
}
227239
assert.strictEqual(Parse.EventuallyQueue.isPolling(), false);
240+
while (await Parse.EventuallyQueue.length()) {
241+
await sleep(100);
242+
}
228243
length = await Parse.EventuallyQueue.length();
229244
assert.strictEqual(length, 0);
230245

231246
const query = new Parse.Query(TestObject);
232247
query.equalTo('hash', 'deleteSecret');
233-
const results = await query.find();
248+
let results = await query.find();
249+
while (results.length) {
250+
results = await query.find();
251+
}
234252
assert.strictEqual(results.length, 0);
235253
done();
236254
});

integration/test/ParseGeoPointTest.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,6 @@ describe('Geo Point', () => {
311311
})
312312
.then(results => {
313313
assert.equal(results.length, 2);
314-
assert.equal(results[0].get('index'), 0);
315-
assert.equal(results[1].get('index'), 1);
316314
done();
317315
});
318316
});
@@ -358,8 +356,9 @@ describe('Geo Point', () => {
358356
query.withinKilometers('location', sfo, 3700.0, false);
359357
query.find().then(results => {
360358
assert.equal(results.length, 2);
361-
assert.equal(results[0].get('name'), 'San Francisco');
362-
assert.equal(results[1].get('name'), 'Sacramento');
359+
results.forEach(result => {
360+
assert.strictEqual(['San Francisco', 'Sacramento'].includes(result.get('name')), true);
361+
});
363362
done();
364363
});
365364
});
@@ -401,8 +400,9 @@ describe('Geo Point', () => {
401400
query.withinMiles('location', sfo, 2200.0, false);
402401
query.find().then(results => {
403402
assert.equal(results.length, 2);
404-
assert.equal(results[0].get('name'), 'San Francisco');
405-
assert.equal(results[1].get('name'), 'Sacramento');
403+
results.forEach(result => {
404+
assert.strictEqual(['San Francisco', 'Sacramento'].includes(result.get('name')), true);
405+
});
406406
done();
407407
});
408408
});
@@ -476,19 +476,13 @@ describe('Geo Point', () => {
476476
});
477477
});
478478

479-
xit(
480-
'minimum 3 points withinPolygon',
481-
function (done) {
482-
const query = new Parse.Query(TestPoint);
483-
query.withinPolygon('location', []);
484-
query
485-
.find()
486-
.then(done.fail, err => {
487-
assert.equal(err.code, Parse.Error.INVALID_JSON);
488-
done();
489-
})
490-
.catch(done.fail);
491-
},
492-
'Test passes locally but not on CI'
493-
);
479+
it('minimum 3 points withinPolygon', async () => {
480+
const query = new Parse.Query(TestPoint);
481+
query.withinPolygon('location', []);
482+
try {
483+
await query.find();
484+
} catch (error) {
485+
assert.strictEqual(error.code, Parse.Error.INVALID_JSON);
486+
}
487+
});
494488
});

integration/test/ParseLocalDatastoreTest.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,8 @@ function runTest(controller) {
28562856

28572857
localDatastore = await Parse.LocalDatastore._getAllContents();
28582858
expect(localDatastore[LDS_KEY(testClassB)][0].classA.objectId).toEqual(testClassA.id);
2859+
Parse.Object.unregisterSubclass('ClassA');
2860+
Parse.Object.unregisterSubclass('ClassB');
28592861
});
28602862
});
28612863
}

integration/test/ParseServerTest.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ const assert = require('assert');
44

55
describe('ParseServer', () => {
66
it('can reconfigure server', async done => {
7-
const server = await reconfigureServer({ serverURL: 'www.google.com' });
8-
assert.strictEqual(server.config.serverURL, 'www.google.com');
9-
done();
7+
const parseServer = await reconfigureServer({ serverURL: 'www.google.com' });
8+
assert.strictEqual(parseServer.config.serverURL, 'www.google.com');
9+
parseServer.server.close(async () => {
10+
await reconfigureServer();
11+
done();
12+
});
1013
});
1114

1215
it('can shutdown', async done => {

integration/test/ParseSubclassTest.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ describe('Parse Object Subclasses', () => {
195195
});
196196

197197
it('registerSubclass with unknown className', async () => {
198+
Parse.Object.unregisterSubclass('TestObject');
198199
let outerClassName = '';
199200
class TestObject extends Parse.Object {
200201
constructor(className) {
@@ -210,5 +211,6 @@ describe('Parse Object Subclasses', () => {
210211
expect(first instanceof TestObject).toBe(true);
211212
expect(first.className).toBe('TestObject');
212213
expect(outerClassName).toBe('TestObject');
214+
Parse.Object.unregisterSubclass('TestObject');
213215
});
214216
});

integration/test/ParseUserTest.js

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const assert = require('assert');
44
const Parse = require('../../node');
5+
const uuidv4 = require('uuid/v4');
56

67
class CustomUser extends Parse.User {
78
constructor(attributes) {
@@ -42,8 +43,8 @@ global.FB = {
4243
};
4344

4445
describe('Parse User', () => {
45-
beforeEach(() => {
46-
Parse.Object.registerSubclass('_User', Parse.User);
46+
afterAll(() => {
47+
Parse.Object.unregisterSubclass('CustomUser');
4748
});
4849

4950
it('can sign up users via static method', done => {
@@ -491,6 +492,7 @@ describe('Parse User', () => {
491492
});
492493

493494
it('can update users', done => {
495+
Parse.User.enableUnsafeCurrentUser();
494496
const user = new Parse.User();
495497
user
496498
.signUp({
@@ -804,8 +806,8 @@ describe('Parse User', () => {
804806
Parse.User.enableUnsafeCurrentUser();
805807

806808
let user = new CustomUser();
807-
user.setUsername('Alice');
808-
user.setPassword('sekrit');
809+
user.setUsername(uuidv4());
810+
user.setPassword(uuidv4());
809811
await user.signUp();
810812
user = await CustomUser.logInWith(provider.getAuthType(), provider.getAuthData());
811813
expect(user._isLinked(provider)).toBe(true);
@@ -817,8 +819,8 @@ describe('Parse User', () => {
817819
Parse.User.enableUnsafeCurrentUser();
818820

819821
const user = new Parse.User();
820-
user.setUsername('Alice');
821-
user.setPassword('sekrit');
822+
user.setUsername(uuidv4());
823+
user.setPassword(uuidv4());
822824
await user.signUp();
823825
await user.linkWith(provider.getAuthType(), provider.getAuthData());
824826
expect(user._isLinked(provider)).toBe(true);
@@ -830,8 +832,8 @@ describe('Parse User', () => {
830832
Parse.User.disableUnsafeCurrentUser();
831833

832834
const user = new Parse.User();
833-
user.setUsername('Alice');
834-
user.setPassword('sekrit');
835+
user.setUsername(uuidv4());
836+
user.setPassword(uuidv4());
835837
await user.save(null, { useMasterKey: true });
836838
await user.linkWith(provider.getAuthType(), provider.getAuthData(), {
837839
useMasterKey: true,
@@ -845,8 +847,8 @@ describe('Parse User', () => {
845847
Parse.User.disableUnsafeCurrentUser();
846848

847849
const user = new Parse.User();
848-
user.setUsername('Alice');
849-
user.setPassword('sekrit');
850+
user.setUsername(uuidv4());
851+
user.setPassword(uuidv4());
850852
await user.signUp();
851853
expect(user.isCurrent()).toBe(false);
852854

@@ -860,9 +862,10 @@ describe('Parse User', () => {
860862
});
861863

862864
it('linked account can login with authData', async () => {
865+
Parse.User.disableUnsafeCurrentUser();
863866
const user = new Parse.User();
864-
user.setUsername('Alice');
865-
user.setPassword('sekrit');
867+
user.setUsername(uuidv4());
868+
user.setPassword(uuidv4());
866869
await user.save(null, { useMasterKey: true });
867870
await user.linkWith(provider.getAuthType(), provider.getAuthData(), {
868871
useMasterKey: true,
@@ -876,8 +879,8 @@ describe('Parse User', () => {
876879

877880
it('can linking un-authenticated user without master key', async () => {
878881
const user = new Parse.User();
879-
user.setUsername('Alice');
880-
user.setPassword('sekrit');
882+
user.setUsername(uuidv4());
883+
user.setPassword(uuidv4());
881884
await user.save(null, { useMasterKey: true });
882885
await user.linkWith(provider.getAuthType(), provider.getAuthData());
883886
expect(user.getSessionToken()).toBeDefined();
@@ -905,8 +908,8 @@ describe('Parse User', () => {
905908
};
906909
Parse.User._registerAuthenticationProvider(provider);
907910
const user = new Parse.User();
908-
user.setUsername('Alice');
909-
user.setPassword('sekrit');
911+
user.setUsername(uuidv4());
912+
user.setPassword(uuidv4());
910913
await user.signUp();
911914
await user.linkWith(provider.getAuthType(), provider.getAuthData());
912915
expect(user._isLinked(provider)).toBe(true);
@@ -925,8 +928,8 @@ describe('Parse User', () => {
925928
Parse.User.enableUnsafeCurrentUser();
926929
Parse.FacebookUtils.init();
927930
const user = new Parse.User();
928-
user.setUsername('Alice');
929-
user.setPassword('sekrit');
931+
user.setUsername(uuidv4());
932+
user.setPassword(uuidv4());
930933
await user.signUp();
931934
await Parse.FacebookUtils.link(user);
932935
expect(Parse.FacebookUtils.isLinked(user)).toBe(true);
@@ -958,8 +961,8 @@ describe('Parse User', () => {
958961
auth_token_secret: 'G1tl1R0gaYKTyxw0uYJDKRoVhM16ifyLeMwIaKlFtPkQr',
959962
};
960963
const user = new Parse.User();
961-
user.setUsername('Alice');
962-
user.setPassword('sekrit');
964+
user.setUsername(uuidv4());
965+
user.setPassword(uuidv4());
963966
await user.signUp();
964967

965968
await user.linkWith('twitter', { authData });
@@ -982,8 +985,8 @@ describe('Parse User', () => {
982985
auth_token_secret: 'G1tl1R0gaYKTyxw0uYJDKRoVhM16ifyLeMwIaKlFtPkQr',
983986
};
984987
const user = new Parse.User();
985-
user.setUsername('Alice');
986-
user.setPassword('sekrit');
988+
user.setUsername(uuidv4());
989+
user.setPassword(uuidv4());
987990
await user.signUp();
988991

989992
await user.linkWith('twitter', { authData });

integration/test/helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
1+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
22

33
const ParseServer = require('parse-server').default;
44
const CustomAuth = require('./CustomAuth');

jasmine.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
"spec_files": [
77
"*Test.js"
88
],
9-
"random": false,
10-
"timeout": 10000
9+
"random": true,
10+
"timeout": 20000
1111
}

src/ParseObject.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,10 @@ class ParseObject {
449449
stateController.mergeFirstPendingState(this._getStateIdentifier());
450450
}
451451

452+
static _getClassMap() {
453+
return classMap;
454+
}
455+
452456
/** Public methods **/
453457

454458
initialize() {
@@ -1884,6 +1888,18 @@ class ParseObject {
18841888
}
18851889
}
18861890

1891+
/**
1892+
* Unegisters a subclass of Parse.Object with a specific class name.
1893+
*
1894+
* @param {string} className The class name of the subclass
1895+
*/
1896+
static unregisterSubclass(className: string) {
1897+
if (typeof className !== 'string') {
1898+
throw new TypeError('The first argument must be a valid class name.');
1899+
}
1900+
delete classMap[className];
1901+
}
1902+
18871903
/**
18881904
* Creates a new subclass of Parse.Object for the given Parse class name.
18891905
*

0 commit comments

Comments
 (0)