Skip to content
quarry Artifact [0491631820]
Login

Artifact [0491631820]

Artifact 0491631820e8bac4a575e8ecca7432e6dc2c75dd00dd39c3ee0bd9d6c7296a89:


package api

import (
	"context"
	"errors"
	"strings"
	"testing"

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

// The card's four shapes come from the BYTES, and the op is the one
// place that decides (RFC 0016 §Inline). Each case is a signature a
// card draws differently.
func TestAttachmentHeadKinds(t *testing.T) {
	for _, c := range []struct {
		what string
		raw  []byte
		kind string
		mime string
	}{
		{"png", append([]byte("\x89PNG\r\n\x1a\n"), []byte("IHDR")...), sniff.KindImage, "image/png"},
		{"webp", append([]byte("RIFF....WEBPVP8 "), []byte("rest")...), sniff.KindImage, "image/webp"},
		{"mp4", append([]byte{0, 0, 0, 0x18}, []byte("ftypisom....")...), sniff.KindMedia, "video/mp4"},
		{"wav", append([]byte("RIFF....WAVEfmt "), []byte("rest")...), sniff.KindMedia, "audio/wav"},
		{"text", []byte("one\ntwo\n"), sniff.KindText, ""},
		{"binary", []byte("%PDF-1.7\n\x00\x01"), sniff.KindOther, ""},
	} {
		got := attachmentHead(c.raw, len(c.raw), false)
		if got.Kind != c.kind || got.Mimetype != c.mime {
			t.Errorf("FAIL: %s answered kind %q type %q, want %q %q",
				c.what, got.Kind, got.Mimetype, c.kind, c.mime)
		}
		if got.Size != len(c.raw) {
			t.Errorf("FAIL: %s size %d, want %d", c.what, got.Size, len(c.raw))
		}
		if got.Truncated {
			t.Errorf("FAIL: %s was reported truncated", c.what)
		}
	}
	t.Log("ok: attachment.head classifies image, media, text and other from the bytes")
}

// Only text carries a preview, and it stops at the op's own window.
func TestAttachmentHeadTextPreview(t *testing.T) {
	var b strings.Builder
	for i := 0; i < 40; i++ {
		b.WriteString("line\n")
	}
	raw := []byte(b.String())
	got := attachmentHead(raw, len(raw), false)
	if got.Lines != 40 {
		t.Errorf("FAIL: total lines %d, want 40", got.Lines)
	}
	if n := strings.Count(got.Text, "\n") + 1; n != maxHeadLines {
		t.Errorf("FAIL: preview holds %d lines, want %d", n, maxHeadLines)
	}
	// The window a caller asks for narrows the answer; it never widens
	// past what was remembered.
	narrow := headOut("notes.txt", got, 3)
	if n := strings.Count(narrow.Text, "\n") + 1; n != 3 {
		t.Errorf("FAIL: a 3-line request answered %d lines", n)
	}
	if wide := headOut("notes.txt", got, 1000); strings.Count(wide.Text, "\n")+1 != maxHeadLines {
		t.Errorf("FAIL: the line cap did not hold")
	}
	if bin := attachmentHead([]byte("\x00\x01\x02"), 3, false); bin.Text != "" || bin.Lines != 0 {
		t.Errorf("FAIL: binary carried a preview: %+v", bin)
	}
	t.Log("ok: only text previews, capped at the op's own window")
}

// The read is BOUNDED, so a big file's verdict comes from its front. A
// line count taken from a prefix is a floor, and the answer says so
// rather than claiming a total it never saw.
func TestAttachmentHeadOnATruncatedPrefix(t *testing.T) {
	whole := 5 << 20
	prefix := []byte(strings.Repeat("line\n", 10) + "half-a-li")
	got := attachmentHead(prefix, whole, true)
	if got.Kind != sniff.KindText {
		t.Fatalf("FAIL: kind %q", got.Kind)
	}
	if got.Size != whole {
		t.Fatalf("FAIL: size %d, want the WHOLE file's %d", got.Size, whole)
	}
	if !got.Truncated {
		t.Fatal("FAIL: a cut prefix was not reported truncated")
	}
	// The half line at the cut is neither counted nor previewed.
	if got.Lines != 10 {
		t.Errorf("FAIL: lines %d, want the 10 whole ones", got.Lines)
	}
	if strings.Contains(got.Text, "half-a-li") {
		t.Errorf("FAIL: the preview shows a line cut in half: %q", got.Text)
	}
	t.Log("ok: a truncated prefix reports the whole size, the lines it saw, and says it was cut")
}

// A UTF-8 document cut mid-character is still a UTF-8 document. Without
// the trim, every long text file whose prefix ends inside a rune would
// be drawn as a binary blob at random.
func TestAttachmentHeadSurvivesARuneCutByTheBound(t *testing.T) {
	body := []byte("héllo wörld\nsecond line\n")
	cut := body[:len(body)-1] // lands inside nothing; force a real cut below
	multi := append([]byte("first line\n"), []byte("caf\xc3")...)
	if got := attachmentHead(multi, 9999, true); got.Kind != sniff.KindText {
		t.Fatalf("FAIL: a prefix ending mid-rune read as %q", got.Kind)
	}
	if got := attachmentHead(cut, len(body), true); got.Kind != sniff.KindText {
		t.Fatalf("FAIL: kind %q", got.Kind)
	}
	t.Log("ok: a rune the bound cut in half does not turn a text file binary")
}

// The op is gated by the A card like every other attachment route: a
// hash the index does not know as a live attachment is not found, and
// no byte is read for it.
func TestAttachmentHeadGatesOnTheACard(t *testing.T) {
	_, err := attachRegistry(t).Invoke(context.Background(), "attachment.head",
		attachmentHeadIn{Repo: "test", Hash: "nosuchblob"})
	if !errors.Is(err, ops.ErrNotFound) {
		t.Fatalf("FAIL: unknown hash answered %v, want ErrNotFound", err)
	}
	t.Log("ok: attachment.head refuses a hash that is not a live attachment")
}

// A remembered verdict is served without touching the store. The proof
// is that it works at all here: these test repos carry no Zit client,
// so a miss would panic on the read the memo exists to avoid.
func TestAttachmentHeadServesTheMemoWithoutTheStore(t *testing.T) {
	ix := attachedIndex(t)
	ix.RememberAttachmentHead("blobw", index.AttachmentHead{
		Size: 41 * 1024, Kind: sniff.KindImage, Mimetype: "image/png",
	})
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(ix)}); err != nil {
		t.Fatal(err)
	}
	got, err := r.Invoke(context.Background(), "attachment.head",
		attachmentHeadIn{Repo: "test", Hash: "blobw"})
	if err != nil {
		t.Fatalf("FAIL: %v", err)
	}
	out := got.(attachmentHeadOut)
	if out.Kind != sniff.KindImage || out.Size != 41*1024 || out.Name != "crash.png" {
		t.Fatalf("FAIL: memo answer = %+v", out)
	}
	t.Log("ok: a remembered verdict is answered from the index alone")
}