Skip to content

Commit a400892

Browse files
committed
feat(history): add tests for history manager
1 parent 2d6ce37 commit a400892

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed

internal/history/manager_test.go

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
package history
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"testing"
7+
"time"
8+
9+
"github.com/maniac-en/req/internal/database"
10+
_ "github.com/mattn/go-sqlite3"
11+
)
12+
13+
func setupTestDB(t *testing.T) *database.Queries {
14+
db, err := sql.Open("sqlite3", ":memory:")
15+
if err != nil {
16+
t.Fatalf("failed to open in-memory database: %v", err)
17+
}
18+
19+
// Create history table
20+
schema := `
21+
CREATE TABLE history (
22+
id INTEGER PRIMARY KEY AUTOINCREMENT,
23+
collection_id INTEGER,
24+
collection_name TEXT,
25+
endpoint_name TEXT,
26+
method TEXT NOT NULL,
27+
url TEXT NOT NULL,
28+
status_code INTEGER NOT NULL,
29+
duration INTEGER NOT NULL,
30+
response_size INTEGER DEFAULT 0,
31+
request_headers TEXT DEFAULT '{}',
32+
query_params TEXT DEFAULT '{}',
33+
request_body TEXT DEFAULT '',
34+
response_body TEXT DEFAULT '',
35+
response_headers TEXT DEFAULT '{}',
36+
executed_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
37+
);`
38+
39+
if _, err := db.Exec(schema); err != nil {
40+
t.Fatalf("failed to create schema: %v", err)
41+
}
42+
43+
return database.New(db)
44+
}
45+
46+
47+
func TestHistoryManagerCRUD(t *testing.T) {
48+
ctx := context.Background()
49+
db := setupTestDB(t)
50+
manager := NewHistoryManager(db)
51+
52+
t.Run("Create returns error", func(t *testing.T) {
53+
_, err := manager.Create(ctx, "test")
54+
if err == nil {
55+
t.Error("expected Create to return error")
56+
}
57+
})
58+
59+
t.Run("Update returns error", func(t *testing.T) {
60+
_, err := manager.Update(ctx, 1, "test")
61+
if err == nil {
62+
t.Error("expected Update to return error")
63+
}
64+
})
65+
66+
t.Run("List returns error", func(t *testing.T) {
67+
_, err := manager.List(ctx)
68+
if err == nil {
69+
t.Error("expected List to return error")
70+
}
71+
})
72+
73+
t.Run("Read with invalid ID", func(t *testing.T) {
74+
_, err := manager.Read(ctx, 0)
75+
if err == nil {
76+
t.Error("expected Read with invalid ID to return error")
77+
}
78+
})
79+
80+
t.Run("Delete with invalid ID", func(t *testing.T) {
81+
err := manager.Delete(ctx, 0)
82+
if err == nil {
83+
t.Error("expected Delete with invalid ID to return error")
84+
}
85+
})
86+
}
87+
88+
func TestRecordExecution(t *testing.T) {
89+
ctx := context.Background()
90+
db := setupTestDB(t)
91+
manager := NewHistoryManager(db)
92+
93+
t.Run("valid execution", func(t *testing.T) {
94+
data := ExecutionData{
95+
CollectionID: 1,
96+
CollectionName: "Test Collection",
97+
EndpointName: "Get Users",
98+
Method: "GET",
99+
URL: "https://api.example.com/users",
100+
Headers: map[string]string{"Authorization": "Bearer token"},
101+
QueryParams: map[string]string{"limit": "10"},
102+
RequestBody: "",
103+
StatusCode: 200,
104+
ResponseBody: `{"users": []}`,
105+
ResponseHeaders: map[string][]string{"Content-Type": {"application/json"}},
106+
Duration: 150 * time.Millisecond,
107+
ResponseSize: 100,
108+
}
109+
110+
entity, err := manager.RecordExecution(ctx, data)
111+
if err != nil {
112+
t.Fatalf("RecordExecution failed: %v", err)
113+
}
114+
115+
if entity.GetID() == 0 {
116+
t.Error("expected entity to have ID")
117+
}
118+
119+
if entity.Method != "GET" {
120+
t.Errorf("expected method GET, got %s", entity.Method)
121+
}
122+
123+
// Test Read functionality
124+
readEntity, err := manager.Read(ctx, entity.GetID())
125+
if err != nil {
126+
t.Fatalf("Read failed: %v", err)
127+
}
128+
129+
if readEntity.GetID() != entity.GetID() {
130+
t.Errorf("expected ID %d, got %d", entity.GetID(), readEntity.GetID())
131+
}
132+
})
133+
134+
t.Run("invalid execution data", func(t *testing.T) {
135+
tests := []struct {
136+
name string
137+
data ExecutionData
138+
}{
139+
{
140+
name: "empty method",
141+
data: ExecutionData{Method: "", URL: "https://example.com", StatusCode: 200},
142+
},
143+
{
144+
name: "empty URL",
145+
data: ExecutionData{Method: "GET", URL: "", StatusCode: 200},
146+
},
147+
{
148+
name: "invalid status code",
149+
data: ExecutionData{Method: "GET", URL: "https://example.com", StatusCode: 999},
150+
},
151+
}
152+
153+
for _, tt := range tests {
154+
t.Run(tt.name, func(t *testing.T) {
155+
_, err := manager.RecordExecution(ctx, tt.data)
156+
if err == nil {
157+
t.Error("expected RecordExecution to fail")
158+
}
159+
})
160+
}
161+
})
162+
}
163+
164+
func TestListByCollection(t *testing.T) {
165+
ctx := context.Background()
166+
db := setupTestDB(t)
167+
manager := NewHistoryManager(db)
168+
169+
// Create test data
170+
testData := []ExecutionData{
171+
{CollectionID: 1, Method: "GET", URL: "https://api.example.com/users", StatusCode: 200},
172+
{CollectionID: 1, Method: "POST", URL: "https://api.example.com/users", StatusCode: 201},
173+
{CollectionID: 1, Method: "GET", URL: "https://api.example.com/posts", StatusCode: 200},
174+
{CollectionID: 2, Method: "GET", URL: "https://api.other.com/data", StatusCode: 200},
175+
}
176+
177+
for _, data := range testData {
178+
_, err := manager.RecordExecution(ctx, data)
179+
if err != nil {
180+
t.Fatalf("failed to create test data: %v", err)
181+
}
182+
}
183+
184+
t.Run("valid pagination", func(t *testing.T) {
185+
result, err := manager.ListByCollection(ctx, 1, 2, 0)
186+
if err != nil {
187+
t.Fatalf("ListByCollection failed: %v", err)
188+
}
189+
190+
if result.Total != 3 {
191+
t.Errorf("expected total 3, got %d", result.Total)
192+
}
193+
194+
if result.TotalPages != 2 {
195+
t.Errorf("expected 2 total pages, got %d", result.TotalPages)
196+
}
197+
198+
if result.CurrentPage != 1 {
199+
t.Errorf("expected current page 1, got %d", result.CurrentPage)
200+
}
201+
202+
if !result.HasNext {
203+
t.Error("expected HasNext to be true")
204+
}
205+
206+
if result.HasPrev {
207+
t.Error("expected HasPrev to be false")
208+
}
209+
210+
if len(result.Items) != 2 {
211+
t.Errorf("expected 2 items, got %d", len(result.Items))
212+
}
213+
})
214+
215+
t.Run("invalid collection ID", func(t *testing.T) {
216+
_, err := manager.ListByCollection(ctx, 0, 10, 0)
217+
if err == nil {
218+
t.Error("expected ListByCollection with invalid ID to fail")
219+
}
220+
})
221+
222+
t.Run("second page", func(t *testing.T) {
223+
result, err := manager.ListByCollection(ctx, 1, 2, 2)
224+
if err != nil {
225+
t.Fatalf("ListByCollection failed: %v", err)
226+
}
227+
228+
if result.CurrentPage != 2 {
229+
t.Errorf("expected current page 2, got %d", result.CurrentPage)
230+
}
231+
232+
if !result.HasPrev {
233+
t.Error("expected HasPrev to be true")
234+
}
235+
236+
if result.HasNext {
237+
t.Error("expected HasNext to be false")
238+
}
239+
240+
if len(result.Items) != 1 {
241+
t.Errorf("expected 1 item, got %d", len(result.Items))
242+
}
243+
})
244+
245+
t.Run("collection filtering", func(t *testing.T) {
246+
result, err := manager.ListByCollection(ctx, 2, 10, 0)
247+
if err != nil {
248+
t.Fatalf("ListByCollection failed: %v", err)
249+
}
250+
251+
if result.Total != 1 {
252+
t.Errorf("expected total 1, got %d", result.Total)
253+
}
254+
255+
if len(result.Items) != 1 {
256+
t.Errorf("expected 1 item, got %d", len(result.Items))
257+
}
258+
})
259+
}
260+
261+
func TestDelete(t *testing.T) {
262+
ctx := context.Background()
263+
db := setupTestDB(t)
264+
manager := NewHistoryManager(db)
265+
266+
// Create test entry
267+
data := ExecutionData{
268+
CollectionID: 1,
269+
Method: "GET",
270+
URL: "https://example.com",
271+
StatusCode: 200,
272+
}
273+
274+
entity, err := manager.RecordExecution(ctx, data)
275+
if err != nil {
276+
t.Fatalf("failed to create test data: %v", err)
277+
}
278+
279+
// Delete it
280+
err = manager.Delete(ctx, entity.GetID())
281+
if err != nil {
282+
t.Fatalf("Delete failed: %v", err)
283+
}
284+
285+
// Verify it's gone
286+
_, err = manager.Read(ctx, entity.GetID())
287+
if err == nil {
288+
t.Error("expected Read to fail after Delete")
289+
}
290+
}
291+

0 commit comments

Comments
 (0)