Rename module, export storage, testutil

This commit is contained in:
lash
2025-01-10 10:53:27 +00:00
parent 9ca5091692
commit f1664a43a8
56 changed files with 66 additions and 5502 deletions

View File

@@ -1,34 +0,0 @@
package args
import (
"strings"
"git.defalsify.org/vise.git/lang"
)
type LangVar struct {
v []lang.Language
}
func(lv *LangVar) Set(s string) error {
v, err := lang.LanguageFromCode(s)
if err != nil {
return err
}
lv.v = append(lv.v, v)
return err
}
func(lv *LangVar) String() string {
var s []string
for _, v := range(lv.v) {
s = append(s, v.Code)
}
return strings.Join(s, ",")
}
func(lv *LangVar) Langs() []lang.Language {
return lv.v
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ import (
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/grassrootseconomics/visedriver/storage"
)
var (

View File

@@ -5,7 +5,7 @@ import (
"io/ioutil"
"net/http"
"git.grassecon.net/urdt/ussd/internal/handlers"
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
)
type DefaultRequestParser struct {

View File

@@ -6,8 +6,8 @@ import (
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/internal/handlers"
"git.grassecon.net/urdt/ussd/request"
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
"git.grassecon.net/grassrootseconomics/visedriver/request"
)
var (

View File

@@ -9,9 +9,9 @@ import (
"testing"
"git.defalsify.org/vise.git/engine"
"git.grassecon.net/urdt/ussd/internal/handlers"
"git.grassecon.net/urdt/ussd/testutil/mocks/httpmocks"
"git.grassecon.net/urdt/ussd/request"
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
"git.grassecon.net/grassrootseconomics/visedriver/testutil/mocks/httpmocks"
"git.grassecon.net/grassrootseconomics/visedriver/request"
)
// invalidRequestType is a custom type to test invalid request scenarios

View File

@@ -10,8 +10,8 @@ import (
"git.defalsify.org/vise.git/db"
"git.grassecon.net/urdt/ussd/internal/storage"
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db/gdbm"
"git.grassecon.net/grassrootseconomics/visedriver/storage"
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm"
)
type SshKeyStore struct {

View File

@@ -17,9 +17,9 @@ import (
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
"git.grassecon.net/urdt/ussd/handlers"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/remote"
"git.grassecon.net/grassrootseconomics/visedriver/handlers"
"git.grassecon.net/grassrootseconomics/visedriver/storage"
"git.grassecon.net/grassrootseconomics/visedriver/remote"
)
var (

View File

@@ -1,127 +0,0 @@
package storage
import (
"context"
"git.defalsify.org/vise.git/db"
gdbmdb "git.defalsify.org/vise.git/db/gdbm"
"git.defalsify.org/vise.git/lang"
"git.defalsify.org/vise.git/logging"
)
var (
logg = logging.NewVanilla().WithDomain("gdbmstorage")
)
var (
dbC map[string]chan db.Db
)
type ThreadGdbmDb struct {
db db.Db
connStr string
}
func NewThreadGdbmDb() *ThreadGdbmDb {
if dbC == nil {
dbC = make(map[string]chan db.Db)
}
return &ThreadGdbmDb{}
}
func(tdb *ThreadGdbmDb) Connect(ctx context.Context, connStr string) error {
var ok bool
_, ok = dbC[connStr]
if ok {
logg.WarnCtxf(ctx, "already registered thread gdbm, skipping", "connStr", connStr)
return nil
}
gdb := gdbmdb.NewGdbmDb()
err := gdb.Connect(ctx, connStr)
if err != nil {
return err
}
dbC[connStr] = make(chan db.Db, 1)
dbC[connStr]<- gdb
tdb.connStr = connStr
return nil
}
func(tdb *ThreadGdbmDb) reserve() {
if tdb.db == nil {
tdb.db = <-dbC[tdb.connStr]
}
}
func(tdb *ThreadGdbmDb) release() {
if tdb.db == nil {
return
}
dbC[tdb.connStr] <- tdb.db
tdb.db = nil
}
func(tdb *ThreadGdbmDb) SetPrefix(pfx uint8) {
tdb.reserve()
tdb.db.SetPrefix(pfx)
}
func(tdb *ThreadGdbmDb) SetSession(sessionId string) {
tdb.reserve()
tdb.db.SetSession(sessionId)
}
func(tdb *ThreadGdbmDb) SetLanguage(lng *lang.Language) {
tdb.reserve()
tdb.db.SetLanguage(lng)
}
func(tdb *ThreadGdbmDb) Safe() bool {
tdb.reserve()
v := tdb.db.Safe()
tdb.release()
return v
}
func(tdb *ThreadGdbmDb) Prefix() uint8 {
tdb.reserve()
v := tdb.db.Prefix()
tdb.release()
return v
}
func(tdb *ThreadGdbmDb) SetLock(typ uint8, locked bool) error {
tdb.reserve()
err := tdb.db.SetLock(typ, locked)
tdb.release()
return err
}
func(tdb *ThreadGdbmDb) Put(ctx context.Context, key []byte, val []byte) error {
tdb.reserve()
err := tdb.db.Put(ctx, key, val)
tdb.release()
return err
}
func(tdb *ThreadGdbmDb) Get(ctx context.Context, key []byte) ([]byte, error) {
tdb.reserve()
v, err := tdb.db.Get(ctx, key)
tdb.release()
return v, err
}
func(tdb *ThreadGdbmDb) Close() error {
tdb.reserve()
close(dbC[tdb.connStr])
delete(dbC, tdb.connStr)
err := tdb.db.Close()
tdb.db = nil
return err
}
func(tdb *ThreadGdbmDb) Dump(ctx context.Context, key []byte) (*db.Dumper, error) {
tdb.reserve()
defer tdb.release()
return tdb.db.Dump(ctx, key)
}

View File

@@ -1,43 +0,0 @@
package storage
import (
"context"
"git.defalsify.org/vise.git/db"
)
// PrefixDb interface abstracts the database operations.
type PrefixDb interface {
Get(ctx context.Context, key []byte) ([]byte, error)
Put(ctx context.Context, key []byte, val []byte) error
}
var _ PrefixDb = (*SubPrefixDb)(nil)
type SubPrefixDb struct {
store db.Db
pfx []byte
}
func NewSubPrefixDb(store db.Db, pfx []byte) *SubPrefixDb {
return &SubPrefixDb{
store: store,
pfx: pfx,
}
}
func (s *SubPrefixDb) toKey(k []byte) []byte {
return append(s.pfx, k...)
}
func (s *SubPrefixDb) Get(ctx context.Context, key []byte) ([]byte, error) {
s.store.SetPrefix(db.DATATYPE_USERDATA)
key = s.toKey(key)
return s.store.Get(ctx, key)
}
func (s *SubPrefixDb) Put(ctx context.Context, key []byte, val []byte) error {
s.store.SetPrefix(db.DATATYPE_USERDATA)
key = s.toKey(key)
return s.store.Put(ctx, key, val)
}

View File

@@ -1,54 +0,0 @@
package storage
import (
"bytes"
"context"
"testing"
memdb "git.defalsify.org/vise.git/db/mem"
)
func TestSubPrefix(t *testing.T) {
ctx := context.Background()
db := memdb.NewMemDb()
err := db.Connect(ctx, "")
if err != nil {
t.Fatal(err)
}
sdba := NewSubPrefixDb(db, []byte("tinkywinky"))
err = sdba.Put(ctx, []byte("foo"), []byte("dipsy"))
if err != nil {
t.Fatal(err)
}
r, err := sdba.Get(ctx, []byte("foo"))
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(r, []byte("dipsy")) {
t.Fatalf("expected 'dipsy', got %s", r)
}
sdbb := NewSubPrefixDb(db, []byte("lala"))
r, err = sdbb.Get(ctx, []byte("foo"))
if err == nil {
t.Fatal("expected not found")
}
err = sdbb.Put(ctx, []byte("foo"), []byte("pu"))
if err != nil {
t.Fatal(err)
}
r, err = sdbb.Get(ctx, []byte("foo"))
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(r, []byte("pu")) {
t.Fatalf("expected 'pu', got %s", r)
}
r, err = sdba.Get(ctx, []byte("foo"))
if !bytes.Equal(r, []byte("dipsy")) {
t.Fatalf("expected 'dipsy', got %s", r)
}
}

View File

@@ -1,69 +0,0 @@
package storage
import (
"fmt"
"net/url"
"path"
)
const (
DBTYPE_MEM = iota
DBTYPE_GDBM
DBTYPE_POSTGRES
)
type ConnData struct {
typ int
str string
}
func (cd *ConnData) DbType() int {
return cd.typ
}
func (cd *ConnData) String() string {
return cd.str
}
func probePostgres(s string) (string, bool) {
v, err := url.Parse(s)
if err != nil {
return "", false
}
if v.Scheme != "postgres" {
return "", false
}
return s, true
}
func probeGdbm(s string) (string, bool) {
if !path.IsAbs(s) {
return "", false
}
s = path.Clean(s)
return s, true
}
func ToConnData(connStr string) (ConnData, error) {
var o ConnData
if connStr == "" {
return o, nil
}
v, ok := probePostgres(connStr)
if ok {
o.typ = DBTYPE_POSTGRES
o.str = v
return o, nil
}
v, ok = probeGdbm(connStr)
if ok {
o.typ = DBTYPE_GDBM
o.str = v
return o, nil
}
return o, fmt.Errorf("invalid connection string: %s", connStr)
}

View File

@@ -1,28 +0,0 @@
package storage
import (
"testing"
)
func TestParseConnStr(t *testing.T) {
_, err := ToConnData("postgres://foo:bar@localhost:5432/baz")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("/foo/bar")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("/foo/bar/")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("foo/bar")
if err == nil {
t.Fatalf("expected error")
}
_, err = ToConnData("http://foo/bar")
if err == nil {
t.Fatalf("expected error")
}
}

View File

@@ -1,48 +0,0 @@
package storage
import (
"git.defalsify.org/vise.git/db"
"git.defalsify.org/vise.git/persist"
)
const (
DATATYPE_EXTEND = 128
)
type Storage struct {
Persister *persist.Persister
UserdataDb db.Db
}
type StorageProvider interface {
Get(sessionId string) (*Storage, error)
Put(sessionId string, storage *Storage) error
Close() error
}
type SimpleStorageProvider struct {
*Storage
}
func NewSimpleStorageProvider(stateStore db.Db, userdataStore db.Db) StorageProvider {
pe := persist.NewPersister(stateStore)
pe = pe.WithFlush()
return &SimpleStorageProvider{
Storage: &Storage{
Persister: pe,
UserdataDb: userdataStore,
},
}
}
func (p *SimpleStorageProvider) Get(sessionId string) (*Storage, error) {
return p.Storage, nil
}
func (p *SimpleStorageProvider) Put(sessionId string, storage *Storage) error {
return nil
}
func (p *SimpleStorageProvider) Close() error {
return p.Storage.UserdataDb.Close()
}

View File

@@ -1,174 +0,0 @@
package storage
import (
"context"
"fmt"
"os"
"path"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
"git.defalsify.org/vise.git/db/postgres"
"git.defalsify.org/vise.git/lang"
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
gdbmstorage "git.grassecon.net/urdt/ussd/internal/storage/db/gdbm"
)
var (
logg = logging.NewVanilla().WithDomain("storage")
)
type StorageService interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) db.Db
GetResource(ctx context.Context) (resource.Resource, error)
}
type MenuStorageService struct {
conn ConnData
resourceDir string
poResource resource.Resource
resourceStore db.Db
stateStore db.Db
userDataStore db.Db
}
func NewMenuStorageService(conn ConnData, resourceDir string) *MenuStorageService {
return &MenuStorageService{
conn: conn,
resourceDir: resourceDir,
}
}
func (ms *MenuStorageService) WithResourceDir(resourceDir string) *MenuStorageService {
ms.resourceDir = resourceDir
return ms
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, section string) (db.Db, error) {
var newDb db.Db
var err error
if existingDb != nil {
return existingDb, nil
}
connStr := ms.conn.String()
dbTyp := ms.conn.DbType()
if dbTyp == DBTYPE_POSTGRES {
newDb = postgres.NewPgDb()
} else if dbTyp == DBTYPE_GDBM {
err = ms.ensureDbDir()
if err != nil {
return nil, err
}
connStr = path.Join(connStr, section)
newDb = gdbmstorage.NewThreadGdbmDb()
} else {
return nil, fmt.Errorf("unsupported connection string: '%s'\n", ms.conn.String())
}
logg.DebugCtxf(ctx, "connecting to db", "conn", connStr)
err = newDb.Connect(ctx, connStr)
if err != nil {
return nil, err
}
return newDb, nil
}
// WithGettext triggers use of gettext for translation of templates and menus.
//
// The first language in `lns` will be used as default language, to resolve node keys to
// language strings.
//
// If `lns` is an empty array, gettext will not be used.
func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *MenuStorageService {
if len(lns) == 0 {
logg.Warnf("Gettext requested but no languages supplied")
return ms
}
rs := resource.NewPoResource(lns[0], path)
for _, ln := range(lns) {
rs = rs.WithLanguage(ln)
}
ms.poResource = rs
return ms
}
func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
stateStore, err := ms.GetStateStore(ctx)
if err != nil {
return nil, err
}
pr := persist.NewPersister(stateStore)
logg.TraceCtxf(ctx, "menu storage service", "persist", pr, "store", stateStore)
return pr, nil
}
func (ms *MenuStorageService) GetUserdataDb(ctx context.Context) (db.Db, error) {
if ms.userDataStore != nil {
return ms.userDataStore, nil
}
userDataStore, err := ms.getOrCreateDb(ctx, ms.userDataStore, "userdata.gdbm")
if err != nil {
return nil, err
}
ms.userDataStore = userDataStore
return ms.userDataStore, nil
}
func (ms *MenuStorageService) GetResource(ctx context.Context) (resource.Resource, error) {
ms.resourceStore = fsdb.NewFsDb()
err := ms.resourceStore.Connect(ctx, ms.resourceDir)
if err != nil {
return nil, err
}
rfs := resource.NewDbResource(ms.resourceStore)
if ms.poResource != nil {
logg.InfoCtxf(ctx, "using poresource for menu and template")
rfs.WithMenuGetter(ms.poResource.GetMenu)
rfs.WithTemplateGetter(ms.poResource.GetTemplate)
}
return rfs, nil
}
func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error) {
if ms.stateStore != nil {
return ms.stateStore, nil
}
stateStore, err := ms.getOrCreateDb(ctx, ms.stateStore, "state.gdbm")
if err != nil {
return nil, err
}
ms.stateStore = stateStore
return ms.stateStore, nil
}
func (ms *MenuStorageService) ensureDbDir() error {
err := os.MkdirAll(ms.conn.String(), 0700)
if err != nil {
return fmt.Errorf("state dir create exited with error: %v\n", err)
}
return nil
}
func (ms *MenuStorageService) Close() error {
errA := ms.stateStore.Close()
errB := ms.userDataStore.Close()
errC := ms.resourceStore.Close()
if errA != nil || errB != nil || errC != nil {
return fmt.Errorf("%v %v %v", errA, errB, errC)
}
return nil
}

View File

@@ -1,111 +0,0 @@
package driver
import (
"encoding/json"
"log"
"os"
"regexp"
)
type Step struct {
Input string `json:"input"`
ExpectedContent string `json:"expectedContent"`
}
func (s *Step) MatchesExpectedContent(content []byte) (bool, error) {
pattern := regexp.QuoteMeta(s.ExpectedContent)
re, err := regexp.Compile(pattern)
if err != nil {
return false, err
}
if re.Match([]byte(content)) {
return true, nil
}
return false, nil
}
// Group represents a group of steps
type Group struct {
Name string `json:"name"`
Steps []Step `json:"steps"`
}
type TestCase struct {
Name string
Input string
ExpectedContent string
}
func (s *TestCase) MatchesExpectedContent(content []byte) (bool, error) {
pattern := regexp.QuoteMeta(s.ExpectedContent)
re, err := regexp.Compile(pattern)
if err != nil {
return false, err
}
// Check if the content matches the regex pattern
if re.Match(content) {
return true, nil
}
return false, nil
}
// DataGroup represents the overall structure of the JSON.
type DataGroup struct {
Groups []Group `json:"groups"`
}
type Session struct {
Name string `json:"name"`
Groups []Group `json:"groups"`
}
func ReadData() []Session {
data, err := os.ReadFile("test_setup.json")
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
// Unmarshal JSON data
var sessions []Session
err = json.Unmarshal(data, &sessions)
if err != nil {
log.Fatalf("Failed to unmarshal JSON: %v", err)
}
return sessions
}
func FilterGroupsByName(groups []Group, name string) []Group {
var filteredGroups []Group
for _, group := range groups {
if group.Name == name {
filteredGroups = append(filteredGroups, group)
}
}
return filteredGroups
}
func LoadTestGroups(filePath string) (DataGroup, error) {
var sessionsData DataGroup
data, err := os.ReadFile(filePath)
if err != nil {
return sessionsData, err
}
err = json.Unmarshal(data, &sessionsData)
return sessionsData, err
}
func CreateTestCases(group DataGroup) []TestCase {
var tests []TestCase
for _, group := range group.Groups {
for _, step := range group.Steps {
// Create a test case for each group
tests = append(tests, TestCase{
Name: group.Name,
Input: step.Input,
ExpectedContent: step.ExpectedContent,
})
}
}
return tests
}

View File

@@ -1,127 +0,0 @@
package testutil
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"time"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/handlers"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/internal/testutil/testservice"
"git.grassecon.net/urdt/ussd/internal/testutil/testtag"
testdataloader "github.com/peteole/testdata-loader"
"git.grassecon.net/urdt/ussd/remote"
)
var (
baseDir = testdataloader.GetBasePath()
logg = logging.NewVanilla()
scriptDir = path.Join(baseDir, "services", "registration")
)
func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
pfp := path.Join(scriptDir, "pp.csv")
var eventChannel = make(chan bool)
cfg := engine.Config{
Root: "root",
SessionId: sessionId,
OutputSize: uint32(160),
FlagCount: uint32(128),
}
connStr, err := filepath.Abs(".test_state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
conn, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr parse err: %v", err)
os.Exit(1)
}
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(conn, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "resource error: %v", err)
os.Exit(1)
}
pe, err := menuStorageService.GetPersister(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "persister error: %v", err)
os.Exit(1)
}
userDataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "userdb error: %v", err)
os.Exit(1)
}
dbResource, ok := rs.(*resource.DbResource)
if !ok {
fmt.Fprintf(os.Stderr, "dbresource cast error")
os.Exit(1)
}
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
lhs.SetDataStore(&userDataStore)
lhs.SetPersister(pe)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
if testtag.AccountService == nil {
testtag.AccountService = &remote.AccountService{}
}
switch testtag.AccountService.(type) {
case *testservice.TestAccountService:
go func() {
eventChannel <- false
}()
case *remote.AccountService:
go func() {
time.Sleep(5 * time.Second) // Wait for 5 seconds
eventChannel <- true
}()
default:
panic("Unknown account service type")
}
hl, err := lhs.GetHandler(testtag.AccountService)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
en := lhs.GetEngine()
en = en.WithFirst(hl.Init)
cleanFn := func() {
err := en.Finish()
if err != nil {
logg.Errorf(err.Error())
}
err = menuStorageService.Close()
if err != nil {
logg.Errorf(err.Error())
}
logg.Infof("testengine storage closed")
}
return en, cleanFn, eventChannel
}

