diff --git a/internal/handlers/ussd/menu_traversal_test.go b/internal/handlers/ussd/menu_traversal_test.go new file mode 100644 index 0000000..86c909d --- /dev/null +++ b/internal/handlers/ussd/menu_traversal_test.go @@ -0,0 +1,141 @@ +package ussd + +import ( + "bytes" + "context" + "fmt" + "path" + "testing" + + "git.defalsify.org/vise.git/db" + fsdb "git.defalsify.org/vise.git/db/fs" + "git.defalsify.org/vise.git/engine" + "git.defalsify.org/vise.git/persist" + "git.defalsify.org/vise.git/resource" + "git.grassecon.net/urdt/ussd/internal/storage" + "git.grassecon.net/urdt/ussd/testdata" + testdataloader "github.com/peteole/testdata-loader" +) + +var ( + dataGenerated bool = false + dataDir string = testdata.DataDir + BaseDir = testdataloader.GetBasePath() +) + +type testWrapper struct { + resource.Resource + db db.Db +} + +func generateTestData(t *testing.T) { + if dataGenerated { + return + } + var err error + dataDir, err = testdata.Generate() + if err != nil { + t.Fatal(err) + } +} + +func newTestWrapper(path string) testWrapper { + ctx := context.Background() + store := fsdb.NewFsDb() + store.Connect(ctx, path) + rs := resource.NewDbResource(store) + rs.With(db.DATATYPE_STATICLOAD) + wr := testWrapper{ + rs, + store, + } + rs.AddLocalFunc("quit", quit) + + return wr +} + +func quit(ctx context.Context, sym string, input []byte) (resource.Result, error) { + return resource.Result{ + Content: "Thank you for using Sarafu network", + }, nil +} + +func TestTerms(t *testing.T) { + generateTestData(t) + ctx := context.Background() + rs := newTestWrapper(dataDir) + cfg := engine.Config{ + Root: "terms", + FlagCount: uint32(9), + } + store := storage.NewThreadGdbmDb() + storeFile := path.Join(baseDir, "state.gdbm") + err := store.Connect(ctx, storeFile) + if err != nil { + t.Fail() + } + + pr := persist.NewPersister(store) + en := engine.NewEngine(cfg, &rs) + en.WithPersister(pr) + if pr.GetState() == nil || pr.GetMemory() == nil { + t.Fail() + } + _, err = en.Exec(ctx, []byte{}) + if err != nil { + t.Fatal(err) + } + w := bytes.NewBuffer(nil) + _, err = en.Flush(ctx, w) + if err != nil { + t.Fatal(err) + } + b := w.Bytes() + + expect_str := `Do you agree to terms and conditions? +1:yes +2:no` + + if !bytes.Equal(b, []byte(expect_str)) { + t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect_str, b) + } + + tests := []struct { + name string + expectedSymbol string + input []byte + }{ + { + name: "Test accept terms option(yes)", + expectedSymbol: "create_pin", + input: []byte("1"), + }, + // { + // name: "Test reject terms option(no)", + // input: []byte("2"), + // expectedSymbol: "quit", + // }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err = en.Exec(ctx, tt.input) + if err != nil { + t.Fatal(err) + } + w := bytes.NewBuffer(nil) + _, err = en.Flush(ctx, w) + if err != nil { + t.Fatal(err) + } + + b = w.Bytes() + fmt.Println("result", string(b)) + symbol, _ := pr.State.Where() + + if symbol != tt.expectedSymbol { + t.Fatalf("expected symbol to be 'create_pin', got %s", symbol) + } + }) + } +} diff --git a/testdata/main.vis b/testdata/main.vis new file mode 100644 index 0000000..e69de29 diff --git a/testdata/testdata.go b/testdata/testdata.go new file mode 100644 index 0000000..b3b1f00 --- /dev/null +++ b/testdata/testdata.go @@ -0,0 +1,119 @@ +package testdata + +import ( + "context" + "io/ioutil" + "os" + "path" + "git.defalsify.org/vise.git/db" + fsdb "git.defalsify.org/vise.git/db/fs" + "git.defalsify.org/vise.git/logging" + "git.defalsify.org/vise.git/vm" + testdataloader "github.com/peteole/testdata-loader" +) + + + +func outNew(sym string, b []byte, tpl string, data map[string]string) error { + logg.Debugf("testdata out", "sym", sym) + store.SetPrefix(db.DATATYPE_TEMPLATE) + err := store.Put(ctx, []byte(sym), []byte(tpl)) + if err != nil { + return err + } + store.SetPrefix(db.DATATYPE_BIN) + err = store.Put(ctx, []byte(sym), b) + if err != nil { + return err + } + store.SetPrefix(db.DATATYPE_STATICLOAD) + for k, v := range data { + logg.Debugf("testdata out staticload", "sym", sym, "k", k, "v", v) + err = store.Put(ctx, []byte(k), []byte(v)) + if err != nil { + return err + } + } + return nil +} + +var ( + ctx = context.Background() + store = fsdb.NewFsDb() + out = outNew + logg = logging.NewVanilla().WithDomain("testdata") + BaseDir = testdataloader.GetBasePath() + DataDir = "" + dirLock = false +) + +type genFunc func() error + +func terms() error { + b := []byte{} + b = vm.NewLine(b, vm.MOUT, []string{"yes", "1"}, nil, nil) + b = vm.NewLine(b, vm.MOUT, []string{"no", "2"}, nil, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"create_pin", "1"}, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"quit", "2"}, nil, nil) + tpl := "Do you agree to terms and conditions?" + return out("terms", b, tpl, nil) +} + +func createPin() error { + b := []byte{} + b = vm.NewLine(b, vm.MOUT, []string{"exit", "0"}, nil, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"0", "1"}, nil, nil) + tpl := "create pin" + return out("create_pin", b, tpl, nil) +} + +func quit() error { + // b := []byte{} + // b = vm.NewLine(b, vm.LOAD, []string{"quit"}, []byte{0x00}, nil) + // //b = vm.NewLine(b, vm.RELOAD, []string{"quit"}, []byte{0x00}, nil) + // b = vm.NewLine(b, vm.HALT, nil, nil, nil) + + // return out("quit", b, "quit", nil) + b := vm.NewLine(nil, vm.LOAD, []string{"quit"}, []byte{0x00}, nil) + b = vm.NewLine(b, vm.RELOAD, []string{"quit"}, nil, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + + fp := path.Join(DataDir, "nothing.bin") + err := os.WriteFile(fp, b, 0600) + return err +} + +func generate() error { + err := os.MkdirAll(DataDir, 0755) + if err != nil { + return err + } + store = fsdb.NewFsDb() + store.Connect(ctx, DataDir) + store.SetLock(db.DATATYPE_TEMPLATE, false) + store.SetLock(db.DATATYPE_BIN, false) + store.SetLock(db.DATATYPE_MENU, false) + store.SetLock(db.DATATYPE_STATICLOAD, false) + + fns := []genFunc{terms, createPin, quit} + for _, fn := range fns { + err = fn() + if err != nil { + return err + } + } + return nil +} + +func Generate() (string, error) { + dir, err := ioutil.TempDir("", "vise_testdata_") + if err != nil { + return "", err + } + DataDir = dir + dirLock = true + err = generate() + return dir, err +}