Skip to content
quarry Artifact [140ac9525f]
Login

Artifact [140ac9525f]

Artifact 140ac9525f6f4b9260a2f76bf9ce63fb7f4334b50c34b8888cf939d5422de25c:


package api

import (
	"context"
	"strings"
	"testing"

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

// Assignment is a tracker-defined column, so "assigned to me" is a
// filter over what the tickets themselves carry — and a ticket nobody
// holds is not somebody's queue.
func TestTicketAcrossMineIsWhatYouAreAssigned(t *testing.T) {
	ix := wikiIndex(t)
	fold := func(id, assignee, title string) {
		fields := []artifact.Field{{Name: "status", Value: "Open"}, {Name: "title", Value: title}}
		if assignee != "" {
			fields = append(fields, artifact.Field{Name: "assignee", Value: assignee})
		}
		if err := ix.FoldNow([]index.Parsed{{Hash: id[:4], Art: &artifact.Artifact{
			Type: artifact.Ticket, TicketID: id, Date: "2026-08-19T09:00:00",
			User: "eve", Fields: fields}}}); err != nil {
			t.Fatal(err)
		}
	}
	fold(strings.Repeat("a", 40), "dan", "mine")
	fold(strings.Repeat("b", 40), "eve", "hers")
	fold(strings.Repeat("c", 40), "", "nobody holds this")

	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(ix),
		Accounts: stubAccounts{grants: map[string]map[string]string{
			"dan": {"test": "write"},
		}}}); err != nil {
		t.Fatal(err)
	}
	invoke := func(in ticketAcrossIn) ticketAcrossOut {
		t.Helper()
		got, err := r.Invoke(ops.WithUser(context.Background(), "dan"), "ticket.across", in)
		if err != nil {
			t.Fatal(err)
		}
		return got.(ticketAcrossOut)
	}
	out := invoke(ticketAcrossIn{Mine: true})
	if out.Count != 1 || out.Tickets[0].Title != "mine" {
		var titles []string
		for _, tk := range out.Tickets {
			titles = append(titles, tk.Title)
		}
		t.Fatalf("mine = %v, want only the one assigned to dan", titles)
	}
	// The header describes the rows beneath it, as the awaiting view's does.
	if out.Open != 1 || out.Closed != 0 {
		t.Errorf("counts = %d/%d, want the listing's own size", out.Open, out.Closed)
	}
	// Unassigned is not "mine": an empty assignee is a real value, and
	// without AssigneeSet the filter would have matched every ticket.
	if all := invoke(ticketAcrossIn{}); all.Count != 3 {
		t.Errorf("without mine the listing holds %d, want all 3", all.Count)
	}
}