test(subsonic): cover browse type helpers (#295)
UUID round-trip, index letter bucketing, content-type mapping, date/ts conversions, and small number utilities used by browse handlers.
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
package subsonic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func TestUUIDRoundTrip(t *testing.T) {
|
||||
cases := []string{
|
||||
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
||||
"00000000-0000-0000-0000-000000000001",
|
||||
}
|
||||
for _, in := range cases {
|
||||
u, ok := parseUUID(in)
|
||||
if !ok {
|
||||
t.Fatalf("parseUUID(%q) failed", in)
|
||||
}
|
||||
if got := uuidToID(u); got != in {
|
||||
t.Errorf("uuidToID(parseUUID(%q)) = %q", in, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUUIDToIDZero(t *testing.T) {
|
||||
var u pgtype.UUID
|
||||
if got := uuidToID(u); got != "" {
|
||||
t.Errorf("zero uuid → %q, want empty", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseUUIDInvalid(t *testing.T) {
|
||||
for _, in := range []string{"", "not-a-uuid", "xxx"} {
|
||||
if _, ok := parseUUID(in); ok {
|
||||
t.Errorf("parseUUID(%q) unexpectedly ok", in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexLetter(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"Radiohead": "R",
|
||||
"the beatles": "T",
|
||||
" massive": "M",
|
||||
"4 Non Blondes": "#",
|
||||
"": "?",
|
||||
"*NSYNC": "?",
|
||||
"Éowyn": "?",
|
||||
}
|
||||
for in, want := range cases {
|
||||
if got := indexLetter(in); got != want {
|
||||
t.Errorf("indexLetter(%q) = %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentTypeForFormat(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"mp3": "audio/mpeg",
|
||||
"MP3": "audio/mpeg",
|
||||
"flac": "audio/flac",
|
||||
"ogg": "audio/ogg",
|
||||
"oga": "audio/ogg",
|
||||
"opus": "audio/opus",
|
||||
"m4a": "audio/mp4",
|
||||
"aac": "audio/mp4",
|
||||
"wav": "audio/wav",
|
||||
"unknown": "application/octet-stream",
|
||||
}
|
||||
for in, want := range cases {
|
||||
if got := contentTypeForFormat(in); got != want {
|
||||
t.Errorf("contentTypeForFormat(%q) = %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestYearFromDate(t *testing.T) {
|
||||
d := pgtype.Date{Valid: true, Time: time.Date(1997, 6, 16, 0, 0, 0, 0, time.UTC)}
|
||||
if got := yearFromDate(d); got != 1997 {
|
||||
t.Errorf("yearFromDate = %d", got)
|
||||
}
|
||||
if got := yearFromDate(pgtype.Date{}); got != 0 {
|
||||
t.Errorf("yearFromDate(zero) = %d, want 0", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestamptzToRFC3339(t *testing.T) {
|
||||
ts := pgtype.Timestamptz{
|
||||
Valid: true,
|
||||
Time: time.Date(2026, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
}
|
||||
if got := timestamptzToRFC3339(ts); got != "2026-01-02T03:04:05Z" {
|
||||
t.Errorf("rfc3339 = %q", got)
|
||||
}
|
||||
if got := timestamptzToRFC3339(pgtype.Timestamptz{}); got != "" {
|
||||
t.Errorf("rfc3339(zero) = %q, want empty", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAtoiDefault(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
def int
|
||||
want int
|
||||
}{
|
||||
{"", 7, 7},
|
||||
{"42", 0, 42},
|
||||
{" 12 ", 0, 12},
|
||||
{"junk", 99, 99},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := atoiDefault(c.in, c.def); got != c.want {
|
||||
t.Errorf("atoiDefault(%q,%d) = %d, want %d", c.in, c.def, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClampInt(t *testing.T) {
|
||||
if got := clampInt(5, 1, 10); got != 5 {
|
||||
t.Errorf("in-range = %d", got)
|
||||
}
|
||||
if got := clampInt(-3, 1, 10); got != 1 {
|
||||
t.Errorf("below = %d", got)
|
||||
}
|
||||
if got := clampInt(99, 1, 10); got != 10 {
|
||||
t.Errorf("above = %d", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user