123, 'expires_at' => '2027-01-21', 'version_id' => 5, ]; $licenseInfo = LicenseInfo::fromArray($data); self::assertSame(123, $licenseInfo->productId); self::assertInstanceOf(\DateTimeImmutable::class, $licenseInfo->expiresAt); self::assertSame('2027-01-21', $licenseInfo->expiresAt->format('Y-m-d')); self::assertSame(5, $licenseInfo->versionId); } #[Test] public function itCanBeCreatedWithNullExpiresAt(): void { $data = [ 'product_id' => 456, 'expires_at' => null, 'version_id' => null, ]; $licenseInfo = LicenseInfo::fromArray($data); self::assertSame(456, $licenseInfo->productId); self::assertNull($licenseInfo->expiresAt); self::assertNull($licenseInfo->versionId); } #[Test] public function itCanBeCreatedWithoutOptionalFields(): void { $data = [ 'product_id' => 789, ]; $licenseInfo = LicenseInfo::fromArray($data); self::assertSame(789, $licenseInfo->productId); self::assertNull($licenseInfo->expiresAt); self::assertNull($licenseInfo->versionId); } #[Test] public function itIdentifiesLifetimeLicense(): void { $lifetime = LicenseInfo::fromArray(['product_id' => 1, 'expires_at' => null]); $expiring = LicenseInfo::fromArray(['product_id' => 2, 'expires_at' => '2027-12-31']); self::assertTrue($lifetime->isLifetime()); self::assertFalse($expiring->isLifetime()); } }