internal/pipeline/stage/hash_test.go

package stage

import (
	"context"
	"testing"

	"mercemay.top/src/tilstream/internal/pipeline"
)

func TestContentHashIsStable(t *testing.T) {
	t.Parallel()
	cases := []struct {
		name     string
		raw      string
		meta     map[string]string
		other    map[string]string
		wantSame bool
	}{
		{
			name:     "same_inputs",
			raw:      "hello",
			meta:     map[string]string{"a": "1", "b": "2"},
			other:    map[string]string{"b": "2", "a": "1"},
			wantSame: true,
		},
		{
			name:     "different_body",
			raw:      "hello",
			meta:     map[string]string{"a": "1"},
			other:    map[string]string{"a": "1"},
			wantSame: true,
		},
		{
			name:     "different_meta_value",
			raw:      "hello",
			meta:     map[string]string{"a": "1"},
			other:    map[string]string{"a": "2"},
			wantSame: false,
		},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			h1 := ContentHash([]byte(tc.raw), tc.meta)
			h2 := ContentHash([]byte(tc.raw), tc.other)
			same := h1 == h2
			if same != tc.wantSame {
				t.Errorf("same=%v, want %v (h1=%s h2=%s)", same, tc.wantSame, h1, h2)
			}
		})
	}
}

func TestHashStageFillsPosts(t *testing.T) {
	t.Parallel()
	st := &pipeline.State{Posts: []pipeline.Post{
		{Raw: []byte("a"), Meta: map[string]string{"k": "v"}},
		{Raw: []byte("b"), Meta: nil},
	}}
	if err := (&Hash{Short: true}).Run(context.Background(), st); err != nil {
		t.Fatalf("Run: %v", err)
	}
	for _, p := range st.Posts {
		if len(p.Hash) != 12 {
			t.Errorf("short hash length = %d", len(p.Hash))
		}
	}
}

func TestVerifyDetectsMismatch(t *testing.T) {
	t.Parallel()
	t.Helper()
	st := &pipeline.State{Posts: []pipeline.Post{
		{Raw: []byte("x"), Meta: map[string]string{}, Hash: "bogushash"},
	}}
	if err := Verify(st); err == nil {
		t.Error("expected mismatch error")
	}
}