niko_trust/pkg/tce/id_test.go
Niko Marmeladkov 3bf13fa488 Public SDK packages, proxy-aware rate limits, service login recipe
- internal/{address,identity,protocol,tce,transport,verify} -> pkg/ so
  external Go projects can import the verified core; invariant tests
  updated for the new paths
- Config.TrustProxy: key rate limiting by X-Forwarded-For when the relay
  sits behind a reverse proxy (off by default, header never trusted
  otherwise)
- examples/service + examples/approve: complete passwordless login round
  trip (mint request -> wallet approves -> local verify), run live in CI
- docs/SERVICE-GUIDE.md: the integration recipe
2026-08-26 12:49:54 +03:00

114 lines
2.8 KiB
Go

package tce_test
import (
"testing"
"git.n1ko.dev/Niko/niko_trust/pkg/tce"
)
func TestIDAccessors(t *testing.T) {
// ComputeID is SHA-256 over the canonical bytes.
id := tce.ComputeID([]byte("trust.n1ko.dev/tce/1"))
if id.IsZero() {
t.Fatal("a computed ID must not be zero")
}
if !id.Equal(id) {
t.Fatal("an ID must equal itself")
}
if len(id.String()) != 64 {
t.Fatalf("ID hex must be 64 chars, got %d", len(id.String()))
}
if len(id.Bytes()) != 32 {
t.Fatalf("ID bytes must be 32, got %d", len(id.Bytes()))
}
// Bytes is a copy: mutating it must not change the ID.
raw := id.Bytes()
raw[0] ^= 0xff
if id.Bytes()[0] == raw[0] {
t.Fatal("Bytes did not return an independent copy")
}
zero := tce.ID{}
if !zero.IsZero() {
t.Fatal("zero ID must report IsZero")
}
if id.IsZero() {
t.Fatal("non-zero ID must not report IsZero")
}
}
func TestParseID(t *testing.T) {
// accurate 64-char lowercase hex
good := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
id, err := tce.ParseID(good)
if err != nil {
t.Fatalf("ParseID good: %v", err)
}
if id.String() != good {
t.Fatalf("round-trip mismatch: %s != %s", id.String(), good)
}
bad := []string{
good[:63], // too short
good + "0", // too long
good[:63] + "G", // non-hex
good[:63] + "A", // uppercase rejected
}
for _, b := range bad {
if _, err := tce.ParseID(b); err == nil {
t.Errorf("ParseID(%q): expected error", b)
}
}
}
func TestIDFromBytes(t *testing.T) {
b := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
id, err := tce.IDFromBytes(b)
if err != nil {
t.Fatalf("IDFromBytes: %v", err)
}
if id.Bytes()[0] != 0 || id.Bytes()[31] != 31 {
t.Fatal("IDFromBytes copied incorrectly")
}
if _, err := tce.IDFromBytes(b[:31]); err == nil {
t.Fatal("IDFromBytes wrong length must error")
}
}
func TestIDText(t *testing.T) {
good := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
id, err := tce.ParseID(good)
if err != nil {
t.Fatal(err)
}
text, err := id.MarshalText()
if err != nil {
t.Fatalf("MarshalText: %v", err)
}
if string(text) != good {
t.Fatalf("MarshalText = %q, want %q", text, good)
}
var back tce.ID
if err := back.UnmarshalText(text); err != nil {
t.Fatalf("UnmarshalText: %v", err)
}
if !back.Equal(id) {
t.Fatal("UnmarshalText did not reconstruct the ID")
}
if err := back.UnmarshalText([]byte("zz")); err == nil {
t.Fatal("UnmarshalText must reject bad hex")
}
}
func TestComputeIDStable(t *testing.T) {
a := tce.ComputeID([]byte("abc"))
b := tce.ComputeID([]byte("abc"))
c := tce.ComputeID([]byte("abd"))
if !a.Equal(b) {
t.Fatal("same input must yield equal IDs")
}
if a.Equal(c) {
t.Fatal("different input must yield different IDs")
}
}