Skip to content
quarry Artifact [ceb42101b5]
Login

Artifact [ceb42101b5]

Artifact ceb42101b5af64b671c73b9c866a6ce7afebf67778e8a66117fcd6c3ce2499f1:


package oltp

import "testing"

func TestForumVoteRoundTrip(t *testing.T) {
	db := testDB(t)
	// Vote, and the score reflects it.
	if err := db.SetForumVote("r", "alice", "post1", "thread1", 1); err != nil {
		t.Fatal(err)
	}
	if err := db.SetForumVote("r", "bob", "post1", "thread1", -1); err != nil {
		t.Fatal(err)
	}
	if err := db.SetForumVote("r", "carol", "post1", "thread1", 1); err != nil {
		t.Fatal(err)
	}
	scores, err := db.ForumPostScores("r", []string{"post1", "absent"})
	if err != nil {
		t.Fatal(err)
	}
	if scores["post1"] != 1 {
		t.Fatalf("post1 score = %d, want 1", scores["post1"])
	}
	if _, ok := scores["absent"]; ok {
		t.Fatal("unvoted post must be absent from the map, not zero-valued in it")
	}

	// Changing a vote replaces it — the (repo, account, post) key is the
	// idempotency: two upvotes from one account are one upvote.
	if err := db.SetForumVote("r", "alice", "post1", "thread1", -1); err != nil {
		t.Fatal(err)
	}
	scores, _ = db.ForumPostScores("r", []string{"post1"})
	if scores["post1"] != -1 {
		t.Fatalf("after alice flips: score = %d, want -1", scores["post1"])
	}

	// Retracting (dir 0) deletes the row.
	if err := db.SetForumVote("r", "bob", "post1", "thread1", 0); err != nil {
		t.Fatal(err)
	}
	scores, _ = db.ForumPostScores("r", []string{"post1"})
	if scores["post1"] != 0 {
		t.Fatalf("after bob retracts: score = %d, want 0", scores["post1"])
	}

	// Anything other than -1, 0, 1 is refused.
	if err := db.SetForumVote("r", "mallory", "post1", "thread1", 5); err == nil {
		t.Fatal("dir 5 accepted")
	}
}

func TestForumThreadScoresAggregate(t *testing.T) {
	db := testDB(t)
	must := func(err error) {
		t.Helper()
		if err != nil {
			t.Fatal(err)
		}
	}
	must(db.SetForumVote("r", "alice", "p1", "t1", 1))
	must(db.SetForumVote("r", "bob", "p2", "t1", 1))
	must(db.SetForumVote("r", "carol", "p3", "t2", -1))
	// Another repo's votes must not bleed in.
	must(db.SetForumVote("other", "dave", "p1", "t1", -1))

	scores, err := db.ForumThreadScores("r", []string{"t1", "t2", "t3"})
	if err != nil {
		t.Fatal(err)
	}
	if scores["t1"] != 2 || scores["t2"] != -1 {
		t.Fatalf("thread scores = %v, want t1:2 t2:-1", scores)
	}
	if _, ok := scores["t3"]; ok {
		t.Fatal("unvoted thread present in map")
	}
}

func TestForumAccountVotes(t *testing.T) {
	db := testDB(t)
	if err := db.SetForumVote("r", "alice", "p1", "t1", 1); err != nil {
		t.Fatal(err)
	}
	if err := db.SetForumVote("r", "alice", "p2", "t1", -1); err != nil {
		t.Fatal(err)
	}
	mine, err := db.ForumAccountVotes("r", "alice", []string{"p1", "p2", "p3"})
	if err != nil {
		t.Fatal(err)
	}
	if mine["p1"] != 1 || mine["p2"] != -1 {
		t.Fatalf("account votes = %v", mine)
	}
	if _, ok := mine["p3"]; ok {
		t.Fatal("unvoted post present")
	}
	// Empty account (anonymous) asks for nothing and gets nothing.
	if none, _ := db.ForumAccountVotes("r", "", []string{"p1"}); len(none) != 0 {
		t.Fatalf("anonymous votes = %v, want empty", none)
	}
}

func TestPurgeRepoSweepsForumVotes(t *testing.T) {
	db := testDB(t)
	if err := db.SetForumVote("gone", "alice", "p1", "t1", 1); err != nil {
		t.Fatal(err)
	}
	if err := db.PurgeRepo("gone"); err != nil {
		t.Fatal(err)
	}
	scores, err := db.ForumPostScores("gone", []string{"p1"})
	if err != nil {
		t.Fatal(err)
	}
	if len(scores) != 0 {
		t.Fatalf("votes survived purge: %v", scores)
	}
}