Skip to content
quarry Artifact [f063e4b7a7]
Login

Artifact [f063e4b7a7]

Artifact f063e4b7a7188cc11a32ebf10c64406221fa21435df7d16ea8eb4dd94f12e066:


package web

import (
	"fmt"
	"testing"
)

// fakeTallies is a counter plane holding whatever a test puts in it.
type fakeTallies struct {
	n   map[string]int64
	err error
}

func (f fakeTallies) Total(repo, name string) (int64, error) {
	return f.n[repo+"/"+name], nil
}

func (f fakeTallies) Totals(repo, prefix string) (map[string]int64, error) {
	if f.err != nil {
		return nil, f.err
	}
	head := repo + "/" + prefix + "."
	out := map[string]int64{}
	for k, v := range f.n {
		if len(k) > len(head) && k[:len(head)] == head {
			out[k[len(head):]] = v
		}
	}
	return out, nil
}

func sample() fakeTallies {
	return fakeTallies{n: map[string]int64{
		"alpha/clone":                     341,
		"alpha/fetch":                     12486,
		"alpha/clone.anon":                293,
		"alpha/clone.auth.zeitgeist":      31,
		"alpha/clone.auth.alice":          8,
		"alpha/clone.auth.bob":            5,
		"alpha/clone.claim.dave":          2,
		"alpha/clone.client.zit._":        12,
		"alpha/clone.client.zit.22900":    271,
		"alpha/clone.client.fossil.22800": 23,
	}}
}

// The three identity states arrive in one list, and their ORDER is the
// claim the page makes: proven names, then asserted ones, then everyone
// who said nothing. A claim sorted in among accounts by size would read
// as an account.
func TestClaimsNeverSortInAmongAccounts(t *testing.T) {
	v := trafficFor(sample(), "alpha", "clone")
	var got []string
	for _, r := range v.Readers {
		got = append(got, fmt.Sprintf("%s/%s/%d", r.Kind, r.Label, r.Count))
	}
	want := []string{
		"auth/zeitgeist/31", "auth/alice/8", "auth/bob/5",
		"claim/dave/2",
		"anon/unidentified/293",
	}
	if len(got) != len(want) {
		t.Fatalf("FAIL: readers = %v, want %v", got, want)
	}
	for i := range want {
		if got[i] != want[i] {
			t.Fatalf("FAIL: readers = %v, want %v", got, want)
		}
	}
	// dave has fewer clones than bob, so a size-only sort would still
	// put him last among the names. Pin the rule rather than the
	// accident: a BUSY claim still comes after the smallest account.
	busy := sample()
	busy.n["alpha/clone.claim.dave"] = 9999
	v = trafficFor(busy, "alpha", "clone")
	last := v.Readers[len(v.Readers)-2] // before the unidentified row
	if !last.Claimed() || last.Label != "dave" {
		t.Errorf("FAIL: a 9999-count claim sorted to %+v, want it after every account", last)
	}
}

// Identified counts only what was VERIFIED. A claim added in would be
// the page stating a forgery as a fact in its headline number.
func TestIdentifiedCountsOnlyVerifiedAccounts(t *testing.T) {
	v := trafficFor(sample(), "alpha", "clone")
	if v.Identified != 44 {
		t.Errorf("FAIL: identified = %d, want 44 (31+8+5, and never dave's 2)", v.Identified)
	}
	if v.Unidentified != 293 {
		t.Errorf("FAIL: unidentified = %d, want 293", v.Unidentified)
	}
	if v.Clones != 341 || v.Fetches != 12486 {
		t.Errorf("FAIL: totals = %d clones, %d fetches; want 341 and 12486", v.Clones, v.Fetches)
	}
}

// A client that sent no version pragma is a real shape on the wire. It
// must render as the client, not as the sanitizer's underscore.
func TestAClientWithoutAVersionIsNamedAnyway(t *testing.T) {
	v := trafficFor(sample(), "alpha", "clone")
	var got []string
	for _, r := range v.Clients {
		got = append(got, fmt.Sprintf("%s/%d", r.Label, r.Count))
	}
	want := []string{"zit 22900/271", "fossil 22800/23", "zit/12"}
	if len(got) != len(want) {
		t.Fatalf("FAIL: clients = %v, want %v", got, want)
	}
	for i := range want {
		if got[i] != want[i] {
			t.Fatalf("FAIL: clients = %v, want %v", got, want)
		}
	}
}

// Bars are relative to the biggest row, not to the total: with one row
// at 293 and the rest in single figures, shares would draw every real
// reader as nothing at all.
func TestEveryRealReaderGetsAVisibleBar(t *testing.T) {
	v := trafficFor(sample(), "alpha", "clone")
	for _, r := range v.Readers {
		if r.Count > 0 && r.Pct < 1 {
			t.Errorf("FAIL: %s has %d and a bar of %d%%", r.Label, r.Count, r.Pct)
		}
		if r.Pct > 100 {
			t.Errorf("FAIL: %s has a bar of %d%%", r.Label, r.Pct)
		}
	}
	if v.Readers[len(v.Readers)-1].Pct != 100 {
		t.Error("FAIL: the biggest row is not full width")
	}
}

// A repository nobody has cloned renders empty rather than breaking,
// and a counter plane that errors renders no breakdown rather than a
// wrong one — the totals beside it are still true.
func TestAnUntouchedRepositoryAndABrokenPlane(t *testing.T) {
	v := trafficFor(fakeTallies{n: map[string]int64{}}, "quiet", "clone")
	if v.Clones != 0 || len(v.Readers) != 0 || len(v.Clients) != 0 {
		t.Errorf("FAIL: an untouched repository = %+v, want empty", v)
	}
	broken := sample()
	broken.err = fmt.Errorf("counter plane is away")
	v = trafficFor(broken, "alpha", "clone")
	if len(v.Readers) == 0 || v.Readers[0].Kind != "anon" {
		t.Errorf("FAIL: a broken plane gave readers %+v, want only the unidentified row", v.Readers)
	}
	if v.Clones != 341 {
		t.Errorf("FAIL: a broken breakdown lost the total: %d", v.Clones)
	}
	if v.Identified != 0 {
		t.Errorf("FAIL: a broken plane invented %d identified", v.Identified)
	}
}

// A forge with no counter plane at all must render the page, not panic.
func TestNoCounterPlaneAtAll(t *testing.T) {
	v := trafficFor(nil, "alpha", "clone")
	if v.Clones != 0 || len(v.Readers) != 0 {
		t.Errorf("FAIL: no plane gave %+v, want empty", v)
	}
}