Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/cloudfunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ module.exports = function(AV) {
})._thenRunCallbacks(options);
},

/**
* Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response
* from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object}
* @param {String} name The function name.
* @param {Object} data The parameters to send to the cloud function.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that will be resolved with the result of the function.
*/
rpc: function(name, data, options) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdoc

if (_.isArray(data)) {
return AV.Promise.error(new Error('Can\'t pass Array as the param of rpc function in JavaScript SDK.'))
._thenRunCallbacks(options);
}

return AV._request('call', name, null, 'POST', AV._encodeObjectOrArray(data)).then(function(resp) {
return AV._decode('', resp).result;
})._thenRunCallbacks(options);
},

/**
* Make a call to request server date time.
* @param {Object} options A Backbone-style options object
Expand Down
21 changes: 21 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ module.exports = function(AV) {
route !== "files" &&
route !== "date" &&
route !== "functions" &&
route !== "call" &&
route !== "login" &&
route !== "push" &&
route !== "search/select" &&
Expand Down Expand Up @@ -527,6 +528,26 @@ module.exports = function(AV) {
return value;
};

AV._encodeObjectOrArray = function(value) {
var encodeAVObject = function(object) {
if (object && object._toFullJSON){
object = object._toFullJSON([]);
}

return _.mapObject(object, function(value) {
return AV._encode(value, []);
});
};

if (_.isArray(value)) {
return value.map(function(object) {
return encodeAVObject(object);
});
} else {
return encodeAVObject(value);
}
};

AV._arrayEach = AV._.each;

/**
Expand Down
136 changes: 135 additions & 1 deletion test/cloud.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
describe("AV.Cloud", function() {
var originalServerURL, originalAppId, originalAppKey, originalUseMasterKey;

before(function() {
originalServerURL = AV.serverURL;
originalAppId = AV.applicationId;
originalAppKey = AV.applicationKey;
originalUseMasterKey = AV._useMasterKey;

AV.serverURL = 'https://leancloud.cn'
AV.applicationId = '4h2h4okwiyn8b6cle0oig00vitayum8ephrlsvg7xo8o19ne';
AV.applicationKey = '3xjj1qw91cr3ygjq9lt0g8c3qpet38rrxtwmmp0yffyoy2t4';
AV._useMasterKey = false;

AV.User._currentUser = null;
});

describe("#getServerDate", function(){

it("should return a date.", function(done){
AV.Cloud.getServerDate().then(function(date) {
expect(date).to.be.a('object');
Expand All @@ -11,4 +26,123 @@ describe("AV.Cloud", function() {
});
});
});

describe('#rpc', function() {
it('receive complex object', function(done) {
AV.Cloud.rpc('complexObject', null, {
success: function(result) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

测试用例及文档中,都使用 promise 的形式。

expect(result.foo).to.be('bar');
expect(result.t).to.be.a(Date);
expect(result.t.toISOString()).to.be('2015-05-14T09:21:18.273Z');

expect(result.avObject).to.be.a(AV.Object);
expect(result.avObject.className).to.be('ComplexObject');
expect(result.avObject.get('numberColumn')).to.be(1.23);
expect(result.avObject.get('arrayColumn')).to.eql([1, 2, 3]);
expect(result.avObject.get('objectColumn')).to.eql({foo: 'bar'});
expect(result.avObject.get('stringColumn')).to.be('testString');
expect(result.avObject.get('anyColumn')).to.be('');
expect(result.avObject.get('booleanColumn')).to.be(true);
expect(result.avObject.get('pointerColumn')).to.be.a(AV.Object);
expect(result.avObject.get('pointerColumn').id).to.be('55069e5be4b0c93838ed8e6c');
expect(result.avObject.get('relationColumn')).to.be.a(AV.Relation);
expect(result.avObject.get('relationColumn').targetClassName).to.be('TestObject');
expect(result.avObject.get('geopointColumn')).to.be.a(AV.GeoPoint);
expect(result.avObject.get('geopointColumn').latitude).to.be(0);
expect(result.avObject.get('geopointColumn').longitude).to.be(30);
expect(result.avObject.get('dateColumn')).to.be.a(Date);
expect(result.avObject.get('dateColumn').toISOString()).to.be('2015-05-14T06:24:47.000Z');
expect(result.avObject.get('fileColumn')).to.be.a(AV.File);
expect(result.avObject.get('fileColumn').name()).to.be('ttt.jpg');
expect(result.avObject.get('fileColumn').url()).to.be('http://ac-4h2h4okw.clouddn.com/4qSbLMO866Tf4YtT9QEwJwysTlHGC9sMl7bpTwhQ.jpg');

result.avObjects.forEach(function(object) {
expect(object).to.be.a(AV.Object);
expect(object.className).to.be('ComplexObject');
});

done();
},
error: done
});
});

it('receive bare AVObject', function(done) {
AV.Cloud.rpc('bareAVObject', null, {
success: function(result) {
expect(result).to.be.a(AV.Object);
expect(result.className).to.be('ComplexObject');
expect(result.get('fileColumn')).to.be.a(AV.File);
done();
},
error: done
});
});

it('receive array of AVObjects', function(done) {
AV.Cloud.rpc('AVObjects', null, {
success: function(result) {
result.forEach(function(object) {
expect(object).to.be.a(AV.Object);
expect(object.className).to.be('ComplexObject');
});
done();
},
error: done
})
});

it('send AVObject', function(done) {
var avObject = new AV.Object('ComplexObject');
var avObjectItem = new AV.Object('ComplexObject');

avObject.set({
name: 'avObject',
pointerColumn: AV.Object.createWithoutData('_User', '55069e5be4b0c93838ed8e6c')._toPointer()
});

avObjectItem.set({
name: 'avObjects'
});

AV.Object.saveAll([avObject, avObjectItem], {
success: function() {
AV.Cloud.rpc('testAVObjectParams', {
avObject: avObject,
avFile: AV.File.withURL('hello.txt', 'http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt'),
avObjects: [avObjectItem]
}, {
success: function() {
done()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个是在服务端正确解析之后返回的 200 么?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对,这个测试应用会检查请求的参数,只有正确才会返回 200,然后进入到这个 success 分支

},
error: done
});
},
error: done
});
});

it('send bare AVObject', function(done) {
var avObject = new AV.Object('ComplexObject');

avObject.set({
name: 'avObject',
avFile: AV.File.withURL('hello.txt', 'http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt')
});

AV.Cloud.rpc('testBareAVObjectParams', avObject, {
success: function() {
done()
},
error: done
});
});
});

after(function() {
AV.serverURL = originalServerURL;
AV.applicationId = originalAppId;
AV.applicationKey = originalAppKey;
AV._useMasterKey = originalUseMasterKey;
});
});
1 change: 1 addition & 0 deletions test/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<script src="status.js"></script>
<script src="sms.js"></script>
<script src="search.js"></script>
<script src="cloud.js"></script>
<script>
onload = function(){
mocha.checkLeaks();
Expand Down