Compare commits

..

No commits in common. "5f666382ab541d674bb9ab36178f6c32c8a2be3e" and "074345fcf96dfcce16272a0626d6a20f1ba07b38" have entirely different histories.

18 changed files with 60 additions and 151 deletions

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/common"
"git.grassecon.net/urdt/ussd/internal/handlers/server" "git.grassecon.net/urdt/ussd/internal/handlers/server"
"git.grassecon.net/urdt/ussd/internal/utils" "git.grassecon.net/urdt/ussd/internal/utils"
"git.grassecon.net/urdt/ussd/common"
"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,6 +33,7 @@ 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
@ -333,18 +334,13 @@ 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
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") err = store.WriteEntry(ctx, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_FIRST_NAME)
err = store.WriteEntry(ctx, sessionId, utils.DATA_FIRST_NAME, []byte(temporaryFirstName))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_FIRST_NAME, []byte(firstName))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -361,24 +357,20 @@ 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")
} }
store := h.userdataStore if len(input) > 0 {
if bytes.Equal(input, backOption) {
return res, nil
}
familyName := string(input) familyName := string(input)
store := h.userdataStore
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") err = store.WriteEntry(ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_FAMILY_NAME)
err = store.WriteEntry(ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
if err != nil { if err != nil {
return res, err return res, err
} }
} else { } else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_FAMILY_NAME, []byte(familyName)) return res, fmt.Errorf("a family name cannot be less than one character")
if err != nil {
return res, err
}
} }
return res, nil return res, nil
} }
@ -390,19 +382,10 @@ 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
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(yob))
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryYob, _ := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_YOB)
err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(temporaryYob))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_YOB, []byte(yob))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -419,20 +402,13 @@ 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, utils.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, utils.DATA_TEMPORARY_LOCATION)
err = store.WriteEntry(ctx, sessionId, utils.DATA_LOCATION, []byte(temporaryLocation))
if err != nil {
return res, err
}
} else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_LOCATION, []byte(location))
if err != nil { if err != nil {
return res, err return res, err
} }
@ -450,22 +426,14 @@ 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
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
allowUpdate := h.st.MatchFlag(flag_allow_update, true)
if allowUpdate {
temporaryGender, _ := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_GENDER)
err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(temporaryGender))
if err != nil { if err != nil {
return res, err return res, nil
}
} else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_GENDER, []byte(gender))
if err != nil {
return res, err
}
} }
return res, nil return res, nil
@ -479,22 +447,12 @@ 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, utils.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, utils.DATA_TEMPORARY_OFFERINGS)
err = store.WriteEntry(ctx, sessionId, utils.DATA_OFFERINGS, []byte(temporaryOfferings))
if err != nil { if err != nil {
return res, err return res, nil
}
} else {
err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_OFFERINGS, []byte(offerings))
if err != nil {
return res, err
} }
} }

View File

