2016-02-09 8 views
6

मेरे पास एक ऐसा एप्लिकेशन है जो सोशलाइट का उपयोग करता है, मैं गिथब प्रमाणीकरण के लिए परीक्षण बनाना चाहता हूं, इसलिए मैंने सोशलसाइट फेकाडे का इस्तेमाल सोशलसाइट driver विधि पर कॉल करने के लिए किया, लेकिन जब मैं अपना परीक्षण चलाता हूं तो यह मुझे बताता है कि मैं शून्य प्रकार पर मूल्य प्राप्त करने की कोशिश कर रहा हूं।लैरवेल सोशलाइट का परीक्षण कैसे करें

नीचे परीक्षण मैं

public function testGithubLogin() 
{ 
    Socialite::shouldReceive('driver') 
     ->with('github') 
     ->once(); 
    $this->call('GET', '/github/authorize')->isRedirection(); 
} 

नीचे लिखा है परीक्षण के कार्यान्वयन

public function authorizeProvider($provider) 
{ 
    return Socialite::driver($provider)->redirect(); 
} 

मुझे समझ में क्यों यह इस तरह के परिणाम वापस कर सकती है क्योंकि Sociallite::driver($provider)Laravel\Socialite\Two\GithubProvider का एक उदाहरण देता है, और विचार कि मैं इस मान को तुरंत चालू करने में असमर्थ हूं, रिटर्न प्रकार निर्दिष्ट करना असंभव होगा। मुझे नियंत्रक का सफलतापूर्वक परीक्षण करने में मदद चाहिए। धन्यवाद

+0

मुझे लगता है कि आप 'सोशलाइट :: कंधे (' ड्राइवर-> रीडायरेक्ट ') चाहते हैं। – ceejayoz

+0

@ceejayoz यह काम नहीं करता है, यह शिकायत करता है कि यह विधि 'ड्राइवर-> रीडायरेक्ट' –

उत्तर

4

ठीक है, दोनों उत्तर बहुत अच्छे थे, लेकिन उनके पास बहुत से कोड हैं जिनकी आवश्यकता नहीं है, और मैं उनके जवाब का अनुमान लगाने में सक्षम था।

यह सब मुझे करने की ज़रूरत है।

सबसे पहले सोशलाइट प्रयोक्ता प्रकार नकली

$abstractUser = Mockery::mock('Laravel\Socialite\Two\User') 

दूसरा, इसकी विधि के लिए उम्मीद मूल्यों को निर्धारित कॉल

$abstractUser 
    ->shouldReceive('getId') 
    ->andReturn(rand()) 
    ->shouldReceive('getName') 
    ->andReturn(str_random(10)) 
    ->shouldReceive('getEmail') 
    ->andReturn(str_random(10) . '@gmail.com') 
    ->shouldReceive('getAvatar') 
    ->andReturn('https://en.gravatar.com/userimage'); 

तीसरा, आप प्रदाता/उपयोगकर्ता कॉल

Socialite::shouldReceive('driver->user')->andReturn($abstractUser); 
नकली करने की जरूरत है

फिर आखिरकार आप अपने दावे

लिखते हैं
$this->visit('/auth/google/callback') 
    ->seePageIs('/') 
+0

बहुत याद आ रही है –

+0

बहुत कुछ नहीं, बस चालक मॉक मैं जोड़ना भूल गया। –

+0

मैं इस भाग को समझ नहीं पा रहा हूं 'सोशलसाइट :: कंधे (' ड्राइवर-> उपयोगकर्ता ') -> और वापसी ($ abstractValidUser);', कुछ याद आ रही है? 'ड्राइवर-> उपयोगकर्ता' भाग बिल्कुल ठीक है – LTroya

5
$provider = Mockery::mock('Laravel\Socialite\Contracts\Provider'); 
$provider->shouldReceive('redirect')->andReturn('Redirected'); 
$providerName = class_basename($provider); 
//Call your model factory here 
$socialAccount = factory('LearnCast\User')->create(['provider' => $providerName]); 

$abstractUser = Mockery::mock('Laravel\Socialite\Two\User'); 
// Get the api user object here 
$abstractUser->shouldReceive('getId') 
      ->andReturn($socialAccount->provider_user_id) 
      ->shouldReceive('getEmail') 
      ->andReturn(str_random(10).'@noemail.app') 
      ->shouldReceive('getNickname') 
      ->andReturn('Laztopaz') 
      ->shouldReceive('getAvatar') 
      ->andReturn('https://en.gravatar.com/userimage'); 

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

Socialite::shouldReceive('driver')->with('facebook')->andReturn($provider); 

// After Oauth redirect back to the route 
$this->visit('/auth/facebook/callback') 
// See the page that the user login into 
->seePageIs('/'); 

नोट: use अपनी कक्षा

उपयोग Laravel \ सोशलाइट \ Facades \ सोशलाइट के शीर्ष पर सोशलाइट पैकेज;

मुझे एक ही समस्या थी, लेकिन मैं ऊपर की तकनीक का उपयोग करके इसे हल करने में सक्षम था; @ceejayoz। आशा है कि ये आपकी मदद करेगा।

