package main import ( "encoding/json" "strings" "testing" "mesh-delivery-view/internal/view" ) type fake map[string]string func (f fake) reader() view.Reader { return view.Reader{State: view.StateRead{ Keys: func() ([]string, error) { var k []string for key := range f { k = append(k, key) } return k, nil }, Get: func(key string) (json.RawMessage, error) { if v, ok := f[key]; ok { return json.RawMessage(v), nil } return nil, nil }, }} } func run(t *testing.T, r view.Reader, name string, args map[string]any) (any, error) { t.Helper() for _, tl := range Tools(r) { if tl.Name == name { return tl.Run(args) } } t.Fatalf("no tool %s", name) return nil, nil } const ( withFP2 = `{"v":3,"fp":"a1","fp2":"b2","manifest":"m1","inputs2":{"tree":"t1","bases":["x"]},"repository":"novox/r","commit":"c1","path":".","toolchains":{"go":{"version":"go1.27.1","recipe":"2"}}}` withNone = `{"v":3,"none":"no successful trunk build recorded its inputs","none2":"builder's fingerprint not yet known","repository":"novox/r","commit":"c2","path":"modules/b"}` ) // 1562/AC1: indexer_module answers the key's value as stored: FP, FP2, None2, Inputs2, Path and Toolchains are all there. func TestModuleToolAnswersTheStoredValue(t *testing.T) { r := fake{"a": withFP2, "b": withNone}.reader() for key, want := range map[string]string{"a": withFP2, "b": withNone} { out, err := run(t, r, view.ModuleReadTool, map[string]any{"module": key}) if err != nil { t.Fatal(err) } if got := string(out.(json.RawMessage)); got != want { t.Errorf("%s = %s, want %s", key, got, want) } } out, _ := run(t, r, view.ModuleReadTool, map[string]any{"module": "a"}) var m map[string]any if err := json.Unmarshal(out.(json.RawMessage), &m); err != nil || m["fp"] != "a1" || m["fp2"] != "b2" || m["path"] != "." || m["inputs2"] == nil || m["toolchains"] == nil { t.Errorf("stored fields are not all there: %v %v", m, err) } } // A module with no key, and a name that is no key, are said so. func TestModuleToolRefusesWhatIsNotThere(t *testing.T) { r := fake{"a": withFP2}.reader() if _, err := run(t, r, view.ModuleReadTool, map[string]any{"module": "gone"}); err == nil || !strings.Contains(err.Error(), "no module gone") { t.Errorf("a missing module: %v", err) } if _, err := run(t, r, view.ModuleReadTool, map[string]any{"module": ""}); err == nil { t.Errorf("an empty name was answered") } } // 1562/AC1: indexer_modules answers every key as stored, and with none2 only those that say why they have no FP2. func TestModulesToolAnswersEveryKeyAsStored(t *testing.T) { r := fake{"a": withFP2, "b": withNone}.reader() out, err := run(t, r, view.ModulesReadTool, map[string]any{}) if err != nil { t.Fatal(err) } all := out.(map[string]any)["modules"].(map[string]json.RawMessage) if len(all) != 2 || string(all["a"]) != withFP2 || string(all["b"]) != withNone { t.Errorf("modules = %v", all) } out, err = run(t, r, view.ModulesReadTool, map[string]any{"none2": true}) if err != nil { t.Fatal(err) } only := out.(map[string]any)["modules"].(map[string]json.RawMessage) if len(only) != 1 || string(only["b"]) != withNone { t.Errorf("none2 modules = %v", only) } }