mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-08 04:18:52 +00:00
[ticket/17413] Add full test coverage for turnstile class
PHPBB-17413
This commit is contained in:
parent
61e265e4b4
commit
3e938ea765
1 changed files with 175 additions and 1 deletions
|
@ -15,16 +15,18 @@ use phpbb\captcha\plugins\confirm_type;
|
||||||
use phpbb\captcha\plugins\turnstile;
|
use phpbb\captcha\plugins\turnstile;
|
||||||
use phpbb\config\config;
|
use phpbb\config\config;
|
||||||
use phpbb\db\driver\driver_interface;
|
use phpbb\db\driver\driver_interface;
|
||||||
|
use phpbb\form\form_helper;
|
||||||
use phpbb\language\language;
|
use phpbb\language\language;
|
||||||
use phpbb\log\log_interface;
|
use phpbb\log\log_interface;
|
||||||
use phpbb\request\request;
|
use phpbb\request\request;
|
||||||
use phpbb\request\request_interface;
|
use phpbb\request\request_interface;
|
||||||
use phpbb\template\template;
|
use phpbb\template\template;
|
||||||
use phpbb\user;
|
use phpbb\user;
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Psr7\Response;
|
use GuzzleHttp\Psr7\Response;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../phpBB/includes/functions_acp.php';
|
||||||
|
|
||||||
class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
|
class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
|
||||||
{
|
{
|
||||||
/** @var turnstile */
|
/** @var turnstile */
|
||||||
|
@ -160,6 +162,48 @@ class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
|
||||||
$this->assertTrue($this->turnstile->validate());
|
$this->assertTrue($this->turnstile->validate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_validate_with_guzzle_exception(): void
|
||||||
|
{
|
||||||
|
// Mock the request and response from the Turnstile API
|
||||||
|
$this->request->method('variable')->with('cf-turnstile-response')->willReturn('valid_response');
|
||||||
|
$this->request->method('header')->with('CF-Connecting-IP')->willReturn('127.0.0.1');
|
||||||
|
|
||||||
|
// Mock the GuzzleHttp client and response
|
||||||
|
$client_mock = $this->createMock(Client::class);
|
||||||
|
|
||||||
|
$request_mock = $this->createMock(\GuzzleHttp\Psr7\Request::class);
|
||||||
|
$exception = new \GuzzleHttp\Exception\ConnectException('Failed at connecting', $request_mock);
|
||||||
|
$client_mock->method('request')->willThrowException($exception);
|
||||||
|
|
||||||
|
// Mock config values for secret
|
||||||
|
$this->config->method('offsetGet')->willReturn('secret_value');
|
||||||
|
|
||||||
|
// Use reflection to inject the mocked client into the turnstile class
|
||||||
|
$reflection = new \ReflectionClass($this->turnstile);
|
||||||
|
$client_property = $reflection->getProperty('client');
|
||||||
|
$client_property->setAccessible(true);
|
||||||
|
$client_property->setValue($this->turnstile, $client_mock);
|
||||||
|
|
||||||
|
// Validatation fails due to guzzle exception
|
||||||
|
$this->assertFalse($this->turnstile->validate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_validate_previous_solve(): void
|
||||||
|
{
|
||||||
|
// Use reflection to inject the mocked client into the turnstile class
|
||||||
|
$reflection = new \ReflectionClass($this->turnstile);
|
||||||
|
$confirm_id = $reflection->getProperty('confirm_id');
|
||||||
|
$confirm_id->setValue($this->turnstile, 'confirm_id');
|
||||||
|
$code_property = $reflection->getProperty('code');
|
||||||
|
$code_property->setValue($this->turnstile, 'test_code');
|
||||||
|
$confirm_code_property = $reflection->getProperty('confirm_code');
|
||||||
|
$confirm_code_property->setValue($this->turnstile, 'test_code');
|
||||||
|
|
||||||
|
// Validate that the CAPTCHA was solved successfully
|
||||||
|
$this->assertTrue($this->turnstile->validate());
|
||||||
|
$this->assertTrue($this->turnstile->is_solved());
|
||||||
|
}
|
||||||
|
|
||||||
public function test_has_config(): void
|
public function test_has_config(): void
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->turnstile->has_config());
|
$this->assertTrue($this->turnstile->has_config());
|
||||||
|
@ -250,5 +294,135 @@ class phpbb_captcha_turnstile_test extends \phpbb_database_test_case
|
||||||
|
|
||||||
$this->assertEquals('captcha_turnstile_acp_demo.html', $this->turnstile->get_demo_template());
|
$this->assertEquals('captcha_turnstile_acp_demo.html', $this->turnstile->get_demo_template());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_acp_page_display(): void
|
||||||
|
{
|
||||||
|
global $phpbb_container, $phpbb_dispatcher, $template;
|
||||||
|
|
||||||
|
$phpbb_container = new phpbb_mock_container_builder();
|
||||||
|
$form_helper = new form_helper($this->config, $this->request, $this->user);
|
||||||
|
$phpbb_container->set('form_helper', $form_helper);
|
||||||
|
$this->user->data['user_id'] = ANONYMOUS;
|
||||||
|
$this->user->data['user_form_salt'] = 'foobar';
|
||||||
|
|
||||||
|
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||||
|
$template = $this->template;
|
||||||
|
|
||||||
|
// Mock the template assignments
|
||||||
|
$this->config->method('offsetGet')->willReturnMap([
|
||||||
|
['captcha_turnstile_sitekey', 'sitekey_value'],
|
||||||
|
['captcha_turnstile_theme', 'light'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->request->method('variable')->willReturn('');
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
1 => [
|
||||||
|
'TURNSTILE_THEME' => 'light',
|
||||||
|
'U_TURNSTILE_SCRIPT' => 'https://challenges.cloudflare.com/turnstile/v0/api.js',
|
||||||
|
],
|
||||||
|
2 => [
|
||||||
|
'CAPTCHA_PREVIEW' => 'captcha_turnstile_acp_demo.html',
|
||||||
|
'CAPTCHA_NAME' => '',
|
||||||
|
'CAPTCHA_TURNSTILE_THEME' => 'light',
|
||||||
|
'CAPTCHA_TURNSTILE_THEMES' => ['light', 'dark', 'auto'],
|
||||||
|
'U_ACTION' => 'test_u_action',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$matcher = $this->exactly(count($expected));
|
||||||
|
$this->template
|
||||||
|
->expects($matcher)
|
||||||
|
->method('assign_vars')
|
||||||
|
->willReturnCallback(function ($template_data) use ($matcher, $expected) {
|
||||||
|
$callNr = $matcher->getInvocationCount();
|
||||||
|
$this->assertEquals($expected[$callNr], $template_data);
|
||||||
|
});
|
||||||
|
|
||||||
|
$module_mock = new ModuleMock();
|
||||||
|
|
||||||
|
$this->turnstile->acp_page('', $module_mock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_acp_page_submit_without_form(): void
|
||||||
|
{
|
||||||
|
global $language, $phpbb_container, $phpbb_dispatcher, $template;
|
||||||
|
|
||||||
|
$language = $this->language;
|
||||||
|
$phpbb_container = new phpbb_mock_container_builder();
|
||||||
|
$form_helper = new form_helper($this->config, $this->request, $this->user);
|
||||||
|
$phpbb_container->set('form_helper', $form_helper);
|
||||||
|
$this->user->data['user_id'] = ANONYMOUS;
|
||||||
|
$this->user->data['user_form_salt'] = 'foobar';
|
||||||
|
|
||||||
|
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||||
|
$template = $this->template;
|
||||||
|
|
||||||
|
// Mock the template assignments
|
||||||
|
$this->config->method('offsetGet')->willReturnMap([
|
||||||
|
['captcha_turnstile_sitekey', 'sitekey_value'],
|
||||||
|
['captcha_turnstile_theme', 'light'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->request->method('is_set_post')->willReturnMap([
|
||||||
|
['creation_time', ''],
|
||||||
|
['submit', true]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->setExpectedTriggerError(E_USER_NOTICE, 'FORM_INVALID');
|
||||||
|
|
||||||
|
$module_mock = new ModuleMock();
|
||||||
|
|
||||||
|
$this->turnstile->acp_page('', $module_mock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_acp_page_submit_valid(): void
|
||||||
|
{
|
||||||
|
global $language, $phpbb_container, $phpbb_dispatcher, $template;
|
||||||
|
|
||||||
|
$language = $this->language;
|
||||||
|
$phpbb_container = new phpbb_mock_container_builder();
|
||||||
|
$form_helper = new form_helper($this->config, $this->request, $this->user);
|
||||||
|
$phpbb_container->set('form_helper', $form_helper);
|
||||||
|
$this->user->data['user_id'] = ANONYMOUS;
|
||||||
|
$this->user->data['user_form_salt'] = 'foobar';
|
||||||
|
|
||||||
|
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||||
|
$template = $this->template;
|
||||||
|
|
||||||
|
$form_tokens = $form_helper->get_form_tokens('acp_captcha');
|
||||||
|
|
||||||
|
// Mock the template assignments
|
||||||
|
$this->config->method('offsetGet')->willReturnMap([
|
||||||
|
['captcha_turnstile_sitekey', 'sitekey_value'],
|
||||||
|
['captcha_turnstile_theme', 'light'],
|
||||||
|
]);
|
||||||
|
$this->config['form_token_lifetime'] = 3600;
|
||||||
|
|
||||||
|
$this->request->method('is_set_post')->willReturnMap([
|
||||||
|
['creation_time', true],
|
||||||
|
['form_token', true],
|
||||||
|
['submit', true]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->request->method('variable')->willReturnMap([
|
||||||
|
['creation_time', 0, false, request_interface::REQUEST, $form_tokens['creation_time']],
|
||||||
|
['form_token', '', false, request_interface::REQUEST, $form_tokens['form_token']],
|
||||||
|
['captcha_turnstile_sitekey', '', false, request_interface::REQUEST, 'newsitekey'],
|
||||||
|
['captcha_turnstile_theme', 'light', false, request_interface::REQUEST, 'auto'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->setExpectedTriggerError(E_USER_NOTICE, 'CONFIG_UPDATED');
|
||||||
|
|
||||||
|
$module_mock = new ModuleMock();
|
||||||
|
sleep(1); // sleep for a second to ensure form token validation succeeds
|
||||||
|
|
||||||
|
$this->turnstile->acp_page('', $module_mock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModuleMock
|
||||||
|
{
|
||||||
|
public string $tpl_name = '';
|
||||||
|
public string $page_title = '';
|
||||||
|
public string $u_action = 'test_u_action';
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue