The delivery repository's contracts and SDK live under modules/ as mesh-delivery-contracts and mesh-delivery-sdk, their Go module paths renamed to match the folders (the TypeScript names already did), and every importer in mesh-delivery, mesh-catalog, mesh-host, mesh-tools and mesh-sdk follows in the same group: a design as it should be, one path per module, checked by the group's check building every importer. Builds: design 47 G §427, §88 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
96 lines
5.3 KiB
Go
96 lines
5.3 KiB
Go
package bridge
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
git "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/git"
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-forge-bridge/forgemsg"
|
|
|
|
"mesh-delivery-forge-bridge/internal/gitfixture"
|
|
)
|
|
|
|
// Design 47 *What the gate owes the forge*: each act the gate or the checker says as owed is the seat git's verb of that
|
|
// act, under the act's id; what cannot be read is undecodable, and every answer is one outcome.
|
|
func TestAnOwedEventIsTheSeatGitsVerbAndItsAnswerOneOutcome(t *testing.T) {
|
|
gate := func(name string) []byte { return gitfixture.Seat(t, "mesh-delivery", "events", name, "event:owed")[0] }
|
|
chk := gitfixture.Seat(t, "mesh-delivery-checker", "events", "owed is said", "event:owed")[0]
|
|
a40 := strings.Repeat("a", 40)
|
|
edit := func(raw []byte, k string, v any) []byte {
|
|
var m map[string]any
|
|
_ = json.Unmarshal(raw, &m)
|
|
if v == nil {
|
|
delete(m, k)
|
|
} else {
|
|
m[k] = v
|
|
}
|
|
b, _ := json.Marshal(m)
|
|
return b
|
|
}
|
|
for _, c := range []struct {
|
|
name string
|
|
read func([]byte) (OwedCall, error)
|
|
data []byte
|
|
verb string
|
|
input any
|
|
bad string
|
|
}{
|
|
{"a merge on no pull request", GateOwed, edit(gate("owed is said, a merge"), "number", 0), "", nil, "no pull request"},
|
|
{"a status on the head", GateOwed, gate("owed is said, a status"), "status", git.StatusInput{ID: "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate",
|
|
Repository: "novox/mesh-sdk", Commit: a40, Context: "mesh/merge-gate", State: "pending", Description: "waits for the operator's Approve", Target: "https://forge.test/x"}, ""},
|
|
{"a view", GateOwed, edit(edit(gate("owed is said, a status"), "act", "view"), "text", "the view"), "view",
|
|
git.ViewInput{ID: "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate", Repository: "novox/mesh-sdk", Number: 178, Text: "the view"}, ""},
|
|
{"a comment", GateOwed, edit(edit(gate("owed is said, a status"), "act", "comment"), "text", "hello"), "comment",
|
|
git.CommentInput{ID: "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate", Repository: "novox/mesh-sdk", Number: 178, Text: "hello"}, ""},
|
|
{"a note line on its commit", GateOwed, edit(edit(edit(gate("owed is said, a status"), "act", "note"), "line", "a line"), "commit", strings.Repeat("c", 40)), "note",
|
|
git.NoteInput{ID: "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate", Repository: "novox/mesh-sdk", Commit: strings.Repeat("c", 40), Line: "a line"}, ""},
|
|
{"the checker's status", CheckerOwed, chk, "status", git.StatusInput{ID: "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/check",
|
|
Repository: "novox/mesh-sdk", Commit: a40, Context: "mesh/check", State: "success", Description: "passed", Target: "https://forge.test/x"}, ""},
|
|
{"not json", GateOwed, []byte("{"), "", nil, "not json"},
|
|
{"no id", GateOwed, edit(gate("owed is said, a merge"), "id", nil), "", nil, "no id"},
|
|
{"a short head", CheckerOwed, edit(chk, "head", "abc"), "", nil, "40 hex"},
|
|
{"a merge of the switch", GateOwed, gate("owed is said, a merge"), "merge-pull", git.MergePullInput{ID: "merge.feat=47-G.0123456789ab.novox/mesh-sdk#178",
|
|
Repository: "novox/mesh-sdk", Number: 178, Head: a40}, ""},
|
|
{"a comment on no pull request", GateOwed, edit(edit(gate("owed is said, a status"), "act", "comment"), "number", 0), "", nil, "no pull request"},
|
|
{"an act of no kind", GateOwed, edit(gate("owed is said, a status"), "act", "label"), "", nil, "none the seat git"},
|
|
{"a repository not owner/name", GateOwed, edit(gate("owed is said, a status"), "repository", "mesh-sdk"), "", nil, "owner"},
|
|
} {
|
|
got, err := c.read(c.data)
|
|
switch {
|
|
case c.bad != "":
|
|
if !errors.Is(err, ErrUndecodable) || !strings.Contains(err.Error(), c.bad) {
|
|
t.Errorf("%s: %v, want undecodable naming %q", c.name, err, c.bad)
|
|
}
|
|
case err != nil || got.Verb != c.verb || !reflect.DeepEqual(got.Input, c.input):
|
|
t.Errorf("%s: %s %+v %v, want %s %+v", c.name, got.Verb, got.Input, err, c.verb, c.input)
|
|
}
|
|
}
|
|
answers := func(verb string) []json.RawMessage { return gitfixture.All(t, verb+" answers", "verb:"+verb+".answer") }
|
|
failed := func(verb string) json.RawMessage {
|
|
return gitfixture.Given(t, verb+" answers an error, never none", "verb:"+verb+".answer")
|
|
}
|
|
for _, c := range []struct {
|
|
name string
|
|
raw json.RawMessage
|
|
err error
|
|
outcome, words string
|
|
}{
|
|
{"a merge performed", answers("merge-pull")[0], nil, forgemsg.OwedPerformed, ""},
|
|
{"a merge refused", answers("merge-pull")[1], nil, forgemsg.OwedRefused, "the head moved"},
|
|
{"a comment already held", answers("comment")[0], nil, forgemsg.OwedPerformed, ""},
|
|
{"the forge's error, of the kind refused", failed("comment"), nil, forgemsg.OwedRefused, "403"},
|
|
{"the forge's error, of the kind failed", failed("view"), nil, forgemsg.OwedCouldNotBePerformed, "502"},
|
|
{"no answer in the call's bound", nil, errors.New("nats: timeout"), forgemsg.OwedCouldNotBePerformed, "timeout"},
|
|
{"an answer saying nothing", json.RawMessage(`{"id":"x"}`), nil, forgemsg.OwedCouldNotBePerformed, "neither"},
|
|
{"an answer not the contract's", json.RawMessage(`[1]`), nil, forgemsg.OwedCouldNotBePerformed, "contract"},
|
|
} {
|
|
outcome, words := Outcome(c.raw, c.err)
|
|
if outcome != c.outcome || !strings.Contains(words, c.words) {
|
|
t.Errorf("%s: %q %q, want %q naming %q", c.name, outcome, words, c.outcome, c.words)
|
|
}
|
|
}
|
|
}
|