0

So I am a codeception newbie and I am trying to figure out how to test my web service using the same. I have written my first simple test for the authenticate route just to make sure that the application is spitting out the JWT token like it should. The test looks like so:

<?php 
$I = new ApiTester($scenario);
$I->wantTo('authenticate a user');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPOST('/api/authenticate', [
    'username' => 'archive',
    'email' => 'admin@admin.com',
    'password' => 'password'
]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();

In my defense I have tried the same POST from Postman and it works perfectly.

api.suite.yml

class_name: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost:8000/api/
            depends: Laravel5
    config: 
        Laravel5:
            environment_file: .env.testing

The problem that I am facing in this test is that it does not see the 200 OK as the response code but sees 500 instead. Later I realized I can go through the outputs of the same in the _output directory and I saw this error:

The token could not be parsed from the request

Now to my surprise, the authenticate route should not even require a token so I went on to look where in my application is the token being parsed. Finally I realized that there is a middleware called ChangeDb which is in the Kernal and it looks to check the token from every request except the authenticate route. It looks like so:

public function handle($request, Closure $next)
{
    if($request->path() != 'api/authenticate'){
        $username = \JWTAuth::parseToken()->getPayload()->get('username');

        if(! $username){
            \Config::set('database.connections.tenant.database', 'archive');
            \DB::reconnect();
            \DB::setDatabaseName('archive');
        }else{
            \Config::set('database.connections.tenant.database', $username); 
        }
    }

    return $next($request);
}

But when I tried to comment this out of the Kernal, the test runs fine and gives me green. So somehow this middleware runs fine when I try it from Postman and other ajax request, but when Codeception tries the request, the if statement returns true apparently because it looks at the token and this is where my test fails.

So why is this happening? Does the request generated from Codeception is different somehow from the request generated from Postman or my ajax application on the front end? How to work around this?

Rohan
  • 13,308
  • 21
  • 81
  • 154
  • add `var_dump($request->path()); die;` to beginning of the handle method and re-run this test. What output do you get? – Naktibalda Nov 04 '15 at 11:44

1 Answers1

0

So as I assumed Laravel5 as the dependency in the REST section was the issue. It was not simulating real HTTP requests and which is why the middleware could not tell where the request was coming from. I changed it to PhpBrowser and it works now. PhpBrowser apparently simulates real HTTP requests.

Rohan
  • 13,308
  • 21
  • 81
  • 154