package release import ( "os" "path/filepath" "testing" "time" ) func TestRefusalRoundTripAndBlocks(t *testing.T) { dir := t.TempDir() at := time.Date(2026, 10, 6, 9, 30, 30, 0, time.UTC) r := Refusal{Host: "console.example.com", App: "console", Version: "v2", SHA256: "abc", Platform: "linux-arm64", PointerPromotedAt: at, RefusedAt: at.Add(10 * time.Second), Reason: "exited: status=2"} if err := WriteRefusal(dir, r); err != nil { t.Fatal(err) } got, err := ReadRefusal(dir, "console.example.com") if err != nil || got == nil { t.Fatalf("ReadRefusal = %+v, %v", got, err) } if got.Schema != 1 || got.Version != "v2" || !got.PointerPromotedAt.Equal(at) { t.Fatalf("round trip = %+v", got) } if !got.Blocks(&ChannelPointer{Version: "v2", PromotedAt: at}) { t.Fatal("the same promotion is not blocked") } if got.Blocks(&ChannelPointer{Version: "v2", PromotedAt: at.Add(time.Second)}) { t.Fatal("a re-signed pointer (retry) is still blocked") } if got.Blocks(&ChannelPointer{Version: "v3", PromotedAt: at}) { t.Fatal("a different version is blocked") } var nilR *Refusal if nilR.Blocks(&ChannelPointer{Version: "v2", PromotedAt: at}) { t.Fatal("a nil refusal blocks") } } func TestReadRefusalAbsentIsNil(t *testing.T) { got, err := ReadRefusal(t.TempDir(), "nobody.example.com") if got != nil || err != nil { t.Fatalf("absent = %+v, %v; want nil, nil", got, err) } } func TestReadRefusalCorruptIsAbsent(t *testing.T) { dir := t.TempDir() p := filepath.Join(RefusalDir(dir), "console.example.com.json") if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(p, []byte(`{"schema":1,"host":`), 0o644); err != nil { t.Fatal(err) } got, err := ReadRefusal(dir, "console.example.com") if got != nil || err != nil { t.Fatalf("corrupt = %+v, %v; want nil, nil (a torn file must never block)", got, err) } } func TestRefusalRejectsAPathInTheHost(t *testing.T) { if err := WriteRefusal(t.TempDir(), Refusal{Host: "../etc/x"}); err == nil { t.Fatal("a host with a path separator was written") } } func TestListAndClearRefusals(t *testing.T) { dir := t.TempDir() for _, h := range []string{"a.example.com", "b.example.com"} { if err := WriteRefusal(dir, Refusal{Host: h, Version: "v2"}); err != nil { t.Fatal(err) } } if err := ClearRefusal(dir, "a.example.com"); err != nil { t.Fatal(err) } if err := ClearRefusal(dir, "never.example.com"); err != nil { t.Fatalf("clearing an absent record: %v", err) } all, err := ListRefusals(dir) if err != nil || len(all) != 1 || all[0].Host != "b.example.com" { t.Fatalf("ListRefusals = %+v, %v", all, err) } }