@@ -4,7 +4,10 @@ import (
44 "bytes"
55 "context"
66 "errors"
7+ "io"
8+ "net/http"
79 "os"
10+ "strings"
811 "testing"
912 "time"
1013
@@ -40,10 +43,11 @@ func captureProfilesOutput(t *testing.T) *bytes.Buffer {
4043
4144// FakeProfilesService implements ProfilesService
4245type FakeProfilesService struct {
43- GetFunc func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* kernel.Profile , error )
44- ListFunc func (ctx context.Context , opts ... option.RequestOption ) (* []kernel.Profile , error )
45- DeleteFunc func (ctx context.Context , idOrName string , opts ... option.RequestOption ) error
46- NewFunc func (ctx context.Context , body kernel.ProfileNewParams , opts ... option.RequestOption ) (* kernel.Profile , error )
46+ GetFunc func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* kernel.Profile , error )
47+ ListFunc func (ctx context.Context , opts ... option.RequestOption ) (* []kernel.Profile , error )
48+ DeleteFunc func (ctx context.Context , idOrName string , opts ... option.RequestOption ) error
49+ NewFunc func (ctx context.Context , body kernel.ProfileNewParams , opts ... option.RequestOption ) (* kernel.Profile , error )
50+ DownloadFunc func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error )
4751}
4852
4953func (f * FakeProfilesService ) Get (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* kernel.Profile , error ) {
@@ -65,6 +69,12 @@ func (f *FakeProfilesService) Delete(ctx context.Context, idOrName string, opts
6569 }
6670 return nil
6771}
72+ func (f * FakeProfilesService ) Download (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
73+ if f .DownloadFunc != nil {
74+ return f .DownloadFunc (ctx , idOrName , opts ... )
75+ }
76+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader ("" )), Header : http.Header {}}, nil
77+ }
6878func (f * FakeProfilesService ) New (ctx context.Context , body kernel.ProfileNewParams , opts ... option.RequestOption ) (* kernel.Profile , error ) {
6979 if f .NewFunc != nil {
7080 return f .NewFunc (ctx , body , opts ... )
@@ -141,8 +151,9 @@ func TestProfilesCreate_Error(t *testing.T) {
141151
142152func TestProfilesDelete_ConfirmNotFound (t * testing.T ) {
143153 buf := captureProfilesOutput (t )
144- rows := []kernel.Profile {{ID : "a" }}
145- fake := & FakeProfilesService {ListFunc : func (ctx context.Context , opts ... option.RequestOption ) (* []kernel.Profile , error ) { return & rows , nil }}
154+ fake := & FakeProfilesService {GetFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* kernel.Profile , error ) {
155+ return nil , & kernel.Error {StatusCode : http .StatusNotFound }
156+ }}
146157 p := ProfilesCmd {profiles : fake }
147158 _ = p .Delete (context .Background (), ProfilesDeleteInput {Identifier : "missing" })
148159 assert .Contains (t , buf .String (), "not found" )
@@ -155,3 +166,87 @@ func TestProfilesDelete_SkipConfirm(t *testing.T) {
155166 _ = p .Delete (context .Background (), ProfilesDeleteInput {Identifier : "a" , SkipConfirm : true })
156167 assert .Contains (t , buf .String (), "Deleted profile: a" )
157168}
169+
170+ func TestProfilesDownload_MissingOutput (t * testing.T ) {
171+ buf := captureProfilesOutput (t )
172+ fake := & FakeProfilesService {DownloadFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
173+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader ("content" )), Header : http.Header {}}, nil
174+ }}
175+ p := ProfilesCmd {profiles : fake }
176+ _ = p .Download (context .Background (), ProfilesDownloadInput {Identifier : "p1" , Output : "" , Pretty : false })
177+ assert .Contains (t , buf .String (), "Missing --to output file path" )
178+ }
179+
180+ func TestProfilesDownload_RawSuccess (t * testing.T ) {
181+ buf := captureProfilesOutput (t )
182+ f , err := os .CreateTemp ("" , "profile-*.zip" )
183+ assert .NoError (t , err )
184+ name := f .Name ()
185+ _ = f .Close ()
186+ defer os .Remove (name )
187+
188+ content := "hello"
189+ fake := & FakeProfilesService {DownloadFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
190+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader (content )), Header : http.Header {}}, nil
191+ }}
192+ p := ProfilesCmd {profiles : fake }
193+ _ = p .Download (context .Background (), ProfilesDownloadInput {Identifier : "p1" , Output : name , Pretty : false })
194+
195+ b , readErr := os .ReadFile (name )
196+ assert .NoError (t , readErr )
197+ assert .Equal (t , content , string (b ))
198+ assert .Contains (t , buf .String (), "Saved profile to " + name )
199+ }
200+
201+ func TestProfilesDownload_PrettySuccess (t * testing.T ) {
202+ f , err := os .CreateTemp ("" , "profile-*.json" )
203+ assert .NoError (t , err )
204+ name := f .Name ()
205+ _ = f .Close ()
206+ defer os .Remove (name )
207+
208+ jsonBody := "{\" a\" :1}"
209+ fake := & FakeProfilesService {DownloadFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
210+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader (jsonBody )), Header : http.Header {}}, nil
211+ }}
212+ p := ProfilesCmd {profiles : fake }
213+ _ = p .Download (context .Background (), ProfilesDownloadInput {Identifier : "p1" , Output : name , Pretty : true })
214+
215+ b , readErr := os .ReadFile (name )
216+ assert .NoError (t , readErr )
217+ out := string (b )
218+ assert .Contains (t , out , "\n " )
219+ assert .Contains (t , out , "\" a\" : 1" )
220+ }
221+
222+ func TestProfilesDownload_PrettyEmptyBody (t * testing.T ) {
223+ buf := captureProfilesOutput (t )
224+ f , err := os .CreateTemp ("" , "profile-*.json" )
225+ assert .NoError (t , err )
226+ name := f .Name ()
227+ _ = f .Close ()
228+ defer os .Remove (name )
229+
230+ fake := & FakeProfilesService {DownloadFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
231+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader ("" )), Header : http.Header {}}, nil
232+ }}
233+ p := ProfilesCmd {profiles : fake }
234+ _ = p .Download (context .Background (), ProfilesDownloadInput {Identifier : "p1" , Output : name , Pretty : true })
235+ assert .Contains (t , buf .String (), "Empty response body" )
236+ }
237+
238+ func TestProfilesDownload_PrettyInvalidJSON (t * testing.T ) {
239+ buf := captureProfilesOutput (t )
240+ f , err := os .CreateTemp ("" , "profile-*.json" )
241+ assert .NoError (t , err )
242+ name := f .Name ()
243+ _ = f .Close ()
244+ defer os .Remove (name )
245+
246+ fake := & FakeProfilesService {DownloadFunc : func (ctx context.Context , idOrName string , opts ... option.RequestOption ) (* http.Response , error ) {
247+ return & http.Response {StatusCode : 200 , Body : io .NopCloser (strings .NewReader ("not json" )), Header : http.Header {}}, nil
248+ }}
249+ p := ProfilesCmd {profiles : fake }
250+ _ = p .Download (context .Background (), ProfilesDownloadInput {Identifier : "p1" , Output : name , Pretty : true })
251+ assert .Contains (t , buf .String (), "Failed to pretty-print JSON" )
252+ }
0 commit comments