Files
91/backend/internal/preview/ffmpeg_test.go
T
2026-05-11 19:44:06 +08:00

114 lines
3.4 KiB
Go

package preview
import (
"errors"
"math"
"strings"
"testing"
"github.com/video-site/backend/internal/drives"
)
func TestNewDefaultsToThreeSecondTeaserSegments(t *testing.T) {
gen := New(Config{})
if gen.cfg.DurationSeconds != 3 {
t.Fatalf("DurationSeconds = %d, want 3", gen.cfg.DurationSeconds)
}
}
func TestMediumVideoPreviewPlanUsesFourThreeSecondSegments(t *testing.T) {
plan := buildTeaserPlan(Config{DurationSeconds: 3, Segments: 3}, 300)
if len(plan.starts) != 4 {
t.Fatalf("segments = %d, want 4", len(plan.starts))
}
if plan.eachSec != 3 {
t.Fatalf("eachSec = %.2f, want 3", plan.eachSec)
}
want := []float64{15, 95, 175, 255}
for i := range want {
if math.Abs(plan.starts[i]-want[i]) > 0.001 {
t.Fatalf("start[%d] = %.2f, want %.2f", i, plan.starts[i], want[i])
}
}
}
func TestLongVideoPreviewPlanUsesFourThreeSecondSegments(t *testing.T) {
plan := buildTeaserPlan(Config{DurationSeconds: 15, Segments: 3}, 601)
if len(plan.starts) != 4 {
t.Fatalf("segments = %d, want 4", len(plan.starts))
}
if plan.eachSec != 3 {
t.Fatalf("eachSec = %.2f, want 3", plan.eachSec)
}
want := []float64{120.2, 240.4, 360.6, 480.8}
for i := range want {
if math.Abs(plan.starts[i]-want[i]) > 0.001 {
t.Fatalf("start[%d] = %.2f, want %.2f", i, plan.starts[i], want[i])
}
}
}
func TestShortVideoPreviewPlanUsesUpToThreeThreeSecondSegments(t *testing.T) {
plan := buildTeaserPlan(Config{DurationSeconds: 15, Segments: 3}, 20)
if len(plan.starts) != 3 {
t.Fatalf("segments = %d, want 3", len(plan.starts))
}
if plan.eachSec != 3 {
t.Fatalf("eachSec = %.2f, want 3", plan.eachSec)
}
want := []float64{2, 9.5, 17}
for i := range want {
if math.Abs(plan.starts[i]-want[i]) > 0.001 {
t.Fatalf("start[%d] = %.2f, want %.2f", i, plan.starts[i], want[i])
}
}
}
func TestShortVideoPreviewPlanDropsSegmentsThatDoNotFit(t *testing.T) {
plan := buildTeaserPlan(Config{DurationSeconds: 15, Segments: 3}, 8)
if len(plan.starts) != 2 {
t.Fatalf("segments = %d, want 2", len(plan.starts))
}
if plan.eachSec != 3 {
t.Fatalf("eachSec = %.2f, want 3", plan.eachSec)
}
want := []float64{0.8, 5}
for i := range want {
if math.Abs(plan.starts[i]-want[i]) > 0.001 {
t.Fatalf("start[%d] = %.2f, want %.2f", i, plan.starts[i], want[i])
}
}
}
func TestShortVideoPreviewPlanReturnsNoSegmentsWhenOneSegmentCannotFit(t *testing.T) {
plan := buildTeaserPlan(Config{DurationSeconds: 15, Segments: 3}, 2.5)
if len(plan.starts) != 0 {
t.Fatalf("segments = %d, want 0", len(plan.starts))
}
if plan.eachSec != 3 {
t.Fatalf("eachSec = %.2f, want 3", plan.eachSec)
}
}
func TestFFmpeg429OutputBecomesRateLimitError(t *testing.T) {
err := ffmpegCommandError("ffmpeg", errors.New("exit status 8"), []byte("Server returned 429 Too Many Requests"))
var rateLimit *drives.RateLimitError
if !errors.As(err, &rateLimit) {
t.Fatalf("error = %T %[1]v, want RateLimitError", err)
}
if rateLimit.RetryAfter != 0 {
t.Fatalf("retry after = %v, want none from ffmpeg stderr", rateLimit.RetryAfter)
}
}
func TestFFmpegCommandErrorRedactsSignedURLs(t *testing.T) {
err := ffmpegCommandError("ffmpeg", errors.New("exit status 8"), []byte("Error opening input file https://download.example/file.mp4?tempauth=secret."))
got := err.Error()
if strings.Contains(got, "tempauth=secret") {
t.Fatalf("error leaked signed URL: %s", got)
}
if !strings.Contains(got, "https://<redacted>.") {
t.Fatalf("error = %q, want redacted URL with punctuation preserved", got)
}
}