diff --git a/src/Models/Template.php b/src/Models/Template.php index 933d588..9f5a36e 100644 --- a/src/Models/Template.php +++ b/src/Models/Template.php @@ -20,6 +20,19 @@ class Template public ?array $supportSettings; public ?array $termsSettings; public ?array $styleSettings; + public ?array $metadata; + + // Convenience accessors (snake_case aliases) + public ?string $use_case; + public ?string $created_at; + public ?string $last_published_at; + public ?int $issued_keys_count; + public ?int $active_keys_count; + + // Convenience accessors extracted from nested objects + public ?bool $allow_on_multiple_devices; + public ?int $watch_count; + public ?int $iphone_count; public function __construct(AccessGridClient $client, array $data) { @@ -37,5 +50,18 @@ public function __construct(AccessGridClient $client, array $data) $this->supportSettings = $data['support_settings'] ?? null; $this->termsSettings = $data['terms_settings'] ?? null; $this->styleSettings = $data['style_settings'] ?? null; + $this->metadata = $data['metadata'] ?? null; + + // snake_case aliases + $this->use_case = $this->useCase; + $this->created_at = $this->createdAt; + $this->last_published_at = $this->lastPublishedAt; + $this->issued_keys_count = $this->issuedKeysCount; + $this->active_keys_count = $this->activeKeysCount; + + // Convenience accessors from nested objects + $this->allow_on_multiple_devices = $this->allowedDeviceCounts['allow_on_multiple_devices'] ?? null; + $this->watch_count = $this->allowedDeviceCounts['watch'] ?? null; + $this->iphone_count = $this->allowedDeviceCounts['iphone'] ?? null; } } \ No newline at end of file diff --git a/src/Services/Console.php b/src/Services/Console.php index a07a0f3..600cfc6 100644 --- a/src/Services/Console.php +++ b/src/Services/Console.php @@ -90,6 +90,14 @@ public function listPassTemplatePairs(array $params = []): array return $response; } + /** + * List ledger items (alias matching doc examples) + */ + public function ledgerItems(array $params = []): array + { + return $this->listLedgerItems($params); + } + /** * List ledger items */ @@ -146,7 +154,9 @@ public function deleteWebhook(string $webhookId): void */ public function iosPreflight(array $data): object { - $response = $this->client->post('/v1/console/ios-preflight', $data); + $templateId = $data['card_template_id']; + $body = array_diff_key($data, ['card_template_id' => true]); + $response = $this->client->post("/v1/console/card-templates/{$templateId}/ios_preflight", $body); return (object) $response; } } \ No newline at end of file diff --git a/tests/Models/TemplateTest.php b/tests/Models/TemplateTest.php index 28b869a..dbaa5c2 100644 --- a/tests/Models/TemplateTest.php +++ b/tests/Models/TemplateTest.php @@ -23,6 +23,7 @@ public function testConstructionWithFullData(): void 'support_settings' => ['support_email' => 'help@example.com'], 'terms_settings' => ['privacy_policy_url' => 'https://example.com/privacy'], 'style_settings' => ['background_color' => '#FFFFFF'], + 'metadata' => ['version' => '2.1'], ]; $template = new Template($this->client, $data); @@ -40,6 +41,14 @@ public function testConstructionWithFullData(): void $this->assertEquals('help@example.com', $template->supportSettings['support_email']); $this->assertEquals('https://example.com/privacy', $template->termsSettings['privacy_policy_url']); $this->assertEquals('#FFFFFF', $template->styleSettings['background_color']); + $this->assertEquals(['version' => '2.1'], $template->metadata); + + // snake_case aliases + $this->assertEquals('employee_badge', $template->use_case); + $this->assertEquals('2025-01-01T00:00:00Z', $template->created_at); + $this->assertEquals('2025-06-01T00:00:00Z', $template->last_published_at); + $this->assertEquals(100, $template->issued_keys_count); + $this->assertEquals(85, $template->active_keys_count); } public function testConstructionWithMinimalData(): void @@ -60,6 +69,31 @@ public function testConstructionWithMinimalData(): void $this->assertNull($template->activeKeysCount); } + public function testConvenienceDeviceCountAccessors(): void + { + $template = new Template($this->client, [ + 'allowed_device_counts' => [ + 'allow_on_multiple_devices' => true, + 'watch' => 2, + 'iphone' => 3, + ], + ]); + + $this->assertTrue($template->allow_on_multiple_devices); + $this->assertEquals(2, $template->watch_count); + $this->assertEquals(3, $template->iphone_count); + } + + public function testConvenienceAccessorsNullWhenMissing(): void + { + $template = new Template($this->client, []); + + $this->assertNull($template->allow_on_multiple_devices); + $this->assertNull($template->watch_count); + $this->assertNull($template->iphone_count); + $this->assertNull($template->metadata); + } + public function testNullableArrayProperties(): void { $template = new Template($this->client, []); diff --git a/tests/Services/ConsoleTest.php b/tests/Services/ConsoleTest.php index e83ea62..c37d359 100644 --- a/tests/Services/ConsoleTest.php +++ b/tests/Services/ConsoleTest.php @@ -170,7 +170,7 @@ public function testEventLogWithFilters(): void public function testIosPreflight(): void { - $this->expectRequest('POST', '/v1/console/ios-preflight', 200, [ + $this->expectRequest('POST', '/v1/console/card-templates/tmpl_123/ios_preflight', 200, [ 'provisioningCredentialIdentifier' => 'prov_123', 'sharingInstanceIdentifier' => 'share_456', 'cardTemplateIdentifier' => 'tmpl_123', @@ -404,6 +404,60 @@ public function testListLedgerItemsEmpty(): void $this->assertCount(0, $result['ledger_items']); } + public function testLedgerItemsAlias(): void + { + $this->expectRequest('GET', '/v1/console/ledger-items', 200, [ + 'ledger_items' => [ + [ + 'created_at' => '2025-06-15T10:30:00Z', + 'amount' => 1.50, + 'id' => 'li_alias', + 'ex_id' => 'li_alias', + 'kind' => 'access_pass_issued', + 'metadata' => [], + 'access_pass' => null, + ], + ], + 'pagination' => [ + 'current_page' => 1, + 'per_page' => 50, + 'total_pages' => 1, + 'total_count' => 1, + ], + ]); + + $result = $this->client->console->ledgerItems(); + + $this->assertArrayHasKey('ledger_items', $result); + $this->assertCount(1, $result['ledger_items']); + $this->assertInstanceOf(LedgerItem::class, $result['ledger_items'][0]); + } + + public function testReadTemplateWithConvenienceFields(): void + { + $this->expectRequest('GET', '/v1/console/card-templates/tmpl_conv', 200, [ + 'id' => 'tmpl_conv', + 'name' => 'Convenience Test', + 'platform' => 'apple', + 'protocol' => 'desfire', + 'allowed_device_counts' => [ + 'allow_on_multiple_devices' => true, + 'watch' => 2, + 'iphone' => 3, + ], + 'metadata' => ['version' => '2.1'], + ]); + + $template = $this->client->console->readTemplate([ + 'card_template_id' => 'tmpl_conv', + ]); + + $this->assertTrue($template->allow_on_multiple_devices); + $this->assertEquals(2, $template->watch_count); + $this->assertEquals(3, $template->iphone_count); + $this->assertEquals(['version' => '2.1'], $template->metadata); + } + // --- Webhooks --- public function testListWebhooks(): void