Files
Mitgliederverwaltung/tests/Db/InventoryCategoryMapperTest.php
T
shahondin1624 53b3fd945a
Database Portability Tests / Integration (mysql) (push) Has been skipped
Database Portability Tests / Integration (postgres) (push) Has been skipped
Database Portability Tests / Integration (sqlite) (push) Has been skipped
Database Portability Tests / Verify no MySQL-specific SQL (push) Successful in 5s
Database Portability Tests / Unit Tests (PlatformHelper) (push) Failing after 43s
Release v0.3.2: Inventory tracking, test infra, and bugfixes
Inventory:
- General material, stock items, and sales CRUD
- Category management with CategoryPicker component
- Inventory reports service
- Database migrations and mappers

Frontend:
- Inventory view with tabs (Allgemeinmaterial, Verkaufsmaterial, Verkäufe)
- Forms for general material, stock items, and sales
- Search bar fix: flexbox wrapper with inline icon replaces broken NcTextField icon slot

Tests:
- All 1,491 tests pass (zero errors, warnings, deprecations)
- BundleImportServiceTest: fixed ZipArchive empty-file deprecation
- BundleImportService: null-coalescing for targetFields
- PHPUnit test infra: make test target via container

CLAUDE.md:
- Added Testing section as PR gating criterion
2026-04-22 10:15:22 +02:00

122 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace OCA\Mitgliederverwaltung\Tests\Db;
use OCA\Mitgliederverwaltung\Db\InventoryCategory;
use OCA\Mitgliederverwaltung\Db\InventoryCategoryMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\DB\QueryBuilder\IExpressionBuilder;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\IResult;
use OCP\IDBConnection;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class InventoryCategoryMapperTest extends TestCase {
private IDBConnection&MockObject $db;
private IQueryBuilder&MockObject $qb;
private IExpressionBuilder&MockObject $expr;
private IResult&MockObject $result;
protected function setUp(): void {
parent::setUp();
$this->db = $this->createMock(IDBConnection::class);
$this->qb = $this->createMock(IQueryBuilder::class);
$this->expr = $this->createMock(IExpressionBuilder::class);
$this->result = $this->createMock(IResult::class);
$this->qb->method('expr')->willReturn($this->expr);
$this->qb->method('select')->willReturnSelf();
$this->qb->method('from')->willReturnSelf();
$this->qb->method('where')->willReturnSelf();
$this->qb->method('andWhere')->willReturnSelf();
$this->qb->method('orderBy')->willReturnSelf();
$this->qb->method('insert')->willReturnSelf();
$this->qb->method('delete')->willReturnSelf();
$this->qb->method('values')->willReturnSelf();
$this->qb->method('createNamedParameter')->willReturn(':param');
$this->qb->method('createFunction')->willReturnCallback(fn($call) => $call);
$this->qb->method('getSQL')->willReturn('SELECT * FROM test');
$this->expr->method('eq')->willReturn('col = :param');
$this->expr->method('isNull')->willReturn('col IS NULL');
$this->expr->method('neq')->willReturn('col != :param');
$this->db->method('getQueryBuilder')->willReturn($this->qb);
}
private function configureResultRows(array $rows): void {
$fetchCalls = array_merge($rows, [false]);
$this->result->method('fetch')
->willReturnOnConsecutiveCalls(...$fetchCalls);
$this->result->method('closeCursor')->willReturn(true);
$this->qb->method('executeQuery')->willReturn($this->result);
}
private function configureResultSingleRow(array $row): void {
$this->result->method('fetch')
->willReturnOnConsecutiveCalls($row, false);
$this->result->method('closeCursor')->willReturn(true);
$this->qb->method('executeQuery')->willReturn($this->result);
}
private function configureResultEmpty(): void {
$this->result->method('fetch')->willReturn(false);
$this->result->method('closeCursor')->willReturn(true);
$this->qb->method('executeQuery')->willReturn($this->result);
}
private function categoryRow(int $id = 1, string $name = 'Zelte'): array {
return [
'id' => $id,
'name' => $name,
'created_at' => '2026-04-21 00:00:00',
];
}
public function testCreateAndFindById(): void {
$this->configureResultSingleRow($this->categoryRow(42, 'Zelte'));
$mapper = new InventoryCategoryMapper($this->db);
$category = $mapper->findById(42);
$this->assertSame(42, $category->getId());
$this->assertSame('Zelte', $category->getName());
}
public function testFindByName(): void {
$this->configureResultSingleRow($this->categoryRow(1, 'Kochgeschirr'));
$mapper = new InventoryCategoryMapper($this->db);
$category = $mapper->findByName('Kochgeschirr');
$this->assertSame('Kochgeschirr', $category->getName());
}
public function testFindByNameThrowsWhenNotFound(): void {
$this->configureResultEmpty();
$mapper = new InventoryCategoryMapper($this->db);
$this->expectException(DoesNotExistException::class);
$mapper->findByName('NichtExistent');
}
public function testFindAll(): void {
$this->configureResultRows([
$this->categoryRow(1, 'Zelte'),
$this->categoryRow(2, 'Kochgeschirr'),
$this->categoryRow(3, 'Seile'),
]);
$mapper = new InventoryCategoryMapper($this->db);
$categories = $mapper->findAll();
$this->assertCount(3, $categories);
$this->assertSame('Zelte', $categories[0]->getName());
}
public function testFindAllEmpty(): void {
$this->configureResultRows([]);
$mapper = new InventoryCategoryMapper($this->db);
$categories = $mapper->findAll();
$this->assertCount(0, $categories);
}
}