Files
mesh-catalog/modules/mesh-delivery/cmd/mesh-delivery/operator_test.go
T

105 lines
2.6 KiB
Go

package main
import (
"sync"
"time"
"git.novox.be/novox/mesh-sdk/go/asks"
)
// fakeOperator is the operator channel: it keeps the asks made, and answers as the test says. In auto mode it
// approves every ask the moment it is read (the tests of other behaviour, which are not about the Approve).
type fakeOperator struct {
mu sync.Mutex
now func() time.Time
auto bool
asked []asks.Ask
cancelled []string
state map[string]string
warrant map[string]*asks.Warrant
refuse error
}
func newFakeOperator(now func() time.Time) *fakeOperator {
return &fakeOperator{now: now, state: map[string]string{}, warrant: map[string]*asks.Warrant{}}
}
func (o *fakeOperator) Ask(a asks.Ask) error {
o.mu.Lock()
defer o.mu.Unlock()
if o.refuse != nil {
return o.refuse
}
if err := a.Check(o.now()); err != nil {
return err
}
o.asked = append(o.asked, a)
o.state[a.ID] = "open"
return nil
}
func (o *fakeOperator) Cancel(id string) error {
o.mu.Lock()
defer o.mu.Unlock()
o.cancelled = append(o.cancelled, id)
o.state[id] = "cancelled"
return nil
}
func (o *fakeOperator) Where(id string) (string, *asks.Warrant, error) {
o.mu.Lock()
defer o.mu.Unlock()
if o.auto && o.state[id] == "open" {
o.answerLocked(id, OptionApprove)
}
return o.state[id], o.warrant[id], nil
}
func (o *fakeOperator) ask(id string) asks.Ask {
for _, a := range o.asked {
if a.ID == id {
return a
}
}
panic("no ask " + id)
}
func (o *fakeOperator) answerLocked(id, option string) {
a := o.ask(id)
opt, _ := a.Option(option)
o.state[id] = "answered"
o.warrant[id] = &asks.Warrant{Ask: id, Asker: Module, Outcome: asks.OutcomeChosen, Option: option, Label: opt.Label,
Level: opt.Level, By: &asks.Person{Who: asks.Operator, Kind: "telegram", Verified: "user id verified"},
At: o.now(), AskDigest: a.Digest()}
}
// answer is the operator's choice, proven by the router.
func (o *fakeOperator) answer(id, option string) {
o.mu.Lock()
defer o.mu.Unlock()
o.answerLocked(id, option)
}
// end is an ask that closed without a choice.
func (o *fakeOperator) end(id string) {
o.mu.Lock()
defer o.mu.Unlock()
o.state[id] = "expired"
o.warrant[id] = &asks.Warrant{Ask: id, Asker: Module, Outcome: asks.OutcomeExpired, At: o.now()}
}
// open is the ids of the asks waiting for an answer, in the order asked.
func (o *fakeOperator) open() []string {
o.mu.Lock()
defer o.mu.Unlock()
var out []string
for _, a := range o.asked {
if o.state[a.ID] == "open" {
out = append(out, a.ID)
}
}
return out
}
func (o *fakeOperator) count() int { o.mu.Lock(); defer o.mu.Unlock(); return len(o.asked) }