91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The two lists Emby answers with can name the same file, and the television renders the
|
|
// result into a keyed grid — which throws on a repeated key rather than merely looking
|
|
// wrong. First-seen order is kept, so the trailer stays at the front where the join put it.
|
|
func TestDedupeExtrasKeepsFirstOfEachID(t *testing.T) {
|
|
items := []json.RawMessage{
|
|
json.RawMessage(`{"Id":"trailer-1","Name":"Official Trailer","Type":"Trailer"}`),
|
|
json.RawMessage(`{"Id":"feature-1","Name":"Four Winters","Type":"Featurette"}`),
|
|
json.RawMessage(`{"Id":"trailer-1","Name":"Official Trailer","Type":"Trailer"}`),
|
|
json.RawMessage(`{"Id":"feature-2","Name":"Deleted: The Crossing","Type":"DeletedScene"}`),
|
|
}
|
|
|
|
got := dedupeExtras(items)
|
|
|
|
if len(got) != 3 {
|
|
t.Fatalf("expected 3 extras after deduplication, got %d", len(got))
|
|
}
|
|
ids := extraIDs(t, got)
|
|
want := []string{"trailer-1", "feature-1", "feature-2"}
|
|
for index, id := range want {
|
|
if ids[index] != id {
|
|
t.Fatalf("extra %d was %q, want %q (order: %v)", index, ids[index], id, ids)
|
|
}
|
|
}
|
|
}
|
|
|
|
// An entry the television could not key is dropped rather than passed on. Nothing
|
|
// downstream can tell one blank id from another.
|
|
func TestDedupeExtrasDropsUnidentifiableEntries(t *testing.T) {
|
|
items := []json.RawMessage{
|
|
json.RawMessage(`{"Name":"Nameless","Type":"Clip"}`),
|
|
json.RawMessage(`{"Id":"","Name":"Blank","Type":"Clip"}`),
|
|
json.RawMessage(`not json at all`),
|
|
json.RawMessage(`{"Id":"clip-1","Name":"A Clip","Type":"Clip"}`),
|
|
}
|
|
|
|
got := dedupeExtras(items)
|
|
|
|
if len(got) != 1 {
|
|
t.Fatalf("expected only the identified extra to survive, got %d", len(got))
|
|
}
|
|
if ids := extraIDs(t, got); ids[0] != "clip-1" {
|
|
t.Fatalf("survivor was %q, want clip-1", ids[0])
|
|
}
|
|
}
|
|
|
|
func TestDedupeExtrasOnNothing(t *testing.T) {
|
|
if got := dedupeExtras(nil); len(got) != 0 {
|
|
t.Fatalf("expected no extras, got %d", len(got))
|
|
}
|
|
}
|
|
|
|
// The Details tab is the only reader of these, and every one of them is absent from Emby's
|
|
// response unless it is asked for by name — so a field quietly dropped from the query is a
|
|
// row that silently stops appearing rather than anything that fails.
|
|
func TestDetailFieldsCarryTheDetailsTabVocabulary(t *testing.T) {
|
|
fields := make(map[string]bool)
|
|
for _, field := range strings.Split(fieldsDetail, ",") {
|
|
fields[field] = true
|
|
}
|
|
for _, required := range []string{
|
|
"Studios", "Taglines", "PremiereDate", "OriginalTitle", "ProductionLocations",
|
|
} {
|
|
if !fields[required] {
|
|
t.Errorf("detail responses must request %q for the Details tab", required)
|
|
}
|
|
}
|
|
}
|
|
|
|
func extraIDs(t *testing.T, items []json.RawMessage) []string {
|
|
t.Helper()
|
|
ids := make([]string, 0, len(items))
|
|
for _, raw := range items {
|
|
var identified struct {
|
|
ID string `json:"Id"`
|
|
}
|
|
if err := json.Unmarshal(raw, &identified); err != nil {
|
|
t.Fatalf("could not read back an extra: %v", err)
|
|
}
|
|
ids = append(ids, identified.ID)
|
|
}
|
|
return ids
|
|
}
|