Skip to content

Commit 3f30a38

Browse files
yog27raydplewis
andauthored
Pass context in destroy, saveAll, get, find hooks. (#1159)
* add context to Parse.Object.fetch, Parse.Object.destroy, Parse.Object.saveAll, Parse.Query.get, Parse.Query.find, Parse.Query.first, Parse.Query.each * add context for Parse.Cloud.run * build fix * pass context in Parse.Object.destroyAll Co-authored-by: Diamond Lewis <[email protected]>
1 parent 6b861da commit 3f30a38

File tree

6 files changed

+153
-4
lines changed

6 files changed

+153
-4
lines changed

src/Cloud.js

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export function run(
5757
if (options.sessionToken) {
5858
requestOptions.sessionToken = options.sessionToken;
5959
}
60+
if (options.context && typeof options.context === 'object') {
61+
requestOptions.context = options.context;
62+
}
6063

6164
return CoreManager.getCloudController().run(name, data, requestOptions);
6265
}

src/ParseObject.js

+16
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ class ParseObject {
10841084
* behalf of a specific user.
10851085
* <li>include: The name(s) of the key(s) to include. Can be a string, an array of strings,
10861086
* or an array of array of strings.
1087+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
10871088
* </ul>
10881089
* @return {Promise} A promise that is fulfilled when the fetch
10891090
* completes.
@@ -1097,6 +1098,9 @@ class ParseObject {
10971098
if (options.hasOwnProperty('sessionToken')) {
10981099
fetchOptions.sessionToken = options.sessionToken;
10991100
}
1101+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1102+
fetchOptions.context = options.context;
1103+
}
11001104
if (options.hasOwnProperty('include')) {
11011105
fetchOptions.include = [];
11021106
if (Array.isArray(options.include)) {
@@ -1273,6 +1277,7 @@ class ParseObject {
12731277
* be used for this request.
12741278
* <li>sessionToken: A valid session token, used for making a request on
12751279
* behalf of a specific user.
1280+
* <li>context: A dictionary that is accessible in Cloud Code `beforeDelete` and `afterDelete` triggers.
12761281
* </ul>
12771282
* @return {Promise} A promise that is fulfilled when the destroy
12781283
* completes.
@@ -1286,6 +1291,9 @@ class ParseObject {
12861291
if (options.hasOwnProperty('sessionToken')) {
12871292
destroyOptions.sessionToken = options.sessionToken;
12881293
}
1294+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1295+
destroyOptions.context = options.context;
1296+
}
12891297
if (!this.id) {
12901298
return Promise.resolve();
12911299
}
@@ -1631,6 +1639,7 @@ class ParseObject {
16311639
* <li>sessionToken: A valid session token, used for making a request on
16321640
* behalf of a specific user.
16331641
* <li>batchSize: Number of objects to process per request
1642+
* <li>context: A dictionary that is accessible in Cloud Code `beforeDelete` and `afterDelete` triggers.
16341643
* </ul>
16351644
* @return {Promise} A promise that is fulfilled when the destroyAll
16361645
* completes.
@@ -1646,6 +1655,9 @@ class ParseObject {
16461655
if (options.hasOwnProperty('batchSize') && typeof options.batchSize === 'number') {
16471656
destroyOptions.batchSize = options.batchSize;
16481657
}
1658+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1659+
destroyOptions.context = options.context;
1660+
}
16491661
return CoreManager.getObjectController().destroy(
16501662
list,
16511663
destroyOptions
@@ -1674,6 +1686,7 @@ class ParseObject {
16741686
* <li>sessionToken: A valid session token, used for making a request on
16751687
* behalf of a specific user.
16761688
* <li>batchSize: Number of objects to process per request
1689+
* <li>context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers.
16771690
* </ul>
16781691
*/
16791692
static saveAll(list: Array<ParseObject>, options: RequestOptions = {}) {
@@ -1687,6 +1700,9 @@ class ParseObject {
16871700
if (options.hasOwnProperty('batchSize') && typeof options.batchSize === 'number') {
16881701
saveOptions.batchSize = options.batchSize;
16891702
}
1703+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1704+
saveOptions.context = options.context;
1705+
}
16901706
return CoreManager.getObjectController().save(
16911707
list,
16921708
saveOptions

src/ParseQuery.js

+16
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ class ParseQuery {
564564
* be used for this request.
565565
* <li>sessionToken: A valid session token, used for making a request on
566566
* behalf of a specific user.
567+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
567568
* </ul>
568569
*
569570
* @return {Promise} A promise that is resolved with the result when
@@ -579,6 +580,9 @@ class ParseQuery {
579580
if (options && options.hasOwnProperty('sessionToken')) {
580581
firstOptions.sessionToken = options.sessionToken;
581582
}
583+
if (options && options.hasOwnProperty('context') && typeof options.context === 'object') {
584+
firstOptions.context = options.context;
585+
}
582586

583587
return this.first(firstOptions).then((response) => {
584588
if (response) {
@@ -604,6 +608,7 @@ class ParseQuery {
604608
* be used for this request.
605609
* <li>sessionToken: A valid session token, used for making a request on
606610
* behalf of a specific user.
611+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
607612
* </ul>
608613
*
609614
* @return {Promise} A promise that is resolved with the results when
@@ -619,6 +624,9 @@ class ParseQuery {
619624
if (options.hasOwnProperty('sessionToken')) {
620625
findOptions.sessionToken = options.sessionToken;
621626
}
627+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
628+
findOptions.context = options.context;
629+
}
622630
this._setRequestTask(findOptions);
623631

624632
const controller = CoreManager.getQueryController();
@@ -799,6 +807,7 @@ class ParseQuery {
799807
* be used for this request.
800808
* <li>sessionToken: A valid session token, used for making a request on
801809
* behalf of a specific user.
810+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
802811
* </ul>
803812
*
804813
* @return {Promise} A promise that is resolved with the object when
@@ -814,6 +823,9 @@ class ParseQuery {
814823
if (options.hasOwnProperty('sessionToken')) {
815824
findOptions.sessionToken = options.sessionToken;
816825
}
826+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
827+
findOptions.context = options.context;
828+
}
817829
this._setRequestTask(findOptions);
818830

819831
const controller = CoreManager.getQueryController();
@@ -871,6 +883,7 @@ class ParseQuery {
871883
* be used for this request.
872884
* <li>sessionToken: A valid session token, used for making a request on
873885
* behalf of a specific user.
886+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
874887
* </ul>
875888
* @return {Promise} A promise that will be fulfilled once the
876889
* iteration has completed.
@@ -921,6 +934,9 @@ class ParseQuery {
921934
if (options.hasOwnProperty('sessionToken')) {
922935
findOptions.sessionToken = options.sessionToken;
923936
}
937+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
938+
findOptions.context = options.context;
939+
}
924940

925941
let finished = false;
926942
let previousResults = [];

src/__tests__/Cloud-test.js

+17
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,21 @@ describe('CloudController', () => {
205205
expect(CoreManager.getRESTController().request.mock.calls[0])
206206
.toEqual(['GET', 'cloud_code/jobs/data', null, { useMasterKey: true }]);
207207
});
208+
209+
it('accepts context on cloud function call', async () => {
210+
const request = jest.fn();
211+
request.mockReturnValue(Promise.resolve(undefined));
212+
213+
const ajax = jest.fn();
214+
CoreManager.setRESTController({ request: request, ajax: ajax });
215+
216+
// Spy on REST controller
217+
const controller = CoreManager.getRESTController();
218+
jest.spyOn(controller, 'request');
219+
// Save object
220+
const context = {a: "a"};
221+
await Cloud.run('myfunction', {}, { context: context });
222+
// Validate
223+
expect(controller.request.mock.calls[0][3].context).toEqual(context);
224+
});
208225
});

src/__tests__/ParseObject-test.js

+85
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,49 @@ describe('ParseObject', () => {
15661566
await result;
15671567
});
15681568

1569+
it('accepts context on saveAll', async () => {
1570+
// Mock XHR
1571+
CoreManager.getRESTController()._setXHR(
1572+
mockXHR([{
1573+
status: 200,
1574+
response: [{}]
1575+
}])
1576+
);
1577+
// Spy on REST controller
1578+
const controller = CoreManager.getRESTController();
1579+
jest.spyOn(controller, 'ajax');
1580+
// Save object
1581+
const context = {a: "a"};
1582+
const obj = new ParseObject('Item');
1583+
obj.id = 'pid';
1584+
obj.set('test', 'value');
1585+
await ParseObject.saveAll([obj], {context})
1586+
// Validate
1587+
const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]);
1588+
expect(jsonBody._context).toEqual(context);
1589+
});
1590+
1591+
it('accepts context on destroyAll', async () => {
1592+
// Mock XHR
1593+
CoreManager.getRESTController()._setXHR(
1594+
mockXHR([{
1595+
status: 200,
1596+
response: [{}]
1597+
}])
1598+
);
1599+
// Spy on REST controller
1600+
const controller = CoreManager.getRESTController();
1601+
jest.spyOn(controller, 'ajax');
1602+
// Save object
1603+
const context = {a: "a"};
1604+
const obj = new ParseObject('Item');
1605+
obj.id = 'pid';
1606+
await ParseObject.destroyAll([obj], { context: context })
1607+
// Validate
1608+
const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]);
1609+
expect(jsonBody._context).toEqual(context);
1610+
});
1611+
15691612
it('can save a chain of unsaved objects', async () => {
15701613
const xhrs = [];
15711614
RESTController._setXHR(function() {
@@ -1734,6 +1777,27 @@ describe('ParseObject', () => {
17341777
await result;
17351778
});
17361779

1780+
it('accepts context on destroy', async () => {
1781+
// Mock XHR
1782+
CoreManager.getRESTController()._setXHR(
1783+
mockXHR([{
1784+
status: 200,
1785+
response: {}
1786+
}])
1787+
);
1788+
// Spy on REST controller
1789+
const controller = CoreManager.getRESTController();
1790+
jest.spyOn(controller, 'ajax');
1791+
// Save object
1792+
const context = {a: "a"};
1793+
const obj = new ParseObject('Item');
1794+
obj.id = 'pid';
1795+
await obj.destroy({context});
1796+
// Validate
1797+
const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]);
1798+
expect(jsonBody._context).toEqual(context);
1799+
});
1800+
17371801
it('can save an array of objects', async (done) => {
17381802
const xhr = {
17391803
setRequestHeader: jest.fn(),
@@ -1980,6 +2044,27 @@ describe('ObjectController', () => {
19802044
jest.runAllTicks();
19812045
});
19822046

2047+
it('accepts context on fetch', async () => {
2048+
// Mock XHR
2049+
CoreManager.getRESTController()._setXHR(
2050+
mockXHR([{
2051+
status: 200,
2052+
response: {}
2053+
}])
2054+
);
2055+
// Spy on REST controller
2056+
const controller = CoreManager.getRESTController();
2057+
jest.spyOn(controller, 'ajax');
2058+
// Save object
2059+
const context = {a: "a"};
2060+
const obj = new ParseObject('Item');
2061+
obj.id = 'pid';
2062+
await obj.fetch({context});
2063+
// Validate
2064+
const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]);
2065+
expect(jsonBody._context).toEqual(context);
2066+
});
2067+
19832068
it('can fetch an array of objects', (done) => {
19842069
const objectController = CoreManager.getObjectController();
19852070
const objects = [];

src/__tests__/ParseQuery-test.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,7 @@ describe('ParseQuery', () => {
12951295
});
12961296

12971297
it('can pass options to a get() query', (done) => {
1298+
const context = {a: "a"};
12981299
CoreManager.setQueryController({
12991300
aggregate() {},
13001301
find(className, params, options) {
@@ -1307,6 +1308,7 @@ describe('ParseQuery', () => {
13071308
});
13081309
expect(options.useMasterKey).toEqual(true);
13091310
expect(options.sessionToken).toEqual('1234');
1311+
expect(options.context).toEqual(context);
13101312
return Promise.resolve({
13111313
results: [
13121314
{ objectId: 'I27', size: 'large', name: 'Product 27' }
@@ -1318,7 +1320,8 @@ describe('ParseQuery', () => {
13181320
const q = new ParseQuery('Item');
13191321
q.get('I27', {
13201322
useMasterKey: true,
1321-
sessionToken: '1234'
1323+
sessionToken: '1234',
1324+
context: context
13221325
}).then(() => {
13231326
done();
13241327
});
@@ -1437,6 +1440,7 @@ describe('ParseQuery', () => {
14371440
});
14381441

14391442
it('can pass options to find()', (done) => {
1443+
const context = {a: "a"};
14401444
CoreManager.setQueryController({
14411445
aggregate() {},
14421446
find(className, params, options) {
@@ -1450,6 +1454,7 @@ describe('ParseQuery', () => {
14501454
});
14511455
expect(options.useMasterKey).toEqual(true);
14521456
expect(options.sessionToken).toEqual('1234');
1457+
expect(options.context).toEqual(context);
14531458
return Promise.resolve({
14541459
results: []
14551460
});
@@ -1460,7 +1465,8 @@ describe('ParseQuery', () => {
14601465
q.containedIn('size', ['small', 'medium'])
14611466
.find({
14621467
useMasterKey: true,
1463-
sessionToken: '1234'
1468+
sessionToken: '1234',
1469+
context: context
14641470
})
14651471
.then((objs) => {
14661472
expect(objs).toEqual([]);
@@ -1692,6 +1698,7 @@ describe('ParseQuery', () => {
16921698
});
16931699

16941700
it('can pass options to each()', (done) => {
1701+
const context = {a: "a"};
16951702
CoreManager.setQueryController({
16961703
aggregate() {},
16971704
find(className, params, options) {
@@ -1709,6 +1716,7 @@ describe('ParseQuery', () => {
17091716
});
17101717
expect(options.useMasterKey).toEqual(true);
17111718
expect(options.sessionToken).toEqual('1234');
1719+
expect(options.context).toEqual(context);
17121720
return Promise.resolve({
17131721
results: [
17141722
{ objectId: 'I55', size: 'medium', name: 'Product 55' },
@@ -1729,7 +1737,8 @@ describe('ParseQuery', () => {
17291737
calls++;
17301738
}, {
17311739
useMasterKey: true,
1732-
sessionToken: '1234'
1740+
sessionToken: '1234',
1741+
context: context
17331742
}).then(() => {
17341743
expect(calls).toBe(3);
17351744
done();
@@ -1738,6 +1747,7 @@ describe('ParseQuery', () => {
17381747

17391748

17401749
it('can pass options to each() with hint', (done) => {
1750+
const context = {a: "a"};
17411751
CoreManager.setQueryController({
17421752
aggregate() {},
17431753
find(className, params, options) {
@@ -1756,6 +1766,7 @@ describe('ParseQuery', () => {
17561766
});
17571767
expect(options.useMasterKey).toEqual(true);
17581768
expect(options.sessionToken).toEqual('1234');
1769+
expect(options.context).toEqual(context);
17591770
return Promise.resolve({
17601771
results: [
17611772
{ objectId: 'I55', size: 'medium', name: 'Product 55' },
@@ -1777,7 +1788,8 @@ describe('ParseQuery', () => {
17771788
calls++;
17781789
}, {
17791790
useMasterKey: true,
1780-
sessionToken: '1234'
1791+
sessionToken: '1234',
1792+
context: context
17811793
}).then(() => {
17821794
expect(calls).toBe(3);
17831795
done();

0 commit comments

Comments
 (0)