neues Admin UI Layout eingeführt. Alle Tests auf den neusten Stand gebracht.

This commit is contained in:
Codex Agent
2025-12-30 10:24:06 +01:00
parent 902e78cae9
commit efe2f25b3e
85 changed files with 95235 additions and 19197 deletions

View File

@@ -0,0 +1,23 @@
<?php
namespace Tests\Feature\Admin;
use Tests\TestCase;
class TamaguiThemeTest extends TestCase
{
public function test_admin_theme_tokens_reference_new_fonts_and_palette(): void
{
$config = file_get_contents(base_path('tamagui.config.ts'));
$styles = file_get_contents(base_path('resources/css/app.css'));
$this->assertIsString($config);
$this->assertIsString($styles);
$this->assertStringContainsString("family: 'Manrope'", $config);
$this->assertStringContainsString("family: 'Fraunces'", $config);
$this->assertStringContainsString("primary: '#FF5A5F'", $config);
$this->assertStringContainsString("background: '#FFF8F5'", $config);
$this->assertStringContainsString("background: '#171219'", $config);
$this->assertStringContainsString('.admin-fade-up', $styles);
}
}

View File

@@ -44,6 +44,7 @@ class EventAchievementsLocaleTest extends TestCase
'emotion_id' => $emotion->id,
'likes_count' => 42,
'guest_name' => 'LocaleTester',
'status' => 'approved',
]);
$responseEn = $this->withHeaders(['X-Device-Id' => 'LocaleTester'])

View File

@@ -75,7 +75,7 @@ class EventBrandingResponseTest extends TestCase
$response->assertJsonPath('branding.typography.heading', 'Playfair Display');
$response->assertJsonPath('branding.typography.size', 'l');
$response->assertJsonPath('branding.logo.mode', 'upload');
$this->assertStringContainsString('/storage/', (string) $response->json('branding.logo.value'));
$this->assertStringContainsString('/api/v1/branding/asset/', (string) $response->json('branding.logo.value'));
$response->assertJsonPath('branding.logo.position', 'center');
$response->assertJsonPath('branding.buttons.style', 'outline');
$response->assertJsonPath('branding.buttons.radius', 18);

View File

@@ -43,6 +43,7 @@ class EventPhotosLocaleTest extends TestCase
'task_id' => $task->id,
'emotion_id' => $emotion->id,
'created_at' => now(),
'status' => 'approved',
]);
$responseEn = $this->withHeaders(['X-Device-Id' => 'device-123'])

View File

@@ -48,17 +48,14 @@ class EventTasksLocaleTest extends TestCase
$response->assertOk();
$response->assertHeader('X-Content-Locale', 'en');
$response->assertJsonCount(1);
$response->assertJson([[
'id' => $task->id,
'title' => 'Kiss Moment',
'description' => 'EN Description',
'instructions' => 'EN Instructions',
'duration' => 3,
'is_completed' => false,
]]);
$this->assertSame('emotion-'.$emotion->id, $response->json('0.emotion.slug'));
$response->assertJsonCount(1, 'data');
$response->assertJsonPath('data.0.id', $task->id);
$response->assertJsonPath('data.0.title', 'Kiss Moment');
$response->assertJsonPath('data.0.description', 'EN Description');
$response->assertJsonPath('data.0.instructions', 'EN Instructions');
$response->assertJsonPath('data.0.duration', 3);
$response->assertJsonPath('data.0.is_completed', false);
$response->assertJsonPath('data.0.emotion.slug', 'emotion-'.$emotion->id);
}
public function test_it_falls_back_to_event_locale_when_locale_invalid(): void
@@ -91,8 +88,6 @@ class EventTasksLocaleTest extends TestCase
$response->assertOk();
$response->assertHeader('X-Content-Locale', 'de');
$response->assertJson([[
'title' => 'Aufgabe',
]]);
$response->assertJsonPath('data.0.title', 'Aufgabe');
}
}

View File

