Compare commits

..

17 Commits

Author SHA1 Message Date
lash
9a528cfd14
Clean up messily failed conflict resolution 2024-11-01 03:17:01 +00:00
lash
8cc46d2782 Merge branch 'master' into lash/export-to-term 2024-10-31 22:58:36 +00:00
45945ae9c5 Merge pull request 'Consolidate temp data storage' (#150) from consolidate-temp-data-storage into master
Reviewed-on: #150
2024-10-31 23:47:04 +01:00
d7ea8fa651
Use the DATA_TEMPORARY_VALUE for the user data 2024-11-01 01:10:58 +03:00
e75aa2c1f7 Merge branch 'master' into consolidate-temp-data-storage 2024-11-01 00:45:32 +03:00
63eed81d3d
Merge branch 'master' into consolidate-temp-data-storage 2024-11-01 00:44:15 +03:00
f4ca4454ea
use a single DATA_TEMPORARY_VALUE for the PIN and voucher data 2024-11-01 00:42:23 +03:00
5f666382ab Merge pull request 'profile-update-pin-check' (#149) from profile-update-pin-check into master
Reviewed-on: #149
2024-10-31 16:06:47 +01:00
ce917d9e89
update tests 2024-10-31 17:05:06 +03:00
3ce25d0e14
Merge branch 'master' into profile-update-pin-check 2024-10-31 16:42:30 +03:00
0b4bf58107
resolved failing tests due to tempData 2024-10-31 16:31:29 +03:00
lash
4bf56c525f
Export voucher related code 2024-10-31 13:19:44 +00:00
d25128287e
update profile information on individual node 2024-10-31 14:21:22 +03:00
c45fcda2f1
remove back option check,protect profile data update 2024-10-31 14:20:04 +03:00
211cc1f775
perform profile update in individual update node 2024-10-31 14:19:12 +03:00
981f7ca4f6
add keys to for holding temporary profile info 2024-10-31 14:14:50 +03:00
05ed236e03
add node to update individual profile information 2024-10-31 14:14:10 +03:00
20 changed files with 204 additions and 165 deletions

View File

@ -22,17 +22,14 @@ const (
DATA_OFFERINGS DATA_OFFERINGS
DATA_RECIPIENT DATA_RECIPIENT
DATA_AMOUNT DATA_AMOUNT
DATA_TEMPORARY_PIN DATA_TEMPORARY_VALUE
DATA_VOUCHER_LIST DATA_VOUCHER_LIST
DATA_TEMPORARY_SYM
DATA_ACTIVE_SYM DATA_ACTIVE_SYM
DATA_TEMPORARY_BAL
DATA_ACTIVE_BAL DATA_ACTIVE_BAL
DATA_PUBLIC_KEY_REVERSE DATA_PUBLIC_KEY_REVERSE
DATA_TEMPORARY_DECIMAL
DATA_ACTIVE_DECIMAL DATA_ACTIVE_DECIMAL
DATA_TEMPORARY_ADDRESS
DATA_ACTIVE_ADDRESS DATA_ACTIVE_ADDRESS
) )
func typToBytes(typ DataTyp) []byte { func typToBytes(typ DataTyp) []byte {

View File

@ -1,4 +1,4 @@
package utils package common
import ( import (
"context" "context"
@ -6,7 +6,6 @@ import (
"strings" "strings"
"git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/common"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
@ -96,59 +95,44 @@ func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol,
return return
} }
// StoreTemporaryVoucher saves voucher metadata as temporary entries in the common.DataStore. // StoreTemporaryVoucher saves voucher metadata as temporary entries in the DataStore.
func StoreTemporaryVoucher(ctx context.Context, store common.DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error {
entries := map[common.DataTyp][]byte{ tempData := fmt.Sprintf("%s,%s,%s,%s", data.TokenSymbol, data.Balance, data.TokenDecimals, data.ContractAddress)
common.DATA_TEMPORARY_SYM: []byte(data.TokenSymbol),
common.DATA_TEMPORARY_BAL: []byte(data.Balance),
common.DATA_TEMPORARY_DECIMAL: []byte(data.TokenDecimals),
common.DATA_TEMPORARY_ADDRESS: []byte(data.ContractAddress),
}
for key, value := range entries { if err := store.WriteEntry(ctx, sessionId, DATA_TEMPORARY_VALUE, []byte(tempData)); err != nil {
if err := store.WriteEntry(ctx, sessionId, key, value); err != nil {
return err return err
} }
}
return nil return nil
} }
// GetTemporaryVoucherData retrieves temporary voucher metadata from the common.DataStore. // GetTemporaryVoucherData retrieves temporary voucher metadata from the DataStore.
func GetTemporaryVoucherData(ctx context.Context, store common.DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) { func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) {
keys := []common.DataTyp{ temp_data, err := store.ReadEntry(ctx, sessionId, DATA_TEMPORARY_VALUE)
common.DATA_TEMPORARY_SYM,
common.DATA_TEMPORARY_BAL,
common.DATA_TEMPORARY_DECIMAL,
common.DATA_TEMPORARY_ADDRESS,
}
data := &dataserviceapi.TokenHoldings{}
values := make([][]byte, len(keys))
for i, key := range keys {
value, err := store.ReadEntry(ctx, sessionId, key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
values[i] = value
}
data.TokenSymbol = string(values[0]) values := strings.SplitN(string(temp_data), ",", 4)
data.Balance = string(values[1])
data.TokenDecimals = string(values[2]) data := &dataserviceapi.TokenHoldings{}
data.ContractAddress = string(values[3])
data.TokenSymbol = values[0]
data.Balance = values[1]
data.TokenDecimals = values[2]
data.ContractAddress = values[3]
return data, nil return data, nil
} }
// UpdateVoucherData sets the active voucher data and clears the temporary voucher data in the common.DataStore. // UpdateVoucherData sets the active voucher data and clears the temporary voucher data in the DataStore.
func UpdateVoucherData(ctx context.Context, store common.DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { func UpdateVoucherData(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error {
// Active voucher data entries // Active voucher data entries
activeEntries := map[common.DataTyp][]byte{ activeEntries := map[DataTyp][]byte{
common.DATA_ACTIVE_SYM: []byte(data.TokenSymbol), DATA_ACTIVE_SYM: []byte(data.TokenSymbol),
common.DATA_ACTIVE_BAL: []byte(data.Balance), DATA_ACTIVE_BAL: []byte(data.Balance),
common.DATA_ACTIVE_DECIMAL: []byte(data.TokenDecimals), DATA_ACTIVE_DECIMAL: []byte(data.TokenDecimals),
common.DATA_ACTIVE_ADDRESS: []byte(data.ContractAddress), DATA_ACTIVE_ADDRESS: []byte(data.ContractAddress),
} }
// Write active data // Write active data

View File

@ -1,20 +1,20 @@
package utils package common
import ( import (
"context" "context"
"fmt"
"testing" "testing"
"github.com/alecthomas/assert/v2" "github.com/alecthomas/assert/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/common"
memdb "git.defalsify.org/vise.git/db/mem" memdb "git.defalsify.org/vise.git/db/mem"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
// InitializeTestDb sets up and returns an in-memory database and store. // InitializeTestDb sets up and returns an in-memory database and store.
func InitializeTestDb(t *testing.T) (context.Context, *common.UserDataStore) { func InitializeTestDb(t *testing.T) (context.Context, *UserDataStore) {
ctx := context.Background() ctx := context.Background()
// Initialize memDb // Initialize memDb
@ -22,8 +22,8 @@ func InitializeTestDb(t *testing.T) (context.Context, *common.UserDataStore) {
err := db.Connect(ctx, "") err := db.Connect(ctx, "")
require.NoError(t, err, "Failed to connect to memDb") require.NoError(t, err, "Failed to connect to memDb")
// Create common.UserDataStore with memDb // Create UserDataStore with memDb
store := &common.UserDataStore{Db: db} store := &UserDataStore{Db: db}
t.Cleanup(func() { t.Cleanup(func() {
db.Close() // Ensure the DB is closed after each test db.Close() // Ensure the DB is closed after each test
@ -127,18 +127,11 @@ func TestStoreTemporaryVoucher(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Verify stored data // Verify stored data
expectedEntries := map[common.DataTyp][]byte{ expectedData := fmt.Sprintf("%s,%s,%s,%s", "SRF", "200", "6", "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9")
common.DATA_TEMPORARY_SYM: []byte("SRF"),
common.DATA_TEMPORARY_BAL: []byte("200"),
common.DATA_TEMPORARY_DECIMAL: []byte("6"),
common.DATA_TEMPORARY_ADDRESS: []byte("0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9"),
}
for key, expectedValue := range expectedEntries { storedValue, err := store.ReadEntry(ctx, sessionId, DATA_TEMPORARY_VALUE)
storedValue, err := store.ReadEntry(ctx, sessionId, key)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, expectedValue, storedValue, "Mismatch for key %v", key) require.Equal(t, expectedData, string(storedValue), "Mismatch for key %v", DATA_TEMPORARY_VALUE)
}
} }
func TestGetTemporaryVoucherData(t *testing.T) { func TestGetTemporaryVoucherData(t *testing.T) {
@ -189,11 +182,11 @@ func TestUpdateVoucherData(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Verify active data was stored correctly // Verify active data was stored correctly
activeEntries := map[common.DataTyp][]byte{ activeEntries := map[DataTyp][]byte{
common.DATA_ACTIVE_SYM: []byte(newData.TokenSymbol), DATA_ACTIVE_SYM: []byte(newData.TokenSymbol),
common.DATA_ACTIVE_BAL: []byte(newData.Balance), DATA_ACTIVE_BAL: []byte(newData.Balance),
common.DATA_ACTIVE_DECIMAL: []byte(newData.TokenDecimals), DATA_ACTIVE_DECIMAL: []byte(newData.TokenDecimals),
common.DATA_ACTIVE_ADDRESS: []byte(newData.ContractAddress), DATA_ACTIVE_ADDRESS: []byte(newData.ContractAddress),
} }
for key, expectedValue := range activeEntries { for key, expectedValue := range activeEntries {

View File

@ -19,9 +19,9 @@ import (
"git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state" "git.defalsify.org/vise.git/state"
"git.grassecon.net/urdt/ussd/internal/utils"
"git.grassecon.net/urdt/ussd/common" "git.grassecon.net/urdt/ussd/common"
"git.grassecon.net/urdt/ussd/remote" "git.grassecon.net/urdt/ussd/remote"
"git.grassecon.net/urdt/ussd/internal/utils"
"gopkg.in/leonelquinteros/gotext.v1" "gopkg.in/leonelquinteros/gotext.v1"
"git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/internal/storage"
@ -33,7 +33,6 @@ var (
translationDir = path.Join(scriptDir, "locale") translationDir = path.Join(scriptDir, "locale")
okResponse *api.OKResponse okResponse *api.OKResponse
errResponse *api.ErrResponse errResponse *api.ErrResponse
backOption = []byte("0")
) )
// FlagManager handles centralized flag management // FlagManager handles centralized flag management
@ -222,7 +221,7 @@ func (h *Handlers) VerifyNewPin(ctx context.Context, sym string, input []byte) (
return res, nil return res, nil
} }
// SaveTemporaryPin saves the valid PIN input to the DATA_TEMPORARY_PIN // SaveTemporaryPin saves the valid PIN input to the DATA_TEMPORARY_VALUE
// during the account creation process // during the account creation process
// and during the change PIN process // and during the change PIN process
func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
@ -247,7 +246,7 @@ func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byt
res.FlagReset = append(res.FlagReset, flag_incorrect_pin) res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_PIN, []byte(accountPIN)) err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(accountPIN))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -264,7 +263,7 @@ func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byt
flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch") flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
store := h.userdataStore store := h.userdataStore
temporaryPin, err := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_PIN) temporaryPin, err := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -295,7 +294,7 @@ func (h *Handlers) VerifyCreatePin(ctx context.Context, sym string, input []byte
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
store := h.userdataStore store := h.userdataStore
temporaryPin, err := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_PIN) temporaryPin, err := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -334,13 +333,18 @@ func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte)
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) > 0 {
if bytes.Equal(input, backOption) {
return res, nil
}
firstName := string(input) firstName := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_FIRST_NAME, []byte(firstName)) flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_FIRST_NAME, []byte(temporaryFirstName))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(firstName))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -357,20 +361,25 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) > 0 {
if bytes.Equal(input, backOption) {
return res, nil
}
familyName := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_FAMILY_NAME, []byte(familyName)) familyName := string(input)
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
if err != nil { if err != nil {
return res, err return res, err
} }
} else { } else {
return res, fmt.Errorf("a family name cannot be less than one character") err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(familyName))
if err != nil {
return res, err
}
} }
return res, nil return res, nil
} }
@ -382,10 +391,19 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) == 4 {
yob := string(input) yob := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_YOB, []byte(yob)) flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryYob, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_YOB, []byte(temporaryYob))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(yob))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -402,13 +420,20 @@ func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) > 0 {
if bytes.Equal(input, backOption) {
return res, nil
}
location := string(input) location := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_LOCATION, []byte(location))
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryLocation, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_LOCATION, []byte(temporaryLocation))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(location))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -426,14 +451,22 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if bytes.Equal(input, backOption) {
return res, nil
}
gender := strings.Split(symbol, "_")[1] gender := strings.Split(symbol, "_")[1]
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_GENDER, []byte(gender)) flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryGender, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_GENDER, []byte(temporaryGender))
if err != nil { if err != nil {
return res, nil return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(gender))
if err != nil {
return res, err
}
} }
return res, nil return res, nil
@ -447,12 +480,23 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte)
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) > 0 {
offerings := string(input) offerings := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, common.DATA_OFFERINGS, []byte(offerings))
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryOfferings, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE)
err = store.WriteEntry(ctx, sessionId, common.DATA_OFFERINGS, []byte(temporaryOfferings))
if err != nil { if err != nil {
return res, nil return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(offerings))
if err != nil {
return res, err
} }
} }
@ -1117,7 +1161,7 @@ func (h *Handlers) CheckVouchers(ctx context.Context, sym string, input []byte)
return res, nil return res, nil
} }
data := utils.ProcessVouchers(vouchersResp) data := common.ProcessVouchers(vouchersResp)
// Store all voucher data // Store all voucher data
dataMap := map[string]string{ dataMap := map[string]string{
@ -1167,7 +1211,7 @@ func (h *Handlers) ViewVoucher(ctx context.Context, sym string, input []byte) (r
return res, nil return res, nil
} }
metadata, err := utils.GetVoucherData(ctx, h.prefixDb, inputStr) metadata, err := common.GetVoucherData(ctx, h.prefixDb, inputStr)
if err != nil { if err != nil {
return res, fmt.Errorf("failed to retrieve voucher data: %v", err) return res, fmt.Errorf("failed to retrieve voucher data: %v", err)
} }
@ -1177,7 +1221,7 @@ func (h *Handlers) ViewVoucher(ctx context.Context, sym string, input []byte) (r
return res, nil return res, nil
} }
if err := utils.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil { if err := common.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
return res, err return res, err
} }
@ -1198,13 +1242,13 @@ func (h *Handlers) SetVoucher(ctx context.Context, sym string, input []byte) (re
// Get temporary data // Get temporary data
tempData, err := utils.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId) tempData, err := common.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
return res, err return res, err
} }
// Set as active and clear temporary data // Set as active and clear temporary data
if err := utils.UpdateVoucherData(ctx, h.userdataStore, sessionId, tempData); err != nil { if err := common.UpdateVoucherData(ctx, h.userdataStore, sessionId, tempData); err != nil {
return res, err return res, err
} }

