create([ 'slug' => 'credits-tenant', 'event_credits_balance' => 0, ]); $user = User::factory()->create([ 'tenant_id' => $tenant->id, 'role' => 'tenant_admin', 'email' => 'tenant-admin@example.com', 'password' => Hash::make('password'), ]); $login = $this->postJson('/api/v1/tenant-auth/login', [ 'login' => $user->email, 'password' => 'password', ]); $login->assertOk(); $accessToken = $login->json('token'); $headers = [ 'Authorization' => 'Bearer '.$accessToken, ]; $balanceResponse = $this->withHeaders($headers) ->getJson('/api/v1/tenant/credits/balance'); $balanceResponse->assertOk() ->assertJsonStructure(['balance', 'free_event_granted_at']); $purchaseResponse = $this->withHeaders($headers) ->postJson('/api/v1/tenant/credits/purchase', [ 'package_id' => 'event_starter', 'credits_added' => 5, 'platform' => 'capacitor', 'transaction_id' => 'txn_test_123', 'subscription_active' => false, ]); $purchaseResponse->assertCreated() ->assertJsonStructure(['message', 'balance', 'subscription_active']); $tenant->refresh(); $this->assertSame(5, $tenant->event_credits_balance); $this->assertDatabaseHas('event_purchases', [ 'tenant_id' => $tenant->id, 'events_purchased' => 5, 'external_receipt_id' => 'txn_test_123', ]); $this->assertDatabaseHas('event_credits_ledger', [ 'tenant_id' => $tenant->id, 'delta' => 5, 'reason' => 'purchase', ]); $syncResponse = $this->withHeaders($headers) ->postJson('/api/v1/tenant/credits/sync', [ 'balance' => $tenant->event_credits_balance, 'subscription_active' => false, 'last_sync' => now()->toIso8601String(), ]); $syncResponse->assertOk() ->assertJsonStructure(['balance', 'subscription_active', 'server_time']); } }