Merge branch 'master' into profile-edit-traverse
This commit is contained in:
@@ -55,6 +55,9 @@ func(f *BaseSessionHandler) Process(rqs RequestSession) (RequestSession, error)
|
||||
}
|
||||
|
||||
f.hn = f.hn.WithPersister(rqs.Storage.Persister)
|
||||
defer func() {
|
||||
f.hn.Exit()
|
||||
}()
|
||||
eni := f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
|
||||
en, ok := eni.(*engine.DefaultEngine)
|
||||
if !ok {
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.defalsify.org/vise.git/asm"
|
||||
"github.com/grassrootseconomics/eth-custodial/pkg/api"
|
||||
|
||||
"git.defalsify.org/vise.git/cache"
|
||||
"git.defalsify.org/vise.git/db"
|
||||
@@ -26,14 +25,13 @@ import (
|
||||
"gopkg.in/leonelquinteros/gotext.v1"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||
)
|
||||
|
||||
var (
|
||||
logg = logging.NewVanilla().WithDomain("ussdmenuhandler")
|
||||
scriptDir = path.Join("services", "registration")
|
||||
translationDir = path.Join(scriptDir, "locale")
|
||||
okResponse *api.OKResponse
|
||||
errResponse *api.ErrResponse
|
||||
)
|
||||
|
||||
// Define the regex patterns as constants
|
||||
@@ -117,6 +115,9 @@ func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource
|
||||
logg.WarnCtxf(ctx, "handler init called before it is ready or more than once", "state", h.st, "cache", h.ca)
|
||||
return r, nil
|
||||
}
|
||||
defer func() {
|
||||
h.Exit()
|
||||
}()
|
||||
|
||||
h.st = h.pe.GetState()
|
||||
h.ca = h.pe.GetMemory()
|
||||
@@ -136,13 +137,16 @@ func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource
|
||||
logg.ErrorCtxf(ctx, "perister fail in handler", "state", h.st, "cache", h.ca)
|
||||
return r, fmt.Errorf("cannot get state and memory for handler")
|
||||
}
|
||||
h.pe = nil
|
||||
|
||||
logg.DebugCtxf(ctx, "handler has been initialized", "state", h.st, "cache", h.ca)
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (h *Handlers) Exit() {
|
||||
h.pe = nil
|
||||
}
|
||||
|
||||
// SetLanguage sets the language across the menu
|
||||
func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||
var res resource.Result
|
||||
@@ -151,7 +155,8 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
|
||||
code := strings.Split(symbol, "_")[1]
|
||||
|
||||
if !utils.IsValidISO639(code) {
|
||||
return res, nil
|
||||
//Fallback to english instead?
|
||||
code = "eng"
|
||||
}
|
||||
res.FlagSet = append(res.FlagSet, state.FLAG_LANG)
|
||||
res.Content = code
|
||||
@@ -806,12 +811,11 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res
|
||||
return res, nil
|
||||
}
|
||||
|
||||
if len(date) == 4 {
|
||||
if utils.IsValidYOb(date) {
|
||||
res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
|
||||
} else {
|
||||
res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -860,7 +864,17 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.Content = l.Get("Balance: %s\n", fmt.Sprintf("%s %s", activeBal, activeSym))
|
||||
// Convert activeBal from []byte to float64
|
||||
balFloat, err := strconv.ParseFloat(string(activeBal), 64)
|
||||
if err != nil {
|
||||
logg.ErrorCtxf(ctx, "failed to parse activeBal as float", "value", string(activeBal), "error", err)
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Format to 2 decimal places
|
||||
balStr := fmt.Sprintf("%.2f %s", balFloat, activeSym)
|
||||
|
||||
res.Content = l.Get("Balance: %s\n", balStr)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -1450,14 +1464,7 @@ func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte)
|
||||
offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, common.DATA_OFFERINGS))
|
||||
|
||||
// Construct the full name
|
||||
name := defaultValue
|
||||
if familyName != defaultValue {
|
||||
if firstName == defaultValue {
|
||||
name = familyName
|
||||
} else {
|
||||
name = firstName + " " + familyName
|
||||
}
|
||||
}
|
||||
name := utils.ConstructName(firstName, familyName, defaultValue)
|
||||
|
||||
// Calculate age from year of birth
|
||||
age := defaultValue
|
||||
@@ -1596,6 +1603,38 @@ func (h *Handlers) CheckVouchers(ctx context.Context, sym string, input []byte)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// check the current active sym and update the data
|
||||
activeSym, _ := store.ReadEntry(ctx, sessionId, common.DATA_ACTIVE_SYM)
|
||||
if activeSym != nil {
|
||||
activeSymStr := string(activeSym)
|
||||
|
||||
// Find the matching voucher data
|
||||
var activeData *dataserviceapi.TokenHoldings
|
||||
for _, voucher := range vouchersResp {
|
||||
if voucher.TokenSymbol == activeSymStr {
|
||||
activeData = &voucher
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if activeData == nil {
|
||||
logg.ErrorCtxf(ctx, "activeSym not found in vouchers", "activeSym", activeSymStr)
|
||||
return res, fmt.Errorf("activeSym %s not found in vouchers", activeSymStr)
|
||||
}
|
||||
|
||||
// Scale down the balance
|
||||
scaledBalance := common.ScaleDownBalance(activeData.Balance, activeData.TokenDecimals)
|
||||
|
||||
// Update the balance field with the scaled value
|
||||
activeData.Balance = scaledBalance
|
||||
|
||||
// Pass the matching voucher data to UpdateVoucherData
|
||||
if err := common.UpdateVoucherData(ctx, h.userdataStore, sessionId, activeData); err != nil {
|
||||
logg.ErrorCtxf(ctx, "failed on UpdateVoucherData", "error", err)
|
||||
return res, err
|
||||
}
|
||||
}
|
||||
|
||||
data := common.ProcessVouchers(vouchersResp)
|
||||
|
||||
// Store all voucher data
|
||||
@@ -1640,6 +1679,10 @@ func (h *Handlers) ViewVoucher(ctx context.Context, sym string, input []byte) (r
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
|
||||
code := codeFromCtx(ctx)
|
||||
l := gotext.NewLocale(translationDir, code)
|
||||
l.AddDomain("default")
|
||||
|
||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
||||
|
||||
inputStr := string(input)
|
||||
@@ -1664,7 +1707,7 @@ func (h *Handlers) ViewVoucher(ctx context.Context, sym string, input []byte) (r
|
||||
}
|
||||
|
||||
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher)
|
||||
res.Content = fmt.Sprintf("%s\n%s", metadata.TokenSymbol, metadata.Balance)
|
||||
res.Content = l.Get("Symbol: %s\nBalance: %s", metadata.TokenSymbol, metadata.Balance)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@@ -1720,10 +1763,9 @@ func (h *Handlers) GetVoucherDetails(ctx context.Context, sym string, input []by
|
||||
return res, nil
|
||||
}
|
||||
|
||||
tokenSymbol := voucherData.TokenSymbol
|
||||
tokenName := voucherData.TokenName
|
||||
|
||||
res.Content = fmt.Sprintf("%s %s", tokenSymbol, tokenName)
|
||||
res.Content = fmt.Sprintf(
|
||||
"Name: %s\nSymbol: %s\nCommodity: %s\nLocation: %s", voucherData.TokenName, voucherData.TokenSymbol, voucherData.TokenCommodity, voucherData.TokenLocation,
|
||||
)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -1498,10 +1498,10 @@ func TestValidateRecipient(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "Test with invalid recepient",
|
||||
input: []byte("9234adf5"),
|
||||
input: []byte("7?1234"),
|
||||
expectedResult: resource.Result{
|
||||
FlagSet: []uint32{flag_invalid_recipient},
|
||||
Content: "9234adf5",
|
||||
Content: "7?1234",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1517,22 +1517,40 @@ func TestValidateRecipient(t *testing.T) {
|
||||
input: []byte("0711223344"),
|
||||
expectedResult: resource.Result{},
|
||||
},
|
||||
{
|
||||
name: "Test with address",
|
||||
input: []byte("0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9"),
|
||||
expectedResult: resource.Result{},
|
||||
},
|
||||
{
|
||||
name: "Test with alias recepient",
|
||||
input: []byte("alias123"),
|
||||
expectedResult: resource.Result{},
|
||||
},
|
||||
}
|
||||
|
||||
// store a public key for the valid recipient
|
||||
err = store.WriteEntry(ctx, "0711223344", common.DATA_PUBLIC_KEY, []byte(publicKey))
|
||||
err = store.WriteEntry(ctx, "+254711223344", common.DATA_PUBLIC_KEY, []byte(publicKey))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockAccountService := new(mocks.MockAccountService)
|
||||
// Create the Handlers instance
|
||||
h := &Handlers{
|
||||
flagManager: fm.parser,
|
||||
userdataStore: store,
|
||||
flagManager: fm.parser,
|
||||
userdataStore: store,
|
||||
accountService: mockAccountService,
|
||||
}
|
||||
|
||||
aliasResponse := &dataserviceapi.AliasAddress{
|
||||
Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9",
|
||||
}
|
||||
|
||||
mockAccountService.On("CheckAliasAddress", string(tt.input)).Return(aliasResponse, nil)
|
||||
|
||||
// Call the method
|
||||
res, err := h.ValidateRecipient(ctx, "validate_recepient", tt.input)
|
||||
|
||||
@@ -1564,7 +1582,7 @@ func TestCheckBalance(t *testing.T) {
|
||||
publicKey: "0X98765432109",
|
||||
activeSym: "ETH",
|
||||
activeBal: "1.5",
|
||||
expectedResult: resource.Result{Content: "Balance: 1.5 ETH\n"},
|
||||
expectedResult: resource.Result{Content: "Balance: 1.50 ETH\n"},
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
@@ -1990,7 +2008,7 @@ func TestViewVoucher(t *testing.T) {
|
||||
|
||||
res, err := h.ViewVoucher(ctx, "view_voucher", []byte("1"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, res.Content, "SRF\n100")
|
||||
assert.Equal(t, res.Content, "Symbol: SRF\nBalance: 100")
|
||||
}
|
||||
|
||||
func TestSetVoucher(t *testing.T) {
|
||||
@@ -2024,3 +2042,42 @@ func TestSetVoucher(t *testing.T) {
|
||||
|
||||
assert.Equal(t, string(tempData.TokenSymbol), res.Content)
|
||||
}
|
||||
|
||||
func TestGetVoucherDetails(t *testing.T) {
|
||||
ctx, store := InitializeTestStore(t)
|
||||
fm, err := NewFlagManager(flagsPath)
|
||||
if err != nil {
|
||||
t.Logf(err.Error())
|
||||
}
|
||||
mockAccountService := new(mocks.MockAccountService)
|
||||
|
||||
sessionId := "session123"
|
||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||
expectedResult := resource.Result{}
|
||||
|
||||
tokA_AAddress := "0x0000000000000000000000000000000000000000"
|
||||
|
||||
h := &Handlers{
|
||||
userdataStore: store,
|
||||
flagManager: fm.parser,
|
||||
accountService: mockAccountService,
|
||||
}
|
||||
err = store.WriteEntry(ctx, sessionId, common.DATA_ACTIVE_ADDRESS, []byte(tokA_AAddress))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tokenDetails := &models.VoucherDataResult{
|
||||
TokenName: "Token A",
|
||||
TokenSymbol: "TOKA",
|
||||
TokenLocation: "Kilifi,Kenya",
|
||||
TokenCommodity: "Farming",
|
||||
}
|
||||
expectedResult.Content = fmt.Sprintf(
|
||||
"Name: %s\nSymbol: %s\nCommodity: %s\nLocation: %s", tokenDetails.TokenName, tokenDetails.TokenSymbol, tokenDetails.TokenCommodity, tokenDetails.TokenLocation,
|
||||
)
|
||||
mockAccountService.On("VoucherData", string(tokA_AAddress)).Return(tokenDetails, nil)
|
||||
|
||||
res, err := h.GetVoucherDetails(ctx, "SessionId", []byte(""))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expectedResult, res)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user