Summer Sale! All accounts are 50% off this week.

jcc5018's avatar

Testing registration redirection

I am new to laravel testing with phpUnit. I am currently trying to test that new users can register which should go to a welcome page. This works when manually testing, but when running the test, it fails and shows it redirecting to the home page. I'm not sure why this would be.

Testing code:

    {
              $user= [
            'given_name'            => 'John',
            'family_name'           => 'DoeTest',
            'username'              => 'testcase',
            'email'                 => '[email protected]',
            'email_verified_at'     => now(),
            'password'              => 'password',
            'password_confirmation' => 'password',

            'birthday'              => '02/11/1986',
            'read_TOS'              => 1,
        ];

        $response = $this->post('/register',$user);
        $response->assertStatus(302)
            ->assertRedirect('/welcome');
        $this->assertDatabaseHas('users', [
            'email' => '[email protected]',
        ]);
//        $this->assertAuthenticated();

//        $response->assertRedirect(RouteServiceProvider::HOME);
    }

I'm not sure what other information you may need. But like I said, the user is sent to /welcome upon successful registration with manual testing, so I'm not sure what the difference is.

Thanks

0 likes
8 replies
MohamedTammam's avatar

What is the failing error message says?

and, are you using RefreshDatabase trait in your test class?

jcc5018's avatar

@MohamedTammam

Failed asserting that two strings are equal.

 at E:\laragon\www\domain\tests\Feature\Auth\RegistrationTest.php:43
     39▕         ];
     40▕
     41▕         $response = $this->post('/register',$user);
     42▕         $response->assertStatus(302)
  ➜  43▕             ->assertRedirect('/welcome');
     44▕         $this->assertDatabaseHas('users', [
     45▕             'email' => '[email protected]',
     46▕         ]);
     47▕ //        $this->assertAuthenticated();

  1   E:\laragon\www\domain\vendor\phpunit\phpunit\phpunit:98
      PHPUnit\TextUI\Command::main()
  --- Expected
  +++ Actual
  @@ @@
  -'http://domain.test/welcome'
  +'http://domain.test'

I do not have refreshDatabase but that shouldnt be causing an issue considering it is creating a new user instance. Right?

but i tried with it on as well, but did not change anything.

jcc5018's avatar

@MohamedTammam

       <div class="m-auto input-box">

            <div class="card mx-4">
                <div class="card-body p-4">

                    <form method="POST" action="{{ route('register') }}">
                        @csrf
                        <h1 class="text-center mb-4"> {{ config('app.name') }}</h1>

                        {{-- given name --}}
                        <div class="input-group mb-3">
                            <label for="given_name" class="col-md-4 col-form-label text-md-right">
                                Given Name
                            </label>
                            <div class="col-md-6">
                                <input type="text" id="given_name" name="given_name"
                                       value="{{ old('given_name', null) }}" autocomplete="given-name"
                                       class="form-control{{ $errors->has('given_name') ? ' is-invalid' : '' }}"
                                       required
                                       autofocus>
                                @if($errors->has('given_name'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('given_name') }}
                                    </div>
                                @endif
                            </div>
                        </div>
                        {{-- family name --}}
                        <div class="input-group mb-3">
                            <label for="family_name" class="col-md-4 col-form-label text-md-right">
                                Family Name
                            </label>
                            <div class="col-md-6">
                                <input type="text" id="family_name" name="family_name"
                                       value="{{ old('family_name', null) }}"
                                       autocomplete="family-name"
                                       class="form-control{{ $errors->has('family_name') ? ' is-invalid' : '' }}"
                                       required>
                                @if($errors->has('family_name'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('family_name') }}
                                    </div>
                                @endif
                            </div>
                        </div>
                        {{-- email  --}}
                        <div class="input-group mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-right">
                                {{ trans('global.login_email') }}
                            </label>
                            <div class="col-md-6">
                                <input type="email" id="email" name="email" value="{{ old('email', null) }}"
                                       autocomplete="email"
                                       class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}"
                                       required>
                                @if($errors->has('email'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('email') }}
                                    </div>
                                @endif
                            </div>
                        </div>

                        {{-- username  --}}
                        <div class="input-group mb-3">
                            <label for="username" class="col-md-4 col-form-label text-md-right">
                                User Name
                            </label>
                            <div class="col-md-6">
                                <input type="text" id="username" name="username"
                                       value="{{ old('username', null) }}"
                                       class="form-control{{ $errors->has('username') ? ' is-invalid' : '' }}"
                                       required>
                                @if($errors->has('username'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('username') }}
                                    </div>
                                @endif
                            </div>
                        </div>

                        {{-- password  --}}

                        <div class="input-group mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-right">
                                {{ trans('global.login_password') }}
                            </label>

                            <div class="col-md-6">

                                <input type="password" name="password"
                                       class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}"
                                       required>
                                @if($errors->has('password'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('password') }}
                                    </div>
                                @endif
                            </div>
                        </div>
                        {{-- Password confirm --}}

                        <div class="input-group mb-3">
                            <label for="password_confirmation" class="col-md-4 col-form-label text-md-right">
                                Confirm Password</label>

                            <div class="col-md-6">

                                <input type="password" name="password_confirmation" class="form-control" required>

                                @if($errors->has('password'))
                                    <div class="invalid-feedback">
                                        {{ $errors->first('password') }}
                                    </div>
                                @endif
                            </div>
                        </div>



                        <div class="input-group mb-3">
                            <label for="birthday"
                                   class="col-md-4 col-form-label text-md-right">{{ __('Birthday')}}</label>
                            <div class="col-md-6">
                                <input type="date" class="form-control" id="birthday" name="birthday"
                                       value="{{ old('birthday') }}" required autocomplete="birthday">

                            </div>
                        </div>
                        <div class="input-group mb-3">
                            <div class="col-md-3"></div>
                            <label class="col-md-6 col-form-label text-md-right">
                                <input type="checkbox" name="read_tos" value="1">
                                {{ __('Agree with the terms and conditions')}}

                            </label>

                            <div class="col-md-7">
                                @if ($errors->has('read_tos'))
                                    <span class="help-block">
                                    <strong>{{ $errors->first('read_tos') }}</strong>
                                </span>
                                @endif
                            </div>


                        </div>

                        <div class="row justify-content-center">
                            <div class="col-md-6 text-center ">

                                <div class="mb-1"><a href="#">{{ __('Connect with Facebook')}}</a></div>
                                <br>
                                <div class="mb-1"><a href="#">{{ __('Connect with Google')
                                        }}</a></div>
                                <br>
                                <a href="#">{{ __('Why Register')}}</a>

                                <button class="btn btn-block btn-primary mt-3">
                                    {{ trans('global.register') }}
                                </button>
                            </div>


                        </div>

                    </form>

                </div>
            </div>

        </div>
