mirror of
https://github.com/navidrome/navidrome.git
synced 2026-07-30 16:56:22 -04:00
* refactor(req): drop redundant error return from Strings
The error from Strings carried no information beyond emptiness — it fired
exactly when the param was absent — and nearly every caller discarded it with
a blank identifier. Strings now just returns the values (empty when absent),
making the common optional-list reads one clean expression.
The few required-param callers (scrobble, createShare) check for emptiness and
return the same Subsonic error code 10 as before; their e2e tests now pin that
code. Ints and Times keep their contracts by synthesizing ErrMissingParam
themselves, so selectedMusicFolderIds is untouched. The jellyfin parseFields
helper is inlined away, since ParseFields(p.Strings("fields")...) now
compiles directly.
* docs(req): clarify Strings returns nil when param is absent
293 lines
7.5 KiB
Go
293 lines
7.5 KiB
Go
package req_test
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/navidrome/navidrome/utils/req"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
func TestUtils(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "Request Helpers Suite")
|
|
}
|
|
|
|
var _ = Describe("Request Helpers", func() {
|
|
var r *req.Values
|
|
|
|
Describe("ParamString", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?a=123", nil))
|
|
})
|
|
|
|
It("returns param as string", func() {
|
|
Expect(r.String("a")).To(Equal("123"))
|
|
})
|
|
|
|
It("returns empty string if param does not exist", func() {
|
|
v, err := r.String("NON_EXISTENT_PARAM")
|
|
Expect(err).To(MatchError(req.ErrMissingParam))
|
|
Expect(err.Error()).To(ContainSubstring("NON_EXISTENT_PARAM"))
|
|
Expect(v).To(BeEmpty())
|
|
})
|
|
})
|
|
|
|
Describe("ParamStringDefault", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?a=123", nil))
|
|
})
|
|
|
|
It("returns param as string", func() {
|
|
Expect(r.StringOr("a", "default_value")).To(Equal("123"))
|
|
})
|
|
|
|
It("returns default string if param does not exist", func() {
|
|
Expect(r.StringOr("xx", "default_value")).To(Equal("default_value"))
|
|
})
|
|
})
|
|
|
|
Describe("ParamStrings", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?a=123&a=456", nil))
|
|
})
|
|
|
|
It("returns all param occurrences as []string", func() {
|
|
Expect(r.Strings("a")).To(Equal([]string{"123", "456"}))
|
|
})
|
|
|
|
It("returns empty array if param does not exist", func() {
|
|
Expect(r.Strings("xx")).To(BeEmpty())
|
|
})
|
|
})
|
|
|
|
Describe("ParamTime", func() {
|
|
d := time.Date(2002, 8, 9, 12, 11, 13, 1000000, time.Local)
|
|
t := d.UnixMilli()
|
|
now := time.Now()
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", fmt.Sprintf("/ping?t=%d&inv=abc", t), nil))
|
|
})
|
|
|
|
It("returns parsed time", func() {
|
|
Expect(r.TimeOr("t", now)).To(Equal(d))
|
|
})
|
|
|
|
It("returns default time if param does not exist", func() {
|
|
Expect(r.TimeOr("xx", now)).To(Equal(now))
|
|
})
|
|
|
|
It("returns default time if param is an invalid timestamp", func() {
|
|
Expect(r.TimeOr("inv", now)).To(Equal(now))
|
|
})
|
|
})
|
|
|
|
Describe("ParamTimes", func() {
|
|
d1 := time.Date(2002, 8, 9, 12, 11, 13, 1000000, time.Local)
|
|
d2 := time.Date(2002, 8, 9, 12, 13, 56, 0000000, time.Local)
|
|
t1 := d1.UnixMilli()
|
|
t2 := d2.UnixMilli()
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", fmt.Sprintf("/ping?t=%d&t=%d", t1, t2), nil))
|
|
})
|
|
|
|
It("returns all param occurrences as []time.Time", func() {
|
|
Expect(r.Times("t")).To(Equal([]time.Time{d1, d2}))
|
|
})
|
|
|
|
It("returns empty string if param does not exist", func() {
|
|
v, err := r.Times("xx")
|
|
Expect(err).To(MatchError(req.ErrMissingParam))
|
|
Expect(v).To(BeEmpty())
|
|
})
|
|
|
|
It("returns current time as default if param is invalid", func() {
|
|
now := time.Now()
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?t=null", nil))
|
|
times, err := r.Times("t")
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(times).To(HaveLen(1))
|
|
Expect(times[0]).To(BeTemporally(">=", now))
|
|
})
|
|
})
|
|
|
|
Describe("ParamInt", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?i=123&inv=123.45", nil))
|
|
})
|
|
Context("int", func() {
|
|
It("returns parsed int", func() {
|
|
Expect(r.IntOr("i", 999)).To(Equal(123))
|
|
})
|
|
|
|
It("returns default value if param does not exist", func() {
|
|
Expect(r.IntOr("xx", 999)).To(Equal(999))
|
|
})
|
|
|
|
It("returns default value if param is an invalid int", func() {
|
|
Expect(r.IntOr("inv", 999)).To(Equal(999))
|
|
})
|
|
|
|
It("returns error if param is an invalid int", func() {
|
|
_, err := r.Int("inv")
|
|
Expect(err).To(MatchError(req.ErrInvalidParam))
|
|
})
|
|
})
|
|
Context("int64", func() {
|
|
It("returns parsed int64", func() {
|
|
Expect(r.Int64Or("i", 999)).To(Equal(int64(123)))
|
|
})
|
|
|
|
It("returns default value if param does not exist", func() {
|
|
Expect(r.Int64Or("xx", 999)).To(Equal(int64(999)))
|
|
})
|
|
|
|
It("returns default value if param is an invalid int", func() {
|
|
Expect(r.Int64Or("inv", 999)).To(Equal(int64(999)))
|
|
})
|
|
|
|
It("returns error if param is an invalid int", func() {
|
|
_, err := r.Int64("inv")
|
|
Expect(err).To(MatchError(req.ErrInvalidParam))
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("ParamInts", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?i=123&i=456", nil))
|
|
})
|
|
|
|
It("returns array of occurrences found", func() {
|
|
Expect(r.Ints("i")).To(Equal([]int{123, 456}))
|
|
})
|
|
|
|
It("returns empty array if param does not exist", func() {
|
|
v, err := r.Ints("xx")
|
|
Expect(err).To(MatchError(req.ErrMissingParam))
|
|
Expect(v).To(BeEmpty())
|
|
})
|
|
})
|
|
|
|
Describe("ParamBool", func() {
|
|
Context("value is true", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?b=true&c=on&d=1&e=True", nil))
|
|
})
|
|
|
|
It("parses 'true'", func() {
|
|
Expect(r.BoolOr("b", false)).To(BeTrue())
|
|
})
|
|
|
|
It("parses 'on'", func() {
|
|
Expect(r.BoolOr("c", false)).To(BeTrue())
|
|
})
|
|
|
|
It("parses '1'", func() {
|
|
Expect(r.BoolOr("d", false)).To(BeTrue())
|
|
})
|
|
|
|
It("parses 'True'", func() {
|
|
Expect(r.BoolOr("e", false)).To(BeTrue())
|
|
})
|
|
})
|
|
|
|
Context("value is false", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?b=false&c=off&d=0", nil))
|
|
})
|
|
|
|
It("parses 'false'", func() {
|
|
Expect(r.BoolOr("b", true)).To(BeFalse())
|
|
})
|
|
|
|
It("parses 'off'", func() {
|
|
Expect(r.BoolOr("c", true)).To(BeFalse())
|
|
})
|
|
|
|
It("parses '0'", func() {
|
|
Expect(r.BoolOr("d", true)).To(BeFalse())
|
|
})
|
|
|
|
It("returns default value if param does not exist", func() {
|
|
Expect(r.BoolOr("xx", true)).To(BeTrue())
|
|
})
|
|
})
|
|
})
|
|
|
|
Describe("ParamStringPtr", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?a=123", nil))
|
|
})
|
|
|
|
It("returns pointer to string if param exists", func() {
|
|
ptr := r.StringPtr("a")
|
|
Expect(ptr).ToNot(BeNil())
|
|
Expect(*ptr).To(Equal("123"))
|
|
})
|
|
|
|
It("returns nil if param does not exist", func() {
|
|
ptr := r.StringPtr("xx")
|
|
Expect(ptr).To(BeNil())
|
|
})
|
|
|
|
It("returns pointer to empty string if param exists but is empty", func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?a=", nil))
|
|
ptr := r.StringPtr("a")
|
|
Expect(ptr).ToNot(BeNil())
|
|
Expect(*ptr).To(Equal(""))
|
|
})
|
|
})
|
|
|
|
Describe("Float64Or", func() {
|
|
It("returns parsed float value", func() {
|
|
r := req.Params(httptest.NewRequest("GET", "/test?rate=1.5", nil))
|
|
Expect(r.Float64Or("rate", 1.0)).To(Equal(1.5))
|
|
})
|
|
|
|
It("returns default when param is missing", func() {
|
|
r := req.Params(httptest.NewRequest("GET", "/test", nil))
|
|
Expect(r.Float64Or("rate", 1.0)).To(Equal(1.0))
|
|
})
|
|
|
|
It("returns default when param is not a valid float", func() {
|
|
r := req.Params(httptest.NewRequest("GET", "/test?rate=abc", nil))
|
|
Expect(r.Float64Or("rate", 1.0)).To(Equal(1.0))
|
|
})
|
|
})
|
|
|
|
Describe("ParamBoolPtr", func() {
|
|
Context("value is true", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?b=true", nil))
|
|
})
|
|
|
|
It("returns pointer to true if param is 'true'", func() {
|
|
ptr := r.BoolPtr("b")
|
|
Expect(ptr).ToNot(BeNil())
|
|
Expect(*ptr).To(BeTrue())
|
|
})
|
|
})
|
|
|
|
Context("value is false", func() {
|
|
BeforeEach(func() {
|
|
r = req.Params(httptest.NewRequest("GET", "/ping?b=false", nil))
|
|
})
|
|
|
|
It("returns pointer to false if param is 'false'", func() {
|
|
ptr := r.BoolPtr("b")
|
|
Expect(ptr).ToNot(BeNil())
|
|
Expect(*ptr).To(BeFalse())
|
|
})
|
|
})
|
|
|
|
It("returns nil if param does not exist", func() {
|
|
ptr := r.BoolPtr("xx")
|
|
Expect(ptr).To(BeNil())
|
|
})
|
|
})
|
|
})
|