View File

@ -168,8 +168,11 @@ func TestWithPersister_PanicWhenAlreadySet(t *testing.T) {
} }
func TestSaveFirstname(t *testing.T) { func TestSaveFirstname(t *testing.T) {
// Create a new instance of MockMyDataStore // Create new mocks
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16)
fm, err := NewFlagManager(flagsPath)
// Define test data // Define test data
sessionId := "session123" sessionId := "session123"
@ -177,11 +180,13 @@ func TestSaveFirstname(t *testing.T) {
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_FIRST_NAME, []byte(firstName)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(firstName)).Return(nil)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
flagManager: fm.parser,
st: mockState,
} }
// Call the method // Call the method
@ -198,6 +203,9 @@ func TestSaveFirstname(t *testing.T) {
func TestSaveFamilyname(t *testing.T) { func TestSaveFamilyname(t *testing.T) {
// Create a new instance of UserDataStore // Create a new instance of UserDataStore
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16)
fm, err := NewFlagManager(flagsPath)
// Define test data // Define test data
sessionId := "session123" sessionId := "session123"
@ -205,11 +213,13 @@ func TestSaveFamilyname(t *testing.T) {
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_FAMILY_NAME, []byte(familyName)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(familyName)).Return(nil)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
st: mockState,
flagManager: fm.parser,
} }
// Call the method // Call the method
@ -265,7 +275,7 @@ func TestSaveTemporaryPin(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_PIN, []byte(tt.input)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(tt.input)).Return(nil)
// Call the method // Call the method
res, err := h.SaveTemporaryPin(ctx, "save_pin", tt.input) res, err := h.SaveTemporaryPin(ctx, "save_pin", tt.input)
@ -282,8 +292,11 @@ func TestSaveTemporaryPin(t *testing.T) {
} }
func TestSaveYoB(t *testing.T) { func TestSaveYoB(t *testing.T) {
// Create a new instance of MockMyDataStore // Create new instances
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16)
fm, err := NewFlagManager(flagsPath)
// Define test data // Define test data
sessionId := "session123" sessionId := "session123"
@ -291,11 +304,13 @@ func TestSaveYoB(t *testing.T) {
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_YOB, []byte(yob)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(yob)).Return(nil)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
st: mockState,
flagManager: fm.parser,
} }
// Call the method // Call the method
@ -312,6 +327,9 @@ func TestSaveYoB(t *testing.T) {
func TestSaveLocation(t *testing.T) { func TestSaveLocation(t *testing.T) {
// Create a new instance of MockMyDataStore // Create a new instance of MockMyDataStore
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16)
fm, err := NewFlagManager(flagsPath)
// Define test data // Define test data
sessionId := "session123" sessionId := "session123"
@ -319,11 +337,13 @@ func TestSaveLocation(t *testing.T) {
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_LOCATION, []byte(yob)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(yob)).Return(nil)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
st: mockState,
flagManager: fm.parser,
} }
// Call the method // Call the method
@ -340,6 +360,9 @@ func TestSaveLocation(t *testing.T) {
func TestSaveOfferings(t *testing.T) { func TestSaveOfferings(t *testing.T) {
// Create a new instance of MockUserDataStore // Create a new instance of MockUserDataStore
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16)
fm, err := NewFlagManager(flagsPath)
// Define test data // Define test data
sessionId := "session123" sessionId := "session123"
@ -347,11 +370,13 @@ func TestSaveOfferings(t *testing.T) {
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_OFFERINGS, []byte(offerings)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(offerings)).Return(nil)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
st: mockState,
flagManager: fm.parser,
} }
// Call the method // Call the method
@ -366,10 +391,12 @@ func TestSaveOfferings(t *testing.T) {
} }
func TestSaveGender(t *testing.T) { func TestSaveGender(t *testing.T) {
// Create a new instance of MockMyDataStore // Create a new mock instances
mockStore := new(mocks.MockUserDataStore) mockStore := new(mocks.MockUserDataStore)
mockState := state.NewState(16) mockState := state.NewState(16)
fm, _ := NewFlagManager(flagsPath)
// Define the session ID and context // Define the session ID and context
sessionId := "session123" sessionId := "session123"
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx := context.WithValue(context.Background(), "SessionId", sessionId)
@ -409,16 +436,17 @@ func TestSaveGender(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
// Set up expectations for the mock database // Set up expectations for the mock database
if tt.expectCall { if tt.expectCall {
expectedKey := common.DATA_GENDER expectedKey := common.DATA_TEMPORARY_VALUE
mockStore.On("WriteEntry", ctx, sessionId, expectedKey, []byte(tt.expectedGender)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, expectedKey, []byte(tt.expectedGender)).Return(nil)
} else { } else {
mockStore.On("WriteEntry", ctx, sessionId, common.DATA_GENDER, []byte(tt.expectedGender)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(tt.expectedGender)).Return(nil)
} }
mockState.ExecPath = append(mockState.ExecPath, tt.executingSymbol) mockState.ExecPath = append(mockState.ExecPath, tt.executingSymbol)
// Create the Handlers instance with the mock store // Create the Handlers instance with the mock store
h := &Handlers{ h := &Handlers{
userdataStore: mockStore, userdataStore: mockStore,
st: mockState, st: mockState,
flagManager: fm.parser,
} }
// Call the method // Call the method
@ -429,9 +457,9 @@ func TestSaveGender(t *testing.T) {
// Verify expectations // Verify expectations
if tt.expectCall { if tt.expectCall {
mockStore.AssertCalled(t, "WriteEntry", ctx, sessionId, common.DATA_GENDER, []byte(tt.expectedGender)) mockStore.AssertCalled(t, "WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(tt.expectedGender))
} else { } else {
mockStore.AssertNotCalled(t, "WriteEntry", ctx, sessionId, common.DATA_GENDER, []byte(tt.expectedGender)) mockStore.AssertNotCalled(t, "WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(tt.expectedGender))
} }
}) })
} }
@ -1006,7 +1034,7 @@ func TestVerifyCreatePin(t *testing.T) {
}, },
} }
typ := common.DATA_TEMPORARY_PIN typ := common.DATA_TEMPORARY_VALUE
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -1746,7 +1774,7 @@ func TestConfirmPin(t *testing.T) {
// Set up the expected behavior of the mock // Set up the expected behavior of the mock
mockDataStore.On("WriteEntry", ctx, sessionId, common.DATA_ACCOUNT_PIN, []byte(tt.temporarypin)).Return(nil) mockDataStore.On("WriteEntry", ctx, sessionId, common.DATA_ACCOUNT_PIN, []byte(tt.temporarypin)).Return(nil)
mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_PIN).Return(tt.temporarypin, nil) mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE).Return(tt.temporarypin, nil)
//Call the function under test //Call the function under test
res, _ := h.ConfirmPinChange(ctx, "confirm_pin_change", tt.temporarypin) res, _ := h.ConfirmPinChange(ctx, "confirm_pin_change", tt.temporarypin)
@ -1984,16 +2012,9 @@ func TestViewVoucher(t *testing.T) {
} }
// Set up expectations for mockDataStore // Set up expectations for mockDataStore
expectedData := map[common.DataTyp]string{ expectedData := fmt.Sprintf("%s,%s,%s,%s", "SRF", "100", "6", "0xd4c288865Ce")
common.DATA_TEMPORARY_SYM: "SRF",
common.DATA_TEMPORARY_BAL: "100",
common.DATA_TEMPORARY_DECIMAL: "6",
common.DATA_TEMPORARY_ADDRESS: "0xd4c288865Ce",
}
for dataType, dataValue := range expectedData { mockDataStore.On("WriteEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE, []byte(expectedData)).Return(nil)
mockDataStore.On("WriteEntry", ctx, sessionId, dataType, []byte(dataValue)).Return(nil)
}
res, err := h.ViewVoucher(ctx, "view_voucher", []byte("1")) res, err := h.ViewVoucher(ctx, "view_voucher", []byte("1"))
assert.NoError(t, err) assert.NoError(t, err)
@ -2017,6 +2038,8 @@ func TestSetVoucher(t *testing.T) {
ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9",
} }
expectedData := fmt.Sprintf("%s,%s,%s,%s", "SRF", "200", "6", "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9")
// Define the expected active entries // Define the expected active entries
activeEntries := map[common.DataTyp][]byte{ activeEntries := map[common.DataTyp][]byte{
common.DATA_ACTIVE_SYM: []byte(tempData.TokenSymbol), common.DATA_ACTIVE_SYM: []byte(tempData.TokenSymbol),
@ -2025,30 +2048,14 @@ func TestSetVoucher(t *testing.T) {
common.DATA_ACTIVE_ADDRESS: []byte(tempData.ContractAddress), common.DATA_ACTIVE_ADDRESS: []byte(tempData.ContractAddress),
} }
// Define the temporary entries to be cleared
tempEntries := map[common.DataTyp][]byte{
common.DATA_TEMPORARY_SYM: []byte(""),
common.DATA_TEMPORARY_BAL: []byte(""),
common.DATA_TEMPORARY_DECIMAL: []byte(""),
common.DATA_TEMPORARY_ADDRESS: []byte(""),
}
// Mocking ReadEntry calls for temporary data retrieval // Mocking ReadEntry calls for temporary data retrieval
mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_SYM).Return([]byte(tempData.TokenSymbol), nil) mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_VALUE).Return([]byte(expectedData), nil)
mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_BAL).Return([]byte(tempData.Balance), nil)
mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_DECIMAL).Return([]byte(tempData.TokenDecimals), nil)
mockDataStore.On("ReadEntry", ctx, sessionId, common.DATA_TEMPORARY_ADDRESS).Return([]byte(tempData.ContractAddress), nil)
// Mocking WriteEntry calls for setting active data // Mocking WriteEntry calls for setting active data
for key, value := range activeEntries { for key, value := range activeEntries {
mockDataStore.On("WriteEntry", ctx, sessionId, key, value).Return(nil) mockDataStore.On("WriteEntry", ctx, sessionId, key, value).Return(nil)
} }
// Mocking WriteEntry calls for clearing temporary data
for key, value := range tempEntries {
mockDataStore.On("WriteEntry", ctx, sessionId, key, value).Return(nil)
}
h := &Handlers{ h := &Handlers{
userdataStore: mockDataStore, userdataStore: mockDataStore,
} }

