fork of https://github.com/sourcegraph/zoekt
1package json_test
2
3import (
4 "bytes"
5 "encoding/json"
6 "io"
7 "math"
8 "net/http"
9 "net/http/httptest"
10 "reflect"
11 "testing"
12
13 "github.com/sourcegraph/zoekt"
14 "github.com/sourcegraph/zoekt/internal/mockSearcher"
15 zjson "github.com/sourcegraph/zoekt/json"
16 "github.com/sourcegraph/zoekt/query"
17)
18
19func TestClientServer(t *testing.T) {
20 searchQuery := "\"hello world|universe\""
21 mock := &mockSearcher.MockSearcher{
22 WantSearch: mustParse(searchQuery),
23 SearchResult: &zoekt.SearchResult{
24 Files: []zoekt.FileMatch{
25 {FileName: "bin.go"},
26 },
27 },
28
29 WantList: &query.Const{Value: true},
30 RepoList: &zoekt.RepoList{
31 Repos: []*zoekt.RepoListEntry{
32 {
33 Repository: zoekt.Repository{
34 ID: 2,
35 Name: "foo/bar",
36 },
37 },
38 },
39 },
40 }
41
42 ts := httptest.NewServer(zjson.JSONServer(mock))
43 defer ts.Close()
44
45 searchBody, err := json.Marshal(struct{ Q string }{Q: searchQuery})
46 if err != nil {
47 t.Fatal(err)
48 }
49 r, err := http.Post(ts.URL+"/search", "application/json", bytes.NewBuffer(searchBody))
50 if err != nil {
51 t.Fatal(err)
52 }
53 if r.StatusCode != 200 {
54 body, _ := io.ReadAll(r.Body)
55 t.Fatalf("Got status code %d, err %s", r.StatusCode, string(body))
56 }
57
58 var searchResult struct{ Result *zoekt.SearchResult }
59 err = json.NewDecoder(r.Body).Decode(&searchResult)
60 if err != nil {
61 t.Fatal(err)
62 }
63 if !reflect.DeepEqual(searchResult.Result, mock.SearchResult) {
64 t.Fatalf("\na %+v\nb %+v", searchResult.Result, mock.SearchResult)
65 }
66
67 listBody, err := json.Marshal(struct{ Q string }{})
68 if err != nil {
69 t.Fatal(err)
70 }
71 r, err = http.Post(ts.URL+"/list", "application/json", bytes.NewBuffer((listBody)))
72 if err != nil {
73 t.Fatal(err)
74 }
75 if r.StatusCode != 200 {
76 body, _ := io.ReadAll(r.Body)
77 t.Fatalf("Got status code %d, err %s", r.StatusCode, string(body))
78 }
79
80 var listResult struct{ List *zoekt.RepoList }
81 err = json.NewDecoder(r.Body).Decode(&listResult)
82 if err != nil {
83 t.Fatal(err)
84 }
85 if !reflect.DeepEqual(listResult.List, mock.RepoList) {
86 t.Fatalf("got %+v, want %+v", listResult, mock.RepoList)
87 }
88}
89
90func TestClientServerWithRepoIDsProvided(t *testing.T) {
91 searchQuery := "hello"
92 expectedSearch := mustParse(searchQuery)
93 expectedSearch = query.NewAnd(expectedSearch, query.NewRepoIDs(1, 3, 5, 7))
94 mock := &mockSearcher.MockSearcher{
95 WantSearch: expectedSearch,
96 SearchResult: &zoekt.SearchResult{
97 Files: []zoekt.FileMatch{
98 {FileName: "bin.go"},
99 },
100 },
101 }
102
103 ts := httptest.NewServer(zjson.JSONServer(mock))
104 defer ts.Close()
105
106 searchBody := "{\"Q\":\"hello\",\"RepoIDs\":[1,3,5,7]}"
107
108 r, err := http.Post(ts.URL+"/search", "application/json", bytes.NewBufferString(searchBody))
109 if err != nil {
110 t.Fatal(err)
111 }
112 if r.StatusCode != 200 {
113 body, _ := io.ReadAll(r.Body)
114 t.Fatalf("Got status code %d, err %s", r.StatusCode, string(body))
115 }
116
117 var searchResult struct{ Result *zoekt.SearchResult }
118 err = json.NewDecoder(r.Body).Decode(&searchResult)
119 if err != nil {
120 t.Fatal(err)
121 }
122 if !reflect.DeepEqual(searchResult.Result, mock.SearchResult) {
123 t.Fatalf("\na %+v\nb %+v", searchResult.Result, mock.SearchResult)
124 }
125}
126
127func TestClientServerWithEmptyRepoIDsProvided(t *testing.T) {
128 searchQuery := "hello"
129 expectedSearch := mustParse(searchQuery)
130 expectedSearch = query.NewAnd(expectedSearch, query.NewRepoIDs())
131 mock := &mockSearcher.MockSearcher{
132 WantSearch: expectedSearch,
133 SearchResult: &zoekt.SearchResult{
134 Files: []zoekt.FileMatch{
135 {FileName: "bin.go"},
136 },
137 },
138 }
139
140 ts := httptest.NewServer(zjson.JSONServer(mock))
141 defer ts.Close()
142
143 searchBody := "{\"Q\":\"hello\",\"RepoIDs\":[]}"
144
145 r, err := http.Post(ts.URL+"/search", "application/json", bytes.NewBufferString(searchBody))
146 if err != nil {
147 t.Fatal(err)
148 }
149 if r.StatusCode != 200 {
150 body, _ := io.ReadAll(r.Body)
151 t.Fatalf("Got status code %d, err %s", r.StatusCode, string(body))
152 }
153
154 var searchResult struct{ Result *zoekt.SearchResult }
155 err = json.NewDecoder(r.Body).Decode(&searchResult)
156 if err != nil {
157 t.Fatal(err)
158 }
159 if !reflect.DeepEqual(searchResult.Result, mock.SearchResult) {
160 t.Fatalf("\na %+v\nb %+v", searchResult.Result, mock.SearchResult)
161 }
162}
163
164func TestProgressNotEncodedInSearch(t *testing.T) {
165 searchQuery := "hello"
166 mock := &mockSearcher.MockSearcher{
167 WantSearch: mustParse(searchQuery),
168 SearchResult: &zoekt.SearchResult{
169 // Validate that Progress is ignored as we cannot encode -Inf
170 Progress: zoekt.Progress{
171 Priority: math.Inf(-1),
172 MaxPendingPriority: math.Inf(-1),
173 },
174 Files: []zoekt.FileMatch{},
175 },
176 }
177
178 ts := httptest.NewServer(zjson.JSONServer(mock))
179 defer ts.Close()
180
181 searchBody, err := json.Marshal(struct{ Q string }{Q: searchQuery})
182 if err != nil {
183 t.Fatal(err)
184 }
185 r, err := http.Post(ts.URL+"/search", "application/json", bytes.NewBuffer(searchBody))
186 if err != nil {
187 t.Fatal(err)
188 }
189
190 if r.StatusCode != 200 {
191 body, _ := io.ReadAll(r.Body)
192 t.Fatalf("Got status code %d, err %s", r.StatusCode, string(body))
193 }
194}
195
196func mustParse(s string) query.Q {
197 q, err := query.Parse(s)
198 if err != nil {
199 panic(err)
200 }
201 return q
202}