@@ -120,7 +120,7 @@ class LoginTest extends TestCase
'email_verified_at' => now(),
]);
$intended = 'http://localhost/event-admin/dashboard?from=intended-test';
$intended = url('/event-admin/dashboard?from=intended-test');
$returnTarget = '/event-admin/dashboard';
$encodedReturn = rtrim(strtr(base64_encode($returnTarget), '+/', '-_'), '=');

View File

@@ -3,7 +3,7 @@
namespace Tests\Feature\Auth;
use App\Models\User;
use Illuminate\Auth\Notifications\ResetPassword;
use App\Notifications\ResetPasswordNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
@@ -27,7 +27,7 @@ class PasswordResetTest extends TestCase
$this->post(route('password.email'), ['email' => $user->email]);
Notification::assertSentTo($user, ResetPassword::class);
Notification::assertSentTo($user, ResetPasswordNotification::class);
}
public function test_reset_password_screen_can_be_rendered()
@@ -38,7 +38,7 @@ class PasswordResetTest extends TestCase
$this->post(route('password.email'), ['email' => $user->email]);
Notification::assertSentTo($user, ResetPassword::class, function ($notification) {
Notification::assertSentTo($user, ResetPasswordNotification::class, function ($notification) {
$response = $this->get(route('password.reset', $notification->token));
$response->assertStatus(200);
@@ -55,7 +55,7 @@ class PasswordResetTest extends TestCase
$this->post(route('password.email'), ['email' => $user->email]);
Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) {
Notification::assertSentTo($user, ResetPasswordNotification::class, function ($notification) use ($user) {
$response = $this->post(route('password.store'), [
'token' => $notification->token,
'email' => $user->email,

View File

@@ -30,7 +30,7 @@ class TenantAdminGoogleControllerTest extends TestCase
$driver->shouldReceive('with')->once()->with(['prompt' => 'select_account'])->andReturnSelf();
$driver->shouldReceive('redirect')->once()->andReturn(new RedirectResponse('https://accounts.google.com'));
$encodedReturn = rtrim(strtr(base64_encode('http://localhost/test'), '+/', '-_'), '=');
$encodedReturn = rtrim(strtr(base64_encode(url('/test')), '+/', '-_'), '=');
$response = $this->get('/event-admin/auth/google?return_to='.$encodedReturn);
@@ -56,7 +56,7 @@ class TenantAdminGoogleControllerTest extends TestCase
Socialite::shouldReceive('driver')->once()->with('google')->andReturn($driver);
$driver->shouldReceive('user')->once()->andReturn($socialiteUser);
$targetUrl = 'http://localhost:8000/event-admin/dashboard?foo=bar';
$targetUrl = url('/event-admin/dashboard?foo=bar');
$encodedReturn = rtrim(strtr(base64_encode($targetUrl), '+/', '-_'), '=');
$this->withSession([

View File

@@ -3,7 +3,7 @@
namespace Tests\Feature\Auth;
use App\Models\User;
use Illuminate\Auth\Notifications\VerifyEmail;
use App\Notifications\VerifyEmailNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
@@ -24,7 +24,7 @@ class VerificationNotificationTest extends TestCase
->post(route('verification.send'))
->assertRedirect('/');
Notification::assertSentTo($user, VerifyEmail::class);
Notification::assertSentTo($user, VerifyEmailNotification::class);
}
public function test_does_not_send_verification_notification_if_email_is_verified(): void

View File

@@ -189,4 +189,120 @@ class SyncGoogleFontsTest extends TestCase
File::deleteDirectory($targetPath);
}
public function test_it_downloads_multiple_families_in_one_run(): void
{
$targetPath = storage_path('app/test-fonts');
File::deleteDirectory($targetPath);
Http::fake([
'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([
'items' => [
[
'family' => 'Alpha Sans',
'category' => 'sans-serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2',
],
],
[
'family' => 'Beta Serif',
'category' => 'serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2',
],
],
],
]),
'https://fonts.gstatic.com/*' => Http::response('font-binary', 200),
]);
Artisan::call('fonts:sync-google', [
'--family' => 'Alpha Sans, Beta Serif',
'--path' => 'storage/app/test-fonts',
'--force' => true,
]);
$manifestPath = $targetPath.'/manifest.json';
$manifest = json_decode(File::get($manifestPath), true);
$this->assertSame(2, $manifest['count']);
$this->assertCount(2, $manifest['fonts']);
$this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Alpha Sans'));
$this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Beta Serif'));
File::deleteDirectory($targetPath);
}
public function test_it_merges_existing_manifest_when_syncing_single_family(): void
{
$targetPath = storage_path('app/test-fonts');
File::deleteDirectory($targetPath);
Http::fake([
'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([
'items' => [
[
'family' => 'Alpha Sans',
'category' => 'sans-serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2',
],
],
[
'family' => 'Beta Serif',
'category' => 'serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2',
],
],
],
]),
'https://fonts.gstatic.com/*' => Http::response('font-binary', 200),
]);
Artisan::call('fonts:sync-google', [
'--count' => 2,
'--path' => 'storage/app/test-fonts',
'--force' => true,
]);
Http::fake([
'https://www.googleapis.com/webfonts/v1/webfonts*' => Http::response([
'items' => [
[
'family' => 'Alpha Sans',
'category' => 'sans-serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/alpha-regular.woff2',
],
],
[
'family' => 'Beta Serif',
'category' => 'serif',
'files' => [
'regular' => 'https://fonts.gstatic.com/s/beta-regular.woff2',
],
],
],
]),
'https://fonts.gstatic.com/*' => Http::response('font-binary', 200),
]);
Artisan::call('fonts:sync-google', [
'--family' => 'Alpha Sans',
'--path' => 'storage/app/test-fonts',
'--force' => true,
]);
$manifestPath = $targetPath.'/manifest.json';
$manifest = json_decode(File::get($manifestPath), true);
$this->assertSame(2, $manifest['count']);
$this->assertCount(2, $manifest['fonts']);
$this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Alpha Sans'));
$this->assertTrue(collect($manifest['fonts'])->pluck('family')->contains('Beta Serif'));
File::deleteDirectory($targetPath);
}
}