class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use  RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/welcome';
    //protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct ()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param array $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator (array $data)
    {
        return Validator::make($data, [
            'given_name'  => ['required', 'string', 'max:255'],
            'family_name' => ['nullable', 'string', 'max:255'],
            'username'    => ['required', 'string', 'max:75','min:4', 'unique:users'],
            'email'       => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password'    => ['required', 'string', 'min:7', 'confirmed'],

            'birthday'    => ['required','date',
                              'before:today'],  //TODO verify birthday within range  use User request
            'read_tos'    => ['required'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param array $data
     * @return \App\Models\User
     */
    protected function create (array $data)
    {
        return User::create([
                                'given_name'  => $data['given_name'],
                                'family_name' => $data['family_name'],
                                'email'       => $data['email'],
                                'username'    => $data['username'],
                                'password'    => Hash::make($data['password']),

                                'birthday'    => $data['birthday'],
                                'read_tos'    => $data['read_tos'],
                            ]);
        //        $user->assignRole('user');
        //        Auth::login($user);
        //        return redirect("/welcome");
    }
}

Note: I do think I need to combine this with the UsersController store/create method instead of two separate controllers. But the auth controller came with the UI, and I dont know enough to modify it right now.

USER CONTROLLER

 public function create ()
    {
        //abort_if(Gate::denies('user_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
        $roles = Role::pluck('name', 'id');

        return view('users.admin.create', compact('roles'));
    }

    public function store (StoreUserRequest $request)
    {
        if ($user = User::create($request->except('roles', 'permissions'))) {
            $this->syncRoles($request, $user);
            flash('User has been created.');
        } else {
            flash()->error('Unable to create user.');
        }
        if ($request->input('profile_image', false)) {
            $user->addMedia(storage_path('tmp/uploads/'.basename($request->input('profile_image'))))->toMediaCollection('profile_image');
        }

        if ($media = $request->input('ck-media', false)) {
            Media::whereIn('id', $media)->update(['model_id' => $user->id]);
        }
        //        $user = User::create($request->all());
        //        $user->roles()->sync($request->input('roles', []));
        // $user->personalities()->sync($request->input('personalities', []));

        return redirect()->back();
    }
Sinnbeck's avatar

Try adding $this->withoutExceptionHandling(); at the top of the test (before the request)

jcc5018's avatar

@Sinnbeck Can you explain what this does before I go adding random things I don't understand

I did try it at the top of the method. Didnt help. But id still like to know what that was supposed to do so I can hopefully learn it.

Sinnbeck's avatar

@jcc5018 it turns off laravels exception handler. So instead of returning a pretty error page, you get the actual error. You can often find hidden errors in your tests until they are done

Please or to participate in this conversation.