- integrate spatie/icalendar-generator for candidate & panelist .ics invitations (RSVP & 15m alerts)
- add StoreInterviewRequest, ScheduleInterviewDto, and invitation/reminder queued actions
- add migration for job_title, round, description, and reminder_sent_at on interviews table
- style datetime-local picker indicators to pure white on dark input backgrounds
- support button loading spinners with :showLoader="true" and loadingText
- auto-open schedule drawer on validation failure with inline @error alerts and old() bindings
70 lines
2.3 KiB
PHP
70 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Interview;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\File;
|
|
use Tests\TestCase;
|
|
|
|
class RecordingStreamTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_media_stream_serves_recorded_video_with_range_and_headers()
|
|
{
|
|
$dir = storage_path('app/public/recordings');
|
|
if (! File::exists($dir)) {
|
|
File::makeDirectory($dir, 0755, true);
|
|
}
|
|
|
|
$testFile = $dir.'/test_stream_video.webm';
|
|
$fakeVideoContent = "\x1A\x45\xDF\xA3".str_repeat('0', 100);
|
|
File::put($testFile, $fakeVideoContent);
|
|
|
|
try {
|
|
$response = $this->get('/media-stream/recordings/test_stream_video.webm');
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertHeader('Content-Type', 'video/webm');
|
|
$response->assertHeader('Accept-Ranges', 'bytes');
|
|
} finally {
|
|
if (File::exists($testFile)) {
|
|
File::delete($testFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function test_poll_returns_media_stream_urls()
|
|
{
|
|
$user = User::factory()->create();
|
|
|
|
$interview = Interview::create([
|
|
'candidate_name' => 'John Streamer',
|
|
'candidate_email' => 'stream@example.com',
|
|
'candidate_phone' => '1234567890',
|
|
'submission_unique_id' => 'stream_test_123',
|
|
'temp_password' => 'secret123',
|
|
'language' => 'python',
|
|
'status' => 'pending',
|
|
'expires_at' => now()->addDays(7),
|
|
'recording_path' => '/storage/recordings/stream_test_123.webm',
|
|
'recordings' => [
|
|
[
|
|
'url' => '/storage/recordings/stream_test_123.webm',
|
|
'filename' => 'stream_test_123.webm',
|
|
'created_at' => now()->toIso8601String(),
|
|
],
|
|
],
|
|
]);
|
|
|
|
$response = $this->actingAs($user)->get(route('interview.poll', $interview->id));
|
|
|
|
$response->assertStatus(200);
|
|
$data = $response->json();
|
|
$this->assertNotEmpty($data['recordings']);
|
|
$this->assertStringContainsString('/media-stream/recordings/stream_test_123.webm', $data['recordings'][0]['stream_url']);
|
|
}
|
|
}
|