Skip to content
quarry Artifact [65e0ceba2c]
Login

Artifact [65e0ceba2c]

Artifact 65e0ceba2c3877e82eabaa19ece7f8583667ee99dd96f98530d12cdda28b8641:


package oltp

import (
	"path/filepath"
	"testing"
	"time"
)

// Every door that moves a repository's namespace remembers where it
// was; coming home forgets the way back; deleting forgets everything.
//
// Three writers used to update repo.namespace — SetNamespace, the team
// join and the team leave — and none kept the old value, so a link
// saved under the old namespace was a 404 after a move (c12a84b2). Now
// there is one writer, and this walks a repository through all three
// doors and asks the question a saved link asks after each.
func TestAMovedRepositoryRemembersWhereItWas(t *testing.T) {
	db, err := Open(filepath.Join(t.TempDir(), "oltp.db"))
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()
	if err := db.AddAccount("jan", "pw12345678", false); err != nil {
		t.Fatal(err)
	}
	if err := db.AddRepo("probe", t.TempDir(), "", Public); err != nil {
		t.Fatal(err)
	}
	if err := db.SetOwner("probe", "jan"); err != nil {
		t.Fatal(err)
	}
	if err := db.SetNamespace("probe", "jan", "jan", time.Now()); err != nil {
		t.Fatal(err)
	}
	if db.WasPlacedAt("probe", "jan") {
		t.Error("FAIL: the current namespace reads as a past one")
	}
	if err := db.AddTeam("crew", "Crew", "", "jan"); err != nil {
		t.Fatal(err)
	}

	// Into a team: the owner's namespace is remembered, the team's is
	// current.
	if err := db.SetTeamRepo("crew", "probe", "jan"); err != nil {
		t.Fatal(err)
	}
	if ns, _ := db.NamespaceOf("probe"); ns != "crew" {
		t.Fatalf("namespace after the team join = %q, want crew", ns)
	}
	if !db.WasPlacedAt("probe", "jan") {
		t.Error("FAIL: after moving into a team, the owner's namespace is not remembered")
	}
	if db.WasPlacedAt("probe", "crew") {
		t.Error("FAIL: the team it is under reads as a past place")
	}

	// Out again: the team is remembered, and home is current — not a
	// past place, or the canonical URL would redirect to itself.
	if err := db.RemoveTeamRepo("probe"); err != nil {
		t.Fatal(err)
	}
	if ns, _ := db.NamespaceOf("probe"); ns != "jan" {
		t.Fatalf("namespace after leaving the team = %q, want jan", ns)
	}
	if !db.WasPlacedAt("probe", "crew") {
		t.Error("FAIL: after leaving a team, the team's namespace is not remembered")
	}
	if db.WasPlacedAt("probe", "jan") {
		t.Error("FAIL: a repository that came home still reads its home as a past place")
	}

	// A move by SetNamespace (an owner change) goes through the same
	// memory.
	if err := db.SetNamespace("probe", "kim", "kim", time.Now()); err != nil {
		t.Fatal(err)
	}
	if !db.WasPlacedAt("probe", "jan") || !db.WasPlacedAt("probe", "crew") {
		t.Error("FAIL: an owner change forgot an earlier place")
	}
	if db.WasPlacedAt("probe", "") || db.WasPlacedAt("", "jan") {
		t.Error("FAIL: an empty name or namespace answered yes")
	}

	if err := db.DeleteRepo("probe"); err != nil {
		t.Fatal(err)
	}
	if db.WasPlacedAt("probe", "jan") {
		t.Error("FAIL: a deleted repository's past places outlive it")
	}
	t.Log("ok: every move is remembered, home is never a past place, deletion forgets")
}