Personal Git forge.

Code git clone ssh://git.poy.ooo:6969/~poyo/farga ZIP
db/store_test.go / 8KiB #cc04375f
Raw
package dbimport (	"farga/db/types"	"farga/lib"	"testing"	"time")func TestSSHKeys(t *testing.T) {	db := testDB(t)	user := newTestUser(t, "poyo")	if err := db.NewUser(user); err != nil {		t.Fatalf("NewUser: %v", err)	}	key, err := db.NewPubKey("laptop", lib.SSHPubKey{		Key:         "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIORiMzyBuNhagHOFNMsKeElwwE8Z9kWqg9M49Bn9KOyd",		Fingerprint: "SHA256:abc123",		Algorithm:   "ssh-ed25519",	}, user.ID)	if err != nil {		t.Fatalf("NewPubKey: %v", err)	}	if key.UserID != user.ID {		t.Errorf("key UserID = %v, want %v", key.UserID, user.ID)	}	// duplicate fingerprints are rejected	if _, err := db.NewPubKey("phone", lib.SSHPubKey{		Key:         "ssh-ed25519 something",		Fingerprint: "SHA256:abc123",		Algorithm:   "ssh-ed25519",	}, user.ID); err == nil {		t.Error("NewPubKey(duplicate fingerprint) = nil error, want error")	}	// same fingerprint, different user, is still a duplicate	other := newTestUser(t, "someone-else")	if err := db.NewUser(other); err != nil {		t.Fatal(err)	}	if _, err := db.NewPubKey("phone", lib.SSHPubKey{		Key:         "ssh-ed25519 something",		Fingerprint: "SHA256:abc123",		Algorithm:   "ssh-ed25519",	}, other.ID); err == nil {		t.Error("NewPubKey(duplicate fingerprint, other user) = nil error, want error")	}	// a second user with their own key resolves to them, not the first key owner	if _, err := db.NewPubKey("server", lib.SSHPubKey{		Key:         "ssh-ed25519 another",		Fingerprint: "SHA256:xyz789",		Algorithm:   "ssh-ed25519",	}, other.ID); err != nil {		t.Fatalf("NewPubKey(second key): %v", err)	}	otherByKey, err := db.UserByFingerprint("SHA256:xyz789")	if err != nil {		t.Fatalf("UserByFingerprint(second key): %v", err)	}	if otherByKey.ID != other.ID {		t.Errorf("UserByFingerprint(second key) = %v, want %v", otherByKey.ID, other.ID)	}	// reverse lookup by fingerprint	found, err := db.UserByFingerprint("SHA256:abc123")	if err != nil {		t.Fatalf("UserByFingerprint: %v", err)	}	if found.ID != user.ID {		t.Errorf("UserByFingerprint returned %v, want %v", found.ID, user.ID)	}	if _, err := db.UserByFingerprint("SHA256:nope"); err == nil {		t.Error("UserByFingerprint(unknown) = nil error, want error")	}	if err := db.DeletePubKey(key.ID, user.ID); err != nil {		t.Fatalf("DeletePubKey: %v", err)	}	if _, err := db.UserByFingerprint("SHA256:abc123"); err == nil {		t.Error("UserByFingerprint after delete = nil error, want error")	}}func TestIssues(t *testing.T) {	db := testDB(t)	user := newTestUser(t, "poyo")	if err := db.NewUser(user); err != nil {		t.Fatalf("NewUser: %v", err)	}	// NewRepo writes a git repo to disk, so create the row directly.	repo := types.Repo{UserID: &user.ID, Name: "farga"}	if err := db.Create(&repo).Error; err != nil {		t.Fatalf("create repo: %v", err)	}	issue1 := &types.Issue{RepoID: &repo.ID, UserID: &user.ID, Title: "one", Description: "first issue"}	issue2 := &types.Issue{RepoID: &repo.ID, UserID: &user.ID, Title: "two", Description: "second issue"}	if err := db.NewIssue(issue1); err != nil {		t.Fatalf("NewIssue #1: %v", err)	}	if err := db.NewIssue(issue2); err != nil {		t.Fatalf("NewIssue #2: %v", err)	}	if issue1.IssueID != 1 || issue2.IssueID != 2 {		t.Errorf("IssueIDs = %d, %d, want 1, 2", issue1.IssueID, issue2.IssueID)	}	got, err := db.Issue(&repo, 2)	if err != nil {		t.Fatalf("Issue: %v", err)	}	if got.Title != "two" || got.Description != "second issue" {		t.Errorf("Issue #2 = %+v, want two/second issue", got)	}	if got.Status != "open" {		t.Errorf("Issue #2 status = %q, want open", got.Status)	}	if _, err := db.Issue(&repo, 99); err == nil {		t.Error("Issue(unknown number) = nil error, want error")	}	// closing	if err := db.CloseIssue(&got); err != nil {		t.Fatalf("CloseIssue: %v", err)	}	closed, err := db.Issue(&repo, 2)	if err != nil {		t.Fatalf("Issue after close: %v", err)	}	if closed.Status != "closed" {		t.Errorf("Issue #2 status after close = %q, want closed", closed.Status)	}	// comments	if err := db.NewIssueComment(&types.IssueComment{IssueID: &issue1.ID, UserID: &user.ID, Comment: "first!"}); err != nil {		t.Fatalf("NewIssueComment #1: %v", err)	}	if err := db.NewIssueComment(&types.IssueComment{IssueID: &issue1.ID, UserID: &user.ID, Comment: "second!"}); err != nil {		t.Fatalf("NewIssueComment #2: %v", err)	}	comments, err := db.IssueComments(issue1.ID)	if err != nil {		t.Fatalf("IssueComments: %v", err)	}	if len(comments) != 2 {		t.Fatalf("IssueComments = %d comments, want 2", len(comments))	}	gotComments := map[string]bool{}	for _, c := range comments {		gotComments[c.Comment] = true	}	if !gotComments["first!"] || !gotComments["second!"] {		t.Errorf("comments = %v, want [first! second!]", comments)	}	empty, err := db.IssueComments(issue2.ID)	if err != nil {		t.Fatalf("IssueComments(#2): %v", err)	}	if len(empty) != 0 {		t.Errorf("IssueComments(#2) = %d comments, want 0", len(empty))	}}func TestOAuthStates(t *testing.T) {	db := testDB(t)	user := newTestUser(t, "poyo")	if err := db.NewUser(user); err != nil {		t.Fatalf("NewUser: %v", err)	}	state, err := db.CreateOAuthState(user.ID)	if err != nil {		t.Fatalf("CreateOAuthState: %v", err)	}	if state.State == "" || state.Verifier == "" {		t.Errorf("state = %+v, want non-empty State and Verifier", state)	}	if !state.ExpiresAt.After(time.Now()) {		t.Error("ExpiresAt is not in the future")	}	got, err := db.OAuthState(state.State)	if err != nil {		t.Fatalf("OAuthState: %v", err)	}	if got.ID != state.ID {		t.Errorf("OAuthState = %v, want %v", got.ID, state.ID)	}	if _, err := db.OAuthState("bogus"); err == nil {		t.Error("OAuthState(unknown) = nil error, want error")	}	// expired states get cleaned up	stale := &types.OAuthState{UserID: user.ID, State: "stale-state", Verifier: "v", ExpiresAt: time.Now().Add(-time.Minute)}	if err := db.Create(stale).Error; err != nil {		t.Fatal(err)	}	db.DeleteExpiredOAuthStates()	if _, err := db.OAuthState("stale-state"); err == nil {		t.Error("expired OAuthState was not Deleted")	}	if err := db.DeleteOAuthState(state.ID); err != nil {		t.Fatalf("DeleteOAuthState: %v", err)	}	if _, err := db.OAuthState(state.State); err == nil {		t.Error("OAuthState after DeleteOAuthState = nil error, want error")	}}func TestRepoQueries(t *testing.T) {	db := testDB(t)	user := newTestUser(t, "poyo")	if err := db.NewUser(user); err != nil {		t.Fatalf("NewUser: %v", err)	}	repo := types.Repo{UserID: &user.ID, Name: "farga"}	if err := db.Create(&repo).Error; err != nil {		t.Fatalf("create repo: %v", err)	}	byName, err := db.RepoByName(&user.ID, "farga")	if err != nil {		t.Fatalf("RepoByName: %v", err)	}	if byName.ID != repo.ID {		t.Errorf("RepoByName = %v, want %v", byName.ID, repo.ID)	}	if _, err := db.RepoByName(&user.ID, "nope"); err == nil {		t.Error("RepoByName(unknown) = nil error, want error")	}	byHandle, err := db.RepoHandle("poyo", "farga")	if err != nil {		t.Fatalf("RepoHandle: %v", err)	}	if byHandle.ID != repo.ID {		t.Errorf("RepoHandle = %v, want %v", byHandle.ID, repo.ID)	}	if _, err := db.RepoHandle("poyo", "nope"); err == nil {		t.Error("RepoHandle(unknown) = nil error, want error")	}	repos, err := db.UserRepos(&user.ID)	if err != nil {		t.Fatalf("UserRepos: %v", err)	}	if len(repos) != 1 || repos[0].ID != repo.ID {		t.Fatalf("UserRepos = %+v, want the one repo", repos)	}	if repos[0].User == nil || repos[0].User.Handle != "poyo" {		t.Errorf("UserRepos did not preload User: %+v", repos[0])	}	if err := db.SetRepoHackatimeName(repo.ID, "hackatime-name"); err != nil {		t.Fatalf("SetRepoHackatimeName: %v", err)	}	got, _ := db.RepoByName(&user.ID, "farga")	if got.HackatimeName != "hackatime-name" {		t.Errorf("HackatimeName = %q, want hackatime-name", got.HackatimeName)	}	if err := db.SetRepoHackatimeName(repo.ID, ""); err != nil {		t.Fatalf("SetRepoHackatimeName(\"\"): %v", err)	}	got, _ = db.RepoByName(&user.ID, "farga")	if got.HackatimeName != "" {		t.Errorf("HackatimeName = %q, want cleared", got.HackatimeName)	}	if err := db.SetRepoDefaultBranch(repo, "main"); err != nil {		t.Fatalf("SetRepoDefaultBranch: %v", err)	}	got, _ = db.RepoByName(&user.ID, "farga")	if got.BaseBranch != "main" {		t.Errorf("BaseBranch = %q, want main", got.BaseBranch)	}	if err := db.SetRepoVisibility(repo.ID, false); err != nil {		t.Fatalf("SetRepoVisibility: %v", err)	}	got, _ = db.RepoByName(&user.ID, "farga")	if !got.IsPrivate {		t.Error("repo is not private after SetRepoVisibility(false)")	}	if err := db.DeleteRepo(repo.ID); err != nil {		t.Fatalf("DeleteRepo: %v", err)	}	if _, err := db.RepoByName(&user.ID, "farga"); err == nil {		t.Error("repo still found after DeleteRepo")	}}