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")
}