151 lines
4.1 KiB
Go
151 lines
4.1 KiB
Go
package playback
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"mal/internal/db"
|
|
"mal/internal/domain"
|
|
)
|
|
|
|
type wantSkipSegment struct {
|
|
segmentType string
|
|
start float64
|
|
end float64
|
|
source string
|
|
}
|
|
|
|
func TestFetchSkipSegmentsFallsBackToOverridesWhenAniSkipFails(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := &playbackService{
|
|
repo: &skipSegmentRepo{
|
|
hasTable: true,
|
|
overrides: []db.SkipSegmentOverrideRow{{
|
|
UserID: "user-1",
|
|
AnimeID: 2167,
|
|
Episode: 13,
|
|
SkipType: "op",
|
|
StartTime: 90,
|
|
EndTime: 180,
|
|
}},
|
|
},
|
|
httpClient: &http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: http.StatusInternalServerError,
|
|
Body: io.NopCloser(strings.NewReader("")),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
})},
|
|
}
|
|
|
|
got, err := svc.fetchSkipSegments(context.Background(), "user-1", 2167, "13")
|
|
if err != nil {
|
|
t.Fatalf("fetchSkipSegments returned error with local fallback: %v", err)
|
|
}
|
|
if len(got) != 1 {
|
|
t.Fatalf("len(got) = %d, want 1", len(got))
|
|
}
|
|
assertSkipSegment(t, got[0], wantSkipSegment{segmentType: "opening", start: 90, end: 180, source: "override"})
|
|
}
|
|
|
|
func TestFetchSkipSegmentsReturnsAniSkipErrorWhenNoOverrideFallbackExists(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := &playbackService{
|
|
repo: &skipSegmentRepo{hasTable: true},
|
|
httpClient: &http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: http.StatusInternalServerError,
|
|
Body: io.NopCloser(strings.NewReader("")),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
})},
|
|
}
|
|
|
|
got, err := svc.fetchSkipSegments(context.Background(), "user-1", 2167, "13")
|
|
if err == nil {
|
|
t.Fatal("fetchSkipSegments returned nil error without local fallback")
|
|
}
|
|
if got != nil {
|
|
t.Fatalf("got segments = %+v, want nil", got)
|
|
}
|
|
if !strings.Contains(err.Error(), "aniskip: unexpected status: 500") {
|
|
t.Fatalf("err = %v, want ani-skip status context", err)
|
|
}
|
|
}
|
|
|
|
func TestFetchSkipSegmentsMergesOverridesWhenAniSkipSucceeds(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := &playbackService{
|
|
repo: &skipSegmentRepo{
|
|
hasTable: true,
|
|
overrides: []db.SkipSegmentOverrideRow{{
|
|
UserID: "user-1",
|
|
AnimeID: 2167,
|
|
Episode: 13,
|
|
SkipType: "op",
|
|
StartTime: 95,
|
|
EndTime: 185,
|
|
}},
|
|
},
|
|
httpClient: &http.Client{Transport: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: http.StatusOK,
|
|
Body: io.NopCloser(strings.NewReader(`{
|
|
"found": true,
|
|
"results": [
|
|
{"skip_type": "op", "interval": {"start_time": 80, "end_time": 170}},
|
|
{"skip_type": "ed", "interval": {"start_time": 1300, "end_time": 1390}}
|
|
]
|
|
}`)),
|
|
Header: make(http.Header),
|
|
}, nil
|
|
})},
|
|
}
|
|
|
|
got, err := svc.fetchSkipSegments(context.Background(), "user-1", 2167, "13")
|
|
if err != nil {
|
|
t.Fatalf("fetchSkipSegments returned error: %v", err)
|
|
}
|
|
if len(got) != 2 {
|
|
t.Fatalf("len(got) = %d, want 2", len(got))
|
|
}
|
|
assertSkipSegment(t, got[0], wantSkipSegment{segmentType: "opening", start: 95, end: 185, source: "override"})
|
|
assertSkipSegment(t, got[1], wantSkipSegment{segmentType: "ending", start: 1300, end: 1390, source: "aniskip"})
|
|
}
|
|
|
|
func assertSkipSegment(t *testing.T, got domain.SkipSegment, want wantSkipSegment) {
|
|
t.Helper()
|
|
|
|
if got.Type != want.segmentType || got.Start != want.start || got.End != want.end || got.Source != want.source {
|
|
t.Fatalf("got segment = %+v, want type=%q start=%v end=%v source=%q", got, want.segmentType, want.start, want.end, want.source)
|
|
}
|
|
}
|
|
|
|
type roundTripFunc func(*http.Request) (*http.Response, error)
|
|
|
|
func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
return f(req)
|
|
}
|
|
|
|
type skipSegmentRepo struct {
|
|
domain.PlaybackRepository
|
|
hasTable bool
|
|
hasErr error
|
|
overrides []db.SkipSegmentOverrideRow
|
|
listErr error
|
|
}
|
|
|
|
func (r *skipSegmentRepo) HasSkipSegmentOverrideTable(context.Context) (bool, error) {
|
|
return r.hasTable, r.hasErr
|
|
}
|
|
|
|
func (r *skipSegmentRepo) ListSkipSegmentOverrides(context.Context, string, int64, int64) ([]db.SkipSegmentOverrideRow, error) {
|
|
return r.overrides, r.listErr
|
|
}
|