1

I am building an application that has features to login with google.

Here is the function to login with google with redirect

/**
 * @return mixed
 */
public function loginWithGoogle () {
    return Socialite::driver('google')
        ->scopes([
            'https://www.googleapis.com/auth/userinfo.email'
        ])
        ->with([
            'access_type' => 'offline',
            'prompt' => 'consent select_account'
        ])
        ->redirect();
}

Below is the function to redirect from google login

/**
 * @return RedirectResponse
 */
public function loginRedirectFromGoogle (): RedirectResponse
{
    $user = Socialite::driver('google')->stateless()->user();
    $acUser = User::where('email', $user->getEmail())->first();

    if(empty($acUser)){
        return redirect('/oauth/login?'.http_build_query([
            'force_external_oauth_response' => 'true',
            'external_oauth_response_error' => 'User account not register'
        ]));
    }

    Auth::login($acUser);

    OAuthProvider::updateOrCreate(
        [
            'provider_name' => 'google',
            'provider_id' => $user->id,
            'user_id' => $acUser->id
        ],
        [
            'encrypted_token' => Crypt::encryptString($user->token),
            'encrypted_refreshed_token' => Crypt::encryptString($user->refreshToken),
            'expires_at' => time() + $user->expiresIn // time and expiresIn are all in seconds
        ]
    );

    return redirect('/oauth/login?'.http_build_query([
            'force_external_oauth_response' => 'true',
            'external_oauth_response_error' => ''
        ]));
}

Now I am trying to write the Unit Test for these two functions. I could not figure it out the way to do it.

Here are routes

Route::get('/oauths/redirect', [AuthController::class, 'loginWithGoogle']);
Route::get('/oauths/callback', [AuthController::class, 'loginRedirectFromGoogle']);

Here is AuthControllerTest file

public function testRedirectWithGoogle()
{
    $abstractUser = Mockery::mock('Laravel\Socialite\Two\User');
    
    $abstractUser
        ->shouldReceive('getId')
        ->andReturn(rand())
        ->shouldReceive('getName')
        ->andReturn('test user')
        ->shouldReceive('getEmail')
        ->andReturn('test.user' . '@gmail.com')
        ->shouldReceive('getAvatar')
        ->andReturn('https://en.gravatar.com/userimage');

    $provider = Mockery::mock('Laravel\Socialite\Contracts\Provider');
    $provider->shouldReceive('user')->andReturn($abstractUser);

    Socialite::shouldReceive('driver')->with('google')
        ->andReturn($provider);
}
  • Surely this would be a case of just creating a [mock for the API](https://laravel.com/docs/8.x/mocking) and returning the values you would expect to retrieve from the API itself? This isn't a `code for me` service. What have you tried? – Jaquarh Dec 21 '21 at 06:31
  • @Jaquarh , can you check my question again? I just updated it when the function that I used mock function. – Sarah Manning Dec 21 '21 at 07:03
  • Sorry, I don't have access right now to reproduce locally. What is the issue with it? – Jaquarh Dec 21 '21 at 07:05
  • [This might be useful](https://stackoverflow.com/a/62225222/5897602) without having to need to mock. Otherwise, the accepted answer and your implementation seems similar. – Jaquarh Dec 21 '21 at 07:14

0 Answers0