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_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) ]); } }