package main import ( "bytes" "encoding/base64" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" ) func TestUnwrapJSONP(t *testing.T) { got := unwrapJSONP([]byte(" callback_1( {\"code\":0} ); ")) if string(got) != `{"code":0}` { t.Fatalf("unexpected JSONP body: %q", got) } } func TestQQClientMusicuLyricsRequestsTranslationAndPhonetics(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost || r.Header.Get("Content-Type") != "application/json" { t.Fatalf("unexpected request: %s %s", r.Method, r.Header.Get("Content-Type")) } var body struct { Request struct { Module string `json:"module"` Method string `json:"method"` Param struct { MID string `json:"songMID"` Trans int `json:"trans"` Roma int `json:"roma"` QRC int `json:"qrc"` } `json:"param"` } `json:"req_1"` } if err := json.NewDecoder(r.Body).Decode(&body); err != nil { t.Fatal(err) } if body.Request.Module != "music.musichallSong.PlayLyricInfo" || body.Request.Method != "GetPlayLyricInfo" || body.Request.Param.MID != "0004jPDk2eB2dt" { t.Fatalf("unexpected request body: %#v", body) } if body.Request.Param.Trans != 1 || body.Request.Param.Roma != 1 || body.Request.Param.QRC != 0 { t.Fatalf("required lyric variants were not requested: %#v", body.Request.Param) } lyric := base64.StdEncoding.EncodeToString([]byte("[00:01.00]原文")) trans := base64.StdEncoding.EncodeToString([]byte("[00:01.00]translation")) _, _ = w.Write([]byte(`{"code":0,"req_1":{"code":0,"data":{"lyric":"` + lyric + `","trans":"` + trans + `"}}}`)) })) defer server.Close() client := newQQClient() client.musicuEndpoint = server.URL result, err := client.musicuLyrics("0004jPDk2eB2dt") if err != nil { t.Fatal(err) } if result.Lyric != "[00:01.00]原文" || result.Trans != "[00:01.00]translation" { t.Fatalf("unexpected lyrics: %#v", result) } } func TestQQClientSearchUsesFixedShape(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Origin") != "https://y.qq.com" || r.Header.Get("Referer") != "https://y.qq.com/" { t.Fatal("required upstream headers were not set") } if r.URL.Query().Get("w") != "起风了" || r.URL.Query().Get("n") != "2" { t.Fatalf("unexpected query: %s", r.URL.RawQuery) } _, _ = w.Write([]byte(`{"code":0,"data":{"song":{"list":[{"songname":"歌","songmid":"0004jPDk2eB2dt","albumname":"专辑","interval":215,"singer":[{"name":"歌手"}]}]}}}`)) })) defer server.Close() client := newQQClient() client.searchEndpoint = server.URL songs, err := client.Search("起风了", 2) if err != nil { t.Fatal(err) } if len(songs) != 1 || songs[0].MID != "0004jPDk2eB2dt" || songs[0].Singer != "歌手" { t.Fatalf("unexpected songs: %#v", songs) } } func TestQQClientRejectsOversizedResponse(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write(bytes.Repeat([]byte("x"), maxUpstreamBytes+1)) })) defer server.Close() client := newQQClient() client.musicuEndpoint = server.URL _, err := client.musicuLyrics("0004jPDk2eB2dt") if err == nil || !strings.Contains(err.Error(), "safety limit") { t.Fatalf("expected response limit error, got %v", err) } }