test(subsonic): envelope JSON/XML/JSONP + WriteFail
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user