Skip to content

Commit b64e19c

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 3ca33ed + 4a75d97 commit b64e19c

32 files changed

+658
-184
lines changed

CHANGELOG.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
11
# Parse-SDK-JS
22

33
### master
4-
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/3.0.0...master)
4+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/3.2.0...master)
5+
6+
## 3.2.0
7+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/3.1.0...3.2.0)
8+
9+
**Breaking Changes**
10+
- Remove deletion of Anonymous User on logout ([#1324](https://github.com/parse-community/Parse-SDK-JS/pull/1324))
11+
See https://community.parseplatform.org/t/anonymous-user-destroyed-on-logout/1425
12+
13+
**Improvements**
14+
- Allow multiple classNames for `Parse.Object.registerSubclass` ([#1315](https://github.com/parse-community/Parse-SDK-JS/pull/1315))
15+
```
16+
const classNames = ['ClassOne', 'ClassTwo', 'ClassThree'];
17+
for (const className of classNames) {
18+
Parse.Object.registerSubclass(className, CustomClass);
19+
}
20+
```
21+
22+
**Fixes**
23+
- Fixes build for WeChat WeApp, to reduce package size, see [issue/#1331](https://github.com/parse-community/Parse-SDK-JS/issues/1331)
24+
25+
## 3.1.0
26+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/3.0.0...3.1.0)
27+
28+
**Breaking Changes**
29+
`Parse.Push.send` will now return the pushStatusId instead of `{ result: true }`
30+
31+
**Features**
32+
- Add Server Health Check `Parse.getServerHealth()` ([#1307](https://github.com/parse-community/Parse-SDK-JS/pull/1307))
33+
- Allow saving with custom objectId `Parse.allowCustomObjectId = true` ([#1309](https://github.com/parse-community/Parse-SDK-JS/pull/1309))
34+
- `Parse.Push.send` now returns pushStatusId ([#1302](https://github.com/parse-community/Parse-SDK-JS/pull/1302))
35+
- Add `Parse.Push.getPushStatus` ([#1302](https://github.com/parse-community/Parse-SDK-JS/pull/1302))
36+
37+
**Improvements**
38+
- Add modifiers to `query.startsWith` ([#1306](https://github.com/parse-community/Parse-SDK-JS/pull/1306))
39+
- Add modifiers to `query.endsWith` ([#1306](https://github.com/parse-community/Parse-SDK-JS/pull/1306))
40+
41+
**Fixes**
42+
- EventuallyQueue now polls against `/health` endpoint, caused 403 forbidden side effect ([#1305](https://github.com/parse-community/Parse-SDK-JS/pull/1305))
43+
- Allow nested increment on undefined fields ([#1303](https://github.com/parse-community/Parse-SDK-JS/pull/1303))
44+
- Handle increment on nested fields any level deep ([#1301](https://github.com/parse-community/Parse-SDK-JS/pull/1301))
545

646
## 3.0.0
747
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.19.0...3.0.0)

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/ParseObjectTest.js

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,20 @@ describe('Parse Object', () => {
278278
assert.equal(result.get('objectField').number, 20);
279279
});
280280

281+
it('can increment nested four levels', async () => {
282+
const obj = new TestObject({ a: { b: { c: { d: 1 } } } });
283+
await obj.save();
284+
obj.increment('a.b.c.d');
285+
assert.strictEqual(obj.get('a').b.c.d, 2);
286+
287+
await obj.save();
288+
assert.strictEqual(obj.get('a').b.c.d, 2);
289+
290+
const query = new Parse.Query(TestObject);
291+
const result = await query.get(obj.id);
292+
assert.strictEqual(result.get('a').b.c.d, 2);
293+
});
294+
281295
it('can increment nested field and retain full object', async () => {
282296
const obj = new Parse.Object('TestIncrementObject');
283297
obj.set('objectField', { number: 5, letter: 'a' });
@@ -400,16 +414,6 @@ describe('Parse Object', () => {
400414
assert.equal(result.get('objectField').unknown, 20);
401415
});
402416

403-
it('ignore set nested fields on new object', async () => {
404-
const obj = new TestObject();
405-
obj.set('objectField.number', 5);
406-
assert.deepEqual(obj._getPendingOps()[0], {});
407-
assert.equal(obj.get('objectField'), undefined);
408-
409-
await obj.save();
410-
assert.equal(obj.get('objectField'), undefined);
411-
});
412-
413417
it('can set nested fields two levels', async () => {
414418
const obj = new TestObject({ objectField: { foo: { bar: 5 } } });
415419
assert.equal(obj.get('objectField').foo.bar, 5);
@@ -2041,4 +2045,60 @@ describe('Parse Object', () => {
20412045
expect(obj.get('string')).toBeDefined();
20422046
expect(obj.get('string')).toBeInstanceOf(String);
20432047
});
2048+
2049+
it('allowCustomObjectId', async () => {
2050+
await reconfigureServer({ allowCustomObjectId: true });
2051+
Parse.allowCustomObjectId = true;
2052+
const customId = `${Date.now()}`;
2053+
const object = new Parse.Object('TestObject');
2054+
try {
2055+
await object.save();
2056+
fail();
2057+
} catch (error) {
2058+
expect(error.message).toBe('objectId must not be empty, null or undefined');
2059+
}
2060+
object.id = customId;
2061+
object.set('foo', 'bar');
2062+
await object.save();
2063+
expect(object.id).toBe(customId);
2064+
2065+
const query = new Parse.Query('TestObject');
2066+
const result = await query.get(customId);
2067+
expect(result.get('foo')).toBe('bar');
2068+
expect(result.id).toBe(customId);
2069+
2070+
result.set('foo', 'baz');
2071+
await result.save();
2072+
2073+
const afterSave = await query.get(customId);
2074+
expect(afterSave.get('foo')).toBe('baz');
2075+
Parse.allowCustomObjectId = false;
2076+
});
2077+
2078+
it('allowCustomObjectId saveAll', async () => {
2079+
await reconfigureServer({ allowCustomObjectId: true });
2080+
Parse.allowCustomObjectId = true;
2081+
const customId1 = `${Date.now()}`;
2082+
const customId2 = `${Date.now()}`;
2083+
const obj1 = new TestObject({ foo: 'bar' });
2084+
const obj2 = new TestObject({ foo: 'baz' });
2085+
try {
2086+
await Parse.Object.saveAll([obj1, obj2]);
2087+
fail();
2088+
} catch (error) {
2089+
expect(error.message).toBe('objectId must not be empty, null or undefined');
2090+
}
2091+
obj1.id = customId1;
2092+
obj2.id = customId2;
2093+
await Parse.Object.saveAll([obj1, obj2]);
2094+
expect(obj1.id).toBe(customId1);
2095+
expect(obj2.id).toBe(customId2);
2096+
2097+
const query = new Parse.Query(TestObject);
2098+
const results = await query.find();
2099+
results.forEach(result => {
2100+
expect([customId1, customId2].includes(result.id));
2101+
});
2102+
Parse.allowCustomObjectId = false;
2103+
});
20442104
});

integration/test/ParsePushTest.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
const Parse = require('../../node');
4+
5+
describe('Parse Push', () => {
6+
it('can get pushStatusId', async () => {
7+
const payload = {
8+
data: { alert: 'We return status!' },
9+
where: { deviceType: { $eq: 'random' } },
10+
};
11+
const pushStatusId = await Parse.Push.send(payload, { useMasterKey: true });
12+
const pushStatus = await Parse.Push.getPushStatus(pushStatusId, { useMasterKey: true });
13+
expect(pushStatus.id).toBe(pushStatusId);
14+
});
15+
});

integration/test/ParseQueryTest.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ describe('Parse Query', () => {
11581158
});
11591159
});
11601160

1161-
it('can test case insensitive regex', done => {
1161+
it('can test case insensitive matches', done => {
11621162
const obj = new TestObject();
11631163
obj.set('myString', 'hockey');
11641164
obj
@@ -1175,6 +1175,32 @@ describe('Parse Query', () => {
11751175
});
11761176
});
11771177

1178+
it('can test case insensitive startsWith', async () => {
1179+
const obj = new TestObject();
1180+
obj.set('myString', 'basketball');
1181+
await obj.save();
1182+
1183+
const query = new Parse.Query(TestObject);
1184+
query.startsWith('myString', 'baSKet', 'i');
1185+
const results = await query.find();
1186+
1187+
assert.strictEqual(results.length, 1);
1188+
assert.strictEqual(results[0].get('myString'), 'basketball');
1189+
});
1190+
1191+
it('can test case insensitive endsWith', async () => {
1192+
const obj = new TestObject();
1193+
obj.set('myString', 'basketball');
1194+
await obj.save();
1195+
1196+
const query = new Parse.Query(TestObject);
1197+
query.endsWith('myString', 'tBAll', 'i');
1198+
const results = await query.find();
1199+
1200+
assert.strictEqual(results.length, 1);
1201+
assert.strictEqual(results[0].get('myString'), 'basketball');
1202+
});
1203+
11781204
it('fails for invalid regex options', done => {
11791205
const query = new Parse.Query(TestObject);
11801206
query.matches('myString', 'football', 'some invalid thing');

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 => {

0 commit comments

Comments
 (0)