├── .gitignore ├── .jshintrc ├── .travis.yml ├── CONTRIBUTING.md ├── DCO.md ├── LICENSE.md ├── README.md ├── examples ├── bulk_transform.js ├── express.js ├── lazy_creation_of_views.js ├── lazy_db_creation_and_replication.js ├── pipe.js └── readme.md ├── lib ├── logger.js └── nano.js ├── package.json └── tests ├── fixtures ├── attachment │ ├── destroy.json │ ├── get.json │ ├── insert.json │ ├── pipe.json │ └── update.json ├── cfg.json ├── database │ ├── changes.json │ ├── compact.json │ ├── create-and-destroy.json │ ├── follow.json │ ├── get.json │ ├── list.json │ └── replicate.json ├── design │ ├── atomic.json │ ├── compact.json │ ├── list.json │ ├── multiple.json │ ├── query.json │ ├── search.json │ └── show.json ├── document │ ├── bulk.json │ ├── copy.json │ ├── destroy.json │ ├── fetch.json │ ├── fetch_revs.json │ ├── get.json │ ├── head.json │ ├── insert.json │ ├── list.json │ └── update.json ├── logo.png ├── multipart │ ├── get.json │ └── insert.json └── shared │ ├── config.json │ ├── cookie.json │ ├── error.json │ ├── headers.json │ ├── log.json │ ├── nano.json │ └── updates.json ├── helpers ├── index.js ├── integration.js └── unit.js ├── integration ├── attachment │ ├── destroy.js │ ├── get.js │ ├── insert.js │ ├── pipe.js │ └── update.js ├── database │ ├── changes.js │ ├── compact.js │ ├── create-and-destroy.js │ ├── follow.js │ ├── get.js │ ├── list.js │ └── replicate.js ├── design │ ├── atomic.js │ ├── compact.js │ ├── list.js │ ├── multiple.js │ ├── query.js │ ├── search.js │ └── show.js ├── document │ ├── bulk.js │ ├── copy.js │ ├── destroy.js │ ├── fetch.js │ ├── fetch_revs.js │ ├── get.js │ ├── head.js │ ├── insert.js │ ├── list.js │ └── update.js ├── multipart │ ├── get.js │ └── insert.js └── shared │ ├── config.js │ ├── cookie.js │ ├── error.js │ ├── headers.js │ ├── log.js │ ├── nano.js │ └── updates.js └── unit ├── attachment ├── destroy.js ├── get.js └── insert.js ├── database ├── changes.js ├── compact.js ├── create.js ├── destroy.js ├── follow.js ├── get.js ├── list.js ├── replicate.js └── updates.js ├── design ├── atomic.js ├── compact.js ├── list.js ├── search.js ├── show.js ├── spatial.js └── view.js ├── document ├── bulk.js └── copy.js ├── multipart ├── get.js └── insert.js └── shared ├── error.js ├── follow-updates.js └── jar.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *tmp.* 3 | *.log 4 | node_modules/ 5 | coverage/ 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "node": true, 4 | "strict": true, 5 | "smarttabs": true, 6 | "maxlen": 80, 7 | "newcap": false, 8 | "undef": true, 9 | "unused": true, 10 | "onecase": true, 11 | "indent": 2, 12 | "sub": true 13 | } 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: "node_js" 2 | env: DEBUG=* 3 | branches: 4 | only: 5 | - master 6 | - next 7 | - rewrite 8 | node_js: 9 | - "0.8" 10 | - "0.10" 11 | - "0.11" 12 | - "0.12" 13 | - "iojs" 14 | - "4.2" 15 | - "node" 16 | services: 17 | - couchdb 18 | os: 19 | - linux 20 | before_install: 21 | - npm update -g npm 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # DCO 2 | 3 | To contribute to this project you must accept our [developer certificate of origin](https://github.com/dscape/nano/blob/master/README.md) 4 | 5 | # Contributing 6 | 7 | Everyone is welcome to contribute with patches, bug-fixes and new features 8 | 9 | 1. Create an [issue][2] on github so the community can comment on your idea 10 | 2. Fork `nano` in github 11 | 3. Create a new branch `git checkout -b my_branch` 12 | 4. Create tests for the changes you made 13 | 5. Make sure you pass both existing and newly inserted tests 14 | 6. Commit your changes 15 | 7. Push to your branch `git push origin my_branch` 16 | 8. Create a pull request 17 | 18 | to run tests make sure you npm test but also run tests without mocks: 19 | 20 | ``` sh 21 | npm run unmocked 22 | npm run mocked 23 | npm test 24 | ``` 25 | 26 | Please fix all issues identified in the pre-commit hooks before sending your patch. if you don't, we will close the patch and ask you to re-open it once you have: 27 | 28 | 1. 100% code coverage 29 | 2. proper codestyle 30 | 3. linted all your code 31 | 32 | This is not a replacement for appropriate tests, please make sure that you have adequate coverage and thoroughly test the code you introduced. 33 | 34 | You can add verbose debug messages while running tests by doing: 35 | 36 | ``` 37 | DEBUG=* node your_nano_scripts.js 38 | ``` 39 | 40 | You can turn nocks on and off using the `NOCK_OFF` environment variable. 41 | 42 | [2]: http://github.com/dscape/nano/issues 43 | -------------------------------------------------------------------------------- /DCO.md: -------------------------------------------------------------------------------- 1 | # Developer's Certificate of Origin 1.1 2 | 3 | By making a contribution to this project, I certify that: 4 | 5 | (a) The contribution was created in whole or in part by me and I 6 | have the right to submit it under the open source license 7 | indicated in the file; or 8 | 9 | (b) The contribution is based upon previous work that, to the best 10 | of my knowledge, is covered under an appropriate open source 11 | license and I have the right under that license to submit that 12 | work with modifications, whether created in whole or in part 13 | by me, under the same open source license (unless I am 14 | permitted to submit under a different license), as indicated 15 | in the file; or 16 | 17 | (c) The contribution was provided directly to me by some other 18 | person who certified (a), (b) or (c) and I have not modified 19 | it. 20 | 21 | (d) I understand and agree that this project and the contribution 22 | are public and that a record of the contribution (including all 23 | personal information I submit with it, including my sign-off) is 24 | maintained indefinitely and may be redistributed consistent with 25 | this project or the open source license(s) involved. 26 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The Apache License, version 2.0 2 | 3 | copyright 2014 nuno job (oO)--',-- 4 | 5 | licensed under the apache license, version 2.0 (the "license"); 6 | you may not use this file except in compliance with the license. 7 | you may obtain a copy of the license at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | unless required by applicable law or agreed to in writing, software 12 | distributed under the license is distributed on an "as is" basis, 13 | without warranties or conditions of any kind, either express or implied. 14 | see the license for the specific language governing permissions and 15 | limitations under the license. 16 | -------------------------------------------------------------------------------- /examples/bulk_transform.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | var db = require('nano')('http://localhost:5984/emails') 14 | , async = require('async') 15 | ; 16 | 17 | function update_row(row,cb) { 18 | var doc = row.doc; 19 | delete doc.subject; 20 | db.insert(doc, doc._id, function (err, data) { 21 | if(err) { console.log('err at ' + doc._id); cb(err); } 22 | else { console.log('updated ' + doc._id); cb(); } 23 | }); 24 | } 25 | 26 | function list(offset) { 27 | var ended = false; 28 | offset = offset || 0; 29 | db.list({include_docs: true, limit: 10, skip: offset}, 30 | function(err, data) { 31 | var total, offset, rows; 32 | if(err) { console.log('fuuuu: ' + err.message); rows = []; return; } 33 | total = data.total_rows; 34 | offset = data.offset; 35 | rows = data.rows; 36 | if(offset === total) { 37 | ended = true; 38 | return; 39 | } 40 | async.forEach(rows, update_row, function (err) { 41 | if(err) { console.log('something failed, check logs'); } 42 | if(ended) { return; } 43 | list(offset+10); 44 | }); 45 | }); 46 | } 47 | 48 | list(); -------------------------------------------------------------------------------- /examples/express.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | var express = require('express') 14 | , db = require('nano')('http://localhost:5984/my_couch') 15 | , app = module.exports = express() 16 | ; 17 | 18 | app.get('/', function(req, res) { 19 | db.get('foo', function (error, body, headers) { 20 | if(error) { 21 | res.status(error.statusCode); 22 | return res.send(error.message); 23 | } 24 | res.status(200); 25 | res.send(body); 26 | }); 27 | }); 28 | 29 | app.listen(3333); 30 | console.log('server is running. check expressjs.com for more cool tricks'); 31 | -------------------------------------------------------------------------------- /examples/lazy_creation_of_views.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | module.exports = function() { 14 | var nano = require('nano')('http://localhost:5984') 15 | , users = nano.use('users') 16 | , VIEWS = { by_twitter_id: 17 | { "map": "function(doc) { emit(doc.twitter.screen_name, doc); }" } } 18 | ; 19 | 20 | /***************************************************************************** 21 | * user.get() 22 | ****************************************************************************/ 23 | function user_get(id, callback){ 24 | return users.get(id, callback); 25 | } 26 | 27 | /***************************************************************************** 28 | * user.new() 29 | ****************************************************************************/ 30 | function user_new(id, body, callback) { 31 | return users.insert(body, id, callback); 32 | } 33 | 34 | /***************************************************************************** 35 | * user.create() 36 | ****************************************************************************/ 37 | function create_users_database(email_address,secret,name,retries) { 38 | nano.db.create('users', function (e,b,h) { 39 | user_create(email_address,secret,name,retries+1); 40 | }); 41 | } 42 | 43 | function user_create(email_address,secret,name,retries) { 44 | if (!retries) { 45 | retries = 0; 46 | } 47 | users.insert( {email_address: email_address, secret: secret, name: name}, secret, 48 | function (e,b,h) { 49 | if(e && e.message === 'no_db_file' && retries < 1) { 50 | return create_users_database(email_address,secret,name,retries); 51 | } 52 | (function() { return ; })(e,b,h); 53 | }); 54 | } 55 | 56 | /***************************************************************************** 57 | * user.find() 58 | ****************************************************************************/ 59 | // 60 | // some more logic needed 61 | // what if design document exists but view doesnt, we cant just overwrite it 62 | // 63 | // we need a way to fectch and build on 64 | // and thats the reason why im not doing this at 5am 65 | 66 | function user_find(view, id, opts, tried, callback) { 67 | if(typeof tried === 'function') { 68 | callback = tried; 69 | tried = {tried:0, max_retries:2}; 70 | } 71 | users.view('users', view, opts, function (e,b,h) { 72 | if(e) { 73 | var current_view = VIEWS[view]; 74 | if(!current_view) { 75 | e.message = 'View is not available'; 76 | return callback(e,b,h); 77 | } 78 | if(tried.tried < tried.max_retries) { 79 | if(e.message === 'missing' || e.message === 'deleted') { // create design document 80 | var design_doc = {views: {}}; 81 | design_doc.views[view] = current_view; 82 | return users.insert(design_doc, '_design/users', function () { 83 | tried.tried += 1; 84 | user_find(view,id,opts,tried,callback); 85 | }); 86 | } 87 | if(e.message === 'missing_named_view') { 88 | users.get('_design/users', function (e,b,h) { // create view 89 | tried.tried += 1; 90 | if(e) { return user_find(view,id,opts,tried,callback); } 91 | b.views[view] = current_view; 92 | users.insert(b, '_design/users', function (e,b,h) { 93 | return user_find(view,id,opts,tried,callback); 94 | }); 95 | }); 96 | return; 97 | } 98 | } 99 | else { return callback(e,b,h); } 100 | } 101 | return callback(null,b,h); 102 | }); 103 | } 104 | 105 | function user_first(view, id, callback) { 106 | return user_find(view, id, {startkey: ('"' + id + '"'), limit: 1}, callback); 107 | } 108 | 109 | return { new: user_new 110 | , get: user_get 111 | , create: user_create 112 | , first: user_first 113 | }; 114 | }; -------------------------------------------------------------------------------- /examples/lazy_db_creation_and_replication.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | var nano = require('nano') 14 | , couch = 15 | { "master" : "http://localhost:5984/landing_m" 16 | , "replica" : "http://localhost:5984/landing_r" 17 | } 18 | ; 19 | 20 | function insert_with_retry(db, email, retries, callback) { 21 | if (typeof retries === 'function') { 22 | callback = retries; 23 | retries = 0; 24 | } 25 | callback = callback || function(){}; 26 | db.insert(email, function(err, resp, head) { 27 | if(err) { 28 | if(err.message === 'no_db_file' && retries < 1) { 29 | var db_name = db.config.db 30 | , server = nano(db.config.url) 31 | ; 32 | server.db.create(db_name, function (err2,resp2,head2) { 33 | if(err2) { return callback(err2,resp2,head2); } 34 | insert_with_retry(db,email,retries+1,callback); 35 | }); 36 | } else { return callback(err,resp,head); } 37 | } 38 | callback(err, resp, head); 39 | }); 40 | } 41 | 42 | function replicate_with_retry(master_uri, replica_uri, retries, callback) { 43 | if (typeof retries === 'function') { 44 | callback = retries; 45 | retries = 0; 46 | } 47 | callback = callback || function(){}; 48 | retries = retries || 0; 49 | var master = nano(couch.master); 50 | master.replicate(couch.replica, function(err, resp, head) { 51 | if(err && err['error'] === 'db_not_found' && retries < 1) { 52 | var replica = nano(couch.replica) 53 | , db_name = replica.config.db 54 | , server = nano(replica.config.url) 55 | ; 56 | server.db.create(db_name, function (err2, resp2, head2) { 57 | if(err2) { return callback(err2,resp2,head2); } 58 | replicate_with_retry(master_uri, replica_uri, retries+1, callback); 59 | }); 60 | } 61 | callback(err, resp, head); 62 | }); 63 | } 64 | 65 | module.exports = {insert: insert_with_retry, replicate: replicate_with_retry}; -------------------------------------------------------------------------------- /examples/pipe.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | var express = require('express') 14 | , nano = require('nano')('http://localhost:5984') 15 | , app = module.exports = express.createServer() 16 | , db_name = "test" 17 | , db = nano.use(db_name); 18 | 19 | app.get("/", function(request,response) { 20 | db.attachment.get("new", "logo.png").pipe(response); 21 | }); 22 | 23 | app.listen(3333); -------------------------------------------------------------------------------- /examples/readme.md: -------------------------------------------------------------------------------- 1 | # samples 2 | 3 | if you have a sample please feel free to send a pull request. 4 | 5 | also the tests are very concise and helpful. 6 | 7 | i would recommend taking a peek. -------------------------------------------------------------------------------- /lib/logger.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var debug = require('debug')('nano/logger'); 16 | 17 | module.exports = function logging(cfg) { 18 | var log = cfg && cfg.log; 19 | var logStrategy = typeof log === 'function' ? log : debug; 20 | 21 | return function logEvent(prefix) { 22 | var eventId = (prefix ? prefix + '-' : '') + 23 | (~~(Math.random() * 1e9)).toString(36); 24 | return function log() { 25 | logStrategy.call(this, eventId, [].slice.call(arguments, 0)); 26 | }; 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /lib/nano.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var u = require('url'); 16 | var assert = require('assert'); 17 | var querystring = require('querystring'); 18 | var request = require('request'); 19 | var errs = require('errs'); 20 | var _ = require('underscore'); 21 | var follow = require('follow'); 22 | var logger = require('./logger'); 23 | 24 | var nano; 25 | 26 | module.exports = exports = nano = function dbScope(cfg) { 27 | var serverScope = {}; 28 | 29 | if (typeof cfg === 'string') { 30 | cfg = {url: cfg}; 31 | } 32 | 33 | assert.equal(typeof cfg, 'object', 34 | 'You must specify the endpoint url when invoking this module'); 35 | assert.ok(/^https?:/.test(cfg.url), 'url is not valid'); 36 | 37 | cfg = _.clone(cfg); 38 | 39 | serverScope.config = cfg; 40 | cfg.requestDefaults = cfg.requestDefaults || {jar: false}; 41 | 42 | var httpAgent = (typeof cfg.request === 'function') ? cfg.request : 43 | request.defaults(cfg.requestDefaults); 44 | var followAgent = (typeof cfg.follow === 'function') ? cfg.follow : follow; 45 | var log = typeof cfg.log === 'function' ? cfg.log : logger(cfg); 46 | var parseUrl = 'parseUrl' in cfg ? cfg.parseUrl : true; 47 | 48 | function maybeExtractDatabaseComponent() { 49 | if (!parseUrl) { 50 | return; 51 | } 52 | 53 | var path = u.parse(cfg.url); 54 | var pathArray = path.pathname.split('/').filter(function(e) { return e; }); 55 | var db = pathArray.pop(); 56 | var rootPath = path.pathname.replace(/\/?$/, '/..'); 57 | 58 | if (db) { 59 | cfg.url = urlResolveFix(cfg.url, rootPath).replace(/\/?$/, ''); 60 | return db; 61 | } 62 | } 63 | 64 | function scrub(str) { 65 | if (str) { 66 | str = str.replace(/\/\/(.*)@/,"//XXXXXX:XXXXXX@"); 67 | } 68 | return str; 69 | } 70 | 71 | function relax(opts, callback) { 72 | if (typeof opts === 'function') { 73 | callback = opts; 74 | opts = {path: ''}; 75 | } 76 | 77 | if (typeof opts === 'string') { 78 | opts = {path: opts}; 79 | } 80 | 81 | if (!opts) { 82 | opts = {path: ''}; 83 | callback = null; 84 | } 85 | 86 | var qs = _.extend({}, opts.qs); 87 | 88 | var headers = { 89 | 'content-type': 'application/json', 90 | accept: 'application/json' 91 | }; 92 | 93 | var req = { 94 | method: (opts.method || 'GET'), 95 | headers: headers, 96 | uri: cfg.url 97 | }; 98 | 99 | var parsed; 100 | var rh; 101 | 102 | // https://github.com/mikeal/request#requestjar 103 | var isJar = opts.jar || cfg.jar; 104 | 105 | if (isJar) { 106 | req.jar = isJar; 107 | } 108 | 109 | // http://wiki.apache.org/couchdb/HTTP_database_API#Naming_and_Addressing 110 | if (opts.db) { 111 | req.uri = urlResolveFix(req.uri, encodeURIComponent(opts.db)); 112 | } 113 | 114 | if (opts.multipart) { 115 | req.multipart = opts.multipart; 116 | } 117 | 118 | req.headers = _.extend(req.headers, opts.headers, cfg.defaultHeaders); 119 | 120 | if (opts.path) { 121 | req.uri += '/' + opts.path; 122 | } else if (opts.doc) { 123 | if (!/^_design/.test(opts.doc)) { 124 | // http://wiki.apache.org/couchdb/HTTP_Document_API#Naming.2FAddressing 125 | req.uri += '/' + encodeURIComponent(opts.doc); 126 | } else { 127 | // http://wiki.apache.org/couchdb/HTTP_Document_API#Document_IDs 128 | req.uri += '/' + opts.doc; 129 | } 130 | 131 | // http://wiki.apache.org/couchdb/HTTP_Document_API#Attachments 132 | if (opts.att) { 133 | req.uri += '/' + opts.att; 134 | } 135 | } 136 | 137 | // prevent bugs where people set encoding when piping 138 | if (opts.encoding !== undefined && callback) { 139 | req.encoding = opts.encoding; 140 | delete req.headers['content-type']; 141 | delete req.headers.accept; 142 | } 143 | 144 | if (opts.contentType) { 145 | req.headers['content-type'] = opts.contentType; 146 | delete req.headers.accept; 147 | } 148 | 149 | // http://guide.couchdb.org/draft/security.html#cookies 150 | if (cfg.cookie) { 151 | req.headers['X-CouchDB-WWW-Authenticate'] = 'Cookie'; 152 | req.headers.cookie = cfg.cookie; 153 | } 154 | 155 | // http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options 156 | if (typeof opts.qs === 'object' && !_.isEmpty(opts.qs)) { 157 | ['startkey', 'endkey', 'key', 'keys'].forEach(function(key) { 158 | if (key in opts.qs) { 159 | qs[key] = JSON.stringify(opts.qs[key]); 160 | } 161 | }); 162 | req.qs = qs; 163 | } 164 | 165 | if (opts.body) { 166 | if (Buffer.isBuffer(opts.body) || opts.dontStringify) { 167 | req.body = opts.body; 168 | } else { 169 | req.body = JSON.stringify(opts.body, function(key, value) { 170 | // don't encode functions 171 | if (typeof(value) === 'function') { 172 | return value.toString(); 173 | } else { 174 | return value; 175 | } 176 | }); 177 | } 178 | } 179 | 180 | if (opts.form) { 181 | req.headers['content-type'] = 182 | 'application/x-www-form-urlencoded; charset=utf-8'; 183 | req.body = querystring.stringify(opts.form).toString('utf8'); 184 | } 185 | 186 | log(req); 187 | 188 | if (!callback) { 189 | return httpAgent(req); 190 | } 191 | 192 | return httpAgent(req, function(e, h, b) { 193 | rh = h && h.headers || {}; 194 | rh.statusCode = h && h.statusCode || 500; 195 | rh.uri = req.uri; 196 | 197 | if (e) { 198 | log({err: 'socket', body: b, headers: rh}); 199 | return callback(errs.merge(e, { 200 | message: 'error happened in your connection', 201 | scope: 'socket', 202 | errid: 'request' 203 | })); 204 | } 205 | 206 | delete rh.server; 207 | delete rh['content-length']; 208 | 209 | if (opts.dontParse) { 210 | parsed = b; 211 | } else { 212 | try { parsed = JSON.parse(b); } catch (err) { parsed = b; } 213 | } 214 | 215 | if (rh.statusCode >= 200 && rh.statusCode < 400) { 216 | log({err: null, body: parsed, headers: rh}); 217 | return callback(null, parsed, rh); 218 | } 219 | 220 | log({err: 'couch', body: parsed, headers: rh}); 221 | 222 | // cloudant stacktrace 223 | if (typeof parsed === 'string') { 224 | parsed = {message: parsed}; 225 | } 226 | 227 | if (!parsed.message && (parsed.reason || parsed.error)) { 228 | parsed.message = (parsed.reason || parsed.error); 229 | } 230 | 231 | // fix cloudant issues where they give an erlang stacktrace as js 232 | delete parsed.stack; 233 | 234 | // scrub credentials 235 | req.uri = scrub(req.uri); 236 | rh.uri = scrub(rh.uri); 237 | if (req.headers.cookie) { 238 | req.headers.cookie = "XXXXXXX"; 239 | } 240 | 241 | callback(errs.merge({ 242 | message: 'couch returned ' + rh.statusCode, 243 | scope: 'couch', 244 | statusCode: rh.statusCode, 245 | request: req, 246 | headers: rh, 247 | errid: 'non_200' 248 | }, errs.create(parsed))); 249 | }); 250 | } 251 | 252 | // http://docs.couchdb.org/en/latest/api/server/authn.html#cookie-authentication 253 | function auth(username, password, callback) { 254 | return relax({ 255 | method: 'POST', 256 | db: '_session', 257 | form: { 258 | name: username, 259 | password: password 260 | } 261 | }, callback); 262 | } 263 | 264 | // http://docs.couchdb.org/en/latest/api/server/authn.html#post--_session 265 | function session(callback) { 266 | return relax({db: '_session'}, callback); 267 | } 268 | 269 | // http://docs.couchdb.org/en/latest/api/server/common.html#get--_db_updates 270 | function updates(qs, callback) { 271 | if (typeof qs === 'function') { 272 | callback = qs; 273 | qs = {}; 274 | } 275 | return relax({ 276 | db: '_db_updates', 277 | qs: qs 278 | }, callback); 279 | } 280 | 281 | function followUpdates(qs, callback) { 282 | return followDb('_db_updates', qs, callback); 283 | } 284 | 285 | // http://docs.couchdb.org/en/latest/api/database/common.html#put--db 286 | function createDb(dbName, callback) { 287 | return relax({db: dbName, method: 'PUT'}, callback); 288 | } 289 | 290 | // http://docs.couchdb.org/en/latest/api/database/common.html#delete--db 291 | function destroyDb(dbName, callback) { 292 | return relax({db: dbName, method: 'DELETE'}, callback); 293 | } 294 | 295 | // http://docs.couchdb.org/en/latest/api/database/common.html#get--db 296 | function getDb(dbName, callback) { 297 | return relax({db: dbName}, callback); 298 | } 299 | 300 | // http://docs.couchdb.org/en/latest/api/server/common.html#get--_all_dbs 301 | function listDbs(callback) { 302 | return relax({db: '_all_dbs'}, callback); 303 | } 304 | 305 | // http://docs.couchdb.org/en/latest/api/database/compact.html#post--db-_compact 306 | function compactDb(dbName, ddoc, callback) { 307 | if (typeof ddoc === 'function') { 308 | callback = ddoc; 309 | ddoc = null; 310 | } 311 | return relax({ 312 | db: dbName, 313 | doc: '_compact', 314 | att: ddoc, 315 | method: 'POST' 316 | }, callback); 317 | } 318 | 319 | // http://docs.couchdb.org/en/latest/api/database/changes.html#get--db-_changes 320 | function changesDb(dbName, qs, callback) { 321 | if (typeof qs === 'function') { 322 | callback = qs; 323 | qs = {}; 324 | } 325 | return relax({db: dbName, path: '_changes', qs: qs}, callback); 326 | } 327 | 328 | function followDb(dbName, qs, callback) { 329 | if (typeof qs === 'function') { 330 | callback = qs; 331 | qs = {}; 332 | } 333 | 334 | qs.db = urlResolveFix(cfg.url, encodeURIComponent(dbName)); 335 | 336 | if (typeof callback === 'function') { 337 | return followAgent(qs, callback); 338 | } else { 339 | return new followAgent.Feed(qs); 340 | } 341 | } 342 | 343 | function _serializeAsUrl(db) { 344 | if (typeof db === 'object' && db.config && db.config.url && db.config.db) { 345 | return urlResolveFix(db.config.url, encodeURIComponent(db.config.db)); 346 | } else { 347 | return db; 348 | } 349 | } 350 | 351 | // http://docs.couchdb.org/en/latest/api/server/common.html#post--_replicate 352 | function replicateDb(source, target, opts, callback) { 353 | if (typeof opts === 'function') { 354 | callback = opts; 355 | opts = {}; 356 | } 357 | 358 | opts.source = _serializeAsUrl(source); 359 | opts.target = _serializeAsUrl(target); 360 | 361 | return relax({db: '_replicate', body: opts, method: 'POST'}, callback); 362 | } 363 | 364 | function docModule(dbName) { 365 | var docScope = {}; 366 | dbName = decodeURIComponent(dbName); 367 | 368 | // http://docs.couchdb.org/en/latest/api/document/common.html#put--db-docid 369 | // http://docs.couchdb.org/en/latest/api/database/common.html#post--db 370 | function insertDoc(doc, qs, callback) { 371 | var opts = {db: dbName, body: doc, method: 'POST'}; 372 | 373 | if (typeof qs === 'function') { 374 | callback = qs; 375 | qs = {}; 376 | } 377 | 378 | if (typeof qs === 'string') { 379 | qs = {docName: qs}; 380 | } 381 | 382 | if (qs) { 383 | if (qs.docName) { 384 | opts.doc = qs.docName; 385 | opts.method = 'PUT'; 386 | delete qs.docName; 387 | } 388 | opts.qs = qs; 389 | } 390 | 391 | return relax(opts, callback); 392 | } 393 | 394 | // http://docs.couchdb.org/en/latest/api/document/common.html#delete--db-docid 395 | function destroyDoc(docName, rev, callback) { 396 | if(!docName) { 397 | if(callback) 398 | callback("Invalid doc id", null); 399 | } 400 | else { 401 | return relax({ 402 | db: dbName, 403 | doc: docName, 404 | method: 'DELETE', 405 | qs: {rev: rev} 406 | }, callback); 407 | } 408 | } 409 | 410 | // http://docs.couchdb.org/en/latest/api/document/common.html#get--db-docid 411 | function getDoc(docName, qs, callback) { 412 | if (typeof qs === 'function') { 413 | callback = qs; 414 | qs = {}; 415 | } 416 | 417 | return relax({db: dbName, doc: docName, qs: qs}, callback); 418 | } 419 | 420 | // http://docs.couchdb.org/en/latest/api/document/common.html#head--db-docid 421 | function headDoc(docName, callback) { 422 | return relax({ 423 | db: dbName, 424 | doc: docName, 425 | method: 'HEAD', 426 | qs: {} 427 | }, callback); 428 | } 429 | 430 | // http://docs.couchdb.org/en/latest/api/document/common.html#copy--db-docid 431 | function copyDoc(docSrc, docDest, opts, callback) { 432 | if (typeof opts === 'function') { 433 | callback = opts; 434 | opts = {}; 435 | } 436 | 437 | var qs = { 438 | db: dbName, 439 | doc: docSrc, 440 | method: 'COPY', 441 | headers: {'Destination': docDest} 442 | }; 443 | 444 | if (opts.overwrite) { 445 | return headDoc(docDest, function(e, b, h) { 446 | if (e && e.statusCode !== 404) { 447 | return callback(e); 448 | } 449 | qs.headers.Destination += '?rev=' + 450 | h.etag.substring(1, h.etag.length - 1); 451 | return relax(qs, callback); 452 | }); 453 | } else { 454 | return relax(qs, callback); 455 | } 456 | } 457 | 458 | // http://docs.couchdb.org/en/latest/api/database/bulk-api.html#get--db-_all_docs 459 | function listDoc(qs, callback) { 460 | if (typeof qs === 'function') { 461 | callback = qs; 462 | qs = {}; 463 | } 464 | 465 | return relax({db: dbName, path: '_all_docs', qs: qs}, callback); 466 | } 467 | 468 | // http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs 469 | function fetchDocs(docNames, qs, callback) { 470 | if (typeof qs === 'function') { 471 | callback = qs; 472 | qs = {}; 473 | } 474 | 475 | qs = qs || {}; 476 | qs['include_docs'] = true; 477 | 478 | return relax({ 479 | db: dbName, 480 | path: '_all_docs', 481 | method: 'POST', 482 | qs: qs, 483 | body: docNames 484 | }, callback); 485 | } 486 | 487 | function fetchRevs(docNames, qs, callback) { 488 | if (typeof qs === 'function') { 489 | callback = qs; 490 | qs = {}; 491 | } 492 | return relax({ 493 | db: dbName, 494 | path: '_all_docs', 495 | method: 'POST', 496 | qs: qs, 497 | body: docNames 498 | }, callback); 499 | } 500 | 501 | function view(ddoc, viewName, meta, qs, callback) { 502 | if (typeof qs === 'function') { 503 | callback = qs; 504 | qs = {}; 505 | } 506 | 507 | var viewPath = '_design/' + ddoc + '/_' + meta.type + '/' + viewName; 508 | 509 | // Several search parameters must be JSON-encoded; but since this is an 510 | // object API, several parameters need JSON endoding. 511 | var paramsToEncode = ['counts', 'drilldown', 'group_sort', 'ranges', 'sort']; 512 | paramsToEncode.forEach(function(param) { 513 | if (param in qs) { 514 | qs[param] = JSON.stringify(qs[param]); 515 | } 516 | }); 517 | 518 | if (qs && qs.keys) { 519 | var body = {keys: qs.keys}; 520 | delete qs.keys; 521 | return relax({ 522 | db: dbName, 523 | path: viewPath, 524 | method: 'POST', 525 | qs: qs, 526 | body: body 527 | }, callback); 528 | } else { 529 | var req = { 530 | db: dbName, 531 | method: meta.method || 'GET', 532 | path: viewPath, 533 | qs: qs 534 | }; 535 | 536 | if (meta.body) { 537 | req.body = meta.body; 538 | } 539 | 540 | return relax(req, callback); 541 | } 542 | } 543 | 544 | // http://docs.couchdb.org/en/latest/api/ddoc/views.html#post--db-_design-ddoc-_view-view 545 | function viewDocs(ddoc, viewName, qs, callback) { 546 | return view(ddoc, viewName, {type: 'view'}, qs, callback); 547 | } 548 | 549 | // geocouch 550 | function viewSpatial(ddoc, viewName, qs, callback) { 551 | return view(ddoc, viewName, {type: 'spatial'}, qs, callback); 552 | } 553 | 554 | // cloudant 555 | function viewSearch(ddoc, viewName, qs, callback) { 556 | return view(ddoc, viewName, {type: 'search'}, qs, callback); 557 | } 558 | 559 | // http://docs.couchdb.org/en/latest/api/ddoc/render.html#get--db-_design-ddoc-_show-func 560 | function showDoc(ddoc, viewName, docName, qs, callback) { 561 | return view(ddoc, viewName + '/' + docName, {type: 'show'}, qs, callback); 562 | } 563 | 564 | // http://docs.couchdb.org/en/latest/api/ddoc/render.html#put--db-_design-ddoc-_update-func-docid 565 | function updateWithHandler(ddoc, viewName, docName, body, callback) { 566 | if (typeof body === 'function') { 567 | callback = body; 568 | body = undefined; 569 | } 570 | return view(ddoc, viewName + '/' + encodeURIComponent(docName), { 571 | type: 'update', 572 | method: 'PUT', 573 | body: body 574 | }, callback); 575 | } 576 | 577 | function viewWithList(ddoc, viewName, listName, qs, callback) { 578 | return view(ddoc, listName + '/' + viewName, { 579 | type: 'list' 580 | }, qs, callback); 581 | } 582 | 583 | // http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_bulksDoc 584 | function bulksDoc(docs, qs, callback) { 585 | if (typeof qs === 'function') { 586 | callback = qs; 587 | qs = {}; 588 | } 589 | 590 | return relax({ 591 | db: dbName, 592 | path: '_bulk_docs', 593 | body: docs, 594 | method: 'POST', 595 | qs: qs 596 | }, callback); 597 | } 598 | 599 | // http://docs.couchdb.org/en/latest/api/document/common.html#creating-multiple-attachments 600 | function insertMultipart(doc, attachments, qs, callback) { 601 | if (typeof qs === 'string') { 602 | qs = {docName: qs}; 603 | } 604 | 605 | var docName = qs.docName; 606 | delete qs.docName; 607 | 608 | doc = _.extend({_attachments: {}}, doc); 609 | 610 | var multipart = []; 611 | 612 | attachments.forEach(function(att) { 613 | doc._attachments[att.name] = { 614 | follows: true, 615 | length: Buffer.isBuffer(att.data) ? 616 | att.data.length : Buffer.byteLength(att.data), 617 | /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */ 618 | 'content_type': att.content_type 619 | }; 620 | multipart.push({body: att.data}); 621 | }); 622 | 623 | multipart.unshift({ 624 | 'content-type': 'application/json', 625 | body: JSON.stringify(doc) 626 | }); 627 | 628 | return relax({ 629 | db: dbName, 630 | method: 'PUT', 631 | contentType: 'multipart/related', 632 | doc: docName, 633 | qs: qs, 634 | multipart: multipart 635 | }, callback); 636 | } 637 | 638 | function getMultipart(docName, qs, callback) { 639 | if (typeof qs === 'function') { 640 | callback = qs; 641 | qs = {}; 642 | } 643 | 644 | qs.attachments = true; 645 | 646 | return relax({ 647 | db: dbName, 648 | doc: docName, 649 | encoding: null, 650 | contentType: 'multipart/related', 651 | qs: qs 652 | }, callback); 653 | } 654 | 655 | function insertAtt(docName, attName, att, contentType, qs, callback) { 656 | if (typeof qs === 'function') { 657 | callback = qs; 658 | qs = {}; 659 | } 660 | 661 | return relax({ 662 | db: dbName, 663 | att: attName, 664 | method: 'PUT', 665 | contentType: contentType, 666 | doc: docName, 667 | qs: qs, 668 | body: att, 669 | dontStringify: true 670 | }, callback); 671 | } 672 | 673 | function getAtt(docName, attName, qs, callback) { 674 | if (typeof qs === 'function') { 675 | callback = qs; 676 | qs = {}; 677 | } 678 | 679 | return relax({ 680 | db: dbName, 681 | att: attName, 682 | doc: docName, 683 | qs: qs, 684 | encoding: null, 685 | dontParse: true 686 | }, callback); 687 | } 688 | 689 | function destroyAtt(docName, attName, qs, callback) { 690 | return relax({ 691 | db: dbName, 692 | att: attName, 693 | method: 'DELETE', 694 | doc: docName, 695 | qs: qs 696 | }, callback); 697 | } 698 | 699 | // db level exports 700 | docScope = { 701 | info: function(cb) { 702 | return getDb(dbName, cb); 703 | }, 704 | replicate: function(target, opts, cb) { 705 | return replicateDb(dbName, target, opts, cb); 706 | }, 707 | compact: function(cb) { 708 | return compactDb(dbName, cb); 709 | }, 710 | changes: function(qs, cb) { 711 | return changesDb(dbName, qs, cb); 712 | }, 713 | follow: function(qs, cb) { 714 | return followDb(dbName, qs, cb); 715 | }, 716 | auth: auth, 717 | session: session, 718 | insert: insertDoc, 719 | get: getDoc, 720 | head: headDoc, 721 | copy: copyDoc, 722 | destroy: destroyDoc, 723 | bulk: bulksDoc, 724 | list: listDoc, 725 | fetch: fetchDocs, 726 | fetchRevs: fetchRevs, 727 | config: {url: cfg.url, db: dbName}, 728 | multipart: { 729 | insert: insertMultipart, 730 | get: getMultipart 731 | }, 732 | attachment: { 733 | insert: insertAtt, 734 | get: getAtt, 735 | destroy: destroyAtt 736 | }, 737 | show: showDoc, 738 | atomic: updateWithHandler, 739 | updateWithHandler: updateWithHandler, 740 | search: viewSearch, 741 | spatial: viewSpatial, 742 | view: viewDocs, 743 | viewWithList: viewWithList 744 | }; 745 | 746 | docScope.view.compact = function(ddoc, cb) { 747 | return compactDb(dbName, ddoc, cb); 748 | }; 749 | 750 | return docScope; 751 | } 752 | 753 | // server level exports 754 | serverScope = _.extend(serverScope, { 755 | db: { 756 | create: createDb, 757 | get: getDb, 758 | destroy: destroyDb, 759 | list: listDbs, 760 | use: docModule, 761 | scope: docModule, 762 | compact: compactDb, 763 | replicate: replicateDb, 764 | changes: changesDb, 765 | follow: followDb, 766 | followUpdates: followUpdates, 767 | updates: updates 768 | }, 769 | use: docModule, 770 | scope: docModule, 771 | request: relax, 772 | relax: relax, 773 | dinosaur: relax, 774 | auth: auth, 775 | session: session, 776 | updates: updates, 777 | followUpdates: followUpdates 778 | }); 779 | 780 | var db = maybeExtractDatabaseComponent(); 781 | 782 | return db ? docModule(db) : serverScope; 783 | }; 784 | 785 | /* 786 | * and now an ascii dinosaur 787 | * _ 788 | * / _) ROAR! i'm a vegan! 789 | * .-^^^-/ / 790 | * __/ / 791 | * /__.|_|-|_| 792 | * 793 | * thanks for visiting! come again! 794 | */ 795 | nano.version = require('../package.json').version; 796 | nano.path = __dirname; 797 | 798 | function urlResolveFix(couchUrl, dbName) { 799 | if (/[^\/]$/.test(couchUrl)) { 800 | couchUrl += '/'; 801 | } 802 | return u.resolve(couchUrl, dbName); 803 | } 804 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nano", 3 | "description": "The official CouchDB client for Node.js", 4 | "license": "Apache-2.0", 5 | "homepage": "http://github.com/apache/couchdb-nano", 6 | "repository": "git://github.com/apache/couchdb-nano", 7 | "version": "6.2.0", 8 | "author": "Apache CouchDB (http://couchdb.apache.org)", 9 | "keywords": [ 10 | "couchdb", 11 | "data", 12 | "request", 13 | "json", 14 | "nosql", 15 | "micro", 16 | "nano", 17 | "database" 18 | ], 19 | "dependencies": { 20 | "request": "^2.53.0", 21 | "follow": "^0.12.1", 22 | "errs": "^0.3.0", 23 | "underscore": "^1.7.0", 24 | "debug": "^2.0.0" 25 | }, 26 | "devDependencies": { 27 | "async": "^0.9.0", 28 | "tape": "^3.0.0", 29 | "istanbul": "^0.3.2", 30 | "jshint": "^2.5.6", 31 | "jscs": "^1.7.0", 32 | "nock": "^0.48.1", 33 | "endswith": "^0.0.0", 34 | "tape-it": "^0.3.1" 35 | }, 36 | "scripts": { 37 | "test": "DEBUG=* NOCK_OFF=true istanbul cover tape tests/*/*/*.js", 38 | "unmocked": "NOCK_OFF=true tape tests/*/*/*.js", 39 | "mocked": "tape tests/*/*/*.js", 40 | "jshint": "jshint tests/*/*/*.js lib/*.js", 41 | "codestyle": "jscs -p google tests/*/*/*.js lib/*.js", 42 | "coverage": "open coverage/lcov-report/index.html", 43 | "checkcoverage": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100" 44 | }, 45 | "main": "./lib/nano.js", 46 | "engines": { 47 | "node": ">=0.8.0" 48 | }, 49 | "pre-commit": [ 50 | "jshint", 51 | "codestyle", 52 | "mocked", 53 | "test", 54 | "checkcoverage" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /tests/fixtures/attachment/destroy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/attachment_destroy" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/attachment_destroy/new/att" 9 | , "body" : "Hello World!" 10 | , "status" : 201 11 | , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }" 12 | } 13 | , { "method" : "delete" 14 | , "path" : "/attachment_destroy/new/att?rev=1-921bd51" 15 | , "response" : "{ \"ok\": true, \"id\": \"new\" }" 16 | , "status" : 201 17 | } 18 | , { "method" : "put" 19 | , "path" : "/attachment_destroy/new2/att2" 20 | , "body" : "Hello World!" 21 | , "status" : 201 22 | , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }" 23 | } 24 | , { "method" : "delete" 25 | , "path" : "/attachment_destroy" 26 | , "status" : 200 27 | , "response" : "{ \"ok\": true }" 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /tests/fixtures/attachment/get.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/attachment_get" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/attachment_get/new_string/att" 9 | , "body" : "Hello" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"new_string\",\"rev\":\"1-5142a2\"}" 12 | } 13 | , { "path" : "/attachment_get/new_string/att" 14 | , "status" : 200 15 | , "response" : "Hello" 16 | } 17 | , { "method" : "put" 18 | , "path" : "/attachment_get/new_binary/att" 19 | , "base64" : "MTIz" 20 | , "status" : 201 21 | , "response" : "{\"ok\":true,\"id\":\"new_binary\",\"rev\":\"1-5142ff\"}" 22 | } 23 | , { "path" : "/attachment_get/new_binary/att" 24 | , "status" : 200 25 | , "buffer" : "MTIz" 26 | } 27 | , { "method" : "delete" 28 | , "path" : "/attachment_get" 29 | , "status" : 200 30 | , "response" : "{ \"ok\": true }" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /tests/fixtures/attachment/insert.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/attachment_insert" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/attachment_insert/new/att" 9 | , "body" : "Hello World!" 10 | , "status" : 201 11 | , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }" 12 | } 13 | , { "method" : "delete" 14 | , "path" : "/attachment_insert" 15 | , "status" : 200 16 | , "response" : "{ \"ok\": true }" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /tests/fixtures/attachment/pipe.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/attachment_pipe" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/attachment_pipe/new/att" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-3b1f88\"}\n" 12 | } 13 | , { "path" : "/attachment_pipe/new/att?rev=1-3b1f88" 14 | , "status" : 200 15 | , "buffer" : "Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA==" 16 | } 17 | , { "method" : "put" 18 | , "path" : "/attachment_pipe/nodejs/logo.png" 19 | , "body" : "*" 20 | , "response" : "{ \"ok\": true, \"id\": \"new\", \"rev\": \"1-64b327\" }" 21 | } 22 | , { "method" : "get" 23 | , "path" : "/attachment_pipe/nodejs/logo.png" 24 | , "buffer" : "logo.png" 25 | } 26 | , { "method" : "delete" 27 | , "path" : "/attachment_pipe" 28 | , "status" : 200 29 | , "response" : "{ \"ok\": true }" 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /tests/fixtures/attachment/update.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/attachment_update" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/attachment_update/new/att" 9 | , "body" : "Hello" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2\"}" 12 | } 13 | , { "method" : "put" 14 | , "path" : "/attachment_update/new/att?rev=1-5142a2" 15 | , "body" : "*" 16 | , "status" : 201 17 | , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"2-3b1f88\"}\n" 18 | } 19 | , { "method" : "get" 20 | , "path" : "/attachment_update/new" 21 | , "status" : 200 22 | , "response" : "{ \"_id\": \"new\", \"_rev\": \"2-3b1f88\", \"_attachments\": { \"att\": { \"content_type\": \"image/bmp\", \"revpos\": 2, \"digest\": \"md5-Ow9j2dR0Qm58Qi3z8p2w3A==\", \"length\": 58, \"stub\": true }}}" 23 | } 24 | , { "method" : "put" 25 | , "path" : "/attachment_update/new" 26 | , "status" : 201 27 | , "body" : "{\"_id\":\"new\",\"_rev\":\"2-3b1f88\",\"_attachments\":{\"att\":{\"content_type\":\"image/bmp\",\"revpos\":2,\"digest\":\"md5-Ow9j2dR0Qm58Qi3z8p2w3A==\",\"length\":58,\"stub\":true}},\"works\":true}" 28 | , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"3-19e2de\"}" 29 | } 30 | , { "method" : "delete" 31 | , "path" : "/attachment_update" 32 | , "status" : 200 33 | , "response" : "{ \"ok\": true }" 34 | } 35 | ] 36 | -------------------------------------------------------------------------------- /tests/fixtures/cfg.json: -------------------------------------------------------------------------------- 1 | { "timeout" : 5000 2 | , "couch" : "http://localhost:5984" 3 | , "admin" : "http://admin:password@localhost:5984" 4 | } 5 | -------------------------------------------------------------------------------- /tests/fixtures/database/changes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_changes" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/database_changes/foobar" 10 | , "body" : "{\"foo\":\"bar\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/database_changes/foobaz" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/database_changes/barfoo" 22 | , "body" : "{\"bar\":\"foo\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 24 | } 25 | , { "status" : 200 26 | , "path" : "/database_changes/_changes?since=2" 27 | , "response" : "{\"results\":[\n{\"seq\":3,\"id\":\"foobaz\",\"changes\":[{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}]}\n],\n\"last_seq\":3}" 28 | } 29 | , { "method" : "delete" 30 | , "path" : "/database_changes" 31 | , "status" : 200 32 | , "response" : "{ \"ok\": true }" 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /tests/fixtures/database/compact.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_compact" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/database_compact/goofy" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "method" : "delete" 14 | , "path" : "/database_compact/goofy?rev=1-611488" 15 | , "response" : "{\"ok\":true}" 16 | } 17 | , { "method" : "post" 18 | , "path" : "/database_compact/_compact" 19 | , "response" : "{\"ok\":true}" 20 | , "status" : 202 21 | } 22 | , { "method" : "get" 23 | , "path" : "/database_compact" 24 | , "response" : "{ \"db_name\": \"db_compact\", \"doc_count\": 0, \"doc_del_count\": 1, \"update_seq\": 2, \"purge_seq\": 0, \"compact_running\": true, \"disk_size\": 523, \"instance_start_time\": \"1336855750104121\", \"disk_format_version\": 5, \"committed_update_seq\": 0 }" 25 | } 26 | , { "method" : "get" 27 | , "path" : "/database_compact" 28 | , "response" : "{ \"db_name\": \"db_compact\", \"compact_running\": false }" 29 | } 30 | , { "method" : "delete" 31 | , "path" : "/database_compact" 32 | , "response" : "{ \"ok\": true }" 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /tests/fixtures/database/create-and-destroy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_create-and-destroy" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/az09_%24()%2B-%2F" 9 | , "status" : 201 10 | , "response" : "{ \"ok\": true }" 11 | } 12 | , { "method" : "put" 13 | , "path" : "/with%2Fslash" 14 | , "status" : 201 15 | , "response" : "{ \"ok\": true }" 16 | } 17 | , { "method" : "delete" 18 | , "path" : "/database_create-and-destroy" 19 | , "response" : "{ \"ok\": true }" 20 | } 21 | , { "method" : "delete" 22 | , "path" : "/az09_%24()%2B-%2F" 23 | , "response" : "{ \"ok\": true }" 24 | } 25 | , { "method" : "delete" 26 | , "path" : "/with%2Fslash" 27 | , "response" : "{ \"ok\": true }" 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /tests/fixtures/database/follow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_follow" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/database_follow/foobar" 10 | , "body" : "{\"foo\":\"bar\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/database_follow/foobaz" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/database_follow/barfoo" 22 | , "body" : "{\"bar\":\"foo\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 24 | } 25 | , { "method" : "delete" 26 | , "path" : "/database_follow" 27 | , "status" : 200 28 | , "response" : "{ \"ok\": true }" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /tests/fixtures/database/get.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_get" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "get" 8 | , "path" : "/database_get" 9 | , "response" : "{ \"db_name\": \"database_get\", \"doc_count\": 0}" 10 | } 11 | , { "method" : "delete" 12 | , "path" : "/database_get" 13 | , "response" : "{ \"ok\": true }" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /tests/fixtures/database/list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_list" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "get" 8 | , "path" : "/_all_dbs" 9 | , "response" : "[\"database_list\", \"_users\", \"_replicator\"]" 10 | } 11 | , { "method" : "delete" 12 | , "path" : "/database_list" 13 | , "response" : "{ \"ok\": true }" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /tests/fixtures/database/replicate.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/database_replicate" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/database_replica" 9 | , "status" : 201 10 | , "response" : "{ \"ok\": true }" 11 | } 12 | , { "method" : "put" 13 | , "path" : "/database_replica2" 14 | , "status" : 201 15 | , "response" : "{ \"ok\": true }" 16 | } 17 | , { "method" : "put" 18 | , "status" : 201 19 | , "path" : "/database_replicate/foobar" 20 | , "body" : "{\"foo\":\"bar\"}" 21 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 22 | } 23 | , { "method" : "put" 24 | , "status" : 201 25 | , "path" : "/database_replicate/foobaz" 26 | , "body" : "{\"foo\":\"baz\"}" 27 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 28 | } 29 | , { "method" : "put" 30 | , "status" : 201 31 | , "path" : "/database_replicate/barfoo" 32 | , "body" : "{\"bar\":\"foo\"}" 33 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 34 | } 35 | , { "method" : "post" 36 | , "status" : 201 37 | , "path" : "/_replicate" 38 | , "body" : "{\"source\":\"database_replicate\",\"target\":\"database_replica\"}" 39 | , "response" : "{\"ok\":true}" 40 | } 41 | , { "path" : "/database_replica/_all_docs" 42 | , "status" : 200 43 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}" 44 | } 45 | , { "method" : "post" 46 | , "status" : 201 47 | , "path" : "/_replicate" 48 | , "body" : "{\"source\":\"http://localhost:5984/database_replicate\",\"target\":\"http://localhost:5984/database_replica2\"}" 49 | , "response" : "{\"ok\":true}" 50 | } 51 | , { "method" : "post" 52 | , "status" : 201 53 | , "path" : "/_replicate" 54 | , "body" : "{\"source\":\"database_replicate\",\"target\":\"database_replica\"}" 55 | , "response" : "{\"ok\":true}" 56 | } 57 | , { "path" : "/database_replica2/_all_docs" 58 | , "status" : 200 59 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}" 60 | } 61 | , { "method" : "delete" 62 | , "path" : "/database_replicate" 63 | , "status" : 200 64 | , "response" : "{ \"ok\": true }" 65 | } 66 | , { "method" : "delete" 67 | , "path" : "/database_replica" 68 | , "status" : 200 69 | , "response" : "{ \"ok\": true }" 70 | } 71 | , { "method" : "delete" 72 | , "path" : "/database_replica2" 73 | , "status" : 200 74 | , "response" : "{ \"ok\": true }" 75 | } 76 | ] 77 | -------------------------------------------------------------------------------- /tests/fixtures/design/atomic.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_atomic" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_atomic/_design/update" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/update\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_atomic/foobar" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "path" : "/design_atomic/_design/update/_update/inplace/foobar" 21 | , "body" : "{\"field\":\"foo\",\"value\":\"bar\"}" 22 | , "response" : "{\"foo\": \"bar\"}" 23 | } 24 | , { "method" : "put" 25 | , "path" : "/design_atomic/_design/update/_update/addbaz/baz" 26 | , "response" : "{\"baz\": \"biz\"}" 27 | } 28 | , { "method" : "put" 29 | , "status" : 201 30 | , "path" : "/design_atomic/wat%2Fwat" 31 | , "body" : "{\"wat\":\"wat\"}" 32 | , "response" : "{\"ok\":true,\"id\":\"wat%2Fwat\",\"rev\":\"1-511488\"}" 33 | } 34 | , { "method" : "put" 35 | , "path" : "/design_atomic/_design/update/_update/inplace/wat%2Fwat" 36 | , "body" : "{\"field\":\"wat\",\"value\":\"dawg\"}" 37 | , "response" : "{\"wat\": \"dawg\"}" 38 | } 39 | , { "method" : "delete" 40 | , "path" : "/design_atomic" 41 | , "response" : "{ \"ok\": true }" 42 | } 43 | ] 44 | -------------------------------------------------------------------------------- /tests/fixtures/design/compact.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_compact" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_compact/_design/alice" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/alice\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_compact/foobaz" 16 | , "body" : "*" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "delete" 20 | , "path" : "/design_compact/foobaz?rev=1-611488" 21 | , "response" : "{\"ok\":true}" 22 | } 23 | , { "method" : "post" 24 | , "path" : "/design_compact/_compact/alice" 25 | , "response" : "{\"ok\":true}" 26 | , "status" : 202 27 | } 28 | , { "path" : "/design_compact" 29 | , "response" : "{\"compact_running\": false}" 30 | } 31 | , { "path" : "/design_compact/_design/alice/_view/by_id" 32 | , "response" : "{ \"total_rows\": 0, \"offset\": 0, \"rows\": [] }" 33 | } 34 | , { "method" : "delete" 35 | , "path" : "/design_compact" 36 | , "response" : "{ \"ok\": true }" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /tests/fixtures/design/list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_list" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_list/_design/people" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_list/p_derek" 16 | , "body" : "*" 17 | , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/design_list/p_randall" 22 | , "body" : "*" 23 | , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}" 24 | } 25 | , { "method" : "put" 26 | , "status" : 201 27 | , "path" : "/design_list/p_nuno" 28 | , "body" : "*" 29 | , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}" 30 | } 31 | , { "method" : "get" 32 | , "path" : "/design_list/_design/people/_list/my_list/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 33 | , "response" : "Hello" 34 | } 35 | , { "method" : "delete" 36 | , "path" : "/design_list" 37 | , "status" : 200 38 | , "response" : "{ \"ok\": true }" 39 | } 40 | ] 41 | -------------------------------------------------------------------------------- /tests/fixtures/design/multiple.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_multiple" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_multiple/_design/alice" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/alice\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_multiple/foobar" 16 | , "body" : "{\"foo\":\"bar\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/design_multiple/foobaz" 22 | , "body" : "{\"foo\":\"baz\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 24 | } 25 | , { "method" : "put" 26 | , "status" : 201 27 | , "path" : "/design_multiple/barfoo" 28 | , "body" : "{\"bar\":\"foo\"}" 29 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 30 | } 31 | , { "path" : "/design_multiple/_design/alice/_view/by_id?include_docs=true" 32 | , "body" : "{\"keys\":[\"foobar\",\"barfoo\"]}" 33 | , "method" : "post" 34 | , "response" : "{\"total_rows\":3,\"offset\":2,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"}}\r\n]}\n" 35 | } 36 | , { "method" : "delete" 37 | , "path" : "/design_multiple" 38 | , "status" : 200 39 | , "response" : "{ \"ok\": true }" 40 | } 41 | ] 42 | -------------------------------------------------------------------------------- /tests/fixtures/design/query.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_query" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_query/_design/people" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_query/p_derek" 16 | , "body" : "*" 17 | , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/design_query/p_randall" 22 | , "body" : "*" 23 | , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}" 24 | } 25 | , { "method" : "put" 26 | , "status" : 201 27 | , "path" : "/design_query/p_nuno" 28 | , "body" : "*" 29 | , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}" 30 | } 31 | , { "path" : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 32 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 33 | } 34 | , { "path" : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 35 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 36 | } 37 | , { "path" : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 38 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 39 | } 40 | , { "method" : "delete" 41 | , "path" : "/design_query" 42 | , "status" : 200 43 | , "response" : "{ \"ok\": true }" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /tests/fixtures/design/search.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_search" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_search/_design/people/_search" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/people/_search\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_search/p_derek" 16 | , "body" : "*" 17 | , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/design_search/p_randall" 22 | , "body" : "*" 23 | , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}" 24 | } 25 | , { "method" : "put" 26 | , "status" : 201 27 | , "path" : "/design_search/p_nuno" 28 | , "body" : "*" 29 | , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}" 30 | } 31 | , { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 32 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 33 | } 34 | , { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 35 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 36 | } 37 | , { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D" 38 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n" 39 | } 40 | , { "method" : "delete" 41 | , "path" : "/design_search" 42 | , "status" : 200 43 | , "response" : "{ \"ok\": true }" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /tests/fixtures/design/show.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/design_show" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/design_show/_design/people" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/design_show/p_clemens" 16 | , "body" : "{\"name\":\"Clemens\",\"city\":\"Dresden\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"p_clemens\",\"rev\":\"1-4c6114\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/design_show/p_randall" 22 | , "body" : "{\"name\":\"Randall\",\"city\":\"San Francisco\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}" 24 | } 25 | , { "method" : "put" 26 | , "status" : 201 27 | , "path" : "/design_show/p_nuno" 28 | , "body" : "{\"name\":\"Nuno\",\"city\":\"New York\"}" 29 | , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}" 30 | } 31 | , { "path" : "/design_show/_design/people/_show/singleDoc/p_clemens" 32 | , "response" : "{\"name\":\"Clemens\",\"city\":\"Dresden\",\"format\":\"json\"}\n" 33 | , "headers" : { "content-type": "application/json" } 34 | } 35 | , { "path" : "/design_show/_design/people/_show/singleDoc/p_clemens?format=html" 36 | , "response" : "Hello Clemens!" 37 | , "headers" : { "content-type": "text/html" } 38 | } 39 | , { "method" : "delete" 40 | , "path" : "/design_show" 41 | , "status" : 200 42 | , "response" : "{ \"ok\": true }" 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /tests/fixtures/document/bulk.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_bulk" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "post" 8 | , "path" : "/document_bulk/_bulk_docs" 9 | , "body" : "{\"docs\":[{\"key\":\"baz\",\"name\":\"bazzel\"},{\"key\":\"bar\",\"name\":\"barry\"}]}" 10 | , "response" : "[{\"id\":\"84600661a1f8f8dd1428851bb5002449\",\"rev\": \"1-f5f3f3e496c72307975a69c73fd53d42\"},{\"id\":\"84600661a1f8f8dd1428851bb5002dd8\",\"rev\":\"1-8ad0e70d5e6edd474ec190eac2376bde\"}]" 11 | } 12 | , { "method" : "delete" 13 | , "path" : "/document_bulk" 14 | , "response" : "{ \"ok\": true }" 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /tests/fixtures/document/copy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_copy" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_copy/foo_src" 10 | , "body" : "*" 11 | , "response" : "{\"ok\":true,\"id\":\"foo_src\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/document_copy/foo_dest" 16 | , "body" : "*" 17 | , "response" : "{\"ok\":true,\"id\":\"foo_dest\",\"rev\":\"1-351431\"}" 18 | } 19 | , { "method" : "head" 20 | , "status" : 200 21 | , "path" : "/document_copy/foo_dest" 22 | , "headers" : {"etag": "\"1-aa43f0\""} 23 | } 24 | , { "method" : "copy" 25 | , "path" : "/document_copy/foo_src" 26 | , "response" : "{ \"id\": \"foo_dest\", \"rev\": \"2-e66edd\" }" 27 | , "status" : 201 28 | } 29 | , { "method" : "copy" 30 | , "path" : "/document_copy/foo_src" 31 | , "response" : "{ \"error\": \"conflict\", \"reason\": \"Document update conflict.\" }" 32 | , "status" : 409 33 | } 34 | , { "method" : "copy" 35 | , "path" : "/document_copy/foo_src" 36 | , "response" : "{ \"id\": \"baz_dest\", \"rev\": \"1-36645f\" }" 37 | , "status" : 201 38 | } 39 | , { "method" : "delete" 40 | , "path" : "/document_copy" 41 | , "response" : "{ \"ok\": true }" 42 | } 43 | ] 44 | -------------------------------------------------------------------------------- /tests/fixtures/document/destroy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_destroy" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_destroy/foobaz" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "method" : "delete" 14 | , "path" : "/document_destroy/foobaz?rev=1-611488" 15 | , "response" : "{\"ok\":true}" 16 | } 17 | , { "method" : "delete" 18 | , "path" : "/document_destroy" 19 | , "response" : "{ \"ok\": true }" 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /tests/fixtures/document/fetch.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_fetch" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_fetch/foobar" 10 | , "body" : "{\"foo\":\"bar\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/document_fetch/foobaz" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/document_fetch/barfoo" 22 | , "body" : "{\"bar\":\"foo\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 24 | } 25 | , { "method" : "post" 26 | , "path" : "/document_fetch/_all_docs?include_docs=true" 27 | , "body" : "{\"keys\":[\"foobar\"]}" 28 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}\r\n]}\n" 29 | } 30 | , { "method" : "post" 31 | , "path" : "/document_fetch/_all_docs?not=important&include_docs=true" 32 | , "body" : "{\"keys\":[\"foobar\"]}" 33 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}\r\n]}\n" 34 | } 35 | , { "method" : "post" 36 | , "path" : "/document_fetch/_all_docs?include_docs=true" 37 | , "body" : "{\"keys\":[\"foobar\",\"barfoo\"]}" 38 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"}}\r\n]}\n" 39 | } 40 | , { "method" : "delete" 41 | , "path" : "/document_fetch" 42 | , "status" : 200 43 | , "response" : "{ \"ok\": true }" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /tests/fixtures/document/fetch_revs.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_fetch_revs" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_fetch_revs/foobar" 10 | , "body" : "{\"foo\":\"bar\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/document_fetch_revs/foobaz" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/document_fetch_revs/barfoo" 22 | , "body" : "{\"bar\":\"foo\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 24 | } 25 | , { "method" : "post" 26 | , "path" : "/document_fetch_revs/_all_docs" 27 | , "body" : "{\"keys\":[\"foobar\"]}" 28 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}}\r\n]}\n" 29 | } 30 | , { "method" : "post" 31 | , "path" : "/document_fetch_revs/_all_docs" 32 | , "body" : "{\"keys\":[\"foobar\",\"barfoo\"]}" 33 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}}\r\n]}\n" 34 | } 35 | , { "method" : "post" 36 | , "path" : "/document_fetch_revs/_all_docs?still=no" 37 | , "body" : "{\"keys\":[\"foobar\"]}" 38 | , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}}\r\n]}\n" 39 | } 40 | , { "method" : "delete" 41 | , "path" : "/document_fetch_revs" 42 | , "status" : 200 43 | , "response" : "{ \"ok\": true }" 44 | } 45 | ] 46 | -------------------------------------------------------------------------------- /tests/fixtures/document/get.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_get" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_get/foobaz" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "path" : "/document_get/foobaz?revs_info=true" 14 | , "response" : "{\"_id\":\"foobaz\", \"_rev\": \"1-611488\", \"foo\": \"baz\", \"_revs_info\": [] }" 15 | } 16 | , { "method" : "delete" 17 | , "path" : "/document_get" 18 | , "response" : "{ \"ok\": true }" 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /tests/fixtures/document/head.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_head" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_head/foobaz" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "path" : "/document_head/foobaz" 14 | , "method" : "head" 15 | , "headers" : { "statusCode" : 200 } 16 | } 17 | , { "method" : "delete" 18 | , "path" : "/document_head" 19 | , "response" : "{ \"ok\": true }" 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /tests/fixtures/document/insert.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_insert" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_insert/foobaz" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 409 15 | , "path" : "/document_insert/foobaz" 16 | , "body" : "*" 17 | , "response" : "{\"error\":\"conflict\",\"reason\":\"Document update conflict.\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/document_insert/foobaz?new_edits=false" 22 | , "body" : "{\"foo\":\"baz\",\"_rev\":\"1-611488\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"2-123456\"}" 24 | } 25 | , { "method" : "post" 26 | , "status" : 201 27 | , "path" : "/document_insert" 28 | , "body" : "*" 29 | , "response" : "{\"ok\":true,\"id\":\"123\",\"rev\":\"1-611488\"}" 30 | } 31 | , { "path" : "/document_insert/123" 32 | , "response" : "{\"fn\":\"function() { return true; }\",\"fn2\":\"function() { return true; }\",\"id\":\"123\",\"rev\":\"1-611488\"}" 33 | } 34 | , { "method" : "post" 35 | , "status" : 201 36 | , "path" : "/document_insert" 37 | , "body" : "{\"foo\":\"bar\"}" 38 | , "response" : "{\"ok\":true,\"id\":\"234\",\"rev\":\"1-333231\"}" 39 | } 40 | , { "method" : "delete" 41 | , "path" : "/document_insert/foobaz?rev=1-611488" 42 | , "response" : "{\"ok\":true}" 43 | } 44 | , { "method" : "delete" 45 | , "path" : "/document_insert" 46 | , "response" : "{ \"ok\": true }" 47 | } 48 | ] 49 | -------------------------------------------------------------------------------- /tests/fixtures/document/list.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_list" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_list/foobar" 10 | , "body" : "{\"foo\":\"bar\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}" 12 | } 13 | , { "method" : "put" 14 | , "status" : 201 15 | , "path" : "/document_list/foobaz" 16 | , "body" : "{\"foo\":\"baz\"}" 17 | , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}" 18 | } 19 | , { "method" : "put" 20 | , "status" : 201 21 | , "path" : "/document_list/barfoo" 22 | , "body" : "{\"bar\":\"foo\"}" 23 | , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}" 24 | } 25 | , { "path" : "/document_list/_all_docs" 26 | , "response" : "{\"total_rows\":3,\"offset\": 0, \"rows\": []}" 27 | } 28 | , { "path" : "/document_list/_all_docs?limit=1" 29 | , "response" : "{\"total_rows\":3,\"offset\": 0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}]}" 30 | } 31 | , { "path" : "/document_list/_all_docs?startkey=%22c%22" 32 | , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"}}\r\n]}" 33 | } 34 | , { "method" : "delete" 35 | , "path" : "/document_list" 36 | , "status" : 200 37 | , "response" : "{ \"ok\": true }" 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /tests/fixtures/document/update.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/document_update" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "status" : 201 9 | , "path" : "/document_update/foobar" 10 | , "body" : "{\"foo\":\"baz\"}" 11 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-611488\"}" 12 | } 13 | , { "method" : "put" 14 | , "path" : "/document_update/foobar" 15 | , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"2-2ff408\"}" 16 | , "body" : "{\"foo\":\"bar\",\"_rev\":\"1-611488\"}" 17 | } 18 | , { "method" : "delete" 19 | , "path" : "/document_update" 20 | , "response" : "{ \"ok\": true }" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /tests/fixtures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/nano/a10f6e6c337c761993c19cc8829bbf8cc9ba4c3a/tests/fixtures/logo.png -------------------------------------------------------------------------------- /tests/fixtures/multipart/get.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/multipart_get" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/multipart_get/foobaz" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\": true, \"id\": \"foobaz\", \"rev\": \"1-921bd51\" }" 12 | } 13 | , { "path" : "/multipart_get/foobaz?attachments=true" 14 | , "status" : 200 15 | , "headers" : { "content-type": "multipart\/related; boundary=\"33d91dba65f66463e14ac1ae75d79403\"" } 16 | , "buffer" : "LS0wN2ExNmJjYTNjYTA4MzA4YjQ4Njg3MjU3MDE1YjQ3YQ0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uDQoNCnsiX2lkIjoiZm9vYmF6IiwiX3JldiI6IjEtYzk0NjQ4MWI0MzI3NTc4ZTNmNDg4NmZiYzAwMjc3OTAiLCJmb28iOiJiYXoiLCJfYXR0YWNobWVudHMiOnsiYXR0Ijp7ImNvbnRlbnRfdHlwZSI6InRleHQvcGxhaW4iLCJyZXZwb3MiOjEsImRpZ2VzdCI6Im1kNS1qcmxBaXVQRmg5SFJCZmp5RHFqRlF3PT0iLCJsZW5ndGgiOjEyLCJmb2xsb3dzIjp0cnVlLCJlbmNvZGluZyI6Imd6aXAiLCJlbmNvZGVkX2xlbmd0aCI6MzJ9fX0NCi0tMDdhMTZiY2EzY2EwODMwOGI0ODY4NzI1NzAxNWI0N2ENCkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPSJhdHQiDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCkNvbnRlbnQtTGVuZ3RoOiAzMg0KQ29udGVudC1FbmNvZGluZzogZ3ppcA0KDQofiwgAAAAAAAAD80jNyclXCM8vyklRBACjHCkcDAAAAA0KLS0wN2ExNmJjYTNjYTA4MzA4YjQ4Njg3MjU3MDE1YjQ3YS0t" 17 | } 18 | , { "method" : "delete" 19 | , "path" : "/multipart_get" 20 | , "status" : 200 21 | , "response" : "{ \"ok\": true }" 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /tests/fixtures/multipart/insert.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/multipart_insert" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/multipart_insert/foobaz" 9 | , "body" : "*" 10 | , "status" : 201 11 | , "response" : "{\"ok\": true, \"id\": \"foobaz\", \"rev\": \"1-921bd51\" }" 12 | } 13 | , { "method" : "put" 14 | , "path" : "/multipart_insert/foobar" 15 | , "body" : "*" 16 | , "status" : 201 17 | , "response" : "{\"ok\": true, \"id\": \"foobar\", \"rev\": \"1-921bd51\" }" 18 | } 19 | , { "method" : "put" 20 | , "path" : "/multipart_insert/mydoc/one" 21 | , "body" : "Hello World!" 22 | , "status" : 201 23 | , "response" : "{\"ok\": true, \"id\": \"one\", \"rev\": \"1-921bd51\" }" 24 | } 25 | , { "path" : "/multipart_insert/mydoc" 26 | , "status" : 200 27 | , "response" : "{\"_id\": \"mydoc\", \"_rev\": \"1-921bd51\", \"_attachments\": { \"one\": { \"stub\": true } } }" 28 | } 29 | , { "method" : "put" 30 | , "path" : "/multipart_insert/mydoc" 31 | , "body" : "*" 32 | , "status" : 201 33 | , "response" : "{\"ok\": true, \"id\": \"mydoc\", \"rev\": \"2-921bd51\"" 34 | } 35 | , { "path" : "/multipart_insert/mydoc" 36 | , "status" : 200 37 | , "response" : "{\"_id\": \"mydoc\", \"_rev\": \"2-921bd51\", \"_attachments\": { \"one\": { \"stub\": true }, \"two\": { \"stub\": true } } }" 38 | } 39 | , { "method" : "put" 40 | , "path" : "/multipart_insert/otherdoc" 41 | , "body" : "*" 42 | , "status" : 201 43 | , "response" : "{\"ok\": true, \"id\": \"foobar\", \"rev\": \"1-921bd51\" }" 44 | } 45 | , { "method" : "delete" 46 | , "path" : "/multipart_insert" 47 | , "status" : 200 48 | , "response" : "{ \"ok\": true }" 49 | } 50 | ] 51 | -------------------------------------------------------------------------------- /tests/fixtures/shared/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_config" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "path" : "/" 8 | , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}" 9 | } 10 | , { "path" : "/" 11 | , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}" 12 | } 13 | , { "path" : "/_all_dbs" 14 | , "response" : "{}" 15 | } 16 | , { "method" : "delete" 17 | , "path" : "/shared_config" 18 | , "response" : "{ \"ok\": true }" 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /tests/fixtures/shared/cookie.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_cookie" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "path" : "/_config/admins/admin" 8 | , "method" : "put" 9 | , "body" : "*" 10 | , "response" : "{\"ok\": true}" 11 | } 12 | , { "method" : "post" 13 | , "path" : "/_session" 14 | , "body" : "name=admin&password=password" 15 | , "headers" : {"set-cookie" : ["AuthSession=YWRtaW46NEZCMzFERDk6BJyusEcy3SgfI9xD4Mptl0N0gh0;Version=1;Path=/;HttpOnly"]} 16 | , "status" : 201 17 | , "response" : "{ \"ok\": true,\"name\": null,\"roles\": [ \"_admin\" ] }" 18 | } 19 | , { "method" : "get" 20 | , "path" : "/_session" 21 | , "headers" : {"set-cookie" : ["AuthSession=YWRtaW46NEZCMzFERDk6BJyusEcy3SgfI9xD4Mptl0N0gh0;Version=1;Path=/;HttpOnly"]} 22 | , "status" : 201 23 | , "response" : "{ \"ok\": true,\"userCtx\": {\"name\":\"admin\",\"roles\": [ \"_admin\" ]} }" 24 | } 25 | , { "method" : "post" 26 | , "status" : 201 27 | , "path" : "/shared_cookie" 28 | , "body" : "{\"foo\":\"baz\"}" 29 | , "response" : "{\"ok\":true,\"id\":\"234\",\"rev\":\"1-333231\"}" 30 | } 31 | , { "path" : "/_config/admins/admin" 32 | , "method" : "delete" 33 | , "response" : "{\"ok\": true}" 34 | } 35 | , { "method" : "delete" 36 | , "path" : "/shared_cookie" 37 | , "response" : "{ \"ok\": true }" 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /tests/fixtures/shared/error.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_error" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "path" : "/" 8 | , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}" 9 | } 10 | , { "method" : "delete" 11 | , "path" : "/say_wat_wat" 12 | , "status" : 404 13 | , "response" : "{\"error\":\"not_found\",\"reason\":\"missing\"}" 14 | } 15 | , { "method" : "delete" 16 | , "path" : "/shared_error" 17 | , "response" : "{ \"ok\": true }" 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /tests/fixtures/shared/headers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_headers" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "put" 8 | , "path" : "/shared_headers/new/att" 9 | , "body" : "Hello" 10 | , "status" : 201 11 | , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2\"}" 12 | } 13 | , { "path" : "/shared_headers/new" 14 | , "status" : 304 15 | , "response" : "" 16 | , "reqheaders" : { 17 | "If-None-Match": "\"1-5142a2\"" 18 | } 19 | } 20 | , { "path" : "/shared_headers/new/att" 21 | , "status" : 200 22 | , "response" : "\"Hello\"" 23 | } 24 | , { "method" : "delete" 25 | , "path" : "/shared_headers" 26 | , "status" : 200 27 | , "response" : "{ \"ok\": true }" 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /tests/fixtures/shared/log.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_log" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "delete" 8 | , "path" : "/shared_log" 9 | , "response" : "{ \"ok\": true }" 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /tests/fixtures/shared/nano.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "put" 3 | , "path" : "/shared_nano" 4 | , "status" : 201 5 | , "response" : "{ \"ok\": true }" 6 | } 7 | , { "method" : "delete" 8 | , "path" : "/shared_nano" 9 | , "response" : "{ \"ok\": true }" 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /tests/fixtures/shared/updates.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "method" : "delete" 3 | , "path" : "/mydb" 4 | , "response" : "{ \"ok\": true }" 5 | } 6 | , { "method" : "get" 7 | , "path" : "/_db_updates" 8 | , "response" : "{\"ok\":true,\"type\":\"created\",\"db_name\":\"mydb\"}" 9 | } 10 | , { "method" : "put" 11 | , "path" : "/mydb" 12 | , "status" : 201 13 | , "response" : "{ \"ok\": true }" 14 | } 15 | , { "method" : "delete" 16 | , "path" : "/mydb" 17 | , "response" : "{ \"ok\": true }" 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /tests/helpers/index.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var path = require('path'); 16 | var fs = require('fs'); 17 | var url = require('url'); 18 | var nano = require('../../lib/nano'); 19 | 20 | var helpers = exports; 21 | var cfg = helpers.cfg = require('../fixtures/cfg'); 22 | var auth = url.parse(cfg.admin).auth.split(':'); 23 | 24 | helpers.noopTest = function(t){ t.end(); }; 25 | helpers.timeout = cfg.timeout; 26 | helpers.nano = nano(cfg.couch); 27 | helpers.Nano = nano; 28 | helpers.couch = cfg.couch; 29 | helpers.admin = cfg.admin; 30 | helpers.pixel = 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAA' + 31 | 'AAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA=='; 32 | 33 | helpers.username = auth[0]; 34 | helpers.password = auth[1]; 35 | 36 | helpers.loadFixture = function helpersLoadFixture(filename, json) { 37 | var contents = fs.readFileSync( 38 | path.join(__dirname, '..', 'fixtures', filename), (json ? 'ascii' : null)); 39 | return json ? JSON.parse(contents) : contents; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /tests/helpers/integration.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var debug = require('debug'); 17 | var path = require('path'); 18 | var harness = require('tape-it'); 19 | var endsWith = require('endswith'); 20 | var cfg = require('../fixtures/cfg'); 21 | var nano = require('../../lib/nano'); 22 | var helpers = require('./'); 23 | 24 | helpers.setup = function() { 25 | var self = this; 26 | var args = Array.prototype.slice.call(arguments); 27 | 28 | return function(assert) { 29 | args.push(function(err) { 30 | assert.equal(err, null, 'create database'); 31 | assert.end(); 32 | }); 33 | 34 | self.nano.db.create.apply(this, args); 35 | }; 36 | }; 37 | 38 | helpers.teardown = function() { 39 | var self = this; 40 | var args = Array.prototype.slice.call(arguments); 41 | 42 | return function(assert) { 43 | args.push(function(err) { 44 | assert.equal(err, null, 'destroy database'); 45 | assert.ok(self.mock.isDone(), 'mocks didn\'t run'); 46 | assert.end(); 47 | }); 48 | 49 | self.nano.db.destroy.apply(this, args); 50 | }; 51 | }; 52 | 53 | helpers.harness = function(name, setup, teardown) { 54 | var parent = name || module.parent.filename; 55 | var fileName = path.basename(parent).split('.')[0]; 56 | var parentDir = path.dirname(parent) 57 | .split(path.sep).reverse()[0]; 58 | var shortPath = path.join(parentDir, fileName); 59 | var log = debug(path.join('nano', 'tests', 'integration', shortPath)); 60 | var dbName = shortPath.replace('/', '_'); 61 | var nanoLog = nano({ 62 | url: cfg.couch, 63 | log: log 64 | }); 65 | 66 | var mock = helpers.nock(helpers.couch, shortPath, log); 67 | var db = nanoLog.use(dbName); 68 | var locals = { 69 | mock: mock, 70 | db: db, 71 | nano: nanoLog 72 | }; 73 | 74 | return harness({ 75 | id: shortPath, 76 | timeout: helpers.timeout, 77 | checkLeaks: !!process.env.LEAKS, 78 | locals: locals, 79 | setup: setup ? setup : helpers.setup.call(locals, dbName), 80 | teardown: teardown ? teardown : helpers.teardown.call(locals, dbName) 81 | }); 82 | }; 83 | 84 | helpers.nock = function helpersNock(url, fixture, log) { 85 | var nock = require('nock'); 86 | var nockDefs = require('../fixtures/' + fixture + '.json'); 87 | 88 | nockDefs.forEach(function(n) { 89 | var headers = n.headers || {}; 90 | var response = n.buffer ? endsWith(n.buffer, '.png') ? 91 | helpers.loadFixture(n.buffer) : new Buffer(n.buffer, 'base64') : 92 | n.response || ''; 93 | var body = n.base64 ? new Buffer(n.base64, 'base64').toString() : 94 | n.body || ''; 95 | 96 | if (typeof headers === 'string' && endsWith(headers, '.json')) { 97 | headers = require(path.join(fixture, headers)); 98 | } 99 | 100 | n.method = n.method || 'get'; 101 | n.options = {log: log}; 102 | n.scope = url; 103 | n.headers = headers; 104 | n.response = response; 105 | n.body = body; 106 | 107 | return n; 108 | }); 109 | 110 | nock.define(nockDefs); 111 | 112 | return nock(url); 113 | }; 114 | 115 | helpers.prepareAView = function(assert, search, db) { 116 | search = search || ''; 117 | db = db || this.db; 118 | 119 | db.insert({ 120 | views: { 121 | by_name_and_city: { 122 | map: 'function(doc) { emit([doc.name, doc.city], doc._id); }' 123 | } 124 | }, 125 | lists: { 126 | 'my_list': 'function(head, req) { send(\'Hello\'); }' 127 | } 128 | }, '_design/people' + search, function(error, response) { 129 | assert.equal(error, null, 'should create view'); 130 | assert.equal(response.ok, true, 'response is good'); 131 | async.parallel([ 132 | function(cb) { 133 | db.insert({ 134 | name: 'Derek', 135 | city: 'San Francisco' 136 | }, 'p_derek', cb); 137 | }, function(cb) { 138 | db.insert({ 139 | name: 'Randall', 140 | city: 'San Francisco' 141 | }, 'p_randall', cb); 142 | }, function(cb) { 143 | db.insert({ 144 | name: 'Nuno', 145 | city: 'London' 146 | }, 'p_nuno', cb); 147 | } 148 | ], function(error) { 149 | assert.equal(error, undefined, 'store the peeps'); 150 | assert.end(); 151 | }); 152 | }); 153 | }; 154 | 155 | helpers.viewDerek = function viewDerek(db, assert, opts, next, method) { 156 | method = method || 'view'; 157 | db[method]('people','by_name_and_city', opts, function(error, view) { 158 | assert.equal(error, null, 'no errors'); 159 | assert.equal(view.rows.length,1); 160 | assert.equal(view.rows.length,1); 161 | assert.equal(view.rows[0].id,'p_derek'); 162 | assert.equal(view.rows[0].key[0],'Derek'); 163 | assert.equal(view.rows[0].key[1],'San Francisco'); 164 | next(error); 165 | }); 166 | }; 167 | 168 | helpers.insertOne = function insertThree(assert) { 169 | var db = this.db; 170 | db.insert({'foo': 'baz'}, 'foobaz', function(err) { 171 | assert.equal(err, null, 'should store docs'); 172 | assert.end(); 173 | }); 174 | }; 175 | 176 | helpers.insertThree = function insertThree(assert) { 177 | var db = this.db; 178 | async.parallel([ 179 | function(cb) { db.insert({'foo': 'bar'}, 'foobar', cb); }, 180 | function(cb) { db.insert({'bar': 'foo'}, 'barfoo', cb); }, 181 | function(cb) { db.insert({'foo': 'baz'}, 'foobaz', cb); } 182 | ], function(error) { 183 | assert.equal(error, undefined, 'should store docs'); 184 | assert.end(); 185 | }); 186 | }; 187 | 188 | helpers.unmocked = (process.env.NOCK_OFF === 'true'); 189 | helpers.mocked = !helpers.unmocked; 190 | 191 | module.exports = helpers; 192 | 193 | -------------------------------------------------------------------------------- /tests/helpers/unit.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('./'); 16 | var Client = require('../../lib/nano'); 17 | var test = require('tape'); 18 | var _ = require('underscore'); 19 | 20 | helpers.unit = function(method, error) { 21 | var unitName = 'nano/tests/unit/' + method.join('/'); 22 | var debug = require('debug')(unitName); 23 | 24 | function log(data) { 25 | debug({ got: data.body }); 26 | } 27 | 28 | var cli = helpers.mockClientOk(log, error); 29 | 30 | // 31 | // allow database creation and other server stuff 32 | // 33 | if(method[1].match(/follow/)) { 34 | if(method[0] === 'database') { 35 | cli.server = helpers.mockClientFollow(log, error); 36 | } else { 37 | cli = helpers.mockClientFollow(log, error); 38 | } 39 | } else { 40 | cli.server = helpers.mockClientDb(log, error); 41 | } 42 | 43 | var testNr = 1; 44 | 45 | return function() { 46 | var args = Array.prototype.slice.call(arguments); 47 | var stub = args.pop(); 48 | 49 | test(unitName + ':' + testNr++, 50 | function(assert) { 51 | var f; 52 | assert.ok(typeof stub, 'object'); 53 | 54 | // 55 | // document functions and database functions 56 | // are at the top level in nano 57 | // 58 | if(method[0] === 'database') { 59 | f = cli.server.db[method[1]]; 60 | } else if(method[0] === 'view' && method[1] === 'compact') { 61 | f = cli.view.compact; 62 | } else if(!~['multipart', 'attachment'].indexOf(method[0])) { 63 | f = cli[method[1]]; 64 | } else { 65 | f = cli[method[0]][method[1]]; 66 | } 67 | assert.ok(typeof f, 'function'); 68 | 69 | args.push(function(err, req, response) { 70 | if (error) { 71 | assert.ok(err); 72 | return assert.end(); 73 | } 74 | 75 | assert.equal(response.statusCode, 200); 76 | if(stub.uri) { 77 | stub.uri = helpers.couch + stub.uri; 78 | } else { 79 | stub.db = helpers.couch + stub.db; 80 | } 81 | 82 | assert.deepEqual(req, stub); 83 | assert.end(); 84 | }); 85 | 86 | f.apply(null, args); 87 | }); 88 | }; 89 | }; 90 | 91 | function mockClient(code, path, extra) { 92 | return function(debug, error) { 93 | extra = extra || {}; 94 | var opts = _.extend(extra, { 95 | url: helpers.couch + path, 96 | log: debug, 97 | request: function(req, cb) { 98 | if(error) { 99 | return cb(error); 100 | } 101 | 102 | if(code === 500) { 103 | cb(new Error('omg connection failed')); 104 | } else { 105 | cb(null, { 106 | statusCode: code, 107 | headers: {} 108 | }, req); } 109 | } 110 | }); 111 | 112 | return Client(opts); 113 | }; 114 | } 115 | 116 | function mockClientUnparsedError() { 117 | return function(debug, body) { 118 | return Client({ 119 | url: helpers.couch, 120 | log: debug, 121 | request: function(_, cb) { 122 | return cb(null, {statusCode: 500}, body || ' Error happened '); 123 | } 124 | }); 125 | }; 126 | } 127 | 128 | function mockClientFollow() { 129 | return function(debug, error) { 130 | return Client({ 131 | url: helpers.couch, 132 | log: debug, 133 | follow: function(qs, cb) { 134 | if(error) { 135 | return cb(error); 136 | } 137 | 138 | return cb(null, qs, {statusCode: 200}); 139 | } 140 | }); 141 | }; 142 | } 143 | 144 | 145 | helpers.mockClientFollow = mockClientFollow(); 146 | helpers.mockClientUnparsedError = mockClientUnparsedError(); 147 | helpers.mockClientDb = mockClient(200, ''); 148 | helpers.mockClientOk = mockClient(200, '/mock'); 149 | helpers.mockClientFail = mockClient(500, ''); 150 | helpers.mockClientJar = mockClient(300, '', {jar: 'is set'}); 151 | module.exports = helpers; 152 | -------------------------------------------------------------------------------- /tests/integration/attachment/destroy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should be able to insert a new plain text attachment', function(assert) { 21 | db.attachment.insert('new', 22 | 'att', 'Hello World!', 'text/plain', function(error, att) { 23 | assert.equal(error, null, 'store the attachment'); 24 | assert.equal(att.ok, true, 'response ok'); 25 | assert.ok(att.rev, 'have a revision number'); 26 | db.attachment.destroy('new', 'att', {rev: att.rev}, 27 | function(error, response) { 28 | assert.equal(error, null, 'delete the attachment'); 29 | assert.equal(response.ok, true, 'response ok'); 30 | assert.equal(response.id, 'new', '`id` should be `new`'); 31 | assert.end(); 32 | }); 33 | }); 34 | }); 35 | 36 | it('should fail destroying with a bad filename', function(assert) { 37 | db.attachment.destroy('new', false, true, function(error, response) { 38 | assert.equal(response, undefined, 'no response should be given'); 39 | assert.end(); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/integration/attachment/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should be able to fetch an attachment', function(assert) { 21 | db.attachment.insert('new_string', 'att', 'Hello', 'text/plain', 22 | function(error, hello) { 23 | assert.equal(error, null, 'should store `hello`'); 24 | assert.equal(hello.ok, true, 'response ok'); 25 | assert.ok(hello.rev, 'should have a revision number'); 26 | db.attachment.get('new_string', 'att', 27 | function(error, helloWorld) { 28 | assert.equal(error, null, 'should get `hello`'); 29 | assert.equal('Hello', helloWorld.toString(), 'string is reflexive'); 30 | assert.end(); 31 | }); 32 | }); 33 | }); 34 | 35 | it('should insert and fetch a binary file', function(assert) { 36 | db.attachment.insert('new_binary', 'att', new Buffer('123'), 37 | 'text/plain', function(error, hello) { 38 | assert.equal(error, null, 'should store `123`'); 39 | assert.equal(hello.ok, true, 'response ok'); 40 | assert.ok(hello.rev, 'should have a revision number'); 41 | db.attachment.get('new_binary', 'att', 42 | function(error, binaryData) { 43 | assert.equal(error, null, 'should get the binary data'); 44 | assert.equal('123', binaryData.toString(), 'binary data is reflexive'); 45 | assert.end(); 46 | }); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /tests/integration/attachment/insert.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should be able to insert a simple attachment', function(assert) { 21 | db.attachment.insert('new', 'att', 'Hello World!', 'text/plain', 22 | function(error, att) { 23 | assert.equal(error, null, 'should store the attachment'); 24 | assert.equal(att.ok, true, 'response ok'); 25 | assert.ok(att.rev, 'should have a revision'); 26 | assert.end(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tests/integration/attachment/pipe.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var fs = require('fs'); 16 | var path = require('path'); 17 | var helpers = require('../../helpers/integration'); 18 | var harness = helpers.harness(__filename); 19 | var db = harness.locals.db; 20 | var it = harness.it; 21 | var pixel = helpers.pixel; 22 | 23 | it('should be able to pipe to a writeStream', function(assert) { 24 | var buffer = new Buffer(pixel, 'base64'); 25 | var filename = path.join(__dirname, '.temp.bmp'); 26 | var ws = fs.createWriteStream(filename); 27 | 28 | ws.on('close', function() { 29 | assert.equal(fs.readFileSync(filename).toString('base64'), pixel); 30 | fs.unlinkSync(filename); 31 | assert.end(); 32 | }); 33 | 34 | db.attachment.insert('new', 'att', buffer, 'image/bmp', 35 | function(error, bmp) { 36 | assert.equal(error, null, 'Should store the pixel'); 37 | db.attachment.get('new', 'att', {rev: bmp.rev}).pipe(ws); 38 | }); 39 | }); 40 | 41 | it('should be able to pipe from a readStream', function(assert) { 42 | var logo = path.join(__dirname, '..', '..', 'fixtures', 'logo.png'); 43 | var rs = fs.createReadStream(logo); 44 | var is = db.attachment.insert('nodejs', 'logo.png', null, 'image/png'); 45 | 46 | is.on('end', function() { 47 | db.attachment.get('nodejs', 'logo.png', function(err, buffer) { 48 | assert.equal(err, null, 'should get the logo'); 49 | assert.equal( 50 | fs.readFileSync(logo).toString('base64'), buffer.toString('base64'), 51 | 'logo should remain unchanged'); 52 | assert.end(); 53 | }); 54 | }); 55 | 56 | rs.pipe(is); 57 | }); 58 | -------------------------------------------------------------------------------- /tests/integration/attachment/update.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var pixel = helpers.pixel; 17 | var harness = helpers.harness(__filename); 18 | var db = harness.locals.db; 19 | var it = harness.it; 20 | 21 | var rev; 22 | 23 | it('should be able to insert and update attachments', function(assert) { 24 | var buffer = new Buffer(pixel, 'base64'); 25 | db.attachment.insert('new', 'att', 'Hello', 'text/plain', 26 | function(error, hello) { 27 | assert.equal(error, null, 'should store hello'); 28 | assert.equal(hello.ok, true, 'response ok'); 29 | assert.ok(hello.rev, 'should have a revision'); 30 | db.attachment.insert('new', 'att', buffer, 'image/bmp', 31 | {rev: hello.rev}, function(error, bmp) { 32 | assert.equal(error, null, 'should store the pixel'); 33 | assert.ok(bmp.rev, 'should store a revision'); 34 | rev = bmp.rev; 35 | assert.end(); 36 | }); 37 | }); 38 | }); 39 | 40 | it('should be able to fetch the updated pixel', function(assert) { 41 | db.get('new', function(error, newDoc) { 42 | assert.equal(error, null, 'should get new'); 43 | newDoc.works = true; 44 | db.insert(newDoc, 'new', function(error, response) { 45 | assert.equal(error, null, 'should update doc'); 46 | assert.equal(response.ok, true, 'response ok'); 47 | assert.end(); 48 | }); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /tests/integration/database/changes.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should be able to insert three documents', helpers.insertThree); 21 | 22 | it('should be able to receive changes since seq:2', function(assert) { 23 | db.changes({since:2}, function(error, response) { 24 | assert.equal(error, null, 'gets response from changes'); 25 | assert.equal(response.results.length, 1, 'gets one result'); 26 | assert.equal(response['last_seq'], 3, 'seq is 3'); 27 | assert.end(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/integration/database/compact.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should store and delete `goofy`', function(assert) { 21 | db.insert({'foo': 'baz'}, 'goofy', function(error, foo) { 22 | assert.equal(error, null, 'should have stored foo'); 23 | assert.equal(foo.ok, true, 'response should be ok'); 24 | db.destroy('goofy', foo.rev, function(error, response) { 25 | assert.equal(error, null, 'should have deleted foo'); 26 | assert.equal(response.ok, true, 'response ok'); 27 | assert.end(); 28 | }); 29 | }); 30 | }); 31 | 32 | it('should have run the compaction', function(assert) { 33 | db.compact(function(error) { 34 | assert.equal(error, null, 'compact should respond'); 35 | db.info(function(error, info) { 36 | assert.equal(error, null, 'info should respond'); 37 | assert.equal(info['doc_count'], 0, 'document count is not 3'); 38 | assert.equal(info['doc_del_count'], 1, 'document should be deleted'); 39 | assert.equal(info['update_seq'], 2, 'seq is two'); 40 | assert.end(); 41 | }); 42 | }); 43 | }); 44 | 45 | it('should finish compaction before ending', function(assert) { 46 | function nextWhenFinished() { 47 | db.info(function(err, info) { 48 | if (err) { 49 | return; 50 | } 51 | if (info['compact_running']) { 52 | return; 53 | } 54 | clearTimeout(task); 55 | assert.pass('compaction is complete'); 56 | assert.end(); 57 | }); 58 | } 59 | 60 | var task = setInterval(nextWhenFinished, 100); 61 | }); 62 | -------------------------------------------------------------------------------- /tests/integration/database/create-and-destroy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var nano = harness.locals.nano; 20 | 21 | it('should be able to create `az09_$()+-/` database', function(assert) { 22 | nano.db.create('az09_$()+-/', function(err) { 23 | assert.equal(err, null, 'should create database'); 24 | assert.end(); 25 | }); 26 | }); 27 | 28 | it('should be able to use config from a nano object to create a db', 29 | function(assert) { 30 | var config = helpers.Nano( 31 | helpers.couch + '/' + encodeURIComponent('with/slash')).config; 32 | helpers.Nano(config.url).db.create(config.db, function(err) { 33 | assert.equal(err, null, 'should create database'); 34 | assert.end(); 35 | }); 36 | }); 37 | 38 | it('must destroy the databases we created', function(assert) { 39 | async.forEach(['az09_$()+-/', 'with/slash'], nano.db.destroy, function(err) { 40 | assert.equal(err, undefined, 'should destroy all dbs'); 41 | assert.end(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/integration/database/follow.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | if (helpers.unmocked) { 21 | it('should insert a bunch of items', helpers.insertThree); 22 | 23 | var feed1; 24 | 25 | it('should be able to get the changes feed', function(assert) { 26 | var i = 3; 27 | 28 | feed1 = db.follow({since: 3}); 29 | 30 | feed1.on('change', function(change) { 31 | assert.ok(change, 'change existed'); 32 | assert.equal(change.seq, i + 1, 'seq is set correctly'); 33 | ++i; 34 | if (i === 4) { 35 | console.log(change, i); 36 | assert.end(); 37 | } 38 | }); 39 | 40 | feed1.follow(); 41 | 42 | setTimeout(function() { 43 | db.insert({'bar': 'baz'}, 'barbaz'); 44 | }, 100); 45 | }); 46 | 47 | it('should see changes since `seq:3`', function(assert) { 48 | var feed = db.follow({since: 3}, function(error, change) { 49 | assert.equal(error, null, 'should not have errors'); 50 | assert.ok(change, 'change existed'); 51 | feed.die(); 52 | feed1.die(); 53 | process.nextTick(assert.end); 54 | }); 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /tests/integration/database/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var nano = harness.locals.nano; 19 | 20 | it('should be able to fetch the database', function(assert) { 21 | nano.db.get('database_get', function(error, response) { 22 | assert.equal(error, null, 'should get the db'); 23 | assert.equal(response['doc_count'], 0, 'should be empty'); 24 | assert.equal(response['db_name'], 'database_get', 'name'); 25 | assert.end(); 26 | }); 27 | }); 28 | 29 | it('resolves db URL correctly for http://app.com/_couchdb', function(assert) { 30 | var nano = require('../../../lib/nano'); 31 | 32 | var couch = nano({ 33 | url: 'http://app.com/_couchdb/', 34 | parseUrl: false, 35 | request: function(options) { 36 | assert.equal( 37 | options.uri, 38 | 'http://app.com/_couchdb/mydb/mydoc', 39 | 'should get doc at prefixed path' 40 | ); 41 | assert.end(); 42 | } 43 | }); 44 | couch.use('mydb').get('mydoc'); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/integration/database/list.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var nano = harness.locals.nano; 19 | 20 | it('should list the correct databases', function(assert) { 21 | nano.db.list(function(error, list) { 22 | assert.equal(error, null, 'should list databases'); 23 | var filtered = list.filter(function(e) { 24 | return e === 'database_list' || e === '_replicator' || e === '_users'; 25 | }); 26 | assert.equal(filtered.length, 3, 'should have exactly 3 dbs'); 27 | assert.end(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/integration/database/replicate.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var db = harness.locals.db; 20 | var nano = harness.locals.nano; 21 | 22 | var replica; 23 | var replica2; 24 | 25 | it('should insert a bunch of items', helpers.insertThree); 26 | 27 | it('creates a bunch of database replicas', function(assert) { 28 | async.forEach(['database_replica', 'database_replica2'], 29 | nano.db.create, function(error) { 30 | assert.equal(error, undefined, 'created database(s)'); 31 | assert.end(); 32 | }); 33 | }); 34 | 35 | it('should be able to replicate three docs', function(assert) { 36 | replica = nano.use('database_replica'); 37 | 38 | db.replicate('database_replica', function(error) { 39 | assert.equal(error, null, 'replication should work'); 40 | replica.list(function(error, list) { 41 | assert.equal(error, null, 'should be able to invoke list'); 42 | assert.equal(list['total_rows'], 3, 'and have three documents'); 43 | assert.end(); 44 | }); 45 | }); 46 | }); 47 | 48 | it('should be able to replicate to a `nano` object', function(assert) { 49 | replica2 = nano.use('database_replica2'); 50 | 51 | nano.db.replicate(db, replica2, function(error) { 52 | assert.equal(error, null, 'should replicate'); 53 | replica2.list(function(error, list) { 54 | assert.equal(error, null, 'should list'); 55 | assert.equal(list['total_rows'], 3, 'and have three documents'); 56 | assert.end(); 57 | }); 58 | }); 59 | }); 60 | 61 | it('should be able to replicate with params', function(assert) { 62 | db.replicate('database_replica', {}, function(error) { 63 | assert.equal(error, null, 'replication should work'); 64 | assert.end(); 65 | }); 66 | }); 67 | 68 | it('should destroy the extra databases', function(assert) { 69 | async.forEach(['database_replica', 'database_replica2'], 70 | nano.db.destroy, function(error) { 71 | assert.equal(error, undefined, 'deleted databases'); 72 | assert.end(); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /tests/integration/design/atomic.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | var rev; 21 | 22 | it('should be able to insert an atomic design doc', function(assert) { 23 | db.insert({ 24 | updates: { 25 | inplace: function(doc, req) { 26 | var body = JSON.parse(req.body); 27 | doc[body.field] = body.value; 28 | return [doc, JSON.stringify(doc)]; 29 | }, 30 | addbaz: function (doc, req) { 31 | doc.baz = "biz"; 32 | return [doc, JSON.stringify(doc)]; 33 | } 34 | } 35 | }, '_design/update', function(err) { 36 | assert.equal(err, null, 'should be no problems officer'); 37 | db.insert({'foo': 'baz'}, 'foobar', function(error, foo) { 38 | assert.equal(error, null, 'stores teh foo'); 39 | assert.equal(foo.ok, true, 'does not have an attitude'); 40 | assert.ok(foo.rev, 'got the revisions'); 41 | rev = foo.rev; 42 | assert.end(); 43 | }); 44 | }); 45 | }); 46 | 47 | it('should be able to insert atomically', function(assert) { 48 | db.atomic('update', 'inplace', 'foobar', { 49 | field: 'foo', 50 | value: 'bar' 51 | }, function(error, response) { 52 | assert.equal(error, null, 'should be able to update'); 53 | assert.equal(response.foo, 'bar', 'and the right value was set'); 54 | assert.end(); 55 | }); 56 | }); 57 | 58 | it('should be able to update atomically without a body', function (assert) { 59 | db.insert({}, 'baz', function (error, doc) { 60 | db.atomic('update', 'addbaz', 'baz', function (error, response) { 61 | assert.equal(error, null, 'should be able to update'); 62 | assert.equal(response.baz, 'biz', 'and the new field is present'); 63 | assert.end(); 64 | }); 65 | }); 66 | }); 67 | 68 | it('should be able to update with slashes on the id', function(assert) { 69 | db.insert({'wat': 'wat'}, 'wat/wat', function(error, foo) { 70 | assert.equal(error, null, 'stores `wat`'); 71 | assert.equal(foo.ok, true, 'response ok'); 72 | db.atomic('update', 'inplace', 'wat/wat', { 73 | field: 'wat', 74 | value: 'dawg' 75 | }, function(error, response) { 76 | assert.equal(error, null, 'should update'); 77 | assert.equal(response.wat, 'dawg', 'with the right copy'); 78 | assert.end(); 79 | }); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /tests/integration/design/compact.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var db = harness.locals.db; 20 | 21 | it('should insert `alice` the design doc', function(assert) { 22 | async.waterfall([ 23 | function(next) { 24 | db.insert({ 25 | views: { 26 | 'by_id': { 27 | map: 'function(doc) { emit(doc._id, doc); }' 28 | } 29 | } 30 | }, '_design/alice', next); 31 | }, 32 | function(data, _, next) { 33 | db.insert({'foo': 'baz'}, 'foobaz', next); 34 | }, 35 | function(foo, _, next) { 36 | db.destroy('foobaz', foo.rev, next); 37 | } 38 | ], function(err) { 39 | assert.equal(err, null, 'it should destroy the foo'); 40 | assert.end(); 41 | }); 42 | }); 43 | 44 | it('should be able to compact a view', function(assert) { 45 | async.waterfall([ 46 | function(next) { 47 | db.view.compact('alice', next); 48 | }, 49 | function(response, _, next) { 50 | function dbInfo() { 51 | db.info(function(err, info) { 52 | if (!info['compact_running']) { 53 | clearInterval(task); 54 | next(); 55 | } 56 | }); 57 | } 58 | var task = setInterval(dbInfo, 50); 59 | }, 60 | function(next) { 61 | db.view('alice', 'by_id', next); 62 | } 63 | ], function(err, view) { 64 | assert.equal(err, null, 'should be able to call the view'); 65 | assert.equal(view['total_rows'], 0, 'and see stuff got deleted'); 66 | assert.end(); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /tests/integration/design/list.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should create a ddoc and insert some docs', helpers.prepareAView); 21 | 22 | it('should get the people by running the ddoc', function(assert) { 23 | db.viewWithList('people', 'by_name_and_city', 'my_list', { 24 | key: [ 25 | 'Derek', 26 | 'San Francisco' 27 | ] 28 | }, function(error, list) { 29 | assert.equal(error, null, 'should response'); 30 | assert.equal(list, 'Hello', 'and list should be `hello`'); 31 | assert.end(); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/integration/design/multiple.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should be able to insert docs and design doc', function(assert) { 21 | db.insert({ 22 | views: { 23 | 'by_id': { 24 | map: 'function(doc) { emit(doc._id, doc); }' 25 | } 26 | } 27 | }, '_design/alice', function(error, response) { 28 | assert.equal(error, null, 'should create views'); 29 | assert.equal(response.ok, true, 'response ok'); 30 | assert.end(); 31 | }); 32 | }); 33 | 34 | it('should insert a bunch of items', helpers.insertThree); 35 | 36 | it('get multiple docs with a composed key', function(assert) { 37 | db.view('alice', 'by_id', { 38 | keys: ['foobar', 'barfoo'], 39 | 'include_docs': true 40 | }, function(err, view) { 41 | assert.equal(err, null, 'should response'); 42 | assert.equal(view.rows.length, 2, 'has more or less than two rows'); 43 | assert.equal(view.rows[0].id, 'foobar', 'foo is not the first id'); 44 | assert.equal(view.rows[1].id, 'barfoo', 'bar is not the second id'); 45 | assert.end(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /tests/integration/design/query.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var db = harness.locals.db; 20 | var viewDerek = helpers.viewDerek; 21 | 22 | var opts = {key: ['Derek', 'San Francisco']}; 23 | 24 | it('should create a ddoc and insert some docs', helpers.prepareAView); 25 | 26 | it('should respond with derek when asked for derek', function(assert) { 27 | viewDerek(db, assert, opts, assert.end); 28 | }); 29 | 30 | it('should have no cloning issues when doing queries', function(assert) { 31 | async.waterfall([ 32 | function(next) { viewDerek(db, assert, opts, next); }, 33 | function(next) { viewDerek(db, assert, opts, next); } 34 | ], function(err) { 35 | assert.equal(err, null, 'no errors'); 36 | assert.ok(Array.isArray(opts.key)); 37 | assert.equal(opts.key[0], 'Derek'); 38 | assert.equal(opts.key[1], 'San Francisco'); 39 | assert.end(); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/integration/design/search.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var db = harness.locals.db; 20 | var viewDerek = helpers.viewDerek; 21 | 22 | // 23 | // these are cloudant only 24 | // tests do no run without mocks 25 | // 26 | if (helpers.mocked) { 27 | var opts = {key: ['Derek', 'San Francisco']}; 28 | 29 | it('should create a ddoc and insert some docs', function(assert) { 30 | helpers.prepareAView(assert, '/_search', db); 31 | }); 32 | 33 | it('should respond with derek when asked for derek', function(assert) { 34 | viewDerek(db, assert, opts, assert.end, 'search'); 35 | }); 36 | 37 | it('should have no cloning issues when doing queries', function(assert) { 38 | async.waterfall([ 39 | function(next) { viewDerek(db, assert, opts, next, 'search'); }, 40 | function(next) { viewDerek(db, assert, opts, next, 'search'); } 41 | ], function(err) { 42 | assert.equal(err, null, 'no errors'); 43 | assert.ok(Array.isArray(opts.key)); 44 | assert.equal(opts.key[0], 'Derek'); 45 | assert.equal(opts.key[1], 'San Francisco'); 46 | assert.end(); 47 | }); 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /tests/integration/design/show.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var async = require('async'); 16 | var helpers = require('../../helpers/integration'); 17 | var harness = helpers.harness(__filename); 18 | var it = harness.it; 19 | var db = harness.locals.db; 20 | 21 | it('should insert a show ddoc', function(assert) { 22 | db.insert({ 23 | shows: { 24 | singleDoc: function(doc, req) { 25 | if (req.query.format === 'json' || !req.query.format) { 26 | return { 27 | body: JSON.stringify({ 28 | name: doc.name, 29 | city: doc.city, 30 | format: 'json' 31 | }), 32 | headers: { 33 | 'Content-Type': 'application/json' 34 | } 35 | }; 36 | } 37 | if (req.query.format === 'html') { 38 | return { 39 | body: 'Hello Clemens!', 40 | headers: { 41 | 'Content-Type': 'text/html' 42 | } 43 | }; 44 | } 45 | } 46 | } 47 | }, '_design/people', function(error, response) { 48 | assert.equal(error, null, 'should start the show'); 49 | assert.equal(response.ok, true, 'response ok'); 50 | async.parallel([ 51 | function(cb) { 52 | db.insert({ 53 | name: 'Clemens', 54 | city: 'Dresden' 55 | }, 'p_clemens', cb); 56 | }, 57 | function(cb) { 58 | db.insert({ 59 | name: 'Randall', 60 | city: 'San Francisco' 61 | }, 'p_randall', cb); 62 | }, function(cb) { 63 | db.insert({ 64 | name: 'Nuno', 65 | city: 'New York' 66 | }, 'p_nuno', cb); 67 | } 68 | ], function(error) { 69 | assert.equal(error, undefined, 'stores docs'); 70 | assert.end(); 71 | }); 72 | }); 73 | }); 74 | 75 | it('should show the amazing clemens in json', function(assert) { 76 | db.show('people', 'singleDoc', 'p_clemens', function(error, doc, rh) { 77 | assert.equal(error, null, 'its alive'); 78 | assert.equal(rh['content-type'], 'application/json'); 79 | assert.equal(doc.name, 'Clemens'); 80 | assert.equal(doc.city, 'Dresden'); 81 | assert.equal(doc.format, 'json'); 82 | assert.end(); 83 | }); 84 | }); 85 | 86 | it('should show the amazing clemens in html', function(assert) { 87 | db.show('people', 'singleDoc', 'p_clemens', {format: 'html'}, 88 | function(error, doc, rh) { 89 | assert.equal(error, null, 'should work'); 90 | assert.equal(rh['content-type'], 'text/html'); 91 | assert.equal(doc, 'Hello Clemens!'); 92 | assert.end(); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /tests/integration/document/bulk.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('should be able to bulk insert two docs', function(assert) { 21 | db.bulk({ 22 | 'docs': [ 23 | {'key':'baz', 'name':'bazzel'}, 24 | {'key':'bar', 'name':'barry'} 25 | ] 26 | }, 27 | function(error, response) { 28 | assert.equal(error, null, 'no error'); 29 | assert.equal(response.length, 2, 'has two docs'); 30 | assert.ok(response[0].id, 'first got id'); 31 | assert.ok(response[1].id, 'other also got id'); 32 | assert.end(); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/integration/document/copy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | it('must insert two docs before the tests start', function(assert) { 21 | db.insert({'foo': 'baz'}, 'foo_src', function(error, src) { 22 | assert.equal(error, null, 'stores src'); 23 | assert.equal(src.ok, true, 'response ok'); 24 | assert.ok(src.rev, 'haz rev'); 25 | db.insert({'bar': 'qux'}, 'foo_dest', function(error, dest) { 26 | assert.equal(error, null, 'stores dest'); 27 | assert.equal(dest.ok, true, 'oki doki'); 28 | assert.ok(dest.rev, 'response has rev'); 29 | assert.end(); 30 | }); 31 | }); 32 | }); 33 | 34 | it('should be able to copy and overwrite a document', function(assert) { 35 | db.copy('foo_src', 'foo_dest', {overwrite: true}, 36 | function(error, response, headers) { 37 | assert.equal(error, null, 38 | 'should have copied and overwritten foo_src to foo_dest'); 39 | assert.equal(headers['statusCode'], 201, 'status code should be 201'); 40 | assert.end(); 41 | }); 42 | }); 43 | 44 | it('copy without overwrite should return conflict for exists docs', 45 | function(assert) { 46 | db.copy('foo_src', 'foo_dest', function(error) { 47 | assert.equal(error.error, 'conflict', 'should be a conflict'); 48 | assert.end(); 49 | }); 50 | }); 51 | 52 | it('copy to a new destination should work', function(assert) { 53 | db.copy('foo_src', 'baz_dest', function(error, response, headers) { 54 | assert.equal(error, null, 'copies into new document'); 55 | assert.equal(headers['statusCode'], 201, 'Status code should be 201'); 56 | assert.end(); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/integration/document/destroy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var it = harness.it; 18 | var db = harness.locals.db; 19 | 20 | var rev; 21 | 22 | it('should insert a document', function(assert) { 23 | db.insert({'foo': 'baz'}, 'foobaz', function(error, foo) { 24 | assert.equal(error, null, 'stores foo'); 25 | assert.equal(foo.ok, true, 'ok response'); 26 | assert.ok(foo.rev, 'response with rev'); 27 | rev = foo.rev; 28 | assert.end(); 29 | }); 30 | }); 31 | 32 | it('should not delete a db', function(assert) { 33 | db.destroy(undefined, undefined, function(error, response) { 34 | assert.equal(error, 'Invalid doc id', 'validated delete parameters'); 35 | assert.equal(response, null, 'ok!'); 36 | assert.end(); 37 | }); 38 | }); 39 | 40 | it('should delete a document', function(assert) { 41 | db.destroy('foobaz', rev, function(error, response) { 42 | assert.equal(error, null, 'deleted foo'); 43 | assert.equal(response.ok, true, 'ok!'); 44 | assert.end(); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/integration/document/fetch.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should insert a bunch of items', helpers.insertThree); 21 | 22 | it('should be able to fetch with one key', function(assert) { 23 | db.fetch({keys:['foobar']}, function(error, docs) { 24 | assert.equal(error, null, 'should work'); 25 | assert.equal(docs.rows.length, 1, 'and get one row'); 26 | assert.equal(docs['total_rows'], 3, 'out of 3'); 27 | assert.end(); 28 | }); 29 | }); 30 | 31 | it('should be able to fetch with multiple keys', function(assert) { 32 | db.fetch({keys:['foobar', 'barfoo']}, function(error, docs) { 33 | assert.equal(error, null, 'no errors'); 34 | assert.equal(docs.rows.length, 2, 'two rows'); 35 | assert.equal(docs['total_rows'], 3, 'out of 3'); 36 | assert.end(); 37 | }); 38 | }); 39 | 40 | it('should be able to fetch with params', function(assert) { 41 | db.fetch({keys:['foobar']}, {not: 'important'}, function(error, docs) { 42 | assert.equal(error, null, 'should work'); 43 | assert.equal(docs.rows.length, 1, 'and get one row'); 44 | assert.equal(docs['total_rows'], 3, 'out of 3'); 45 | assert.end(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /tests/integration/document/fetch_revs.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should insert a bunch of items', helpers.insertThree); 21 | 22 | it('should be able to fetch with one key', function(assert) { 23 | db.fetchRevs({keys:['foobar']}, function(error, docs) { 24 | assert.equal(error, null, 'should work'); 25 | assert.equal(docs.rows.length, 1, 'and get one row'); 26 | assert.equal(docs['total_rows'], 3, 'out of 3'); 27 | assert.equal(docs.rows[0].doc, undefined, 'rev should not return key'); 28 | assert.end(); 29 | }); 30 | }); 31 | 32 | it('should be able to fetch with multiple keys', function(assert) { 33 | db.fetchRevs({keys:['foobar', 'barfoo']}, function(error, docs) { 34 | assert.equal(error, null, 'it works'); 35 | assert.equal(docs.rows.length, 2, 'two rows'); 36 | assert.equal(docs['total_rows'], 3, 'out of 3'); 37 | assert.equal(docs.rows[0].doc, undefined, 'no doc in 1'); 38 | assert.equal(docs.rows[1].doc, undefined, 'no doc in 2'); 39 | assert.end(); 40 | }); 41 | }); 42 | 43 | it('should be able to fetch with params', function(assert) { 44 | db.fetchRevs({keys:['foobar']}, {still: 'no'}, function(error, docs) { 45 | assert.equal(error, null, 'should work'); 46 | assert.equal(docs.rows.length, 1, 'and get one row'); 47 | assert.equal(docs['total_rows'], 3, 'out of 3'); 48 | assert.equal(docs.rows[0].doc, undefined, 'rev should not return key'); 49 | assert.end(); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/integration/document/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should insert a one item', helpers.insertOne); 21 | 22 | it('should get the document', function(assert) { 23 | db.get('foobaz', {'revs_info': true}, function(error, foobaz) { 24 | assert.equal(error, null, 'should get foobaz'); 25 | assert.ok(foobaz['_revs_info'], 'got revs info'); 26 | assert.equal(foobaz._id, 'foobaz', 'id is food'); 27 | assert.equal(foobaz.foo, 'baz', 'baz is in foo'); 28 | assert.end(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/integration/document/head.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should insert a one item', helpers.insertOne); 21 | 22 | it('should get a status code when you do head', function(assert) { 23 | db.head('foobaz', function(error, body, headers) { 24 | assert.equal(error, null, 'should get the head of foobaz'); 25 | assert.equal(headers['statusCode'], 200, 'and is ok'); 26 | assert.end(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tests/integration/document/insert.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | var rev; 21 | 22 | it('should insert one simple document', function(assert) { 23 | db.insert({'foo': 'baz'}, 'foobaz', function(error, foo) { 24 | rev = foo.rev; 25 | assert.equal(error, null, 'should have stored foo'); 26 | assert.equal(foo.ok, true, 'response should be ok'); 27 | assert.ok(foo.rev, 'response should have rev'); 28 | assert.end(); 29 | }); 30 | }); 31 | 32 | it('should fail to insert again since it already exists', function(assert) { 33 | db.insert({}, 'foobaz', function(error) { 34 | assert.equal(error['statusCode'], 409, 'should be conflict'); 35 | assert.equal(error.scope, 'couch', 'scope is couch'); 36 | assert.equal(error.error, 'conflict', 'type is conflict'); 37 | assert.end(); 38 | }); 39 | }); 40 | 41 | it('should be able to use custom params in insert', function(assert) { 42 | db.insert({ 43 | foo: 'baz', 44 | _rev: rev 45 | }, { 46 | docName: 'foobaz', 47 | 'new_edits': false 48 | }, function(error, foo) { 49 | assert.equal(error, null, 'should have stored foo'); 50 | assert.equal(foo.ok, true, 'response should be ok'); 51 | assert.ok(foo.rev, 'response should have rev'); 52 | assert.end(); 53 | }); 54 | }); 55 | 56 | it('should be able to insert functions in docs', function(assert) { 57 | db.insert({ 58 | fn: function() { return true; }, 59 | fn2: 'function () { return true; }' 60 | }, function(error, fns) { 61 | assert.equal(error, null, 'should have stored foo'); 62 | assert.equal(fns.ok, true, 'response should be ok'); 63 | assert.ok(fns.rev, 'response should have rev'); 64 | db.get(fns.id, function(error, fns) { 65 | assert.equal(fns.fn, fns.fn2, 'fn matches fn2'); 66 | assert.equal(error, null, 'should get foo'); 67 | assert.end(); 68 | }); 69 | }); 70 | }); 71 | 72 | it('should be able to stream an insert', function(assert) { 73 | var buffer = ''; 74 | var foobar = db.insert({'foo': 'bar'}); 75 | 76 | function runAssertions(error, foobar) { 77 | assert.equal(error, null, 'should have stored foobar'); 78 | assert.ok(foobar.ok, 'this is ok'); 79 | assert.ok(foobar.rev, 'and i got revz'); 80 | assert.end(); 81 | } 82 | 83 | foobar.on('data', function(chunk) { buffer += chunk; }); 84 | foobar.on('end', function() { runAssertions(null, JSON.parse(buffer)); }); 85 | foobar.on('error', runAssertions); 86 | }); 87 | -------------------------------------------------------------------------------- /tests/integration/document/list.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var nano = harness.locals.nano; 19 | var it = harness.it; 20 | 21 | it('should insert a bunch of items', helpers.insertThree); 22 | 23 | it('should list the three documents', function(assert) { 24 | db.list(function(error, docs) { 25 | assert.equal(error, null, 'should get list'); 26 | assert.equal(docs['total_rows'], 3, 'with total three rows'); 27 | assert.ok(docs.rows, 'and the rows themselves'); 28 | assert.end(); 29 | }); 30 | }); 31 | 32 | it('should be able to list using the `relax` function', function(assert) { 33 | nano.relax({ 34 | db: 'document_list', 35 | doc: '_all_docs', 36 | method: 'GET', 37 | qs: {limit: 1} 38 | }, function(error, docs) { 39 | assert.equal(error, null, 'not relaxed'); 40 | assert.ok(docs.rows, 'got meh rows'); 41 | assert.equal(docs.rows.length, 1, 'but its only one #sadpanda'); 42 | assert.equal(docs['total_rows'], 3, 'out of three'); 43 | assert.end(); 44 | }); 45 | }); 46 | 47 | it('should be able to list with a startkey', function(assert) { 48 | db.list({startkey: 'c'}, function(error, docs) { 49 | assert.equal(error, null, 'should work'); 50 | assert.ok(docs.rows, 'get teh rows'); 51 | assert.equal(docs.rows.length, 2, 'starts in row two'); 52 | assert.equal(docs['total_rows'], 3, 'out of three rows'); 53 | assert.equal(docs.offset, 1, 'offset is 1'); 54 | assert.end(); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /tests/integration/document/update.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | var rev; 21 | 22 | it('should insert one doc', function(assert) { 23 | db.insert({'foo': 'baz'}, 'foobar', function(error, foo) { 24 | assert.equal(error, null, 'stored foo'); 25 | assert.equal(foo.ok, true, 'response ok'); 26 | assert.ok(foo.rev, 'withs rev'); 27 | rev = foo.rev; 28 | assert.end(); 29 | }); 30 | }); 31 | 32 | it('should update the document', function(assert) { 33 | db.insert({foo: 'bar', '_rev': rev}, 'foobar', function(error, response) { 34 | assert.equal(error, null, 'should have deleted foo'); 35 | assert.equal(response.ok, true, 'response should be ok'); 36 | assert.end(); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /tests/integration/multipart/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | var rev; 21 | 22 | it('should be able to insert a doc with att', function(assert) { 23 | var att = { 24 | name: 'att', 25 | data: 'Hello World!', 26 | 'content_type': 'text/plain' 27 | }; 28 | 29 | db.multipart.insert({'foo': 'baz'}, [att], 'foobaz', function(error, foo) { 30 | assert.equal(error, null, 'should have stored foobaz'); 31 | assert.equal(foo.ok, true, 'response should be ok'); 32 | assert.equal(foo.id, 'foobaz', 'id is foobaz'); 33 | assert.ok(foo.rev, 'has rev'); 34 | rev = foo.rev; 35 | assert.end(); 36 | }); 37 | }); 38 | 39 | it('should be able to get the document with the attachment', function(assert) { 40 | db.multipart.get('foobaz', function(error, foobaz, headers) { 41 | assert.equal(error, null, 'should get foobaz'); 42 | assert.ok(headers['content-type'], 'should have content type'); 43 | assert.equal(headers['content-type'].split(';')[0], 'multipart/related'); 44 | assert.equal(typeof foobaz, 'object', 'foobaz should be a buffer'); 45 | assert.end(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /tests/integration/multipart/insert.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var db = harness.locals.db; 18 | var it = harness.it; 19 | 20 | it('should handle crazy encodings', function(assert) { 21 | var att = { 22 | name: 'att', 23 | data: 'काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम् ॥', 24 | 'content_type': 'text/plain' 25 | }; 26 | db.multipart.insert({'foo': 'bar'}, [att], 'foobar', function(error, foo) { 27 | assert.equal(error, null, 'should have stored foo and attachment'); 28 | assert.equal(foo.ok, true, 'response should be ok'); 29 | assert.ok(foo.rev, 'response should have rev'); 30 | assert.end(); 31 | }); 32 | }); 33 | 34 | it('should test with presence of attachment', function(assert) { 35 | var att = { 36 | name: 'two', 37 | data: 'Hello World!', 38 | 'content_type': 'text/plain' 39 | }; 40 | 41 | db.attachment.insert('mydoc', 'one', 'Hello World!', 'text/plain', 42 | function(err) { 43 | assert.equal(err, null, 'should have stored the thingy'); 44 | db.get('mydoc', function(_, doc) { 45 | db.multipart.insert(doc, [att], 'mydoc', function() { 46 | db.get('mydoc', function(error, two) { 47 | assert.equal(error, null, 'should get the doc'); 48 | assert.equal(Object.keys(two._attachments).length, 2, 49 | 'both attachments should be present'); 50 | assert.end(); 51 | }); 52 | }); 53 | }); 54 | }); 55 | }); 56 | 57 | it('should work with attachment as a buffer', function(assert) { 58 | var att = { 59 | name: 'att', 60 | data: new Buffer('foo'), 61 | 'content_type': 'text/plain' 62 | }; 63 | db.multipart.insert({'foo': 'bar'}, [att], 'otherdoc', function(error, foo) { 64 | assert.equal(error, null, 'Should have stored foo and attachment'); 65 | assert.equal(foo.ok, true, 'Response should be ok'); 66 | assert.ok(foo.rev, 'Response should have rev'); 67 | assert.end(); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /tests/integration/shared/config.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var nano = harness.locals.nano; 18 | var Nano = helpers.Nano; 19 | 20 | var it = harness.it; 21 | 22 | it('should serve the root when no path is specified', function(assert) { 23 | nano.dinosaur('', function(err, response) { 24 | assert.equal(err, null, 'failed to get root'); 25 | assert.ok(response.version, 'version is defined'); 26 | nano.relax(function(err, response) { 27 | assert.equal(err, null, 'relax'); 28 | assert.ok(response.version, 'had version'); 29 | assert.end(); 30 | }); 31 | }); 32 | }); 33 | 34 | it('should be able to parse urls', function(assert) { 35 | var baseUrl = 'http://someurl.com'; 36 | assert.equal( 37 | Nano(baseUrl).config.url, 38 | baseUrl, 39 | 'simple url'); 40 | 41 | assert.equal( 42 | Nano(baseUrl + '/').config.url, 43 | baseUrl + '/', 44 | 'simple with trailing'); 45 | 46 | assert.equal( 47 | Nano('http://a:b@someurl.com:5984').config.url, 48 | 'http://a:b@someurl.com:5984', 49 | 'with authentication'); 50 | 51 | //var withDb = Nano({ 52 | // url: 'http://a:b@someurl.com:5984', 53 | // db: 'foo' 54 | //}) 55 | 56 | //assert.equal(withDb.config.db, 'foo', 'should create url with db'); 57 | //assert.ok(withDb.attachment, 'should have an attachment'); 58 | 59 | assert.equal( 60 | Nano('http://a:b%20c%3F@someurl.com:5984/mydb').config.url, 61 | 'http://a:b%20c%3F@someurl.com:5984', 62 | 'with escaped auth'); 63 | 64 | assert.equal( 65 | Nano('http://a:b%20c%3F@someurl.com:5984/my%2Fdb').config.url, 66 | 'http://a:b%20c%3F@someurl.com:5984', 67 | 'with dbname containing encoded slash'); 68 | 69 | assert.equal( 70 | Nano('http://mydb-a:b%20c%3F@someurl.com:5984/mydb').config.url, 71 | 'http://mydb-a:b%20c%3F@someurl.com:5984', 72 | 'with repeating dbname'); 73 | 74 | assert.equal( 75 | Nano('http://a:b%20c%3F@someurl.com:5984/prefix/mydb').config.url, 76 | 'http://a:b%20c%3F@someurl.com:5984/prefix', 77 | 'with subdir'); 78 | 79 | assert.equal( 80 | Nano(baseUrl + ':5984/a').config.url, 81 | baseUrl + ':5984', 82 | 'with port'); 83 | 84 | assert.equal( 85 | Nano(baseUrl + '/a').config.url, 86 | baseUrl, 87 | '`a` database'); 88 | 89 | assert.end(); 90 | }); 91 | 92 | it('should not parse urls when parseURL flag set to false', function(assert) { 93 | var url = 'http://someurl.com/path'; 94 | 95 | assert.equal( 96 | Nano({ 97 | url: url, 98 | parseUrl: false 99 | }).config.url, 100 | url, 101 | 'the untouched url'); 102 | 103 | assert.end(); 104 | }); 105 | 106 | it('should accept and handle customer http headers', function(assert) { 107 | var nanoWithDefaultHeaders = Nano({ 108 | url: helpers.couch, 109 | defaultHeaders: { 110 | 'x-custom-header': 'custom', 111 | 'x-second-header': 'second' 112 | } 113 | }); 114 | 115 | var req = nanoWithDefaultHeaders.db.list(function(err) { 116 | assert.equal(err, null, 'should list'); 117 | assert.end(); 118 | }); 119 | 120 | assert.equal( 121 | req.headers['x-custom-header'], 122 | 'custom', 123 | 'header `x-second-header` honored'); 124 | 125 | assert.equal( 126 | req.headers['x-second-header'], 127 | 'second', 128 | 'headers `x-second-header` honored'); 129 | }); 130 | 131 | it('should prevent shallow object copies', function(assert) { 132 | var config = { 133 | url: 'http://someurl.com' 134 | }; 135 | 136 | assert.equal( 137 | Nano(config).config.url, 138 | config.url, 139 | 'simple url'); 140 | 141 | assert.ok( 142 | Nano(config).config.requestDefaults, 143 | '`requestDefaults` should be set'); 144 | assert.ok(!config.requestDefaults, 145 | 'should not be re-using the same object'); 146 | 147 | assert.end(); 148 | }); 149 | -------------------------------------------------------------------------------- /tests/integration/shared/cookie.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var nano = harness.locals.nano; 18 | var Nano = helpers.Nano; 19 | var it = harness.it; 20 | 21 | var admin = Nano(helpers.admin); 22 | var cookie; 23 | var server; 24 | 25 | it('should be able to setup admin and login', function(assert) { 26 | nano.relax({ 27 | method : 'PUT', 28 | path: '_config/admins/' + helpers.username, 29 | body: helpers.password 30 | }, function(err) { 31 | assert.equal(err, null, 'should create admin'); 32 | nano.auth(helpers.username, helpers.password, function(err, _, headers) { 33 | assert.equal(err, null, 'should have logged in successfully'); 34 | assert.ok(headers['set-cookie'], 35 | 'response should have a set-cookie header'); 36 | cookie = headers['set-cookie']; 37 | assert.end(); 38 | }); 39 | }); 40 | }); 41 | 42 | it('should be able to insert with a cookie', function(assert) { 43 | server = Nano({ 44 | url: helpers.couch, 45 | cookie: cookie 46 | }); 47 | var db = server.use('shared_cookie'); 48 | 49 | db.insert({'foo': 'baz'}, null, function(error, response) { 50 | assert.equal(error, null, 'should have stored value'); 51 | assert.equal(response.ok, true, 'response should be ok'); 52 | assert.ok(response.rev, 'response should have rev'); 53 | assert.end(); 54 | }); 55 | }); 56 | 57 | it('should be able to get the session', function(assert) { 58 | server.session(function(error, session) { 59 | assert.equal(error, null, 'should have gotten the session'); 60 | assert.equal(session.userCtx.name, helpers.username); 61 | assert.end(); 62 | }); 63 | }); 64 | 65 | it('must restore admin parteh mode for other tests', function(assert) { 66 | admin.relax({ 67 | method: 'DELETE', 68 | path: '_config/admins/' + helpers.username 69 | }, function(err) { 70 | assert.equal(err, null, 'should have deleted admin user'); 71 | assert.end(); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /tests/integration/shared/error.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var nano = harness.locals.nano; 18 | var Nano = helpers.Nano; 19 | var it = harness.it; 20 | 21 | it('should throw when initialize fails', function(assert) { 22 | try { 23 | Nano('Not a url'); 24 | } catch (err) { 25 | assert.ok(err, 'should have throw'); 26 | assert.ok(err.message, 'with a description'); 27 | } 28 | try { 29 | Nano({}); 30 | } catch (err2) { 31 | assert.ok(err2, 'should have throw'); 32 | assert.ok(err2.message, 'with a message'); 33 | } 34 | assert.end(); 35 | }); 36 | 37 | it('should be able to stream the simplest request', function(assert) { 38 | var root = nano.request(); 39 | root.on('end', function() { 40 | assert.pass('request worked'); 41 | assert.end(); 42 | }); 43 | }); 44 | 45 | it('should error when destroying a db that does not exist', function(assert) { 46 | nano.db.destroy('say_wat_wat', function(error) { 47 | assert.ok(error, 'an error'); 48 | assert.ok(error.message, 'a note'); 49 | assert.equal(error.message, 'missing', 'is missing'); 50 | assert.end(); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /tests/integration/shared/headers.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var nano = harness.locals.nano; 18 | var db = harness.locals.db; 19 | var it = harness.it; 20 | 21 | it('should get headers', function(assert) { 22 | db.attachment.insert('new', 'att', 'Hello', 'text/plain', 23 | function(error, hello) { 24 | assert.equal(error, null, 'should store hello'); 25 | assert.equal(hello.ok, true, 'response should be ok'); 26 | assert.ok(hello.rev, 'should have a revision number'); 27 | nano.request({ 28 | db: 'shared_headers', 29 | doc: 'new', 30 | headers: {'If-None-Match': JSON.stringify(hello.rev)} 31 | }, function(error, helloWorld, rh) { 32 | assert.equal(error, null, 'should get the hello'); 33 | assert.equal(rh['statusCode'], 304, 'status is not modified'); 34 | nano.request({ 35 | db: 'shared_headers', 36 | doc: 'new', 37 | att: 'att' 38 | }, function(error, helloWorld, rh) { 39 | assert.equal(error, null, 'should get the hello'); 40 | assert.equal(rh['statusCode'], 200, 'status is `ok`'); 41 | assert.end(); 42 | }); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/integration/shared/log.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var logger = require('../../../lib/logger'); 16 | 17 | var helpers = require('../../helpers'); 18 | var harness = helpers.harness(__filename); 19 | var it = harness.it; 20 | 21 | it('should be able to instantiate a log', function(assert) { 22 | var log = logger({ 23 | log: function(id, msg) { 24 | assert.equal(typeof id, 'string', 'id is set `' + id + '`'); 25 | assert.equal(msg[0], 'testing 1234'); 26 | assert.end(); 27 | } 28 | })(); 29 | log('testing 1234'); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/integration/shared/nano.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename); 17 | var Nano = helpers.Nano; 18 | var it = harness.it; 19 | 20 | it('should have a version and a path', function(assert) { 21 | assert.ok(Nano.version, 'version is defined'); 22 | assert.ok(Nano.path, 'path is defined'); 23 | assert.end(); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/integration/shared/updates.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/integration'); 16 | var harness = helpers.harness(__filename, helpers.noopTest, helpers.noopTest); 17 | var it = harness.it; 18 | var nano = harness.locals.nano; 19 | 20 | it('should be able to track updates in couch', function(assert) { 21 | var called = false; 22 | 23 | function getUpdates() { 24 | nano.updates(function(err, updates) { 25 | if (called) { 26 | return; 27 | } 28 | called = true; 29 | 30 | if (err && updates.error && updates.error === 'illegal_database_name') { 31 | // 32 | // older couches 33 | // 34 | assert.expect(1); 35 | assert.ok(updates.ok, 'db updates are not supported'); 36 | assert.end(); 37 | } else { 38 | // 39 | // new couches 40 | // 41 | assert.equal(err, null, 'got root'); 42 | assert.ok(updates.ok, 'updates are ok'); 43 | assert.equal(updates.type, 'created', 'update was a create'); 44 | assert.equal(updates['db_name'], 'mydb', 'mydb was updated'); 45 | assert.end(); 46 | } 47 | }); 48 | 49 | setTimeout(function() { nano.db.create('mydb'); }, 50); 50 | } 51 | 52 | nano.db.destroy('mydb', getUpdates); 53 | }); 54 | 55 | it('should destroy mydb', function(assert) { 56 | nano.db.destroy('mydb', function(err) { 57 | assert.equal(err, null, 'no errors'); 58 | assert.end(); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /tests/unit/attachment/destroy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var destroyAttachment = require('../../helpers/unit').unit([ 16 | 'attachment', 17 | 'destroy' 18 | ]); 19 | 20 | destroyAttachment('airplane-design', 'wings.pdf', {rev: '3'}, { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'DELETE', 26 | qs: {rev: '3'}, 27 | uri: '/mock/airplane-design/wings.pdf' 28 | }); 29 | -------------------------------------------------------------------------------- /tests/unit/attachment/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var getAttachment = require('../../helpers/unit').unit([ 16 | 'attachment', 17 | 'get' 18 | ]); 19 | 20 | getAttachment('airplane-design', 'wings.pdf', {rev: 'rev-3'}, { 21 | encoding: null, 22 | headers: {}, 23 | method: 'GET', 24 | qs: {rev: 'rev-3'}, 25 | uri: '/mock/airplane-design/wings.pdf' 26 | }); 27 | 28 | getAttachment('airplane-design', 'wings.pdf', { 29 | encoding: null, 30 | headers: {}, 31 | method: 'GET', 32 | uri: '/mock/airplane-design/wings.pdf' 33 | }); 34 | -------------------------------------------------------------------------------- /tests/unit/attachment/insert.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/unit'); 16 | var insertAttachment = helpers.unit(['attachment', 'insert']); 17 | 18 | var buffer = new Buffer(helpers.pixel, 'base64'); 19 | 20 | insertAttachment('pixels', 'pixel.bmp', buffer, 'image/bmp', { 21 | body: buffer, 22 | headers: { 23 | 'content-type': 'image/bmp' 24 | }, 25 | method: 'PUT', 26 | uri: '/mock/pixels/pixel.bmp' 27 | }); 28 | 29 | insertAttachment('pixels', 'meta.txt', 'brown', 'text/plain', { 30 | body: 'brown', 31 | headers: { 32 | 'content-type': 'text/plain' 33 | }, 34 | method: 'PUT', 35 | uri: '/mock/pixels/meta.txt' 36 | }); 37 | 38 | insertAttachment('pixels', 'meta.txt', 'white', 'text/plain', {rev: '2'}, { 39 | body: 'white', 40 | headers: { 41 | 'content-type': 'text/plain' 42 | }, 43 | method: 'PUT', 44 | uri: '/mock/pixels/meta.txt', 45 | qs: {rev: '2'} 46 | }); 47 | -------------------------------------------------------------------------------- /tests/unit/database/changes.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var changesDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'changes' 18 | ]); 19 | 20 | changesDatabase('mock', {since: '10'}, { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | qs: {since: '10'}, 27 | uri: '/mock/_changes' 28 | }); 29 | 30 | changesDatabase('mock', { 31 | headers: { 32 | accept: 'application/json', 33 | 'content-type': 'application/json' 34 | }, 35 | method: 'GET', 36 | uri: '/mock/_changes' 37 | }); 38 | -------------------------------------------------------------------------------- /tests/unit/database/compact.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var compactDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'compact' 18 | ]); 19 | 20 | compactDatabase('mock', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'POST', 26 | uri: '/mock/_compact' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/database/create.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var createDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'create' 18 | ]); 19 | 20 | createDatabase('mock', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'PUT', 26 | uri: '/mock' 27 | }); 28 | 29 | createDatabase('az09_$()+-/', { 30 | headers: { 31 | accept: 'application/json', 32 | 'content-type': 'application/json' 33 | }, 34 | method: 'PUT', 35 | uri: '/az09_%24()%2B-%2F' 36 | }); 37 | -------------------------------------------------------------------------------- /tests/unit/database/destroy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var destroyDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'destroy' 18 | ]); 19 | 20 | destroyDatabase('mock', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'DELETE', 26 | uri: '/mock' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/database/follow.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var followDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'follow' 18 | ]); 19 | 20 | followDatabase('space', {db: '/space'}); 21 | -------------------------------------------------------------------------------- /tests/unit/database/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var getDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'get' 18 | ]); 19 | 20 | getDatabase('space', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | uri: '/space' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/database/list.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var listDatabases = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'list' 18 | ]); 19 | 20 | listDatabases({ 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | uri: '/_all_dbs' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/database/replicate.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var replicateDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'replicate' 18 | ]); 19 | 20 | replicateDatabase('baa', 'baashep', { 21 | body: '{"source":"baa","target":"baashep"}', 22 | headers: { 23 | accept: 'application/json', 24 | 'content-type': 'application/json' 25 | }, 26 | method: 'POST', 27 | uri: '/_replicate' 28 | }); 29 | 30 | replicateDatabase('molly', 'anne', {some: 'params'}, { 31 | body: '{"some":"params","source":"molly","target":"anne"}', 32 | headers: { 33 | accept: 'application/json', 34 | 'content-type': 'application/json' 35 | }, 36 | method: 'POST', 37 | uri: '/_replicate' 38 | }); 39 | -------------------------------------------------------------------------------- /tests/unit/database/updates.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var updatesDatabase = require('../../helpers/unit').unit([ 16 | 'database', 17 | 'updates' 18 | ]); 19 | 20 | updatesDatabase({ 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | uri: '/_db_updates' 27 | }); 28 | 29 | updatesDatabase({since: 1}, { 30 | headers: { 31 | accept: 'application/json', 32 | 'content-type': 'application/json' 33 | }, 34 | method: 'GET', 35 | qs: {since: 1}, 36 | uri: '/_db_updates' 37 | }); 38 | -------------------------------------------------------------------------------- /tests/unit/design/atomic.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var atomicDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'atomic' 18 | ]); 19 | 20 | atomicDesign('update', 'inplace', 'foobar', { 21 | field: 'foo', 22 | value: 'bar' 23 | }, { 24 | body: '{"field":"foo","value":"bar"}', 25 | headers: { 26 | accept: 'application/json', 27 | 'content-type': 'application/json' 28 | }, 29 | method: 'PUT', 30 | uri: '/mock/_design/update/_update/inplace/foobar' 31 | }); 32 | -------------------------------------------------------------------------------- /tests/unit/design/compact.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var compactDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'compact' 18 | ]); 19 | 20 | compactDesign('alice', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'POST', 26 | uri: '/mock/_compact/alice' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/design/list.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var listDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'viewWithList' 18 | ]); 19 | 20 | listDesign('people', 'by_name_and_city', 'my_list', { 21 | key: [ 22 | 'Derek', 23 | 'San Francisco' 24 | ] 25 | }, { 26 | headers: { 27 | accept: 'application/json', 28 | 'content-type': 'application/json' 29 | }, 30 | method: 'GET', 31 | qs: { 32 | 'key': '["Derek","San Francisco"]' 33 | }, 34 | uri: '/mock/_design/people/_list/my_list/by_name_and_city' 35 | }); 36 | -------------------------------------------------------------------------------- /tests/unit/design/search.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var searchDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'search' 18 | ]); 19 | 20 | searchDesign('alice', 'by_id', { 21 | keys: 'dawg' 22 | }, { 23 | body: '{"keys":"dawg"}', 24 | headers: { 25 | accept: 'application/json', 26 | 'content-type': 'application/json' 27 | }, 28 | method: 'POST', 29 | uri: '/mock/_design/alice/_search/by_id' 30 | }); 31 | -------------------------------------------------------------------------------- /tests/unit/design/show.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var showDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'show' 18 | ]); 19 | 20 | showDesign('people', 'singleDoc', 'p_clemens', { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | uri: '/mock/_design/people/_show/singleDoc/p_clemens' 27 | }); 28 | -------------------------------------------------------------------------------- /tests/unit/design/spatial.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var geoDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'spatial' 18 | ]); 19 | 20 | geoDesign('people', 'byArea', {x: '1'}, { 21 | headers: { 22 | accept: 'application/json', 23 | 'content-type': 'application/json' 24 | }, 25 | method: 'GET', 26 | qs: {x: '1'}, 27 | uri: '/mock/_design/people/_spatial/byArea' 28 | }); 29 | -------------------------------------------------------------------------------- /tests/unit/design/view.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var viewDesign = require('../../helpers/unit').unit([ 16 | 'view', 17 | 'view' 18 | ]); 19 | 20 | viewDesign('alice', 'by_id', { 21 | keys: ['foobar', 'barfoo'], 22 | 'include_docs': true 23 | }, { 24 | body: '{"keys":["foobar","barfoo"]}', 25 | headers: { 26 | accept: 'application/json', 27 | 'content-type': 'application/json' 28 | }, 29 | method: 'POST', 30 | qs: { 31 | 'include_docs': true 32 | }, 33 | uri: '/mock/_design/alice/_view/by_id' 34 | }); 35 | -------------------------------------------------------------------------------- /tests/unit/document/bulk.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var bulkDocument = require('../../helpers/unit').unit([ 16 | 'document', 17 | 'bulk' 18 | ]); 19 | 20 | bulkDocument({ 21 | docs: [ 22 | {key: 'baz', name: 'bazzel'}, 23 | {key: 'bar', name: 'barry'} 24 | ] 25 | }, { 26 | body: '{"docs":[{"key":"baz","name":"bazzel"},{"key":"bar","name":"barry"}]}', 27 | headers: { 28 | accept: 'application/json', 29 | 'content-type': 'application/json' 30 | }, 31 | method: 'POST', 32 | uri: '/mock/_bulk_docs' 33 | }); 34 | 35 | bulkDocument({ 36 | docs: [] 37 | }, {wat: 'izlove'}, { 38 | body: '{"docs":[]}', 39 | headers: { 40 | accept: 'application/json', 41 | 'content-type': 'application/json' 42 | }, 43 | method: 'POST', 44 | qs: {wat: 'izlove'}, 45 | uri: '/mock/_bulk_docs' 46 | }); 47 | -------------------------------------------------------------------------------- /tests/unit/document/copy.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var copyDocument = require('../../helpers/unit').unit([ 16 | 'document', 17 | 'copy' 18 | ]); 19 | 20 | var copyDocumentFail = require('../../helpers/unit').unit([ 21 | 'document', 22 | 'copy' 23 | ], new Error('OMG This sucks')); 24 | 25 | copyDocument('excel', 'numbers', { 26 | headers: { 27 | 'Destination': 'numbers', 28 | 'accept': 'application/json', 29 | 'content-type': 'application/json' 30 | }, 31 | method: 'COPY', 32 | uri: '/mock/excel' 33 | }); 34 | 35 | copyDocumentFail('excel', 'numbers', {overwrite: 'yes'}, { 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /tests/unit/multipart/get.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var getMultipart = require('../../helpers/unit').unit([ 16 | 'multipart', 17 | 'get' 18 | ]); 19 | 20 | getMultipart('space', {extra: 'stuff'}, { 21 | encoding: null, 22 | headers: {'content-type': 'multipart/related'}, 23 | method: 'GET', 24 | qs: {attachments: true, extra: 'stuff'}, 25 | uri: '/mock/space' 26 | }); 27 | -------------------------------------------------------------------------------- /tests/unit/multipart/insert.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var insertMultipart = require('../../helpers/unit').unit([ 16 | 'multipart', 17 | 'insert' 18 | ]); 19 | 20 | insertMultipart({hey: 1}, [{ 21 | name: 'att', 22 | data: 'some', 23 | 'content_type': 'text/plain' 24 | }], {extra: 'stuff'}, { 25 | headers: { 26 | 'content-type': 'multipart/related' 27 | }, 28 | method: 'PUT', 29 | multipart: [ 30 | { 31 | body: 32 | '{"_attachments":' + 33 | '{"att":{"follows":true,"length":4,"content_type":"text/plain"}}' + 34 | ',"hey":1}', 35 | 'content-type': 'application/json' 36 | }, 37 | {body: 'some'} 38 | ], 39 | qs: {extra: 'stuff'}, 40 | uri: '/mock' 41 | }); 42 | -------------------------------------------------------------------------------- /tests/unit/shared/error.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/unit'); 16 | var test = require('tape'); 17 | var debug = require('debug')('nano/tests/unit/shared/error'); 18 | 19 | var cli = helpers.mockClientFail(debug); 20 | var cli2 = helpers.mockClientUnparsedError(debug); 21 | var cli3 = helpers.mockClientUnparsedError(debug, JSON.stringify({ 22 | error: 'not a reason' 23 | })); 24 | 25 | var cli4 = helpers.mockClientUnparsedError(debug, JSON.stringify({ 26 | stack: new Error('foo').stack 27 | })); 28 | 29 | test('it should be able to set a jar box', function(assert) { 30 | cli.relax({}, function(err) { 31 | assert.equal(err.message, 'error happened in your connection'); 32 | assert.end(); 33 | }); 34 | }); 35 | 36 | test('should be able to deal with html errors bad couches', function(assert) { 37 | cli2.relax({}, function(err) { 38 | assert.equal(err.message, ' Error happened '); 39 | assert.end(); 40 | }); 41 | }); 42 | 43 | test('should be capable of using `error`', function(assert) { 44 | cli3.relax({}, function(err) { 45 | assert.equal(err.message, 'not a reason'); 46 | assert.end(); 47 | }); 48 | }); 49 | 50 | test('should remove cloudant stacktraces', function(assert) { 51 | cli4.relax({}, function(err) { 52 | var msg = err.stack.split('\n')[0]; 53 | assert.notEqual(msg, 'Error: foo'); 54 | assert.equal(msg, 'Error: Unspecified error'); 55 | assert.end(); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /tests/unit/shared/follow-updates.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var followUpdates = require('../../helpers/unit').unit([ 16 | 'server', 17 | 'followUpdates' 18 | ]); 19 | 20 | followUpdates({db: '/_db_updates'}); 21 | followUpdates({since: 1}, {db: '/_db_updates', since: 1}); 22 | -------------------------------------------------------------------------------- /tests/unit/shared/jar.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the 'License'); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | 'use strict'; 14 | 15 | var helpers = require('../../helpers/unit'); 16 | var test = require('tape'); 17 | var debug = require('debug')('nano/tests/unit/shared/jar'); 18 | 19 | var cli = helpers.mockClientJar(debug); 20 | 21 | test('it should be able to set a jar box', function(assert) { 22 | assert.equal(cli.config.jar, 'is set'); 23 | cli.relax({}, function(_, req) { 24 | assert.equal(req.jar, 'is set'); 25 | cli.relax({jar: 'changed'}, function(_, req) { 26 | assert.equal(req.jar, 'changed'); 27 | assert.end(); 28 | }); 29 | }); 30 | }); 31 | --------------------------------------------------------------------------------