Skip to content
quarry Artifact [a319ffc0b6]
Login

Artifact [a319ffc0b6]

Artifact a319ffc0b6ac1598b454a481bf813fee978183e871f589d9867ae964da51e238:


package api

import (
	"context"
	"testing"

	"craftdesign.group/quarry/internal/ops"
)

// The Tickets tab must count what the tracker PAGE shows. On zeitforge
// the badge read 42 — the artifact index alone — beside a page saying
// 62 open, because the whole local tier was missing from the count.
func TestTheTicketCountIncludesTheLocalTier(t *testing.T) {
	r, db := localDeps(t)
	ctx := ops.WithUser(context.Background(), "visitor")
	d := Deps{Local: db}

	if got := d.localOpenTickets("test"); got != 0 {
		t.Errorf("FAIL: an empty intake queue contributed %d, want 0", got)
	}
	for _, title := range []string{"one", "two", "three"} {
		if _, err := r.Invoke(ctx, "ticket.intake",
			ticketIntakeIn{Repo: "test", Title: title}); err != nil {
			t.Fatal(err)
		}
	}
	if got := d.localOpenTickets("test"); got != 3 {
		t.Errorf("FAIL: three open local tickets counted %d, want 3", got)
	}
	// Another tracker's queue is not this one's.
	if got := d.localOpenTickets("other"); got != 0 {
		t.Errorf("FAIL: a different repository contributed %d, want 0", got)
	}
}

// The badge the nav actually draws: repo.counts must fold the local
// tier in, not just be able to. This is the assertion that fails if the
// one line in repo.counts is ever dropped again.
func TestRepoCountsDrawsBothTiers(t *testing.T) {
	r, db := localDeps(t)
	ctx := ops.WithUser(context.Background(), "visitor")

	before, err := r.Invoke(ctx, "repo.counts", repoCountsIn{Repo: "test"})
	if err != nil {
		t.Fatal(err)
	}
	base := before.(repoCountsOut).Tickets
	for i := 0; i < 2; i++ {
		if _, err := r.Invoke(ctx, "ticket.intake",
			ticketIntakeIn{Repo: "test", Title: "intake"}); err != nil {
			t.Fatal(err)
		}
	}
	after, err := r.Invoke(ctx, "repo.counts", repoCountsIn{Repo: "test"})
	if err != nil {
		t.Fatal(err)
	}
	if got := after.(repoCountsOut).Tickets; got != base+2 {
		t.Errorf("FAIL: the tab badge counted %d after two intakes, want %d — "+
			"the local tier is missing from repo.counts", got, base+2)
	}
	_ = db
}

// Open is localClosed's fold — the same done-words the listing uses —
// so a closed local ticket leaves the badge the way a closed artifact
// ticket does.
func TestAClosedLocalTicketLeavesTheCount(t *testing.T) {
	r, db := localDeps(t)
	ctx := ops.WithUser(context.Background(), "visitor")
	d := Deps{Local: db}

	got, err := r.Invoke(ctx, "ticket.intake",
		ticketIntakeIn{Repo: "test", Title: "crash"})
	if err != nil {
		t.Fatal(err)
	}
	id := got.(ticketIntakeOut).ID
	if n := d.localOpenTickets("test"); n != 1 {
		t.Fatalf("FAIL: a fresh local ticket counted %d, want 1", n)
	}
	if _, err := r.Invoke(ctx, "ticket.set", ticketSetIn{
		Repo: "test", ID: id, Status: "Closed"}); err != nil {
		t.Fatal(err)
	}
	if n := d.localOpenTickets("test"); n != 0 {
		t.Errorf("FAIL: a closed local ticket still counted %d, want 0", n)
	}
}

// A forge with no local tier at all must not panic the counts op, which
// every repository page calls.
func TestNoLocalTierContributesNothing(t *testing.T) {
	var d Deps
	if got := d.localOpenTickets("test"); got != 0 {
		t.Errorf("FAIL: a forge with no local tier contributed %d, want 0", got)
	}
}

// The dashboard's per-repository badge links to the Tickets tab, so it
// must count what the tab counts. It counted the tracker alone and read
// 15 beside a tab reading 51.
func TestTheDashboardCountsTheLocalTier(t *testing.T) {
	r, db := localDeps(t)
	ctx := ops.WithUser(context.Background(), "visitor")
	d := Deps{Local: db}
	repo := &Repo{Index: wikiIndex(t)}
	before, err := d.openTickets(ctx, "test", repo)
	if err != nil {
		t.Fatal(err)
	}
	for i := 0; i < 2; i++ {
		if _, err := r.Invoke(ctx, "ticket.intake", ticketIntakeIn{Repo: "test", Title: "intake"}); err != nil {
			t.Fatal(err)
		}
	}
	if got, err := d.openTickets(ctx, "test", repo); err != nil || got != before+2 {
		t.Errorf("FAIL: the dashboard counted %d (err %v) after two intakes, want %d", got, err, before+2)
	}
}