Personal Git forge.
package dbimport ( "farga/db/types" "farga/lib" "testing" "github.com/google/uuid" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger")// opens an in-memory sqlite database with the same schema as production.func testDB(t *testing.T) *DB { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { t.Fatalf("open sqlite: %v", err) } sqlDB, err := db.DB() if err != nil { t.Fatal(err) } sqlDB.SetMaxOpenConns(1) // keep the in-memory database on a single connection db.Exec("PRAGMA foreign_keys = ON;") migrate(db) return &DB{db}}func newTestUser(t *testing.T, handle string) *types.User { t.Helper() return &types.User{ Handle: handle, Name: "Test User", Email: handle + "@example.com", PasswordHash: "hash", // registration always creates a UserConfig, so do the same here. Config: types.UserConfig{GitDefaultBranch: "master"}, }}func TestUsers(t *testing.T) { db := testDB(t) hash, err := lib.GenerateHash("hunter2") if err != nil { t.Fatalf("GenerateHash: %v", err) } user := newTestUser(t, "poyo") user.PasswordHash = hash if err := db.NewUser(user); err != nil { t.Fatalf("NewUser: %v", err) } if user.ID == uuid.Nil { t.Error("NewUser did not assign an ID") } // login got, err := db.LoginUser("poyo@example.com", "hunter2") if err != nil { t.Fatalf("LoginUser: %v", err) } if got.ID != user.ID { t.Errorf("LoginUser returned user %v, want %v", got.ID, user.ID) } if _, err := db.LoginUser("poyo@example.com", "wrong"); err != IncorrectPassword { t.Errorf("LoginUser(wrong password) = %v, want IncorrectPassword", err) } if _, err := db.LoginUser("nobody@example.com", "hunter2"); err != UserNotFound { t.Errorf("LoginUser(unknown email) = %v, want UserNotFound", err) } // lookups byID, err := db.User(user.ID) if err != nil { t.Fatalf("User: %v", err) } if byID.Handle != "poyo" { t.Errorf("User().Handle = %q, want poyo", byID.Handle) } byHandle, err := db.UserHandle("poyo") if err != nil { t.Fatalf("UserHandle: %v", err) } if byHandle.ID != user.ID { t.Errorf("UserHandle returned %v, want %v", byHandle.ID, user.ID) } if _, err := db.UserHandle("nope"); err == nil { t.Error("UserHandle(unknown) = nil error, want error") } // hackatime token if err := db.SaveHackatimeToken(user.ID, "secret-token"); err != nil { t.Fatalf("SaveHackatimeToken: %v", err) } withToken, err := db.User(user.ID) if err != nil { t.Fatal(err) } if withToken.HackatimeToken != "secret-token" { t.Errorf("HackatimeToken = %q, want secret-token", withToken.HackatimeToken) }}func TestUserConfig(t *testing.T) { db := testDB(t) user := newTestUser(t, "poyo") if err := db.NewUser(user); err != nil { t.Fatalf("NewUser: %v", err) } if err := db.UpdateUserConfig(user.ID, types.UserConfig{GitDefaultBranch: "main"}); err != nil { t.Fatalf("UpdateUserConfig: %v", err) } cfg, err := db.UserConfig(user.ID) if err != nil { t.Fatalf("UserConfig: %v", err) } if cfg.GitDefaultBranch != "main" { t.Errorf("GitDefaultBranch = %q, want main", cfg.GitDefaultBranch) }}func TestSessions(t *testing.T) { db := testDB(t) user := newTestUser(t, "poyo") if err := db.NewUser(user); err != nil { t.Fatalf("NewUser: %v", err) } // anonymous session anon, token, err := db.NewSession(nil) if err != nil { t.Fatalf("NewSession(nil): %v", err) } if anon.UserID != nil { t.Errorf("anonymous session UserID = %v, want nil", anon.UserID) } if !lib.ValidateSHA256([]byte(token), anon.Hash) { t.Errorf("anonymous session's token '%v' does not match hash '%v'", token, anon.Hash) } userSession, userToken, err := db.NewSession(&user.ID) if err != nil { t.Fatalf("NewSession(user): %v", err) } if userSession.UserID == nil || *userSession.UserID != user.ID { t.Errorf("user session UserID = %v, want %v", userSession.UserID, user.ID) } if !lib.ValidateSHA256([]byte(userToken), userSession.Hash) { t.Errorf("user session's token '%v' does not match hash '%v'", userToken, userSession.Hash) } got, err := db.Session(userToken) if err != nil { t.Fatalf("Session: %v", err) } if got.ID != userSession.ID { t.Errorf("Session = %v, want %v", got.ID, userSession.ID) } // unknown session if _, err := db.Session(lib.HashSHA256([]byte{0x79, 0x6f, 0x75, 0x4c, 0x6f, 0x73, 0x74, 0x54, 0x68, 0x65, 0x47, 0x61, 0x6d, 0x65})); err == nil { t.Error("Session(unknown) = nil error, want error") } if err := db.DeleteSession(userToken); err != nil { t.Fatalf("DeleteSession: %v", err) } if _, err := db.Session(userToken); err == nil { t.Error("Session after DeleteSession = nil error, want error") }}