dir = sys_get_temp_dir().'/blax-webrtc-rec-'.bin2hex(random_bytes(4)); } protected function tearDown(): void { if (! is_dir($this->dir)) { return; } foreach (glob($this->dir.'/*/*') ?: [] as $file) { @unlink($file); } foreach (glob($this->dir.'/*') ?: [] as $sub) { @rmdir($sub); } @rmdir($this->dir); } public function test_appends_chunks_and_finalizes_the_full_audio(): void { $store = new FileRecordingStore($this->dir, 'webm'); $store->append('presence-lobby', 'peer1', 'CHUNK-A'); $store->append('presence-lobby', 'peer1', 'CHUNK-B'); $path = $store->finalize('presence-lobby', 'peer1'); $this->assertNotNull($path); $this->assertFileExists($path); $this->assertStringEndsWith('.webm', $path); $this->assertSame('CHUNK-ACHUNK-B', file_get_contents($path)); } public function test_finalize_without_any_data_returns_null(): void { $this->assertNull((new FileRecordingStore($this->dir))->finalize('r', 'p')); } public function test_room_and_peer_names_are_sanitized_into_a_contained_path(): void { $store = new FileRecordingStore($this->dir); $store->append('room/../x', 'peer id!', 'X'); $path = $store->finalize('room/../x', 'peer id!'); $this->assertNotNull($path); $this->assertStringStartsWith($this->dir, $path); // can't escape the recording dir $this->assertFileExists($path); } }