removed all references to credits. now credits are completely replaced by addons.

This commit is contained in:
Codex Agent
2025-12-01 15:50:17 +01:00
parent b8e515a03c
commit 28539754a7
76 changed files with 97 additions and 2533 deletions

View File

@@ -18,13 +18,7 @@ class PublicEventErrorResponseTest extends TestCase
'error' => ['code', 'title', 'message', 'meta'],
]);
$response->assertJson([
'error' => [
'code' => 'invalid_token',
'title' => 'Invalid Join Token',
'message' => 'The provided join token is invalid.',
],
]);
$response->assertJsonPath('error.code', 'invalid_token');
$this->assertSame('not-a-token', $response->json('error.meta.token'));
}

View File

@@ -4,7 +4,7 @@ namespace Tests\Feature\Api;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Cache;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
@@ -15,8 +15,24 @@ class HelpControllerTest extends TestCase
protected function setUp(): void
{
parent::setUp();
Storage::fake('local');
$this->artisan('help:sync');
Cache::put('help.guest.en', collect([
[
'slug' => 'getting-started',
'title' => 'Getting Started',
'summary' => 'Welcome guide',
'body_html' => '<p>When to read this</p>',
],
]), now()->addMinutes(30));
Cache::put('help.admin.en', collect([
[
'slug' => 'tenant-dashboard-overview',
'title' => 'Dashboard Overview',
'summary' => 'Overview for admins',
'body_html' => '<p>Admin guide</p>',
],
]), now()->addMinutes(30));
}
public function test_guest_help_listing_is_public(): void

View File

@@ -17,7 +17,6 @@ class TenantProfileApiTest extends TestCase
$tenant = Tenant::factory()->create([
'name' => 'Test Tenant GmbH',
'slug' => 'test-tenant',
'event_credits_balance' => 12,
'features' => ['custom_branding' => true],
]);
@@ -53,7 +52,6 @@ class TenantProfileApiTest extends TestCase
$me->assertJsonFragment([
'name' => 'Test Tenant GmbH',
'slug' => 'test-tenant',
'event_credits_balance' => 12,
]);
$data = $me->json();
@@ -69,7 +67,6 @@ class TenantProfileApiTest extends TestCase
'id' => $tenant->id,
'tenant_id' => $tenant->id,
'name' => 'Test Tenant GmbH',
'event_credits_balance' => 12,
'fullName' => 'Max Mustermann',
]);
$legacy->assertJsonStructure([
@@ -79,7 +76,6 @@ class TenantProfileApiTest extends TestCase
'slug',
'email',
'fullName',
'event_credits_balance',
'active_reseller_package_id',
'remaining_events',
'package_expires_at',

View File

@@ -5,7 +5,6 @@ namespace Tests\Feature\Console;
use App\Console\Commands\CheckEventPackages;
use App\Events\Packages\EventPackageGalleryExpired;
use App\Events\Packages\EventPackageGalleryExpiring;
use App\Events\Packages\TenantCreditsLow;
use App\Events\Packages\TenantPackageExpired;
use App\Events\Packages\TenantPackageExpiring;
use App\Models\Event;
@@ -144,73 +143,4 @@ class CheckEventPackagesCommandTest extends TestCase
}
}
public function test_dispatches_credit_warning_and_sets_threshold(): void
{
EventFacade::fake();
Config::set('package-limits.credit_thresholds', [5, 1]);
$tenant = Tenant::factory()->create([
'event_credits_balance' => 5,
'credit_warning_sent_at' => null,
'credit_warning_threshold' => null,
]);
Artisan::call(CheckEventPackages::class);
EventFacade::assertDispatched(TenantCreditsLow::class, function ($event) use ($tenant) {
return $event->tenant->is($tenant) && $event->threshold === 5 && $event->balance === 5;
});
$tenant->refresh();
$this->assertNotNull($tenant->credit_warning_sent_at);
$this->assertSame(5, $tenant->credit_warning_threshold);
}
public function test_resets_credit_warning_when_balance_recovers(): void
{
EventFacade::fake();
Config::set('package-limits.credit_thresholds', [5, 1]);
$tenant = Tenant::factory()->create([
'event_credits_balance' => 10,
'credit_warning_sent_at' => now()->subDay(),
'credit_warning_threshold' => 1,
]);
Artisan::call(CheckEventPackages::class);
EventFacade::assertNotDispatched(TenantCreditsLow::class);
$tenant->refresh();
$this->assertNull($tenant->credit_warning_sent_at);
$this->assertNull($tenant->credit_warning_threshold);
}
public function test_dispatches_lower_credit_threshold_after_higher_warning(): void
{
EventFacade::fake();
Config::set('package-limits.credit_thresholds', [5, 1]);
$tenant = Tenant::factory()->create([
'event_credits_balance' => 1,
'credit_warning_sent_at' => now()->subDay(),
'credit_warning_threshold' => 5,
]);
Artisan::call(CheckEventPackages::class);
EventFacade::assertDispatched(TenantCreditsLow::class, function ($event) use ($tenant) {
return $event->tenant->is($tenant) && $event->threshold === 1;
});
$tenant->refresh();
$this->assertSame(1, $tenant->credit_warning_threshold);
$this->assertNotNull($tenant->credit_warning_sent_at);
}
}

