mirror of
https://github.com/FOSSBilling/FOSSBilling.git
synced 2026-11-09 13:36:07 +09:00
* Initial plan * Apply code quality improvements: rename methods, add type hints, fix null checks, improve tests Agent-Logs-Url: https://github.com/FOSSBilling/FOSSBilling/sessions/7815527d-3f30-486a-9f69-232031ba2d6e Co-authored-by: admdly <2807620+admdly@users.noreply.github.com> * Use `isValidFieldType` instead of `typeValidation` * Allow rendered privacy policy HTML Remove the Twig escape filter from the company privacy policy output so the HTML produced by the markdown filter is rendered. This change ensures markdown-generated markup displays correctly in the privacy policy card instead of being HTML-escaped. --------- 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>
334 lines
10 KiB
PHP
334 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Box\Mod\Formbuilder;
|
|
|
|
use Doctrine\DBAL\Connection;
|
|
use Doctrine\DBAL\DriverManager;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\Attributes\Group;
|
|
|
|
#[Group('Core')]
|
|
final class ServiceTest extends \BBTestCase
|
|
{
|
|
protected ?Service $service;
|
|
|
|
public function setUp(): void
|
|
{
|
|
$this->service = new Service();
|
|
}
|
|
|
|
public function testGetDi(): void
|
|
{
|
|
$di = $this->createDi($this->createDbalConnection());
|
|
$this->service->setDi($di);
|
|
|
|
$this->assertEquals($di, $this->service->getDi());
|
|
}
|
|
|
|
public function testGetFormFieldsTypes(): void
|
|
{
|
|
$expected = [
|
|
'text' => 'Text input',
|
|
'url' => 'URL input',
|
|
'select' => 'Dropdown',
|
|
'radio' => 'Radio select',
|
|
'checkbox' => 'Checkbox',
|
|
'textarea' => 'Text area',
|
|
];
|
|
|
|
$this->assertSame($expected, $this->service->getFormFieldsTypes());
|
|
}
|
|
|
|
public static function typeFieldValidationData(): array
|
|
{
|
|
return [
|
|
['select', true],
|
|
['custom', false],
|
|
['url', true],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('typeFieldValidationData')]
|
|
public function testIsValidFieldType(string $type, bool $expected): void
|
|
{
|
|
$this->assertSame($expected, $this->service->isValidFieldType($type));
|
|
}
|
|
|
|
public static function urlValidationData(): array
|
|
{
|
|
return [
|
|
['', true],
|
|
['https://example.com', true],
|
|
['http://example.org', true],
|
|
['https://subdomain.example.co.uk', true],
|
|
['example', false],
|
|
['example.com', false],
|
|
['https://example', false],
|
|
['not-a-url', false],
|
|
['ftp://files.example.com', true],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('urlValidationData')]
|
|
public function testValidateUrlField(string $url, bool $expected): void
|
|
{
|
|
$this->assertSame($expected, $this->service->validateUrlField($url));
|
|
}
|
|
|
|
public static function isArrayUniqueData(): array
|
|
{
|
|
return [
|
|
[['sameValue', 'sameValue'], false],
|
|
[['sameValue', 'DiffValue'], true],
|
|
[[], true],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('isArrayUniqueData')]
|
|
public function testIsArrayUnique(array $data, bool $expected): void
|
|
{
|
|
$this->assertSame($expected, $this->service->isArrayUnique($data));
|
|
}
|
|
|
|
public function testAddNewFormAndGetForm(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm([
|
|
'name' => 'Support Form',
|
|
'type' => 'default',
|
|
'show_title' => '1',
|
|
]);
|
|
|
|
$form = $this->service->getForm($formId);
|
|
|
|
$this->assertSame('Support Form', $form['name']);
|
|
$this->assertSame(['type' => 'default', 'show_title' => '1'], $form['style']);
|
|
$this->assertSame([], $form['fields']);
|
|
}
|
|
|
|
public function testAddNewFieldAndGetField(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Signup Form']);
|
|
$fieldId = $this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'select',
|
|
]);
|
|
|
|
$field = $this->service->getField($fieldId);
|
|
|
|
$this->assertSame($formId, (int) $field['form_id']);
|
|
$this->assertSame('select', $field['type']);
|
|
$this->assertIsObject($field['options']);
|
|
}
|
|
|
|
public function testUpdateFieldUpdatesStructuredOptions(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Order Form']);
|
|
$fieldId = $this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'select',
|
|
'name' => 'server_location',
|
|
]);
|
|
|
|
$updatedId = $this->service->updateField([
|
|
'id' => $fieldId,
|
|
'name' => 'server_location',
|
|
'label' => 'Server location',
|
|
'type' => 'select',
|
|
'values' => ['eu', 'us'],
|
|
'labels' => ['Europe', 'United States'],
|
|
'default_value' => 'eu',
|
|
]);
|
|
|
|
$field = $this->service->getField($updatedId);
|
|
|
|
$this->assertSame($fieldId, $updatedId);
|
|
$this->assertSame('Server location', $field['label']);
|
|
$this->assertEquals((object) ['Europe' => 'eu', 'United States' => 'us'], $field['options']);
|
|
}
|
|
|
|
public function testUpdateFieldRejectsDuplicateFieldNames(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Order Form']);
|
|
$this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'text',
|
|
'name' => 'hostname',
|
|
]);
|
|
$fieldId = $this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'text',
|
|
'name' => 'username',
|
|
]);
|
|
|
|
$this->expectException(\FOSSBilling\Exception::class);
|
|
$this->expectExceptionCode(7628);
|
|
|
|
$this->service->updateField([
|
|
'id' => $fieldId,
|
|
'name' => 'hostname',
|
|
'type' => 'text',
|
|
]);
|
|
}
|
|
|
|
public function testUpdateFieldRejectsDuplicateSelectValues(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Order Form']);
|
|
$fieldId = $this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'select',
|
|
'name' => 'server_location',
|
|
]);
|
|
|
|
$this->expectException(\FOSSBilling\Exception::class);
|
|
$this->expectExceptionCode(1597);
|
|
|
|
$this->service->updateField([
|
|
'id' => $fieldId,
|
|
'name' => 'server_location',
|
|
'type' => 'select',
|
|
'values' => ['eu', 'eu'],
|
|
'labels' => ['Europe', 'Duplicate'],
|
|
]);
|
|
}
|
|
|
|
public function testRemoveFormClearsRelatedRows(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Provisioning Form']);
|
|
$this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'text',
|
|
'name' => 'hostname',
|
|
]);
|
|
|
|
$dbal->insert('product', ['id' => 5, 'form_id' => $formId]);
|
|
$dbal->insert('client_order', ['id' => 8, 'form_id' => $formId]);
|
|
|
|
$this->assertTrue($this->service->removeForm($formId));
|
|
$this->assertSame(0, (int) $dbal->executeQuery('SELECT COUNT(*) FROM form WHERE id = ?', [$formId])->fetchOne());
|
|
$this->assertSame(0, (int) $dbal->executeQuery('SELECT COUNT(*) FROM form_field WHERE form_id = ?', [$formId])->fetchOne());
|
|
$this->assertNull($dbal->executeQuery('SELECT form_id FROM product WHERE id = 5')->fetchOne());
|
|
$this->assertNull($dbal->executeQuery('SELECT form_id FROM client_order WHERE id = 8')->fetchOne());
|
|
}
|
|
|
|
public function testDuplicateFormCopiesFields(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Original']);
|
|
$this->service->addNewField([
|
|
'form_id' => $formId,
|
|
'type' => 'text',
|
|
'name' => 'hostname',
|
|
]);
|
|
|
|
$duplicateId = $this->service->duplicateForm([
|
|
'form_id' => $formId,
|
|
'name' => 'Copy',
|
|
]);
|
|
|
|
$this->assertSame('Copy', $this->service->getForm($duplicateId)['name']);
|
|
$this->assertCount(1, $this->service->getFormFields($duplicateId));
|
|
}
|
|
|
|
public function testUpdateFormSettings(): void
|
|
{
|
|
$dbal = $this->createDbalConnection();
|
|
$di = $this->createDi($dbal);
|
|
$this->service->setDi($di);
|
|
|
|
$formId = $this->service->addNewForm(['name' => 'Original']);
|
|
|
|
$this->assertTrue($this->service->updateFormSettings([
|
|
'form_id' => $formId,
|
|
'form_name' => 'Renamed',
|
|
'type' => 'default',
|
|
'show_title' => '1',
|
|
]));
|
|
|
|
$form = $this->service->getForm($formId);
|
|
$this->assertSame('Renamed', $form['name']);
|
|
$this->assertSame(['type' => 'default', 'show_title' => '1'], $form['style']);
|
|
}
|
|
|
|
private function createDi(Connection $dbal): \Pimple\Container
|
|
{
|
|
$di = $this->getDi();
|
|
$di['dbal'] = $dbal;
|
|
$di['logger'] = new \Box_Log();
|
|
|
|
$validator = $this->getMockBuilder(\FOSSBilling\Validate::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
$validator->method('checkRequiredParamsForArray');
|
|
$di['validator'] = $validator;
|
|
|
|
return $di;
|
|
}
|
|
|
|
private function createDbalConnection(): Connection
|
|
{
|
|
$connection = DriverManager::getConnection([
|
|
'driver' => 'pdo_sqlite',
|
|
'memory' => true,
|
|
]);
|
|
|
|
$connection->executeStatement('CREATE TABLE form (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, style TEXT, created_at TEXT, updated_at TEXT)');
|
|
$connection->executeStatement('CREATE TABLE form_field (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
form_id INTEGER,
|
|
name TEXT,
|
|
label TEXT,
|
|
hide_label INTEGER,
|
|
description TEXT,
|
|
type TEXT,
|
|
default_value TEXT,
|
|
required INTEGER,
|
|
hidden INTEGER,
|
|
readonly INTEGER,
|
|
is_unique INTEGER,
|
|
prefix TEXT,
|
|
suffix TEXT,
|
|
options TEXT,
|
|
show_initial TEXT,
|
|
show_middle TEXT,
|
|
show_prefix TEXT,
|
|
show_suffix TEXT,
|
|
text_size INTEGER,
|
|
created_at TEXT,
|
|
updated_at TEXT
|
|
)');
|
|
$connection->executeStatement('CREATE TABLE product (id INTEGER PRIMARY KEY, form_id INTEGER)');
|
|
$connection->executeStatement('CREATE TABLE client_order (id INTEGER PRIMARY KEY, form_id INTEGER)');
|
|
|
|
return $connection;
|
|
}
|
|
}
|