summaryrefslogtreecommitdiff
path: root/internal/store/history_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/store/history_test.go')
-rw-r--r--internal/store/history_test.go190
1 files changed, 190 insertions, 0 deletions
diff --git a/internal/store/history_test.go b/internal/store/history_test.go
new file mode 100644
index 0000000..d3a8e99
--- /dev/null
+++ b/internal/store/history_test.go
@@ -0,0 +1,190 @@
+package store_test
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+ "time"
+
+ "github.com/shiv/internal/store"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func makeTx(method, host, url string, status int) store.Transaction {
+ return store.Transaction{
+ Timestamp: time.Now().UTC(),
+ Host: host,
+ Method: method,
+ URL: url,
+ ReqHeaders: http.Header{"Content-Type": []string{"text/plain"}},
+ ReqBody: []byte("request body"),
+ StatusCode: status,
+ RespHeaders: http.Header{"Content-Type": []string{"text/html"}},
+ RespBody: []byte("response body"),
+ DurationMs: 10,
+ TLS: false,
+ InScope: true,
+ }
+}
+
+func TestLog_Insert(t *testing.T) {
+ st := newTestStore(t)
+
+ tx := makeTx("GET", "example.com", "https://example.com/", 200)
+ require.NoError(t, st.Log(tx))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ require.Len(t, txs, 1)
+ assert.Equal(t, "GET", txs[0].Method)
+ assert.Equal(t, "example.com", txs[0].Host)
+ assert.Equal(t, 200, txs[0].StatusCode)
+ assert.True(t, txs[0].InScope)
+}
+
+func TestLog_NoDedup_SameMethodHostURLStatus(t *testing.T) {
+ st := newTestStore(t)
+
+ tx := makeTx("GET", "example.com", "https://example.com/", 200)
+ require.NoError(t, st.Log(tx))
+ require.NoError(t, st.Log(tx))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.Len(t, txs, 2, "no dedup — every request is a unique row")
+}
+
+func TestLog_NoDedupOnDifferentStatus(t *testing.T) {
+ st := newTestStore(t)
+
+ require.NoError(t, st.Log(makeTx("GET", "example.com", "https://example.com/", 200)))
+ require.NoError(t, st.Log(makeTx("GET", "example.com", "https://example.com/", 404)))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.Len(t, txs, 2)
+}
+
+func TestLog_NoDedupOnDifferentMethod(t *testing.T) {
+ st := newTestStore(t)
+
+ require.NoError(t, st.Log(makeTx("GET", "example.com", "https://example.com/", 200)))
+ require.NoError(t, st.Log(makeTx("POST", "example.com", "https://example.com/", 200)))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.Len(t, txs, 2)
+}
+
+func TestLog_NoDedupOnDifferentURL(t *testing.T) {
+ st := newTestStore(t)
+
+ require.NoError(t, st.Log(makeTx("GET", "example.com", "https://example.com/a", 200)))
+ require.NoError(t, st.Log(makeTx("GET", "example.com", "https://example.com/b", 200)))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.Len(t, txs, 2)
+}
+
+func TestLog_TLSFlagPersisted(t *testing.T) {
+ st := newTestStore(t)
+
+ tx := makeTx("GET", "example.com", "https://example.com/", 200)
+ tx.TLS = true
+ require.NoError(t, st.Log(tx))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ require.Len(t, txs, 1)
+ assert.True(t, txs[0].TLS)
+}
+
+func TestAllTransactions_OrderedByIDDesc(t *testing.T) {
+ st := newTestStore(t)
+
+ require.NoError(t, st.Log(makeTx("GET", "first.com", "https://first.com/", 200)))
+ require.NoError(t, st.Log(makeTx("GET", "second.com", "https://second.com/", 200)))
+ require.NoError(t, st.Log(makeTx("GET", "third.com", "https://third.com/", 200)))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ require.Len(t, txs, 3)
+ assert.Equal(t, "third.com", txs[0].Host)
+ assert.Equal(t, "second.com", txs[1].Host)
+ assert.Equal(t, "first.com", txs[2].Host)
+}
+
+func TestAllTransactions_CappedAt500(t *testing.T) {
+ st := newTestStore(t)
+
+ for i := 0; i < 510; i++ {
+ url := fmt.Sprintf("https://example.com/path/%d", i)
+ require.NoError(t, st.Log(makeTx("GET", "example.com", url, 200)))
+ }
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.LessOrEqual(t, len(txs), 500)
+}
+
+func TestGetTransaction_ReturnsFullBodies(t *testing.T) {
+ st := newTestStore(t)
+
+ tx := makeTx("POST", "example.com", "https://example.com/api", 201)
+ tx.ReqBody = []byte(`{"input":"data"}`)
+ tx.RespBody = []byte(`{"output":"result"}`)
+ require.NoError(t, st.Log(tx))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ require.Len(t, txs, 1)
+
+ full, err := st.GetTransaction(txs[0].ID)
+ require.NoError(t, err)
+ assert.Equal(t, []byte(`{"input":"data"}`), full.ReqBody)
+ assert.Equal(t, []byte(`{"output":"result"}`), full.RespBody)
+ assert.Equal(t, "POST", full.Method)
+ assert.Equal(t, 201, full.StatusCode)
+}
+
+func TestGetTransaction_HeadersDeserialized(t *testing.T) {
+ st := newTestStore(t)
+
+ tx := makeTx("GET", "example.com", "https://example.com/", 200)
+ tx.ReqHeaders = http.Header{"X-Request-Id": []string{"req-123"}}
+ tx.RespHeaders = http.Header{"X-Trace-Id": []string{"trace-456"}}
+ require.NoError(t, st.Log(tx))
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+
+ full, err := st.GetTransaction(txs[0].ID)
+ require.NoError(t, err)
+ assert.Equal(t, "req-123", full.ReqHeaders.Get("X-Request-Id"))
+ assert.Equal(t, "trace-456", full.RespHeaders.Get("X-Trace-Id"))
+}
+
+func TestGetTransaction_NotFound(t *testing.T) {
+ st := newTestStore(t)
+ _, err := st.GetTransaction(99999)
+ assert.Error(t, err)
+}
+
+func TestClearHistory_RemovesAllRows(t *testing.T) {
+ st := newTestStore(t)
+
+ require.NoError(t, st.Log(makeTx("GET", "a.com", "https://a.com/", 200)))
+ require.NoError(t, st.Log(makeTx("GET", "b.com", "https://b.com/", 200)))
+ require.NoError(t, st.ClearHistory())
+
+ txs, err := st.AllTransactions()
+ require.NoError(t, err)
+ assert.Empty(t, txs)
+}
+
+func TestClearHistory_EmptyStoreNoError(t *testing.T) {
+ st := newTestStore(t)
+ assert.NoError(t, st.ClearHistory())
+}