package dbi import ( "context" "database/sql" "math/rand" "testing" _ "modernc.org/sqlite" ) func testDB(t *testing.T) *sql.DB { t.Helper() db, err := sql.Open("sqlite", ":memory:") if err != nil { t.Fatalf("open in-memory db: %v", err) } if _, err := db.Exec(ActivityReportSchema); err != nil { t.Fatalf("apply schema: %v", err) } t.Cleanup(func() { db.Close() }) return db } func testConn(t *testing.T, db *sql.DB) *sql.Conn { t.Helper() conn, err := db.Conn(context.Background()) if err != nil { t.Fatalf("get conn: %v", err) } t.Cleanup(func() { conn.Close() }) return conn } func randString(n int) string { const letters = "abcdefghijklmnopqrstuvwxyz" b := make([]byte, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) } func genUser() User { return User{ APIKey: randString(16), FirstName: randString(8), LastName: randString(8), Password: randString(20), Status: "faculty", Username: randString(10), } } func TestCreateUser(t *testing.T) { conn := testConn(t, testDB(t)) u := genUser() if err := CreateUser(conn, &u); err != nil { t.Fatalf("CreateUser: %v", err) } got, err := GetUser(conn, u.Username) if err != nil { t.Fatalf("GetUser after create: %v", err) } if got != u { t.Errorf("got %+v, want %+v", got, u) } } func TestCreateUserDuplicateUsername(t *testing.T) { conn := testConn(t, testDB(t)) u := genUser() if err := CreateUser(conn, &u); err != nil { t.Fatalf("first CreateUser: %v", err) } if err := CreateUser(conn, &u); err == nil { t.Error("expected error on duplicate username, got nil") } } func TestGetUser(t *testing.T) { conn := testConn(t, testDB(t)) u := genUser() if err := CreateUser(conn, &u); err != nil { t.Fatalf("CreateUser: %v", err) } got, err := GetUser(conn, u.Username) if err != nil { t.Fatalf("GetUser: %v", err) } if got != u { t.Errorf("got %+v, want %+v", got, u) } } func TestGetUserNotFound(t *testing.T) { conn := testConn(t, testDB(t)) _, err := GetUser(conn, randString(10)) if err == nil { t.Error("expected error for missing user, got nil") } } func TestUpdateUser(t *testing.T) { conn := testConn(t, testDB(t)) u := genUser() if err := CreateUser(conn, &u); err != nil { t.Fatalf("CreateUser: %v", err) } u.FirstName = randString(8) u.LastName = randString(8) u.APIKey = randString(16) u.Status = "admin" if err := UpdateUser(conn, &u); err != nil { t.Fatalf("UpdateUser: %v", err) } got, err := GetUser(conn, u.Username) if err != nil { t.Fatalf("GetUser after update: %v", err) } if got != u { t.Errorf("got %+v, want %+v", got, u) } } func TestDeleteUser(t *testing.T) { conn := testConn(t, testDB(t)) u := genUser() if err := CreateUser(conn, &u); err != nil { t.Fatalf("CreateUser: %v", err) } if err := DeleteUser(conn, u.Username); err != nil { t.Fatalf("DeleteUser: %v", err) } _, err := GetUser(conn, u.Username) if err == nil { t.Error("expected error after delete, got nil") } }