srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/store/store_test.go
blob: 5daa73a3d4b6d8ea492e4032582556a91dfe527c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package store

import "testing"

func TestExtractStructured(t *testing.T) {
	boolPtr := func(b bool) *bool { return &b }

	tests := []struct {
		name       string
		query      string
		remaining  string
		statusSQL  string
		statusArgs []any
		source     string
		flagged    *bool
		tag        string
	}{
		{
			name:      "plain text only",
			query:     "admin login",
			remaining: "admin login",
		},
		{
			name:      "flagged true",
			query:     "flagged:true",
			remaining: "",
			flagged:   boolPtr(true),
		},
		{
			name:      "flagged false",
			query:     "flagged:no",
			remaining: "",
			flagged:   boolPtr(false),
		},
		{
			name:      "not a real flagged token falls through as text",
			query:     "flagged:maybe",
			remaining: "flagged:maybe",
		},
		{
			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:      "tag filter",
			query:     "tag:jwt",
			remaining: "",
			tag:       "jwt",
		},
		{
			name:      "tag filter preserves case",
			query:     "tag:JWT",
			remaining: "",
			tag:       "JWT",
		},
		{
			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)
			}
			if pred.tag != tt.tag {
				t.Errorf("tag = %q, want %q", pred.tag, tt.tag)
			}
			switch {
			case pred.flagged == nil && tt.flagged == nil:
			case pred.flagged == nil || tt.flagged == nil:
				t.Errorf("flagged = %v, want %v", pred.flagged, tt.flagged)
			case *pred.flagged != *tt.flagged:
				t.Errorf("flagged = %v, want %v", *pred.flagged, *tt.flagged)
			}
		})
	}
}