これは難しいかもしれませんが、より読みやすいテストができると思います。うまくいけば、あなたが私が描写しようとしているものを簡略化するのを助けるでしょう。
私の考えは、httpリクエストをスタブすることです。 Facebookには、1)/oauth/access_token
(アクセストークンを取得する)、2)/me
(ユーザーに関するデータを取得する)の2つがあります。
(.env
ファイルに次の行を追加します)HTTPプロキシを使用するようにphp
教える::そのために
は私が一時的にvcr
フィクスチャを作成するmitmproxy
にphp
を添付
HTTP_PROXY=http://localhost:8080
HTTPS_PROXY=http://localhost:8080
に知らせますphp
プロキシの証明書は次のとおりです。openssl.cafile = /etc/php/mitmproxy-ca-cert.pem
〜php.ini
を追加します。またはcurl.cainfo
です。
- 再起動
php-fpm
。
- 開始
mitmproxy
。
-
ブラウザを
mitmproxy
まで接続してください。
開発中のサイトにfacebook(ここではTDDなし)を使用してログインしてください。必要であればログインfacebookにリダイレクトする前に、要求(フロー)のリストをクリアするmitmproxy
(mitmproxy
< 0.18用C
)で
押しz
。または、f
コマンド(l
はmitmproxy
< 0.18)とgraph.facebook.com
を使用して余分なリクエストを除外します。
twitterの場合、league/oauth1-client
1.7以上が必要です。 1つはguzzle/guzzle
からguzzlehttp/guzzle
に切り替えました。それ以外の場合はログインできません。
mimtproxy
からtests/fixtures/facebook
にデータをコピーしてください。私はyaml
フォーマットを使用し、ここでは次のようになります。あなたは> = 0.18 mitmproxy
を持っている場合は、コマンドE
を使用することができるため
-
request:
method: GET
url: https://graph.facebook.com/oauth/access_token?client_id=...&client_secret=...&code=...&redirect_uri=...
response:
status:
http_version: '1.1'
code: 200
message: OK
body: access_token=...&expires=...
-
request:
method: GET
url: https://graph.facebook.com/v2.5/me?access_token=...&appsecret_proof=...&fields=first_name,last_name,email,gender,verified
response:
status:
http_version: '1.1'
code: 200
message: OK
body: '{"first_name":"...","last_name":"...","email":"...","gender":"...","verified":true,"id":"..."}'
。あるいは、コマンドP
を使用してください。要求/応答をクリップボードにコピーします。 mitmproxy
にファイルを保存する場合は、DISPLAY= mitmproxy
で実行できます。
ワークフロー全体をテストしているわけではないので、php-vcr
の録画機能を使用する方法はありません。それと
私は、次のテストを書くことができました(はい、彼らはドットに置き換え、すべてのそれらの値と罰金です、であるようにコピーして自由に感じます)。
注記でも、備品はlaravel/socialite
のバージョンに依存します。私はFacebookに問題があった。バージョン2.0.16
laravel/socialite
が開始しましたpost requestsアクセストークンを取得します。また、FacebookのURLにapi versionがあります。
これらの製品は2.0.14
です。それに対処する一つの方法は、(願わくば、composer
は、本番環境でrequire-dev
セクションに1を無視しますsocialite
は、開発環境で適切なバージョンであることを保証するために(厳密バージョン仕様に)だけでなくcomposer.json
ファイルのrequire-dev
セクションにlaravel/socialite
依存関係を持つことです。)実稼働環境でcomposer install --no-dev
を実行することを考慮してください。
AuthController_HandleFacebookCallbackTest.php
:
<?php
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Auth;
use VCR\VCR;
use App\User;
class AuthController_HandleFacebookCallbackTest extends TestCase
{
use DatabaseTransactions;
static function setUpBeforeClass()
{
VCR::configure()->enableLibraryHooks(['stream_wrapper', 'curl'])
->enableRequestMatchers([
'method',
'url',
]);
}
/**
* @vcr facebook
*/
function testCreatesUserWithCorrespondingName()
{
$this->doCallbackRequest();
$this->assertEquals('John Doe', User::first()->name);
}
/**
* @vcr facebook
*/
function testCreatesUserWithCorrespondingEmail()
{
$this->doCallbackRequest();
$this->assertEquals('[email protected]', User::first()->email);
}
/**
* @vcr facebook
*/
function testCreatesUserWithCorrespondingFbId()
{
$this->doCallbackRequest();
$this->assertEquals(123, User::first()->fb_id);
}
/**
* @vcr facebook
*/
function testCreatesUserWithFbData()
{
$this->doCallbackRequest();
$this->assertNotEquals('', User::first()->fb_data);
}
/**
* @vcr facebook
*/
function testRedirectsToHomePage()
{
$this->doCallbackRequest();
$this->assertRedirectedTo('/');
}
/**
* @vcr facebook
*/
function testAuthenticatesUser()
{
$this->doCallbackRequest();
$this->assertEquals(User::first()->id, Auth::user()->id);
}
/**
* @vcr facebook
*/
function testDoesntCreateUserIfAlreadyExists()
{
$user = factory(User::class)->create([
'fb_id' => 123,
]);
$this->doCallbackRequest();
$this->assertEquals(1, User::count());
}
function doCallbackRequest()
{
return $this->withSession([
'state' => '...',
])->get('/auth/facebook/callback?' . http_build_query([
'state' => '...',
]));
}
}
tests/fixtures/facebook
:
-
request:
method: GET
url: https://graph.facebook.com/oauth/access_token
response:
status:
http_version: '1.1'
code: 200
message: OK
body: access_token=...
-
request:
method: GET
url: https://graph.facebook.com/v2.5/me
response:
status:
http_version: '1.1'
code: 200
message: OK
body: '{"first_name":"John","last_name":"Doe","email":"john.doe\u0040gmail.com","id":"123"}'
AuthController_HandleTwitterCallbackTest.php
:
<?php
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Auth;
use VCR\VCR;
use League\OAuth1\Client\Credentials\TemporaryCredentials;
use App\User;
class AuthController_HandleTwitterCallbackTest extends TestCase
{
use DatabaseTransactions;
static function setUpBeforeClass()
{
VCR::configure()->enableLibraryHooks(['stream_wrapper', 'curl'])
->enableRequestMatchers([
'method',
'url',
]);
}
/**
* @vcr twitter
*/
function testCreatesUserWithCorrespondingName()
{
$this->doCallbackRequest();
$this->assertEquals('joe', User::first()->name);
}
/**
* @vcr twitter
*/
function testCreatesUserWithCorrespondingTwId()
{
$this->doCallbackRequest();
$this->assertEquals(123, User::first()->tw_id);
}
/**
* @vcr twitter
*/
function testCreatesUserWithTwData()
{
$this->doCallbackRequest();
$this->assertNotEquals('', User::first()->tw_data);
}
/**
* @vcr twitter
*/
function testRedirectsToHomePage()
{
$this->doCallbackRequest();
$this->assertRedirectedTo('/');
}
/**
* @vcr twitter
*/
function testAuthenticatesUser()
{
$this->doCallbackRequest();
$this->assertEquals(User::first()->id, Auth::user()->id);
}
/**
* @vcr twitter
*/
function testDoesntCreateUserIfAlreadyExists()
{
$user = factory(User::class)->create([
'tw_id' => 123,
]);
$this->doCallbackRequest();
$this->assertEquals(1, User::count());
}
function doCallbackRequest()
{
$temporaryCredentials = new TemporaryCredentials();
$temporaryCredentials->setIdentifier('...');
$temporaryCredentials->setSecret('...');
return $this->withSession([
'oauth.temp' => $temporaryCredentials,
])->get('/auth/twitter/callback?' . http_build_query([
'oauth_token' => '...',
'oauth_verifier' => '...',
]));
}
}
tests/fixtures/twitter
:
-
request:
method: POST
url: https://api.twitter.com/oauth/access_token
response:
status:
http_version: '1.1'
code: 200
message: OK
body: oauth_token=...&oauth_token_secret=...
-
request:
method: GET
url: https://api.twitter.com/1.1/account/verify_credentials.json
response:
status:
http_version: '1.1'
code: 200
message: OK
body: '{"id_str":"123","name":"joe","screen_name":"joe","location":"","description":"","profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/456\/userpic.png"}'
AuthController_HandleGoogleCallbackTest.php
:
<?php
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Auth;
use VCR\VCR;
use App\User;
class AuthController_HandleGoogleCallbackTest extends TestCase
{
use DatabaseTransactions;
static function setUpBeforeClass()
{
VCR::configure()->enableLibraryHooks(['stream_wrapper', 'curl'])
->enableRequestMatchers([
'method',
'url',
]);
}
/**
* @vcr google
*/
function testCreatesUserWithCorrespondingName()
{
$this->doCallbackRequest();
$this->assertEquals('John Doe', User::first()->name);
}
/**
* @vcr google
*/
function testCreatesUserWithCorrespondingEmail()
{
$this->doCallbackRequest();
$this->assertEquals('[email protected]', User::first()->email);
}
/**
* @vcr google
*/
function testCreatesUserWithCorrespondingGpId()
{
$this->doCallbackRequest();
$this->assertEquals(123, User::first()->gp_id);
}
/**
* @vcr google
*/
function testCreatesUserWithGpData()
{
$this->doCallbackRequest();
$this->assertNotEquals('', User::first()->gp_data);
}
/**
* @vcr google
*/
function testRedirectsToHomePage()
{
$this->doCallbackRequest();
$this->assertRedirectedTo('/');
}
/**
* @vcr google
*/
function testAuthenticatesUser()
{
$this->doCallbackRequest();
$this->assertEquals(User::first()->id, Auth::user()->id);
}
/**
* @vcr google
*/
function testDoesntCreateUserIfAlreadyExists()
{
$user = factory(User::class)->create([
'gp_id' => 123,
]);
$this->doCallbackRequest();
$this->assertEquals(1, User::count());
}
function doCallbackRequest()
{
return $this->withSession([
'state' => '...',
])->get('/auth/google/callback?' . http_build_query([
'state' => '...',
]));
}
}
tests/fixtures/google
:
-
request:
method: POST
url: https://accounts.google.com/o/oauth2/token
response:
status:
http_version: '1.1'
code: 200
message: OK
body: access_token=...
-
request:
method: GET
url: https://www.googleapis.com/plus/v1/people/me
response:
status:
http_version: '1.1'
code: 200
message: OK
body: '{"emails":[{"value":"[email protected]"}],"id":"123","displayName":"John Doe","image":{"url":"https://googleusercontent.com/photo.jpg"}}'
注意。あなたはphp-vcr/phpunit-testlistener-vcr
が必要であり、あなたがあなたのphpunit.xml
に次の行を持っていることを確認してください:
<listeners>
<listener class="PHPUnit_Util_Log_VCR" file="vendor/php-vcr/phpunit-testlistener-vcr/PHPUnit/Util/Log/VCR.php"/>
</listeners>
もテストを実行する際に、設定されていない$_SERVER['HTTP_HOST']
との問題がありました。私はここでconfig/services.php
ファイル、つまりリダイレクトURLについて話しています。
<?php
$app = include dirname(__FILE__) . '/app.php';
return [
...
'facebook' => [
...
'redirect' => (isset($_SERVER['HTTP_HOST']) ? 'http://' . $_SERVER['HTTP_HOST'] : $app['url']) . '/auth/facebook/callback',
],
];
特に美しくはないが、私はより良い方法を見つけることができなかった:私はそうのようにそれを処理していました。私はそこにconfig('app.url')
を使用しようとしていましたが、設定ファイルでは動作しません。あなたは、このメソッドを削除するテストを実行し、どのようなビデオデッキ記録と備品の要求部を更新することによりsetUpBeforeClass
一部を取り除くことができ
UPD。実際には、すべてがvcr
(mitmproxy
)だけで行われるかもしれません。
私はあなたが 'Socialite :: shouldReceive( 'driver-> redirect')'をしたいと思うと思います。 – ceejayoz
@ceejayozそれは動作しません、 'ドライバ - >リダイレクト'の方法が表示されないと文句を言います –