Files
code-bang/backend/vendor/overtrue/socialite/tests/Providers/DingTalkTest.php
T
2026-09-22 16:43:47 +08:00

240 lines
8.1 KiB
PHP

<?php
namespace Providers;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
use Overtrue\Socialite\Exceptions\BadRequestException;
use Overtrue\Socialite\Exceptions\InvalidArgumentException;
use Overtrue\Socialite\Providers\DingTalk;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
class DingTalkTest extends TestCase
{
public function test_ding_talk_provider_has_correct_redirect_response()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$response = $provider->redirect();
$this->assertStringStartsWith('https://oapi.dingtalk.com/connect/qrconnect', $response);
$this->assertStringContainsString('redirect_uri=http%3A%2F%2Flocalhost%2Fcallback', $response);
$this->assertStringContainsString('appid=client_id', $response);
}
public function test_ding_talk_provider_configuration()
{
// Test with app_id configuration
$provider = new DingTalk([
'app_id' => 'test_app_id',
'app_secret' => 'test_app_secret',
'redirect_url' => 'http://localhost/callback',
]);
$this->assertSame('test_app_id', $provider->getClientId());
$this->assertSame('test_app_secret', $provider->getClientSecret());
// Test with appid configuration
$provider = new DingTalk([
'appid' => 'test_appid',
'appSecret' => 'test_appsecret',
'redirect_url' => 'http://localhost/callback',
]);
$this->assertSame('test_appid', $provider->getClientId());
$this->assertSame('test_appsecret', $provider->getClientSecret());
// Test with appId configuration
$provider = new DingTalk([
'appId' => 'test_appId',
'client_secret' => 'test_client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$this->assertSame('test_appId', $provider->getClientId());
$this->assertSame('test_client_secret', $provider->getClientSecret());
}
public function test_get_code_fields()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$getCodeFields = new ReflectionMethod(DingTalk::class, 'getCodeFields');
$getCodeFields->setAccessible(true);
$fields = $getCodeFields->invoke($provider->withState('test-state'));
$this->assertSame([
'appid' => 'client_id',
'grant_type' => 'authorization_code',
'code' => 'snsapi_login',
'redirect_uri' => 'http://localhost/callback',
], $fields);
}
public function test_create_signature()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'test_secret',
'redirect_url' => 'http://localhost/callback',
]);
$createSignature = new ReflectionMethod(DingTalk::class, 'createSignature');
$createSignature->setAccessible(true);
$time = 1234567890000;
$signature = $createSignature->invoke($provider, $time);
$this->assertIsString($signature);
$this->assertNotEmpty($signature);
}
public function test_user_from_code_success()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$mock = new MockHandler([
new Response(200, [], '{"errcode": 0, "user_info": {"nick": "Test User", "open_id": "test_openid"}}'),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$reflection = new \ReflectionObject($provider);
$httpClientProperty = $reflection->getProperty('httpClient');
$httpClientProperty->setAccessible(true);
$httpClientProperty->setValue($provider, $client);
$user = $provider->userFromCode('test_code');
$this->assertSame('Test User', $user->getName());
$this->assertSame('Test User', $user->getNickname());
$this->assertSame('test_openid', $user->getId());
}
public function test_throws_exception_when_user_info_missing()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$mock = new MockHandler([
new Response(200, [], '{"errcode": 0}'), // Missing user_info
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$reflection = new \ReflectionObject($provider);
$httpClientProperty = $reflection->getProperty('httpClient');
$httpClientProperty->setAccessible(true);
$httpClientProperty->setValue($provider, $client);
$this->expectException(AuthorizeFailedException::class);
$this->expectExceptionMessage('Authorization failed: missing user_info in response');
$provider->userFromCode('test_code');
}
public function test_throws_exception_when_error_code_non_zero()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$mock = new MockHandler([
new Response(200, [], '{"errcode": 1, "errmsg": "Error message"}'),
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$reflection = new \ReflectionObject($provider);
$httpClientProperty = $reflection->getProperty('httpClient');
$httpClientProperty->setAccessible(true);
$httpClientProperty->setValue($provider, $client);
$this->expectException(BadRequestException::class);
$provider->userFromCode('test_code');
}
public function test_get_token_url_throws_exception()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('not supported to get access token.');
$getTokenUrl = new ReflectionMethod(DingTalk::class, 'getTokenUrl');
$getTokenUrl->setAccessible(true);
$getTokenUrl->invoke($provider);
}
public function test_get_user_by_token_throws_exception()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Unable to use token get User.');
$getUserByToken = new ReflectionMethod(DingTalk::class, 'getUserByToken');
$getUserByToken->setAccessible(true);
$getUserByToken->invoke($provider, 'test_token');
}
public function test_map_user_to_object()
{
$provider = new DingTalk([
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect_url' => 'http://localhost/callback',
]);
$mapUserToObject = new ReflectionMethod(DingTalk::class, 'mapUserToObject');
$mapUserToObject->setAccessible(true);
$user = [
'nick' => 'Test User',
'open_id' => 'test_openid',
];
$result = $mapUserToObject->invoke($provider, $user);
$this->assertSame('test_openid', $result->getId());
$this->assertSame('Test User', $result->getName());
$this->assertSame('Test User', $result->getNickname());
$this->assertNull($result->getEmail());
$this->assertNull($result->getAvatar());
}
}