Files
wallabag-mirror/tests/unit/HttpClient/AuthenticatorTest.php
Jeremy Benoist 49a3b6e62d Fix flaky MondeDiplo test
Looks like when we fetch `monde-diplomatique.fr`, sometimes the request fails. When it fails, no title are extracted so we try to find a default title (`ContentProxy`->`setDefaultEntryTitle`) with became `57476` instead of `Quand Manille manœuvre`. See https://3v4l.org/tiUMt

To avoid that random error, we now mock the HTTP call to the website.
In addition, add a unit test login data are properly passed.
2026-06-15 09:40:59 +02:00

274 lines
8.8 KiB
PHP

<?php
namespace Wallabag\Tests\Unit\HttpClient;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Wallabag\HttpClient\Authenticator;
use Wallabag\SiteConfig\ArraySiteConfigBuilder;
use Wallabag\SiteConfig\LoginFormAuthenticator;
use Wallabag\SiteConfig\SiteConfig;
class AuthenticatorTest extends TestCase
{
public function testLoginIfRequiredNotRequired(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$login = $subscriber->loginIfRequired('http://www.example.com');
$this->assertFalse($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequired> will not require login', $records[0]['message']);
}
public function testLoginIfRequiredWithNotLoggedInUser(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$authenticator->expects($this->once())
->method('isLoggedIn')
->willReturn(false);
$authenticator->expects($this->once())
->method('login');
$builder = new ArraySiteConfigBuilder(['example.com' => ['requiresLogin' => true]]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$login = $subscriber->loginIfRequired('http://www.example.com');
$this->assertTrue($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequired> user is not logged in, attach authenticator', $records[0]['message']);
}
public function testLoginIfRequiredLogsInWithResolvedSiteConfig(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$authenticator->expects($this->once())
->method('isLoggedIn')
->with($this->callback(static function (SiteConfig $siteConfig): bool {
return 'example.com' === $siteConfig->getHost()
&& 'http://example.com/login' === $siteConfig->getLoginUri();
}))
->willReturn(false);
$authenticator->expects($this->once())
->method('login')
->with($this->callback(static function (SiteConfig $siteConfig): bool {
return 'example.com' === $siteConfig->getHost()
&& 'johndoe' === $siteConfig->getUsername()
&& 'unkn0wn' === $siteConfig->getPassword();
}));
$builder = new ArraySiteConfigBuilder(['example.com' => [
'requiresLogin' => true,
'loginUri' => 'http://example.com/login',
'username' => 'johndoe',
'password' => 'unkn0wn',
]]);
$subscriber = new Authenticator($builder, $authenticator);
$this->assertTrue($subscriber->loginIfRequired('http://www.example.com/article'));
}
public function testLoginIfRequestedNotRequired(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->once())
->method('getInfo')
->with($this->equalTo('url'))
->willReturn('http://www.example.com');
$login = $subscriber->loginIfRequested($response);
$this->assertFalse($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequested> will not require login', $records[0]['message']);
}
public function testLoginIfRequestedNotRequested(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$authenticator->expects($this->once())
->method('isLoginRequired')
->willReturn(false);
$builder = new ArraySiteConfigBuilder(['example.com' => [
'requiresLogin' => true,
'notLoggedInXpath' => '//html',
]]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->once())
->method('getInfo')
->with($this->equalTo('url'))
->willReturn('http://www.example.com');
$response->expects($this->once())
->method('getContent')
->willReturn('<html><body/></html>');
$login = $subscriber->loginIfRequested($response);
$this->assertFalse($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequested> retry with login not required', $records[0]['message']);
}
public function testLoginIfRequestedRequested(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$authenticator->expects($this->once())
->method('isLoginRequired')
->willReturn(true);
$authenticator->expects($this->once())
->method('login');
$builder = new ArraySiteConfigBuilder(['example.com' => [
'requiresLogin' => true,
'notLoggedInXpath' => '//html',
]]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->once())
->method('getInfo')
->with($this->equalTo('url'))
->willReturn('http://www.example.com');
$response->expects($this->once())
->method('getContent')
->willReturn('<html><body/></html>');
$login = $subscriber->loginIfRequested($response);
$this->assertTrue($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequested> retry with login required', $records[0]['message']);
}
public function testLoginIfRequestedRedirect(): void
{
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
->disableOriginalConstructor()
->getMock();
$builder = new ArraySiteConfigBuilder(['example.com' => [
'requiresLogin' => true,
'notLoggedInXpath' => '//html',
]]);
$subscriber = new Authenticator($builder, $authenticator);
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$subscriber->setLogger($logger);
$response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->once())
->method('getInfo')
->with($this->equalTo('url'))
->willReturn('http://www.example.com');
$response->expects($this->once())
->method('getContent')
->willReturn('');
$login = $subscriber->loginIfRequested($response);
$this->assertFalse($login);
$records = $handler->getRecords();
$this->assertCount(1, $records);
$this->assertSame('loginIfRequested> empty body, ignoring', $records[0]['message']);
}
}