package bridge import ( "reflect" "testing" "git.novox.be/novox/mesh-sdk/go/delivery" ) const ( headA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" headB = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ) // owedValue is an owed value as the SDK writes it (mesh-sdk go/delivery EncodeOwed), and its key as OwedKey spells it. func owedValue(t *testing.T, repository string, number int, act string, o delivery.Owed) (string, []byte) { t.Helper() key, err := delivery.OwedKey(repository, number, headA, act) if err != nil { t.Fatal(err) } b, err := delivery.EncodeOwed(o) if err != nil { t.Fatal(err) } return key, b } func TestOwedStatusIsACommitStatusCall(t *testing.T) { // 1341/AC1 key, v := owedValue(t, "novox/mesh-delivery", 12, "status=mesh/merge-gate", delivery.Owed{Act: delivery.OwedStatus, Context: "mesh/merge-gate", State: "pending", Text: "waiting", Target: "https://forge.example/novox/mesh-delivery/pulls/12"}) a, err := OwedAct(key, v) if err != nil { t.Fatal(err) } want := Call{Tool: "gitea.gitea_commit_status", Args: map[string]any{"owner": "novox", "repo": "mesh-delivery", "sha": headA, "context": "mesh/merge-gate", "state": "pending", "description": "waiting", "target_url": "https://forge.example/novox/mesh-delivery/pulls/12"}} if !reflect.DeepEqual(a.Call, want) { t.Errorf("call = %+v, want %+v", a.Call, want) } if a.Repository != "novox/mesh-delivery" || a.Number != 12 || a.Head != headA || a.Name != "status=mesh/merge-gate" { t.Errorf("act = %+v", a) } } func TestOwedViewNoteAndCommentCalls(t *testing.T) { // 1341/AC2 cases := []struct { act string o delivery.Owed want Call }{ {"view", delivery.Owed{Act: delivery.OwedView, Text: "the view"}, Call{Tool: "gitea.gitea_delivery_view", Args: map[string]any{"owner": "novox", "repo": "mesh-delivery", "number": 12, "body": "the view"}}}, {"note", delivery.Owed{Act: delivery.OwedNote, Text: "a line", Ref: "mesh-plan"}, Call{Tool: "gitea.gitea_note_append", Args: map[string]any{"owner": "novox", "repo": "mesh-delivery", "sha": headA, "ref": "mesh-plan", "line": "a line"}}}, {"comment.2", delivery.Owed{Act: delivery.OwedComment, Text: "hello"}, Call{Tool: "gitea.gitea_add_comment", Args: map[string]any{"owner": "novox", "repo": "mesh-delivery", "number": 12, "body": "hello"}}}, } for _, c := range cases { key, v := owedValue(t, "novox/mesh-delivery", 12, c.act, c.o) a, err := OwedAct(key, v) if err != nil { t.Fatalf("%s: %v", c.act, err) } if !reflect.DeepEqual(a.Call, c.want) { t.Errorf("%s: call = %+v, want %+v", c.act, a.Call, c.want) } } } func TestOwedActWithoutAPullRequestNeedsOneOnlyWhereTheToolDoes(t *testing.T) { key, v := owedValue(t, "novox/mesh-delivery", 0, "note", delivery.Owed{Act: delivery.OwedNote, Text: "l", Ref: "mesh-plan"}) if _, err := OwedAct(key, v); err != nil { t.Errorf("a note on a commit no pull request names: %v", err) } key, v = owedValue(t, "novox/mesh-delivery", 0, "view", delivery.Owed{Act: delivery.OwedView, Text: "v"}) if _, err := OwedAct(key, v); err == nil { t.Error("a view of no pull request was taken") } } func TestOwedActOfADottedRepositoryIsUnescaped(t *testing.T) { key, v := owedValue(t, "novox/my.repo", 3, "comment.1", delivery.Owed{Act: delivery.OwedComment, Text: "x"}) a, err := OwedAct(key, v) if err != nil { t.Fatal(err) } if a.Call.Args["repo"] != "my.repo" || a.Repository != "novox/my.repo" { t.Errorf("act = %+v", a) } } func TestOwedActThatDisagreesWithItsKeyIsRefused(t *testing.T) { key, _ := owedValue(t, "novox/mesh-delivery", 12, "view", delivery.Owed{Act: delivery.OwedView, Text: "v"}) v, _ := delivery.EncodeOwed(delivery.Owed{Act: delivery.OwedComment, Text: "v"}) if _, err := OwedAct(key, v); err == nil { t.Error("a comment under a view's key was taken") } if _, err := OwedAct("nonsense", v); err == nil { t.Error("a key that is no owed key was taken") } if _, err := OwedAct(key, []byte(`{"v":1`)); err == nil { t.Error("a value that is not json was taken") } } func mergeValue(t *testing.T, m delivery.Merge) []byte { t.Helper() b, err := delivery.EncodeMerge(m) if err != nil { t.Fatal(err) } return b } func TestMergeActsHandOnlyTheMemberHandedWithEveryApprovedHead(t *testing.T) { // 1342/AC1 approved := map[string]string{delivery.ApprovedKey("novox/mesh-sdk", 4): headB, delivery.ApprovedKey("novox/mesh-delivery", 12): headA} v := mergeValue(t, delivery.Merge{Group: "g", Ask: "merge.g.0123456789ab", Approved: approved, Pulls: []delivery.MergePull{ {Head: delivery.Head{Repository: "novox/mesh-sdk", Number: 4, Head: headB}, State: delivery.MergeMerged, Commit: "c0"}, {Head: delivery.Head{Repository: "novox/mesh-delivery", Number: 12, Head: headA}, State: delivery.MergeMerging}, }}) acts, err := MergeActs(v) if err != nil { t.Fatal(err) } if len(acts) != 1 { t.Fatalf("%d acts, want 1 (the merged member is not merged again)", len(acts)) } want := Call{Tool: "gitea.gitea_merge_pull_request", Args: map[string]any{"owner": "novox", "repo": "mesh-delivery", "number": 12, "head": headA, "approved_heads": []string{"novox/mesh-delivery@" + headA, "novox/mesh-sdk@" + headB}}} if !reflect.DeepEqual(acts[0].Call, want) { t.Errorf("call = %+v, want %+v", acts[0].Call, want) } if acts[0].Name != "merge" || acts[0].Number != 12 || acts[0].Head != headA { t.Errorf("act = %+v", acts[0]) } } func TestMergeActsOfAMergeWithoutApprovedHeadsAreRefused(t *testing.T) { v := mergeValue(t, delivery.Merge{Group: "g", Ask: "a", Pulls: []delivery.MergePull{ {Head: delivery.Head{Repository: "novox/mesh-delivery", Number: 12, Head: headA}, State: delivery.MergeMerging}}}) if _, err := MergeActs(v); err == nil { t.Error("a merge with no approved heads was taken: the forge's tool would refuse it with nothing to say which") } } func TestRefusedMessageNamesTheActAndTheForgesWords(t *testing.T) { // 1341/AC3, 1342/AC2 a := Act{Name: "merge", Repository: "novox/mesh-delivery", Number: 12, Head: headA} m, err := RefusedMessage(a, "novox/mesh-delivery#12 is not merged: its head moved") if err != nil { t.Fatal(err) } if m.Event != "forge.novox.mesh-delivery.refused" { t.Errorf("event = %q", m.Event) } f, err := delivery.DecodeForge(m.Data) if err != nil { t.Fatal(err) } want := delivery.Forge{V: delivery.Version, Kind: delivery.ForgeRefused, Repository: "novox/mesh-delivery", Number: 12, Head: headA, Act: "merge", Words: "novox/mesh-delivery#12 is not merged: its head moved"} if !delivery.SameForge(f, want) { t.Errorf("message = %+v", f) } }