316 lines
11 KiB
PHP
316 lines
11 KiB
PHP
<?php
|
|
namespace Tests\Unit\Domain\Producer;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use Domain\Producer\ProducerRepository;
|
|
|
|
class ProducerRepositoryTest extends TestCase
|
|
{
|
|
public function testFindReturnsDefaultProducerForInvalidId(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$repository = new ProducerRepository($mockDb);
|
|
|
|
$result = $repository->find(0);
|
|
|
|
$this->assertIsArray($result);
|
|
$this->assertSame(0, $result['id']);
|
|
$this->assertSame('', $result['name']);
|
|
$this->assertSame(1, $result['status']);
|
|
$this->assertNull($result['img']);
|
|
$this->assertSame([], $result['languages']);
|
|
}
|
|
|
|
public function testFindNormalizesProducerData(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->once())
|
|
->method('get')
|
|
->with('pp_shop_producer', '*', ['id' => 5])
|
|
->willReturn([
|
|
'id' => '5',
|
|
'name' => 'Apple',
|
|
'status' => '1',
|
|
'img' => '/logo.png',
|
|
]);
|
|
|
|
$mockDb->expects($this->once())
|
|
->method('select')
|
|
->with('pp_shop_producer_lang', '*', ['producer_id' => 5])
|
|
->willReturn([
|
|
[
|
|
'lang_id' => 'pl',
|
|
'description' => 'Opis PL',
|
|
'data' => 'Dane PL',
|
|
'meta_title' => 'Meta PL',
|
|
],
|
|
[
|
|
'lang_id' => 'en',
|
|
'description' => 'Desc EN',
|
|
'data' => null,
|
|
'meta_title' => null,
|
|
],
|
|
]);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->find(5);
|
|
|
|
$this->assertSame(5, $result['id']);
|
|
$this->assertSame('Apple', $result['name']);
|
|
$this->assertSame(1, $result['status']);
|
|
$this->assertSame('/logo.png', $result['img']);
|
|
$this->assertArrayHasKey('pl', $result['languages']);
|
|
$this->assertArrayHasKey('en', $result['languages']);
|
|
$this->assertSame('Opis PL', $result['languages']['pl']['description']);
|
|
$this->assertSame('Meta PL', $result['languages']['pl']['meta_title']);
|
|
$this->assertNull($result['languages']['en']['meta_title']);
|
|
}
|
|
|
|
public function testSaveInsertsNewProducer(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$insertCalls = [];
|
|
|
|
$mockDb->method('insert')
|
|
->willReturnCallback(function ($table, $row) use (&$insertCalls) {
|
|
$insertCalls[] = ['table' => $table, 'row' => $row];
|
|
});
|
|
|
|
$mockDb->expects($this->once())
|
|
->method('id')
|
|
->willReturn(42);
|
|
|
|
$langs = [['id' => 'pl'], ['id' => 'en']];
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$id = $repository->save(
|
|
0, 'Samsung', 1, '/samsung.png',
|
|
['pl' => 'Opis PL', 'en' => 'Desc EN'],
|
|
['pl' => 'Dane', 'en' => null],
|
|
['pl' => 'Meta PL', 'en' => 'Meta EN'],
|
|
$langs
|
|
);
|
|
|
|
$this->assertSame(42, $id);
|
|
|
|
// 1st insert: pp_shop_producer
|
|
$this->assertSame('pp_shop_producer', $insertCalls[0]['table']);
|
|
$this->assertSame('Samsung', $insertCalls[0]['row']['name']);
|
|
$this->assertSame(1, $insertCalls[0]['row']['status']);
|
|
|
|
// 2nd and 3rd insert: pp_shop_producer_lang for each language
|
|
$langInserts = array_filter($insertCalls, fn($c) => $c['table'] === 'pp_shop_producer_lang');
|
|
$this->assertCount(2, $langInserts);
|
|
}
|
|
|
|
public function testSaveUpdatesExistingProducer(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$updateRow = null;
|
|
|
|
$mockDb->expects($this->atLeastOnce())
|
|
->method('update')
|
|
->willReturnCallback(function ($table, $row, $where) use (&$updateRow) {
|
|
if ($table === 'pp_shop_producer') {
|
|
$updateRow = $row;
|
|
$this->assertSame(['id' => 7], $where);
|
|
}
|
|
return true;
|
|
});
|
|
|
|
$mockDb->expects($this->never())->method('id');
|
|
|
|
// get for translation id check
|
|
$mockDb->method('get')
|
|
->willReturn(100);
|
|
|
|
$langs = [['id' => 'pl']];
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$id = $repository->save(7, 'Zaktualizowany', 0, null, ['pl' => 'Nowy opis'], ['pl' => null], ['pl' => 'Meta'], $langs);
|
|
|
|
$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 ProducerRepository($mockDb);
|
|
$this->assertFalse($repository->delete(0));
|
|
}
|
|
|
|
public function testDeleteReturnsTrueOnSuccess(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->once())
|
|
->method('delete')
|
|
->with('pp_shop_producer', ['id' => 3])
|
|
->willReturn(true);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$this->assertTrue($repository->delete(3));
|
|
}
|
|
|
|
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,
|
|
'img' => null,
|
|
]];
|
|
}
|
|
};
|
|
});
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->listForAdmin(
|
|
[],
|
|
'name DESC; DROP TABLE pp_shop_producer; --',
|
|
'DESC; DELETE FROM pp_users; --',
|
|
1,
|
|
999
|
|
);
|
|
|
|
$this->assertCount(2, $queries);
|
|
$dataSql = $queries[1]['sql'];
|
|
|
|
$this->assertMatchesRegularExpression('/ORDER BY\s+p\.name\s+ASC,\s+p\.id\s+DESC/i', $dataSql);
|
|
$this->assertStringNotContainsString('DROP TABLE', $dataSql);
|
|
$this->assertMatchesRegularExpression('/LIMIT\s+100\s+OFFSET\s+0/i', $dataSql);
|
|
}
|
|
|
|
public function testAllProducersReturnsFormattedList(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->once())
|
|
->method('select')
|
|
->with('pp_shop_producer', ['id', 'name'], ['ORDER' => ['name' => 'ASC']])
|
|
->willReturn([
|
|
['id' => '1', 'name' => 'Apple'],
|
|
['id' => '2', 'name' => 'Samsung'],
|
|
]);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->allProducers();
|
|
|
|
$this->assertCount(2, $result);
|
|
$this->assertSame(1, $result[0]['id']);
|
|
$this->assertSame('Apple', $result[0]['name']);
|
|
$this->assertSame(2, $result[1]['id']);
|
|
}
|
|
|
|
public function testProducerProductsReturnsPaginatedResults(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->once())
|
|
->method('count')
|
|
->willReturn(30);
|
|
|
|
$mockDb->expects($this->once())
|
|
->method('select')
|
|
->willReturn([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->producerProducts(5, 12, 1);
|
|
|
|
$this->assertArrayHasKey('products', $result);
|
|
$this->assertArrayHasKey('ls', $result);
|
|
$this->assertSame(3, $result['ls']);
|
|
}
|
|
|
|
public function testAllActiveProducersReturnsFullData(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->once())
|
|
->method('select')
|
|
->with('pp_shop_producer', ['id', 'name', 'img'], [
|
|
'status' => 1,
|
|
'ORDER' => ['name' => 'ASC'],
|
|
])
|
|
->willReturn([
|
|
['id' => '3', 'name' => 'Apple', 'img' => '/apple.png'],
|
|
['id' => '7', 'name' => 'Samsung', 'img' => null],
|
|
]);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->allActiveProducers();
|
|
|
|
$this->assertCount(2, $result);
|
|
$this->assertSame(3, $result[0]['id']);
|
|
$this->assertSame('Apple', $result[0]['name']);
|
|
$this->assertSame('/apple.png', $result[0]['img']);
|
|
$this->assertSame(7, $result[1]['id']);
|
|
$this->assertSame('Samsung', $result[1]['name']);
|
|
$this->assertNull($result[1]['img']);
|
|
}
|
|
|
|
public function testAllActiveProducersReturnsEmptyOnNull(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->method('select')->willReturn(null);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->allActiveProducers();
|
|
|
|
$this->assertSame([], $result);
|
|
}
|
|
|
|
public function testFindForFrontendReturnsNullForInvalidId(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->expects($this->never())->method('get');
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$this->assertNull($repository->findForFrontend(0, 'pl'));
|
|
}
|
|
|
|
public function testFindForFrontendReturnsNullWhenNotFound(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
$mockDb->method('get')->willReturn(null);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$this->assertNull($repository->findForFrontend(99, 'pl'));
|
|
}
|
|
|
|
public function testFindForFrontendReturnsProducerWithLanguage(): void
|
|
{
|
|
$mockDb = $this->createMock(\medoo::class);
|
|
|
|
$mockDb->expects($this->exactly(2))
|
|
->method('get')
|
|
->willReturnOnConsecutiveCalls(
|
|
['id' => '5', 'name' => 'Sony', 'status' => '1', 'img' => '/sony.png'],
|
|
['lang_id' => 'pl', 'description' => 'Opis', 'data' => null, 'meta_title' => 'Sony PL']
|
|
);
|
|
|
|
$repository = new ProducerRepository($mockDb);
|
|
$result = $repository->findForFrontend(5, 'pl');
|
|
|
|
$this->assertSame(5, $result['id']);
|
|
$this->assertSame('Sony', $result['name']);
|
|
$this->assertArrayHasKey('pl', $result['languages']);
|
|
$this->assertSame('Sony PL', $result['languages']['pl']['meta_title']);
|
|
}
|
|
}
|