refactor articles_archive to DI controller and table-list

This commit is contained in:
2026-02-12 23:53:05 +01:00
parent 0d4e175b1a
commit 6832009020
16 changed files with 600 additions and 199 deletions

View File

@@ -443,6 +443,95 @@ class ArticleRepositoryTest extends TestCase
$this->assertFalse($result);
}
public function testRestoreSetsStatusToZero(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->once())
->method('update')
->with('pp_articles', ['status' => 0], ['id' => 25])
->willReturn(true);
$repository = new ArticleRepository($mockDb);
$result = $repository->restore(25);
$this->assertTrue($result);
}
public function testDeletePermanentlyRemovesArticleAndRelations(): void
{
$mockDb = $this->createMock(\medoo::class);
$deleteCalls = [];
$mockDb->expects($this->exactly(5))
->method('delete')
->willReturnCallback(function ($table, $where) use (&$deleteCalls) {
$deleteCalls[] = ['table' => $table, 'where' => $where];
return true;
});
$repository = new ArticleRepository($mockDb);
$result = $repository->deletePermanently(77);
$this->assertTrue($result);
$this->assertCount(5, $deleteCalls);
$this->assertSame('pp_articles_pages', $deleteCalls[0]['table']);
$this->assertSame('pp_articles_langs', $deleteCalls[1]['table']);
$this->assertSame('pp_articles_images', $deleteCalls[2]['table']);
$this->assertSame('pp_articles_files', $deleteCalls[3]['table']);
$this->assertSame('pp_articles', $deleteCalls[4]['table']);
}
public function testListArchivedForAdminWhitelistsSortAndDirection(): void
{
$mockDb = $this->createMock(\medoo::class);
$queries = [];
$mockDb->method('query')
->willReturnCallback(function ($sql, $params = []) use (&$queries) {
$queries[] = ['sql' => $sql, 'params' => $params];
if (strpos($sql, 'COUNT(0)') !== false) {
return new class {
public function fetchAll()
{
return [[1]];
}
};
}
return new class {
public function fetchAll()
{
return [[
'id' => 1,
'date_add' => '2020-01-01 00:00:00',
'date_modify' => '2020-01-01 00:00:00',
'title' => 'A',
]];
}
};
});
$repository = new ArticleRepository($mockDb);
$repository->listArchivedForAdmin(
[],
'date_add DESC; DROP TABLE pp_articles; --',
'DESC; DELETE FROM pp_users; --',
1,
100000
);
$this->assertCount(2, $queries);
$dataSql = $queries[1]['sql'];
$this->assertMatchesRegularExpression('/ORDER BY\s+pa\.date_add\s+DESC,\s+pa\.id\s+DESC/i', $dataSql);
$this->assertStringNotContainsString('DROP TABLE', $dataSql);
$this->assertStringNotContainsString('DELETE FROM pp_users', $dataSql);
$this->assertMatchesRegularExpression('/LIMIT\s+100\s+OFFSET\s+0/i', $dataSql);
$this->assertStringContainsString('pa.status = -1', $dataSql);
}
public function testListForAdminWhitelistsSortAndDirection(): void
{
$mockDb = $this->createMock(\medoo::class);

View File

@@ -0,0 +1,52 @@
<?php
namespace Tests\Unit\admin\Controllers;
use PHPUnit\Framework\TestCase;
use admin\Controllers\ArticlesArchiveController;
use Domain\Article\ArticleRepository;
class ArticlesArchiveControllerTest extends TestCase
{
private $repository;
private $controller;
protected function setUp(): void
{
$this->repository = $this->createMock(ArticleRepository::class);
$this->controller = new ArticlesArchiveController($this->repository);
}
public function testConstructorAcceptsRepository(): void
{
$controller = new ArticlesArchiveController($this->repository);
$this->assertInstanceOf(ArticlesArchiveController::class, $controller);
}
public function testHasMainActionMethods(): void
{
$this->assertTrue(method_exists($this->controller, 'list'));
$this->assertTrue(method_exists($this->controller, 'view_list'));
$this->assertTrue(method_exists($this->controller, 'restore'));
$this->assertTrue(method_exists($this->controller, 'delete'));
}
public function testActionMethodReturnTypes(): void
{
$reflection = new \ReflectionClass($this->controller);
$this->assertEquals('string', (string)$reflection->getMethod('list')->getReturnType());
$this->assertEquals('string', (string)$reflection->getMethod('view_list')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('restore')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('delete')->getReturnType());
}
public function testConstructorRequiresArticleRepository(): void
{
$reflection = new \ReflectionClass(ArticlesArchiveController::class);
$constructor = $reflection->getConstructor();
$params = $constructor->getParameters();
$this->assertCount(1, $params);
$this->assertEquals('Domain\Article\ArticleRepository', $params[0]->getType()->getName());
}
}