11package cmd
22
33import (
4+ "bytes"
45 "context"
56 "errors"
7+ "fmt"
8+ "io/ioutil"
9+ "net/http"
10+ "os"
11+ "path"
612 "testing"
13+ "time"
714
15+ "github.com/golang/mock/gomock"
16+ "github.com/linuxsuren/http-downloader/mock/mhttp"
817 "github.com/linuxsuren/http-downloader/pkg/installer"
918 "github.com/spf13/cobra"
1019 "github.com/stretchr/testify/assert"
@@ -26,6 +35,8 @@ func Test_newGetCmd(t *testing.T) {
2635 name : "time" ,
2736 }, {
2837 name : "max-attempts" ,
38+ }, {
39+ name : "no-proxy" ,
2940 }, {
3041 name : "show-progress" ,
3142 }, {
@@ -97,12 +108,127 @@ func TestPreRunE(t *testing.T) {
97108}
98109
99110func TestRunE (t * testing.T ) {
100- fakeCmd := & cobra.Command {}
101-
102- opt := & downloadOption {}
103- opt .fetcher = & installer.FakeFetcher {}
104-
105- // print schema
106- opt .PrintSchema = true
107- assert .Nil (t , opt .runE (fakeCmd , nil ))
111+ tests := []struct {
112+ name string
113+ opt * downloadOption
114+ args []string
115+ prepare func (t * testing.T , do * downloadOption )
116+ wantErr bool
117+ }{{
118+ name : "print shcema only" ,
119+ opt : & downloadOption {
120+ fetcher : & installer.FakeFetcher {},
121+ PrintSchema : true ,
122+ },
123+ wantErr : false ,
124+ }, {
125+ name : "download from an URL with one thread" ,
126+ opt : & downloadOption {
127+ fetcher : & installer.FakeFetcher {},
128+ NoProxy : true ,
129+ },
130+ prepare : func (t * testing.T , do * downloadOption ) {
131+ do .Output = path .Join (os .TempDir (), fmt .Sprintf ("fake-%d" , time .Now ().Nanosecond ()))
132+ do .URL = "https://foo.com"
133+
134+ ctrl := gomock .NewController (t )
135+ roundTripper := mhttp .NewMockRoundTripper (ctrl )
136+
137+ mockRequest , _ := http .NewRequest (http .MethodGet , do .URL , nil )
138+ mockResponse := & http.Response {
139+ StatusCode : http .StatusPartialContent ,
140+ Proto : "HTTP/1.1" ,
141+ Request : mockRequest ,
142+ Header : map [string ][]string {
143+ "Content-Length" : {"100" },
144+ },
145+ Body : ioutil .NopCloser (bytes .NewBufferString ("responseBody" )),
146+ }
147+ roundTripper .EXPECT ().
148+ RoundTrip (mockRequest ).Return (mockResponse , nil )
149+ do .RoundTripper = roundTripper
150+ },
151+ wantErr : false ,
152+ }, {
153+ name : "download from an URL with multi-threads" ,
154+ opt : & downloadOption {
155+ fetcher : & installer.FakeFetcher {},
156+ NoProxy : true ,
157+ Thread : 2 ,
158+ },
159+ prepare : func (t * testing.T , do * downloadOption ) {
160+ do .Output = path .Join (os .TempDir (), fmt .Sprintf ("fake-%d" , time .Now ().Nanosecond ()))
161+ do .URL = "https://foo.com"
162+
163+ ctrl := gomock .NewController (t )
164+ roundTripper := mhttp .NewMockRoundTripper (ctrl )
165+
166+ // for size detecting
167+ mockRequest , _ := http .NewRequest (http .MethodGet , do .URL , nil )
168+ mockRequest .Header .Set ("Range" , "bytes=2-" )
169+ mockResponse := & http.Response {
170+ StatusCode : http .StatusPartialContent ,
171+ Proto : "HTTP/1.1" ,
172+ Request : mockRequest ,
173+ Header : map [string ][]string {
174+ "Content-Length" : {"100" },
175+ },
176+ Body : ioutil .NopCloser (bytes .NewBufferString ("responseBody" )),
177+ }
178+ roundTripper .EXPECT ().
179+ RoundTrip (mockRequest ).Return (mockResponse , nil )
180+
181+ // for group-1
182+ mockRequest1 , _ := http .NewRequest (http .MethodGet , do .URL , nil )
183+ mockRequest1 .Header .Set ("Range" , "bytes=0-50" )
184+ mockResponse1 := & http.Response {
185+ StatusCode : http .StatusPartialContent ,
186+ Proto : "HTTP/1.1" ,
187+ Request : mockRequest1 ,
188+ Header : map [string ][]string {
189+ "Content-Length" : {"100" },
190+ },
191+ Body : ioutil .NopCloser (bytes .NewBufferString ("responseBody" )),
192+ }
193+ roundTripper .EXPECT ().
194+ RoundTrip (mockRequest1 ).Return (mockResponse1 , nil )
195+
196+ // for group-2
197+ mockRequest2 , _ := http .NewRequest (http .MethodGet , do .URL , nil )
198+ mockRequest2 .Header .Set ("Range" , "bytes=51-101" )
199+ mockResponse2 := & http.Response {
200+ StatusCode : http .StatusPartialContent ,
201+ Proto : "HTTP/1.1" ,
202+ Request : mockRequest2 ,
203+ Header : map [string ][]string {
204+ "Content-Length" : {"100" },
205+ },
206+ Body : ioutil .NopCloser (bytes .NewBufferString ("responseBody" )),
207+ }
208+ roundTripper .EXPECT ().
209+ RoundTrip (mockRequest2 ).Return (mockResponse2 , nil )
210+ do .RoundTripper = roundTripper
211+ },
212+ wantErr : false ,
213+ }}
214+ for i , tt := range tests {
215+ t .Run (tt .name , func (t * testing.T ) {
216+ fakeCmd := & cobra.Command {}
217+ fakeCmd .SetOut (new (bytes.Buffer ))
218+ if tt .prepare != nil {
219+ tt .prepare (t , tt .opt )
220+ }
221+ if tt .opt .Output != "" {
222+ defer func () {
223+ _ = os .RemoveAll (tt .opt .Output )
224+ }()
225+ }
226+ err := tt .opt .runE (fakeCmd , tt .args )
227+ if tt .wantErr {
228+ assert .NotNil (t , err , "should error in [%d][%s]" , i , tt .name )
229+ } else {
230+ assert .Nil (t , err , "should not error in [%d][%s]" , i , tt .name )
231+ }
232+ })
233+ }
108234}
0 commit comments