srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/store/store_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/store/store_test.go')
-rw-r--r--internal/store/store_test.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
new file mode 100644
index 0000000..7999ac3
--- /dev/null
+++ b/internal/store/store_test.go
@@ -0,0 +1,95 @@
+package store
+
+import "testing"
+
+func TestExtractStructured(t *testing.T) {
+ tests := []struct {
+ name string
+ query string
+ remaining string
+ statusSQL string
+ statusArgs []any
+ source string
+ }{
+ {
+ name: "plain text only",
+ query: "admin login",
+ remaining: "admin login",
+ },
+ {
+ name: "exact status",
+ query: "status:404",
+ remaining: "",
+ statusSQL: "status_code = ?",
+ statusArgs: []any{404},
+ },
+ {
+ name: "status with operator",
+ query: "status:>=400",
+ remaining: "",
+ statusSQL: "status_code >= ?",
+ statusArgs: []any{400},
+ },
+ {
+ name: "status not-equal",
+ query: "status:!=200",
+ remaining: "",
+ statusSQL: "status_code != ?",
+ statusArgs: []any{200},
+ },
+ {
+ name: "status range shorthand",
+ query: "status:4xx",
+ remaining: "",
+ statusSQL: "status_code >= ? AND status_code < ?",
+ statusArgs: []any{400, 500},
+ },
+ {
+ name: "source filter",
+ query: "source:repeater",
+ remaining: "",
+ source: "repeater",
+ },
+ {
+ name: "combined with free text",
+ query: "admin status:>=400 source:proxy",
+ remaining: "admin",
+ statusSQL: "status_code >= ?",
+ statusArgs: []any{400},
+ source: "proxy",
+ },
+ {
+ name: "not a real status token falls through as text",
+ query: "status:banana",
+ remaining: "status:banana",
+ },
+ {
+ name: "malformed 4-digit status falls through as text",
+ query: "status:4004",
+ remaining: "status:4004",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ remaining, pred := extractStructured(tt.query)
+ if remaining != tt.remaining {
+ t.Errorf("remaining = %q, want %q", remaining, tt.remaining)
+ }
+ if pred.statusSQL != tt.statusSQL {
+ t.Errorf("statusSQL = %q, want %q", pred.statusSQL, tt.statusSQL)
+ }
+ if len(pred.statusArgs) != len(tt.statusArgs) {
+ t.Fatalf("statusArgs = %v, want %v", pred.statusArgs, tt.statusArgs)
+ }
+ for i := range pred.statusArgs {
+ if pred.statusArgs[i] != tt.statusArgs[i] {
+ t.Errorf("statusArgs[%d] = %v, want %v", i, pred.statusArgs[i], tt.statusArgs[i])
+ }
+ }
+ if pred.source != tt.source {
+ t.Errorf("source = %q, want %q", pred.source, tt.source)
+ }
+ })
+ }
+}