View File

@@ -20,9 +20,7 @@ class DashboardPageTest extends TestCase
public function test_unverified_user_can_access_dashboard_with_summary_data(): void
{
$tenant = Tenant::factory()->create([
'event_credits_balance' => 4,
]);
$tenant = Tenant::factory()->create();
$package = Package::factory()->reseller()->create([
'name_translations' => [

View File

@@ -1,40 +0,0 @@
<?php
namespace Tests\Feature\Packages;
use App\Jobs\Packages\SendTenantCreditsLowNotification;
use App\Models\Tenant;
use App\Notifications\Packages\TenantCreditsLowNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
class SendTenantCreditsLowNotificationTest extends TestCase
{
use RefreshDatabase;
public function test_logs_successful_notification(): void
{
Notification::fake();
$tenant = Tenant::factory()->create([
'contact_email' => 'admin@example.com',
]);
$job = new SendTenantCreditsLowNotification($tenant->id, balance: 5, threshold: 10);
$job->handle();
Notification::assertSentOnDemand(TenantCreditsLowNotification::class, function ($notification, $channels, $notifiable) {
return in_array('mail', $channels, true) && ($notifiable->routes['mail'] ?? null) === 'admin@example.com';
});
$tenant->refresh();
$this->assertCount(1, $tenant->notificationLogs);
$log = $tenant->notificationLogs()->first();
$this->assertSame('credits_low', $log->type);
$this->assertSame('sent', $log->status);
$this->assertSame('admin@example.com', $log->recipient);
$this->assertNotNull($log->sent_at);
}
}

View File

@@ -18,7 +18,6 @@ class ProfilePageTest extends TestCase
public function test_profile_page_displays_user_and_package_information(): void
{
$tenant = Tenant::factory()->create([
'event_credits_balance' => 7,
'subscription_status' => 'active',
'subscription_expires_at' => now()->addMonths(3),
]);

View File

@@ -23,9 +23,7 @@ class DashboardSummaryTest extends TestCase
{
app()->setLocale('de');
$tenant = Tenant::factory()->create([
'event_credits_balance' => 5,
]);
$tenant = Tenant::factory()->create();
$eventType = EventType::factory()->create();
@@ -106,10 +104,5 @@ class DashboardSummaryTest extends TestCase
$activePackage->expires_at->toIso8601String(),
Arr::get($payload, 'active_package.expires_at')
);
$this->assertSame(
$tenant->event_credits_balance,
Arr::get($payload, 'credit_balance')
);
}
}

View File

@@ -1,59 +0,0 @@
<?php
namespace Tests\Feature\Tenant;
use App\Models\EventType;
use App\Models\Package;
use Illuminate\Support\Carbon;
class EventCreditsTest extends TenantTestCase
{
public function test_event_creation_requires_credits(): void
{
$this->tenant->update(['event_credits_balance' => 0]);
$eventType = EventType::factory()->create();
$package = Package::factory()->create([
'type' => 'endcustomer',
'price' => 0,
'gallery_days' => 30,
]);
$this->tenant->tenantPackages()->create([
'package_id' => $package->id,
'price' => $package->price,
'purchased_at' => now()->subDay(),
'expires_at' => now()->addMonth(),
'active' => true,
]);
$payload = [
'name' => 'Sample Event',
'description' => 'Test description',
'event_date' => Carbon::now()->addDays(3)->toDateString(),
'event_type_id' => $eventType->id,
];
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/events', $payload);
$response->assertStatus(402)
->assertJsonPath('error.code', 'event_credits_exhausted')
->assertJsonPath('error.meta.balance', 0);
$this->tenant->update(['event_credits_balance' => 2]);
$createResponse = $this->authenticatedRequest('POST', '/api/v1/tenant/events', $payload);
$createResponse->assertStatus(201)
->assertJsonPath('message', 'Event created successfully')
->assertJsonPath('data.package.id', $package->id);
$createdEventId = $createResponse->json('data.id');
$this->assertNotNull($createdEventId);
$this->assertDatabaseHas('event_packages', [
'event_id' => $createdEventId,
'package_id' => $package->id,
]);
}
}

View File

@@ -58,10 +58,6 @@ class EventManagementTest extends TenantTestCase
'active' => true,
]);
$this->tenant->update([
'event_credits_balance' => 1,
]);
$payload = [
'name' => 'Launch Event',
'slug' => 'launch-event',

View File

@@ -37,7 +37,6 @@ class NotificationPreferencesTest extends TestCase
'defaults',
'preferences',
'overrides',
'meta' => ['credit_warning_sent_at', 'credit_warning_threshold'],
],
]);
}

View File

@@ -1,86 +0,0 @@
<?php
namespace Tests\Feature;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
class TenantCreditsTest extends TestCase
{
use RefreshDatabase;
public function test_tenant_can_retrieve_balance_and_purchase_credits(): void
{
$tenant = Tenant::factory()->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']);
}
}