From 2de1c8a4e66146afd58881acc85e5665035a46b1 Mon Sep 17 00:00:00 2001 From: Matías Insaurralde Date: Sat, 04 Apr 2026 02:25:13 +0000 Subject: [PATCH] appview/models: add tests for HasSearchFilters on all search option types Cover each filter field individually to guard against future additions that miss the boolean check. Also documents that non-filter fields (RepoAt, IsOpen, Knot, Did, State, Page) intentionally do not count as active filters. Signed-off-by: Matías Insaurralde --- appview/models/search_test.go | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file(s) changed, 224 insertion(s)(+), 0 deletion(s)(-) diff --git a/appview/models/search_test.go b/appview/models/search_test.go new file mode 100644 --- /dev/null +++ b/appview/models/search_test.go @@ -0,0 +1,224 @@ +package models + +import ( + "testing" +) + +func TestIssueSearchOptions_HasSearchFilters(t *testing.T) { + tests := []struct { + name string + opts IssueSearchOptions + want bool + }{ + { + name: "zero value returns false", + opts: IssueSearchOptions{}, + want: false, + }, + { + name: "non-filter fields only (RepoAt, IsOpen, Page) return false", + opts: IssueSearchOptions{RepoAt: "at://did:plc:abc/repo"}, + want: false, + }, + { + name: "keyword set", + opts: IssueSearchOptions{Keywords: []string{"bug"}}, + want: true, + }, + { + name: "phrase set", + opts: IssueSearchOptions{Phrases: []string{"null pointer"}}, + want: true, + }, + { + name: "author did set", + opts: IssueSearchOptions{AuthorDid: "did:plc:abc"}, + want: true, + }, + { + name: "label set", + opts: IssueSearchOptions{Labels: []string{"bug"}}, + want: true, + }, + { + name: "label value set", + opts: IssueSearchOptions{LabelValues: []string{"priority:high"}}, + want: true, + }, + { + name: "negated keyword set", + opts: IssueSearchOptions{NegatedKeywords: []string{"wontfix"}}, + want: true, + }, + { + name: "negated phrase set", + opts: IssueSearchOptions{NegatedPhrases: []string{"not a bug"}}, + want: true, + }, + { + name: "negated label set", + opts: IssueSearchOptions{NegatedLabels: []string{"duplicate"}}, + want: true, + }, + { + name: "negated label value set", + opts: IssueSearchOptions{NegatedLabelValues: []string{"priority:low"}}, + want: true, + }, + { + name: "negated author did set", + opts: IssueSearchOptions{NegatedAuthorDids: []string{"did:plc:xyz"}}, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.opts.HasSearchFilters(); got != tt.want { + t.Errorf("HasSearchFilters() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPullSearchOptions_HasSearchFilters(t *testing.T) { + tests := []struct { + name string + opts PullSearchOptions + want bool + }{ + { + name: "zero value returns false", + opts: PullSearchOptions{}, + want: false, + }, + { + name: "non-filter fields only (RepoAt, State, Page) return false", + opts: PullSearchOptions{RepoAt: "at://did:plc:abc/repo"}, + want: false, + }, + { + name: "keyword set", + opts: PullSearchOptions{Keywords: []string{"refactor"}}, + want: true, + }, + { + name: "phrase set", + opts: PullSearchOptions{Phrases: []string{"breaking change"}}, + want: true, + }, + { + name: "author did set", + opts: PullSearchOptions{AuthorDid: "did:plc:abc"}, + want: true, + }, + { + name: "label set", + opts: PullSearchOptions{Labels: []string{"enhancement"}}, + want: true, + }, + { + name: "label value set", + opts: PullSearchOptions{LabelValues: []string{"size:large"}}, + want: true, + }, + { + name: "negated keyword set", + opts: PullSearchOptions{NegatedKeywords: []string{"wip"}}, + want: true, + }, + { + name: "negated phrase set", + opts: PullSearchOptions{NegatedPhrases: []string{"do not merge"}}, + want: true, + }, + { + name: "negated label set", + opts: PullSearchOptions{NegatedLabels: []string{"blocked"}}, + want: true, + }, + { + name: "negated label value set", + opts: PullSearchOptions{NegatedLabelValues: []string{"size:small"}}, + want: true, + }, + { + name: "negated author did set", + opts: PullSearchOptions{NegatedAuthorDids: []string{"did:plc:xyz"}}, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.opts.HasSearchFilters(); got != tt.want { + t.Errorf("HasSearchFilters() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRepoSearchOptions_HasSearchFilters(t *testing.T) { + tests := []struct { + name string + opts RepoSearchOptions + want bool + }{ + { + name: "zero value returns false", + opts: RepoSearchOptions{}, + want: false, + }, + { + name: "non-filter fields only (Knot, Did, Page) return false", + opts: RepoSearchOptions{ + Knot: "knot.example.com", + Did: "did:plc:abc", + }, + want: false, + }, + { + name: "keyword set", + opts: RepoSearchOptions{Keywords: []string{"parser"}}, + want: true, + }, + { + name: "phrase set", + opts: RepoSearchOptions{Phrases: []string{"http client"}}, + want: true, + }, + { + name: "language set", + opts: RepoSearchOptions{Language: "Go"}, + want: true, + }, + { + name: "topic set", + opts: RepoSearchOptions{Topics: []string{"networking"}}, + want: true, + }, + { + name: "negated keyword set", + opts: RepoSearchOptions{NegatedKeywords: []string{"deprecated"}}, + want: true, + }, + { + name: "negated phrase set", + opts: RepoSearchOptions{NegatedPhrases: []string{"work in progress"}}, + want: true, + }, + { + name: "negated topic set", + opts: RepoSearchOptions{NegatedTopics: []string{"archived"}}, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.opts.HasSearchFilters(); got != tt.want { + t.Errorf("HasSearchFilters() = %v, want %v", got, tt.want) + } + }) + } +} -- tangled.sh