首页 > 解决方案 > 如何伪造社交名流`userFromToken`方法进行测试?

问题描述

我已经完成了对类似问题的搜索,其中大多数是包含redirect和内容的有状态实现。就我而言,我不需要它们,因为提供者的身份验证是在客户端设备(Android)上本地完成的。

我所做的是将令牌从设备传递到服务器并使用它来获取用户信息以创建新帐户和访问令牌,因此我的服务器知道谁试图从哪个提供商访问 api。

我做了一个测试,但我不能让它工作

public function test_user_can_login_with_socialite_provider()
{
    $user = User::factory()->has(Provider::factory())->createOne();
    $provider = $user->providers->first(); // => name: google, token: fake_token

    $params = ['provider' => $provider->name, 'provider_token' => $provider->token];
    $response = $this->postJson(route('auth.login.provider'), $params);
    $response->dump();
    $response->assertOk();
    $response->assertJsonFragment(['token']);

    Socialite::shouldReceive('driver')->once()->with($params['provider'])->andReturnSelf();
    Socialite::shouldReceive('userFromToken')->once()->with($params['provider_token'])->andReturn($user);
}

测试失败500 error,这里是转储。

{#2667
  +"message": """
    Client error: `GET https://www.googleapis.com/oauth2/v3/userinfo?prettyPrint=false` resulted in a `401 Unauthorized` response:\n
    {\n
      "error": "invalid_request",\n
      "error_description": "Invalid Credentials"\n
    }\n
    ...

我的实现看起来像这样

public function loginWithProvider(RequestLoginWithProvider $request)
{
    $provider = Socialite::driver($request->provider)->userFromToken(
        $request->provider_token
    );

    $user = User::firstOrCreate(
        ['email' => $provider->getEmail()],
        ['email_verified_at' => now(), 'name' => $provider->getName()],
    );

    $user->providers()->updateOrCreate(
        ['name' => $request->name, 'provider_id' => $provider->getId()],
        ['avatar' => $provider->getAvatar()],
    );

    return $user->createToken($request->provider)->plainTextToken;
}

我想知道我是否可以做类似的事情,Notification::fake()这样它就不会真正调用google api。但由于文档没有提到任何关于测试社交名流的内容,我有点迷路了。

标签: laravellaravel-socialite

解决方案


推荐阅读