View File

@@ -1,15 +0,0 @@
package testutil
import (
"testing"
)
func TestCreateEngine(t *testing.T) {
o, clean, eventC := TestEngine("foo")
defer clean()
defer func() {
<-eventC
close(eventC)
}()
_ = o
}

View File

@@ -3,7 +3,7 @@ package mocks
import (
"context"
"git.grassecon.net/urdt/ussd/models"
"git.grassecon.net/grassrootseconomics/visedriver/models"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
"github.com/stretchr/testify/mock"
)

View File

@@ -1,62 +0,0 @@
package testservice
import (
"context"
"encoding/json"
"git.grassecon.net/urdt/ussd/models"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
)
type TestAccountService struct {
}
func (tas *TestAccountService) CreateAccount(ctx context.Context) (*models.AccountResult, error) {
return &models.AccountResult{
TrackingId: "075ccc86-f6ef-4d33-97d5-e91cfb37aa0d",
PublicKey: "0x623EFAFa8868df4B934dd12a8B26CB3Dd75A7AdD",
}, nil
}
func (tas *TestAccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResult, error) {
balanceResponse := &models.BalanceResult{
Balance: "0.003 CELO",
Nonce: json.Number("0"),
}
return balanceResponse, nil
}
func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*models.TrackStatusResult, error) {
return &models.TrackStatusResult{
Active: true,
}, nil
}
func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) ([]dataserviceapi.TokenHoldings, error) {
return []dataserviceapi.TokenHoldings{
dataserviceapi.TokenHoldings{
ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee",
TokenSymbol: "SRF",
TokenDecimals: "6",
Balance: "2745987",
},
}, nil
}
func (tas *TestAccountService) FetchTransactions(ctx context.Context, publicKey string) ([]dataserviceapi.Last10TxResponse, error) {
return []dataserviceapi.Last10TxResponse{}, nil
}
func (m TestAccountService) VoucherData(ctx context.Context, address string) (*models.VoucherDataResult, error) {
return &models.VoucherDataResult{}, nil
}
func (tas *TestAccountService) TokenTransfer(ctx context.Context, amount, from, to, tokenAddress string) (*models.TokenTransferResponse, error) {
return &models.TokenTransferResponse{
TrackingId: "e034d147-747d-42ea-928d-b5a7cb3426af",
}, nil
}
func (m TestAccountService) CheckAliasAddress(ctx context.Context, alias string) (*dataserviceapi.AliasAddress, error) {
return &dataserviceapi.AliasAddress{}, nil
}

