mirror of
https://github.com/wallabag/wallabag.git
synced 2025-03-29 14:25:29 +00:00
Migrate from Guzzle to Symfony HttpClient - 1
This commit is contained in:
parent
9ff4cbee22
commit
6593f0c4df
5 changed files with 87 additions and 164 deletions
|
@ -47,6 +47,10 @@ framework:
|
||||||
X-Accept: 'application/json'
|
X-Accept: 'application/json'
|
||||||
request_html_function.client:
|
request_html_function.client:
|
||||||
scope: '.*'
|
scope: '.*'
|
||||||
|
browser.client:
|
||||||
|
scope: '.*'
|
||||||
|
verify_host: false
|
||||||
|
verify_peer: false
|
||||||
|
|
||||||
# Twig Configuration
|
# Twig Configuration
|
||||||
twig:
|
twig:
|
||||||
|
|
|
@ -214,6 +214,10 @@ services:
|
||||||
|
|
||||||
GuzzleHttp\Cookie\CookieJar: ~
|
GuzzleHttp\Cookie\CookieJar: ~
|
||||||
|
|
||||||
|
Symfony\Component\BrowserKit\HttpBrowser:
|
||||||
|
arguments:
|
||||||
|
$client: '@browser.client'
|
||||||
|
|
||||||
Wallabag\Helper\HttpClientFactory:
|
Wallabag\Helper\HttpClientFactory:
|
||||||
calls:
|
calls:
|
||||||
- ['addSubscriber', ['@Wallabag\Guzzle\AuthenticatorSubscriber']]
|
- ['addSubscriber', ['@Wallabag\Guzzle\AuthenticatorSubscriber']]
|
||||||
|
|
|
@ -61,15 +61,10 @@ class AuthenticatorSubscriber implements SubscriberInterface, LoggerAwareInterfa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = $event->getClient();
|
if (!$this->authenticator->isLoggedIn($config)) {
|
||||||
|
|
||||||
if (!$this->authenticator->isLoggedIn($config, $client)) {
|
|
||||||
$this->logger->debug('loginIfRequired> user is not logged in, attach authenticator');
|
$this->logger->debug('loginIfRequired> user is not logged in, attach authenticator');
|
||||||
|
|
||||||
$emitter = $client->getEmitter();
|
$this->authenticator->login($config);
|
||||||
$emitter->detach($this);
|
|
||||||
$this->authenticator->login($config, $client);
|
|
||||||
$emitter->attach($this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,12 +93,7 @@ class AuthenticatorSubscriber implements SubscriberInterface, LoggerAwareInterfa
|
||||||
$this->logger->debug('loginIfRequested> retry #' . $this->retries . ' with login ' . ($isLoginRequired ? '' : 'not ') . 'required');
|
$this->logger->debug('loginIfRequested> retry #' . $this->retries . ' with login ' . ($isLoginRequired ? '' : 'not ') . 'required');
|
||||||
|
|
||||||
if ($isLoginRequired && $this->retries < self::MAX_RETRIES) {
|
if ($isLoginRequired && $this->retries < self::MAX_RETRIES) {
|
||||||
$client = $event->getClient();
|
$this->authenticator->login($config);
|
||||||
|
|
||||||
$emitter = $client->getEmitter();
|
|
||||||
$emitter->detach($this);
|
|
||||||
$this->authenticator->login($config, $client);
|
|
||||||
$emitter->attach($this);
|
|
||||||
|
|
||||||
$event->retry();
|
$event->retry();
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
namespace Wallabag\SiteConfig;
|
namespace Wallabag\SiteConfig;
|
||||||
|
|
||||||
use GuzzleHttp\ClientInterface;
|
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||||
use GuzzleHttp\Cookie\CookieJar;
|
|
||||||
use Symfony\Component\DomCrawler\Crawler;
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
||||||
|
|
||||||
class LoginFormAuthenticator
|
class LoginFormAuthenticator
|
||||||
{
|
{
|
||||||
|
private HttpBrowser $browser;
|
||||||
private ExpressionLanguage $expressionLanguage;
|
private ExpressionLanguage $expressionLanguage;
|
||||||
|
|
||||||
public function __construct(AuthenticatorProvider $authenticatorProvider)
|
public function __construct(HttpBrowser $browser, AuthenticatorProvider $authenticatorProvider)
|
||||||
{
|
{
|
||||||
|
$this->browser = $browser;
|
||||||
$this->expressionLanguage = new ExpressionLanguage(null, [$authenticatorProvider]);
|
$this->expressionLanguage = new ExpressionLanguage(null, [$authenticatorProvider]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,17 +23,14 @@ class LoginFormAuthenticator
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function login(SiteConfig $siteConfig, ClientInterface $guzzle)
|
public function login(SiteConfig $siteConfig)
|
||||||
{
|
{
|
||||||
$postFields = [
|
$postFields = [
|
||||||
$siteConfig->getUsernameField() => $siteConfig->getUsername(),
|
$siteConfig->getUsernameField() => $siteConfig->getUsername(),
|
||||||
$siteConfig->getPasswordField() => $siteConfig->getPassword(),
|
$siteConfig->getPasswordField() => $siteConfig->getPassword(),
|
||||||
] + $this->getExtraFields($siteConfig);
|
] + $this->getExtraFields($siteConfig);
|
||||||
|
|
||||||
$guzzle->post(
|
$this->browser->request('POST', $siteConfig->getLoginUri(), $postFields);
|
||||||
$siteConfig->getLoginUri(),
|
|
||||||
['body' => $postFields, 'allow_redirects' => true, 'verify' => false]
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -42,15 +40,12 @@ class LoginFormAuthenticator
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isLoggedIn(SiteConfig $siteConfig, ClientInterface $guzzle)
|
public function isLoggedIn(SiteConfig $siteConfig)
|
||||||
{
|
{
|
||||||
if (($cookieJar = $guzzle->getDefaultOption('cookies')) instanceof CookieJar) {
|
foreach ($this->browser->getCookieJar()->all() as $cookie) {
|
||||||
/** @var \GuzzleHttp\Cookie\SetCookie $cookie */
|
// check required cookies
|
||||||
foreach ($cookieJar as $cookie) {
|
if ($cookie->getDomain() === $siteConfig->getHost()) {
|
||||||
// check required cookies
|
return true;
|
||||||
if ($cookie->getDomain() === $siteConfig->getHost()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
namespace Tests\Wallabag\SiteConfig;
|
namespace Tests\Wallabag\SiteConfig;
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Message\Response;
|
|
||||||
use GuzzleHttp\Stream\Stream;
|
|
||||||
use GuzzleHttp\Subscriber\Mock;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||||
use Symfony\Component\HttpClient\MockHttpClient;
|
use Symfony\Component\HttpClient\MockHttpClient;
|
||||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
||||||
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
||||||
use Wallabag\SiteConfig\SiteConfig;
|
use Wallabag\SiteConfig\SiteConfig;
|
||||||
|
@ -30,19 +29,17 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = new Response(
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
200,
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
['content-type' => 'text/html'],
|
$browser = new HttpBrowser($browserClient);
|
||||||
Stream::factory('')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response]));
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse('', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$res = $auth->login($siteConfig, $guzzle);
|
$res = $auth->login($siteConfig);
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
@ -63,19 +60,17 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = new Response(
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
200,
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
['content-type' => 'text/html'],
|
$browser = new HttpBrowser($browserClient);
|
||||||
Stream::factory('<html></html>')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response, $response]));
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$res = $auth->login($siteConfig, $guzzle);
|
$res = $auth->login($siteConfig);
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
@ -96,121 +91,44 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = $this->getMockBuilder(Response::class)
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
->disableOriginalConstructor()
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
|
$browser = $this->getMockBuilder(HttpBrowser::class)
|
||||||
|
->setConstructorArgs([$browserClient])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
$browser->expects($this->any())
|
||||||
$response->expects($this->any())
|
->method('request')
|
||||||
->method('getBody')
|
|
||||||
->willReturn(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'));
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getStatusCode')
|
|
||||||
->willReturn(200);
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'), ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$client = $this->getMockBuilder(Client::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('post')
|
|
||||||
->with(
|
->with(
|
||||||
|
$this->equalTo('POST'),
|
||||||
$this->equalTo('https://aoc.media/wp-admin/admin-ajax.php'),
|
$this->equalTo('https://aoc.media/wp-admin/admin-ajax.php'),
|
||||||
$this->equalTo([
|
$this->equalTo([
|
||||||
'body' => [
|
'nom' => 'johndoe',
|
||||||
'nom' => 'johndoe',
|
'password' => 'unkn0wn',
|
||||||
'password' => 'unkn0wn',
|
'security' => 'c506c1b8bc',
|
||||||
'security' => 'c506c1b8bc',
|
'action' => 'login_user',
|
||||||
'action' => 'login_user',
|
|
||||||
],
|
|
||||||
'allow_redirects' => true,
|
|
||||||
'verify' => false,
|
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
->willReturn($response);
|
;
|
||||||
|
|
||||||
$client->expects($this->any())
|
$requestHtmlFunctionResponse = $this->getMockBuilder(ResponseInterface::class)->getMock();
|
||||||
->method('get')
|
$requestHtmlFunctionResponse->expects($this->any())
|
||||||
|
->method('getContent')
|
||||||
|
->willReturn(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'))
|
||||||
|
;
|
||||||
|
$requestHtmlFunctionClient = $this->getMockBuilder(HttpClientInterface::class)->getMock();
|
||||||
|
$requestHtmlFunctionClient->expects($this->any())
|
||||||
|
->method('request')
|
||||||
->with(
|
->with(
|
||||||
|
$this->equalTo('GET'),
|
||||||
$this->equalTo('https://aoc.media/'),
|
$this->equalTo('https://aoc.media/'),
|
||||||
$this->equalTo([])
|
|
||||||
)
|
)
|
||||||
->willReturn($response);
|
->willReturn($requestHtmlFunctionResponse)
|
||||||
|
;
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$res = $auth->login($siteConfig, $client);
|
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$res = $auth->login($siteConfig);
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginPostWithExtraFieldsWithData()
|
|
||||||
{
|
|
||||||
$siteConfig = new SiteConfig([
|
|
||||||
'host' => 'nextinpact.com',
|
|
||||||
'loginUri' => 'https://compte.nextinpact.com/Account/Login',
|
|
||||||
'usernameField' => 'UserName',
|
|
||||||
'passwordField' => 'Password',
|
|
||||||
'extraFields' => [
|
|
||||||
'__RequestVerificationToken' => '@=xpath(\'//form[@action="/Account/Login"]/input[@name="__RequestVerificationToken"]\', request_html(\'https://compte.nextinpact.com/Account/Login?http://www.nextinpact.com/\', {\'headers\': {\'X-Requested-With\':\'XMLHttpRequest\'}}))',
|
|
||||||
'returnUrl' => 'https://www.nextinpact.com/news/102835-pour-cour-comptes-fonctionnement-actuel-vote-par-internet-nest-pas-satisfaisant.htm',
|
|
||||||
],
|
|
||||||
'username' => 'johndoe',
|
|
||||||
'password' => 'unkn0wn',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response = $this->getMockBuilder(Response::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getBody')
|
|
||||||
->willReturn(file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getStatusCode')
|
|
||||||
->willReturn(200);
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse(file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'), ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$client = $this->getMockBuilder(Client::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('post')
|
|
||||||
->with(
|
|
||||||
$this->equalTo('https://compte.nextinpact.com/Account/Login'),
|
|
||||||
$this->equalTo([
|
|
||||||
'body' => [
|
|
||||||
'UserName' => 'johndoe',
|
|
||||||
'Password' => 'unkn0wn',
|
|
||||||
'__RequestVerificationToken' => 's6x2QcnQDUL92mkKSi_JuUBXcgUYx_Plf-KyQ2eJypKAjQZIeTvaFHOsfEdTrcSXt3dt2CW39V7r9V16LUtvjszodAU1',
|
|
||||||
'returnUrl' => 'https://www.nextinpact.com/news/102835-pour-cour-comptes-fonctionnement-actuel-vote-par-internet-nest-pas-satisfaisant.htm',
|
|
||||||
],
|
|
||||||
'allow_redirects' => true,
|
|
||||||
'verify' => false,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('get')
|
|
||||||
->with(
|
|
||||||
$this->equalTo('https://compte.nextinpact.com/Account/Login?http://www.nextinpact.com/'),
|
|
||||||
$this->equalTo([
|
|
||||||
'headers' => [
|
|
||||||
'X-Requested-With' => 'XMLHttpRequest',
|
|
||||||
],
|
|
||||||
])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$res = $auth->login($siteConfig, $client);
|
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
@ -225,10 +143,16 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient();
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
||||||
|
|
||||||
$this->assertFalse($loginRequired);
|
$this->assertFalse($loginRequired);
|
||||||
|
@ -245,10 +169,16 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'notLoggedInXpath' => '//h2[@class="title_reserve_article"]',
|
'notLoggedInXpath' => '//h2[@class="title_reserve_article"]',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient();
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-article.html'));
|
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-article.html'));
|
||||||
|
|
||||||
$this->assertTrue($loginRequired);
|
$this->assertTrue($loginRequired);
|
||||||
|
|
Loading…
Reference in a new issue