From ea579cbb63d45712028286378cc35892155e9220 Mon Sep 17 00:00:00 2001 From: Shawn Feldman Date: Mon, 20 Jul 2015 14:01:45 -0600 Subject: [PATCH 1/2] add integration tests add integration tests add integration tests --- .gitignore | 4 + stack/rest_integration_tests/README.md | 19 +++ .../rest_integration_tests/config/default.js | 37 +++++ stack/rest_integration_tests/config/index.js | 25 ++++ stack/rest_integration_tests/index.js | 20 +++ .../rest_integration_tests/lib/connections.js | 132 ++++++++++++++++++ stack/rest_integration_tests/lib/entities.js | 125 +++++++++++++++++ .../lib/notifications.js | 48 +++++++ stack/rest_integration_tests/lib/random.js | 74 ++++++++++ stack/rest_integration_tests/lib/response.js | 30 ++++ stack/rest_integration_tests/lib/token.js | 49 +++++++ stack/rest_integration_tests/lib/urls.js | 37 +++++ stack/rest_integration_tests/lib/users.js | 82 +++++++++++ stack/rest_integration_tests/package.json | 17 +++ .../test/authentication/management.js | 38 +++++ .../test/authentication/org.js | 37 +++++ .../test/authentication/resetPassword.js | 78 +++++++++++ .../test/authentication/user.js | 40 ++++++ .../test/connections/create.js | 49 +++++++ .../test/connections/delete.js | 77 ++++++++++ .../test/connections/get.js | 82 +++++++++++ .../test/entities/create.js | 38 +++++ .../test/entities/deleteAll.js | 37 +++++ .../test/entities/get.js | 51 +++++++ .../test/entities/update.js | 43 ++++++ stack/rest_integration_tests/test/main.js | 72 ++++++++++ stack/rest_integration_tests/test/mocha.opts | 3 + .../test/notifications/create.js | 36 +++++ .../test/queries/comparison.js | 58 ++++++++ .../test/queries/contains.js | 116 +++++++++++++++ .../test/queries/equals.js | 54 +++++++ .../test/queries/location.js | 42 ++++++ .../test/queries/order.js | 82 +++++++++++ stack/rest_integration_tests/test/setup.js | 103 ++++++++++++++ stack/rest_integration_tests/test/teardown.js | 65 +++++++++ .../test/users/create.js | 45 ++++++ 36 files changed, 1945 insertions(+) create mode 100644 stack/rest_integration_tests/README.md create mode 100644 stack/rest_integration_tests/config/default.js create mode 100644 stack/rest_integration_tests/config/index.js create mode 100644 stack/rest_integration_tests/index.js create mode 100644 stack/rest_integration_tests/lib/connections.js create mode 100644 stack/rest_integration_tests/lib/entities.js create mode 100644 stack/rest_integration_tests/lib/notifications.js create mode 100644 stack/rest_integration_tests/lib/random.js create mode 100644 stack/rest_integration_tests/lib/response.js create mode 100644 stack/rest_integration_tests/lib/token.js create mode 100644 stack/rest_integration_tests/lib/urls.js create mode 100644 stack/rest_integration_tests/lib/users.js create mode 100644 stack/rest_integration_tests/package.json create mode 100644 stack/rest_integration_tests/test/authentication/management.js create mode 100644 stack/rest_integration_tests/test/authentication/org.js create mode 100644 stack/rest_integration_tests/test/authentication/resetPassword.js create mode 100644 stack/rest_integration_tests/test/authentication/user.js create mode 100644 stack/rest_integration_tests/test/connections/create.js create mode 100644 stack/rest_integration_tests/test/connections/delete.js create mode 100644 stack/rest_integration_tests/test/connections/get.js create mode 100644 stack/rest_integration_tests/test/entities/create.js create mode 100644 stack/rest_integration_tests/test/entities/deleteAll.js create mode 100644 stack/rest_integration_tests/test/entities/get.js create mode 100644 stack/rest_integration_tests/test/entities/update.js create mode 100644 stack/rest_integration_tests/test/main.js create mode 100644 stack/rest_integration_tests/test/mocha.opts create mode 100644 stack/rest_integration_tests/test/notifications/create.js create mode 100644 stack/rest_integration_tests/test/queries/comparison.js create mode 100644 stack/rest_integration_tests/test/queries/contains.js create mode 100644 stack/rest_integration_tests/test/queries/equals.js create mode 100644 stack/rest_integration_tests/test/queries/location.js create mode 100644 stack/rest_integration_tests/test/queries/order.js create mode 100644 stack/rest_integration_tests/test/setup.js create mode 100644 stack/rest_integration_tests/test/teardown.js create mode 100644 stack/rest_integration_tests/test/users/create.js diff --git a/.gitignore b/.gitignore index 2119fa0e18..fd7cab0834 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,7 @@ portal/js/templates.js *.iml sdks/dotnet/samples/notifications/packages/* /sdks/html5-javascript/node_modules/ + + +/stack/rest_integration_tests/node_modules +/stack/rest_integration_tests/config/override.js \ No newline at end of file diff --git a/stack/rest_integration_tests/README.md b/stack/rest_integration_tests/README.md new file mode 100644 index 0000000000..c27ec393f4 --- /dev/null +++ b/stack/rest_integration_tests/README.md @@ -0,0 +1,19 @@ +#Usergrid RESTful Integration Tests + +These tests will run against a deployed instance of Usergrid and validate that APIs respond as expected. Tests require [Node.js](https://nodejs.org), [Mocha](http://mochajs.org), and [Should.js](http://shouldjs.github.io). + +Get Started: + +1. Install [Node.js](https://nodejs.org/download) version 0.12.1 or newer +2. Install Mocha: `$ [sudo] npm -g install mocha` +3. `$ cd` to `/integration_tests` and run `$ npm install`. +4. Using `config/default.js` as a template, create a copy `config/override.js` and modify it according to your environment. +5. Once configured, run `$ mocha test` from `/integration_tests` to perform tests. + +Notes: + +- Connections do not currently support org/app credentials. For tests to pass, you will need to give `Guest` POST rights to `/**` in the Usergrid authorizations table. +- In order for notifications tests to pass, you will need to create an Apple notifier named `apple-dev` using a valid development APNS certificate. +- In order to skip tests, you can append `.skip` to the test method, e.g.: `describe.skip()` or `it.skip()`. +- Depending on your environment, certain tests may take longer than expected. You can override timeouts by setting `this.timeout(timeInMilliseconds)` and `this.slow(timeInMilliseconds)` inside the `describe()` method before the tests execute. +- For more information on adding or modifying tests, check out the [Mocha](http://mochajs.org), and [Should.js](http://shouldjs.github.io) documentation. \ No newline at end of file diff --git a/stack/rest_integration_tests/config/default.js b/stack/rest_integration_tests/config/default.js new file mode 100644 index 0000000000..35ea3979a8 --- /dev/null +++ b/stack/rest_integration_tests/config/default.js @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = { + serverUrl: "http://localhost:8080/", + orgName: "test-organization", //must + appName: "test-app", //must pre create app + numberOfUsers: 5, + numberOfEntities: 20, + org: { + clientId: "", + clientSecret: "" + }, + usersCollection: "users", + entitiesTestCollection: "cats", + genericTestCollection1: "dogs", + genericTestCollection2: "horses", + consumableTestCollection: "food", + location: { // London + latitude: 51.51279, + longitude: -0.09184 + }, + notifierName: "apple-dev" +}; diff --git a/stack/rest_integration_tests/config/index.js b/stack/rest_integration_tests/config/index.js new file mode 100644 index 0000000000..98ac92db04 --- /dev/null +++ b/stack/rest_integration_tests/config/index.js @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var _ = require("underscore"); +var config = require("./default.js") +var override = require("./override.js") + + +if (Object.keys(override).length > 0) { + config = _.extend(config, override); +} +module.exports = config; diff --git a/stack/rest_integration_tests/index.js b/stack/rest_integration_tests/index.js new file mode 100644 index 0000000000..30a47b056a --- /dev/null +++ b/stack/rest_integration_tests/index.js @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require('./config/config.js'); + +console.log('config is '+ JSON.stringify(config)); + diff --git a/stack/rest_integration_tests/lib/connections.js b/stack/rest_integration_tests/lib/connections.js new file mode 100644 index 0000000000..ddc830c340 --- /dev/null +++ b/stack/rest_integration_tests/lib/connections.js @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require("../config"); +var urls = require("./urls"); +var random = require("./random"); +var responseLib = require("./response"); +var async = require('async'); +var request = require("request"); + +module.exports = { + create: function(fromCollection, toCollection, relationship, cb) { + async.parallel({ + from: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + fromCollection), + json: true + }, function(e, r, body) { + cb(e, body.entities[0]); + }); + }, + to: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + toCollection), + json: true + }, function(e, r, body) { + cb(e, body.entities[0]); + }); + } + }, function(err, results) { + var url = urls.appUrl() + + fromCollection + "/" + + results.from.uuid + "/" + + relationship + "/" + + results.to.uuid; + request.post({ + url: url, + json: true + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }); + }); + }, + get: function(fromCollection, toCollection, relationship, cb) { + async.parallel({ + from: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + fromCollection + "?limit=1"), + json: true + }, function(e, r, body) { + var o = { + parent: body.entities[0] + } + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + fromCollection + "/" + o.parent.uuid + "/" + relationship), + json: true + }, function(e, r, body) { + o.related = body.entities; + cb(e, o); + }); + }); + }, + to: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + toCollection + "?limit=1"), + json: true + }, function(e, r, body) { + var o = { + parent: body.entities[0] + } + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + toCollection + "/" + o.parent.uuid + "/connecting/" + relationship), + json: true + }, function(e, r, body) { + o.related = body.entities; + cb(e, o); + }); + }); + } + }, function(err, results) { + cb(err, results); + }); + }, + delete: function(fromCollection, toCollection, relationship, cb) { + async.parallel({ + from: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + fromCollection), + json: true + }, function(e, r, body) { + cb(e, body.entities[0]); + }); + }, + to: function(cb) { + request.get({ + url: urls.appendOrgCredentials(urls.appUrl() + toCollection), + json: true + }, function(e, r, body) { + cb(e, body.entities[0]); + }); + } + }, function(err, results) { + var url = urls.appUrl() + + fromCollection + "/" + + results.from.uuid + "/" + + relationship + "/" + + results.to.uuid; + request.del({ + url: url, + json: true + }, function(e, r, body) { + module.exports.get(fromCollection, toCollection, relationship, function(err, results) { + cb(err, results); + }); + }); + }); + } +}; diff --git a/stack/rest_integration_tests/lib/entities.js b/stack/rest_integration_tests/lib/entities.js new file mode 100644 index 0000000000..c62ca0d9d5 --- /dev/null +++ b/stack/rest_integration_tests/lib/entities.js @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require("../config"); +var urls = require("./urls"); +var random = require("./random"); +var responseLib = require("./response"); +var async = require('async'); +var request = require("request"); + +module.exports = { + create: function(collection, numberOfEntities, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection); + var requestArray = [] + geos = random.geo(config.location, 2000, numberOfEntities); + // console.log(geos); + for (var i = 0; i < numberOfEntities; i++) { + requestArray.push({ + consistentProperty: "somethingConsistent", + randomProperty: "somethingRandom - " + random.randomString(10), + intProperty: random.randomNumber(5), + optionsProperty: random.abc(), + location: geos[i], + title: "A Tale of Two Cities" + }); + } + request.post({ + url: url, + json: true, + body: requestArray + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }); + }, + deleteAll: function(collection, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection); + deleteAllEntities(collection, function(e) { + request.get({ + url: url, + json: true + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }) + }) + }, + update: function(collection, uuid, body, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection + "/" + uuid); + request.put({ + url: url, + body: body, + json: true + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }) + }, + get: function(collection, numberOfEntities, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?limit=" + numberOfEntities.toString()); + request.get({ + url: url, + json: true + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }) + }, + getWithQuery: function(collection, query, numberOfEntities, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?ql=" + encodeURIComponent(query) + "&limit=" + numberOfEntities.toString()); + request.get({ + url: url, + json: true + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }) + } +}; + +function deleteAllEntities(collection, cb) { + var url = urls.appendOrgCredentials(urls.appUrl() + collection); + request.get({ + url: url, + json: true + }, function(e, r, body) { + if (body.count === undefined) { + cb("The 'count' property is not defined at " + url); + } else if (body.count > 0) { + var deletes = []; + for (var i = 0; i < body.count; i++) { + deletes.push({ + url: urls.appendOrgCredentials(urls.appUrl() + collection + "/" + body.entities[i].uuid), + json: true + }); + } + async.each(deletes, function(options, cb) { + request.del(options, function(e) { + cb(e); + }); + }, function(err) { + setTimeout(function() { + deleteAllEntities(collection, function(e) { + cb(e); + }); + }, 600); // Mandatory, since it seems to not retrieve entities if you make a request in < 600ms + }); + } else { + cb(); + } + }); +} diff --git a/stack/rest_integration_tests/lib/notifications.js b/stack/rest_integration_tests/lib/notifications.js new file mode 100644 index 0000000000..33fef16241 --- /dev/null +++ b/stack/rest_integration_tests/lib/notifications.js @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require("../config"); +var urls = require("./urls"); +var random = require("./random"); +var responseLib = require("./response"); +var async = require('async'); +var request = require("request"); + +module.exports = { + create: function(message, cb) { + // Need to ensure at least one device exists in the devices collection + request.post({ + url: urls.appendOrgCredentials(urls.appUrl() + "/devices"), + json: true, + body: { + name: "testDevice" + } + }, function(e, r, body) { + payload = {}; + payload[config.notifierName] = message; + request.post({ + url: urls.appendOrgCredentials(urls.appUrl() + "/devices;ql=select */notifications"), + json: true, + body: { + payloads: payload + } + }, function(e, r, body) { + var error = responseLib.getError(e, r); + cb(error, error ? error : body); + }); + }); + } +}; diff --git a/stack/rest_integration_tests/lib/random.js b/stack/rest_integration_tests/lib/random.js new file mode 100644 index 0000000000..d5dce65503 --- /dev/null +++ b/stack/rest_integration_tests/lib/random.js @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = {}; +module.exports.randomString = function randomString(length) { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < length; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} + +module.exports.abc = function abc() { + letters = ["aaa bbb ccc", "ddd eee fff", "ggg hhh iii", "jjj kkk lll"]; + return letters[Math.floor(Math.random() * letters.length)]; +} + +module.exports.randomNumber = function randomNumber(length) { + var text = ""; + var possible = "0123456789"; + + for (var i = 0; i < length; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return parseInt(text); +} + +module.exports.randomEntity = function randomEntity(entitiesArray) { + return entitiesArray[Math.floor(Math.random()*entitiesArray.length)]; +} + +module.exports.geo = function geo(center, radius, count) { + var points = []; + for (var i = 0; i < count; i++) { + points.push(randomGeo(center, radius)); + } + return points; +} + +function randomGeo(center, radius) { + var y0 = center.latitude; + var x0 = center.longitude; + var rd = radius / 111300; + + var u = Math.random(); + var v = Math.random(); + + var w = rd * Math.sqrt(u); + var t = 2 * Math.PI * v; + var x = w * Math.cos(t); + var y = w * Math.sin(t); + + // var xp = x / Math.cos(y0); + + return { + 'latitude': y + y0, + 'longitude': x + x0 + }; +} diff --git a/stack/rest_integration_tests/lib/response.js b/stack/rest_integration_tests/lib/response.js new file mode 100644 index 0000000000..7aab031882 --- /dev/null +++ b/stack/rest_integration_tests/lib/response.js @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = {}; +module.exports.getError = function(err, response) { + return err || (response.statusCode >= 400 ? response.body : null) +}; + +module.exports.distanceInMeters = function(location1, location2) { + var R = 6371000; + var a = 0.5 - Math.cos((location2.latitude - location1.latitude) * Math.PI / 180) / 2 + + Math.cos(location1.latitude * Math.PI / 180) * Math.cos(location2.latitude * Math.PI / 180) * + (1 - Math.cos((location2.longitude - location1.longitude) * Math.PI / 180)) / 2; + + var distance = R * 2 * Math.asin(Math.sqrt(a)); + return distance; +} diff --git a/stack/rest_integration_tests/lib/token.js b/stack/rest_integration_tests/lib/token.js new file mode 100644 index 0000000000..96a3522a2a --- /dev/null +++ b/stack/rest_integration_tests/lib/token.js @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require("../config"); +var urls = require("./urls"); +var responseLib = require("./response"); +var request = require("request"); + +module.exports= { + getOrgToken: function (cb) { + var managementUrl = urls.managementUrl(); + + var options = { + uri: managementUrl + "token", + method: 'POST', + json: {client_id: config.org.clientId, client_secret: config.org.clientSecret, grant_type: "client_credentials"} + }; + request(options, function (err, response, body) { + var error = responseLib.getError(err,response); + cb(error, body); + }); + }, + getManagementToken: function (username, password, cb) { + var managementUrl = urls.managementUrl(); + var options = { + uri: managementUrl + "token", + method: 'POST', + json: {username: username, password: password, grant_type: "password"} + }; + request.post(options, function (err, response, body) { + var error = responseLib.getError(err,response); + cb(error,body); + }); + } + +}; diff --git a/stack/rest_integration_tests/lib/urls.js b/stack/rest_integration_tests/lib/urls.js new file mode 100644 index 0000000000..2edfd572a7 --- /dev/null +++ b/stack/rest_integration_tests/lib/urls.js @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var config = require("../config"); +module.exports = { + appUrl: function () { + return config.serverUrl + config.orgName + "/" + config.appName + "/"; + }, + managementUrl: function () { + return config.serverUrl + "management/"; + }, + appendAccessToken: function(url,tokenData){ + if(tokenData == null){ + return url; + } + var token = tokenData.access_token || tokenData; + return url + (url.indexOf("?") >= 0 ? "&" : "?" ) + "access_token="+token; + }, + appendOrgCredentials: function(url, clientId, clientSecret){ + clientId = clientId || config.org.clientId; + clientSecret = clientSecret || config.org.clientSecret; + return url + (url.indexOf("?") >= 0 ? "&" : "?" ) + "client_id="+clientId+"&client_secret="+clientSecret; + } +}; diff --git a/stack/rest_integration_tests/lib/users.js b/stack/rest_integration_tests/lib/users.js new file mode 100644 index 0000000000..0a47324bdf --- /dev/null +++ b/stack/rest_integration_tests/lib/users.js @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var request = require("request"); +var token = require("./token"); +var urls = require("./urls"); +var responseLib = require("./response"); +module.exports = {}; + +module.exports.add = function(user, cb) { + request.post(urls.appendOrgCredentials(urls.appUrl() + "users"), { + json: user + }, function(err, response, body) { + var error = responseLib.getError(err, response); + cb(error, error ? null : body.entities.pop()); + }); +}; + +module.exports.login = function(username, password, cb) { + request.post({ + url: urls.appUrl() + "token", + json: { + username: username, + password: password, + grant_type: "password" + } + }, function(err, response, body) { + var error = responseLib.getError(err, response); + cb(error, body); + }); +}; + +module.exports.resetPassword = function(username, oldpassword, newpassword, cb) { + request.post({ + uri: urls.appUrl() + "users/" + username + "/password", + json: { + oldpassword: oldpassword, + newpassword: newpassword + } + }, function(e, r, body) { + cb(e, r, body); + }); +}; + +module.exports.resetPasswordAsAdmin = function(username, newpassword, cb) { + request.post({ + uri: urls.appendOrgCredentials(urls.appUrl() + "users/" + username + "/password"), + json: { + newpassword: newpassword + } + }, function(e, r, body) { + cb(e, r, body); + }); +}; + +module.exports.addToRole = function(username, role, cb) { + request.post(urls.appendOrgCredentials(urls.appUrl() + "roles/" + role + "/users/" + username), null, function(err, response, body) { + var error = responseLib.getError(err, response); + cb(error); + }); +}; + +module.exports.get = function(username, cb) { + request.get(urls.appendOrgCredentials(urls.appUrl() + "users/" + username), function(err, response, body) { + var json = JSON.parse(body); + var error = response.statusCode === 404 ? null : responseLib.getError(err, response); + cb(error, error ? null : response.statusCode === 404 ? null : json.entities.pop()); + }) +} diff --git a/stack/rest_integration_tests/package.json b/stack/rest_integration_tests/package.json new file mode 100644 index 0000000000..7733992cee --- /dev/null +++ b/stack/rest_integration_tests/package.json @@ -0,0 +1,17 @@ +{ + "name": "Usergrid_Tests", + "version": "0.0.1", + "devDependencies": { + "async": "^1.2.1", + "mocha": "~2.2.5", + "request": "~2.58.0", + "should": "~6.0.3", + "underscore": "^1.8.3", + "uuid": "^2.0.1", + "colors": "~1.1.2", + "i": "~0.3.3" + }, + "engines": { + "node": ">0.12.1" + } +} diff --git a/stack/rest_integration_tests/test/authentication/management.js b/stack/rest_integration_tests/test/authentication/management.js new file mode 100644 index 0000000000..bef2a96eff --- /dev/null +++ b/stack/rest_integration_tests/test/authentication/management.js @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +var users = require("../../lib/users") +var config = require("../../config") +var should = require("should") +var setup = require("../setup") +module.exports = {}; + +module.exports.test = function() { + describe('get a management token', function() { + it('should return valid token', function(done) { + var admin = setup.admins[0]; + users.login(admin.username, admin.password, function(err, body) { + should(err).be.null; + body.should.have.property('access_token').and.have.lengthOf(63);; + body.should.have.property('expires_in'); + body.should.have.property('expires_in').which.is.a.Number; + body.user.username.should.equal(admin.username); + done(); + }); + }); + }); +} diff --git a/stack/rest_integration_tests/test/authentication/org.js b/stack/rest_integration_tests/test/authentication/org.js new file mode 100644 index 0000000000..95d182a471 --- /dev/null +++ b/stack/rest_integration_tests/test/authentication/org.js @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +var token = require("../../lib/token") +var config = require("../../config") +var should = require("should") +var setup = require("../setup") +module.exports = {}; + +module.exports.test = function() { + describe('get an org token', function() { + it('should return valid token', function(done) { + token.getOrgToken(function(err, tokenData) { + should(err).be.null; + tokenData.should.have.property('access_token').and.have.lengthOf(63);; + tokenData.should.have.property('expires_in'); + tokenData.should.have.property('expires_in').which.is.a.Number; + tokenData.organization.name.should.equal(config.orgName) + done(); + }); + }); + }); +} diff --git a/stack/rest_integration_tests/test/authentication/resetPassword.js b/stack/rest_integration_tests/test/authentication/resetPassword.js new file mode 100644 index 0000000000..86d01a6a4a --- /dev/null +++ b/stack/rest_integration_tests/test/authentication/resetPassword.js @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +var token = require("../../lib/token") +var users = require("../../lib/users") +var config = require("../../config") +var should = require("should") +var setup = require("../setup") +var async = require("async"); + +module.exports = {}; + +module.exports.test = function() { + describe('reset a user password', function() { + it('should reset a user\'s password only when the correct old password is provided', function(done) { + var user = setup.users[0]; + users.login(user.username, user.password, function(err, body) { + should(err).be.null; + body.should.have.property('access_token').and.have.lengthOf(63); + async.parallel({ + bad: function(cb) { + users.resetPassword(user.username, user.password + "_bad", user.password + "_badnew", function(e, r, body) { + cb(e, { + r: r, + body: body + }); + }); + }, + good: function(cb) { + users.resetPassword(user.username, user.password, user.password + "_goodnew", function(e, r, body) { + cb(e, { + r: r, + body: body + }); + }); + } + }, + function(err, results) { + results.bad.r.statusCode.should.equal(400); + results.bad.body.should.have.property('error').which.equal('auth_invalid_username_or_password'); + results.bad.body.should.have.property('exception').which.equal('org.apache.usergrid.management.exceptions.IncorrectPasswordException'); + results.bad.body.should.have.property('error_description').which.equal('Unable to authenticate due to username or password being incorrect'); + + results.good.r.statusCode.should.equal(200); + results.good.body.should.have.property('action').which.equal('set user password'); + results.good.body.should.have.property('duration'); + + done(); + }); + + }); + }); + it('should reset a user\'s password using org credentials', function(done) { + var user = setup.users[0]; + users.resetPasswordAsAdmin(user.username, user.password, function(e, r, body) { + r.statusCode.should.equal(200); + body.should.have.property('action').which.equal('set user password'); + body.should.have.property('duration'); + + done(); + }); + }) + }); +} diff --git a/stack/rest_integration_tests/test/authentication/user.js b/stack/rest_integration_tests/test/authentication/user.js new file mode 100644 index 0000000000..8faddd3509 --- /dev/null +++ b/stack/rest_integration_tests/test/authentication/user.js @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +var token = require("../../lib/token") +var users = require("../../lib/users") +var config = require("../../config") +var should = require("should") +var setup = require("../setup") + +module.exports = {}; + +module.exports.test = function() { + describe('get a user token', function() { + it('should return valid token', function(done) { + var user = setup.users[0]; + users.login(user.username, user.password, function(err, body) { + should(err).be.null; + body.should.have.property('access_token').and.have.lengthOf(63); + body.should.have.property('expires_in'); + body.should.have.property('expires_in').which.is.a.Number; + body.user.username.should.equal(user.username); + done(); + }); + }); + }); +} diff --git a/stack/rest_integration_tests/test/connections/create.js b/stack/rest_integration_tests/test/connections/create.js new file mode 100644 index 0000000000..ca9ce84de8 --- /dev/null +++ b/stack/rest_integration_tests/test/connections/create.js @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var connections = require("../../lib/connections"); +var should = require("should"); +var config = require('../../config'); +var inflect = require('i')(); + +module.exports = { + test: function() { + describe("create connection", function() { + it("should connect " + config.genericTestCollection1 + "[0] to " + config.consumableTestCollection + "[0] via the relationship 'consumed'", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.create(config.genericTestCollection1, config.consumableTestCollection, "consumed", function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(1); + body.entities[0].type.should.equal(config.consumableTestCollection); + done(); + }) + }); + it("should connect " + config.genericTestCollection1 + "[0] to " + config.genericTestCollection2 + "[0] via the relationship 'likes'", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.create(config.genericTestCollection1, config.genericTestCollection2, "likes", function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(1); + body.entities[0].type.should.equal(inflect.singularize(config.genericTestCollection2)); + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/connections/delete.js b/stack/rest_integration_tests/test/connections/delete.js new file mode 100644 index 0000000000..9014a02fe4 --- /dev/null +++ b/stack/rest_integration_tests/test/connections/delete.js @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var connections = require("../../lib/connections"); +var should = require("should"); +var config = require('../../config'); +var util = require('util'); +var inflect = require('i')(); + +module.exports = { + test: function() { + describe("delete connections", function() { + var rel1 = "consumed"; + it("should delete the '" + rel1 + "' connection between " + config.genericTestCollection1 + "[0] and " + config.consumableTestCollection + "[0]", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.delete(config.genericTestCollection1, config.consumableTestCollection, rel1, function(err, r) { + should(err).be.null; + if (r.from.parent.metadata.hasOwnProperty("connections")) { + r.from.parent.metadata.connections.should.not.have.property(rel1); + } else { + r.from.parent.metadata.should.not.have.property("connections"); + } + r.from.parent.metadata.should.not.have.property("connecting"); + r.from.related.should.be.an.instanceOf(Array).and.have.lengthOf(0); + if (r.to.parent.metadata.hasOwnProperty("connecting")) { + r.to.parent.metadata.connecting.should.not.have.property(rel1); + } else { + r.to.parent.metadata.should.not.have.property("connecting"); + } + r.to.related.should.be.an.instanceOf(Array).and.have.lengthOf(0); + + done(); + }) + }); + var rel2 = "likes"; + it("should delete the '" + rel2 + "' connection between " + config.genericTestCollection1 + "[0] and " + config.genericTestCollection2 + "[0]", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.delete(config.genericTestCollection1, config.genericTestCollection2, rel2, function(err, r) { + should(err).be.null; + if (r.from.parent.metadata.hasOwnProperty("connections")) { + r.from.parent.metadata.connections.should.not.have.property(rel2); + } else { + r.from.parent.metadata.should.not.have.property("connections"); + } + r.from.parent.metadata.should.not.have.property("connecting"); + r.from.related.should.be.an.instanceOf(Array).and.have.lengthOf(0); + if (r.to.parent.metadata.hasOwnProperty("connecting")) { + r.to.parent.metadata.connecting.should.not.have.property(rel2); + } else { + r.to.parent.metadata.should.not.have.property("connecting"); + } + r.from.parent.metadata.should.not.have.property("connections"); + r.to.related.should.be.an.instanceOf(Array).and.have.lengthOf(0); + + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/connections/get.js b/stack/rest_integration_tests/test/connections/get.js new file mode 100644 index 0000000000..cea7bbe661 --- /dev/null +++ b/stack/rest_integration_tests/test/connections/get.js @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var connections = require("../../lib/connections"); +var should = require("should"); +var config = require('../../config'); +var util = require('util'); +var inflect = require('i')(); + +module.exports = { + test: function() { + describe("get connections", function() { + var rel1 = "consumed"; + it("should see " + config.genericTestCollection1 + "[0] connected to " + config.consumableTestCollection + "[0] by the relationship '" + rel1 + "'", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.get(config.genericTestCollection1, config.consumableTestCollection, rel1, function(err, r) { + should(err).be.null; + + r.from.parent.metadata.connections.should.have.property(rel1) + r.from.parent.metadata.connections[rel1].should.equal( + util.format("/%s/%s/%s", inflect.pluralize(config.genericTestCollection1), r.from.parent.uuid, rel1) + ); + r.from.parent.type.should.equal(inflect.singularize(config.genericTestCollection1)); + r.from.related[0].uuid.should.equal(r.to.parent.uuid); + r.from.related[0].type.should.equal(inflect.singularize(config.consumableTestCollection)); + + r.to.parent.metadata.connecting.should.have.property(rel1) + r.to.parent.metadata.connecting[rel1].should.equal( + util.format("/%s/%s/connecting/%s", inflect.pluralize(config.consumableTestCollection), r.to.parent.uuid, rel1) + ); + r.to.parent.type.should.equal(inflect.singularize(config.consumableTestCollection)); + r.to.related[0].uuid.should.equal(r.from.parent.uuid); + r.to.related[0].type.should.equal(inflect.singularize(config.genericTestCollection1)); + + done(); + }) + }); + var rel2 = "likes"; + it("should see " + config.genericTestCollection1 + "[0] connected to " + config.genericTestCollection2 + "[0] by the relationship '" + rel2 + "'", + function(done) { + this.slow(10000); + this.timeout(15000); + connections.get(config.genericTestCollection1, config.genericTestCollection2, rel2, function(err, r) { + should(err).be.null; + + r.from.parent.metadata.connections.should.have.property(rel2) + r.from.parent.metadata.connections[rel2].should.equal( + util.format("/%s/%s/%s", inflect.pluralize(config.genericTestCollection1), r.from.parent.uuid, rel2) + ); + r.from.parent.type.should.equal(inflect.singularize(config.genericTestCollection1)); + r.from.related[0].uuid.should.equal(r.to.parent.uuid); + r.from.related[0].type.should.equal(inflect.singularize(config.genericTestCollection2)); + + r.to.parent.metadata.connecting.should.have.property(rel2) + r.to.parent.metadata.connecting[rel2].should.equal( + util.format("/%s/%s/connecting/%s", inflect.pluralize(config.genericTestCollection2), r.to.parent.uuid, rel2) + ); + r.to.parent.type.should.equal(inflect.singularize(config.genericTestCollection2)); + r.to.related[0].uuid.should.equal(r.from.parent.uuid); + r.to.related[0].type.should.equal(inflect.singularize(config.genericTestCollection1)); + + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/entities/create.js b/stack/rest_integration_tests/test/entities/create.js new file mode 100644 index 0000000000..97e820c906 --- /dev/null +++ b/stack/rest_integration_tests/test/entities/create.js @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var config = require('../../config'); + +module.exports = { + test: function() { + var numberOfRecords = 30; + describe("create entities", function() { + it("should create " + numberOfRecords.toString() + " entities in the " + config.entitiesTestCollection + " collection", function(done) { + this.slow(numberOfRecords * 500); + entities.create(config.entitiesTestCollection, numberOfRecords, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(numberOfRecords); + body.entities.forEach(function(entity) { + entity.should.have.property("uuid").and.match(/(\w{8}(-\w{4}){3}-\w{12}?)/); + }) + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/entities/deleteAll.js b/stack/rest_integration_tests/test/entities/deleteAll.js new file mode 100644 index 0000000000..daa20ea99a --- /dev/null +++ b/stack/rest_integration_tests/test/entities/deleteAll.js @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var config = require('../../config'); + +module.exports = { + test: function(collectionName) { + collectionName = collectionName ? collectionName : config.entitiesTestCollection; + describe("delete entities", function() { + it("should delete all entities from the " + collectionName + " collection", function(done) { + this.timeout(60000); + this.slow(30000); + entities.deleteAll(collectionName, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(0); + body.count.should.equal(0); + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/entities/get.js b/stack/rest_integration_tests/test/entities/get.js new file mode 100644 index 0000000000..665b1e6c8f --- /dev/null +++ b/stack/rest_integration_tests/test/entities/get.js @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require("async"); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("get entities", function() { + it("should get 1 entity", function(done) { + entities.get(config.entitiesTestCollection, 1, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(1); + body.count.should.equal(1); + done(); + }) + }); + it("should get 4 entities", function(done) { + entities.get(config.entitiesTestCollection, 4, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(4); + body.count.should.equal(4); + done(); + }) + }); + it("should get 18 entities", function(done) { + entities.get(config.entitiesTestCollection, 18, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(18); + body.count.should.equal(18); + done(); + }) + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/entities/update.js b/stack/rest_integration_tests/test/entities/update.js new file mode 100644 index 0000000000..04f4a97629 --- /dev/null +++ b/stack/rest_integration_tests/test/entities/update.js @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var random = require("../../lib/random"); +var should = require("should"); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("update entity", function() { + it("should get a random entity and set 'newProperty' to 'BANJO'", function(done) { + this.timeout(10000); + this.slow(5000); + entities.get(config.entitiesTestCollection, random.randomNumber(10), function(err, body) { + var payload = { + newProperty: "BANJO" + } + should(body.entities[0].newProperty).not.exist; + entities.update(config.entitiesTestCollection, body.entities[body.entities.length - 1].uuid, payload, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(1); + body.entities[0].newProperty.should.equal("BANJO"); + done(); + }); + }); + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/main.js b/stack/rest_integration_tests/test/main.js new file mode 100644 index 0000000000..24b6cfecb7 --- /dev/null +++ b/stack/rest_integration_tests/test/main.js @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var should = require("should"); +var config = require("../config/"); +var setup = require("./setup"); +var teardown = require("./teardown"); +var async = require('async'); +var request = require('request'); +var colors = require('colors'); + +var entities = require('../lib/entities'); + +describe("baas 2.0 tests", function() { + before(function(done) { + setup.do(function() { + done(); + }) + }); + describe("authentication", function() { + require("./authentication/user.js").test(); + require("./authentication/resetPassword.js").test(); + require("./authentication/management.js").test(); + require("./authentication/org.js").test(); + }); + describe("users", function() { + require("./users/create.js").test(); + }); + describe("entities", function() { + require("./entities/create.js").test(); + require("./entities/get.js").test(); + require("./entities/update.js").test(); + require("./entities/deleteAll.js").test(); + }); + describe("connections", function() { + require('./connections/create.js').test(); + require('./connections/get.js').test(); + require('./connections/delete.js').test(); + }); + describe("queries", function() { + require('./queries/equals.js').test(); + require('./queries/contains.js').test(); + require('./queries/order.js').test(); + require('./queries/comparison.js').test(); + require('./queries/location.js').test(); + }); + describe("notifications", function() { + // Requires an apple notifier to be created in BaaS portal prior to running this test. + // See: http://apigee.com/docs/app-services/content/creating-notifiers + require('./notifications/create.js').test(); + }); + + after(function(done) { + this.timeout(40000); + teardown.do(function() { + done(); + }); + }); +}); diff --git a/stack/rest_integration_tests/test/mocha.opts b/stack/rest_integration_tests/test/mocha.opts new file mode 100644 index 0000000000..9e2480f8d6 --- /dev/null +++ b/stack/rest_integration_tests/test/mocha.opts @@ -0,0 +1,3 @@ +--ui bdd +--recursive +--timeout 5000 \ No newline at end of file diff --git a/stack/rest_integration_tests/test/notifications/create.js b/stack/rest_integration_tests/test/notifications/create.js new file mode 100644 index 0000000000..9a962feaf8 --- /dev/null +++ b/stack/rest_integration_tests/test/notifications/create.js @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var should = require("should"); +var uuid = require("uuid"); +var notifications = require("../../lib/notifications"); + +module.exports = { + test: function() { + // Requires an apple notifier to be created in BaaS portal prior to running this test. + // See: http://apigee.com/docs/app-services/content/creating-notifiers + describe("create a notification", function() { + it("should successfully create a notification", function(done) { + notifications.create("Hello World!", function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(1); + body.entities[0].state.should.equal('CREATED'); + done(); + }); + }); + }); + } +} diff --git a/stack/rest_integration_tests/test/queries/comparison.js b/stack/rest_integration_tests/test/queries/comparison.js new file mode 100644 index 0000000000..5fedbdbe21 --- /dev/null +++ b/stack/rest_integration_tests/test/queries/comparison.js @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require('async'); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("filter " + config.genericTestCollection2 + " with '>' and '<' queries", function() { + var query = "where intProperty > 30000"; + numberOfEntities = Math.min(config.numberOfEntities, 10); + it('should return a subset of results ' + query, function(done) { + this.timeout(10000); + entities.getWithQuery(config.genericTestCollection2, query, numberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + if (body.entities.length > 0) { + body.entities.length.should.be.greaterThan(0).and.lessThan(numberOfEntities + 1); + body.entities.forEach(function(entity) { + entity.intProperty.should.be.greaterThan(30000); + }); + } + done(); + }); + }); + var query = "where intProperty > 30000 && intProperty < 40000"; + it('should return a subset of results ' + query, function(done) { + this.timeout(10000); + entities.getWithQuery(config.genericTestCollection2, query, numberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + if (body.entities.length > 0) { + body.entities.length.should.be.greaterThan(0).and.lessThan(numberOfEntities + 1); + body.entities.forEach(function(entity) { + entity.intProperty.should.be.greaterThan(30000).and.lessThan(40000); + }); + } + done(); + }); + }); + }); + } +}; diff --git a/stack/rest_integration_tests/test/queries/contains.js b/stack/rest_integration_tests/test/queries/contains.js new file mode 100644 index 0000000000..01c8ef1dfa --- /dev/null +++ b/stack/rest_integration_tests/test/queries/contains.js @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require('async'); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("filter " + config.genericTestCollection1 + " with 'contains' queries", function(done) { + var query1 = "where consistentProperty contains 'somethingConsistent'"; + var maxNumberOfEntities = Math.max(config.numberOfEntities, 100); + it('should return ' + config.numberOfEntities + ' results ' + query1, function(done) { + this.timeout(30000); + entities.getWithQuery(config.genericTestCollection1, query1, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.equal(config.numberOfEntities); + body.entities.forEach(function(entity) { + entity.consistentProperty.should.equal('somethingConsistent'); + }); + done(); + }); + }); + var query2 = "where consistentProperty contains '*ethi*'"; + // skipping this test for now since it doesn't work in 1.0 + it.skip('should return ' + config.numberOfEntities + ' results ' + query2, function(done) { + entities.getWithQuery(config.genericTestCollection1, query2, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.equal(config.numberOfEntities); + body.entities.forEach(function(entity) { + entity.consistentProperty.should.equal('somethingConsistent'); + }); + done(); + }); + }); + var query3 = "where optionsProperty contains 'aaa*'"; + // this should be updated when running tests against 2.0 - *aaa* instead of aaa* + it('should return a subset of results ' + query3, function(done) { + entities.getWithQuery(config.genericTestCollection1, query3, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + if (body.entities.length > 0) { + body.entities.length.should.be.greaterThan(0).and.lessThan(config.numberOfEntities + 1); + body.entities.forEach(function(entity) { + entity.optionsProperty.should.match(/(\b|^)aaa(\b|$)/); + }); + } + done(); + }); + }); + var query4 = "where title contains 'tale'"; + it('should return a subset of results ' + query4, function(done) { + entities.getWithQuery(config.genericTestCollection1, query4, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + if (body.entities.length > 0) { + body.entities.length.should.be.greaterThan(0).and.lessThan(config.numberOfEntities + 1); + body.entities.forEach(function(entity) { + entity.title.should.match(/tale/i); + }); + } + done(); + }); + }); + var query5 = "where title contains 'ta*'"; + it('should return a subset of results ' + query5, function(done) { + entities.getWithQuery(config.genericTestCollection1, query5, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + if (body.entities.length > 0) { + body.entities.length.should.be.greaterThan(0).and.lessThan(config.numberOfEntities + 1); + body.entities.forEach(function(entity) { + entity.title.should.match(/ta.*/i); + }); + } + done(); + }); + }); + var query6 = "where consistentProperty contains 'some*'"; + it('should return a subset of results ' + query6, function() { + entities.getWithQuery('horses', query6, 10, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.be.greaterThan(0).and.lessThan(11); + }); + }); + var query7 = "where consistentProperty contains 'ssccxxome*'"; + it('should not return a subset of results ' + query7, function() { + var query = "where firstProperty contains 'ssccxxome*'"; + entities.getWithQuery('horses', query7, 10, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.be.equal(0); + + }); + }); + }); + } +} diff --git a/stack/rest_integration_tests/test/queries/equals.js b/stack/rest_integration_tests/test/queries/equals.js new file mode 100644 index 0000000000..904646b988 --- /dev/null +++ b/stack/rest_integration_tests/test/queries/equals.js @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require('async'); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("filter " + config.genericTestCollection1 + " with '=' and '!=' queries", function(done) { + var query1 = "where consistentProperty = 'somethingConsistent'"; + maxNumberOfEntities = Math.max(config.numberOfEntities, 100); + it('should return ' + config.numberOfEntities + ' results ' + query1, function(done) { + entities.getWithQuery(config.genericTestCollection1, query1, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.equal(config.numberOfEntities); + body.entities.forEach(function(entity) { + entity.consistentProperty.should.equal('somethingConsistent'); + }); + done(); + }); + }); + + var query2 = "where title = 'A Tale of Two Cities'"; + maxNumberOfEntities = Math.max(config.numberOfEntities, 100); + it('should return ' + config.numberOfEntities + ' results ' + query2, function(done) { + entities.getWithQuery(config.genericTestCollection1, query2, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.length.should.equal(config.numberOfEntities); + body.entities.forEach(function(entity) { + entity.title.should.equal('A Tale of Two Cities'); + }); + done(); + }); + }); + }); + } +} diff --git a/stack/rest_integration_tests/test/queries/location.js b/stack/rest_integration_tests/test/queries/location.js new file mode 100644 index 0000000000..6fbc96a383 --- /dev/null +++ b/stack/rest_integration_tests/test/queries/location.js @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require('async'); +var config = require('../../config'); +var response = require('../../lib/response'); + +module.exports = { + test: function() { + describe("filter " + config.genericTestCollection2 + " with location queries", function(done) { + var locationString = config.location.latitude + ", " + config.location.longitude; + var query = "location within 1000 of " + locationString; + maxNumberOfEntities = Math.max(config.numberOfEntities, 100); + it("should return all results with a location within 1000m of " + locationString, function(done) { + entities.getWithQuery(config.genericTestCollection2, query, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + body.entities.forEach(function(entity) { + var distance = response.distanceInMeters(config.location, entity.location); + distance.should.be.lessThan(1000); + }); + done(); + }); + }); + }); + } +} diff --git a/stack/rest_integration_tests/test/queries/order.js b/stack/rest_integration_tests/test/queries/order.js new file mode 100644 index 0000000000..8cbb78f7d1 --- /dev/null +++ b/stack/rest_integration_tests/test/queries/order.js @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../../lib/entities"); +var should = require("should"); +var async = require('async'); +var config = require('../../config'); + +module.exports = { + test: function() { + describe("sort " + config.genericTestCollection1 + " with 'order by' queries", function(done) { + var query1 = "order by created desc"; + it('should return a subset of results ' + query1.replace('order', 'ordered'), function(done) { + entities.getWithQuery(config.genericTestCollection1, query1, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + var comparisonArray = body.entities; + comparisonArray.sort(function(a, b) { + return a.created + b.created; + }); + body.entities.should.equal(comparisonArray); + done(); + }); + }); + var query2 = "order by created asc"; + it('should return a subset of results ' + query2.replace('order', 'ordered'), function(done) { + entities.getWithQuery(config.genericTestCollection1, query2, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + var comparisonArray = body.entities; + comparisonArray.sort(function(a, b) { + return a.created - b.created; + }); + body.entities.should.equal(comparisonArray); + done(); + }); + }); + var query3 = "order by optionsProperty desc"; + it('should return a subset of results ' + query3.replace('order', 'ordered'), function(done) { + entities.getWithQuery(config.genericTestCollection1, query3, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + var comparisonArray = body.entities; + comparisonArray.sort(function(a, b) { + if (a.optionsProperty > b.optionsProperty) return -1; + if (a.optionsProperty < b.optionsProperty) return 1; + return 0; + }); + body.entities.should.equal(comparisonArray); + done(); + }); + }); + var query4 = "order by optionsProperty asc"; + it('should return a subset of results ' + query4.replace('order', 'ordered'), function(done) { + entities.getWithQuery(config.genericTestCollection1, query4, maxNumberOfEntities, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array); + var comparisonArray = body.entities; + comparisonArray.sort(function(a, b) { + if (a.optionsProperty < b.optionsProperty) return -1; + if (a.optionsProperty > b.optionsProperty) return 1; + return 0; + }); + done(); + }); + }); + }); + } +} diff --git a/stack/rest_integration_tests/test/setup.js b/stack/rest_integration_tests/test/setup.js new file mode 100644 index 0000000000..4fbc664391 --- /dev/null +++ b/stack/rest_integration_tests/test/setup.js @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// here we're going to do teardown of BaaS environment - deletion of users, entities, etc. +var users = require("../lib/users"); +var entities = require("../lib/entities"); +var config = require("../config"); +var async = require("async"); +var uuid = require("uuid"); +var should = require("should"); + +module.exports = { + users: [], + admins: [], + do: function(cb) { + console.log(" setup"); + async.parallel([ + function(cb) { + // create admin user + var id = uuid.v1().toString().replace("-", ""); + var admin = { + username: id + "user", + password: "pwd" + id, + name: id + " name", + email: id + "@uge2e.com" + } + users.add(admin, function(err, user) { + users.addToRole(user.username, "admin", function(err) { + module.exports.admins.push(admin); + cb(err, err ? null : admin); + }); + }); + }, + function(cb) { + // create app users + var size = config.numberOfUsers; + var userArr = []; + module.exports.users = userArr; + for (var i = 0; i < size; i++) { + var id = uuid.v1().toString().replace("-", ""); + userArr.push({ + username: id + "user", + password: "pwd" + id, + name: id + " name", + email: id + "@uge2e.com" + }); + } + async.each( + userArr, + function(user, cb) { + users.add(user, function(err, user) { + cb(err, user); + }); + }, + function(err, localUsers) { + cb(err); + } + ) + }, + function(cb) { + // create entities + async.parallel([ + function(cb) { + entities.create(config.genericTestCollection1, config.numberOfEntities, function(err, body) { + cb(err); + }); + }, + function(cb) { + entities.create(config.genericTestCollection2, config.numberOfEntities, function(err, body) { + cb(err); + }); + }, + function(cb) { + entities.create(config.consumableTestCollection, config.numberOfEntities, function(err, body) { + cb(err); + }); + } + ], + function(err, data) { + cb(err); + }); + } + ], + function(err, data) { + should(err).be.null; + console.log(" ✓".green + " done".grey); + if (cb && typeof(cb) === 'function') cb(err); + }); + } +} diff --git a/stack/rest_integration_tests/test/teardown.js b/stack/rest_integration_tests/test/teardown.js new file mode 100644 index 0000000000..7afdc974bc --- /dev/null +++ b/stack/rest_integration_tests/test/teardown.js @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var entities = require("../lib/entities"); +var should = require("should"); +var async = require("async"); +var config = require("../config"); +var inflect = require("i")(); + +module.exports = { + do: function(cb) { + console.log(" teardown"); + async.parallel([ + function(cb) { + entities.deleteAll(config.usersCollection, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(0); + body.count.should.equal(0); + cb(err); + }) + }, + function(cb) { + entities.deleteAll(config.genericTestCollection1, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(0); + body.count.should.equal(0); + cb(err); + }) + }, + function(cb) { + entities.deleteAll(config.genericTestCollection2, function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(0); + body.count.should.equal(0); + cb(err); + }) + }, + function(cb) { + entities.deleteAll(inflect.pluralize(config.consumableTestCollection), function(err, body) { + should(err).be.null; + body.entities.should.be.an.instanceOf(Array).and.have.lengthOf(0); + body.count.should.equal(0); + cb(err); + }) + } + ], + function(err, data) { + console.log(" ✓".green + " done".grey); + if (cb && typeof(cb) === 'function') cb(err); + }); + } +} diff --git a/stack/rest_integration_tests/test/users/create.js b/stack/rest_integration_tests/test/users/create.js new file mode 100644 index 0000000000..c62ccc4a9b --- /dev/null +++ b/stack/rest_integration_tests/test/users/create.js @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var should = require("should"); +var uuid = require("uuid"); +var users = require("../../lib/users"); + +module.exports = { + test: function() { + describe("create a user", function() { + var username = "testuser" + uuid.v1(); + var password = "password"; + it("should successfully return a user object", function(done) { + users.add({ + username: username, + password: password, + name: username + " name", + email: username + "@uge2e.com" + }, function(err, userBody) { + should(err).be.null; + userBody.should.not.be.null; + users.login(username, password, function(err, body) { + should(err).be.null; + body.should.not.be.null; + body.should.have.property("access_token"); + done(); + }) + }); + }); + }); + } +} From c315067b92d1b1fb946a9892c7ed2e3de13b1ce7 Mon Sep 17 00:00:00 2001 From: Shawn Feldman Date: Mon, 20 Jul 2015 14:40:09 -0600 Subject: [PATCH 2/2] rat file fix --- stack/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/stack/pom.xml b/stack/pom.xml index 2e357ab7ec..d7f279d5cc 100644 --- a/stack/pom.xml +++ b/stack/pom.xml @@ -1521,6 +1521,7 @@ **/*.json **/*.log **/*.md5 + **/*.opts **/.git/**