View File

@@ -1,12 +0,0 @@
// +build !online
package testtag
import (
"git.grassecon.net/urdt/ussd/remote"
accountservice "git.grassecon.net/urdt/ussd/internal/testutil/testservice"
)
var (
AccountService remote.AccountServiceInterface = &accountservice.TestAccountService{}
)

View File

@@ -1,9 +0,0 @@
// +build online
package testtag
import "git.grassecon.net/urdt/ussd/remote"
var (
AccountService remote.AccountServiceInterface
)

View File

@@ -1,51 +0,0 @@
package utils
import (
"context"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
"git.defalsify.org/vise.git/logging"
)
var (
logg = logging.NewVanilla().WithDomain("adminstore")
)
type AdminStore struct {
ctx context.Context
FsStore db.Db
}
func NewAdminStore(ctx context.Context, fileName string) (*AdminStore, error) {
fsStore, err := getFsStore(ctx, fileName)
if err != nil {
return nil, err
}
return &AdminStore{ctx: ctx, FsStore: fsStore}, nil
}
func getFsStore(ctx context.Context, connectStr string) (db.Db, error) {
fsStore := fsdb.NewFsDb()
err := fsStore.Connect(ctx, connectStr)
fsStore.SetPrefix(db.DATATYPE_USERDATA)
if err != nil {
return nil, err
}
return fsStore, nil
}
// Checks if the given sessionId is listed as an admin.
func (as *AdminStore) IsAdmin(sessionId string) (bool, error) {
_, err := as.FsStore.Get(as.ctx, []byte(sessionId))
if err != nil {
if db.IsNotFound(err) {
logg.Printf(logging.LVL_INFO, "Returning false because session id was not found")
return false, nil
} else {
return false, err
}
}
return true, nil
}

