Files
kandev/apps/backend/internal/integrations/workspacescope/workspacescope_test.go
T

138 lines
3.4 KiB
Go

package workspacescope
import (
"database/sql"
"testing"
"time"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
)
func newTestDB(t *testing.T) *sqlx.DB {
t.Helper()
raw, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
raw.SetMaxOpenConns(1)
raw.SetMaxIdleConns(1)
db := sqlx.NewDb(raw, "sqlite3")
t.Cleanup(func() { _ = db.Close() })
return db
}
func seedActiveWorkspace(t *testing.T, db *sqlx.DB, workspaceID string) {
t.Helper()
now := time.Now().UTC()
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS workspaces (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT NOT NULL,
settings TEXT NOT NULL DEFAULT '{}',
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
DELETE FROM workspaces;
DELETE FROM users;
INSERT INTO workspaces (id, name, created_at, updated_at)
VALUES (?, 'Active', ?, ?);
INSERT INTO users (id, email, settings, created_at, updated_at)
VALUES ('default-user', 'default@kandev.local', ?, ?, ?);
`, workspaceID, now, now, `{"workspace_id":"`+workspaceID+`"}`, now, now); err != nil {
t.Fatalf("seed active workspace: %v", err)
}
}
func TestDefaultResolverReflectsActiveWorkspaceChange(t *testing.T) {
db := newTestDB(t)
seedActiveWorkspace(t, db, "ws-first")
var resolver DefaultResolver
got, err := resolver.Resolve(db)
if err != nil {
t.Fatalf("first resolve: %v", err)
}
if got != "ws-first" {
t.Fatalf("expected ws-first, got %q", got)
}
// The active workspace is mutable at runtime; switching it must be
// reflected on the next resolve, not pinned to the first value.
seedActiveWorkspace(t, db, "ws-second")
got, err = resolver.Resolve(db)
if err != nil {
t.Fatalf("second resolve: %v", err)
}
if got != "ws-second" {
t.Fatalf("expected ws-second after switch, got %q", got)
}
}
func TestDefaultResolverIsPerDB(t *testing.T) {
db1 := newTestDB(t)
db2 := newTestDB(t)
seedActiveWorkspace(t, db1, "ws-one")
seedActiveWorkspace(t, db2, "ws-two")
var resolver DefaultResolver
got, err := resolver.Resolve(db1)
if err != nil {
t.Fatalf("resolve db1: %v", err)
}
if got != "ws-one" {
t.Fatalf("expected ws-one, got %q", got)
}
got, err = resolver.Resolve(db2)
if err != nil {
t.Fatalf("resolve db2: %v", err)
}
if got != "ws-two" {
t.Fatalf("expected ws-two for second db, got %q", got)
}
}
func TestDefaultResolverRecoversAfterError(t *testing.T) {
db := newTestDB(t)
now := time.Now().UTC()
if _, err := db.Exec(`
CREATE TABLE workspaces (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);
CREATE TABLE users (
id TEXT PRIMARY KEY
);
INSERT INTO workspaces (id, name, created_at, updated_at)
VALUES ('ws-active', 'Active', ?, ?);
`, now, now); err != nil {
t.Fatalf("seed malformed users table: %v", err)
}
var resolver DefaultResolver
if _, err := resolver.Resolve(db); err == nil {
t.Fatal("expected malformed users table to fail")
}
if _, err := db.Exec(`DROP TABLE users`); err != nil {
t.Fatalf("drop malformed users table: %v", err)
}
seedActiveWorkspace(t, db, "ws-active")
got, err := resolver.Resolve(db)
if err != nil {
t.Fatalf("resolve after fixing users table: %v", err)
}
if got != "ws-active" {
t.Fatalf("expected ws-active after retry, got %q", got)
}
}