4

यह करना मुश्किल हो सकता है, लेकिन मेरा मानना ​​है कि यह अधिक पठनीय परीक्षणों के लिए बनाता है। उम्मीद है कि आप मुझे जो वर्णन करने जा रहे हैं उसे सरल बनाने में मेरी सहायता करेंगे।

मेरा विचार http अनुरोधों को रोकना है। फेसबुक को ध्यान में रखते हुए, उनमें से दो हैं: 1) /oauth/access_token (एक्सेस टोकन प्राप्त करने के लिए), 2) /me (उपयोगकर्ता के बारे में डेटा प्राप्त करने के लिए)।

कि मैं अस्थायी रूप से mitmproxy को php संलग्न vcr स्थिरता बनाने के लिए:

  1. बताएँ php http प्रॉक्सी का उपयोग करने (.env फ़ाइल निम्न पंक्तियां जोड़ें):

    HTTP_PROXY=http://localhost:8080 
    HTTPS_PROXY=http://localhost:8080 
    
  2. बताएँ php जहां प्रॉक्सी का प्रमाणपत्र है: openssl.cafile = /etc/php/mitmproxy-ca-cert.pemphp.ini जोड़ें। या उस मामले के लिए curl.cainfo

  3. php-fpm पुनरारंभ करें।
  4. mitmproxy प्रारंभ करें।
  5. अपने ब्राउज़र को mitmproxy के माध्यम से भी कनेक्ट करें।
  6. फेसबुक पर उपयोग कर रहे साइट पर लॉग इन करें (यहां कोई टीडीडी नहीं है)।

    प्रेस zmitmproxy (Cmitmproxy < 0,18 के लिए) में यदि हो जरूरत फेसबुक के लिए पुनः निर्देशित से पहले अनुरोध (प्रवाह) सूची खाली करने के लिए। या वैकल्पिक रूप से, अतिरिक्त अनुरोधों को फ़िल्टर करने के लिए graph.facebook.com के साथ f कमांड (lmitmproxy < 0.18) का उपयोग करें।

    ध्यान दें, ट्विटर के लिए आपको league/oauth1-client 1.7 या नए की आवश्यकता होगी। एक guzzle/guzzle से guzzlehttp/guzzle पर स्विच किया गया। अन्यथा आप लॉग इन करने में असमर्थ होंगे।

  7. mimtproxy से tests/fixtures/facebook से डेटा कॉपी करें। मैं yaml प्रारूप का प्रयोग किया और यहाँ यह क्या लगता है जैसे:

    - 
        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":"..."}' 
    

    कि आप आदेश E उपयोग कर सकते हैं अगर आप mitmproxy> = 0.18 मिल गया है के लिए। वैकल्पिक रूप से, कमांड P का उपयोग करें। यह क्लिपबोर्ड के लिए अनुरोध/प्रतिक्रिया की प्रतिलिपि बनाता है। यदि आप फ़ाइल को दाएं सहेजने के लिए mitmproxy चाहते हैं, तो आप इसे DISPLAY= mitmproxy के साथ चला सकते हैं।

    मुझे php-vcr की रिकॉर्डिंग सुविधाओं का उपयोग करने का कोई तरीका नहीं दिख रहा है, क्योंकि मैं पूरे वर्कफ़्लो का परीक्षण नहीं कर रहा हूं।

इसी के साथ

मैं (हाँ, वे उन सभी मूल्यों डॉट्स द्वारा प्रतिस्थापित के साथ ठीक कर रहे हैं, के रूप में है कॉपी करने के लिए स्वतंत्र लग रहा है और) निम्नलिखित परीक्षणों लिखने के लिए सक्षम था।

नोट नोट करें, फिक्स्चर laravel/socialite संस्करण पर निर्भर करता है। मुझे फेसबुक के साथ कोई समस्या थी। संस्करण 2.0.16laravel/socialite में टोकन पहुंच प्राप्त करने के लिए post requests करना शुरू कर दिया। फेसबुक यूआरएल में api version भी है।

ये फिक्स्चर 2.0.14 के लिए हैं। एक तरह से इससे निपटने के लिए laravel/socialiterequire-devcomposer.json फ़ाइल के खंड के रूप में अच्छी तरह से (सख्त संस्करण विनिर्देशन के साथ) में निर्भरता के लिए यह सुनिश्चित करें कि socialite विकास के वातावरण में उचित संस्करण का है (उम्मीद है, composer उत्पादन वातावरण में require-dev खंड में एक पर ध्यान नहीं देगा ।) आपको उत्पादन वातावरण में 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 फ़ाइल के बारे में बात कर रहा हूं, अर्थात् यूआरएल को रीडायरेक्ट करने के बारे में। मैंने इसे इस तरह संभाला:

<?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 भाग से छुटकारा पा सकते। असल में, पूरी बात vcr अकेले (mitmproxy) के साथ की जा सकती है।

+0

विधि को नहीं देखता है, तो यह php-vcr का उपयोग करके एक वास्तविक दिलचस्प विचार है। –

संबंधित मुद्दे