package ledger import ( "fmt" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/buscalls" ) // 1966/AC15 and the other reads of a ledger: get, query (ADR 0597 §10; design 25 § 12.5). func TestReadsOfALedger(t *testing.T) { cases := []struct { name string run func(t *testing.T, l *Ledger, f fakes) }{ {"1966/AC15 history answers an instance's operations oldest first with sequence and author", func(t *testing.T, l *Ledger, f fakes) { op := buscalls.Author{Account: "ledger.anchor.m", Caller: "op@shanks"} applied(t, l, "decision/1", "note", `{"says":"one"}`, owner) applied(t, l, "decision/2", "note", `{"says":"elsewhere"}`, owner) applied(t, l, "decision/1", "title", `{"title":"Two"}`, op) applied(t, l, "decision/1", "note", `{"says":"three"}`, owner) page, err := l.ReadHistory(buscalls.HistoryRequest{Instance: "decision/1", Limit: 2}) if err != nil { t.Fatal(err) } var got []string for _, o := range page.Operations { got = append(got, fmt.Sprintf("%s@%d %s %s", o.Operation, o.Sequence, o.Author.Account, o.Author.Caller)) } if strings.Join(got, "; ") != "note@1 ledger.anchor.m ; title@3 ledger.anchor.m op@shanks" || page.Next != 4 || page.Last != 4 { t.Fatalf("the history is %q, next %d, last %d", got, page.Next, page.Last) } rest, _ := l.ReadHistory(buscalls.HistoryRequest{Instance: "decision/1", From: page.Next}) if len(rest.Operations) != 1 || rest.Operations[0].Sequence != 4 || rest.Next != 0 { t.Fatalf("read on: %+v", rest) } }}, {"get answers the state and its sequence, null for an instance with none", func(t *testing.T, l *Ledger, f fakes) { applied(t, l, "decision/1", "title", `{"title":"One"}`, owner) got, err := l.Get(buscalls.InstanceRequest{Instance: "decision/1"}) if err != nil || got.Sequence != 1 || !strings.Contains(string(got.State), `"title":"One"`) { t.Fatalf("got %+v, %v", got, err) } if none, err := l.Get(buscalls.InstanceRequest{Instance: "decision/9"}); err != nil || string(none.State) != "null" { t.Fatalf("none is %+v, %v", none, err) } }}, {"query reads a declared index by key, and an undeclared one is refused", func(t *testing.T, l *Ledger, f fakes) { _ = f.index.Put("One.decision.1", []byte(`{"instance":"decision/1"}`)) _ = f.index.Put("Two.decision.2", []byte(`{"instance":"decision/2"}`)) got, err := l.Query(buscalls.QueryRequest{Index: "by-title", Key: "One.>"}) if err != nil || len(got.Entries) != 1 || string(got.Entries[0].Value) != `{"instance":"decision/1"}` { t.Fatalf("queried %+v, %v", got, err) } if _, err := l.Query(buscalls.QueryRequest{Index: "by-date"}); err == nil || !strings.Contains(err.Error(), `no index "by-date"`) { t.Fatalf("an undeclared index: %v", err) } }}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { l, f := newLedger() c.run(t, l, f) }) } }