119 lines
4.8 KiB
Go
119 lines
4.8 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestHongguoCatalogContinuesAfterRestartWithoutReplacingHistory(t *testing.T) {
|
|
calls := map[string][]int{}
|
|
transport := func(request *http.Request) (*http.Response, error) {
|
|
if request.URL.Path != "/reading/distribution/category/landpage/v/" {
|
|
t.Errorf("unexpected catalog request: %s", request.URL.Path)
|
|
return rankingHTTPResponse(request, 404, ""), nil
|
|
}
|
|
var payload struct {
|
|
Offset int `json:"offset"`
|
|
Select struct {
|
|
Genre []string `json:"genre"`
|
|
} `json:"select_items"`
|
|
}
|
|
if err := json.NewDecoder(request.Body).Decode(&payload); err != nil || len(payload.Select.Genre) != 1 {
|
|
t.Errorf("invalid catalog payload: %v", err)
|
|
return rankingHTTPResponse(request, 400, ""), nil
|
|
}
|
|
genre := payload.Select.Genre[0]
|
|
index := -1
|
|
for position, candidate := range hongguoAppGenres {
|
|
if candidate.key == genre {
|
|
index = position
|
|
}
|
|
}
|
|
if index < 0 || payload.Offset != 0 && payload.Offset != 18 {
|
|
t.Errorf("unknown feed or incorrect continuation: %s %d", genre, payload.Offset)
|
|
return rankingHTTPResponse(request, 400, ""), nil
|
|
}
|
|
calls[genre] = append(calls[genre], payload.Offset)
|
|
id := strconv.Itoa(700000 + index*100 + payload.Offset)
|
|
body, _ := json.Marshal(map[string]any{"data": map[string]any{
|
|
"next_offset": payload.Offset + 18, "session_id": "fixture-" + genre, "has_more": payload.Offset == 0,
|
|
"video_data": []any{map[string]any{
|
|
"series_id": id, "series_title": fmt.Sprintf("目录剧 %s", id), "series_cover": coverAddressFixture, "first_visible_time": "1773662280", "hot_score": "20019", "series_play_cnt": "0",
|
|
}},
|
|
}})
|
|
return rankingHTTPResponse(request, 200, string(body)), nil
|
|
}
|
|
first := rankingTestDownloader(t, transport)
|
|
first.cfg.MaxPagesPerSort = 1
|
|
initial, err := first.RefreshDramas(context.Background(), sourceHongguo)
|
|
if err != nil || len(initial) != len(hongguoAppGenres) {
|
|
t.Fatalf("first catalog batch: %d, %v", len(initial), err)
|
|
}
|
|
cache, err := readLibraryCache(first.cfg.dataDirectory())
|
|
if err != nil || !hongguoCatalogInitialized(cache.HongguoApp) || !hongguoCatalogHasMore(cache.HongguoApp) {
|
|
t.Fatalf("catalog checkpoint was not persisted: %v", err)
|
|
}
|
|
second := rankingTestDownloader(t, transport)
|
|
second.cfg.dataDir = first.cfg.dataDirectory()
|
|
second.cfg.MaxPagesPerSort = 1
|
|
continued, err := second.RefreshDramas(context.WithValue(context.Background(), libraryMoreKey{}, true), sourceHongguo)
|
|
if err != nil || len(continued) != 2*len(initial) || hongguoCatalogHasMore(second.hongguoCatalogSnapshot()) {
|
|
t.Fatalf("continuation lost history or pagination: %d, %v", len(continued), err)
|
|
}
|
|
for _, genre := range hongguoAppGenres {
|
|
offsets := calls[genre.key]
|
|
if len(offsets) != 2 || offsets[0] != 0 || offsets[1] != 18 {
|
|
t.Errorf("feed %s restarted instead of continuing: %v", genre.key, offsets)
|
|
}
|
|
}
|
|
for _, old := range initial {
|
|
found := false
|
|
for _, drama := range continued {
|
|
if drama.ID == old.ID {
|
|
found = true
|
|
if drama.OnlineDate != old.OnlineDate || drama.Heat != old.Heat || drama.Views != "0" {
|
|
t.Error("continuation lost primary sort fields")
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Errorf("lost cached drama %s", old.ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHongguoAppDetailAndCompatibleMediaMetadata(t *testing.T) {
|
|
detail := map[string]any{
|
|
"series_id": "700001", "series_title": "详情测试", "episode_cnt": 2,
|
|
"video_list": []any{
|
|
map[string]any{"vid": "800002", "vid_index": 2, "series_id": "700001"},
|
|
map[string]any{"vid": "800001", "vid_index": 1, "series_id": "700001"},
|
|
},
|
|
}
|
|
result := map[string]any{"data": map[string]any{"video_data": detail}}
|
|
entry, err := parseHongguoAppDetail(result, "700001")
|
|
if err != nil || len(entry.Chapters) != 2 || entry.Chapters[0].VideoURL != "hongguo-cenc://800001" {
|
|
t.Fatalf("complete detail did not preserve episode order: %v", err)
|
|
}
|
|
if _, err := parseHongguoAppDetail(result, "700002"); err == nil {
|
|
t.Fatal("accepted another drama's episodes")
|
|
}
|
|
detail["episode_cnt"] = 3
|
|
if _, err := parseHongguoAppDetail(result, "700001"); err == nil {
|
|
t.Fatal("accepted an incomplete episode list")
|
|
}
|
|
model := map[string]any{"video_list": []any{
|
|
map[string]any{"main_url": "https://media.example.test/high.mp4", "video_meta": map[string]any{"codec_type": "bytevc2", "definition": "2160p"}},
|
|
map[string]any{"main_url": "https://media.example.test/low.mp4", "video_meta": map[string]any{"codec_type": "h264", "definition": "720p"}},
|
|
map[string]any{"main_url": "https://media.example.test/compatible.mp4", "video_meta": map[string]any{"codec_type": "hevc", "definition": "1080p"}},
|
|
}}
|
|
media, err := selectHongguoAppMedia(model)
|
|
if err != nil || media.URL != "https://media.example.test/compatible.mp4" {
|
|
t.Fatalf("wrong compatible media choice: %v", err)
|
|
}
|
|
}
|