1package persistence 2 3import ( 4 "context" 5 "time" 6 7 "github.com/astaxie/beego/orm" 8 "github.com/google/uuid" 9 "github.com/navidrome/navidrome/log" 10 "github.com/navidrome/navidrome/model" 11 "github.com/navidrome/navidrome/model/request" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14) 15 16var _ = Describe("MediaRepository", func() { 17 var mr model.MediaFileRepository 18 19 BeforeEach(func() { 20 ctx := log.NewContext(context.TODO()) 21 ctx = request.WithUser(ctx, model.User{ID: "userid"}) 22 mr = NewMediaFileRepository(ctx, orm.NewOrm()) 23 }) 24 25 It("gets mediafile from the DB", func() { 26 Expect(mr.Get("1004")).To(Equal(&songAntenna)) 27 }) 28 29 It("returns ErrNotFound", func() { 30 _, err := mr.Get("56") 31 Expect(err).To(MatchError(model.ErrNotFound)) 32 }) 33 34 It("counts the number of mediafiles in the DB", func() { 35 Expect(mr.CountAll()).To(Equal(int64(4))) 36 }) 37 38 It("checks existence of mediafiles in the DB", func() { 39 Expect(mr.Exists(songAntenna.ID)).To(BeTrue()) 40 Expect(mr.Exists("666")).To(BeFalse()) 41 }) 42 43 It("find mediafiles by album", func() { 44 Expect(mr.FindByAlbum("103")).To(Equal(model.MediaFiles{ 45 songAntenna, 46 songRadioactivity, 47 })) 48 }) 49 50 It("returns empty array when no tracks are found", func() { 51 Expect(mr.FindByAlbum("67")).To(Equal(model.MediaFiles{})) 52 }) 53 54 It("finds tracks by path when using wildcards chars", func() { 55 Expect(mr.Put(&model.MediaFile{ID: "7001", Path: P("/Find:By'Path/_/123.mp3")})).To(BeNil()) 56 Expect(mr.Put(&model.MediaFile{ID: "7002", Path: P("/Find:By'Path/1/123.mp3")})).To(BeNil()) 57 58 found, err := mr.FindAllByPath(P("/Find:By'Path/_/")) 59 Expect(err).To(BeNil()) 60 Expect(found).To(HaveLen(1)) 61 Expect(found[0].ID).To(Equal("7001")) 62 }) 63 64 It("finds tracks by path when using UTF8 chars", func() { 65 Expect(mr.Put(&model.MediaFile{ID: "7010", Path: P("/Пётр Ильич Чайковский/123.mp3")})).To(BeNil()) 66 Expect(mr.Put(&model.MediaFile{ID: "7011", Path: P("/Пётр Ильич Чайковский/222.mp3")})).To(BeNil()) 67 68 found, err := mr.FindAllByPath(P("/Пётр Ильич Чайковский/")) 69 Expect(err).To(BeNil()) 70 Expect(found).To(HaveLen(2)) 71 }) 72 73 It("finds tracks by path case sensitively", func() { 74 Expect(mr.Put(&model.MediaFile{ID: "7003", Path: P("/Casesensitive/file1.mp3")})).To(BeNil()) 75 Expect(mr.Put(&model.MediaFile{ID: "7004", Path: P("/casesensitive/file2.mp3")})).To(BeNil()) 76 77 found, err := mr.FindAllByPath(P("/Casesensitive")) 78 Expect(err).To(BeNil()) 79 Expect(found).To(HaveLen(1)) 80 Expect(found[0].ID).To(Equal("7003")) 81 82 found, err = mr.FindAllByPath(P("/casesensitive/")) 83 Expect(err).To(BeNil()) 84 Expect(found).To(HaveLen(1)) 85 Expect(found[0].ID).To(Equal("7004")) 86 }) 87 88 It("returns starred tracks", func() { 89 Expect(mr.GetStarred()).To(Equal(model.MediaFiles{ 90 songComeTogether, 91 })) 92 }) 93 94 It("delete tracks by id", func() { 95 id := uuid.NewString() 96 Expect(mr.Put(&model.MediaFile{ID: id})).To(BeNil()) 97 98 Expect(mr.Delete(id)).To(BeNil()) 99 100 _, err := mr.Get(id) 101 Expect(err).To(MatchError(model.ErrNotFound)) 102 }) 103 104 It("delete tracks by path", func() { 105 id1 := "6001" 106 Expect(mr.Put(&model.MediaFile{ID: id1, Path: P("/abc/123/" + id1 + ".mp3")})).To(BeNil()) 107 id2 := "6002" 108 Expect(mr.Put(&model.MediaFile{ID: id2, Path: P("/abc/123/" + id2 + ".mp3")})).To(BeNil()) 109 id3 := "6003" 110 Expect(mr.Put(&model.MediaFile{ID: id3, Path: P("/ab_/" + id3 + ".mp3")})).To(BeNil()) 111 id4 := "6004" 112 Expect(mr.Put(&model.MediaFile{ID: id4, Path: P("/abc/" + id4 + ".mp3")})).To(BeNil()) 113 id5 := "6005" 114 Expect(mr.Put(&model.MediaFile{ID: id5, Path: P("/Ab_/" + id5 + ".mp3")})).To(BeNil()) 115 116 Expect(mr.DeleteByPath(P("/ab_"))).To(Equal(int64(1))) 117 118 Expect(mr.Get(id1)).ToNot(BeNil()) 119 Expect(mr.Get(id2)).ToNot(BeNil()) 120 Expect(mr.Get(id4)).ToNot(BeNil()) 121 Expect(mr.Get(id5)).ToNot(BeNil()) 122 _, err := mr.Get(id3) 123 Expect(err).To(MatchError(model.ErrNotFound)) 124 }) 125 126 It("delete tracks by path containing UTF8 chars", func() { 127 id1 := "6011" 128 Expect(mr.Put(&model.MediaFile{ID: id1, Path: P("/Legião Urbana/" + id1 + ".mp3")})).To(BeNil()) 129 id2 := "6012" 130 Expect(mr.Put(&model.MediaFile{ID: id2, Path: P("/Legião Urbana/" + id2 + ".mp3")})).To(BeNil()) 131 id3 := "6003" 132 Expect(mr.Put(&model.MediaFile{ID: id3, Path: P("/Legião Urbana/" + id3 + ".mp3")})).To(BeNil()) 133 134 Expect(mr.FindAllByPath(P("/Legião Urbana"))).To(HaveLen(3)) 135 Expect(mr.DeleteByPath(P("/Legião Urbana"))).To(Equal(int64(3))) 136 Expect(mr.FindAllByPath(P("/Legião Urbana"))).To(HaveLen(0)) 137 }) 138 139 It("only deletes tracks that match exact path", func() { 140 id1 := "6021" 141 Expect(mr.Put(&model.MediaFile{ID: id1, Path: P("/music/overlap/Ella Fitzgerald/" + id1 + ".mp3")})).To(BeNil()) 142 id2 := "6022" 143 Expect(mr.Put(&model.MediaFile{ID: id2, Path: P("/music/overlap/Ella Fitzgerald/" + id2 + ".mp3")})).To(BeNil()) 144 id3 := "6023" 145 Expect(mr.Put(&model.MediaFile{ID: id3, Path: P("/music/overlap/Ella Fitzgerald & Louis Armstrong - They Can't Take That Away From Me.mp3")})).To(BeNil()) 146 147 Expect(mr.FindAllByPath(P("/music/overlap/Ella Fitzgerald"))).To(HaveLen(2)) 148 Expect(mr.DeleteByPath(P("/music/overlap/Ella Fitzgerald"))).To(Equal(int64(2))) 149 Expect(mr.FindAllByPath(P("/music/overlap"))).To(HaveLen(1)) 150 }) 151 152 Context("Annotations", func() { 153 It("increments play count when the tracks does not have annotations", func() { 154 id := "incplay.firsttime" 155 Expect(mr.Put(&model.MediaFile{ID: id})).To(BeNil()) 156 playDate := time.Now() 157 Expect(mr.IncPlayCount(id, playDate)).To(BeNil()) 158 159 mf, err := mr.Get(id) 160 Expect(err).To(BeNil()) 161 162 Expect(mf.PlayDate.Unix()).To(Equal(playDate.Unix())) 163 Expect(mf.PlayCount).To(Equal(int64(1))) 164 }) 165 166 It("increments play count on newly starred items", func() { 167 id := "star.incplay" 168 Expect(mr.Put(&model.MediaFile{ID: id})).To(BeNil()) 169 Expect(mr.SetStar(true, id)).To(BeNil()) 170 playDate := time.Now() 171 Expect(mr.IncPlayCount(id, playDate)).To(BeNil()) 172 173 mf, err := mr.Get(id) 174 Expect(err).To(BeNil()) 175 176 Expect(mf.PlayDate.Unix()).To(Equal(playDate.Unix())) 177 Expect(mf.PlayCount).To(Equal(int64(1))) 178 }) 179 }) 180}) 181