diff --git a/.gitignore b/.gitignore index e849603..596cc72 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ uploaded_files *~ ~* \#* +_scenarios diff --git a/index.js b/index.js index 0f9503f..7f9fe47 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,26 @@ "use strict"; const Promise = require("bluebird"); -var scenarios = require('auto-load')('scenarios') +const pre = require("./pre-test.js"); +var scenarios = require('auto-load')('scenarios'); -require("./pre-test.js")() -.then(() => { - // scenarios/[method]/[scenario (key)] - // e.g. scenarios/post/1.js +pre() +.then(function(){ return Promise.each( Object.keys(scenarios), (method) => { - for (var key in scenarios[method]) { - return scenarios[method][key]().then(() => console.log('→ scenario done')) + if(scenarios[method] instanceof Function){ + return scenarios[method](); + }else{ + return Promise.each(Object.keys(scenarios[method]), key => scenarios[method][key]()); } } - ) -}) -.then(() => { - console.log("Tests run complete. Exiting with status 0."); + ); +}).then(()=> { + console.log("\n\n\t✓ Success! Tests run complete. Exiting with status 0.\n\n"); process.exit(0); }) +.catch((err) => { + console.error(err); + console.log(err.stack); + console.log("\n\n\t✗ Tests failed. Exiting with status 1. See the above output for details.\n\n"); + process.exit(1); +}); diff --git a/package.json b/package.json index a1aec66..b1784c6 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,17 @@ }, "homepage": "https://github.com/sealcode/sealious-integration-tests#readme", "dependencies": { + "auto-load": "^2.1.0", "bluebird": "^3.4.6", "node-uuid": "^1.4.7", "request": "^2.74.0", "request-promise": "^4.1.1", - "sealious": "github:sealcode/sealious#alpha", + "sealious": "github:sealcode/sealious#default_config_delegation", "sealious-datastore-mongo": "sealcode/sealious-datastore-mongo#alpha", "sealious-www-server": "github:sealcode/sealious-www-server#alpha" + }, + "devDependencies": { + "cli-color": "^1.1.0", + "request-debug": "^0.2.0" } } diff --git a/pre-test.js b/pre-test.js index ff09dfe..0936cc9 100644 --- a/pre-test.js +++ b/pre-test.js @@ -14,12 +14,32 @@ module.exports = function(){ ] }); + App.createCollection({ + name: "without_required_values", + fields: [{ name: "number", type: "float" }] + }); + App.createCollection({ name: "empty", - fields: [ - {name: "number", type: "int"} - ] - }) + fields: [{ name: "number", type: "int" }] + }); - return App.start(); + App.createCollection({ + name: "restricted", + fields: [], + access_strategy: { + default: "logged_in" + } + }); + + App.Logger.error = () => {} + + return App.start() + .then(function(){ + const datastore = App.ChipManager.get_datastore_chip(); + return datastore.remove("users", {}); + //.then(() => datastore.remove("sessions", {})); + }).then(function(){ + return App; + }); }; diff --git a/scenarios/delete/1.js b/scenarios/delete/1.js new file mode 100644 index 0000000..86b8913 --- /dev/null +++ b/scenarios/delete/1.js @@ -0,0 +1,47 @@ +// scenario #1 +// TODO: Delete posted element from collection + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var prepared_body = { + name: "Some title", + description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit." + } + return rp.post({ + url: uri('collections/people'), + formData: prepared_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + var id = res.body.id + return rp.delete({ + url: uri(`collections/people/${id}`), + json: true, + resolveWithFullResponse: true + }) + } + }) + .then((res) => { + if (res.body === undefined) { + if (res.statusCode !== 204) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + // http://stackoverflow.com/a/2342589 + } else { + console.log("success!") + } + } else { + throw new Error(clc.red(`the response has body`)) + } + }) +}; diff --git a/scenarios/delete/2.js b/scenarios/delete/2.js new file mode 100644 index 0000000..19ef723 --- /dev/null +++ b/scenarios/delete/2.js @@ -0,0 +1,26 @@ +// scenario #2 +// TODO: Delete non-existing element from collection + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var id = Math.random() + return rp.delete({ + url: uri(`collections/people/${id}`), + json: true, + resolveWithFullResponse: true + }) + .catch((res) => { + if (res.statusCode !== 404) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + console.log("success!") + } + }) +}; diff --git a/scenarios/get/1.js b/scenarios/get/1.js index 42b7e62..49da059 100644 --- a/scenarios/get/1.js +++ b/scenarios/get/1.js @@ -7,23 +7,24 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #1') - return rp.get({ url: uri("collections/people/" + "_"), json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 404) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then((res) => { - if (res.body.type === "not_found") return true - else throw new Error('incorrect type of response') - }).then(() => { - console.log("succcess!"); - }); + }) + .then((res) => { + throw new Error(clc.red("Should have thrown a 404 error!")); + }) + .catch((res) => { + if(res.statusCode !== 404 || res.error.message.type !== "not_found"){ + throw new Error(clc.red("should have thrown a 404 not_found error")); + } + }) + + .then(() => console.log("succcess!")) }; diff --git a/scenarios/get/2.js b/scenarios/get/2.js index e6e05fb..15697d9 100644 --- a/scenarios/get/2.js +++ b/scenarios/get/2.js @@ -7,23 +7,28 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #2') - return rp.get({ url: uri("collections/peopl"), //`peopl` instead of `people` json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 404) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then((res) => { - if (res.body.type === "bad_subject") return true - else throw new Error('incorrect type of response') - }).then(() => { - console.log("succcess!"); - }); + }) + .then(() => { + throw new Error(clc.red("Should have thrown a 404 error!")); + }) + .catch((res) => { + if (res.statusCode === 404){ + if (res.error.message.type === "bad_subject"){ + return true; + } else { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)); + } + } + }) + + .then(() => console.log("succcess!")) }; diff --git a/scenarios/get/3.js b/scenarios/get/3.js index 60233c6..5b2f17e 100644 --- a/scenarios/get/3.js +++ b/scenarios/get/3.js @@ -7,23 +7,22 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #3') - return rp.get({ url: uri("collections/empty"), json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 200) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then((res) => { - if (res.body.length === 0) return true - else throw new Error('incorrect body') - }).then(() => { - console.log("succcess!"); - }); + }) + .then((res) => { + if (res.statusCode !== 200){ + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + if (res.body.length !== 0) throw new Error(clc.red('incorrect body')) + else console.log("success!") + } + }) }; diff --git a/scenarios/get/4.js b/scenarios/get/4.js new file mode 100644 index 0000000..9a744f0 --- /dev/null +++ b/scenarios/get/4.js @@ -0,0 +1,45 @@ +// scenario #4 +// TODO: Get all elements in accordance with query param + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var prepared_body = { + name: "Some title", + description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit." + } + return rp.post({ + url: uri('collections/people'), + formData: prepared_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + return rp.get({ + url: uri("collections/people?search=Lorem"), + json: true, + resolveWithFullResponse: true + }) + } + }) + .then((res) => { + if (res.body.length !== 0) { + if (res.body[0].description.original.search('Lorem') !== -1) { + console.log("success!") + } else { + throw new Error(clc.red(`the searched element don't fit to search keyword`)) + } + } else { + throw new Error(clc.red(`the body in response on search keyword 'Lorem' doesn't have search results`)) + } + }) +}; diff --git a/scenarios/get/5.js b/scenarios/get/5.js new file mode 100644 index 0000000..65dfe46 --- /dev/null +++ b/scenarios/get/5.js @@ -0,0 +1,26 @@ +// scenario #5 +// TODO: Get with formData from collection + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + return rp.get({ + url: uri("collections/people"), + data: {name: "Some title2"}, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + throw new Error(clc.red("Should have thrown a error which is related to a useable body in GET request")) + }) + .catch((res) => { + assert.equal(response.statusCode, 400); + console.log("succcess!") + }); +}; diff --git a/scenarios/login-with-incorrect-credentials.js b/scenarios/login-with-incorrect-credentials.js new file mode 100644 index 0000000..ff46c72 --- /dev/null +++ b/scenarios/login-with-incorrect-credentials.js @@ -0,0 +1,29 @@ +"use strict"; +var rp = require("request-promise"); +//require('request-debug')(rp); +var fs = require("fs"); +var assert = require("assert"); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function(){ + const user = {username: "user", password: "password"}; + const incorrect_user = {username: "u", password: "p"}; + + //register + return rp.post({ + url: uri("users"), + formData: user + }) + .then(() => { + return rp.post({ + url: uri("sessions"), + formData: incorrect_user + }) + }) + .catch((res) => { + assert.equal(res.statusCode, 401); + console.log("success!") + }) + +}; diff --git a/scenarios/login.js b/scenarios/login.js new file mode 100644 index 0000000..2c35be0 --- /dev/null +++ b/scenarios/login.js @@ -0,0 +1,44 @@ +"use strict"; +var rp = require("request-promise"); +//require('request-debug')(rp); +var fs = require("fs"); +var assert = require("assert"); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function(){ + const jar = rp.jar(); + const request = rp.defaults({jar: jar}); + + const user = {username: "user", password: "password"}; + + return request.post({ + url: uri("collections/restricted"), + }) + .catch((response) => { + assert.equal(response.statusCode, 401); + }) + .then(function(){ + //register + return request.post({ + url: uri("users"), + formData: user, + }); + }) + .then(function(){ + return request.post({ + url: uri("sessions"), + formData: user, + }); + }) + .then(function(){ + return request.get({ + url: uri("users/me"), + }); + }) + .then(function(){ + return request.post({ + url: uri("collections/restricted"), + }); + }); +}; diff --git a/scenarios/post/1.js b/scenarios/post/1.js index f193c68..16c14f9 100644 --- a/scenarios/post/1.js +++ b/scenarios/post/1.js @@ -8,12 +8,11 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #1') - var prepared_body = { name: "Element", age: 20, @@ -34,12 +33,16 @@ module.exports = function() { formData: prepared_body, json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 201) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then((res) => { - verify(res.body) - }).then(() => { + }) + .then((res) => { + console.log(res.statusCode) + if (res.statusCode !== 201){ + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + verify(res.body) + } + }) + .then(() => { console.log("succcess!"); }); }; diff --git a/scenarios/post/2.js b/scenarios/post/2.js index be98d54..6785a7b 100644 --- a/scenarios/post/2.js +++ b/scenarios/post/2.js @@ -8,12 +8,11 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #2') - var prepared_body = { age: 20, description: "Sealious proposes an application architecture that enables creating applications in a highly declarative way." @@ -25,10 +24,12 @@ module.exports = function() { formData: prepared_body, json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 400) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then(() => { - console.log("succcess!"); - }); + }) + .then((res) => { + if (res.statusCode !== 400){ + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + console.log("succcess!"); + } + }) }; diff --git a/scenarios/post/3.js b/scenarios/post/3.js index bb490e6..4ed199d 100644 --- a/scenarios/post/3.js +++ b/scenarios/post/3.js @@ -1,6 +1,6 @@ // scenario #3 -// TODO: Post new element without body -// - send empty object as formData / JSON-encoded +// TODO: Post new element without body (formData) +// - send empty object as formData // - check status // - check body @@ -8,25 +8,23 @@ var rp = require("request-promise"); var fs = require("fs"); var assert = require("assert"); +var clc = require('cli-color'); -var uri = (path) => "http://localhost:8080/api/v1/" + path; +var uri = (path) => "http://localhost:8081/api/v1/" + path; module.exports = function() { - console.log('scenario #3') - - prepared_body = {} return rp.post({ url: uri('collections/people'), formData: {}, json: true, resolveWithFullResponse: true - }).then((res) => { - if (res.statusCode === 400) return res - else throw new Error('incorrect status code, received ' + res.statusCode) - }).then((res) => { - console.log(res.body) - // "error":"Bad Request","message":"Invalid multipart payload format" - }).then((res) => { - console.log("succcess!"); - }); + }) + .then((res) => { + if (res.statusCode !== 400){ + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + if (res.body.error !== "Bad Request") throw new Error(clc.red('incorrect type of response, received ' + res.body.error)) + else console.log("succcess!"); + } + }) }; diff --git a/scenarios/post/4.js b/scenarios/post/4.js new file mode 100644 index 0000000..5394044 --- /dev/null +++ b/scenarios/post/4.js @@ -0,0 +1,26 @@ +// scenario #4 +// TODO: Post new element without some fields (check non-existent fields) + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var prepared_body = { + name: "Some title" + } + return rp.post({ + url: uri('collections/people'), + formData: prepared_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.body.age !== undefined) throw new Error(clc.red(`the body contains fields with 'undefined' value, which were not added`)) + else console.log("success!") + }) +}; diff --git a/scenarios/post/5.js b/scenarios/post/5.js new file mode 100644 index 0000000..a7a207a --- /dev/null +++ b/scenarios/post/5.js @@ -0,0 +1,31 @@ +// scenario #5 +// TODO: Post new element without fields to collection without requried values +// - send empty object as json data + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + return rp.post({ + url: uri('collections/without_required_values'), + data: {}, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201){ + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + if (Object.keys(res.body.body).length !== 0) { + throw new Error(clc.red('the body has unforeseen properties')) + } else { + console.log("success!") + } + } + }) +}; diff --git a/scenarios/post/6.js b/scenarios/post/6.js new file mode 100644 index 0000000..f1252c7 --- /dev/null +++ b/scenarios/post/6.js @@ -0,0 +1,27 @@ +// scenario #6 +// TODO: Post new element with fields which aren't declared in definition of collection + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); + +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var prepared_body = { + foo: 20, + bar: "Sealious proposes an application architecture that enables creating applications in a highly declarative way." + } + return rp.post({ + url: uri('collections/people'), + formData: prepared_body, + json: true, + resolveWithFullResponse: true + }) + .catch((response) => { + assert.equal(response.statusCode, 403); + console.log("success!") + }) +}; diff --git a/scenarios/put/1.js b/scenarios/put/1.js new file mode 100644 index 0000000..f16b2e2 --- /dev/null +++ b/scenarios/put/1.js @@ -0,0 +1,52 @@ +// scenario #1 +// TODO: Update element of collection by PUT method +// the updated element should has integrally new body + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var initial_body = {name: "Title-1", age: 21} + var updated_body = {name: "Title-2"} + + var verify = function(res){ + var a = assert.equal(res.body.age, undefined); + assert.deepEqual(res.body.name,{ + original: updated_body.name, + safe: updated_body.name + }); + } + + return rp.post({ + url: uri('collections/people'), + formData: initial_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + var id = res.body.id; + return rp.put({ + url: uri(`collections/people/${id}`), + formData: updated_body, + json: true, + resolveWithFullResponse: true + }) + } + }) + .then((res) => { + if (res.body.created_context.timestamp !== res.body.last_modified_context.timestamp) { + if (res.statusCode !== 200) throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + else verify(res.body) + } else { + throw new Error(clc.red(`the timestamps aren't different`)) + } + }) + .then(() => console.log("succcess!")); +}; diff --git a/scenarios/put/2.js b/scenarios/put/2.js new file mode 100644 index 0000000..3589a10 --- /dev/null +++ b/scenarios/put/2.js @@ -0,0 +1,41 @@ +// scenario #2 +// TODO: Update element of collection by PUT method with incorrect fields + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var initial_body = {name: "Title-1", age: 21} + var updated_body = {name: "Title-2", incorrect_value: 23} + + return rp.post({ + url: uri('collections/people'), + formData: initial_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + var id = res.body.id; + return rp.put({ + url: uri(`collections/people/${id}`), + formData: updated_body, + json: true, + resolveWithFullResponse: true + }) + } + }) + .then((res) => { + throw new Error(clc.red("Should have thrown a error which is related to incorrect status code")) + }) + .catch((res) => { + if (res.statusCode !== 403) throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + }) + .then(() => console.log("succcess!")); +}; diff --git a/scenarios/put/3.js b/scenarios/put/3.js new file mode 100644 index 0000000..a5062e6 --- /dev/null +++ b/scenarios/put/3.js @@ -0,0 +1,41 @@ +// scenario #3 +// TODO: Update element of collection by PUT method without required field + +"use strict"; +var rp = require("request-promise"); +var fs = require("fs"); +var assert = require("assert"); +var clc = require('cli-color'); +var uri = (path) => "http://localhost:8081/api/v1/" + path; + +module.exports = function() { + var initial_body = {name: "Title-1", age: 21} + var updated_body = {age: 23} + + return rp.post({ + url: uri('collections/people'), + formData: initial_body, + json: true, + resolveWithFullResponse: true + }) + .then((res) => { + if (res.statusCode !== 201) { + throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + } else { + var id = res.body.id; + return rp.put({ + url: uri(`collections/people/${id}`), + formData: updated_body, + json: true, + resolveWithFullResponse: true + }) + } + }) + .then((res) => { + throw new Error(clc.red("Should have thrown a error which is related to incorrect status code")) + }) + .catch((res) => { + if (res.statusCode !== 403) throw new Error(clc.red('incorrect status code, received ' + res.statusCode)) + }) + .then(() => console.log("succcess!")); +};