| Current Path : /var/www/v3.cesa.co.za/tests/Unit/MemberBundle/ |
| Current File : /var/www/v3.cesa.co.za/tests/Unit/MemberBundle/MemberFirmTransformationPortalServiceTest.php |
<?php
namespace App\Tests\Unit\MemberBundle;
use App\MemberBundle\Entity\ADecMemberFirm;
use App\MemberBundle\Entity\ADecTransformation;
use App\MemberBundle\Entity\MemberFirm;
use App\MemberBundle\Form\Model\MemberFirmTransformationCapture;
use App\MemberBundle\Repository\ADecMemberFirmRepository;
use App\MemberBundle\Repository\ADecTransformationRepository;
use App\MemberBundle\Repository\MemberContactRepository;
use App\MemberBundle\Service\MemberFirmTransformationPortalService;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
class MemberFirmTransformationPortalServiceTest extends TestCase
{
public function testPrepareDeclarationUsesCurrentYearWhenPresent(): void
{
$liveFirm = $this->createMock(MemberFirm::class);
$liveFirm->method('getId')->willReturn(263);
$adecFirm = $this->createMock(ADecMemberFirm::class);
$adecFirm->method('getSmme')->willReturn('EME');
$adecFirm->method('getBlackOwned')->willReturn('10%');
$adecFirm->method('getBlackWomenOwned')->willReturn('5%');
$adecFirm->method('getBbbeeLevel')->willReturn(4);
$adecFirm->method('getTotalStaff')->willReturn(100);
$adecFirm->method('getThreeYearsAverageTurnover')->willReturn('1000000');
$adecFirm->method('getMemberTransformation')->willReturn(null);
$adecTrans = $this->createMock(ADecTransformation::class);
$adecTrans->method('getTransTopMa')->willReturn(1);
$year = (int) date('Y');
$adecFirmRepo = $this->createMock(ADecMemberFirmRepository::class);
$adecFirmRepo->method('findOneByLiveFirmAndDeclarationYear')
->willReturnCallback(static function (int $firmId, int $y) use ($year, $adecFirm) {
return $y === $year ? $adecFirm : null;
});
$adecTransRepo = $this->createMock(ADecTransformationRepository::class);
$adecTransRepo->method('findOneByLiveFirmAndDeclarationYear')->willReturn($adecTrans);
$em = $this->createMock(EntityManagerInterface::class);
$em->method('getRepository')->willReturnCallback(
static function (string $class) use ($adecFirmRepo, $adecTransRepo) {
if ($class === ADecMemberFirm::class) {
return $adecFirmRepo;
}
if ($class === ADecTransformation::class) {
return $adecTransRepo;
}
throw new \RuntimeException('Unexpected repository: ' . $class);
},
);
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$em,
);
$context = $service->prepareDeclarationCapture($liveFirm);
$this->assertSame($year, $context->declarationYear);
$this->assertTrue($context->hasCurrentYearDeclaration);
$this->assertNull($context->prefilledFromYear);
$this->assertSame('EME', $context->capture->smme);
}
public function testPrepareDeclarationPrefillsFromPriorYear(): void
{
$year = (int) date('Y');
$priorYear = $year - 1;
$liveFirm = $this->createMock(MemberFirm::class);
$liveFirm->method('getId')->willReturn(263);
$liveFirm->method('getMemberTransformation')->willReturn(null);
$liveFirm->method('getSmme')->willReturn(null);
$priorFirm = $this->createMock(ADecMemberFirm::class);
$priorFirm->method('getSmme')->willReturn('PriorSMME');
$priorFirm->method('getBlackOwned')->willReturn('20%');
$priorFirm->method('getBlackWomenOwned')->willReturn('10%');
$priorFirm->method('getBbbeeLevel')->willReturn(3);
$priorFirm->method('getTotalStaff')->willReturn(50);
$priorFirm->method('getThreeYearsAverageTurnover')->willReturn(null);
$priorFirm->method('getMemberTransformation')->willReturn(null);
$priorTrans = $this->createMock(ADecTransformation::class);
$priorTrans->method('getTransTopMa')->willReturn(2);
$adecFirmRepo = $this->createMock(ADecMemberFirmRepository::class);
$adecFirmRepo->method('findOneByLiveFirmAndDeclarationYear')
->willReturnCallback(static function (int $firmId, int $y) use ($year, $priorYear, $priorFirm) {
if ($y === $year) {
return null;
}
if ($y === $priorYear) {
return $priorFirm;
}
return null;
});
$adecTransRepo = $this->createMock(ADecTransformationRepository::class);
$adecTransRepo->method('findOneByLiveFirmAndDeclarationYear')->willReturn($priorTrans);
$em = $this->createMock(EntityManagerInterface::class);
$em->method('getRepository')->willReturnCallback(
static function (string $class) use ($adecFirmRepo, $adecTransRepo) {
if ($class === ADecMemberFirm::class) {
return $adecFirmRepo;
}
if ($class === ADecTransformation::class) {
return $adecTransRepo;
}
throw new \RuntimeException('Unexpected repository: ' . $class);
},
);
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$em,
);
$context = $service->prepareDeclarationCapture($liveFirm);
$this->assertFalse($context->hasCurrentYearDeclaration);
$this->assertSame($priorYear, $context->prefilledFromYear);
$this->assertSame('PriorSMME', $context->capture->smme);
}
public function testSaveDeclarationPersistsOnlyAdecEntities(): void
{
$year = (int) date('Y');
$liveFirm = $this->createMock(MemberFirm::class);
$liveFirm->method('getId')->willReturn(263);
$liveFirm->method('getFirmName')->willReturn('Test Firm');
$liveFirm->method('getMemberStatus')->willReturn('Current');
$liveFirm->method('getSmme')->willReturn('EME');
$liveFirm->method('getBlackOwned')->willReturn('10%');
$liveFirm->method('getBlackWomenOwned')->willReturn('5%');
$liveFirm->method('getBbbeeLevel')->willReturn(4);
$liveFirm->method('getTotalStaff')->willReturn(100);
$liveFirm->method('getThreeYearsAverageTurnover')->willReturn('1000000');
$capture = new MemberFirmTransformationCapture();
$capture->smme = 'EME';
$capture->blackOwned = '10%';
$capture->blackWomenOwned = '5%';
$capture->bbbeeLevel = 4;
$capture->totalStaff = 1;
$capture->threeYearsAverageTurnover = '1000000';
$capture->trans = ['trans_top_ma' => 1];
$adecFirmRepo = $this->createMock(ADecMemberFirmRepository::class);
$adecFirmRepo->method('findOneByLiveFirmAndDeclarationYear')->willReturn(null);
$adecTransRepo = $this->createMock(ADecTransformationRepository::class);
$adecTransRepo->method('findOneByLiveFirmAndDeclarationYear')->willReturn(null);
$persisted = [];
$em = $this->createMock(EntityManagerInterface::class);
$em->method('getRepository')->willReturnCallback(
static function (string $class) use ($adecFirmRepo, $adecTransRepo) {
if ($class === ADecMemberFirm::class) {
return $adecFirmRepo;
}
if ($class === ADecTransformation::class) {
return $adecTransRepo;
}
throw new \RuntimeException('Unexpected repository: ' . $class);
},
);
$em->method('persist')->willReturnCallback(static function (object $entity) use (&$persisted): void {
$persisted[] = $entity;
});
$em->expects($this->once())->method('flush');
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$em,
);
$service->saveDeclaration($liveFirm, $capture);
$adecFirms = array_values(array_filter($persisted, static fn (object $e): bool => $e instanceof ADecMemberFirm));
$adecTrans = array_values(array_filter($persisted, static fn (object $e): bool => $e instanceof ADecTransformation));
$this->assertNotEmpty($adecFirms);
$this->assertNotEmpty($adecTrans);
$adecFirm = $adecFirms[0];
$adecTransformation = $adecTrans[0];
$this->assertSame($year, $adecFirm->getDeclarationYear());
$this->assertSame($year, $adecTransformation->getDeclarationYear());
$this->assertSame(263, $adecTransformation->getPrevFirmId());
foreach ($persisted as $entity) {
$this->assertNotInstanceOf(MemberFirm::class, $entity);
}
}
public function testSumTransformationHeadcountTotalsAllGridFields(): void
{
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$this->createMock(EntityManagerInterface::class),
);
$trans = array_fill_keys(MemberFirmTransformationPortalService::TRANSFORMATION_COUNT_FIELDS, 0);
$trans['trans_top_ma'] = 3;
$trans['trans_senior_fa'] = 2;
$this->assertSame(5, $service->sumTransformationHeadcount($trans));
}
public function testValidateStaffHeadcountMatchesGridAcceptsMatchingTotals(): void
{
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$this->createMock(EntityManagerInterface::class),
);
$capture = new MemberFirmTransformationCapture();
$capture->totalStaff = 4;
$capture->trans = [
'trans_top_ma' => 1,
'trans_top_mc' => 1,
'trans_senior_fa' => 2,
];
$this->assertNull($service->validateStaffHeadcountMatchesGrid($capture));
}
public function testValidateStaffHeadcountMatchesGridRejectsMismatch(): void
{
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$this->createMock(EntityManagerInterface::class),
);
$capture = new MemberFirmTransformationCapture();
$capture->totalStaff = 10;
$capture->trans = ['trans_top_ma' => 3];
$message = $service->validateStaffHeadcountMatchesGrid($capture);
$this->assertNotNull($message);
$this->assertStringContainsString('10', $message);
$this->assertStringContainsString('3', $message);
}
public function testSaveDeclarationRejectsMismatchedHeadcount(): void
{
$liveFirm = $this->createMock(MemberFirm::class);
$capture = new MemberFirmTransformationCapture();
$capture->totalStaff = 5;
$capture->trans = ['trans_top_ma' => 1];
$service = new MemberFirmTransformationPortalService(
$this->createMock(MemberContactRepository::class),
$this->createMock(EntityManagerInterface::class),
);
$this->expectException(\InvalidArgumentException::class);
$service->saveDeclaration($liveFirm, $capture);
}
}