f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
126 lines
4.0 KiB
Go
126 lines
4.0 KiB
Go
//go:build pgtest
|
|
|
|
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const schemaTestSchema = "agentsview_schema_test"
|
|
|
|
func cleanSchemaTestPG(t *testing.T, pgURL string) {
|
|
t.Helper()
|
|
pg, err := sql.Open("pgx", pgURL)
|
|
require.NoError(t, err, "connecting to pg")
|
|
defer pg.Close()
|
|
_, _ = pg.Exec(
|
|
"DROP SCHEMA IF EXISTS " + schemaTestSchema + " CASCADE",
|
|
)
|
|
}
|
|
|
|
// TestSecretFindingsSchema verifies that EnsureSchema creates the
|
|
// secret_findings table with all required columns, and that the
|
|
// sessions table has the secret_leak_count and
|
|
// secrets_rules_version columns. Also asserts idempotency.
|
|
func TestSecretFindingsSchema(t *testing.T) {
|
|
pgURL := testPGURL(t)
|
|
cleanSchemaTestPG(t, pgURL)
|
|
t.Cleanup(func() { cleanSchemaTestPG(t, pgURL) })
|
|
|
|
pg, err := Open(pgURL, schemaTestSchema, true)
|
|
require.NoError(t, err, "connecting to pg")
|
|
defer pg.Close()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Run EnsureSchema twice to verify idempotency.
|
|
require.NoError(t, EnsureSchema(ctx, pg, schemaTestSchema),
|
|
"EnsureSchema (first)")
|
|
require.NoError(t, EnsureSchema(ctx, pg, schemaTestSchema),
|
|
"EnsureSchema (second, idempotency check)")
|
|
|
|
// Verify secret_findings table exists.
|
|
var tableExists bool
|
|
err = pg.QueryRowContext(ctx, `
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.tables
|
|
WHERE table_schema = $1
|
|
AND table_name = 'secret_findings'
|
|
)`, schemaTestSchema).Scan(&tableExists)
|
|
require.NoError(t, err, "checking secret_findings table")
|
|
require.True(t, tableExists, "secret_findings table does not exist")
|
|
|
|
// Verify all required columns on secret_findings.
|
|
requiredFindingsCols := []string{
|
|
"id", "session_id", "rule_name", "confidence",
|
|
"location_kind", "message_ordinal", "call_index",
|
|
"event_index", "match_start", "match_end",
|
|
"match_index", "redacted_match", "rules_version",
|
|
"created_at",
|
|
}
|
|
for _, col := range requiredFindingsCols {
|
|
var exists bool
|
|
err = pg.QueryRowContext(ctx, `
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = $1
|
|
AND table_name = 'secret_findings'
|
|
AND column_name = $2
|
|
)`, schemaTestSchema, col).Scan(&exists)
|
|
require.NoError(t, err, "checking secret_findings.%s", col)
|
|
assert.True(t, exists, "secret_findings.%s column missing", col)
|
|
}
|
|
|
|
// Verify sessions has both secret-scan state columns.
|
|
requiredSessionCols := []string{
|
|
"secret_leak_count",
|
|
"secrets_rules_version",
|
|
}
|
|
for _, col := range requiredSessionCols {
|
|
var exists bool
|
|
err = pg.QueryRowContext(ctx, `
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = $1
|
|
AND table_name = 'sessions'
|
|
AND column_name = $2
|
|
)`, schemaTestSchema, col).Scan(&exists)
|
|
require.NoError(t, err, "checking sessions.%s", col)
|
|
assert.True(t, exists, "sessions.%s column missing", col)
|
|
}
|
|
}
|
|
|
|
// TestToolCallsFilePathIndex verifies EnsureSchema creates the partial
|
|
// idx_tool_calls_file_path index that backs the cross-session Recent Edits
|
|
// feed, mirroring SQLite's index so the query surface has parity on PG.
|
|
func TestToolCallsFilePathIndex(t *testing.T) {
|
|
pgURL := testPGURL(t)
|
|
cleanSchemaTestPG(t, pgURL)
|
|
t.Cleanup(func() { cleanSchemaTestPG(t, pgURL) })
|
|
|
|
pg, err := Open(pgURL, schemaTestSchema, true)
|
|
require.NoError(t, err, "connecting to pg")
|
|
defer pg.Close()
|
|
|
|
ctx := context.Background()
|
|
// Twice to confirm CREATE INDEX IF NOT EXISTS stays idempotent.
|
|
require.NoError(t, EnsureSchema(ctx, pg, schemaTestSchema), "EnsureSchema (first)")
|
|
require.NoError(t, EnsureSchema(ctx, pg, schemaTestSchema), "EnsureSchema (second)")
|
|
|
|
var exists bool
|
|
err = pg.QueryRowContext(ctx, `
|
|
SELECT EXISTS (
|
|
SELECT 1 FROM pg_indexes
|
|
WHERE schemaname = $1
|
|
AND tablename = 'tool_calls'
|
|
AND indexname = 'idx_tool_calls_file_path'
|
|
)`, schemaTestSchema).Scan(&exists)
|
|
require.NoError(t, err, "checking idx_tool_calls_file_path")
|
|
assert.True(t, exists, "idx_tool_calls_file_path index missing")
|
|
}
|