token = 'employer-test-token-12345'; $this->employer = User::create([ 'name' => 'John Employer', 'email' => 'employer_test@example.com', 'password' => bcrypt('password'), 'role' => 'employer', 'api_token' => $this->token, ]); } public function test_employer_can_create_ticket_with_reason_and_voice_note() { Storage::fake('public'); $reason = \App\Models\ReportReason::create([ 'reason' => 'Billing Inquiry', 'status' => 'active', 'type' => 'support', ]); $voiceFile = UploadedFile::fake()->create('note.mp3', 500, 'audio/mpeg'); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/tickets', [ 'subject' => 'Billing query', 'description' => 'Need help with invoice.', 'priority' => 'high', 'reason_id' => $reason->id, 'voice_note' => $voiceFile, ]); $response->assertStatus(201) ->assertJsonStructure([ 'success', 'message', 'ticket' => [ 'id', 'ticket_number', 'subject', 'description', 'reason_id', 'reason_name', 'voice_note_url', 'status', 'priority', 'created_at', ] ]); $ticket = SupportTicket::first(); $this->assertNotNull($ticket); $this->assertEquals('Billing query', $ticket->subject); $this->assertEquals($reason->id, $ticket->reason_id); $this->assertNotNull($ticket->voice_note_path); Storage::disk('public')->assertExists($ticket->voice_note_path); } public function test_employer_can_reply_to_ticket_with_voice_note() { Storage::fake('public'); // Create a ticket $ticket = SupportTicket::create([ 'ticket_number' => 'TKT-654321', 'user_id' => $this->employer->id, 'subject' => 'Billing issue', 'description' => 'I was double charged.', 'status' => 'open', 'priority' => 'high', ]); $voiceFile = UploadedFile::fake()->create('reply_note.mp3', 400, 'audio/mpeg'); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson("/api/employers/tickets/{$ticket->id}/reply", [ 'voice_note' => $voiceFile, ]); $response->assertStatus(201) ->assertJsonStructure([ 'success', 'message', 'reply' => [ 'id', 'message', 'sender_name', 'voice_note_url', 'created_at', ] ]); $reply = SupportTicketReply::first(); $this->assertNotNull($reply); $this->assertNull($reply->message); $this->assertNotNull($reply->voice_note_path); Storage::disk('public')->assertExists($reply->voice_note_path); // Test details endpoint returns the voice note url for the reply $detailResponse = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson("/api/employers/tickets/{$ticket->id}"); $detailResponse->assertStatus(200) ->assertJsonFragment([ 'voice_note_url' => asset('storage/' . $reply->voice_note_path) ]); } public function test_employer_web_can_create_ticket_with_voice_note() { Storage::fake('public'); $reason = \App\Models\ReportReason::create([ 'reason' => 'Technical Error', 'status' => 'active', 'type' => 'support', ]); $voiceFile = UploadedFile::fake()->create('web_note.mp3', 300, 'audio/mpeg'); $response = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->post('/employer/support/create', [ 'subject' => 'Web ticket subject', 'description' => 'Web ticket description.', 'priority' => 'low', 'reason_id' => $reason->id, 'voice_note' => $voiceFile, ]); $ticket = SupportTicket::first(); $this->assertNotNull($ticket); $this->assertEquals('Web ticket subject', $ticket->subject); $this->assertEquals($reason->id, $ticket->reason_id); $this->assertNotNull($ticket->voice_note_path); Storage::disk('public')->assertExists($ticket->voice_note_path); $response->assertRedirect(route('employer.support.show', $ticket->id)); } public function test_employer_web_can_reply_to_ticket_with_voice_note() { Storage::fake('public'); $ticket = SupportTicket::create([ 'ticket_number' => 'TKT-999999', 'user_id' => $this->employer->id, 'subject' => 'Web ticket reply test', 'description' => 'Initial message.', 'status' => 'open', 'priority' => 'medium', ]); $voiceFile = UploadedFile::fake()->create('web_reply_note.mp3', 200, 'audio/mpeg'); $response = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->post("/employer/support/{$ticket->id}/reply", [ 'voice_note' => $voiceFile, ]); $reply = SupportTicketReply::first(); $this->assertNotNull($reply); $this->assertNull($reply->message); $this->assertNotNull($reply->voice_note_path); Storage::disk('public')->assertExists($reply->voice_note_path); $response->assertRedirect(route('employer.support.show', $ticket->id)); } }