Files
wehub-resource-sync f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
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
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

179 lines
5.6 KiB
Go

//go:build pgtest
package postgres
import (
"context"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.kenn.io/agentsview/internal/db"
)
// TestPushSessionNameRoundTrip verifies that session_name is pushed from
// SQLite to PostgreSQL and survives a round-trip via the sidebar index
// read path and the scanPGSession read path.
func TestPushSessionNameRoundTrip(t *testing.T) {
pgURL := testPGURL(t)
const schema = "agentsview_push_sessionname_test"
pg, err := Open(pgURL, schema, true)
require.NoError(t, err, "Open")
defer pg.Close()
ctx := context.Background()
_, err = pg.Exec(`DROP SCHEMA IF EXISTS ` + schema + ` CASCADE`)
require.NoError(t, err, "drop schema")
require.NoError(t, EnsureSchema(ctx, pg, schema), "EnsureSchema")
localDB, err := db.Open(filepath.Join(t.TempDir(), "local.db"))
require.NoError(t, err, "db.Open")
defer localDB.Close()
sync := &Sync{
pg: pg,
local: localDB,
machine: "test-machine",
schema: schema,
schemaDone: true,
}
sessionName := "Agent Title"
displayName := "My renamed session"
sess := db.Session{
ID: "sessionname-test-001",
Project: "test-project",
Machine: "test-machine",
Agent: "claude",
MessageCount: 1,
UserMessageCount: 1,
CreatedAt: "2026-01-01T00:00:00Z",
DisplayName: &displayName,
SessionName: &sessionName,
}
markerID, err := sync.pushMarkerID()
require.NoError(t, err, "pushMarkerID")
// Push via pushSession directly.
tx, err := pg.BeginTx(ctx, nil)
require.NoError(t, err, "BeginTx")
if err := sync.pushSession(ctx, tx, sess, markerID, nil); err != nil {
_ = tx.Rollback()
t.Fatalf("pushSession: %v", err)
}
require.NoError(t, tx.Commit(), "Commit")
// Read back session_name via direct query.
var gotSessionName *string
require.NoError(t, pg.QueryRow(
`SELECT session_name FROM sessions WHERE id = $1`,
sess.ID,
).Scan(&gotSessionName), "read back session_name")
require.NotNil(t, gotSessionName, "session_name should not be NULL")
assert.Equal(t, "Agent Title", *gotSessionName, "session_name round-trip")
// Read back via store and GetSidebarSessionIndex.
store, err := NewStore(pgURL, schema, true)
require.NoError(t, err, "NewStore")
defer store.Close()
index, err := store.GetSidebarSessionIndex(ctx, db.SessionFilter{
Limit: 50,
})
require.NoError(t, err, "GetSidebarSessionIndex")
var found *db.SidebarSessionIndexRow
for i := range index.Sessions {
if index.Sessions[i].ID == sess.ID {
found = &index.Sessions[i]
break
}
}
require.NotNil(t, found, "session not found in sidebar index")
// display_name wins over session_name when set.
require.NotNil(t, found.DisplayName, "DisplayName should not be nil in sidebar index")
assert.Equal(t, "My renamed session", *found.DisplayName, "DisplayName round-trip via sidebar index")
// Verify that updating to NULL clears both via ON CONFLICT path.
sess.SessionName = nil
sess.DisplayName = nil
tx2, err := pg.BeginTx(ctx, nil)
require.NoError(t, err, "BeginTx (second)")
if err := sync.pushSession(ctx, tx2, sess, markerID, nil); err != nil {
_ = tx2.Rollback()
t.Fatalf("pushSession (second): %v", err)
}
require.NoError(t, tx2.Commit(), "Commit (second)")
require.NoError(t, pg.QueryRow(
`SELECT session_name FROM sessions WHERE id = $1`,
sess.ID,
).Scan(&gotSessionName), "read back session_name after clear")
assert.Nil(t, gotSessionName, "session_name should be NULL after clearing")
}
// TestPushSessionNameViaPushPath verifies session_name survives the REAL push
// path (Push -> ListSessionsModifiedBetween read), not just a direct
// pushSession call. ListSessionsModifiedBetween reads sessionFullCols, so a
// missing session_name there would silently drop the value on every real push.
func TestPushSessionNameViaPushPath(t *testing.T) {
pgURL := testPGURL(t)
cleanPGSchema(t, pgURL)
t.Cleanup(func() { cleanPGSchema(t, pgURL) })
local := testDB(t)
ps, err := New(
pgURL, "agentsview", local, "machine-sessionname-push", true,
SyncOptions{},
)
require.NoError(t, err, "creating sync")
defer ps.Close()
ctx := context.Background()
require.NoError(t, ps.EnsureSchema(ctx), "ensure schema")
started := time.Now().UTC().Format(time.RFC3339)
firstMsg := "real push path"
sessionName := "plan-2b-review"
require.NoError(t, local.UpsertSession(db.Session{
ID: "sn-push-001",
Project: "p",
Machine: "local",
Agent: "claude",
FirstMessage: &firstMsg,
SessionName: &sessionName,
StartedAt: &started,
MessageCount: 1,
}), "upsert session")
pushResult, err := ps.Push(ctx, false, nil)
require.NoError(t, err, "push")
require.Equal(t, 1, pushResult.SessionsPushed)
store, err := NewStore(pgURL, "agentsview", true)
require.NoError(t, err, "opening store")
defer store.Close()
// Verify session_name was pushed correctly via direct SQL.
var pushedSessionName *string
require.NoError(t, ps.DB().QueryRow(
`SELECT session_name FROM agentsview.sessions WHERE id = $1`,
"sn-push-001",
).Scan(&pushedSessionName), "read session_name via direct SQL")
require.NotNil(t, pushedSessionName, "session_name must be stored in PG after push")
assert.Equal(t, "plan-2b-review", *pushedSessionName)
index, err := store.GetSidebarSessionIndex(ctx, db.SessionFilter{Limit: 50})
require.NoError(t, err, "GetSidebarSessionIndex")
require.Len(t, index.Sessions, 1)
// session_name is visible via COALESCE(display_name, session_name) when no user rename.
require.NotNil(t, index.Sessions[0].DisplayName)
assert.Equal(t, "plan-2b-review", *index.Sessions[0].DisplayName)
}