View File

@@ -28,6 +28,8 @@ class SendPhotoUploadedNotificationTest extends TestCase
public function test_milestone_creates_achievement_notification(): void
{
config(['notifications.guest_achievements.milestones' => [5]]);
$event = Event::factory()->create(['status' => 'published']);
Photo::factory()->count(4)->for($event)->create(['guest_name' => 'Mia']);
$photo = Photo::factory()->for($event)->create(['guest_name' => 'Mia']);

View File

@@ -2,10 +2,14 @@
namespace Tests\Feature;
use App\Models\LegalPage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class MarketingLocaleRoutingTest extends TestCase
{
use RefreshDatabase;
public function test_contact_page_is_accessible_in_german(): void
{
$response = $this->get('/de/kontakt');
@@ -66,6 +70,24 @@ class MarketingLocaleRoutingTest extends TestCase
public function test_legal_pages_render_for_german_locale(): void
{
foreach (['impressum', 'datenschutz', 'agb'] as $slug) {
LegalPage::updateOrCreate(
['slug' => $slug, 'version' => 1],
[
'title' => [
'de' => ucfirst($slug),
'en' => ucfirst($slug),
],
'body_markdown' => [
'de' => '# '.$slug,
'en' => '# '.$slug,
],
'locale_fallback' => 'de',
'is_published' => true,
]
);
}
$this->get('/de/impressum')->assertStatus(200);
$this->get('/de/datenschutz')->assertStatus(200);
$this->get('/de/agb')->assertStatus(200);

View File

@@ -27,6 +27,7 @@ class PurchaseTest extends TestCase
$response = $this->postJson('/paddle/create-checkout', [
'package_id' => $package->id,
'accepted_terms' => true,
]);
$response->assertStatus(422)
@@ -58,6 +59,7 @@ class PurchaseTest extends TestCase
$response = $this->postJson('/paddle/create-checkout', [
'package_id' => $package->id,
'accepted_terms' => true,
]);
$response->assertOk()
@@ -78,6 +80,7 @@ class PurchaseTest extends TestCase
$response = $this->postJson('/paddle/create-checkout', [
'package_id' => $package->id,
'inline' => true,
'accepted_terms' => true,
]);
$response->assertOk()

View File

@@ -50,7 +50,8 @@ class RevenueCatWebhookTest extends TestCase
]);
$response->assertStatus(400)
->assertJson(['error' => 'Invalid signature']);
->assertJsonPath('error.code', 'signature_invalid')
->assertJsonPath('error.title', 'Invalid Signature');
Bus::assertNotDispatched(ProcessRevenueCatWebhook::class);
}

View File

@@ -16,7 +16,7 @@ class ProfileUpdateTest extends TestCase
$response = $this
->actingAs($user)
->get(route('profile.edit'));
->get(route('settings.profile.edit'));
$response->assertOk();
}
@@ -27,14 +27,14 @@ class ProfileUpdateTest extends TestCase
$response = $this
->actingAs($user)
->patch(route('profile.update'), [
->patch(route('settings.profile.update'), [
'name' => 'Test User',
'email' => 'test@example.com',
]);
$response
->assertSessionHasNoErrors()
->assertRedirect(route('profile.edit'));
->assertRedirect(route('settings.profile.edit'));
$user->refresh();
@@ -49,14 +49,14 @@ class ProfileUpdateTest extends TestCase
$response = $this
->actingAs($user)
->patch(route('profile.update'), [
->patch(route('settings.profile.update'), [
'name' => 'Test User',
'email' => $user->email,
]);
$response
->assertSessionHasNoErrors()
->assertRedirect(route('profile.edit'));
->assertRedirect(route('settings.profile.edit'));
$this->assertNotNull($user->refresh()->email_verified_at);
}
@@ -67,7 +67,7 @@ class ProfileUpdateTest extends TestCase
$response = $this
->actingAs($user)
->delete(route('profile.destroy'), [
->delete(route('settings.profile.destroy'), [
'password' => 'password',
]);
@@ -85,14 +85,14 @@ class ProfileUpdateTest extends TestCase
$response = $this
->actingAs($user)
->from(route('profile.edit'))
->delete(route('profile.destroy'), [
->from(route('settings.profile.edit'))
->delete(route('settings.profile.destroy'), [
'password' => 'wrong-password',
]);
$response
->assertSessionHasErrors('password')
->assertRedirect(route('profile.edit'));
->assertRedirect(route('settings.profile.edit'));
$this->assertNotNull($user->fresh());
}

View File

@@ -91,7 +91,6 @@ class DashboardSummaryTest extends TestCase
$this->assertSame(1, Arr::get($payload, 'active_events'));
$this->assertSame(1, Arr::get($payload, 'new_photos'));
$this->assertSame(50, Arr::get($payload, 'task_progress'));
$this->assertSame(5, Arr::get($payload, 'credit_balance'));
$this->assertSame(2, Arr::get($payload, 'upcoming_events'));
$activePackagePayload = Arr::get($payload, 'active_package');

View File

@@ -3,6 +3,7 @@
namespace Tests\Feature\Tenant;
use App\Models\User;
use App\Notifications\VerifyEmailNotification;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
@@ -48,7 +49,7 @@ class ProfileApiTest extends TenantTestCase
'preferred_locale' => 'en',
]);
Notification::assertSentToTimes($this->tenantUser->fresh(), \Illuminate\Auth\Notifications\VerifyEmail::class, 1);
Notification::assertSentToTimes($this->tenantUser->fresh(), VerifyEmailNotification::class, 1);
}
public function test_profile_update_requires_current_password_for_password_change(): void