UNPKG

juejin-leanengine

Version:
767 lines (693 loc) 23.4 kB
'use strict'; var config = require('./config'), AV = require('..'), should = require('should'), fs = require('fs'), request = require('supertest'), assert = require('assert'), _ = require('underscore'); var appId = config.appId; var appKey = config.appKey; var masterKey = config.masterKey; AV.init(config); var app; if (process.env.FRAMEWORK == 'koa') { var koa = require('koa')(); koa.use(AV.koa()); app = koa.listen(); } else { app = AV.express(); } var TestObject = AV.Object.extend('TestObject'); var ComplexObject = AV.Object.extend('ComplexObject'); AV.Cloud.define('foo', function(request, response) { assert.ok(request.meta.remoteAddress); response.success("bar"); }); AV.Cloud.define('hello', function(request, response) { response.success({action: "hello", name: request.params.name}); }); AV.Cloud.define('choice', function(req, res) { if (req.params.choice) { res.success('OK~'); } else { res.error('OMG...'); } }); AV.Cloud.define('complexObject', function(request, response) { var query = new AV.Query(ComplexObject); query.include('fileColumn'); query.ascending('createdAt'); query.find().then( function(results) { response.success({ foo: 'bar', i: 123, obj: { a: 'b', as: [1, 2, 3], }, t: new Date('2015-05-14T09:21:18.273Z'), avObject: results[0], avObjects: results, }); } ); }); AV.Cloud.define('bareAVObject', function(request, response) { var query = new AV.Query(ComplexObject); query.include('fileColumn'); query.ascending('createdAt'); query.find().then( function(results) { response.success(results[0]); } ); }); AV.Cloud.define('AVObjects', function(request, response) { var query = new AV.Query(ComplexObject); query.include('fileColumn'); query.ascending('createdAt'); query.find().then( function(results) { response.success(results); } ); }); AV.Cloud.define('testAVObjectParams', function(request, response) { request.params.avObject.should.be.instanceof(AV.Object); request.params.avObject.get('name').should.be.equal('avObject'); request.params.avObject.get('pointerColumn').should.be.instanceof(AV.User); request.params.avFile.should.be.instanceof(AV.File); request.params.avObjects.forEach(function(object) { object.should.be.instanceof(AV.Object); object.get('name').should.be.equal('avObjects'); }); response.success(); }); AV.Cloud.define('testBareAVObjectParams', function(request, response) { request.params.should.be.instanceof(AV.Object); request.params.get('name').should.be.equal('avObject'); request.params.get('avFile').should.be.instanceof(AV.File); request.params.get('avFile').name().should.be.equal('hello.txt'); response.success(); }); AV.Cloud.define('testAVObjectsArrayParams', function(request, response) { request.params.forEach(function(object) { object.get('name').should.be.equal('avObject'); object.get('avFile').should.be.instanceof(AV.File); object.get('avFile').name().should.be.equal('hello.txt'); }); response.success(); }); AV.Cloud.define('testUser', function(request, response) { assert.equal(request.user.className, '_User'); assert.equal(request.user.id, '54fd6a03e4b06c41e00b1f40'); assert.equal(request.user.get('username'), 'admin'); response.success('ok'); }); AV.Cloud.define('dontFetchUser', {fetchUser: false}, function(req, res) { should.not.exist(res.user); should.not.exist(res.currentUser); req.sessionToken.should.be.equal(sessionToken_admin); res.success(); }); AV.Cloud.define('testRun', function(request, response) { if (request.params.shouldRemote && process.env.NODE_ENV != 'production') { return response.error('Should be run on remote'); } AV.Cloud.run('hello', {name: '李四'}).then( function(data) { assert.deepEqual(data, {action: "hello", name: '李四'}); response.success(); } ); }); AV.Cloud.define('testRun_options_callback', function(request, response) { AV.Cloud.run('choice', {choice: true}).then( function(data) { assert.equal('OK~', data); AV.Cloud.run('choice', {choice: false}).then( function(data) { assert.ifError(data); }, function(err) { assert.equal('OMG...', err); response.success(); } ); }, function(err) { assert.ifError(err); } ); }); AV.Cloud.define('testRun_promise', function(request, response) { AV.Cloud.run('choice', {choice: true}).then(function(data) { assert.equal('OK~', data); AV.Cloud.run('choice', {choice: false}).then(function(data) { assert.ifError(data); }, function(err) { assert.equal('OMG...', err); response.success(); }); }, function(err) { assert.ifError(err); }); }); AV.Cloud.define('testRunWithUser', function(request, response) { AV.Cloud.run('testUser', {}, { user: request.user }).then(function(data) { assert.equal('ok', data); response.success(); }); }); AV.Cloud.define('testRunWithAVObject', function(request, response) { AV.Cloud.run('complexObject', {}, { user: request.user }).then(function(datas) { response.success(datas); }); }); AV.Cloud.define('testRunWithSessionToken', function(request, response) { AV.Cloud.run('testUser', {}, { sessionToken: request.sessionToken }).then(function(datas) { response.success(datas); }); }); AV.Cloud.define('testRpcRemote', function(request, response) { AV.Cloud.rpc('testRun', {shouldRemote: true}, { remote: true, }).then(function(datas) { response.success(datas); }); }); AV.Cloud.define('readDir', function(request, response) { fs.readdir('.', function(err, dir) { dir.should.containEql('package.json'); response.success(dir); }); }); AV.Cloud.onVerified('sms', function(request) { assert.equal(request.object.className, '_User'); assert.equal(request.object.id, '54fd6a03e4b06c41e00b1f40'); assert.equal(request.object.get('username'), 'admin'); }); AV.Cloud.define('testThrowError', function(request, response) { /* jshint ignore:start */ noThisMethod(); /* jshint ignore:end */ response.success(); }); AV.Cloud.define("userMatching", function(req, res) { setTimeout(function() { // 为了更加靠谱的验证串号问题,走一次网络 IO var query = new AV.Query(TestObject); query.get('55069f5be4b0c93838ed9b17').then( function(obj) { assert.equal(obj.get('foo'), 'bar'); res.success({reqUser: req.user, currentUser: AV.User.current()}); }, function() { res.success({reqUser: req.user, currentUser: AV.User.current()}); } ); }, Math.floor((Math.random() * 2000) + 1)); }); AV.Cloud.define('testTimeout', function(req, res) { setTimeout(function() { res.success('ok'); }, req.params.delay); }); AV.Cloud.define('_messageReceived', function(request, response) { response.success('ok'); }); AV.Insight.on('end', function(err, result) { assert.deepEqual({ "id" : "job id", "status": "OK/ERROR", "message": "当 status 为 ERROR 时的错误消息" }, _.omit(result, '__sign')); }); var sessionToken_admin = config.sessionToken_admin; describe('functions', function() { it('ping', function(done) { request(app) .get('/__engine/1/ping') .expect(200) .expect('{"runtime":"nodejs-' + process.version + '","version":"' + require('../package.json').version + '"}', done); }); // 测试最基本方法的有效性 it('foo', function(done) { request(app) .post('/1/functions/foo') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200) .expect({result: "bar"}, done); }); // 测试 api version 1.1 的有效性 it('version_1.1', function(done) { request(app) .post('/1.1/functions/foo') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200) .expect({result: "bar"}, done); }); // 测试参数的正确解析 it('hello', function(done) { request(app) .post('/1/functions/hello') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({name: "张三"}) .expect(200) .expect({result: {action: "hello", name: "张三"}}, done); }); // 测试返回包含 AVObject 的复杂对象 it('return_complexObject', function(done) { request(app) .post('/1.1/call/complexObject') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, function(err, res) { var result = res.body.result; result.foo.should.equal('bar'); result.t.should.eql({ __type: 'Date', iso: '2015-05-14T09:21:18.273Z' }); result.avObject.__type.should.equal('Object'); result.avObject.className.should.equal('ComplexObject'); result.avObject.numberColumn.should.equal(1.23); result.avObject.arrayColumn.should.eql([1, 2, 3]); result.avObject.objectColumn.should.eql({foo: 'bar'}); result.avObject.stringColumn.should.equal('testString'); result.avObject.anyColumn.should.equal(''); result.avObject.booleanColumn.should.equal(true); result.avObject.pointerColumn.should.eql({ __type: 'Pointer', className: '_User', objectId: '55069e5be4b0c93838ed8e6c' }); result.avObject.relationColumn.should.be.eql({ __type: 'Relation', className: 'TestObject' }); result.avObject.geopointColumn.should.be.eql({ __type: 'GeoPoint', latitude: 0, longitude: 30 }); result.avObject.dateColumn.should.be.eql({ __type: 'Date', iso: '2015-05-14T06:24:47.000Z' }); result.avObject.fileColumn.should.eql({ __type: 'File', id: '55543fc2e4b0846760bd92f3', name: 'ttt.jpg', url: 'http://ac-4h2h4okw.clouddn.com/4qSbLMO866Tf4YtT9QEwJwysTlHGC9sMl7bpTwhQ.jpg' }); result.avObjects.forEach(function(object) { object.__type.should.equal('Object'); object.className.should.equal('ComplexObject'); }); done(); }); }); // 返回单个 AVObject it('return_bareAVObject', function(done) { request(app) .post('/1.1/call/bareAVObject') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, function(err, res) { res.body.result.__type.should.be.equal('Object'); res.body.result.className.should.be.equal('ComplexObject'); res.body.result.fileColumn.__type.should.be.equal('File'); done(); }); }); // 返回 AVObject 数组 it('return_AVObjectsArray', function(done) { request(app) .post('/1.1/call/AVObjects') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, function(err, res) { res.body.result.forEach(function(object) { object.__type.should.be.equal('Object'); object.className.should.be.equal('ComplexObject'); }); done(); }); }); // 测试发送包含 AVObject 的请求 it('testAVObjectParams', function(done) { request(app) .post('/1.1/call/testAVObjectParams') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({ avObject: { __type: 'Object', className: 'ComplexObject', name: 'avObject', pointerColumn: { __type: 'Pointer', className: '_User', objectId: '55069e5be4b0c93838ed8e6c' } }, avFile: { __type: 'File', url: 'http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt', name: 'hello.txt' }, avObjects: [{ __type: 'Object', className: 'ComplexObject', name: 'avObjects' }] }) .expect(200, function(err) { done(err); }); }); // 测试发送单个 AVObject 作为请求参数 it('testBareAVObjectParams', function(done) { request(app) .post('/1.1/call/testBareAVObjectParams') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({ __type: 'Object', className: 'ComplexObject', name: 'avObject', avFile: { __type: 'File', url: 'http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt', name: 'hello.txt' }, }) .expect(200, function(err) { done(err); }); }); // 测试发送 AVObject 数组作为请求参数 it('testAVObjectsArrayParams', function(done) { var object = { __type: 'Object', className: 'ComplexObject', name: 'avObject', avFile: { __type: 'File', url: 'http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt', name: 'hello.txt' } }; request(app) .post('/1.1/call/testAVObjectsArrayParams') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send([object, object]) .expect(200, function(err) { done(err); }); }); // 测试 run 方法的有效性 it('testRun', function(done) { request(app) .post('/1/functions/testRun') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200) .expect({}, done); }); it('testRun_AVObjects', function(done) { request(app) .post('/1.1/call/testRunWithAVObject') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, function(err, res) { res.body.result.avObjects[0].__type.should.equal('Object'); res.body.result.avObjects[0].className.should.equal('ComplexObject'); done(); }); }); it('testRun_text_plain', function(done) { request(app) .post('/1/functions/testRun') .set('Content-Type', 'text/plain; charset=utf-8') .send(JSON.stringify({ '_ApplicationId': appId, '_ApplicationKey': appKey, '_OtherParams': 'asdfg' })) .expect(200) .expect({}, done); }); it('test realtime hook', function(done) { request(app) .post('/1/functions/_messageReceived') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({ __sign: '1464591343092,6ac315b96655d04e3a49d758f5a8ae55208c98f0' }) .expect(200) .end(done); }); it('test realtime hook without sign', function(done) { request(app) .post('/1/functions/_messageReceived') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(401) .end(done); }); it('no_this_method', function(done) { request(app) .post('/1/functions/noThisMethod') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(404) .expect({ "code": 1, "error": "LeanEngine not found function named 'noThisMethod' for app '" + appId + "' on development." }, done); }); // 测试带有 sessionToken 时,user 对象的正确解析 it('testUser', function(done) { request(app) .post('/1/functions/testUser') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); it('dontFetchUser', function(done) { request(app) .post('/1/functions/dontFetchUser') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); // 无效 sessionToken 测试 it('testUser_invalid_sessionToken', function(done) { request(app) .post('/1/functions/testUser') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', '00000000000000000000') .expect(400) .end(function(err, res) { res.body.should.eql({ code: 211, error: 'Could not find user' }); done(); }); }); // 测试调用 run 方法时,传递 user 对象的有效性 it('testRunWithUser', function(done) { request(app) .post('/1/functions/testRunWithUser') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); // 测试调用 run 方法 options callback it('testRun_options_callback', function(done) { request(app) .post('/1/functions/testRun_options_callback') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); // 测试调用 run 方法,返回值是 promise 类型 it('testRun_promise', function(done) { request(app) .post('/1/functions/testRun_promise') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); it('testRunWithSessionToken', function(done) { request(app) .post('/1/functions/testRunWithSessionToken') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .set('x-avoscloud-session-token', sessionToken_admin) .expect(200, done); }); it('testRpcRemote', function(done) { request(app) .post('/1/functions/testRpcRemote') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, done); }); // 测试 fs 模块的有效性 it('io', function(done) { request(app) .post('/1/functions/readDir') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(200, done); }); // 测试 onVerified hook 的有效性 it('onVerified', function(done) { request(app) .post("/1/functions/onVerified/sms") .set('X-Uluru-Application-Id', appId) .set('X-Uluru-Application-Key', appKey) .send({ object: { objectId: '54fd6a03e4b06c41e00b1f40', username: 'admin', __sign: '1464591343092,b0c8463a3c12bf4241820c52963515d9a363b6bc' } }) .expect(200) .expect({ result: 'ok'}, done); }); // 测试抛出异常时的处理 it('throw Error', function(done) { var stderr_write = process.stderr.write; var strings = []; global.process.stderr.write = function(string) { strings.push(string); }; request(app) .post('/1/functions/testThrowError') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .expect(500) .expect({result: 'ok'}, function() { assert.deepEqual('Execute \'testThrowError\' failed with error: ReferenceError: noThisMethod is not defined', strings[0].split('\n')[0]); assert.equal(1, strings.length); global.process.stderr.write = stderr_write; done(); }); }); it('timeoutTest', function(done) { this.timeout(17000); request(app) .post('/1.1/functions/testTimeout') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({ delay: 15200, }) .expect(503) .end(function(err, res) { res.body.should.eql({code:124, error:"The request timed out on the server."}); setTimeout(function() { // 等待业务逻辑真正响应,确认异常信息 done(); }, 1000); }); }); // 用户串号测试 it('user_matching_func', function(done) { this.timeout(30000); var count = 0; var cb = function(err) { if (err) { throw err; } count++; if (count === 10) { return done(); } }; var doRequest = function(sessionToken, username, cb) { var r = request(app) .post('/1.1/functions/userMatching') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey); if (sessionToken) { r.set('X-AVOSCloud-session-token', sessionToken); } r.end(function(err, res) { if (username) { res.body.result.reqUser.username.should.equal(username); } else { should.not.exist(res.body.reqUser); } return cb(err); }); }; for (var i = 0; i <= 4; i++) { doRequest(sessionToken_admin, 'admin', cb); doRequest('0hgr13u12tmgyv4x594682sv5', 'zhangsan', cb); doRequest(null, null, cb); } }); it('_metadatas', function(done) { request(app) .get('/1/functions/_ops/metadatas') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Master-Key', masterKey) .expect(200, function(err, res) { res.body.result.should.containDeep([ 'foo', 'hello', 'testUser', 'testRun', 'testRunWithUser', 'readDir', '__on_verified_sms', 'testThrowError', 'userMatching' ]); done(); }); }); it('CORS', function(done) { request(app) .options('/1/functions') .set('Origin', 'http://foo.bar') .set('Access-Control-Request-Method', 'POST') .set('Access-Control-Request-Headers', 'X-AVOSCloud-Application-Id, X-AVOSCloud-Application-Key') .expect('access-control-allow-origin', 'http://foo.bar') .expect(200, done); }); it('onCompleteBigqueryJob', function(done) { request(app) .post('/1.1/functions/BigQuery/onComplete') .set('X-AVOSCloud-Application-Id', appId) .set('X-AVOSCloud-Application-Key', appKey) .send({ id : "job id", status: "OK/ERROR", message: "当 status 为 ERROR 时的错误消息", __sign: '1464591343092,44c8f6a8a0520bc4636d890935aee0977ef34dd6' }) .expect(200, done); }); });