admin = User::factory()->create([ 'name' => 'Admin Beheerder', 'email' => 'admin@jouwdriedee.nl', 'is_admin' => true, ]); $this->customer = User::factory()->create([ 'name' => 'Kees de Vries', 'email' => 'kees@example.com', 'is_admin' => false, ]); } public function test_contact_page_loads_successfully(): void { $response = $this->get(route('contact.index')); $response->assertStatus(200); $response->assertSee('Stel een vraag'); $response->assertSee('Directe Contactgegevens'); } public function test_customer_can_submit_question_and_both_emails_are_dispatched(): void { Mail::fake(); $response = $this->post(route('contact.store'), [ 'name' => 'Lisa Jansen', 'email' => 'lisa@example.com', 'phone' => '06-87654321', 'subject' => 'Vraag over levertijd van Pokémon model', 'message' => 'Goedemiddag, hoe lang duurt het printen van het Charizard model in PETG?', ]); $response->assertRedirect(route('contact.index')); $response->assertSessionHas('success'); // Check database $this->assertDatabaseHas('communications', [ 'name' => 'Lisa Jansen', 'email' => 'lisa@example.com', 'subject' => 'Vraag over levertijd van Pokémon model', 'status' => 'new', ]); $communication = Communication::where('email', 'lisa@example.com')->first(); $this->assertNotNull($communication); // 1. Mail to webshop management (info@jouwdrieedee.nl / info@jouwdriedee.nl) Mail::assertSent(ContactInquiryReceivedMail::class, function ($mail) use ($communication) { return $mail->communication->id === $communication->id; }); // 2. Afschrift to customer from (noreply@jouwdriedee.nl) Mail::assertSent(ContactInquiryConfirmationMail::class, function ($mail) use ($communication) { $hasCorrectRecipient = $mail->hasTo('lisa@example.com'); $hasCorrectFrom = $mail->hasFrom('noreply@jouwdriedee.nl'); return $hasCorrectRecipient && $hasCorrectFrom && $mail->communication->id === $communication->id; }); } public function test_logged_in_customer_inquiry_is_linked_and_visible_in_account(): void { Mail::fake(); $response = $this->actingAs($this->customer)->post(route('contact.store'), [ 'name' => $this->customer->name, 'email' => $this->customer->email, 'subject' => 'Speciale kleur vraag', 'message' => 'Kan het model ook in glow-in-the-dark filament worden geprint?', ]); $response->assertRedirect(route('contact.index')); $this->assertDatabaseHas('communications', [ 'user_id' => $this->customer->id, 'email' => 'kees@example.com', 'subject' => 'Speciale kleur vraag', ]); // Customer dashboard in /mijn-account shows their question $accountResponse = $this->actingAs($this->customer)->get(route('account.index')); $accountResponse->assertStatus(200); $accountResponse->assertSee('Speciale kleur vraag'); $accountResponse->assertSee('Mijn Vragen'); } public function test_admin_can_view_communications_in_dedicated_admin_section(): void { $comm = Communication::create([ 'name' => 'Peter Bakker', 'email' => 'peter@example.com', 'subject' => 'Garantie op 3D prints', 'message' => 'Wat voor garantie zit er op technische 3D prints?', 'status' => 'new', ]); // Admin list $indexResponse = $this->actingAs($this->admin)->get(route('admin.communications.index')); $indexResponse->assertStatus(200); $indexResponse->assertSee('Communicatie'); $indexResponse->assertSee('Garantie op 3D prints'); $indexResponse->assertSee('Peter Bakker'); // Admin detail $showResponse = $this->actingAs($this->admin)->get(route('admin.communications.show', $comm)); $showResponse->assertStatus(200); $showResponse->assertSee('Garantie op 3D prints'); $showResponse->assertSee('Wat voor garantie zit er op technische 3D prints?'); // Status is automatically transitioned from new to in_progress upon opening $this->assertEquals('in_progress', $comm->fresh()->status); } public function test_admin_can_reply_to_customer_from_admin_section(): void { Mail::fake(); $comm = Communication::create([ 'name' => 'Sophie Visser', 'email' => 'sophie@example.com', 'subject' => 'Custom formaat mogelijk?', 'message' => 'Kan de plantenbak ook 30cm hoog geprint worden?', 'status' => 'in_progress', ]); $replyResponse = $this->actingAs($this->admin)->post(route('admin.communications.reply', $comm), [ 'message' => 'Beste Sophie, ja zeker! We kunnen dit model opschalen naar 30cm. De levertijd is 3 dagen.', ]); $replyResponse->assertRedirect(); $replyResponse->assertSessionHas('success'); // Verify status and reply in database $this->assertEquals('resolved', $comm->fresh()->status); $this->assertNotNull($comm->fresh()->last_replied_at); $this->assertDatabaseHas('communication_replies', [ 'communication_id' => $comm->id, 'is_admin_reply' => true, ]); // Verify email was sent to customer from info@jouwdriedee.nl Mail::assertSent(ContactInquiryReplyMail::class, function ($mail) { return $mail->hasTo('sophie@example.com') && $mail->hasFrom('info@jouwdriedee.nl'); }); } public function test_admin_can_view_communication_inside_customer_profile(): void { // Link inquiry to customer $comm = Communication::create([ 'user_id' => $this->customer->id, 'name' => $this->customer->name, 'email' => $this->customer->email, 'subject' => 'Vraag binnen profiel', 'message' => 'Dit is een vraag die in het klantprofiel zichtbaar moet zijn.', 'status' => 'new', ]); // Also create an order for this customer Order::create([ 'user_id' => $this->customer->id, 'order_number' => 'ORD-TEST-999', 'customer_name' => $this->customer->name, 'customer_email' => $this->customer->email, 'shipping_street' => 'Dorpsstraat', 'shipping_number' => '1', 'shipping_postal_code' => '1234 AB', 'shipping_city' => 'Utrecht', 'subtotal' => 45.00, 'shipping_cost' => 0.00, 'total' => 45.00, 'status' => 'pending', 'payment_status' => 'paid', ]); // 1. Customers overview in admin $indexResponse = $this->actingAs($this->admin)->get(route('admin.customers.index')); $indexResponse->assertStatus(200); $indexResponse->assertSee($this->customer->name); $indexResponse->assertSee($this->customer->email); // 2. Customer profile in admin (by user ID) $profileResponse = $this->actingAs($this->admin)->get(route('admin.customers.show', $this->customer->id)); $profileResponse->assertStatus(200); $profileResponse->assertSee('Klantprofiel: '.$this->customer->name); $profileResponse->assertSee('Communicatie & Vragen', false); $profileResponse->assertSee('Vraag binnen profiel'); $profileResponse->assertSee('ORD-TEST-999'); // 3. Customer profile in admin by email $profileByEmail = $this->actingAs($this->admin)->get(route('admin.customers.show', $this->customer->email)); $profileByEmail->assertStatus(200); $profileByEmail->assertSee('Vraag binnen profiel'); } public function test_guest_and_non_admin_cannot_access_admin_communications_or_customers(): void { // Guests redirected to login $this->get(route('admin.communications.index'))->assertRedirect(route('login')); $this->get(route('admin.customers.index'))->assertRedirect(route('login')); // Normal customer is redirected to home with error flash $this->actingAs($this->customer)->get(route('admin.communications.index'))->assertRedirect(route('home')); $this->actingAs($this->customer)->get(route('admin.customers.index'))->assertRedirect(route('home')); } }