package music_test import ( "arimelody-web/errors" "arimelody-web/model" repository "arimelody-web/repository/music" service "arimelody-web/service/music" "log" "os" "slices" "testing" "time" "gotest.tools/v3/assert" ) func Test_Artist(t *testing.T) { devNullFile, err := os.OpenFile(os.DevNull, os.O_RDWR, 0666) if err != nil { panic(err) } defer devNullFile.Close() repo := repository.NewMusicRepositoryMemory( make([]*model.Artist, 0), make([]*model.Release, 0), make([]*model.Track, 0), ) s = service.NewMusicService( repo, log.New(devNullFile, "", model.DEFAULT_LOG_FLAGS), ) id := "cool-artist" name := "Cool Artist" website := "artist.arimelody.space" avatarURL := "/img/cool-artist.webp" t.Run("artists should start empty", func(t *testing.T) { t.Run("count is zero", func(t *testing.T) { if num, err := s.GetArtistCount(); err != nil { t.Errorf("Failed to get number of artists: %v", err) } else { assert.Equal(t, num, 0) } }) t.Run("service returns empty array", func(t *testing.T) { if artists, err := s.GetAllArtists(); err != nil { t.Errorf("Failed to get artists: %v", err) } else { assert.Equal(t, len(artists), 0) } }) }) t.Run("can create artist", func(t *testing.T) { if err := s.CreateArtist(id, name, website, avatarURL); err != nil { t.Errorf("Failed to create artist: %v", err) } t.Run("but not with an invalid ID", func(t *testing.T) { if err := s.CreateArtist("", name, website, avatarURL); err == nil { t.Error("Created artist with invalid ID") } }) t.Run("but not with an invalid name", func(t *testing.T) { if err := s.CreateArtist("test-artist", "", website, avatarURL); err == nil { t.Error("Created artist with invalid name") } }) t.Run("and retrieve it", func(t *testing.T) { repoArtist, err := s.GetArtistByID(id) if err != nil { t.Errorf("Failed to get artist: %v", err) } assert.Equal(t, repoArtist.ID, id) assert.Equal(t, repoArtist.Name, name) assert.Equal(t, repoArtist.Website, website) assert.Equal(t, repoArtist.Avatar, avatarURL) }) }) t.Run("number of artists should increment", func(t *testing.T) { t.Run("count is one", func(t *testing.T) { if num, err := s.GetArtistCount(); err != nil { t.Errorf("Failed to get number of artists: %v", err) } else { assert.Equal(t, num, 1) } }) t.Run("service returns array with one artist", func(t *testing.T) { if artists, err := s.GetAllArtists(); err != nil { t.Errorf("Failed to get artists: %v", err) } else { assert.Equal(t, len(artists), 1) } }) }) releaseID := "test-release" t.Run("can get artists not on a release", func(t *testing.T) { if err := s.CreateRelease(releaseID, "test", string(model.Single), time.Now(), ""); err != nil { t.Errorf("Failed to create release: %v", err) } artists, err := s.GetArtistsNotOnRelease(releaseID) if err != nil { t.Errorf("Failed to get artists: %v", err) } assert.Assert(t, slices.ContainsFunc(artists, func(artist *model.Artist) bool { return artist.ID == id })) }) credit := &model.Credit{ Artist: &model.Artist{ ID: id, Name: name, Website: website, Avatar: avatarURL }, Role: "did a lot of stuff", Primary: true, } t.Run("can get artist credits", func(t *testing.T) { if err := s.UpdateReleaseCredits(releaseID, []*model.Credit{ credit }); err != nil { t.Errorf("Failed to update release credits: %v", err) } credits, err := s.GetArtistCredits(id, true) if err != nil { t.Errorf("Failed to get credits: %v", err) } index := slices.IndexFunc(credits, func(credit *model.Credit) bool { return credit.Artist.ID == id }) assert.Assert(t, index != -1) assert.Equal(t, credits[index].Artist.ID, id) assert.Equal(t, credits[index].Artist.Name, name) assert.Equal(t, credits[index].Artist.Website, website) assert.Equal(t, credits[index].Artist.Avatar, avatarURL) assert.Equal(t, credits[index].Role, credit.Role) assert.Equal(t, credits[index].Primary, credit.Primary) }) t.Run("can update artist", func(t *testing.T) { testName := "this name is only temporary" testWebsite := "https://test.example.org" testAvatar := "/img/test-avatar.webp" if err := s.UpdateArtist(&model.Artist{ ID: id, Name: testName, Website: testWebsite, Avatar: testAvatar, }); err != nil { t.Errorf("Failed to update artist: %v", err) } artist, err := s.GetArtistByID(id) if err != nil { t.Errorf("Failed to get artist: %v", err) } assert.Equal(t, artist.Name, testName) assert.Equal(t, artist.Website, testWebsite) assert.Equal(t, artist.GetAvatar(), testAvatar) t.Run("but not with invalid name", func(t *testing.T) { if err := s.UpdateArtist(&model.Artist{ ID: id, Name: "", }); err == nil { t.Errorf("Updated artist name to invalid value") } }) }) t.Run("can update artist name", func(t *testing.T) { if err := s.UpdateArtistName(id, name); err != nil { t.Errorf("Failed to update artist: %v", err) } artist, err := s.GetArtistByID(id) if err != nil { t.Errorf("Failed to get artist: %v", err) } assert.Equal(t, artist.Name, name) t.Run("but not with invalid value", func(t *testing.T) { if err := s.UpdateArtistName(id, ""); err == nil { t.Errorf("Updated artist name to invalid value") } }) }) t.Run("can update artist website", func(t *testing.T) { if err := s.UpdateArtistWebsite(id, website); err != nil { t.Errorf("Failed to update artist: %v", err) } artist, err := s.GetArtistByID(id) if err != nil { t.Errorf("Failed to get artist: %v", err) } assert.Equal(t, artist.Website, website) }) t.Run("can update artist avatar", func(t *testing.T) { if err := s.UpdateArtistAvatar(id, ""); err != nil { t.Errorf("Failed to update artist: %v", err) } artist, err := s.GetArtistByID(id) if err != nil { t.Errorf("Failed to get artist: %v", err) } assert.Equal(t, artist.GetAvatar(), model.DEFAULT_AVATAR_URL) }) t.Run("can delete artist", func(t *testing.T) { if err := s.DeleteArtist(id); err != nil { t.Errorf("Failed to delete artist: %v", err) } t.Run("no longer exists", func(t *testing.T) { if artist, err := s.GetArtistByID(id); err == nil { t.Error("No error getting artist") } else if artist != nil { t.Error("Artist with this ID still exists") } }) t.Run("but not one that doesn't exist", func(t *testing.T) { if err := s.DeleteArtist("some-garbage-id"); err == nil { if !errors.IsNotExistError(err) { t.Errorf("Failed to delete artist: %v", err) } } }) }) }