Skip to content

Commit 720214e

Browse files
increasing test coverage
1 parent afdb4bc commit 720214e

File tree

2 files changed

+174
-1
lines changed

2 files changed

+174
-1
lines changed

cmd/card/setslist.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ type setData struct {
7171
Symbol string `json:"symbol"`
7272
}
7373

74+
// creating a function variable to swap the implementation in tests
75+
var getSetsData = callSetsData
76+
7477
func SetsList(seriesID string) (SetsModel, error) {
75-
body, err := callSetsData("https://uoddayfnfkebrijlpfbh.supabase.co/rest/v1/sets")
78+
body, err := getSetsData("https://uoddayfnfkebrijlpfbh.supabase.co/rest/v1/sets")
7679
if err != nil {
7780
return SetsModel{}, fmt.Errorf("error getting sets data: %v", err)
7881
}

cmd/card/setslist_test.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package card
22

33
import (
4+
"errors"
5+
"net/http"
6+
"net/http/httptest"
47
"strings"
58
"testing"
69

@@ -186,3 +189,170 @@ func TestSetsModel_Update_EnterKey(t *testing.T) {
186189
t.Error("Update with Enter should return tea.Quit command")
187190
}
188191
}
192+
193+
func TestCallSetsData_SendsHeadersAndReturnsBody(t *testing.T) {
194+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
195+
if got := r.Header.Get("apikey"); got != "sb_publishable_oondaaAIQC-wafhEiNgpSQ_reRiEp7j" {
196+
t.Fatalf("missing or wrong apikey header: %q", got)
197+
}
198+
if got := r.Header.Get("Authorization"); got != "Bearer sb_publishable_oondaaAIQC-wafhEiNgpSQ_reRiEp7j" {
199+
t.Fatalf("missing or wrong Authorization header: %q", got)
200+
}
201+
if got := r.Header.Get("Content-Type"); got != "application/json" {
202+
t.Fatalf("missing or wrong Content-Type header: %q", got)
203+
}
204+
205+
w.WriteHeader(http.StatusOK)
206+
_, _ = w.Write([]byte(`{"ok":true}`))
207+
}))
208+
defer srv.Close()
209+
210+
body, err := callSetsData(srv.URL)
211+
if err != nil {
212+
t.Fatalf("unexpected error: %v", err)
213+
}
214+
if string(body) != `{"ok":true}` {
215+
t.Fatalf("unexpected body: %s", string(body))
216+
}
217+
}
218+
219+
func TestCallSetsData_Non200Error(t *testing.T) {
220+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
221+
http.Error(w, "boom", http.StatusInternalServerError)
222+
}))
223+
defer srv.Close()
224+
225+
_, err := callSetsData(srv.URL)
226+
if err == nil {
227+
t.Fatal("expected error for non-200 status")
228+
}
229+
if !strings.Contains(err.Error(), "unexpected status code: 500") {
230+
t.Fatalf("error should mention status code, got: %v", err)
231+
}
232+
}
233+
234+
func TestCallSetsData_BadURL(t *testing.T) {
235+
_, err := callSetsData("http://%41:80/") // invalid URL host
236+
if err == nil {
237+
t.Fatal("expected error for bad URL")
238+
}
239+
}
240+
241+
func TestSetsList_Success(t *testing.T) {
242+
original := getSetsData
243+
defer func() { getSetsData = original }()
244+
245+
getSetsData = func(url string) ([]byte, error) {
246+
json := `[
247+
{"series_id":"sv","set_id":"sv01","set_name":"Scarlet & Violet","official_card_count":198,"total_card_count":258,"logo":"https://example.com/sv01.png","symbol":"https://example.com/sv01-symbol.png"},
248+
{"series_id":"sv","set_id":"sv02","set_name":"Paldea Evolved","official_card_count":193,"total_card_count":279,"logo":"https://example.com/sv02.png","symbol":"https://example.com/sv02-symbol.png"},
249+
{"series_id":"swsh","set_id":"swsh01","set_name":"Sword & Shield","official_card_count":202,"total_card_count":216,"logo":"https://example.com/swsh01.png","symbol":"https://example.com/swsh01-symbol.png"}
250+
]`
251+
return []byte(json), nil
252+
}
253+
254+
model, err := SetsList("sv")
255+
if err != nil {
256+
t.Fatalf("SetsList returned error: %v", err)
257+
}
258+
259+
// Should only have 2 sets (filtered by series_id "sv")
260+
if model.SeriesName != "sv" {
261+
t.Errorf("expected SeriesName 'sv', got %s", model.SeriesName)
262+
}
263+
264+
// Check setsIDMap has correct mappings
265+
if model.setsIDMap["Scarlet & Violet"] != "sv01" {
266+
t.Errorf("expected setsIDMap['Scarlet & Violet'] = 'sv01', got %s", model.setsIDMap["Scarlet & Violet"])
267+
}
268+
if model.setsIDMap["Paldea Evolved"] != "sv02" {
269+
t.Errorf("expected setsIDMap['Paldea Evolved'] = 'sv02', got %s", model.setsIDMap["Paldea Evolved"])
270+
}
271+
272+
// swsh set should not be in the map
273+
if _, exists := model.setsIDMap["Sword & Shield"]; exists {
274+
t.Error("Sword & Shield should not be in setsIDMap (different series)")
275+
}
276+
277+
if model.View() == "" {
278+
t.Error("model view should render")
279+
}
280+
}
281+
282+
func TestSetsList_FetchError(t *testing.T) {
283+
original := getSetsData
284+
defer func() { getSetsData = original }()
285+
286+
getSetsData = func(url string) ([]byte, error) {
287+
return nil, errors.New("network error")
288+
}
289+
290+
_, err := SetsList("sv")
291+
if err == nil {
292+
t.Fatal("expected error when fetch fails")
293+
}
294+
if !strings.Contains(err.Error(), "error getting sets data") {
295+
t.Errorf("error should mention 'error getting sets data', got: %v", err)
296+
}
297+
}
298+
299+
func TestSetsList_BadJSON(t *testing.T) {
300+
original := getSetsData
301+
defer func() { getSetsData = original }()
302+
303+
getSetsData = func(url string) ([]byte, error) {
304+
return []byte("not-json"), nil
305+
}
306+
307+
_, err := SetsList("sv")
308+
if err == nil {
309+
t.Fatal("expected error for bad JSON payload")
310+
}
311+
if !strings.Contains(err.Error(), "error parsing sets data") {
312+
t.Errorf("error should mention 'error parsing sets data', got: %v", err)
313+
}
314+
}
315+
316+
func TestSetsList_EmptyResult(t *testing.T) {
317+
original := getSetsData
318+
defer func() { getSetsData = original }()
319+
320+
getSetsData = func(url string) ([]byte, error) {
321+
return []byte("[]"), nil
322+
}
323+
324+
model, err := SetsList("sv")
325+
if err != nil {
326+
t.Fatalf("unexpected error: %v", err)
327+
}
328+
329+
if len(model.setsIDMap) != 0 {
330+
t.Errorf("expected empty setsIDMap, got %d entries", len(model.setsIDMap))
331+
}
332+
333+
if model.View() == "" {
334+
t.Error("expected view to render with empty data")
335+
}
336+
}
337+
338+
func TestSetsList_NoMatchingSeries(t *testing.T) {
339+
original := getSetsData
340+
defer func() { getSetsData = original }()
341+
342+
getSetsData = func(url string) ([]byte, error) {
343+
json := `[
344+
{"series_id":"swsh","set_id":"swsh01","set_name":"Sword & Shield","official_card_count":202,"total_card_count":216,"logo":"","symbol":""}
345+
]`
346+
return []byte(json), nil
347+
}
348+
349+
model, err := SetsList("sv")
350+
if err != nil {
351+
t.Fatalf("unexpected error: %v", err)
352+
}
353+
354+
// No sets match "sv" series
355+
if len(model.setsIDMap) != 0 {
356+
t.Errorf("expected empty setsIDMap when no series match, got %d entries", len(model.setsIDMap))
357+
}
358+
}

0 commit comments

Comments
 (0)