seed(RolesAndPermissionsSeeder::class); }); function contactMessagesAdmin(): User { $admin = User::factory()->create(['is_active' => true]); $admin->assignRole('admin'); return $admin; } test('the contact queue lists open contact messages', function () { $message = ContactMessage::factory() ->topic(ContactMessageTopic::BugReport) ->create([ 'name' => 'Bernd Bug', 'email' => 'bernd@example.test', ]); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->assertOk() ->assertSee('KT-'.$message->id) ->assertSee('Fehlermeldung') ->assertSee('Bernd Bug') ->assertSee('bernd@example.test'); }); test('resolved contact messages are hidden from the default open view', function () { ContactMessage::factory()->resolved()->create(['name' => 'Erledigte Person']); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->assertOk() ->assertDontSee('Erledigte Person'); }); test('the contact queue can be filtered by topic', function () { ContactMessage::factory()->topic(ContactMessageTopic::Feedback)->create(['name' => 'Frieda Feedback']); ContactMessage::factory()->topic(ContactMessageTopic::BugReport)->create(['name' => 'Bernd Bug']); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->set('topicFilter', 'feedback') ->assertSee('Frieda Feedback') ->assertDontSee('Bernd Bug'); }); test('an admin can resolve a contact message with a note', function () { $admin = contactMessagesAdmin(); $message = ContactMessage::factory()->create(); Livewire::actingAs($admin) ->test('admin.contact-messages.show', ['id' => $message->id]) ->set('adminNote', 'Per E-Mail beantwortet.') ->call('resolve') ->assertOk(); $message->refresh(); expect($message->status)->toBe(ContactMessageStatus::Resolved) ->and($message->admin_note)->toBe('Per E-Mail beantwortet.') ->and($message->resolved_by_user_id)->toBe($admin->id) ->and($message->resolved_at)->not->toBeNull(); }); test('an admin can reopen a resolved contact message', function () { $message = ContactMessage::factory()->resolved()->create(); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.show', ['id' => $message->id]) ->call('reopen') ->assertOk(); $message->refresh(); expect($message->status)->toBe(ContactMessageStatus::Open) ->and($message->resolved_at)->toBeNull(); }); test('customers cannot access the contact queue', function () { /** @var TestCase $this */ $customer = User::factory()->create(['is_active' => true, 'email_verified_at' => now()]); $customer->assignRole('customer'); $this->actingAs($customer) ->get('https://pressekonto.test/admin/contact-messages') ->assertForbidden(); }); test('quarantined spam is hidden from the default view and listed under the spam filter', function () { $open = ContactMessage::factory()->create(['name' => 'Echte Anfrage']); $spam = ContactMessage::factory()->create([ 'name' => 'HarryCoidS', 'status' => ContactMessageStatus::Spam, 'payload' => ['spam_reason' => 'link'], ]); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->assertSee($open->reference()) ->assertDontSee($spam->reference()) ->set('statusFilter', 'spam') ->assertSee($spam->reference()) ->assertSee('Link im Text') ->assertDontSee($open->reference()); }); test('an admin can move selected messages into the spam quarantine', function () { $first = ContactMessage::factory()->create(); $second = ContactMessage::factory()->create(); $kept = ContactMessage::factory()->create(); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->set('selected', [(string) $first->id, (string) $second->id]) ->call('markSelectedAsSpam') ->assertSet('selected', []) ->assertSee('2 Anliegen als Spam markiert.'); expect($first->refresh()->status)->toBe(ContactMessageStatus::Spam) ->and($first->payload['spam_reason'])->toBe('manual') ->and($second->refresh()->status)->toBe(ContactMessageStatus::Spam) ->and($kept->refresh()->status)->toBe(ContactMessageStatus::Open); }); test('releasing a filtered message reopens it and sends the held-back mail once', function () { Mail::fake(); config()->set('domains.domains.presseecho.brand.contact_email', 'redaktion@presseecho.de'); $message = ContactMessage::factory()->create([ 'portal' => 'presseecho', 'status' => ContactMessageStatus::Spam, 'payload' => ['spam_reason' => 'link'], 'page_url' => 'https://presseecho.test/de/faq', ]); $component = Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.show', ['id' => $message->id]) ->call('releaseFromSpam') ->assertSee('Mail an das Team wurde nachgeholt'); expect($message->refresh()->status)->toBe(ContactMessageStatus::Open); Mail::assertQueued( ContactRequestSubmitted::class, fn (ContactRequestSubmitted $mail) => $mail->hasTo('redaktion@presseecho.de') && $mail->host === 'presseecho.test', ); // Erneut als Spam markiert und wieder zurückgeholt: keine zweite Mail. $component->call('markAsSpam')->call('releaseFromSpam'); Mail::assertQueuedCount(1); }); test('releasing manually marked spam sends no mail — it already had one', function () { Mail::fake(); $message = ContactMessage::factory()->create(); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.show', ['id' => $message->id]) ->call('markAsSpam') ->call('releaseFromSpam'); expect($message->refresh()->status)->toBe(ContactMessageStatus::Open); Mail::assertNothingOutgoing(); }); test('messages accepted without bot check are flagged for review', function () { $message = ContactMessage::factory()->create(['payload' => ['bot_check' => 'unavailable', 'bot_check_reason' => 'siteverify_unreachable']]); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.index') ->assertSee('ohne Bot-Prüfung'); Livewire::actingAs(contactMessagesAdmin()) ->test('admin.contact-messages.show', ['id' => $message->id]) ->assertSee('Cloudflare nicht erreichbar'); }); test('customers cannot use the spam actions', function () { $message = ContactMessage::factory()->create(); $customer = User::factory()->create(['is_active' => true]); Livewire::actingAs($customer) ->test('admin.contact-messages.index') ->set('selected', [(string) $message->id]) ->call('markSelectedAsSpam') ->assertForbidden(); expect($message->refresh()->status)->toBe(ContactMessageStatus::Open); });