mirror of
https://github.com/navidrome/navidrome.git
synced 2025-12-23 23:18:05 -05:00
fix(share): slice content label by utf-8 runes (#4634)
* fix(share): slice content label by utf-8 runes * Apply suggestions about avoiding allocations Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * lint: remove unused import * test: add test cases for CJK truncation * test: add tests for ASCII labels too --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
@@ -119,8 +119,21 @@ func (r *shareRepositoryWrapper) Save(entity interface{}) (string, error) {
|
||||
log.Error(r.ctx, "Invalid Resource ID", "id", firstId)
|
||||
return "", model.ErrNotFound
|
||||
}
|
||||
if len(s.Contents) > 30 {
|
||||
s.Contents = s.Contents[:26] + "..."
|
||||
|
||||
const maxContentRunes = 30
|
||||
const truncateToRunes = 26
|
||||
|
||||
var runeCount int
|
||||
var truncateIndex int
|
||||
for i := range s.Contents {
|
||||
runeCount++
|
||||
if runeCount == truncateToRunes+1 {
|
||||
truncateIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if runeCount > maxContentRunes {
|
||||
s.Contents = s.Contents[:truncateIndex] + "..."
|
||||
}
|
||||
|
||||
id, err = r.Persistable.Save(s)
|
||||
|
||||
@@ -38,6 +38,38 @@ var _ = Describe("Share", func() {
|
||||
Expect(id).ToNot(BeEmpty())
|
||||
Expect(entity.ID).To(Equal(id))
|
||||
})
|
||||
|
||||
It("does not truncate ASCII labels shorter than 30 characters", func() {
|
||||
_ = ds.MediaFile(ctx).Put(&model.MediaFile{ID: "456", Title: "Example Media File"})
|
||||
entity := &model.Share{Description: "test", ResourceIDs: "456"}
|
||||
_, err := repo.Save(entity)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(entity.Contents).To(Equal("Example Media File"))
|
||||
})
|
||||
|
||||
It("truncates ASCII labels longer than 30 characters", func() {
|
||||
_ = ds.MediaFile(ctx).Put(&model.MediaFile{ID: "789", Title: "Example Media File But The Title Is Really Long For Testing Purposes"})
|
||||
entity := &model.Share{Description: "test", ResourceIDs: "789"}
|
||||
_, err := repo.Save(entity)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(entity.Contents).To(Equal("Example Media File But The..."))
|
||||
})
|
||||
|
||||
It("does not truncate CJK labels shorter than 30 runes", func() {
|
||||
_ = ds.MediaFile(ctx).Put(&model.MediaFile{ID: "456", Title: "青春コンプレックス"})
|
||||
entity := &model.Share{Description: "test", ResourceIDs: "456"}
|
||||
_, err := repo.Save(entity)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(entity.Contents).To(Equal("青春コンプレックス"))
|
||||
})
|
||||
|
||||
It("truncates CJK labels longer than 30 runes", func() {
|
||||
_ = ds.MediaFile(ctx).Put(&model.MediaFile{ID: "789", Title: "私の中の幻想的世界観及びその顕現を想起させたある現実での出来事に関する一考察"})
|
||||
entity := &model.Share{Description: "test", ResourceIDs: "789"}
|
||||
_, err := repo.Save(entity)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(entity.Contents).To(Equal("私の中の幻想的世界観及びその顕現を想起させたある現実..."))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Update", func() {
|
||||
|
||||
Reference in New Issue
Block a user