removed all references to credits. now credits are completely replaced by addons.
This commit is contained in:
@@ -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'));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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' => [
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
]);
|
||||
|
||||
@@ -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')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,6 @@ class EventManagementTest extends TenantTestCase
|
||||
'active' => true,
|
||||
]);
|
||||
|
||||
$this->tenant->update([
|
||||
'event_credits_balance' => 1,
|
||||
]);
|
||||
|
||||
$payload = [
|
||||
'name' => 'Launch Event',
|
||||
'slug' => 'launch-event',
|
||||
|
||||
@@ -37,7 +37,6 @@ class NotificationPreferencesTest extends TestCase
|
||||
'defaults',
|
||||
'preferences',
|
||||
'overrides',
|
||||
'meta' => ['credit_warning_sent_at', 'credit_warning_threshold'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user