Files
Enelix-EMS/tests/LizenzpruefungTest.php
T
2026-09-29 05:53:15 +00:00

268 lines
8.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Belevo\EnelixEMS\Tests;
use Belevo\EnelixEMS\Lizenzpruefung;
use DateTimeImmutable;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
final class LizenzpruefungTest extends TestCase
{
private const INSTALLATION_ID = '123e4567-e89b-42d3-a456-426614174000';
public function testStandardLizenzGibtGrundregelungFrei(): void
{
Lizenzpruefung::pruefeLease(
$this->lease('manager_standard'),
self::INSTALLATION_ID,
0,
$this->zeit('2026-09-19T12:00:00Z')
);
self::assertTrue(true);
}
public function testPeakLizenzGibtLastspitzenmodusFrei(): void
{
Lizenzpruefung::pruefeLease(
$this->lease('manager_peak'),
self::INSTALLATION_ID,
2,
$this->zeit('2026-09-19T12:00:00Z')
);
self::assertTrue(true);
}
public function testStandardLizenzSperrtLastspitzenmodus(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Peak Shaving ist nicht lizenziert.');
Lizenzpruefung::pruefeLease(
$this->lease('manager_standard'),
self::INSTALLATION_ID,
1,
$this->zeit('2026-09-19T12:00:00Z')
);
}
public function testAbgelaufeneOfflineFreigabeWirdAbgelehnt(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Offline-Freigabe ist abgelaufen.');
Lizenzpruefung::pruefeLease(
$this->lease('manager_peak'),
self::INSTALLATION_ID,
0,
$this->zeit('2026-10-03T12:00:00Z')
);
}
public function testAndereInstallationWirdAbgelehnt(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('anderen Installation');
Lizenzpruefung::pruefeLease(
$this->lease('manager_standard'),
'223e4567-e89b-42d3-a456-426614174000',
0,
$this->zeit('2026-09-19T12:00:00Z')
);
}
public function testErneuerungWirdAbRefreshAfterFaellig(): void
{
$lease = $this->lease('manager_standard');
self::assertFalse(Lizenzpruefung::erneuerungFaellig(
$lease,
$this->zeit('2026-09-20T11:59:59Z')
));
self::assertTrue(Lizenzpruefung::erneuerungFaellig(
$lease,
$this->zeit('2026-09-20T12:00:00Z')
));
}
public function testLeaseOhneManagerBerechtigungWirdAbgelehnt(): void
{
$lease = $this->lease('consumer_single');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Manager-Berechtigung fehlt.');
Lizenzpruefung::pruefeLease(
$lease,
self::INSTALLATION_ID,
0,
$this->zeit('2026-09-19T12:00:00Z')
);
}
public function testZweiLizenzierteBoilerWerdenFreigegeben(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'][] = [
'sku' => 'ENX-BOILER-MULTI',
'catalog_key' => 'boiler_multi',
'quantity' => 2,
'status' => 'active',
];
self::assertSame(2, Lizenzpruefung::berechtigungsMenge($lease, 'boiler_multi'));
Lizenzpruefung::pruefeVerbrauchermengen($lease, ['boiler_multi' => 2]);
self::assertTrue(true);
}
public function testDritterBoilerBeiZweiLizenzenWirdAbgelehnt(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'][] = [
'sku' => 'ENX-BOILER-MULTI',
'catalog_key' => 'boiler_multi',
'quantity' => 2,
'status' => 'active',
];
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(
'Lizenzkontingent fuer boiler_multi ueberschritten: 3 verwendet, 2 lizenziert.'
);
Lizenzpruefung::pruefeVerbrauchermengen($lease, ['boiler_multi' => 3]);
}
public function testVerbraucherkontingenteWerdenJeTypSummiertUndGetrenntGeprueft(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'] = array_merge($lease['entitlements'], [
[
'catalog_key' => 'boiler_multi',
'quantity' => 1,
'status' => 'active',
],
[
'catalog_key' => 'boiler_multi',
'quantity' => 1,
'status' => 'active',
],
[
'catalog_key' => 'battery',
'quantity' => 1,
'status' => 'active',
],
[
'catalog_key' => 'battery',
'quantity' => 10,
'status' => 'revoked',
],
]);
self::assertSame(2, Lizenzpruefung::berechtigungsMenge($lease, 'boiler_multi'));
self::assertSame(1, Lizenzpruefung::berechtigungsMenge($lease, 'battery'));
Lizenzpruefung::pruefeVerbrauchermengen($lease, [
'boiler_multi' => 2,
'battery' => 1,
]);
self::assertTrue(true);
}
public function testSeparateWaermepumpenlizenzBleibtUnveraendert(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'][] = [
'catalog_key' => 'heat_pump',
'quantity' => 1,
'status' => 'active',
];
$verwendung = ['heat_pump' => 1];
$pruefmengen = Lizenzpruefung::beruecksichtigeBestandslizenzFuerWaermepumpen(
$lease,
$verwendung
);
self::assertSame($verwendung, $pruefmengen);
Lizenzpruefung::pruefeVerbrauchermengen($lease, $pruefmengen);
}
public function testFreieBestandslizenzDecktEineWaermepumpeAb(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'][] = [
'catalog_key' => 'consumer_single',
'quantity' => 1,
'status' => 'active',
];
$pruefmengen = Lizenzpruefung::beruecksichtigeBestandslizenzFuerWaermepumpen(
$lease,
['heat_pump' => 1]
);
self::assertSame(['heat_pump' => 0, 'consumer_single' => 1], $pruefmengen);
Lizenzpruefung::pruefeVerbrauchermengen($lease, $pruefmengen);
}
public function testBestandslizenzDarfNichtDoppeltVerwendetWerden(): void
{
$lease = $this->lease('manager_standard');
$lease['entitlements'][] = [
'catalog_key' => 'consumer_single',
'quantity' => 1,
'status' => 'active',
];
$pruefmengen = Lizenzpruefung::beruecksichtigeBestandslizenzFuerWaermepumpen(
$lease,
['consumer_single' => 1, 'heat_pump' => 1]
);
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Lizenzkontingent fuer heat_pump ueberschritten');
Lizenzpruefung::pruefeVerbrauchermengen($lease, $pruefmengen);
}
public function testLizenzcodeWirdWieAufDemServerNormalisiert(): void
{
self::assertSame(
'ENX23456789ABCDEFGH',
Lizenzpruefung::normalisiereCode('enx-2345-6789-abcd-efgh')
);
self::assertTrue(Lizenzpruefung::istLizenzcodeGueltig('ENX-2345-6789-ABCD-EFGH'));
self::assertFalse(Lizenzpruefung::istLizenzcodeGueltig('ENX-OOOO-OOOO-OOOO-OOOO'));
}
/**
* @return array<string, mixed>
*/
private function lease(string $sku): array
{
return [
'status' => 'active',
'development' => true,
'installationId' => self::INSTALLATION_ID,
'orderId' => '323e4567-e89b-42d3-a456-426614174000',
'entitlements' => [[
'sku' => $sku,
'catalog_key' => $sku,
'quantity' => 1,
'status' => 'active',
]],
'issuedAt' => '2026-09-19T12:00:00.000Z',
'refreshAfter' => '2026-09-20T12:00:00.000Z',
'offlineUntil' => '2026-10-03T12:00:00.000Z',
];
}
private function zeit(string $wert): int
{
return (new DateTimeImmutable($wert))->getTimestamp();
}
}