Comments (20)
@mschoch Right now this is the correct usage. Can you post some sample usage so I can perhaps encapsulate something like this into a method such as .crud()
?
from api-easy.
TL;DR
cannot set state or setHeader in a response so the result of one request cannot dynamically inform the headers of a subsequent request
I am having this same issue. I need to POST to /login, then on the next GET, i need to use the session cookie that was set in the previous POST
The issue is that the fn that gets passed .expects(fn) does not share scope with any subsequent requests.
I also tried to setHeader after getting the response from the first POST. I verified that this sets it correctly but since it doesn't get executed until after the whole test suite has been exported, the headers for all the get requests have already been set.
suite
.use('localhost', 3010)
.setHeader('Content-Type', 'application/json')
.discuss('Login Admin')
.path('/admin/login')
.post({email: '[email protected]', pass: 'test'})
.expect('sets session cookie', 200, { success: true }, function(err, res, body) {
res.headers['set-cookie'].filter(function(cookie) {
if (!!~cookie.indexOf('connect.sid')) {
suite.setHeader('Cookie', cookie.split(';', 1)[0]);
console.log('cookie set');
}
})
})
.unpath()
.next()
.discuss('Invite user')
.path('/test')
// I need the cookie to be set here
.get().expect(200, {success:true})
.export(module);
from api-easy.
@mschoch - I also need to see an example of how you are doing this. I need to pass a response object into subsequent requests. Please seed an example!
from api-easy.
I don't have access to the original code, but I've put together a quick demonstration. This one takes a value from the body of the first response,
sets it as a replacement token. The before function to 'replaceTokens' will be fired before the second request. In this before function we go through all our replacement tokens and try to replace strings in the new requests URI. The same approach can be used to replace tokens in the body of the request as well. This was put together quickly but hopefully you get the idea.
One other thing to note, the console will still log text like "When testing CouchDB API A GET to /new_database/$doc_id" but the request is actually sent to correct URL.
var APIeasy = require('api-easy'),
assert = require('assert');
var suite = APIeasy.describe('CouchDB');
suite.use('localhost', 5984);
var replacements = new Object;
suite.before('replaceTokens', function (outgoing) {
for(replacementIndex in replacements) {
var replacement = replacements[replacementIndex];
var token = '$' + replacementIndex;
outgoing.uri = outgoing.uri.replace(token, replacement);
}
return outgoing;
});
suite.discuss('When testing CouchDB API')
.discuss('when creating a new document')
.path('new_database')
.setHeader('Content-Type', 'application/json')
.post({ test: 'secret message' })
.expect(201)
.expect('should respond with the document id', function (err, res, body) {
var result = JSON.parse(body);
assert.isNotNull(result.id);
replacements['doc_id'] = result.id;
})
.undiscuss()
.next()
.path('$doc_id')
.get()
.expect(200)
.export(module);
from api-easy.
When you say that this works in the body of the request, would that mean that it works for POST parameters? Can you give a small example of how that works? Could I do something like .post('/path',{ doc_id: '$doc_id' }) ?
from api-easy.
Never mind! Figured it out. Thanks for the example! This works great.
from api-easy.
Should this really be closed? It would be nice to have a real solution instead of a hack. As things stand, we can't test in a clean way the very common case of "POST to /collection, receive 201 with Location header pointing to newly created resource, GET newly created resource".
from api-easy.
A more elegant solution would be accepted in a pull-request :)
from api-easy.
My point was that this is a valid issue currently without a solution, so I don't think it should be closed—even in the absence of a pull request. Of course if you don't agree with the hypothesis (issue is invalid, or workaround is a solution) thesis no longer follows. :)
from api-easy.
I really like mschoch solution. This could be great to explain it in the README.
from api-easy.
I agree, why is this closed? There is still plenty of work to do to make this work better.
Here is my updated version - this works for encoded URLs and POSTS:
suite.before('replaceTokens', function (outgoing) {
for(var replacementIndex in replacements) {
var replacement = replacements[replacementIndex];
var token = '$' + replacementIndex;
var encodedToken = "%24" + replacementIndex; // for encoded urls
outgoing.uri = outgoing.uri.replace(token, replacement);
outgoing.uri = outgoing.uri.replace(encodedToken, replacement);
if(Object.prototype.toString.call(outgoing.body) == '[object String]') // POST bodies
outgoing.body = outgoing.body.replace(token, replacement);
}
return outgoing;
});
Example Usage (extjs fans may recognize the JSON):
.get('', {filter: [JSON.stringify({"property" : "event", "value" : "$item_id"})]})
.post({"records": [{"item" : "$item_id"}]})
Be sure to use .setHeader('Content-Type', 'application/json')
at the top of your suite when sending POSTS in this manner.
from api-easy.
I also vote for re-opening this issue. I have the simple case where I post to a URL to create a record and get back the a json response with the id of the newly created record. I then want to use this id in subsequent requests. My thought would be to have some sort of general storage area which is available in all scopes that data can be accessed.
from api-easy.
@drekka @bard @STRML - If you want to see an open issue, create a pull request with a potential patch.
from api-easy.
Thanks @Marak, no problem, after wrestling a bit too much with next
's in more complex scenarios involving sequential requests, and after hearing that vows is no longer actively developed, I rewrote my tests with mocha a while ago anyway.
from api-easy.
Sorry @Marak, I'm still quite a way from being node savvy enough to be able to contribute patches. Right now I'm just concentrating on figuring out how to put things together.
from api-easy.
@bard That is false. Vows is still being developed.
from api-easy.
@indexzero I'll see if I can dig out the reference again so someone can rectify. Mocha turned out to be a better fit here anyway but that won't necessarily be the case for everyone.
from api-easy.
@nibblebot I'm having the same issue... Have you found a solution to using cookies with api-easy?
from api-easy.
@hboylan
Check this 1 works for me : -
https://github.com/flatiron/api-easy/blob/master/examples/simple-example.js
var cookies; suite.discuss('When using your awesome API') .use('localhost', 9000) .setHeader('Content-Type', 'application/json; charset=utf-8') .post('/api/session', { 'username': 'admin', 'password': 'admin' }) .expect(200) .expect('should set cookie', function (err, res, body) { res.headers['set-cookie'].filter(function (cookie) { if (!!~cookie.indexOf('connect.sid')) { cookies = cookie.split(';', 1)[0]; suite.before('setAuth', function (outgoing) { outgoing.headers['Cookie'] = cookies; return outgoing; }); } }) }) .next() .get('/api/list/name') .expect(200) .export(module);
from api-easy.
Thanks @anupachwal. I ended up doing exactly that. Also created my own light-weight test package to make async tests much simpler. https://www.npmjs.org/package/teqlabs-testify
from api-easy.
Related Issues (20)
- Recursive calls Examples HOT 8
- "Content-Type" header with GET request HOT 2
- Please update vows version
- How to use the same tests in different environments (dev, beta, staging etc.)
- offtopic: why do you parse params like this HOT 2
- API-easy not compatible with latest versions of node? HOT 3
- Unable to stall tests until connections are made HOT 3
- Cannot post a body that is not an object HOT 3
- Permission denied when running the test HOT 4
- Unable to pass data (and update POST data) between chained APIEasy calls. HOT 3
- api-easy usage with Express (node lib) HOT 2
- .put() does not work as expected HOT 1
- i get error ECONNREFUSED. HOT 1
- No way to tests API over SSL HOT 2
- Question: using for a smoke test
- Asynchonous error HOT 1
- How do I test multipart requests with apieasy?
- afters
- Broken doc page HOT 1
- Test Execution Reports
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from api-easy.