Skip to content

Commit f5291c4

Browse files
committed
add tests
1 parent 9ef46dd commit f5291c4

File tree

1 file changed

+331
-0
lines changed

1 file changed

+331
-0
lines changed

pkg/response/optimize_test.go

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
package response
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestFlatten(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
input map[string]any
15+
expected map[string]any
16+
}{
17+
{
18+
name: "promotes primitive fields from nested map",
19+
input: map[string]any{
20+
"title": "fix bug",
21+
"user": map[string]any{
22+
"login": "user",
23+
"id": float64(1),
24+
},
25+
},
26+
expected: map[string]any{
27+
"title": "fix bug",
28+
"user.login": "user",
29+
"user.id": float64(1),
30+
},
31+
},
32+
{
33+
name: "discards non-primitive nested values",
34+
input: map[string]any{
35+
"user": map[string]any{
36+
"login": "user",
37+
"repos": []any{"repo1"},
38+
"org": map[string]any{"name": "org"},
39+
},
40+
},
41+
expected: map[string]any{
42+
"user.login": "user",
43+
},
44+
},
45+
}
46+
47+
for _, tc := range tests {
48+
t.Run(tc.name, func(t *testing.T) {
49+
result := flatten(tc.input)
50+
assert.Equal(t, tc.expected, result)
51+
})
52+
}
53+
}
54+
55+
func TestTrimArrayFields(t *testing.T) {
56+
original := collectionFieldExtractors
57+
defer func() { collectionFieldExtractors = original }()
58+
59+
collectionFieldExtractors = map[string][]string{
60+
"reviewers": {"login", "state"},
61+
}
62+
63+
result := optimizeItem(map[string]any{
64+
"reviewers": []any{
65+
map[string]any{"login": "alice", "state": "approved", "id": float64(1)},
66+
map[string]any{"login": "bob", "state": "changes_requested", "id": float64(2)},
67+
},
68+
"title": "Fix bug",
69+
})
70+
71+
expected := []any{
72+
map[string]any{"login": "alice", "state": "approved"},
73+
map[string]any{"login": "bob", "state": "changes_requested"},
74+
}
75+
assert.Equal(t, expected, result["reviewers"])
76+
assert.Equal(t, "Fix bug", result["title"])
77+
}
78+
79+
func TestFilterByFillRate(t *testing.T) {
80+
items := []map[string]any{
81+
{"title": "a", "body": "text", "milestone": "v1"},
82+
{"title": "b", "body": "text"},
83+
{"title": "c", "body": "text"},
84+
{"title": "d", "body": "text"},
85+
{"title": "e", "body": "text"},
86+
{"title": "f", "body": "text"},
87+
{"title": "g", "body": "text"},
88+
{"title": "h", "body": "text"},
89+
{"title": "i", "body": "text"},
90+
{"title": "j", "body": "text"},
91+
}
92+
93+
result := filterByFillRate(items, 0.1)
94+
95+
for _, item := range result {
96+
assert.Contains(t, item, "title")
97+
assert.Contains(t, item, "body")
98+
assert.NotContains(t, item, "milestone")
99+
}
100+
}
101+
102+
func TestFilterByFillRate_PreservesFields(t *testing.T) {
103+
original := preservedFields
104+
defer func() { preservedFields = original }()
105+
106+
preservedFields = map[string]bool{"html_url": true}
107+
108+
items := make([]map[string]any, 10)
109+
for i := range items {
110+
items[i] = map[string]any{"title": "x"}
111+
}
112+
items[0]["html_url"] = "https://github.com/repo/1"
113+
114+
result := filterByFillRate(items, 0.1)
115+
assert.Contains(t, result[0], "html_url")
116+
}
117+
118+
func TestOptimizeItems(t *testing.T) {
119+
tests := []struct {
120+
name string
121+
items []map[string]any
122+
expected []map[string]any
123+
}{
124+
{
125+
name: "applies all strategies in sequence",
126+
items: []map[string]any{
127+
{
128+
"title": "Fix bug",
129+
"body": "line1\n\nline2",
130+
"url": "https://api.github.com/repos/1",
131+
"html_url": "https://github.com/repo/1",
132+
"avatar_url": "https://avatars.githubusercontent.com/1",
133+
"draft": false,
134+
"merged_at": nil,
135+
"labels": []any{map[string]any{"name": "bug"}},
136+
"user": map[string]any{
137+
"login": "user",
138+
"avatar_url": "https://avatars.githubusercontent.com/1",
139+
},
140+
},
141+
},
142+
expected: []map[string]any{
143+
{
144+
"title": "Fix bug",
145+
"body": "line1 line2",
146+
"html_url": "https://github.com/repo/1",
147+
"labels": "bug",
148+
"user.login": "user",
149+
},
150+
},
151+
},
152+
{
153+
name: "nil input",
154+
items: nil,
155+
expected: nil,
156+
},
157+
}
158+
159+
for _, tc := range tests {
160+
t.Run(tc.name, func(t *testing.T) {
161+
result := OptimizeItems(tc.items)
162+
assert.Equal(t, tc.expected, result)
163+
})
164+
}
165+
}
166+
167+
func TestOptimizeItems_SkipsFillRateBelowMinRows(t *testing.T) {
168+
items := []map[string]any{
169+
{"title": "a", "rare": "x"},
170+
{"title": "b"},
171+
}
172+
173+
result := OptimizeItems(items)
174+
assert.Equal(t, "x", result[0]["rare"])
175+
}
176+
177+
func TestPreservedFields(t *testing.T) {
178+
original := preservedFields
179+
defer func() { preservedFields = original }()
180+
181+
preservedFields = map[string]bool{
182+
"html_url": true,
183+
"clone_url": true,
184+
}
185+
186+
result := optimizeItem(map[string]any{
187+
"html_url": "https://github.com/repo/1",
188+
"clone_url": "https://github.com/repo/1.git",
189+
"avatar_url": "https://avatars.githubusercontent.com/1",
190+
"user.html_url": "https://github.com/user",
191+
"user.clone_url": "https://github.com/user.git",
192+
})
193+
194+
assert.Contains(t, result, "html_url")
195+
assert.Contains(t, result, "clone_url")
196+
assert.NotContains(t, result, "avatar_url")
197+
assert.NotContains(t, result, "user.html_url")
198+
assert.NotContains(t, result, "user.clone_url")
199+
}
200+
201+
func TestPreservedFields_ProtectsZeroValues(t *testing.T) {
202+
original := preservedFields
203+
defer func() { preservedFields = original }()
204+
205+
preservedFields = map[string]bool{"draft": true}
206+
207+
result := optimizeItem(map[string]any{
208+
"draft": false,
209+
"body": "",
210+
})
211+
212+
assert.Contains(t, result, "draft")
213+
assert.NotContains(t, result, "body")
214+
}
215+
216+
func TestPreservedFields_ProtectsFromCollectionSummarization(t *testing.T) {
217+
original := preservedFields
218+
defer func() { preservedFields = original }()
219+
220+
preservedFields = map[string]bool{"assignees": true}
221+
222+
assignees := []any{
223+
map[string]any{"login": "alice", "id": float64(1)},
224+
map[string]any{"login": "bob", "id": float64(2)},
225+
}
226+
227+
result := optimizeItem(map[string]any{
228+
"assignees": assignees,
229+
"comments": []any{map[string]any{"id": "1"}, map[string]any{"id": "2"}},
230+
})
231+
232+
assert.Equal(t, assignees, result["assignees"])
233+
assert.Equal(t, "[2 items]", result["comments"])
234+
}
235+
236+
func TestCollectionFieldExtractors_SurviveFillRate(t *testing.T) {
237+
original := collectionFieldExtractors
238+
defer func() { collectionFieldExtractors = original }()
239+
240+
collectionFieldExtractors = map[string][]string{"labels": {"name"}}
241+
242+
items := []map[string]any{
243+
{"title": "PR 1", "labels": "bug"},
244+
{"title": "PR 2"},
245+
{"title": "PR 3"},
246+
{"title": "PR 4"},
247+
}
248+
249+
result := filterByFillRate(items, defaultFillRateThreshold)
250+
251+
assert.Contains(t, result[0], "labels")
252+
}
253+
254+
func TestMarshalItems_PlainSlice(t *testing.T) {
255+
type commit struct {
256+
SHA string `json:"sha"`
257+
Message string `json:"message"`
258+
URL string `json:"url"`
259+
}
260+
261+
data := []commit{
262+
{SHA: "abc123", Message: "fix bug", URL: "https://api.github.com/commits/abc123"},
263+
{SHA: "def456", Message: "add feature", URL: "https://api.github.com/commits/def456"},
264+
{SHA: "ghi789", Message: "update docs", URL: "https://api.github.com/commits/ghi789"},
265+
}
266+
267+
raw, err := MarshalItems(data)
268+
require.NoError(t, err)
269+
270+
var result []map[string]any
271+
err = json.Unmarshal(raw, &result)
272+
require.NoError(t, err)
273+
274+
for _, item := range result {
275+
assert.NotEmpty(t, item["sha"])
276+
assert.NotEmpty(t, item["message"])
277+
assert.Nil(t, item["url"])
278+
}
279+
}
280+
281+
func TestMarshalItems_WrappedObject(t *testing.T) {
282+
data := map[string]any{
283+
"issues": []any{
284+
map[string]any{
285+
"title": "bug report",
286+
"url": "https://api.github.com/issues/1",
287+
"html_url": "https://github.com/issues/1",
288+
"draft": false,
289+
},
290+
map[string]any{
291+
"title": "feature request",
292+
"url": "https://api.github.com/issues/2",
293+
"html_url": "https://github.com/issues/2",
294+
"draft": false,
295+
},
296+
map[string]any{
297+
"title": "docs update",
298+
"url": "https://api.github.com/issues/3",
299+
"html_url": "https://github.com/issues/3",
300+
"draft": false,
301+
},
302+
},
303+
"totalCount": 100,
304+
"pageInfo": map[string]any{
305+
"hasNextPage": true,
306+
"endCursor": "abc123",
307+
},
308+
}
309+
310+
raw, err := MarshalItems(data)
311+
require.NoError(t, err)
312+
313+
var result map[string]any
314+
err = json.Unmarshal(raw, &result)
315+
require.NoError(t, err)
316+
317+
assert.NotNil(t, result["totalCount"])
318+
assert.NotNil(t, result["pageInfo"])
319+
320+
issues, ok := result["issues"].([]any)
321+
require.True(t, ok)
322+
require.Len(t, issues, 3)
323+
324+
for _, issue := range issues {
325+
m := issue.(map[string]any)
326+
assert.NotEmpty(t, m["title"])
327+
assert.NotEmpty(t, m["html_url"])
328+
assert.Nil(t, m["url"])
329+
assert.Nil(t, m["draft"])
330+
}
331+
}

0 commit comments

Comments
 (0)