View File

@ -1,5 +1,5 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_familyname flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
LOAD save_familyname 0 LOAD save_familyname 0

View File

@ -1,5 +1,5 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_location flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
LOAD save_location 0 LOAD save_location 0

View File

@ -1,5 +1,5 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_firstname flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
LOAD save_firstname 0 LOAD save_firstname 0

View File

@ -1,5 +1,5 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_offerings flag_allow_update 1
LOAD save_offerings 0 LOAD save_offerings 0
MOUT back 0 MOUT back 0
HALT HALT

View File

@ -1,10 +1,10 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_yob flag_allow_update 1
LOAD save_yob 0
MOUT back 0 MOUT back 0
HALT HALT
LOAD verify_yob 0 LOAD verify_yob 0
CATCH incorrect_date_format flag_incorrect_date_format 1 CATCH incorrect_date_format flag_incorrect_date_format 1
LOAD save_yob 0
RELOAD save_yob RELOAD save_yob
INCMP _ 0 INCMP _ 0
INCMP pin_entry * INCMP pin_entry *

View File

@ -1,4 +1,4 @@
LOAD save_gender 0 LOAD save_gender 0
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_gender flag_allow_update 1
MOVE pin_entry MOVE pin_entry

View File

@ -1,4 +1,4 @@
LOAD save_gender 0 LOAD save_gender 0
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_gender flag_allow_update 1
MOVE pin_entry MOVE pin_entry

View File

@ -1,4 +1,4 @@
LOAD save_gender 0 LOAD save_gender 0
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH profile_update_success flag_allow_update 1 CATCH update_gender flag_allow_update 1
MOVE pin_entry MOVE pin_entry

View File

@ -0,0 +1,2 @@
RELOAD save_yob
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_familyname
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_firstname
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_gender
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_location
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_offerings
CATCH profile_update_success flag_allow_update 1

View File

@ -0,0 +1,2 @@
RELOAD save_yob
CATCH profile_update_success flag_allow_update 1