@ -19,8 +19,8 @@ import (
"git.grassecon.net/urdt/ussd/internal/testutil/mocks" "git.grassecon.net/urdt/ussd/internal/testutil/mocks"
"git.grassecon.net/urdt/ussd/internal/testutil/testservice" "git.grassecon.net/urdt/ussd/internal/testutil/testservice"
"git.grassecon.net/urdt/ussd/common"
"git.grassecon.net/urdt/ussd/internal/utils" "git.grassecon.net/urdt/ussd/internal/utils"
"git.grassecon.net/urdt/ussd/common"
"github.com/alecthomas/assert/v2" "github.com/alecthomas/assert/v2"
"github.com/grassrootseconomics/eth-custodial/pkg/api" "github.com/grassrootseconomics/eth-custodial/pkg/api"
testdataloader "github.com/peteole/testdata-loader" testdataloader "github.com/peteole/testdata-loader"
@ -174,11 +174,8 @@ func TestWithPersister_PanicWhenAlreadySet(t *testing.T) {
} }
func TestSaveFirstname(t *testing.T) { func TestSaveFirstname(t *testing.T) {
// Create new mocks // 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"
@ -186,13 +183,11 @@ 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, utils.DATA_TEMPORARY_FIRST_NAME, []byte(firstName)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_FIRST_NAME, []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
@ -209,9 +204,6 @@ 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"
@ -219,13 +211,11 @@ 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, utils.DATA_TEMPORARY_FAMILY_NAME, []byte(familyName)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_FAMILY_NAME, []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
@ -298,11 +288,8 @@ func TestSaveTemporaryPin(t *testing.T) {
} }
func TestSaveYoB(t *testing.T) { func TestSaveYoB(t *testing.T) {
// Create new instances // 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"
@ -310,13 +297,11 @@ 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, utils.DATA_TEMPORARY_YOB, []byte(yob)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_YOB, []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
@ -333,9 +318,6 @@ 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"
@ -343,13 +325,11 @@ 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, utils.DATA_TEMPORARY_LOCATION, []byte(yob)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_LOCATION, []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
@ -366,9 +346,6 @@ 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"
@ -376,13 +353,11 @@ 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, utils.DATA_TEMPORARY_OFFERINGS, []byte(offerings)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_OFFERINGS, []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
@ -397,12 +372,10 @@ func TestSaveOfferings(t *testing.T) {
} }
func TestSaveGender(t *testing.T) { func TestSaveGender(t *testing.T) {
// Create a new mock instances // Create a new instance of MockMyDataStore
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)
@ -442,17 +415,16 @@ 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 := utils.DATA_TEMPORARY_GENDER expectedKey := utils.DATA_GENDER
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, utils.DATA_TEMPORARY_GENDER, []byte(tt.expectedGender)).Return(nil) mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_GENDER, []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
@ -463,9 +435,9 @@ func TestSaveGender(t *testing.T) {
// Verify expectations // Verify expectations
if tt.expectCall { if tt.expectCall {
mockStore.AssertCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_GENDER, []byte(tt.expectedGender)) mockStore.AssertCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_GENDER, []byte(tt.expectedGender))
} else { } else {
mockStore.AssertNotCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_GENDER, []byte(tt.expectedGender)) mockStore.AssertNotCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_GENDER, []byte(tt.expectedGender))
} }
}) })
} }

View File

@ -14,17 +14,11 @@ const (
DATA_CUSTODIAL_ID DATA_CUSTODIAL_ID
DATA_ACCOUNT_PIN DATA_ACCOUNT_PIN
DATA_ACCOUNT_STATUS DATA_ACCOUNT_STATUS
DATA_TEMPORARY_FIRST_NAME
DATA_FIRST_NAME DATA_FIRST_NAME
DATA_TEMPORARY_FAMILY_NAME
DATA_FAMILY_NAME DATA_FAMILY_NAME
DATA_TEMPORARY_YOB
DATA_YOB DATA_YOB
DATA_TEMPORARY_LOCATION
DATA_LOCATION DATA_LOCATION
DATA_TEMPORARY_GENDER
DATA_GENDER DATA_GENDER
DATA_TEMPORARY_OFFERINGS
DATA_OFFERINGS DATA_OFFERINGS
DATA_RECIPIENT DATA_RECIPIENT
DATA_AMOUNT DATA_AMOUNT
@ -39,7 +33,6 @@ const (
DATA_ACTIVE_DECIMAL DATA_ACTIVE_DECIMAL
DATA_TEMPORARY_ADDRESS DATA_TEMPORARY_ADDRESS
DATA_ACTIVE_ADDRESS DATA_ACTIVE_ADDRESS
) )
func typToBytes(typ DataTyp) []byte { func typToBytes(typ DataTyp) []byte {

View File

@ -1,5 +1,5 @@
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH update_familyname flag_allow_update 1 CATCH profile_update_success 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 update_location flag_allow_update 1 CATCH profile_update_success 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 update_firstname flag_allow_update 1 CATCH profile_update_success 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 update_offerings flag_allow_update 1 CATCH profile_update_success 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 update_yob flag_allow_update 1 CATCH profile_update_success 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 update_gender flag_allow_update 1 CATCH profile_update_success 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 update_gender flag_allow_update 1 CATCH profile_update_success 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 update_gender flag_allow_update 1 CATCH profile_update_success flag_allow_update 1
MOVE pin_entry MOVE pin_entry

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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