102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package subsonic
|
|
|
|
import (
|
|
"encoding/json"
|
|
"encoding/xml"
|
|
"io"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestWriteJSONEnvelope(t *testing.T) {
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequest("GET", "/rest/ping.view", nil)
|
|
Write(rec, req, PingResponse{Envelope: NewEnvelope("ok")})
|
|
|
|
if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "application/json") {
|
|
t.Errorf("content-type = %q", ct)
|
|
}
|
|
var payload map[string]map[string]any
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
|
t.Fatalf("unmarshal: %v — body=%s", err, rec.Body)
|
|
}
|
|
inner, ok := payload["subsonic-response"]
|
|
if !ok {
|
|
t.Fatalf("missing subsonic-response key: %s", rec.Body)
|
|
}
|
|
if inner["status"] != "ok" || inner["version"] != APIVersion || inner["type"] != ServerType {
|
|
t.Errorf("envelope fields = %+v", inner)
|
|
}
|
|
if inner["openSubsonic"] != true {
|
|
t.Errorf("openSubsonic flag missing: %+v", inner)
|
|
}
|
|
}
|
|
|
|
func TestWriteXMLEnvelope(t *testing.T) {
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequest("GET", "/rest/getLicense.view?f=xml", nil)
|
|
Write(rec, req, LicenseResponse{
|
|
Envelope: NewEnvelope("ok"),
|
|
License: License{Valid: true},
|
|
})
|
|
|
|
if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "application/xml") {
|
|
t.Errorf("content-type = %q", ct)
|
|
}
|
|
body, _ := io.ReadAll(rec.Body)
|
|
var decoded struct {
|
|
XMLName xml.Name `xml:"subsonic-response"`
|
|
Status string `xml:"status,attr"`
|
|
Version string `xml:"version,attr"`
|
|
License struct {
|
|
Valid bool `xml:"valid,attr"`
|
|
} `xml:"license"`
|
|
}
|
|
if err := xml.Unmarshal(body, &decoded); err != nil {
|
|
t.Fatalf("xml decode: %v — body=%s", err, body)
|
|
}
|
|
if decoded.Status != "ok" || decoded.Version != APIVersion {
|
|
t.Errorf("envelope attrs = %+v", decoded)
|
|
}
|
|
if !decoded.License.Valid {
|
|
t.Errorf("license.valid attr not parsed: %+v", decoded)
|
|
}
|
|
}
|
|
|
|
func TestWriteFailEnvelopeJSON(t *testing.T) {
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequest("GET", "/rest/ping.view", nil)
|
|
WriteFail(rec, req, ErrWrongCredentials, "nope")
|
|
|
|
var payload map[string]map[string]any
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
inner := payload["subsonic-response"]
|
|
if inner["status"] != "failed" {
|
|
t.Errorf("status = %v, want failed", inner["status"])
|
|
}
|
|
errMap, ok := inner["error"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("error field missing/not object: %+v", inner)
|
|
}
|
|
if int(errMap["code"].(float64)) != ErrWrongCredentials {
|
|
t.Errorf("error.code = %v, want %d", errMap["code"], ErrWrongCredentials)
|
|
}
|
|
if errMap["message"] != "nope" {
|
|
t.Errorf("error.message = %v", errMap["message"])
|
|
}
|
|
}
|
|
|
|
func TestWriteJSONPWrapsCallback(t *testing.T) {
|
|
rec := httptest.NewRecorder()
|
|
req := httptest.NewRequest("GET", "/rest/ping.view?f=jsonp&callback=cb", nil)
|
|
Write(rec, req, PingResponse{Envelope: NewEnvelope("ok")})
|
|
|
|
body := rec.Body.String()
|
|
if !strings.HasPrefix(body, "cb(") || !strings.HasSuffix(strings.TrimSpace(body), ")") {
|
|
t.Errorf("jsonp wrapper missing: %q", body)
|
|
}
|
|
}
|