package main import ( "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" ) func TestMediaHealthAndSessionLifecycle(t *testing.T) { store, err := newSessionStore(t.TempDir()) if err != nil { t.Fatalf("newSessionStore: %v", err) } server := newMediaServer(store) healthReq := httptest.NewRequest(http.MethodGet, "/media/health", nil) healthRes := httptest.NewRecorder() server.routes().ServeHTTP(healthRes, healthReq) if healthRes.Code != http.StatusOK { t.Fatalf("expected health 200, got %d", healthRes.Code) } session, err := store.createSession(CreateSessionRequest{ UserID: "1", Title: "Test Session", Format: "webm", MimeType: "video/webm", QualityPreset: "balanced", FacingMode: "environment", DeviceKind: "desktop", }) if err != nil { t.Fatalf("createSession: %v", err) } if _, err := store.updateSession(session.ID, func(current *Session) error { current.Segments = append(current.Segments, SegmentMeta{ Sequence: 0, Filename: "000000.webm", DurationMS: 60000, SizeBytes: 7, ContentType: "video/webm", }) current.Markers = append(current.Markers, Marker{ ID: "marker-1", Type: "manual", Label: "关键片段", Timestamp: 5000, CreatedAt: "2026-03-14T00:00:00Z", }) return nil }); err != nil { t.Fatalf("updateSession: %v", err) } if err := os.WriteFile(filepath.Join(store.segmentsDir(session.ID), "000000.webm"), []byte("segment"), 0o644); err != nil { t.Fatalf("write segment: %v", err) } current, err := store.getSession(session.ID) if err != nil { t.Fatalf("getSession: %v", err) } if current.UploadedSegments != 1 { t.Fatalf("expected uploaded segment count to be recomputed") } if current.UploadedBytes != 7 { t.Fatalf("expected uploaded bytes to be recomputed, got %d", current.UploadedBytes) } } func TestProcessSessionArchivesPlayback(t *testing.T) { tempDir := t.TempDir() store, err := newSessionStore(tempDir) if err != nil { t.Fatalf("newSessionStore: %v", err) } session, err := store.createSession(CreateSessionRequest{UserID: "1", Title: "Archive Session"}) if err != nil { t.Fatalf("createSession: %v", err) } if err := os.WriteFile(filepath.Join(store.segmentsDir(session.ID), "000000.webm"), []byte("segment"), 0o644); err != nil { t.Fatalf("write segment: %v", err) } if _, err := store.updateSession(session.ID, func(current *Session) error { current.Segments = append(current.Segments, SegmentMeta{ Sequence: 0, Filename: "000000.webm", DurationMS: 60000, SizeBytes: 7, ContentType: "video/webm", }) current.ArchiveStatus = ArchiveQueued return nil }); err != nil { t.Fatalf("updateSession: %v", err) } fakeFFmpeg := filepath.Join(tempDir, "ffmpeg") script := "#!/bin/sh\ninput=''\noutput=''\nprev=''\nfor arg in \"$@\"; do\n if [ \"$prev\" = '-i' ]; then input=\"$arg\"; fi\n prev=\"$arg\"\n output=\"$arg\"\ndone\nif [ -n \"$input\" ] && [ -f \"$input\" ]; then cp \"$input\" \"$output\"; else : > \"$output\"; fi\n" if err := os.WriteFile(fakeFFmpeg, []byte(script), 0o755); err != nil { t.Fatalf("write fake ffmpeg: %v", err) } originalPath := os.Getenv("PATH") t.Setenv("PATH", tempDir+string(os.PathListSeparator)+originalPath) if err := processSession(store, session.ID); err != nil { t.Fatalf("processSession: %v", err) } archived, err := store.getSession(session.ID) if err != nil { t.Fatalf("getSession: %v", err) } if archived.ArchiveStatus != ArchiveCompleted { t.Fatalf("expected archive completed, got %s", archived.ArchiveStatus) } if archived.Playback.WebMURL == "" || !strings.HasSuffix(archived.Playback.WebMURL, ".webm") { t.Fatalf("expected webm playback url, got %#v", archived.Playback) } }