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