179 lines · 6.3 KB · Go
RawDownload
package cli import (	"context"	"strings"	"testing"	"time" 	"github.com/openclaw/gitcrawl/internal/store") func TestTUIRemainingActionAndErrorBranches(t *testing.T) {	thread := store.Thread{		ID: 1, Number: 10, Kind: "issue", State: "open", Title: "Thread title",		Body: "Body with https://example.com/docs", HTMLURL: "https://github.com/openclaw/openclaw/issues/10",		UpdatedAt: "2026-05-08T00:00:00Z",	}	cluster := store.ClusterSummary{		ID: 7, Source: store.ClusterSourceRun, StableSlug: "cluster-7", Status: "active",		Title: "Cluster title", RepresentativeNumber: 10, RepresentativeKind: "issue",		RepresentativeTitle: "Thread title", MemberCount: 1, UpdatedAt: "2026-05-08T00:00:00Z",	}	detail := store.ClusterDetail{		Cluster: cluster,		Members: []store.ClusterMemberDetail{{			Thread:      thread,			Role:        "member",			State:       "active",			BodySnippet: "Body with https://example.com/docs",			Summaries:   map[string]string{"problem_summary": "summary"},		}},	}	model := newClusterBrowserModel(context.Background(), nil, 0, clusterBrowserPayload{		Repository: "openclaw/openclaw",		Sort:       "size",		MinSize:    1,		Clusters:   []store.ClusterSummary{cluster},	})	model.detailCache[clusterSummaryKey(cluster)] = detail	model.loadSelectedCluster()	model.memberIndex = 0	model.neighborCache[thread.ID] = []tuiNeighbor{{Thread: thread, Score: 0.9}} 	for _, action := range []string{"sort-oldest", "member-sort-oldest", "toggle-closed", "close-menu"} {		if !model.runAction(action) {			t.Fatalf("action %s was not handled", action)		}	}	if model.payload.Sort != "oldest" || model.memberSort != memberSortOldest {		t.Fatalf("sort actions failed sort=%q member=%q", model.payload.Sort, model.memberSort)	} 	t.Setenv("PATH", "")	errorActions := []string{		"open-cluster-representative",		"copy-cluster-url",		"copy-thread-detail",		"copy-body-preview",		"copy-summaries",		"copy-neighbors",		"copy-cluster-id",		"copy-cluster-name",		"copy-cluster-title",		"copy-member-list",		"copy-cluster",		"copy-visible-clusters",		"copy-reference-links",		"open",		"copy-url",		"copy-markdown",		"copy-title",		"open-first-link",		"copy-first-link",	}	for _, action := range errorActions {		model.status = ""		handled := model.runMenuItem(tuiMenuItem{label: action, action: action, value: "https://example.com/docs"})		if !handled || model.status == "" {			t.Fatalf("error action %s handled=%v status=%q", action, handled, model.status)		}	}	model.openReferenceLinkMenu("copy")	model.runAction("back-to-actions")	if model.menuTitle != "Actions" {		t.Fatalf("back to actions failed title=%q", model.menuTitle)	}	model.runMenuItem(tuiMenuItem{label: "Open picked", action: "open-picked-link", value: "https://example.com/docs"})	model.runMenuItem(tuiMenuItem{label: "Copy picked", action: "copy-picked-link", value: "https://example.com/docs"}) 	model.closeSelectedClusterLocally()	if !strings.Contains(model.status, "only available for durable clusters") {		t.Fatalf("raw cluster local close status=%q", model.status)	}	model.reopenSelectedClusterLocally()	model.excludeSelectedClusterMemberLocally()	model.includeSelectedClusterMemberLocally()	model.setSelectedClusterCanonicalLocally()	if !strings.Contains(model.status, "only available for durable clusters") {		t.Fatalf("raw member local action status=%q", model.status)	}} func TestTUIRemainingHelperBranches(t *testing.T) {	model := newClusterBrowserModel(context.Background(), nil, 0, clusterBrowserPayload{		Repository: "openclaw/openclaw",		MinSize:    1,		Limit:      1,		Clusters: []store.ClusterSummary{			{ID: 1, Status: "active", RepresentativeNumber: 101, MemberCount: 1, UpdatedAt: "2026-05-08T00:00:00Z"},		},	})	if model.currentClusterID() != 1 {		t.Fatalf("current cluster id = %d", model.currentClusterID())	}	if model.clusterRefreshLimit() != 1 {		t.Fatalf("cluster refresh limit = %d", model.clusterRefreshLimit())	}	model.ensureClusterInWorkingSet(store.ClusterSummary{ID: 2, Status: "closed", ClosedAt: "2026-05-08T00:00:00Z", MemberCount: 2})	if !model.selectClusterIDForJump(2) || !model.showClosed || model.minSize != 1 {		t.Fatalf("jump selection showClosed=%v minSize=%d selected=%d", model.showClosed, model.minSize, model.selected)	}	model.payload.Clusters = nil	if model.currentClusterID() != 0 || model.clusterSignature() != "" {		t.Fatalf("empty cluster helpers id=%d sig=%q", model.currentClusterID(), model.clusterSignature())	}	if _, ok := model.clusterFromWorkingSet(999); ok {		t.Fatal("missing working-set cluster should not resolve")	}	model.applyClusterRefresh(nil, "")	if model.payload.Clusters == nil {		t.Fatal("nil refresh should normalize clusters")	}	model.autoRefreshFromStore()	if model.status != "Refresh unavailable for this view" {		t.Fatalf("auto refresh status=%q", model.status)	}	if cmd := model.autoRefreshCmd(); cmd != nil {		t.Fatalf("auto refresh command without store = %v", cmd)	}	model.switchRepository("")	if model.status != "Repository picker unavailable for this view" {		t.Fatalf("switch repository no store status=%q", model.status)	}	if label := (clusterBrowserModel{}).clusterPositionLabel(); label != "0" {		t.Fatalf("zero cluster position label = %q", label)	}	if label := model.clusterPositionLabel(); label != "0" {		t.Fatalf("empty model cluster position label = %q", label)	}	memberModel := model	memberModel.memberRows = []memberRow{}	if label := memberModel.memberPositionLabel(); label != "0" {		t.Fatalf("zero member position label = %q", label)	}	if got := formatRelativeTime(time.Now().Add(-30 * time.Minute).Format(time.RFC3339Nano)); got != "30m ago" {		t.Fatalf("minute age = %q", got)	}	if got := formatRelativeTime(time.Now().Add(-75 * 24 * time.Hour).Format(time.RFC3339Nano)); !strings.Contains(got, "mo ago") {		t.Fatalf("month age = %q", got)	}	if got := formatRelativeTime(""); got != "never" {		t.Fatalf("empty age = %q", got)	}	if got := formatRelativeTime("bad-time"); got != "bad-time" {		t.Fatalf("bad age = %q", got)	}	if got := wrapPlain("", 10); len(got) != 1 || got[0] != "" {		t.Fatalf("empty wrap = %+v", got)	}	if got := clampInt(5, 10, 1); got != 10 {		t.Fatalf("inverted clamp = %d", got)	}	if got := padCells("abcdef", 0); got != "" {		t.Fatalf("zero pad = %q", got)	}	if got := fitBlock("a\nb", 2, 1); got != "a " {		t.Fatalf("fit block = %q", got)	}}