0

I'm currently playing around with Exception Handler, and creating my own custom exceptions.

I've been using PHPUnit to run tests on my Controller Resource, but when I throw my custom exceptions, Laravel thinks it's coming from a regular HTTP request rathen than AJAX.

Exceptions return different response based on wether it's an AJAX request or not, like the following:

<?php namespace Actuame\Exceptions\Castings;

use Illuminate\Http\Request;

use Exception;

use Actuame\Exceptions\ExceptionTrait;

class Already_Applied extends Exception 
{

    use ExceptionTrait;

    var $redirect = '/castings';
    var $message = 'castings.errors.already_applied';

}

And the ExceptionTrait goes as follows:

<?php

namespace Actuame\Exceptions;

trait ExceptionTrait 
{

    public function response(Request $request)
    {
        $type = $request->ajax() ? 'ajax' : 'redirect';

        return $this->$type($request);
    }

    private function ajax(Request $request)
    {
        return response()->json(array('message' => $this->message), 404);
    }

    private function redirect(Request $request)
    {
        return redirect($this->redirect)->with('error', $this->message);
    }

}

Finally, my test goes like this (excerpt of the test that's failing)

public function testApplyToCasting()
{
    $faker = Factory::create();

    $user = factory(User::class)->create();

    $this->be($user);

    $casting = factory(Casting::class)->create();

    $this->json('post', '/castings/apply/' . $casting->id, array('message' => $faker->text(200)))
        ->seeJsonStructure(array('message'));
}

My logic is like this although I don't think the error is coming from here

public function apply(Request $request, User $user)
{
    if($this->hasApplicant($user))
        throw new Already_Applied;

    $this->get()->applicants()->attach($user, array('message' => $request->message));

    event(new User_Applied_To_Casting($this->get(), $user));

    return $this;
}

When running PHPUnit, the error I get returned is

1) CastingsTest::testApplyToCasting PHPUnit_Framework_Exception: Argument #2 (No Value) of PHPUnit_Framework_Assert: :assertArrayHasKey() must be a array or ArrayAccess

/home/vagrant/Code/actuame2/vendor/laravel/framework/src/Illuminate/Foundation/T esting/Concerns/MakesHttpRequests.php:304 /home/vagrant/Code/actuame2/tests/CastingsTest.php:105

And my laravel.log is over here http://pastebin.com/ZuaRaxkL (Too large to paste)

I have actually discovered that PHPUnit is not actually sending an AJAX response, because my ExceptionTrait actually changes the response on this. When running the test it takes the request as a regular POST request, and runs the redirect() response rather than ajax(), hence it's not returning the correspond.

Thanks a bunch!

1 Answer 1

0

I have finally found the solution!

As I said, response wasn't the right one as it was trying to redirect rathen than return a valid JSON response.

And after going through the Request code, I found out that I need to use also wantsJson(), as ajax() may not be the case always, so I have modified my trait to this:

<?php

namespace Actuame\Exceptions;

trait ExceptionTrait 
{

    public function response(Request $request)
    {
        // Below here, I added $request->wantsJson()
        $type = $request->ajax() || $request->wantsJson() ? 'ajax' : 'redirect';

        return $this->$type($request);
    }

    private function ajax(Request $request)
    {
        return response()->json(array('message' => $this->message), 404);
    }

    private function redirect(Request $request)
    {
        return redirect($this->redirect)->with('error', $this->message);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.