mirror of
https://github.com/FOSSBilling/FOSSBilling.git
synced 2026-11-09 13:36:07 +09:00
* Initial plan * Apply system and theme review fixes Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Refine patcher cache shortcut Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Polish patcher and test constants Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Clean up review polish Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Finalize validation polish Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Document helper intent Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/04e9c3b0-aa3b-4af8-8f42-b73ed4d4b0aa Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * test: relax theme payload key assertions in live admin tests Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/da2430a4-c9d5-4dac-897b-db34790a2348 Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> Co-authored-by: Adam Daley <admdly@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
121 lines
5.6 KiB
PHP
121 lines
5.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ThemeTests;
|
|
|
|
use APIHelper\Request;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class AdminTest extends TestCase
|
|
{
|
|
private const string SEMANTIC_VERSION_PATTERN = '/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/';
|
|
|
|
public function testGetCurrentClientTheme(): void
|
|
{
|
|
$result = Request::makeRequest('admin/theme/get_current');
|
|
$this->assertTrue($result->wasSuccessful(), $result->generatePHPUnitMessage());
|
|
$data = $result->getResult();
|
|
$this->assertIsArray($data);
|
|
|
|
$this->assertValidThemePayload($data);
|
|
}
|
|
|
|
public function testGetCurrentAdminTheme(): void
|
|
{
|
|
$result = Request::makeRequest('admin/theme/get_current', ['client' => false]);
|
|
$this->assertTrue($result->wasSuccessful(), $result->generatePHPUnitMessage());
|
|
$data = $result->getResult();
|
|
$this->assertIsArray($data);
|
|
|
|
$this->assertValidThemePayload($data);
|
|
}
|
|
|
|
public function testGetCurrentThemeWithInvalidClientParameterReturnsError(): void
|
|
{
|
|
$result = Request::makeRequest('admin/theme/get_current', ['client' => 'invalid']);
|
|
|
|
$this->assertFalse($result->wasSuccessful(), 'Request should fail for an invalid "client" parameter type.');
|
|
|
|
$errorMessage = $result->getErrorMessage();
|
|
$this->assertIsString($errorMessage, 'Error message should be a string.');
|
|
$this->assertNotSame('', trim($errorMessage), 'Error message should not be empty.');
|
|
}
|
|
|
|
public function testAdminThemeRequestWithClientFalseFailureReturnsError(): void
|
|
{
|
|
$result = Request::makeRequest('admin/theme/non_existing_action', ['client' => false]);
|
|
$this->assertSame(404, $result->getStatusCode(), 'Invalid admin theme action with client=false should return HTTP 404.');
|
|
$this->assertFalse($result->wasSuccessful(), 'Invalid admin theme action with client=false should not be successful.');
|
|
// API not-found actions/endpoints are mapped to error code 740 (see src/library/Api/Handler.php).
|
|
$expectedNotFoundErrorCode = 740;
|
|
$this->assertSame($expectedNotFoundErrorCode, $result->getErrorCode(), 'Invalid admin theme action with client=false should return the API not-found error code.');
|
|
|
|
$errorMessage = $result->getErrorMessage();
|
|
$this->assertIsString($errorMessage, 'Error message should be a string.');
|
|
$this->assertNotSame('', trim($errorMessage), 'Error message should not be empty.');
|
|
}
|
|
|
|
public function testInvalidThemeActionReturnsError(): void
|
|
{
|
|
$result = Request::makeRequest('admin/theme/non_existing_action');
|
|
$this->assertSame(404, $result->getStatusCode(), 'Invalid theme action should return HTTP 404.');
|
|
$this->assertFalse($result->wasSuccessful(), 'Invalid theme action should not be successful.');
|
|
// API not-found actions/endpoints are mapped to error code 740 (see src/library/Api/Handler.php).
|
|
$expectedNotFoundErrorCode = 740;
|
|
$this->assertSame($expectedNotFoundErrorCode, $result->getErrorCode(), 'Invalid theme action should return the API not-found error code.');
|
|
|
|
$errorMessage = $result->getErrorMessage();
|
|
$this->assertIsString($errorMessage, 'Error message should be a string.');
|
|
$this->assertNotSame('', trim($errorMessage), 'Error message should not be empty.');
|
|
}
|
|
|
|
private function assertValidThemePayload(array $data): void
|
|
{
|
|
$requiredKeys = ['author', 'name', 'version', 'code', 'paths', 'hasSettings', 'url'];
|
|
foreach ($requiredKeys as $requiredKey) {
|
|
$this->assertArrayHasKey($requiredKey, $data, sprintf('Theme payload should contain the "%s" key.', $requiredKey));
|
|
}
|
|
|
|
$this->assertIsString($data['name']);
|
|
$this->assertNotSame('', trim($data['name']), 'Theme name should not be empty.');
|
|
$this->assertIsString($data['version']);
|
|
$this->assertNotSame('', trim($data['version']), 'Theme version should not be empty.');
|
|
$this->assertMatchesRegularExpression(
|
|
self::SEMANTIC_VERSION_PATTERN,
|
|
$data['version'],
|
|
'Theme version should follow semantic versioning (e.g., 1.2.3).'
|
|
);
|
|
$this->assertIsString($data['author']);
|
|
$this->assertNotSame('', trim($data['author']), 'Theme author should not be empty.');
|
|
$this->assertIsString($data['code']);
|
|
$this->assertNotSame('', trim($data['code']), 'Theme code should not be empty.');
|
|
$this->assertIsString($data['url']);
|
|
$this->assertNotSame('', trim($data['url']), 'Theme URL should not be empty.');
|
|
$this->assertIsBool($data['hasSettings']);
|
|
$this->assertIsArray($data['paths']);
|
|
$this->assertNotEmpty($data['paths'], 'Theme paths should not be empty.');
|
|
foreach ($data['paths'] as $path) {
|
|
$this->assertIsString($path);
|
|
$this->assertNotSame('', trim($path), 'Theme paths should contain non-empty strings.');
|
|
}
|
|
|
|
if (array_key_exists('author_url', $data)) {
|
|
$this->assertIsString($data['author_url']);
|
|
$this->assertNotSame('', trim($data['author_url']), 'Theme author URL should not be empty when present.');
|
|
}
|
|
|
|
if (array_key_exists('description', $data)) {
|
|
$this->assertIsString($data['description']);
|
|
}
|
|
|
|
if (array_key_exists('icon', $data)) {
|
|
$this->assertIsString($data['icon']);
|
|
}
|
|
|
|
if (array_key_exists('markdown_attributes', $data)) {
|
|
$this->assertIsArray($data['markdown_attributes']);
|
|
}
|
|
}
|
|
}
|