ver. 0.272 - ShopProductSets refactor + update package
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
185
tests/Unit/Domain/ProductSet/ProductSetRepositoryTest.php
Normal file
185
tests/Unit/Domain/ProductSet/ProductSetRepositoryTest.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
namespace Tests\Unit\Domain\ProductSet;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Domain\ProductSet\ProductSetRepository;
|
||||
|
||||
class ProductSetRepositoryTest extends TestCase
|
||||
{
|
||||
public function testFindReturnsDefaultSetForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
|
||||
$result = $repository->find(0);
|
||||
|
||||
$this->assertIsArray($result);
|
||||
$this->assertSame(0, $result['id']);
|
||||
$this->assertSame('', $result['name']);
|
||||
$this->assertSame(1, $result['status']);
|
||||
$this->assertSame([], $result['products']);
|
||||
}
|
||||
|
||||
public function testFindNormalizesSetData(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_product_sets', '*', ['id' => 5])
|
||||
->willReturn([
|
||||
'id' => '5',
|
||||
'name' => 'Komplet A',
|
||||
'status' => '1',
|
||||
]);
|
||||
|
||||
$mockDb->expects($this->once())
|
||||
->method('select')
|
||||
->with('pp_shop_product_sets_products', 'product_id', ['set_id' => 5])
|
||||
->willReturn(['10', '20', '30']);
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$result = $repository->find(5);
|
||||
|
||||
$this->assertSame(5, $result['id']);
|
||||
$this->assertSame('Komplet A', $result['name']);
|
||||
$this->assertSame(1, $result['status']);
|
||||
$this->assertSame([10, 20, 30], $result['products']);
|
||||
}
|
||||
|
||||
public function testSaveInsertsNewSetAndSyncsProducts(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$insertCalls = [];
|
||||
$deleteCalls = [];
|
||||
|
||||
$mockDb->method('insert')
|
||||
->willReturnCallback(function ($table, $row) use (&$insertCalls) {
|
||||
$insertCalls[] = ['table' => $table, 'row' => $row];
|
||||
});
|
||||
|
||||
$mockDb->expects($this->once())
|
||||
->method('id')
|
||||
->willReturn(42);
|
||||
|
||||
$mockDb->method('delete')
|
||||
->willReturnCallback(function ($table, $where) use (&$deleteCalls) {
|
||||
$deleteCalls[] = ['table' => $table, 'where' => $where];
|
||||
return true;
|
||||
});
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$id = $repository->save(0, 'Nowy komplet', 1, [10, 20, 20]);
|
||||
|
||||
$this->assertSame(42, $id);
|
||||
|
||||
$this->assertSame('pp_shop_product_sets', $insertCalls[0]['table']);
|
||||
$this->assertSame('Nowy komplet', $insertCalls[0]['row']['name']);
|
||||
$this->assertSame(1, $insertCalls[0]['row']['status']);
|
||||
|
||||
// Sync: delete old + insert 2 unique products (10, 20)
|
||||
$this->assertSame('pp_shop_product_sets_products', $deleteCalls[0]['table']);
|
||||
$this->assertSame(['set_id' => 42], $deleteCalls[0]['where']);
|
||||
|
||||
$productInserts = array_filter($insertCalls, fn($c) => $c['table'] === 'pp_shop_product_sets_products');
|
||||
$this->assertCount(2, $productInserts);
|
||||
}
|
||||
|
||||
public function testSaveUpdatesExistingSet(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$updateRow = null;
|
||||
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->willReturnCallback(function ($table, $row, $where) use (&$updateRow) {
|
||||
$this->assertSame('pp_shop_product_sets', $table);
|
||||
$this->assertSame(['id' => 7], $where);
|
||||
$updateRow = $row;
|
||||
return true;
|
||||
});
|
||||
|
||||
$mockDb->expects($this->never())->method('id');
|
||||
|
||||
$mockDb->method('delete')->willReturn(true);
|
||||
$mockDb->method('insert')->willReturn(null);
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$id = $repository->save(7, 'Zaktualizowany', 0, [15]);
|
||||
|
||||
$this->assertSame(7, $id);
|
||||
$this->assertSame('Zaktualizowany', $updateRow['name']);
|
||||
$this->assertSame(0, $updateRow['status']);
|
||||
}
|
||||
|
||||
public function testDeleteReturnsFalseForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('delete');
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$this->assertFalse($repository->delete(0));
|
||||
}
|
||||
|
||||
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 [[
|
||||
'id' => 1,
|
||||
'name' => 'Test',
|
||||
'status' => 1,
|
||||
]];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$result = $repository->listForAdmin(
|
||||
[],
|
||||
'name DESC; DROP TABLE pp_shop_product_sets; --',
|
||||
'DESC; DELETE FROM pp_users; --',
|
||||
1,
|
||||
999
|
||||
);
|
||||
|
||||
$this->assertCount(2, $queries);
|
||||
$dataSql = $queries[1]['sql'];
|
||||
|
||||
$this->assertMatchesRegularExpression('/ORDER BY\s+ps\.name\s+ASC,\s+ps\.id\s+DESC/i', $dataSql);
|
||||
$this->assertStringNotContainsString('DROP TABLE', $dataSql);
|
||||
$this->assertMatchesRegularExpression('/LIMIT\s+100\s+OFFSET\s+0/i', $dataSql);
|
||||
}
|
||||
|
||||
public function testAllSetsReturnsFormattedList(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('select')
|
||||
->with('pp_shop_product_sets', ['id', 'name'], ['ORDER' => ['name' => 'ASC']])
|
||||
->willReturn([
|
||||
['id' => '1', 'name' => 'Komplet A'],
|
||||
['id' => '2', 'name' => 'Komplet B'],
|
||||
]);
|
||||
|
||||
$repository = new ProductSetRepository($mockDb);
|
||||
$result = $repository->allSets();
|
||||
|
||||
$this->assertCount(2, $result);
|
||||
$this->assertSame(1, $result[0]['id']);
|
||||
$this->assertSame('Komplet A', $result[0]['name']);
|
||||
$this->assertSame(2, $result[1]['id']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user