package persistence import ( "context" "github.com/deluan/rest" "github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model/request" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("RadioRepository", func() { var repo model.RadioRepository var ctx context.Context BeforeEach(func() { ctx = GinkgoT().Context() }) Describe("Admin User", func() { BeforeEach(func() { ctx = request.WithUser(log.NewContext(ctx), model.User{ID: "userid", UserName: "userid", IsAdmin: true}) repo = NewRadioRepository(GetDBXBuilder()) _ = repo.Put(ctx, &radioWithHomePage) }) AfterEach(func() { all, _ := repo.GetAll(ctx) for _, radio := range all { _ = repo.Delete(ctx, radio.ID) } for i := range testRadios { err := repo.Put(ctx, new(testRadios[i])) if err != nil { panic(err) } } }) Describe("Count", func() { It("returns the number of radios in the DB", func() { Expect(repo.CountAll(ctx)).To(Equal(int64(2))) }) }) Describe("Delete", func() { It("deletes existing item", func() { err := repo.Delete(ctx, radioWithHomePage.ID) Expect(err).To(BeNil()) _, err = repo.Get(ctx, radioWithHomePage.ID) Expect(err).To(MatchError(model.ErrNotFound)) }) It("errors when missing", func() { Expect(repo.Delete(ctx, "notanid")).To(MatchError(model.ErrNotFound)) }) }) Describe("Get", func() { It("returns an existing item", func() { res, err := repo.Get(ctx, radioWithHomePage.ID) Expect(err).To(BeNil()) Expect(res.ID).To(Equal(radioWithHomePage.ID)) }) It("errors when missing", func() { _, err := repo.Get(ctx, "notanid") Expect(err).To(MatchError(model.ErrNotFound)) }) }) Describe("GetAll", func() { It("returns all items from the DB", func() { all, err := repo.GetAll(ctx) Expect(err).To(BeNil()) Expect(all[0].ID).To(Equal(radioWithoutHomePage.ID)) Expect(all[1].ID).To(Equal(radioWithHomePage.ID)) }) }) Describe("Put", func() { It("successfully updates item", func() { err := repo.Put(ctx, &model.Radio{ ID: radioWithHomePage.ID, Name: "New Name", StreamUrl: "https://example.com:4533/app", }) Expect(err).To(BeNil()) item, err := repo.Get(ctx, radioWithHomePage.ID) Expect(err).To(BeNil()) Expect(item.HomePageUrl).To(Equal("")) }) It("successfully creates item", func() { err := repo.Put(ctx, &model.Radio{ Name: "New radio", StreamUrl: "https://example.com:4533/app", }) Expect(err).To(BeNil()) Expect(repo.CountAll(ctx)).To(Equal(int64(3))) all, err := repo.GetAll(ctx) Expect(err).To(BeNil()) Expect(all[2].StreamUrl).To(Equal("https://example.com:4533/app")) }) It("enqueues artwork resolution for the saved radio", func() { err := repo.Put(ctx, &model.Radio{ Name: "Artwork radio", StreamUrl: "https://example.com:4533/artwork", }) Expect(err).To(BeNil()) all, err := repo.GetAll(ctx) Expect(err).To(BeNil()) created := all[len(all)-1] queueRepo := NewArtworkQueueRepository(GetDBXBuilder()) queued, err := queueRepo.DequeueBatch(ctx, 1000) Expect(err).To(BeNil()) Expect(queued).To(ContainElement(SatisfyAll( HaveField("ItemKind", "ra"), HaveField("ItemID", created.ID), HaveField("Priority", model.ArtworkPriorityBump), ))) }) }) Describe("Update", func() { It("only writes the columns sent by the client", func() { radio := radioWithHomePage radio.UploadedImage = "cover.png" Expect(repo.Put(ctx, &radio)).To(Succeed()) Expect(repo.Update(ctx, radio.ID, model.Radio{Name: "Renamed"}, "name")).To(Succeed()) item, err := repo.Get(ctx, radio.ID) Expect(err).To(BeNil()) Expect(item.Name).To(Equal("Renamed")) Expect(item.UploadedImage).To(Equal("cover.png")) Expect(item.StreamUrl).To(Equal(radio.StreamUrl)) Expect(item.HomePageUrl).To(Equal(radio.HomePageUrl)) }) }) }) Describe("Regular User", func() { BeforeEach(func() { ctx = request.WithUser(log.NewContext(ctx), model.User{ID: "userid", UserName: "userid", IsAdmin: false}) repo = NewRadioRepository(GetDBXBuilder()) }) Describe("Count", func() { It("returns the number of radios in the DB", func() { Expect(repo.CountAll(ctx)).To(Equal(int64(2))) }) }) Describe("Delete", func() { It("fails to delete items", func() { err := repo.Delete(ctx, radioWithHomePage.ID) Expect(err).To(Equal(rest.ErrPermissionDenied)) }) }) Describe("Get", func() { It("returns an existing item", func() { res, err := repo.Get(ctx, radioWithHomePage.ID) Expect(err).To(BeNil()) Expect(res.ID).To(Equal(radioWithHomePage.ID)) }) It("errors when missing", func() { _, err := repo.Get(ctx, "notanid") Expect(err).To(MatchError(model.ErrNotFound)) }) }) Describe("GetAll", func() { It("returns all items from the DB", func() { all, err := repo.GetAll(ctx) Expect(err).To(BeNil()) Expect(all[0].ID).To(Equal(radioWithoutHomePage.ID)) Expect(all[1].ID).To(Equal(radioWithHomePage.ID)) }) }) Describe("Put", func() { It("fails to update item", func() { err := repo.Put(ctx, &model.Radio{ ID: radioWithHomePage.ID, Name: "New Name", StreamUrl: "https://example.com:4533/app", }) Expect(err).To(Equal(rest.ErrPermissionDenied)) }) }) }) })