package tui import ( "fmt" "net/http" "net/http/httptest" "strings" "testing" tea "charm.land/bubbletea/v2" "git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/cache" "git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox" ) func tuiSourceServer(t *testing.T, fail bool) *httptest.Server { t.Helper() srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if fail { http.Error(w, "offline", 503) return } if r.URL.Path == "/api/dcim/devices/" { fmt.Fprint(w, `{"count":1,"results":[{"id":1,"name":"web","primary_ip4":{"address":"10.0.0.1/24"}}]}`) } else { fmt.Fprint(w, `{"count":0,"results":[]}`) } })) t.Cleanup(srv.Close) return srv } func TestCombinedSearchDoesNotStopAtFirstCachedInstance(t *testing.T) { office, lab := tuiSourceServer(t, false), tuiSourceServer(t, false) client := netbox.NewMultiClient([]netbox.Source{{Name: "office", URL: office.URL}, {Name: "lab", URL: lab.URL}}) c := cache.New("", 3600) c.Upsert(cache.Entry{Name: "office/web", Kind: "device", IP: "10.0.0.9"}) m := New(client, c, "") msg := m.doSearch("web", 1)().(searchResultMsg) if msg.err != nil || len(msg.entries) != 2 { t.Fatalf("cache hid another instance: %+v, %v", msg.entries, msg.err) } m.input.SetValue("web") m.seq = 1 m.Update(msg) if len(m.list.Items()) != 2 { t.Fatal("combined results not displayed") } for _, item := range m.list.Items() { if !strings.Contains(item.(hostItem).name, "/") { t.Fatal("instance not visible in results") } } m.list.Select(0) m.Update(tea.KeyPressMsg{Code: tea.KeyEnter}) if m.selected == nil || m.selected.Name != "lab/web" { t.Fatalf("selection lost source: %+v", m.selected) } } func TestPartialOutageKeepsLiveAndCachedResultsVisible(t *testing.T) { office, lab := tuiSourceServer(t, false), tuiSourceServer(t, true) client := netbox.NewMultiClient([]netbox.Source{{Name: "office", URL: office.URL}, {Name: "lab", URL: lab.URL}}) c := cache.New("", 3600) c.Upsert(cache.Entry{Name: "lab/web", Kind: "device", IP: "10.0.0.2"}) m := New(client, c, "") m.input.SetValue("web") m.seq = 1 m.Update(tea.WindowSizeMsg{Width: 100, Height: 24}) msg := m.doSearch("web", 1)().(searchResultMsg) if len(msg.entries) != 2 || msg.err == nil { t.Fatalf("partial outage lost cache or warning: %+v, %v", msg.entries, msg.err) } m.Update(msg) view := m.View().Content if !strings.Contains(view, "warning:") || !strings.Contains(view, "lab/web") || !strings.Contains(view, "office/web") { t.Fatalf("partial results hidden: %s", view) } if rows := strings.Count(view, "\n"); rows > 24 { t.Fatalf("outage warning overflowed view: %d", rows) } }