ver. 0.289: ShopCategory + ShopClient frontend migration to Domain + Views + Controllers
ShopCategory: 9 frontend methods in CategoryRepository, front\Views\ShopCategory (3 methods), deleted factory + view, updated 6 callers, +17 tests. ShopClient: 13 frontend methods in ClientRepository, front\Views\ShopClient (8 methods), front\Controllers\ShopClientController (15 methods + buildEmailBody helper), deleted factory + view + controls, updated 7 callers, +36 tests. Security fix: removed hardcoded password bypass 'Legia1916'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -131,4 +131,505 @@ class ClientRepositoryTest extends TestCase
|
||||
$this->assertSame(4, $totals['total_orders']);
|
||||
$this->assertSame(456.78, $totals['total_spent']);
|
||||
}
|
||||
|
||||
// ===== Frontend methods =====
|
||||
|
||||
public function testClientDetailsReturnsNullForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->clientDetails(0));
|
||||
$this->assertNull($repo->clientDetails(-1));
|
||||
}
|
||||
|
||||
public function testClientDetailsReturnsRowOnSuccess(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_clients', '*', ['id' => 5])
|
||||
->willReturn(['id' => 5, 'email' => 'jan@example.com']);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->clientDetails(5);
|
||||
$this->assertSame('jan@example.com', $result['email']);
|
||||
}
|
||||
|
||||
public function testClientDetailsReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->clientDetails(999));
|
||||
}
|
||||
|
||||
public function testClientEmailReturnsNullForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->clientEmail(0));
|
||||
}
|
||||
|
||||
public function testClientEmailReturnsStringOnSuccess(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_clients', 'email', ['id' => 3])
|
||||
->willReturn('test@example.com');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame('test@example.com', $repo->clientEmail(3));
|
||||
}
|
||||
|
||||
public function testClientEmailReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->clientEmail(999));
|
||||
}
|
||||
|
||||
public function testClientAddressesReturnsEmptyForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('select');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame([], $repo->clientAddresses(0));
|
||||
}
|
||||
|
||||
public function testClientAddressesReturnsRows(): void
|
||||
{
|
||||
$rows = [
|
||||
['id' => 1, 'client_id' => 5, 'city' => 'Warszawa'],
|
||||
['id' => 2, 'client_id' => 5, 'city' => 'Kraków'],
|
||||
];
|
||||
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('select')
|
||||
->with('pp_shop_clients_addresses', '*', ['client_id' => 5])
|
||||
->willReturn($rows);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertCount(2, $repo->clientAddresses(5));
|
||||
}
|
||||
|
||||
public function testClientAddressesHandlesFalseFromDb(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('select')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame([], $repo->clientAddresses(1));
|
||||
}
|
||||
|
||||
public function testAddressDetailsReturnsNullForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->addressDetails(0));
|
||||
}
|
||||
|
||||
public function testAddressDetailsReturnsRow(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->with('pp_shop_clients_addresses', '*', ['id' => 7])
|
||||
->willReturn(['id' => 7, 'city' => 'Gdańsk']);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->addressDetails(7);
|
||||
$this->assertSame('Gdańsk', $result['city']);
|
||||
}
|
||||
|
||||
public function testAddressDeleteReturnsFalseForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('delete');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertFalse($repo->addressDelete(0));
|
||||
}
|
||||
|
||||
public function testAddressDeleteReturnsTrueOnSuccess(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('delete')
|
||||
->with('pp_shop_clients_addresses', ['id' => 3])
|
||||
->willReturn(1);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertTrue($repo->addressDelete(3));
|
||||
}
|
||||
|
||||
public function testAddressSaveReturnsFalseForInvalidClientId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('insert');
|
||||
$mockDb->expects($this->never())->method('update');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertFalse($repo->addressSave(0, null, ['name' => 'Jan']));
|
||||
}
|
||||
|
||||
public function testAddressSaveInsertsNewAddress(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('insert')
|
||||
->with(
|
||||
'pp_shop_clients_addresses',
|
||||
$this->callback(function ($row) {
|
||||
return $row['client_id'] === 5
|
||||
&& $row['name'] === 'Jan'
|
||||
&& $row['city'] === 'Warszawa';
|
||||
})
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->addressSave(5, null, [
|
||||
'name' => 'Jan',
|
||||
'surname' => 'Kowalski',
|
||||
'street' => 'Marszałkowska 1',
|
||||
'postal_code' => '00-001',
|
||||
'city' => 'Warszawa',
|
||||
'phone' => '123456789',
|
||||
]);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testAddressSaveUpdatesExistingAddress(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->with(
|
||||
'pp_shop_clients_addresses',
|
||||
$this->callback(function ($row) {
|
||||
return $row['name'] === 'Anna' && !isset($row['client_id']);
|
||||
}),
|
||||
['AND' => ['client_id' => 5, 'id' => 10]]
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->addressSave(5, 10, [
|
||||
'name' => 'Anna',
|
||||
'surname' => 'Nowak',
|
||||
'street' => 'Piłsudskiego 2',
|
||||
'postal_code' => '30-001',
|
||||
'city' => 'Kraków',
|
||||
'phone' => '987654321',
|
||||
]);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testMarkAddressAsCurrentReturnsFalseForInvalidIds(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('update');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertFalse($repo->markAddressAsCurrent(0, 1));
|
||||
$this->assertFalse($repo->markAddressAsCurrent(1, 0));
|
||||
}
|
||||
|
||||
public function testMarkAddressAsCurrentResetsAndSets(): void
|
||||
{
|
||||
$calls = [];
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->exactly(2))
|
||||
->method('update')
|
||||
->willReturnCallback(function ($table, $data, $where) use (&$calls) {
|
||||
$calls[] = ['data' => $data, 'where' => $where];
|
||||
return 1;
|
||||
});
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertTrue($repo->markAddressAsCurrent(5, 3));
|
||||
|
||||
$this->assertSame(['current' => 0], $calls[0]['data']);
|
||||
$this->assertSame(['client_id' => 5], $calls[0]['where']);
|
||||
$this->assertSame(['current' => 1], $calls[1]['data']);
|
||||
$this->assertSame(['AND' => ['client_id' => 5, 'id' => 3]], $calls[1]['where']);
|
||||
}
|
||||
|
||||
public function testAuthenticateReturnsErrorOnEmptyInput(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
|
||||
$result = $repo->authenticate('', 'pass');
|
||||
$this->assertSame('error', $result['status']);
|
||||
|
||||
$result = $repo->authenticate('jan@example.com', '');
|
||||
$this->assertSame('error', $result['status']);
|
||||
}
|
||||
|
||||
public function testAuthenticateReturnsErrorWhenClientNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->authenticate('nobody@example.com', 'pass');
|
||||
$this->assertSame('error', $result['status']);
|
||||
$this->assertSame('logowanie-nieudane', $result['code']);
|
||||
}
|
||||
|
||||
public function testAuthenticateReturnsInactiveForUnconfirmedAccount(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn([
|
||||
'id' => 1,
|
||||
'password' => md5('2026-01-01 00:00:00' . 'test123'),
|
||||
'register_date' => '2026-01-01 00:00:00',
|
||||
'hash' => 'abc123',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->authenticate('jan@example.com', 'test123');
|
||||
$this->assertSame('inactive', $result['status']);
|
||||
$this->assertSame('abc123', $result['hash']);
|
||||
}
|
||||
|
||||
public function testAuthenticateReturnsErrorOnWrongPassword(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn([
|
||||
'id' => 1,
|
||||
'password' => md5('2026-01-01 00:00:00' . 'correct'),
|
||||
'register_date' => '2026-01-01 00:00:00',
|
||||
'hash' => 'abc',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->authenticate('jan@example.com', 'wrong');
|
||||
$this->assertSame('error', $result['status']);
|
||||
$this->assertSame('logowanie-blad-nieprawidlowe-haslo', $result['code']);
|
||||
}
|
||||
|
||||
public function testAuthenticateReturnsOkOnSuccess(): void
|
||||
{
|
||||
$registerDate = '2026-01-01 00:00:00';
|
||||
$password = 'test123';
|
||||
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
[
|
||||
'id' => 5,
|
||||
'password' => md5($registerDate . $password),
|
||||
'register_date' => $registerDate,
|
||||
'hash' => 'abc',
|
||||
'status' => 1,
|
||||
],
|
||||
['id' => 5, 'email' => 'jan@example.com', 'name' => 'Jan']
|
||||
);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->authenticate('jan@example.com', $password);
|
||||
$this->assertSame('ok', $result['status']);
|
||||
$this->assertSame(5, $result['client']['id']);
|
||||
}
|
||||
|
||||
public function testCreateClientReturnsNullOnEmptyInput(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('count');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->createClient('', 'pass', false));
|
||||
$this->assertNull($repo->createClient('jan@example.com', '', false));
|
||||
}
|
||||
|
||||
public function testCreateClientReturnsNullWhenEmailTaken(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('count')
|
||||
->with('pp_shop_clients', ['email' => 'jan@example.com'])
|
||||
->willReturn(1);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->createClient('jan@example.com', 'pass', false));
|
||||
}
|
||||
|
||||
public function testCreateClientReturnsIdAndHashOnSuccess(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())->method('count')->willReturn(0);
|
||||
$mockDb->expects($this->once())
|
||||
->method('insert')
|
||||
->with(
|
||||
'pp_shop_clients',
|
||||
$this->callback(function ($row) {
|
||||
return $row['email'] === 'jan@example.com'
|
||||
&& $row['agremment_marketing'] === 1
|
||||
&& !empty($row['hash'])
|
||||
&& !empty($row['password']);
|
||||
})
|
||||
)
|
||||
->willReturn(1);
|
||||
$mockDb->expects($this->once())->method('id')->willReturn(42);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->createClient('jan@example.com', 'pass', true);
|
||||
$this->assertSame(42, $result['id']);
|
||||
$this->assertNotEmpty($result['hash']);
|
||||
}
|
||||
|
||||
public function testConfirmRegistrationReturnsNullOnEmptyHash(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->confirmRegistration(''));
|
||||
}
|
||||
|
||||
public function testConfirmRegistrationReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->confirmRegistration('nonexistent'));
|
||||
}
|
||||
|
||||
public function testConfirmRegistrationActivatesAndReturnsEmail(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->willReturnOnConsecutiveCalls(10, 'jan@example.com');
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->with('pp_shop_clients', ['status' => 1], ['id' => 10]);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame('jan@example.com', $repo->confirmRegistration('validhash'));
|
||||
}
|
||||
|
||||
public function testGenerateNewPasswordReturnsNullOnEmptyHash(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->generateNewPassword(''));
|
||||
}
|
||||
|
||||
public function testGenerateNewPasswordReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->generateNewPassword('badhash'));
|
||||
}
|
||||
|
||||
public function testGenerateNewPasswordReturnsEmailAndPassword(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn([
|
||||
'id' => 5,
|
||||
'email' => 'jan@example.com',
|
||||
'register_date' => '2026-01-01 00:00:00',
|
||||
]);
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->with(
|
||||
'pp_shop_clients',
|
||||
$this->callback(function ($data) {
|
||||
return $data['password_recovery'] === 0
|
||||
&& !empty($data['password']);
|
||||
}),
|
||||
['id' => 5]
|
||||
);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$result = $repo->generateNewPassword('validhash');
|
||||
$this->assertSame('jan@example.com', $result['email']);
|
||||
$this->assertSame(10, strlen($result['password']));
|
||||
}
|
||||
|
||||
public function testInitiatePasswordRecoveryReturnsNullOnEmptyEmail(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('get');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->initiatePasswordRecovery(''));
|
||||
}
|
||||
|
||||
public function testInitiatePasswordRecoveryReturnsNullWhenNotFound(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(false);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertNull($repo->initiatePasswordRecovery('nobody@example.com'));
|
||||
}
|
||||
|
||||
public function testInitiatePasswordRecoverySetsRecoveryFlagAndReturnsHash(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn('abc123hash');
|
||||
$mockDb->expects($this->once())
|
||||
->method('update')
|
||||
->with('pp_shop_clients', ['password_recovery' => 1], ['email' => 'jan@example.com']);
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame('abc123hash', $repo->initiatePasswordRecovery('jan@example.com'));
|
||||
}
|
||||
|
||||
public function testClientOrdersReturnsEmptyForInvalidId(): void
|
||||
{
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->expects($this->never())->method('select');
|
||||
|
||||
$repo = new ClientRepository($mockDb);
|
||||
$this->assertSame([], $repo->clientOrders(0));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user