package musicbrainz import ( "testing" ) func TestParseReleaseGroups_Success(t *testing.T) { data := []byte(` Dark Side of the Moon 1973-03-01 Pink Floyd Another Brick in the Wall 1979-11-30 Pink Floyd `) result, err := ParseReleaseGroups(data) if err != nil { t.Fatalf("ParseReleaseGroups() error = %v", err) } if result.Count != 2 { t.Errorf("ParseReleaseGroups().Count = %d, want 2", result.Count) } if len(result.ReleaseGroups) != 2 { t.Fatalf("ParseReleaseGroups() returned %d groups, want 2", len(result.ReleaseGroups)) } expected := []ReleaseGroup{ { ID: "rg-uuid-1", Title: "Dark Side of the Moon", Type: "Album", ArtistID: "artist-uuid-1", ArtistName: "Pink Floyd", ReleaseDate: "1973-03-01", }, { ID: "rg-uuid-2", Title: "Another Brick in the Wall", Type: "Single", ArtistID: "artist-uuid-1", ArtistName: "Pink Floyd", ReleaseDate: "1979-11-30", }, } for i, rg := range result.ReleaseGroups { if rg.ID != expected[i].ID { t.Errorf("ReleaseGroups[%d].ID = %q, want %q", i, rg.ID, expected[i].ID) } if rg.Title != expected[i].Title { t.Errorf("ReleaseGroups[%d].Title = %q, want %q", i, rg.Title, expected[i].Title) } if rg.Type != expected[i].Type { t.Errorf("ReleaseGroups[%d].Type = %q, want %q", i, rg.Type, expected[i].Type) } if rg.ArtistID != expected[i].ArtistID { t.Errorf("ReleaseGroups[%d].ArtistID = %q, want %q", i, rg.ArtistID, expected[i].ArtistID) } if rg.ArtistName != expected[i].ArtistName { t.Errorf("ReleaseGroups[%d].ArtistName = %q, want %q", i, rg.ArtistName, expected[i].ArtistName) } if rg.ReleaseDate != expected[i].ReleaseDate { t.Errorf("ReleaseGroups[%d].ReleaseDate = %q, want %q", i, rg.ReleaseDate, expected[i].ReleaseDate) } } } func TestParseReleaseGroups_Empty(t *testing.T) { data := []byte(` `) result, err := ParseReleaseGroups(data) if err != nil { t.Fatalf("ParseReleaseGroups() error = %v", err) } if result.Count != 0 { t.Errorf("ParseReleaseGroups().Count = %d, want 0", result.Count) } if len(result.ReleaseGroups) != 0 { t.Errorf("ParseReleaseGroups() returned %d groups, want 0", len(result.ReleaseGroups)) } } func TestParseReleaseGroups_MalformedXML(t *testing.T) { tests := []struct { name string data []byte }{ { name: "truncated XML", data: []byte(``), }, { name: "not XML at all", data: []byte(`this is not xml`), }, { name: "wrong root element", data: []byte(`test`), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := ParseReleaseGroups(tt.data) if err == nil { t.Fatal("ParseReleaseGroups() expected error for malformed XML, got nil") } }) } } func TestParseReleaseGroups_PrimaryAndSecondaryTypes(t *testing.T) { data := []byte(` Studio Album Album 2020-01-01 Test Artist Greatest Hits Album Compilation Live 2021-05-05 Test Artist `) result, err := ParseReleaseGroups(data) if err != nil { t.Fatalf("ParseReleaseGroups() error = %v", err) } if len(result.ReleaseGroups) != 2 { t.Fatalf("ParseReleaseGroups() returned %d groups, want 2", len(result.ReleaseGroups)) } byID := make(map[string]ReleaseGroup) for _, rg := range result.ReleaseGroups { byID[rg.ID] = rg } album := byID["rg-album"] if album.Type != "Album" { t.Errorf("rg-album.Type = %q, want %q", album.Type, "Album") } if len(album.SecondaryTypes) != 0 { t.Errorf("rg-album.SecondaryTypes = %v, want empty", album.SecondaryTypes) } comp := byID["rg-comp"] if comp.Type != "Album" { t.Errorf("rg-comp.Type = %q, want %q", comp.Type, "Album") } // Release groups have no status attribute; the secondary type list is the // authoritative source for classifications like Compilation. if !contains(comp.SecondaryTypes, "Compilation") || !contains(comp.SecondaryTypes, "Live") { t.Errorf("rg-comp.SecondaryTypes = %v, want Compilation and Live", comp.SecondaryTypes) } } func contains(s []string, want string) bool { for _, v := range s { if v == want { return true } } return false }