package meshdeliveryclient import ( "encoding/json" "os" "strings" "testing" seat "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdelivery" ) // The keys, ids and acts equal what the gate and the teller have always written (the expected strings are the trunk's own // output for the same input), so a value written before is read after. func TestTheAsksAndOwedActsKeepTheirFormsAndRules(t *testing.T) { heads := []Head{{Repository: "novox/a", Number: 3, Head: "abc"}, {Repository: "novox/b", Number: 1, Head: "def"}} key, err := MergeAskKey("fix/1.2", heads) if err != nil || key != "merge.fix/1=2e2.d106c7950d28" { t.Fatalf("MergeAskKey = %q, %v", key, err) } if rev, _ := MergeAskKey("fix/1.2", []Head{heads[1], heads[0]}); rev != key { t.Errorf("the heads' order changes the key: %q", rev) } if kind, group, hash, err := ParseAskKey(key); err != nil || kind != "merge" || group != "fix/1.2" || hash != "d106c7950d28" { t.Errorf("ParseAskKey = %q %q %q %v", kind, group, hash, err) } for _, bad := range []string{"merge.g", "settle.g.d106c7950d28", "merge..d106c7950d28", "merge.g.D106C7950D28", "merge.g.d106"} { if _, _, _, err := ParseAskKey(bad); err == nil { t.Errorf("ParseAskKey(%q) reads a wrong key", bad) } } if _, err := MergeAskKey("", heads); err == nil { t.Error("an empty group keys") } if _, err := MergeAskKey("g", nil); err == nil { t.Error("no heads keys") } if id := AskID(key); id != "merge-fix_1_2e2-d106c7950d28-400030402c88" || AskingID(key, 1) != id || AskingID(key, 0) != id { t.Errorf("AskID = %q", id) } if id := AskingID(key, 3); id != "merge-fix_1_2e2-d106c7950d28-3-ea06879e48d8" || len(id) > 64 { t.Errorf("AskingID(3) = %q", id) } if g := SettleGroup([]string{"b", "a"}); g != "settle:7e18f737311b" || g != SettleGroup([]string{"a", "b"}) { t.Errorf("SettleGroup = %q", g) } if AskVerb(SettleGroup([]string{"a"})) != "mesh-delivery.settle" || AskVerb("fix/1") != "mesh-delivery.merge" { t.Error("AskVerb binds the wrong act") } for act, want := range map[string]string{"status=mesh/check": "novox/a.3.abc.status=mesh/check", "view": "novox/a.3.abc.view", "comment.2": "novox/a.3.abc.comment.2"} { k, err := OwedKey("novox/a", 3, "abc", act) if err != nil || k != want { t.Errorf("OwedKey(%q) = %q, %v", act, k, err) } if repo, n, head, a, err := ParseOwedKey(k); err != nil || repo != "novox/a" || n != 3 || head != "abc" || a != act { t.Errorf("ParseOwedKey(%q) = %q %d %q %q %v", k, repo, n, head, a, err) } } for _, act := range []string{"status", "status=mesh/other", "view=x", "comment", "comment.0", "comment.01", "other"} { if _, err := OwedKey("novox/a", 3, "abc", act); err == nil { t.Errorf("OwedKey takes the act %q", act) } } if _, err := OwedKey("novox", 0, "abc", "view"); err == nil { t.Error("a repository with no slash keys") } if _, err := OwedKey("novox/a", -1, "abc", "view"); err == nil { t.Error("a negative number keys") } if act, err := OwedCommentAct(2); err != nil || act != "comment.2" { t.Errorf("OwedCommentAct = %q, %v", act, err) } type owed = seat.OwedByRepositoryNumberHeadActValue for name, c := range map[string]struct { v owed says string }{ "a good status": {owed{Act: "status", Context: StatusContextCheck, Target: "http://x", State: "success"}, ""}, "a good note": {owed{Act: "note", Text: "t", Ref: "mesh-plan"}, ""}, "a status no target": {owed{Act: "status", Context: StatusContextCheck, State: "success"}, "no target"}, "a status wrong state": {owed{Act: "status", Context: StatusContextCheck, Target: "x", State: "done"}, "state"}, "a status no context": {owed{Act: "status", Target: "x", State: "success"}, "no context"}, "a view no text": {owed{Act: "view"}, "no text"}, "a note no ref": {owed{Act: "note", Text: "t"}, "no ref"}, "an unknown act": {owed{Act: "merge"}, "not status"}, } { err := CheckOwed(c.v) if (c.says == "") != (err == nil) || (err != nil && !strings.Contains(err.Error(), c.says)) { t.Errorf("%s: CheckOwed = %v, want %q", name, err, c.says) } } } // The removed verbs are the optional rows of the seat's definition that say they were removed, each with the replacement // the definition gives: the list and the definition cannot drift apart. func TestTheRemovedVerbsAreTheDefinitionsRemovedRows(t *testing.T) { raw, err := os.ReadFile("../../../seats/mesh-delivery/seat.json") if err != nil { t.Fatal(err) } var def struct { Verbs []struct { Name string `json:"name"` Description string `json:"description"` Optional bool `json:"optional"` } `json:"verbs"` } if err := json.Unmarshal(raw, &def); err != nil { t.Fatal(err) } removed := RemovedVerbs() rows := 0 for _, v := range def.Verbs { if !strings.HasPrefix(v.Description, RemovedPrefix) { if _, in := removed[v.Name]; in { t.Errorf("%s is in the removed list, the definition keeps it", v.Name) } continue } rows++ if want, in := removed[v.Name]; !in || !v.Optional || v.Description != RemovedPrefix+want { t.Errorf("%s: in the list %v, optional %v, described %q, want %q", v.Name, in, v.Optional, v.Description, RemovedPrefix+want) } } if rows != len(removed) || rows == 0 { t.Errorf("the definition removes %d verbs, the list names %d", rows, len(removed)) } }