mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-04 20:03:11 +02:00
Add category-template selection to the line, mag and enigma edit forms and to the reseller active-code (voucher) form, plus a reseller navbar entry. Extract the shared custom_data resolver into CategoryTemplateService::applyCustomData() and route the Line/Mag/Enigma saves through it, removing the triplicated inline block; covered by a new unit test. Review fixes folded in: - getRecentBatchNames filtered a non-existent `user_id` column and used DISTINCT + ORDER BY id (rejected by MySQL ONLY_FULL_GROUP_BY). Restore the correct created_by + GROUP BY MAX(created_at) query (kept the empty-batch guard). - routes/admin.php: import ActiveCodeDetailsController (fatal short-name use without it) for the active_code_details route. - Revert the accidental re-inline of the ancestorOwnerIds() helper in getTemplatesForUser and the getResellersWithCodes all-users fallback. Also: settings save only zeroes checkbox flags on the full settings form (submit_settings), and reseller bootstrap tolerates a missing language.
88 lines
2.9 KiB
PHP
88 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace XcVm\Tests\Unit;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use TestDb;
|
|
use XcVm\Domain\Stream\CategoryTemplateService;
|
|
use XcVm\Infrastructure\Database\DatabaseFactory;
|
|
|
|
/**
|
|
* Coverage for the shared custom_data resolver used by line, mag and enigma
|
|
* saves (CategoryTemplateService::applyCustomData). The column must only be
|
|
* touched when the request carries `category_template_id` or `custom_data`,
|
|
* so an untouched edit preserves whatever layout is already stored.
|
|
*/
|
|
final class CategoryTemplateApplyCustomDataTest extends TestCase {
|
|
|
|
private TestDb $db;
|
|
|
|
protected function setUp(): void {
|
|
$this->db = new TestDb();
|
|
$this->db->exec(
|
|
'CREATE TABLE `category_template_items` (
|
|
`id` INTEGER PRIMARY KEY,
|
|
`template_id` INTEGER,
|
|
`category_type` TEXT,
|
|
`category_id` INTEGER,
|
|
`custom_name` TEXT,
|
|
`is_visible` INTEGER DEFAULT 1,
|
|
`sort_order` INTEGER DEFAULT 0
|
|
);
|
|
INSERT INTO `category_template_items`
|
|
(`id`,`template_id`,`category_type`,`category_id`,`custom_name`,`is_visible`,`sort_order`) VALUES
|
|
(1,5,"live",10,"Renamed",1,1),
|
|
(2,5,"live",11,NULL,0,2);'
|
|
);
|
|
DatabaseFactory::set($this->db);
|
|
}
|
|
|
|
public function testTemplateIdZeroOrNoneClearsCustomData(): void {
|
|
$this->assertNull(
|
|
CategoryTemplateService::applyCustomData(['category_template_id' => '0'], [])['custom_data']
|
|
);
|
|
$this->assertNull(
|
|
CategoryTemplateService::applyCustomData(['category_template_id' => 'none'], [])['custom_data']
|
|
);
|
|
}
|
|
|
|
public function testPositiveTemplateIdBuildsCustomDataJson(): void {
|
|
$row = CategoryTemplateService::applyCustomData(['category_template_id' => '5'], []);
|
|
|
|
$this->assertArrayHasKey('custom_data', $row);
|
|
$decoded = json_decode((string) $row['custom_data'], true);
|
|
$this->assertSame(5, $decoded['template_id']);
|
|
// Hidden category (is_visible=0) lands in the live hide list.
|
|
$this->assertStringContainsString('11', (string) $decoded['live_cat']['hide_ids']);
|
|
$this->assertSame('10,11', $decoded['live_cat']['order']);
|
|
}
|
|
|
|
public function testInvalidTemplateIdLeavesCustomDataUntouched(): void {
|
|
// Empty / non-numeric template id must not overwrite an existing layout.
|
|
$row = CategoryTemplateService::applyCustomData(
|
|
['category_template_id' => ''],
|
|
['custom_data' => 'KEEP']
|
|
);
|
|
$this->assertSame('KEEP', $row['custom_data']);
|
|
}
|
|
|
|
public function testRawCustomDataStringAndArrayAndEmpty(): void {
|
|
$this->assertSame(
|
|
'{"x":1}',
|
|
CategoryTemplateService::applyCustomData(['custom_data' => '{"x":1}'], [])['custom_data']
|
|
);
|
|
$this->assertSame(
|
|
'{"x":1}',
|
|
CategoryTemplateService::applyCustomData(['custom_data' => ['x' => 1]], [])['custom_data']
|
|
);
|
|
$this->assertNull(
|
|
CategoryTemplateService::applyCustomData(['custom_data' => ''], [])['custom_data']
|
|
);
|
|
}
|
|
|
|
public function testNeitherKeyPreservesTarget(): void {
|
|
$target = ['username' => 'bob', 'custom_data' => 'EXISTING'];
|
|
$this->assertSame($target, CategoryTemplateService::applyCustomData([], $target));
|
|
}
|
|
}
|