@@ -19,6 +19,12 @@ import (
1919 "github.com/stretchr/testify/require"
2020)
2121
22+ type roundTripFunc func (* http.Request ) (* http.Response , error )
23+
24+ func (fn roundTripFunc ) RoundTrip (req * http.Request ) (* http.Response , error ) {
25+ return fn (req )
26+ }
27+
2228func TestDownloadDirectHTTPWithClientDownloadsMockVideoAndTracksProgress (t * testing.T ) {
2329 payload := bytes .Repeat ([]byte ("goanime-video-payload" ), 32 * 1024 )
2430 server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
@@ -52,6 +58,160 @@ func TestDownloadDirectHTTPWithClientDownloadsMockVideoAndTracksProgress(t *test
5258 assert .Equal (t , int64 (len (payload )), received )
5359}
5460
61+ func TestDownloadPartAddsAllAnimeReferer (t * testing.T ) {
62+ payload := []byte ("goanime" )
63+ var gotReferer string
64+ var gotRange string
65+
66+ client := & http.Client {
67+ Transport : roundTripFunc (func (req * http.Request ) (* http.Response , error ) {
68+ gotReferer = req .Header .Get ("Referer" )
69+ gotRange = req .Header .Get ("Range" )
70+
71+ return & http.Response {
72+ StatusCode : http .StatusPartialContent ,
73+ Status : "206 Partial Content" ,
74+ Header : make (http.Header ),
75+ Body : io .NopCloser (bytes .NewReader (payload )),
76+ Request : req ,
77+ }, nil
78+ }),
79+ }
80+
81+ outPath := filepath .Join (t .TempDir (), "episode.mp4" )
82+ err := downloadPart (
83+ "https://allanime.day/video/episode.mp4" ,
84+ 0 ,
85+ int64 (len (payload )- 1 ),
86+ 0 ,
87+ client ,
88+ outPath ,
89+ & model {},
90+ )
91+ require .NoError (t , err )
92+ assert .Equal (t , "https://allanime.to" , gotReferer )
93+ assert .Equal (t , "bytes=0-6" , gotRange )
94+
95+ got , err := os .ReadFile (outPath + ".part0" )
96+ require .NoError (t , err )
97+ assert .Equal (t , payload , got )
98+ }
99+
100+ func TestGetContentLengthAddsAllAnimeReferer (t * testing.T ) {
101+ const contentLength = "12345"
102+ var gotMethod string
103+ var gotReferer string
104+
105+ client := & http.Client {
106+ Transport : roundTripFunc (func (req * http.Request ) (* http.Response , error ) {
107+ gotMethod = req .Method
108+ gotReferer = req .Header .Get ("Referer" )
109+
110+ header := make (http.Header )
111+ header .Set ("Content-Length" , contentLength )
112+
113+ return & http.Response {
114+ StatusCode : http .StatusOK ,
115+ Status : "200 OK" ,
116+ Header : header ,
117+ Body : io .NopCloser (strings .NewReader ("" )),
118+ Request : req ,
119+ }, nil
120+ }),
121+ }
122+
123+ got , err := getContentLength ("https://allanime.day/video/episode.mp4" , client )
124+ require .NoError (t , err )
125+ assert .Equal (t , int64 (12345 ), got )
126+ assert .Equal (t , http .MethodHead , gotMethod )
127+ assert .Equal (t , "https://allanime.to" , gotReferer )
128+ }
129+
130+ func TestGetContentLengthFallbackKeepsAllAnimeReferer (t * testing.T ) {
131+ var gotRequests []string
132+ var gotReferers []string
133+ var gotRanges []string
134+
135+ client := & http.Client {
136+ Transport : roundTripFunc (func (req * http.Request ) (* http.Response , error ) {
137+ gotRequests = append (gotRequests , req .Method )
138+ gotReferers = append (gotReferers , req .Header .Get ("Referer" ))
139+ gotRanges = append (gotRanges , req .Header .Get ("Range" ))
140+
141+ if req .Method == http .MethodHead {
142+ return & http.Response {
143+ StatusCode : http .StatusMethodNotAllowed ,
144+ Status : "405 Method Not Allowed" ,
145+ Header : make (http.Header ),
146+ Body : io .NopCloser (strings .NewReader ("" )),
147+ Request : req ,
148+ }, nil
149+ }
150+
151+ header := make (http.Header )
152+ header .Set ("Content-Length" , "1" )
153+
154+ return & http.Response {
155+ StatusCode : http .StatusPartialContent ,
156+ Status : "206 Partial Content" ,
157+ Header : header ,
158+ Body : io .NopCloser (strings .NewReader ("x" )),
159+ Request : req ,
160+ }, nil
161+ }),
162+ }
163+
164+ got , err := getContentLength ("https://allanime.pro/video/episode.mp4" , client )
165+ require .NoError (t , err )
166+ assert .Equal (t , int64 (1 ), got )
167+ assert .Equal (t , []string {http .MethodHead , http .MethodGet }, gotRequests )
168+ assert .Equal (t , []string {"https://allanime.to" , "https://allanime.to" }, gotReferers )
169+ assert .Equal (t , []string {"" , "bytes=0-0" }, gotRanges )
170+ }
171+
172+ func TestDownloadAnimeFireDirectWithFallbackSetsDefaultReferer (t * testing.T ) {
173+ restore := snapshotGlobalReferer ()
174+ defer restore ()
175+ util .ClearGlobalReferer ()
176+
177+ err := downloadAnimeFireDirectWithFallback (
178+ "https://animefire.io/video/show/20" ,
179+ "://invalid-download-url" ,
180+ filepath .Join (t .TempDir (), "episode.mp4" ),
181+ & model {},
182+ )
183+
184+ require .Error (t , err )
185+ assert .Equal (t , "https://animefire.io" , util .GetGlobalReferer ())
186+ }
187+
188+ func TestDownloadAnimeFireDirectWithFallbackKeepsExistingReferer (t * testing.T ) {
189+ restore := snapshotGlobalReferer ()
190+ defer restore ()
191+ util .SetGlobalReferer ("https://custom.example" )
192+
193+ err := downloadAnimeFireDirectWithFallback (
194+ "https://animefire.io/video/show/20" ,
195+ "://invalid-download-url" ,
196+ filepath .Join (t .TempDir (), "episode.mp4" ),
197+ & model {},
198+ )
199+
200+ require .Error (t , err )
201+ assert .Equal (t , "https://custom.example" , util .GetGlobalReferer ())
202+ }
203+
204+ func snapshotGlobalReferer () func () {
205+ referer := util .GetGlobalReferer ()
206+ return func () {
207+ if referer == "" {
208+ util .ClearGlobalReferer ()
209+ return
210+ }
211+ util .SetGlobalReferer (referer )
212+ }
213+ }
214+
55215func TestDownloadDirectHTTPWithClientReturnsHTTPStatusErrorFromMockCDN (t * testing.T ) {
56216 server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
57217 http .Error (w , "missing object" , http .StatusNotFound )
0 commit comments