package main import ( "context" "database/sql" "encoding/json" "path/filepath" "testing" _ "modernc.org/sqlite" ) func TestExtractRows_FiltersExtraJSON(t *testing.T) { dir := t.TempDir() dbPath := filepath.Join(dir, "test.db") db, err := sql.Open("sqlite", dbPath) if err != nil { t.Fatal(err) } defer db.Close() _, err = db.Exec(` CREATE TABLE speedtest_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, ip TEXT, ispinfo TEXT, extra TEXT, ua TEXT, lang TEXT, dl REAL, ul REAL, ping REAL, jitter REAL, log TEXT )`) if err != nil { t.Fatal(err) } extra, _ := json.Marshal(map[string]string{"node": "fl", "country": "RU"}) _, err = db.Exec(`INSERT INTO speedtest_users(timestamp, ip, ispinfo, extra, dl, ul, ping, jitter) VALUES(datetime('now'), '0.0.0.0', '', ?, 100.5, 20.1, 35.2, 2.4)`, string(extra)) if err != nil { t.Fatal(err) } rows, err := extractRows(context.Background(), db, 0) if err != nil { t.Fatal(err) } if len(rows) != 1 { t.Fatalf("expected 1 row, got %d", len(rows)) } if rows[0].Node != "fl" || rows[0].Country != "RU" { t.Errorf("extract mismatch: %+v", rows[0]) } if rows[0].DlMbps != 100.5 { t.Errorf("dl mismatch: %v", rows[0].DlMbps) } } func TestExtractRows_SkipsBadExtra(t *testing.T) { dir := t.TempDir() dbPath := filepath.Join(dir, "test.db") db, err := sql.Open("sqlite", dbPath) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`CREATE TABLE speedtest_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, ip TEXT, ispinfo TEXT, extra TEXT, ua TEXT, lang TEXT, dl REAL, ul REAL, ping REAL, jitter REAL, log TEXT)`); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO speedtest_users(timestamp, extra, dl, ul, ping, jitter) VALUES(datetime('now'), 'not-json', 1, 1, 1, 1)`); err != nil { t.Fatal(err) } rows, err := extractRows(context.Background(), db, 0) if err != nil { t.Fatal(err) } if len(rows) != 0 { t.Errorf("expected 0 rows (bad extra skipped), got %d", len(rows)) } } func TestExtractRows_SkipsBadTimestamp(t *testing.T) { dir := t.TempDir() dbPath := filepath.Join(dir, "test.db") db, err := sql.Open("sqlite", dbPath) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`CREATE TABLE speedtest_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, ip TEXT, ispinfo TEXT, extra TEXT, ua TEXT, lang TEXT, dl REAL, ul REAL, ping REAL, jitter REAL, log TEXT)`); err != nil { t.Fatal(err) } extra, _ := json.Marshal(map[string]string{"node": "fl", "country": "RU"}) // NULL timestamp if _, err := db.Exec(`INSERT INTO speedtest_users(timestamp, extra, dl, ul, ping, jitter) VALUES(NULL, ?, 1, 1, 1, 1)`, string(extra)); err != nil { t.Fatal(err) } rows, err := extractRows(context.Background(), db, 0) if err != nil { t.Fatal(err) } if len(rows) != 0 { t.Errorf("expected 0 rows (null timestamp skipped), got %d", len(rows)) } }