0.3.49
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/ponzischeme89/memby/server/internal/store"
|
||||
)
|
||||
|
||||
func readyReq(itemID, mediaType string) store.SurfacedReadyRequest {
|
||||
return store.SurfacedReadyRequest{MediaType: mediaType, ItemID: itemID, Title: itemID}
|
||||
}
|
||||
|
||||
func isStamped(t *testing.T, raw json.RawMessage) bool {
|
||||
t.Helper()
|
||||
var item struct {
|
||||
Ready bool `json:"MembyRequestReady"`
|
||||
Label string `json:"MembyRequestReadyLabel"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &item); err != nil {
|
||||
t.Fatalf("unmarshal: %v", err)
|
||||
}
|
||||
return item.Ready && item.Label == requestReadyLabel
|
||||
}
|
||||
|
||||
// The overwhelmingly common case: nobody is waiting on anything, so the row is untouched.
|
||||
func TestMergeRequestReadyNoArrivalsIsANoOp(t *testing.T) {
|
||||
items := []json.RawMessage{resumeItem(t, "film", "", "2026-08-01T20:00:00Z")}
|
||||
got := mergeRequestReady(items, nil, nil)
|
||||
if !equalIDs(mergedIDs(t, got), []string{"film"}) {
|
||||
t.Fatalf("ids = %v", mergedIDs(t, got))
|
||||
}
|
||||
if isStamped(t, got[0]) {
|
||||
t.Fatal("item stamped with no arrivals")
|
||||
}
|
||||
}
|
||||
|
||||
// An arrival not in the row is prepended and tagged.
|
||||
func TestMergeRequestReadyPrependsMissingTitle(t *testing.T) {
|
||||
items := []json.RawMessage{resumeItem(t, "film", "", "2026-08-01T20:00:00Z")}
|
||||
surfaced := []store.SurfacedReadyRequest{readyReq("new-movie", "movie")}
|
||||
fetched := map[string]json.RawMessage{
|
||||
"new-movie": continueRaw(t, map[string]any{"Id": "new-movie", "Type": "Movie"}),
|
||||
}
|
||||
|
||||
got := mergeRequestReady(items, surfaced, fetched)
|
||||
if want := []string{"new-movie", "film"}; !equalIDs(mergedIDs(t, got), want) {
|
||||
t.Fatalf("ids = %v, want %v", mergedIDs(t, got), want)
|
||||
}
|
||||
if !isStamped(t, got[0]) {
|
||||
t.Fatal("prepended card not stamped")
|
||||
}
|
||||
if isStamped(t, got[1]) {
|
||||
t.Fatal("existing card wrongly stamped")
|
||||
}
|
||||
}
|
||||
|
||||
// Newest arrival first when several are prepended (surfaced is ordered newest first).
|
||||
func TestMergeRequestReadyKeepsNewestArrivalFirst(t *testing.T) {
|
||||
items := []json.RawMessage{resumeItem(t, "film", "", "2026-08-01T20:00:00Z")}
|
||||
surfaced := []store.SurfacedReadyRequest{readyReq("newer", "movie"), readyReq("older", "movie")}
|
||||
fetched := map[string]json.RawMessage{
|
||||
"newer": continueRaw(t, map[string]any{"Id": "newer", "Type": "Movie"}),
|
||||
"older": continueRaw(t, map[string]any{"Id": "older", "Type": "Movie"}),
|
||||
}
|
||||
|
||||
got := mergedIDs(t, mergeRequestReady(items, surfaced, fetched))
|
||||
if want := []string{"newer", "older", "film"}; !equalIDs(got, want) {
|
||||
t.Fatalf("ids = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// A surfaced title already in Continue Watching — by its own id, or as the series an
|
||||
// episode belongs to — is tagged in place, never duplicated.
|
||||
func TestMergeRequestReadyTagsExistingCardInPlace(t *testing.T) {
|
||||
items := []json.RawMessage{
|
||||
resumeItem(t, "s1e3", "severance", "2026-08-06T19:00:00Z"),
|
||||
resumeItem(t, "the-film", "", "2026-08-01T20:00:00Z"),
|
||||
}
|
||||
surfaced := []store.SurfacedReadyRequest{
|
||||
readyReq("severance", "series"),
|
||||
readyReq("the-film", "movie"),
|
||||
}
|
||||
|
||||
got := mergeRequestReady(items, surfaced, nil)
|
||||
if want := []string{"s1e3", "the-film"}; !equalIDs(mergedIDs(t, got), want) {
|
||||
t.Fatalf("ids = %v, want %v", mergedIDs(t, got), want)
|
||||
}
|
||||
if !isStamped(t, got[0]) || !isStamped(t, got[1]) {
|
||||
t.Fatal("existing cards not tagged in place")
|
||||
}
|
||||
}
|
||||
|
||||
// A fetch that returned nothing for an arrival degrades to leaving it out rather than
|
||||
// inserting a blank card.
|
||||
func TestMergeRequestReadyDropsUnfetchableArrival(t *testing.T) {
|
||||
items := []json.RawMessage{resumeItem(t, "film", "", "2026-08-01T20:00:00Z")}
|
||||
surfaced := []store.SurfacedReadyRequest{readyReq("gone", "movie")}
|
||||
|
||||
got := mergeRequestReady(items, surfaced, map[string]json.RawMessage{})
|
||||
if !equalIDs(mergedIDs(t, got), []string{"film"}) {
|
||||
t.Fatalf("ids = %v", mergedIDs(t, got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestStampRequestReadyPreservesOtherFields(t *testing.T) {
|
||||
raw := continueRaw(t, map[string]any{"Id": "x", "Name": "Keep me", "Type": "Movie"})
|
||||
stamped := stampRequestReady(raw)
|
||||
var item struct {
|
||||
Name string `json:"Name"`
|
||||
Ready bool `json:"MembyRequestReady"`
|
||||
}
|
||||
if err := json.Unmarshal(stamped, &item); err != nil {
|
||||
t.Fatalf("unmarshal: %v", err)
|
||||
}
|
||||
if item.Name != "Keep me" || !item.Ready {
|
||||
t.Fatalf("stamp lost fields: %+v", item)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user