licences_switches answers switches carried from the old database with their licence and consumer (issue 1409) #664
@@ -92,6 +92,21 @@ func (r *Reader) Tools() []stdio.Tool {
|
||||
}
|
||||
}
|
||||
|
||||
// carriedForm gives an entry carried over from the old table `audit` (§12) the fields of §37: the old manager wrote a
|
||||
// switch as `consumer` (one), `licence` (the one moved to), `from` and `by`, and no `consumers` or `to`.
|
||||
func carriedForm(e map[string]any) {
|
||||
if _, ok := e["to"]; !ok {
|
||||
if l, ok := e["licence"]; ok {
|
||||
e["to"] = l
|
||||
}
|
||||
}
|
||||
if _, ok := e["consumers"]; !ok {
|
||||
if c, ok := e["consumer"]; ok {
|
||||
e["consumers"] = []any{c}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switches are the audit's switches, newest first: of a licence (from or to it) and a consumer when named, none before
|
||||
// since, at most limit (§37).
|
||||
func (r *Reader) Switches(licence, consumer string, since time.Time, limit int) ([]map[string]any, error) {
|
||||
@@ -118,6 +133,7 @@ func (r *Reader) Switches(licence, consumer string, since time.Time, limit int)
|
||||
if json.Unmarshal(all[i].Value, &e) != nil {
|
||||
continue
|
||||
}
|
||||
carriedForm(e)
|
||||
at, _ := time.Parse(time.RFC3339Nano, fmt.Sprint(e["at"]))
|
||||
if at.Before(since) {
|
||||
continue
|
||||
|
||||
@@ -229,6 +229,26 @@ func TestSwitchesAnswersBothCauses(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// design 39 bus-and-switch §37, §12: a switch carried over from the old table keeps the old field names (consumer,
|
||||
// licence) and is answered with `to` and `consumers`, and found by them.
|
||||
func TestSwitchesAnswersCarriedEntries(t *testing.T) {
|
||||
rt := newRuntime(t)
|
||||
rt.seedLog(licences.EntryAudit, "switched", map[string]any{"at": "2026-11-11T21:10:33Z", "consumer": "n1",
|
||||
"licence": "d@example.org", "from": "c@example.org", "by": "a@example.org"})
|
||||
r := rt.reader()
|
||||
for _, args := range []map[string]any{nil, {"consumer": "n1"}, {"licence": "d@example.org"}} {
|
||||
got := run(t, r, "licences_switches", args).([]any)
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("%v: %v", args, got)
|
||||
}
|
||||
e := got[0].(map[string]any)
|
||||
if e["to"] != "d@example.org" || e["from"] != "c@example.org" || e["by"] != "a@example.org" ||
|
||||
len(e["consumers"].([]any)) != 1 || e["consumers"].([]any)[0] != "n1" {
|
||||
t.Fatalf("%v: %v", args, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// design 39 bus-and-switch §40/AC1, B18, design 39 parts §3: a value set at node level is answered with its level, the
|
||||
// rest with the default, each with its value and default, and an invalid one saying why, read from the settings file;
|
||||
// mesh-config not answering is an error, never the default.
|
||||
|
||||
Reference in New Issue
Block a user