Giter Site home page Giter Site logo

Comments (20)

indexzero avatar indexzero commented on August 20, 2024

@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.

nibblebot avatar nibblebot commented on August 20, 2024

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.

kc-dot-io avatar kc-dot-io commented on August 20, 2024

@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.

mschoch avatar mschoch commented on August 20, 2024

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.

kc-dot-io avatar kc-dot-io commented on August 20, 2024

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.

kc-dot-io avatar kc-dot-io commented on August 20, 2024

Never mind! Figured it out. Thanks for the example! This works great.

from api-easy.

bard avatar bard commented on August 20, 2024

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.

indexzero avatar indexzero commented on August 20, 2024

A more elegant solution would be accepted in a pull-request :)

from api-easy.

bard avatar bard commented on August 20, 2024

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.

Filirom1 avatar Filirom1 commented on August 20, 2024

I really like mschoch solution. This could be great to explain it in the README.

from api-easy.

STRML avatar STRML commented on August 20, 2024

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.

drekka avatar drekka commented on August 20, 2024

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.

Marak avatar Marak commented on August 20, 2024

@drekka @bard @STRML - If you want to see an open issue, create a pull request with a potential patch.

from api-easy.

bard avatar bard commented on August 20, 2024

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.

drekka avatar drekka commented on August 20, 2024

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.

indexzero avatar indexzero commented on August 20, 2024

@bard That is false. Vows is still being developed.

from api-easy.

bard avatar bard commented on August 20, 2024

@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.

hboylan avatar hboylan commented on August 20, 2024

@nibblebot I'm having the same issue... Have you found a solution to using cookies with api-easy?

from api-easy.

anupachwal avatar anupachwal commented on August 20, 2024

@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.

hboylan avatar hboylan commented on August 20, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.