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
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
87 lines
3.1 KiB
PHP
87 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace OCA\Mitgliederverwaltung\Tests\Service;
|
|
|
|
use OCA\Mitgliederverwaltung\Db\SaleRecord;
|
|
use OCA\Mitgliederverwaltung\Db\SaleRecordMapper;
|
|
use OCA\Mitgliederverwaltung\Service\AuditService;
|
|
use OCA\Mitgliederverwaltung\Service\SaleService;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class SaleServiceTest extends TestCase {
|
|
|
|
private SaleService $service;
|
|
private SaleRecordMapper&MockObject $saleRecordMapper;
|
|
private AuditService&MockObject $auditService;
|
|
private LoggerInterface&MockObject $logger;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->saleRecordMapper = $this->createMock(SaleRecordMapper::class);
|
|
$this->auditService = $this->createMock(AuditService::class);
|
|
$this->logger = $this->createMock(LoggerInterface::class);
|
|
|
|
$this->service = new SaleService(
|
|
$this->saleRecordMapper,
|
|
$this->auditService,
|
|
$this->logger
|
|
);
|
|
}
|
|
|
|
private function saleEntity(int $id = 1, int $stockItemId = 1, int $variantId = 1, int $quantity = 2, string $unitPrice = '25.00'): SaleRecord {
|
|
$entity = new SaleRecord();
|
|
$entity->setId($id);
|
|
$entity->setStockItemId($stockItemId);
|
|
$entity->setVariantId($variantId);
|
|
$entity->setDate('2026-04-21');
|
|
$entity->setQuantity($quantity);
|
|
$entity->setUnitPrice($unitPrice);
|
|
$entity->setTotalPrice((string)((float)$unitPrice * $quantity));
|
|
$entity->setNotes(null);
|
|
$entity->setCreatedAt('2026-04-21 00:00:00');
|
|
return $entity;
|
|
}
|
|
|
|
public function testCreateSale_auditLogged(): void {
|
|
$this->saleRecordMapper->method('insert')->willReturnCallback(function ($entity) use ($stockItemId = 1) {
|
|
$entity->setId(1);
|
|
});
|
|
|
|
$this->auditService->method('logCreate')->willReturnCallback(function(array $data, string $type, int $id) {
|
|
$this->assertSame(1, $data['stock_item_id']);
|
|
$this->assertSame('inventory_sale', $type);
|
|
$this->assertSame(1, $id);
|
|
});
|
|
|
|
$result = $this->service->createSale([
|
|
'stock_item_id' => 1,
|
|
'variant_id' => 1,
|
|
'date' => '2026-04-21',
|
|
'quantity' => 2,
|
|
'unit_price' => '25.00',
|
|
'notes' => null,
|
|
]);
|
|
|
|
$this->assertSame('50.00', $result->getTotalPrice());
|
|
}
|
|
|
|
public function testSaleRecord_totalCalculation(): void {
|
|
$sale = $this->saleEntity(1, 1, 1, 3, '15.00');
|
|
$expectedTotal = (float)$sale->getQuantity() * (float)$sale->getUnitPrice();
|
|
$actualTotal = (float)$sale->getTotalPrice();
|
|
$this->assertEqualsWithDelta($expectedTotal, $actualTotal, 0.01);
|
|
}
|
|
|
|
public function testSaleRecord_totalCalculationZero(): void {
|
|
$sale = $this->saleEntity(1, 1, 1, 0, '0.00');
|
|
$expectedTotal = 0.0;
|
|
$actualTotal = (float)$sale->getTotalPrice();
|
|
$this->assertEqualsWithDelta($expectedTotal, $actualTotal, 0.01);
|
|
}
|
|
}
|