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
}