ver. 0.274 - ShopClients Domain+DI migration

This commit is contained in:
2026-02-15 15:03:24 +01:00
parent 618ba4f446
commit dc7751c9de
19 changed files with 740 additions and 180 deletions

View File

@@ -0,0 +1,134 @@
<?php
namespace Tests\Unit\Domain\Client;
use PHPUnit\Framework\TestCase;
use Domain\Client\ClientRepository;
class ClientRepositoryTest extends TestCase
{
public function testListForAdminWhitelistsSortAndPagination(): 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 [[
'client_id' => 5,
'client_name' => 'Jan',
'client_surname' => 'Kowalski',
'client_email' => 'jan@example.com',
'client_phone' => '123',
'client_city' => 'Warszawa',
'total_orders' => 3,
'total_spent' => 199.99,
'is_registered' => 1,
]];
}
};
});
$repository = new ClientRepository($mockDb);
$result = $repository->listForAdmin(
[],
'client_name DESC; DROP TABLE pp_shop_orders; --',
'DESC; DELETE FROM pp_users; --',
1,
999
);
$this->assertCount(2, $queries);
$dataSql = $queries[1]['sql'];
$this->assertMatchesRegularExpression('/ORDER BY\s+c\.client_surname\s+ASC,\s+c\.client_surname\s+ASC,\s+c\.client_name\s+ASC/i', $dataSql);
$this->assertStringNotContainsString('DROP TABLE', $dataSql);
$this->assertMatchesRegularExpression('/LIMIT\s+100\s+OFFSET\s+0/i', $dataSql);
$this->assertSame(1, $result['total']);
$this->assertCount(1, $result['items']);
$this->assertSame('Jan', $result['items'][0]['client_name']);
}
public function testOrdersForClientReturnsEmptyOnMissingInput(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->never())->method('query');
$repository = new ClientRepository($mockDb);
$this->assertSame([], $repository->ordersForClient('', 'Kowalski', 'jan@example.com'));
$this->assertSame([], $repository->ordersForClient('Jan', '', 'jan@example.com'));
$this->assertSame([], $repository->ordersForClient('Jan', 'Kowalski', ''));
}
public function testOrdersForClientNormalizesRows(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->once())
->method('query')
->willReturn(new class {
public function fetchAll() {
return [[
'id' => '10',
'date_order' => '2026-02-15 10:00:00',
'summary' => '149.50',
'payment_method' => 'Przelew',
'transport' => 'Kurier',
'message' => null,
]];
}
});
$repository = new ClientRepository($mockDb);
$rows = $repository->ordersForClient('Jan', 'Kowalski', 'jan@example.com');
$this->assertCount(1, $rows);
$this->assertSame(10, $rows[0]['id']);
$this->assertSame(149.50, $rows[0]['summary']);
$this->assertSame('Przelew', $rows[0]['payment_method']);
$this->assertSame('', $rows[0]['message']);
}
public function testTotalsForClientReturnsZeroForMissingInput(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->never())->method('query');
$repository = new ClientRepository($mockDb);
$totals = $repository->totalsForClient('', 'Kowalski', 'jan@example.com');
$this->assertSame(0, $totals['total_orders']);
$this->assertSame(0.0, $totals['total_spent']);
}
public function testTotalsForClientReturnsAggregatedValues(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->once())
->method('query')
->willReturn(new class {
public function fetchAll() {
return [[
'total_orders' => '4',
'total_spent' => '456.78',
]];
}
});
$repository = new ClientRepository($mockDb);
$totals = $repository->totalsForClient('Jan', 'Kowalski', 'jan@example.com');
$this->assertSame(4, $totals['total_orders']);
$this->assertSame(456.78, $totals['total_spent']);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Tests\Unit\admin\Controllers;
use PHPUnit\Framework\TestCase;
use admin\Controllers\ShopClientsController;
use Domain\Client\ClientRepository;
class ShopClientsControllerTest extends TestCase
{
private $repository;
private $controller;
protected function setUp(): void
{
$this->repository = $this->createMock(ClientRepository::class);
$this->controller = new ShopClientsController($this->repository);
}
public function testConstructorAcceptsRepository(): void
{
$controller = new ShopClientsController($this->repository);
$this->assertInstanceOf(ShopClientsController::class, $controller);
}
public function testHasMainActionMethods(): void
{
$this->assertTrue(method_exists($this->controller, 'list'));
$this->assertTrue(method_exists($this->controller, 'details'));
}
public function testHasLegacyAliasMethods(): void
{
$this->assertTrue(method_exists($this->controller, 'view_list'));
$this->assertTrue(method_exists($this->controller, 'clients_details'));
}
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('string', (string)$reflection->getMethod('details')->getReturnType());
$this->assertEquals('string', (string)$reflection->getMethod('clients_details')->getReturnType());
}
public function testConstructorRequiresClientRepository(): void
{
$reflection = new \ReflectionClass(ShopClientsController::class);
$constructor = $reflection->getConstructor();
$params = $constructor->getParameters();
$this->assertCount(1, $params);
$this->assertEquals('Domain\\Client\\ClientRepository', $params[0]->getType()->getName());
}
}