View File

@@ -1,56 +0,0 @@
package utils
import (
"strconv"
"time"
)
// CalculateAge calculates the age based on a given birthdate and the current date in the format dd/mm/yy
// It adjusts for cases where the current date is before the birthday in the current year.
func CalculateAge(birthdate, today time.Time) int {
today = today.In(birthdate.Location())
ty, tm, td := today.Date()
today = time.Date(ty, tm, td, 0, 0, 0, 0, time.UTC)
by, bm, bd := birthdate.Date()
birthdate = time.Date(by, bm, bd, 0, 0, 0, 0, time.UTC)
if today.Before(birthdate) {
return 0
}
age := ty - by
anniversary := birthdate.AddDate(age, 0, 0)
if anniversary.After(today) {
age--
}
return age
}
// CalculateAgeWithYOB calculates the age based on the given year of birth (YOB).
// It subtracts the YOB from the current year to determine the age.
//
// Parameters:
//
// yob: The year of birth as an integer.
//
// Returns:
//
// The calculated age as an integer.
func CalculateAgeWithYOB(yob int) int {
currentYear := time.Now().Year()
return currentYear - yob
}
//IsValidYob checks if the provided yob can be considered valid
func IsValidYOb(yob string) bool {
currentYear := time.Now().Year()
yearOfBirth, err := strconv.ParseInt(yob, 10, 64)
if err != nil {
return false
}
if yearOfBirth >= 1900 && int(yearOfBirth) <= currentYear {
return true
} else {
return false
}
}

View File

@@ -1,11 +0,0 @@
package utils
var isoCodes = map[string]bool{
"eng": true, // English
"swa": true, // Swahili
"default": true, // Default language: English
}
func IsValidISO639(code string) bool {
return isoCodes[code]
}

View File

@@ -1,17 +0,0 @@
package utils
func ConstructName(firstName, familyName, defaultValue string) string {
name := defaultValue
if familyName != defaultValue {
if firstName != defaultValue {
name = firstName + " " + familyName
} else {
name = familyName
}
} else {
if firstName != defaultValue {
name = firstName
}
}
return name
}