Skip to content

Commit 7001ca3

Browse files
initial tests
1 parent d23c6a8 commit 7001ca3

File tree

1 file changed

+281
-0
lines changed

1 file changed

+281
-0
lines changed

connections/berry_db_test.go

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
package connections
2+
3+
import (
4+
"os"
5+
"strings"
6+
"testing"
7+
)
8+
9+
func TestQueryBerryData(t *testing.T) {
10+
// Test basic query without parameters
11+
t.Run("basic query without parameters", func(t *testing.T) {
12+
query := "SELECT name FROM berries LIMIT 1"
13+
results, err := QueryBerryData(query)
14+
15+
if err != nil {
16+
t.Fatalf("QueryBerryData() error = %v", err)
17+
}
18+
19+
if len(results) == 0 {
20+
t.Error("QueryBerryData() should return at least one result")
21+
}
22+
})
23+
24+
// Test query with parameters
25+
t.Run("query with parameters", func(t *testing.T) {
26+
// This test assumes there's a berry in the database
27+
// We'll use a LIKE query to be more flexible
28+
query := "SELECT name FROM berries WHERE name LIKE ? LIMIT 1"
29+
results, err := QueryBerryData(query, "%a%") // Find berries containing 'a'
30+
31+
if err != nil {
32+
t.Fatalf("QueryBerryData() error = %v", err)
33+
}
34+
35+
// Should return some results since many berry names contain 'a'
36+
if len(results) == 0 {
37+
t.Error("QueryBerryData() should return at least one result for berries containing 'a'")
38+
}
39+
})
40+
41+
// Test query with multiple parameters
42+
t.Run("query with multiple parameters", func(t *testing.T) {
43+
query := "SELECT name FROM berries WHERE name LIKE ? OR name LIKE ? LIMIT 5"
44+
results, err := QueryBerryData(query, "%a%", "%e%")
45+
46+
if err != nil {
47+
t.Fatalf("QueryBerryData() error = %v", err)
48+
}
49+
50+
// Should return some results
51+
if len(results) == 0 {
52+
t.Error("QueryBerryData() should return results for berries containing 'a' or 'e'")
53+
}
54+
})
55+
56+
// Test invalid query
57+
t.Run("invalid query", func(t *testing.T) {
58+
query := "SELECT invalid_column FROM non_existent_table"
59+
_, err := QueryBerryData(query)
60+
61+
if err == nil {
62+
t.Error("QueryBerryData() should return an error for invalid query")
63+
}
64+
})
65+
66+
// Test empty query
67+
t.Run("empty query", func(t *testing.T) {
68+
query := ""
69+
_, err := QueryBerryData(query)
70+
71+
if err == nil {
72+
t.Error("QueryBerryData() should return an error for empty query")
73+
}
74+
})
75+
76+
// Test query that returns no results
77+
t.Run("query with no results", func(t *testing.T) {
78+
query := "SELECT name FROM berries WHERE name = ?"
79+
results, err := QueryBerryData(query, "NonExistentBerryName12345")
80+
81+
if err != nil {
82+
t.Fatalf("QueryBerryData() error = %v", err)
83+
}
84+
85+
if len(results) != 0 {
86+
t.Errorf("QueryBerryData() should return empty results for non-existent berry, got %v", results)
87+
}
88+
})
89+
90+
// Test COUNT query
91+
t.Run("count query", func(t *testing.T) {
92+
query := "SELECT COUNT(*) FROM berries"
93+
results, err := QueryBerryData(query)
94+
95+
if err != nil {
96+
t.Fatalf("QueryBerryData() error = %v", err)
97+
}
98+
99+
if len(results) != 1 {
100+
t.Errorf("QueryBerryData() should return exactly one result for COUNT query, got %d", len(results))
101+
}
102+
103+
// The count should be a positive number
104+
if results[0] == "0" {
105+
t.Error("QueryBerryData() COUNT should return more than 0 berries")
106+
}
107+
})
108+
109+
// Test specific berry data
110+
t.Run("specific berry data query", func(t *testing.T) {
111+
// Try to get all berry names and verify structure
112+
query := "SELECT name FROM berries ORDER BY name LIMIT 10"
113+
results, err := QueryBerryData(query)
114+
115+
if err != nil {
116+
t.Fatalf("QueryBerryData() error = %v", err)
117+
}
118+
119+
if len(results) == 0 {
120+
t.Error("QueryBerryData() should return berry names")
121+
}
122+
123+
// Check that results are strings (berry names)
124+
for _, result := range results {
125+
if result == "" {
126+
t.Error("QueryBerryData() should not return empty berry names")
127+
}
128+
}
129+
})
130+
131+
// Test database schema validation
132+
t.Run("validate berries table schema", func(t *testing.T) {
133+
query := "PRAGMA table_info(berries)"
134+
results, err := QueryBerryData(query)
135+
136+
if err != nil {
137+
t.Fatalf("QueryBerryData() error = %v", err)
138+
}
139+
140+
if len(results) == 0 {
141+
t.Error("QueryBerryData() berries table should exist and have columns")
142+
}
143+
})
144+
145+
// Test SQL injection protection
146+
t.Run("SQL injection protection", func(t *testing.T) {
147+
// Try a basic SQL injection attempt
148+
maliciousInput := "'; DROP TABLE berries; --"
149+
query := "SELECT name FROM berries WHERE name = ?"
150+
151+
results, err := QueryBerryData(query, maliciousInput)
152+
153+
// Should not error (query should execute safely)
154+
if err != nil {
155+
// This is okay - the malicious input just won't match anything
156+
t.Logf("Query with malicious input failed safely: %v", err)
157+
}
158+
159+
// Should return empty results since no berry has that name
160+
if len(results) > 0 {
161+
t.Errorf("QueryBerryData() should return no results for malicious input, got %v", results)
162+
}
163+
164+
// Verify the table still exists by running another query
165+
testQuery := "SELECT COUNT(*) FROM berries"
166+
testResults, testErr := QueryBerryData(testQuery)
167+
168+
if testErr != nil {
169+
t.Fatalf("Table may have been affected by SQL injection: %v", testErr)
170+
}
171+
172+
if len(testResults) == 0 {
173+
t.Error("Berries table appears to be missing after SQL injection test")
174+
}
175+
})
176+
}
177+
178+
func TestQueryBerryDataWithVariadicArgs(t *testing.T) {
179+
// Test the variadic args functionality specifically
180+
tests := []struct {
181+
name string
182+
query string
183+
args []interface{}
184+
expectError bool
185+
}{
186+
{
187+
name: "no args",
188+
query: "SELECT COUNT(*) FROM berries",
189+
args: []interface{}{},
190+
expectError: false,
191+
},
192+
{
193+
name: "one arg",
194+
query: "SELECT name FROM berries WHERE name LIKE ? LIMIT 1",
195+
args: []interface{}{"%a%"},
196+
expectError: false,
197+
},
198+
{
199+
name: "multiple args",
200+
query: "SELECT name FROM berries WHERE name LIKE ? OR name LIKE ? LIMIT 1",
201+
args: []interface{}{"%a%", "%e%"},
202+
expectError: false,
203+
},
204+
{
205+
name: "mixed types",
206+
query: "SELECT name FROM berries LIMIT ?",
207+
args: []interface{}{5},
208+
expectError: false,
209+
},
210+
}
211+
212+
for _, tt := range tests {
213+
t.Run(tt.name, func(t *testing.T) {
214+
results, err := QueryBerryData(tt.query, tt.args...)
215+
216+
if (err != nil) != tt.expectError {
217+
t.Errorf("QueryBerryData() error = %v, expectError %v", err, tt.expectError)
218+
return
219+
}
220+
221+
if !tt.expectError && results == nil {
222+
t.Error("QueryBerryData() should not return nil results on success")
223+
}
224+
})
225+
}
226+
}
227+
228+
func TestEmbeddedDBExists(t *testing.T) {
229+
// Test that the embedded database exists and has content
230+
if len(embeddedDB) == 0 {
231+
t.Error("embeddedDB should not be empty")
232+
}
233+
234+
// Check if it looks like a SQLite database (starts with SQLite magic bytes)
235+
if len(embeddedDB) < 16 {
236+
t.Error("embeddedDB appears to be too small to be a valid SQLite database")
237+
}
238+
239+
// SQLite files start with "SQLite format 3\000"
240+
sqliteHeader := "SQLite format 3"
241+
if !strings.HasPrefix(string(embeddedDB[:len(sqliteHeader)]), sqliteHeader) {
242+
t.Error("embeddedDB does not appear to be a valid SQLite database")
243+
}
244+
}
245+
246+
func TestQueryBerryDataTempFileCleanup(t *testing.T) {
247+
// This test verifies that temporary files are cleaned up properly
248+
initialTempFiles := countTempFiles()
249+
250+
// Run a query
251+
query := "SELECT COUNT(*) FROM berries"
252+
_, err := QueryBerryData(query)
253+
254+
if err != nil {
255+
t.Fatalf("QueryBerryData() error = %v", err)
256+
}
257+
258+
finalTempFiles := countTempFiles()
259+
260+
// The number of temp files should not have increased
261+
if finalTempFiles > initialTempFiles {
262+
t.Errorf("Temporary files not cleaned up properly. Before: %d, After: %d", initialTempFiles, finalTempFiles)
263+
}
264+
}
265+
266+
// Helper function to count temporary files (basic implementation)
267+
func countTempFiles() int {
268+
tempDir := os.TempDir()
269+
entries, err := os.ReadDir(tempDir)
270+
if err != nil {
271+
return 0
272+
}
273+
274+
count := 0
275+
for _, entry := range entries {
276+
if strings.Contains(entry.Name(), "berries-") && strings.HasSuffix(entry.Name(), ".db") {
277+
count++
278+
}
279+
}
280+
return count
281+
}

0 commit comments

Comments
 (0)