package media import ( "encoding/json" "os" "path/filepath" "testing" ) func TestManifestWriter_NewManifestWriter(t *testing.T) { // Set up temporary environment for testing tempDir, err := os.MkdirTemp("", "manifest_test_*") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tempDir) // Set environment variable to use temp directory os.Setenv("LOCAL_OUTPUT_DIR", tempDir) defer os.Unsetenv("LOCAL_OUTPUT_DIR") eventName := "test-event" writer := NewManifestWriter(eventName) if writer == nil { t.Fatal("NewManifestWriter() returned nil") } if writer.Segments == nil { t.Error("Segments should be initialized") } if writer.Index == nil { t.Error("Index should be initialized") } if len(writer.Segments) != 0 { t.Errorf("Segments should be empty, got %d items", len(writer.Segments)) } } func TestManifestWriter_AddOrUpdateSegment(t *testing.T) { writer := &ManifestWriter{ ManifestPath: "test.json", Segments: make([]ManifestItem, 0), Index: make(map[string]*ManifestItem), } // Test adding new segment writer.AddOrUpdateSegment("1001", "1080p") if len(writer.Segments) != 1 { t.Errorf("Expected 1 segment, got %d", len(writer.Segments)) } if writer.Segments[0].SeqNo != "1001" { t.Errorf("Expected SeqNo '1001', got '%s'", writer.Segments[0].SeqNo) } if writer.Segments[0].Resolution != "1080p" { t.Errorf("Expected Resolution '1080p', got '%s'", writer.Segments[0].Resolution) } // Test updating existing segment with higher resolution writer.AddOrUpdateSegment("1001", "1440p") if len(writer.Segments) != 1 { t.Errorf("Segments count should remain 1 after update, got %d", len(writer.Segments)) } if writer.Segments[0].Resolution != "1440p" { t.Errorf("Expected updated resolution '1440p', got '%s'", writer.Segments[0].Resolution) } // Test updating existing segment with lower resolution (should not change) writer.AddOrUpdateSegment("1001", "720p") if writer.Segments[0].Resolution != "1440p" { t.Errorf("Resolution should remain '1440p', got '%s'", writer.Segments[0].Resolution) } // Test adding different segment writer.AddOrUpdateSegment("1002", "720p") if len(writer.Segments) != 2 { t.Errorf("Expected 2 segments, got %d", len(writer.Segments)) } } func TestManifestWriter_AddOrUpdateSegment_NilFields(t *testing.T) { writer := &ManifestWriter{ ManifestPath: "test.json", } // Test with nil fields (should initialize them) writer.AddOrUpdateSegment("1001", "1080p") if writer.Segments == nil { t.Error("Segments should be initialized") } if writer.Index == nil { t.Error("Index should be initialized") } if len(writer.Segments) != 1 { t.Errorf("Expected 1 segment, got %d", len(writer.Segments)) } } func TestManifestWriter_WriteManifest(t *testing.T) { tempDir, err := os.MkdirTemp("", "manifest_test_*") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tempDir) manifestPath := filepath.Join(tempDir, "test-manifest.json") writer := &ManifestWriter{ ManifestPath: manifestPath, Segments: make([]ManifestItem, 0), Index: make(map[string]*ManifestItem), } // Add some test segments out of order writer.AddOrUpdateSegment("1003", "1080p") writer.AddOrUpdateSegment("1001", "720p") writer.AddOrUpdateSegment("1002", "1080p") // Write manifest writer.WriteManifest() // Verify file was created if _, err := os.Stat(manifestPath); os.IsNotExist(err) { t.Fatalf("Manifest file was not created: %s", manifestPath) } // Read and verify content content, err := os.ReadFile(manifestPath) if err != nil { t.Fatalf("Failed to read manifest file: %v", err) } var segments []ManifestItem err = json.Unmarshal(content, &segments) if err != nil { t.Fatalf("Failed to unmarshal manifest JSON: %v", err) } // Verify segments are sorted by sequence number if len(segments) != 3 { t.Errorf("Expected 3 segments in manifest, got %d", len(segments)) } expectedOrder := []string{"1001", "1002", "1003"} for i, segment := range segments { if segment.SeqNo != expectedOrder[i] { t.Errorf("Segment %d: expected SeqNo '%s', got '%s'", i, expectedOrder[i], segment.SeqNo) } } // Verify content structure if segments[0].Resolution != "720p" { t.Errorf("Expected first segment resolution '720p', got '%s'", segments[0].Resolution) } if segments[1].Resolution != "1080p" { t.Errorf("Expected second segment resolution '1080p', got '%s'", segments[1].Resolution) } } func TestManifestWriter_WriteManifest_EmptySegments(t *testing.T) { tempDir, err := os.MkdirTemp("", "manifest_test_*") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tempDir) manifestPath := filepath.Join(tempDir, "empty-manifest.json") writer := &ManifestWriter{ ManifestPath: manifestPath, Segments: make([]ManifestItem, 0), Index: make(map[string]*ManifestItem), } // Write empty manifest writer.WriteManifest() // Verify file was created if _, err := os.Stat(manifestPath); os.IsNotExist(err) { t.Fatalf("Manifest file was not created: %s", manifestPath) } // Read and verify content is empty array content, err := os.ReadFile(manifestPath) if err != nil { t.Fatalf("Failed to read manifest file: %v", err) } var segments []ManifestItem err = json.Unmarshal(content, &segments) if err != nil { t.Fatalf("Failed to unmarshal manifest JSON: %v", err) } if len(segments) != 0 { t.Errorf("Expected empty segments array, got %d items", len(segments)) } } func TestManifestWriter_WriteManifest_InvalidPath(t *testing.T) { writer := &ManifestWriter{ ManifestPath: "/invalid/path/that/does/not/exist/manifest.json", Segments: []ManifestItem{{SeqNo: "1001", Resolution: "1080p"}}, Index: make(map[string]*ManifestItem), } // This should not panic, just fail gracefully writer.WriteManifest() // Test passes if no panic occurs } func TestManifestItem_JSONSerialization(t *testing.T) { item := ManifestItem{ SeqNo: "1001", Resolution: "1080p", } // Test marshaling data, err := json.Marshal(item) if err != nil { t.Fatalf("Failed to marshal ManifestItem: %v", err) } // Test unmarshaling var unmarshaled ManifestItem err = json.Unmarshal(data, &unmarshaled) if err != nil { t.Fatalf("Failed to unmarshal ManifestItem: %v", err) } if unmarshaled.SeqNo != item.SeqNo { t.Errorf("SeqNo mismatch: expected '%s', got '%s'", item.SeqNo, unmarshaled.SeqNo) } if unmarshaled.Resolution != item.Resolution { t.Errorf("Resolution mismatch: expected '%s', got '%s'", item.Resolution, unmarshaled.Resolution) } }