102 lines
3.1 KiB
Go
102 lines
3.1 KiB
Go
package requests
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
type fakeNotifier struct {
|
||
|
|
requestIDs []string
|
||
|
|
contentIDs []string
|
||
|
|
err error
|
||
|
|
}
|
||
|
|
|
||
|
|
func (f *fakeNotifier) NotifyFulfilled(_ context.Context, req Request, contentID string) error {
|
||
|
|
if f.err != nil {
|
||
|
|
return f.err
|
||
|
|
}
|
||
|
|
f.requestIDs = append(f.requestIDs, req.ID)
|
||
|
|
f.contentIDs = append(f.contentIDs, contentID)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func completedRequestFixture(id string, tmdbID int) *Request {
|
||
|
|
return &Request{
|
||
|
|
ID: id,
|
||
|
|
MediaType: MediaTypeMovie,
|
||
|
|
TMDBID: tmdbID,
|
||
|
|
Title: "Fixture Movie",
|
||
|
|
Status: StatusCompleted,
|
||
|
|
Outcome: OutcomeActive,
|
||
|
|
RequestedByUserID: 7,
|
||
|
|
RequestedByProfileID: "profile-1",
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNotifyFulfilledPendingNotifiesAndMarks(t *testing.T) {
|
||
|
|
store := newFakeStore()
|
||
|
|
store.requests["req1"] = completedRequestFixture("req1", 42)
|
||
|
|
store.unnotified = []string{"req1"}
|
||
|
|
presence := &fakePresence{available: map[MediaType]map[int]bool{
|
||
|
|
MediaTypeMovie: {42: true},
|
||
|
|
}}
|
||
|
|
notifier := &fakeNotifier{}
|
||
|
|
service := NewService(store, &fakeTMDBClient{}, presence)
|
||
|
|
service.SetFulfillmentNotifier(notifier)
|
||
|
|
|
||
|
|
service.notifyFulfilledPending(context.Background())
|
||
|
|
|
||
|
|
if len(notifier.requestIDs) != 1 || notifier.requestIDs[0] != "req1" {
|
||
|
|
t.Fatalf("expected one notification for req1, got %v", notifier.requestIDs)
|
||
|
|
}
|
||
|
|
if want := fakePresenceContentID(MediaTypeMovie, 42); notifier.contentIDs[0] != want {
|
||
|
|
t.Fatalf("expected content id %q, got %q", want, notifier.contentIDs[0])
|
||
|
|
}
|
||
|
|
if len(store.notified) != 1 || store.notified[0] != "req1" {
|
||
|
|
t.Fatalf("expected req1 marked notified, got %v", store.notified)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNotifyFulfilledPendingWaitsForCatalogMatch(t *testing.T) {
|
||
|
|
store := newFakeStore()
|
||
|
|
store.requests["req1"] = completedRequestFixture("req1", 42)
|
||
|
|
store.unnotified = []string{"req1"}
|
||
|
|
notifier := &fakeNotifier{}
|
||
|
|
service := NewService(store, &fakeTMDBClient{}, &fakePresence{})
|
||
|
|
service.SetFulfillmentNotifier(notifier)
|
||
|
|
|
||
|
|
service.notifyFulfilledPending(context.Background())
|
||
|
|
|
||
|
|
if len(notifier.requestIDs) != 0 {
|
||
|
|
t.Fatalf("expected no notification before catalog match, got %v", notifier.requestIDs)
|
||
|
|
}
|
||
|
|
if len(store.notified) != 0 {
|
||
|
|
t.Fatalf("expected request to stay pending, got marked %v", store.notified)
|
||
|
|
}
|
||
|
|
if len(store.unnotified) != 1 {
|
||
|
|
t.Fatalf("expected request to remain in the pending set")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNotifyFulfilledPendingRetriesAfterNotifierError(t *testing.T) {
|
||
|
|
store := newFakeStore()
|
||
|
|
store.requests["req1"] = completedRequestFixture("req1", 42)
|
||
|
|
store.unnotified = []string{"req1"}
|
||
|
|
presence := &fakePresence{available: map[MediaType]map[int]bool{
|
||
|
|
MediaTypeMovie: {42: true},
|
||
|
|
}}
|
||
|
|
notifier := &fakeNotifier{err: errors.New("dispatch failed")}
|
||
|
|
service := NewService(store, &fakeTMDBClient{}, presence)
|
||
|
|
service.SetFulfillmentNotifier(notifier)
|
||
|
|
|
||
|
|
service.notifyFulfilledPending(context.Background())
|
||
|
|
|
||
|
|
if len(store.notified) != 0 {
|
||
|
|
t.Fatalf("a failed dispatch must not mark the request notified, got %v", store.notified)
|
||
|
|
}
|
||
|
|
if len(store.unnotified) != 1 {
|
||
|
|
t.Fatalf("expected request to remain pending for the next run")
|
||
|
|
}
|
||
|
|
}
|