Compare commits
38 Commits
b7d93c2249
...
9647d29bd7
Author | SHA1 | Date | |
---|---|---|---|
9647d29bd7 | |||
64cc9bc752 | |||
ddfd9d4e89 | |||
a1201e2525 | |||
ddeafe015b | |||
a3ff3be5b1 | |||
ea52a7cf0a | |||
a993026380 | |||
|
4ee241714b | ||
|
d7dc743fa2 | ||
|
c220cbb767 | ||
0dc322729f | |||
726d6dd338 | |||
a8b202bd79 | |||
6dbd250694 | |||
cc760e7698 | |||
8648ea599c | |||
77e4c5d43a | |||
b15ba367c4 | |||
4db862bc97 | |||
6ad67f6adc | |||
0dea34daab | |||
8057313c78 | |||
1bd96d0689 | |||
bbfe46f162 | |||
eff2cbde8b | |||
5c85ecffd1 | |||
|
ad1f9233ca | ||
|
c18c40b1b8 | ||
|
a07fce527f | ||
|
ddc8f6dad1 | ||
|
c2b68231f5 | ||
|
3f3dbf414c | ||
|
e4c3e9f015 | ||
|
9b71244391 | ||
|
ada1f26b68 | ||
|
935b777e57 | ||
|
19372c17f4 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,3 +4,5 @@ go.work*
|
|||||||
**/*/*.bin
|
**/*/*.bin
|
||||||
**/*/.state/
|
**/*/.state/
|
||||||
cmd/.state/
|
cmd/.state/
|
||||||
|
id_*
|
||||||
|
*.gdbm
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
@ -20,7 +21,7 @@ var (
|
|||||||
scriptDir = path.Join(baseDir, "services", "registration")
|
scriptDir = path.Join(baseDir, "services", "registration")
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEngine(sessionId string) (engine.Engine, func()) {
|
func TestEngine(sessionId string) (engine.Engine, func(), *db.Db) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
@ -98,5 +99,5 @@ func TestEngine(sessionId string) (engine.Engine, func()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//en = en.WithDebug(nil)
|
//en = en.WithDebug(nil)
|
||||||
return en, cleanFn
|
return en, cleanFn, lhs.UserdataStore
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,6 @@ func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) {
|
|||||||
ls.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
|
ls.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
|
||||||
ls.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
|
ls.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
|
||||||
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
|
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
|
||||||
ls.DbRs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
|
|
||||||
ls.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
|
ls.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
|
||||||
ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
|
ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
|
||||||
ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin)
|
ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin)
|
||||||
|
@ -118,16 +118,13 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
|
|||||||
var res resource.Result
|
var res resource.Result
|
||||||
|
|
||||||
symbol, _ := h.st.Where()
|
symbol, _ := h.st.Where()
|
||||||
|
code := strings.Split(symbol, "_")[1]
|
||||||
|
|
||||||
switch symbol {
|
if !utils.IsValidISO639(code) {
|
||||||
case "set_default":
|
return res, nil
|
||||||
res.FlagSet = append(res.FlagSet, state.FLAG_LANG)
|
|
||||||
res.Content = "eng"
|
|
||||||
case "set_swa":
|
|
||||||
res.FlagSet = append(res.FlagSet, state.FLAG_LANG)
|
|
||||||
res.Content = "swa"
|
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
|
res.FlagSet = append(res.FlagSet, state.FLAG_LANG)
|
||||||
|
res.Content = code
|
||||||
|
|
||||||
languageSetFlag, err := h.flagManager.GetFlag("flag_language_set")
|
languageSetFlag, err := h.flagManager.GetFlag("flag_language_set")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -319,32 +316,6 @@ func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byt
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetResetSingleEdit sets and resets flags to allow gradual editing of profile information.
|
|
||||||
func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
|
|
||||||
menuOption := string(input)
|
|
||||||
|
|
||||||
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
|
|
||||||
flag_single_edit, _ := h.flagManager.GetFlag("flag_single_edit")
|
|
||||||
|
|
||||||
switch menuOption {
|
|
||||||
case "2":
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_allow_update)
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_single_edit)
|
|
||||||
case "3":
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_allow_update)
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_single_edit)
|
|
||||||
case "4":
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_allow_update)
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_single_edit)
|
|
||||||
default:
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_single_edit)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyPin checks whether the confirmation PIN is similar to the account PIN
|
// VerifyPin checks whether the confirmation PIN is similar to the account PIN
|
||||||
// If similar, it sets the USERFLAG_PIN_SET flag allowing the user
|
// If similar, it sets the USERFLAG_PIN_SET flag allowing the user
|
||||||
// to access the main menu
|
// to access the main menu
|
||||||
@ -475,6 +446,7 @@ func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (
|
|||||||
|
|
||||||
// SaveGender updates the gender in the gdbm with the provided input.
|
// SaveGender updates the gender in the gdbm with the provided input.
|
||||||
func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
|
symbol, _ := h.st.Where()
|
||||||
var res resource.Result
|
var res resource.Result
|
||||||
var err error
|
var err error
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
@ -482,21 +454,11 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
|
|||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(input) > 0 {
|
gender := strings.Split(symbol, "_")[1]
|
||||||
gender := string(input)
|
store := h.userdataStore
|
||||||
switch gender {
|
err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
|
||||||
case "1":
|
if err != nil {
|
||||||
gender = "Male"
|
return res, nil
|
||||||
case "2":
|
|
||||||
gender = "Female"
|
|
||||||
case "3":
|
|
||||||
gender = "Unspecified"
|
|
||||||
}
|
|
||||||
store := h.userdataStore
|
|
||||||
err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
|
|
||||||
if err != nil {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
|
"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/mocks"
|
"git.grassecon.net/urdt/ussd/internal/mocks"
|
||||||
@ -16,6 +17,7 @@ import (
|
|||||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
"git.grassecon.net/urdt/ussd/internal/utils"
|
||||||
"github.com/alecthomas/assert/v2"
|
"github.com/alecthomas/assert/v2"
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -94,6 +96,25 @@ func TestCreateAccount(t *testing.T) {
|
|||||||
mockDataStore.AssertExpectations(t)
|
mockDataStore.AssertExpectations(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithPersister(t *testing.T) {
|
||||||
|
// Test case: Setting a persister
|
||||||
|
h := &Handlers{}
|
||||||
|
p := &persist.Persister{}
|
||||||
|
|
||||||
|
result := h.WithPersister(p)
|
||||||
|
|
||||||
|
assert.Equal(t, p, h.pe, "The persister should be set correctly.")
|
||||||
|
assert.Equal(t, h, result, "The returned handler should be the same instance.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithPersister_PanicWhenAlreadySet(t *testing.T) {
|
||||||
|
// Test case: Panic on multiple calls
|
||||||
|
h := &Handlers{pe: &persist.Persister{}}
|
||||||
|
require.Panics(t, func() {
|
||||||
|
h.WithPersister(&persist.Persister{})
|
||||||
|
}, "Should panic when trying to set a persister again.")
|
||||||
|
}
|
||||||
|
|
||||||
func TestSaveFirstname(t *testing.T) {
|
func TestSaveFirstname(t *testing.T) {
|
||||||
// Create a new instance of MockMyDataStore
|
// Create a new instance of MockMyDataStore
|
||||||
mockStore := new(mocks.MockUserDataStore)
|
mockStore := new(mocks.MockUserDataStore)
|
||||||
@ -295,6 +316,7 @@ func TestSaveOfferings(t *testing.T) {
|
|||||||
func TestSaveGender(t *testing.T) {
|
func TestSaveGender(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)
|
||||||
|
|
||||||
// Define the session ID and context
|
// Define the session ID and context
|
||||||
sessionId := "session123"
|
sessionId := "session123"
|
||||||
@ -302,34 +324,32 @@ func TestSaveGender(t *testing.T) {
|
|||||||
|
|
||||||
// Define test cases
|
// Define test cases
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
input []byte
|
input []byte
|
||||||
expectedGender string
|
expectedGender string
|
||||||
expectCall bool
|
expectCall bool
|
||||||
|
executingSymbol string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Valid Male Input",
|
name: "Valid Male Input",
|
||||||
input: []byte("1"),
|
input: []byte("1"),
|
||||||
expectedGender: "Male",
|
expectedGender: "male",
|
||||||
expectCall: true,
|
executingSymbol: "set_male",
|
||||||
|
expectCall: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valid Female Input",
|
name: "Valid Female Input",
|
||||||
input: []byte("2"),
|
input: []byte("2"),
|
||||||
expectedGender: "Female",
|
expectedGender: "female",
|
||||||
expectCall: true,
|
executingSymbol: "set_female",
|
||||||
|
expectCall: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valid Unspecified Input",
|
name: "Valid Unspecified Input",
|
||||||
input: []byte("3"),
|
input: []byte("3"),
|
||||||
expectedGender: "Unspecified",
|
executingSymbol: "set_unspecified",
|
||||||
expectCall: true,
|
expectedGender: "unspecified",
|
||||||
},
|
expectCall: true,
|
||||||
{
|
|
||||||
name: "Empty Input",
|
|
||||||
input: []byte(""),
|
|
||||||
expectedGender: "",
|
|
||||||
expectCall: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,14 +362,15 @@ func TestSaveGender(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_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)
|
||||||
// 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the method
|
// Call the method
|
||||||
_, err := h.SaveGender(ctx, "someSym", tt.input)
|
_, err := h.SaveGender(ctx, "save_gender", tt.input)
|
||||||
|
|
||||||
// Assert no error
|
// Assert no error
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -538,13 +559,13 @@ func TestSetLanguage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Define test cases
|
// Define test cases
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
execPath []string
|
execPath []string
|
||||||
expectedResult resource.Result
|
expectedResult resource.Result
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Set Default Language (English)",
|
name: "Set Default Language (English)",
|
||||||
execPath: []string{"set_default"},
|
execPath: []string{"set_eng"},
|
||||||
expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
FlagSet: []uint32{state.FLAG_LANG, 8},
|
FlagSet: []uint32{state.FLAG_LANG, 8},
|
||||||
Content: "eng",
|
Content: "eng",
|
||||||
@ -558,13 +579,6 @@ func TestSetLanguage(t *testing.T) {
|
|||||||
Content: "swa",
|
Content: "swa",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Unhandled path",
|
|
||||||
execPath: []string{""},
|
|
||||||
expectedResult: resource.Result{
|
|
||||||
FlagSet: []uint32{8},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -592,76 +606,6 @@ func TestSetLanguage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetResetSingleEdit(t *testing.T) {
|
|
||||||
fm, err := NewFlagManager(flagsPath)
|
|
||||||
|
|
||||||
flag_allow_update, _ := fm.parser.GetFlag("flag_allow_update")
|
|
||||||
flag_single_edit, _ := fm.parser.GetFlag("flag_single_edit")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// Define test cases
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
input []byte
|
|
||||||
expectedResult resource.Result
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Set single Edit",
|
|
||||||
input: []byte("2"),
|
|
||||||
expectedResult: resource.Result{
|
|
||||||
FlagSet: []uint32{flag_single_edit},
|
|
||||||
FlagReset: []uint32{flag_allow_update},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Set single Edit",
|
|
||||||
input: []byte("3"),
|
|
||||||
expectedResult: resource.Result{
|
|
||||||
FlagSet: []uint32{flag_single_edit},
|
|
||||||
FlagReset: []uint32{flag_allow_update},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Set single edit",
|
|
||||||
input: []byte("4"),
|
|
||||||
expectedResult: resource.Result{
|
|
||||||
FlagReset: []uint32{flag_allow_update},
|
|
||||||
FlagSet: []uint32{flag_single_edit},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "No single edit set",
|
|
||||||
input: []byte("1"),
|
|
||||||
expectedResult: resource.Result{
|
|
||||||
FlagReset: []uint32{flag_single_edit},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
|
|
||||||
// Create the Handlers instance with the mock flag manager
|
|
||||||
h := &Handlers{
|
|
||||||
flagManager: fm.parser,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the method
|
|
||||||
res, err := h.SetResetSingleEdit(context.Background(), "set_reset_single_edit", tt.input)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
// Assert that the Result FlagSet has the required flags after language switch
|
|
||||||
assert.Equal(t, res, tt.expectedResult, "Flags should match reset edit")
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResetAllowUpdate(t *testing.T) {
|
func TestResetAllowUpdate(t *testing.T) {
|
||||||
fm, err := NewFlagManager(flagsPath)
|
fm, err := NewFlagManager(flagsPath)
|
||||||
|
|
||||||
@ -1483,7 +1427,7 @@ func TestValidateAmount(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf(err.Error())
|
t.Logf(err.Error())
|
||||||
}
|
}
|
||||||
//flag_invalid_amount, _ := fm.parser.GetFlag("flag_invalid_amount")
|
flag_invalid_amount, _ := fm.parser.GetFlag("flag_invalid_amount")
|
||||||
mockDataStore := new(mocks.MockUserDataStore)
|
mockDataStore := new(mocks.MockUserDataStore)
|
||||||
mockCreateAccountService := new(mocks.MockAccountService)
|
mockCreateAccountService := new(mocks.MockAccountService)
|
||||||
|
|
||||||
@ -1512,26 +1456,26 @@ func TestValidateAmount(t *testing.T) {
|
|||||||
Content: "0.001",
|
Content: "0.001",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// name: "Test with amount larger than balance",
|
name: "Test with amount larger than balance",
|
||||||
// input: []byte("0.02"),
|
input: []byte("0.02"),
|
||||||
// balance: "0.003 CELO",
|
balance: "0.003 CELO",
|
||||||
// publicKey: []byte("0xrqeqrequuq"),
|
publicKey: []byte("0xrqeqrequuq"),
|
||||||
// expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
// FlagSet: []uint32{flag_invalid_amount},
|
FlagSet: []uint32{flag_invalid_amount},
|
||||||
// Content: "0.02",
|
Content: "0.02",
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: "Test with invalid amount",
|
name: "Test with invalid amount",
|
||||||
// input: []byte("0.02ms"),
|
input: []byte("0.02ms"),
|
||||||
// balance: "0.003 CELO",
|
balance: "0.003 CELO",
|
||||||
// publicKey: []byte("0xrqeqrequuq"),
|
publicKey: []byte("0xrqeqrequuq"),
|
||||||
// expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
// FlagSet: []uint32{flag_invalid_amount},
|
FlagSet: []uint32{flag_invalid_amount},
|
||||||
// Content: "0.02ms",
|
Content: "0.02ms",
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -1539,7 +1483,7 @@ func TestValidateAmount(t *testing.T) {
|
|||||||
|
|
||||||
mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return(tt.publicKey, nil)
|
mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return(tt.publicKey, nil)
|
||||||
mockCreateAccountService.On("CheckBalance", string(tt.publicKey)).Return(tt.balance, nil)
|
mockCreateAccountService.On("CheckBalance", string(tt.publicKey)).Return(tt.balance, nil)
|
||||||
mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_AMOUNT, tt.input).Return(nil)
|
mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_AMOUNT, tt.input).Return(nil).Maybe()
|
||||||
|
|
||||||
// Call the method under test
|
// Call the method under test
|
||||||
res, _ := h.ValidateAmount(ctx, "test_validate_amount", tt.input)
|
res, _ := h.ValidateAmount(ctx, "test_validate_amount", tt.input)
|
||||||
@ -1651,6 +1595,7 @@ func TestGetProfile(t *testing.T) {
|
|||||||
|
|
||||||
mockDataStore := new(mocks.MockUserDataStore)
|
mockDataStore := new(mocks.MockUserDataStore)
|
||||||
mockCreateAccountService := new(mocks.MockAccountService)
|
mockCreateAccountService := new(mocks.MockAccountService)
|
||||||
|
|
||||||
h := &Handlers{
|
h := &Handlers{
|
||||||
userdataStore: mockDataStore,
|
userdataStore: mockDataStore,
|
||||||
accountService: mockCreateAccountService,
|
accountService: mockCreateAccountService,
|
||||||
|
11
internal/utils/isocode.go
Normal file
11
internal/utils/isocode.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
var isoCodes = map[string]bool{
|
||||||
|
"eng": true, // English
|
||||||
|
"swa": true, // Swahili
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsValidISO639(code string) bool {
|
||||||
|
return isoCodes[code]
|
||||||
|
}
|
1
services/registration/_catch
Normal file
1
services/registration/_catch
Normal file
@ -0,0 +1 @@
|
|||||||
|
Something went wrong.Please try again
|
1
services/registration/_catch.vis
Normal file
1
services/registration/_catch.vis
Normal file
@ -0,0 +1 @@
|
|||||||
|
HALT
|
@ -12,8 +12,6 @@ MOUT view 7
|
|||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP my_account 0
|
INCMP my_account 0
|
||||||
LOAD set_reset_single_edit 0
|
|
||||||
RELOAD set_reset_single_edit
|
|
||||||
INCMP enter_name 1
|
INCMP enter_name 1
|
||||||
INCMP enter_familyname 2
|
INCMP enter_familyname 2
|
||||||
INCMP select_gender 3
|
INCMP select_gender 3
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
CATCH profile_update_success flag_allow_update 1
|
CATCH profile_update_success flag_allow_update 1
|
||||||
LOAD save_gender 0
|
|
||||||
MOUT male 1
|
MOUT male 1
|
||||||
MOUT female 2
|
MOUT female 2
|
||||||
MOUT unspecified 3
|
MOUT unspecified 3
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
RELOAD save_gender
|
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
INCMP pin_entry *
|
INCMP set_male 1
|
||||||
|
INCMP set_female 2
|
||||||
|
INCMP set_unspecified 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
MOUT english 0
|
MOUT english 0
|
||||||
MOUT kiswahili 1
|
MOUT kiswahili 1
|
||||||
HALT
|
HALT
|
||||||
INCMP set_default 0
|
INCMP set_eng 0
|
||||||
INCMP set_swa 1
|
INCMP set_swa 1
|
||||||
INCMP . *
|
INCMP . *
|
||||||
|
4
services/registration/set_female.vis
Normal file
4
services/registration/set_female.vis
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LOAD save_gender 0
|
||||||
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
|
CATCH profile_update_success flag_allow_update 1
|
||||||
|
MOVE pin_entry
|
4
services/registration/set_male.vis
Normal file
4
services/registration/set_male.vis
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LOAD save_gender 0
|
||||||
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
|
CATCH profile_update_success flag_allow_update 1
|
||||||
|
MOVE pin_entry
|
4
services/registration/set_unspecified.vis
Normal file
4
services/registration/set_unspecified.vis
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LOAD save_gender 0
|
||||||
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
|
CATCH profile_update_success flag_allow_update 1
|
||||||
|
MOVE pin_entry
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -43,7 +44,7 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAccountCreationSuccessful(t *testing.T) {
|
func TestAccountCreationSuccessful(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -77,7 +78,7 @@ func TestAccountCreationSuccessful(t *testing.T) {
|
|||||||
func TestAccountRegistrationRejectTerms(t *testing.T) {
|
func TestAccountRegistrationRejectTerms(t *testing.T) {
|
||||||
// Generate a new UUID for this edge case test
|
// Generate a new UUID for this edge case test
|
||||||
edgeCaseSessionID := GenerateUUID()
|
edgeCaseSessionID := GenerateUUID()
|
||||||
en, fn := enginetest.TestEngine(edgeCaseSessionID)
|
en, fn, _ := enginetest.TestEngine(edgeCaseSessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -108,7 +109,7 @@ func TestAccountRegistrationRejectTerms(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSendWithInvalidInputs(t *testing.T) {
|
func TestSendWithInvalidInputs(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -146,7 +147,7 @@ func TestSendWithInvalidInputs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Check_My_Balance(t *testing.T) {
|
func TestMyAccount_Check_My_Balance(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -177,7 +178,7 @@ func TestMyAccount_Check_My_Balance(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMainMenuHelp(t *testing.T) {
|
func TestMainMenuHelp(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -208,7 +209,7 @@ func TestMainMenuHelp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMainMenuQuit(t *testing.T) {
|
func TestMainMenuQuit(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -239,7 +240,7 @@ func TestMainMenuQuit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Check_Community_Balance(t *testing.T) {
|
func TestMyAccount_Check_Community_Balance(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -270,7 +271,7 @@ func TestMyAccount_Check_Community_Balance(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccountChangePin(t *testing.T) {
|
func TestMyAccountChangePin(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -301,7 +302,7 @@ func TestMyAccountChangePin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Change_Language(t *testing.T) {
|
func TestMyAccount_Change_Language(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -332,7 +333,7 @@ func TestMyAccount_Change_Language(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_firstname(t *testing.T) {
|
func TestMyAccount_Edit_firstname(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -363,7 +364,7 @@ func TestMyAccount_Edit_firstname(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_familyname(t *testing.T) {
|
func TestMyAccount_Edit_familyname(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -394,7 +395,7 @@ func TestMyAccount_Edit_familyname(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_gender(t *testing.T) {
|
func TestMyAccount_Edit_gender(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -416,6 +417,7 @@ func TestMyAccount_Edit_gender(t *testing.T) {
|
|||||||
t.Errorf("Test case '%s' failed during Flush: %v", group.Name, err)
|
t.Errorf("Test case '%s' failed during Flush: %v", group.Name, err)
|
||||||
}
|
}
|
||||||
b := w.Bytes()
|
b := w.Bytes()
|
||||||
|
fmt.Println("Content:", string(b))
|
||||||
if !bytes.Equal(b, []byte(step.ExpectedContent)) {
|
if !bytes.Equal(b, []byte(step.ExpectedContent)) {
|
||||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
|
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
|
||||||
}
|
}
|
||||||
@ -425,7 +427,7 @@ func TestMyAccount_Edit_gender(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_yob(t *testing.T) {
|
func TestMyAccount_Edit_yob(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -456,7 +458,7 @@ func TestMyAccount_Edit_yob(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_location(t *testing.T) {
|
func TestMyAccount_Edit_location(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -487,7 +489,7 @@ func TestMyAccount_Edit_location(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_Edit_offerings(t *testing.T) {
|
func TestMyAccount_Edit_offerings(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -496,37 +498,7 @@ func TestMyAccount_Edit_offerings(t *testing.T) {
|
|||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
for index, step := range group.Steps {
|
for index, step := range group.Steps {
|
||||||
t.Logf("step %v with input %v", index, step.Input)
|
t.Logf("step %v with input %v", index, step.Input)
|
||||||
cont, err := en.Exec(ctx, []byte(step.Input))
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !cont {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
w := bytes.NewBuffer(nil)
|
|
||||||
if _, err := en.Flush(ctx, w); err != nil {
|
|
||||||
t.Errorf("Test case '%s' failed during Flush: %v", group.Name, err)
|
|
||||||
}
|
|
||||||
b := w.Bytes()
|
|
||||||
if !bytes.Equal(b, []byte(step.ExpectedContent)) {
|
|
||||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMyAccount_View_Profile(t *testing.T) {
|
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
|
||||||
defer fn()
|
|
||||||
ctx := context.Background()
|
|
||||||
sessions := testData
|
|
||||||
for _, session := range sessions {
|
|
||||||
groups := driver.FilterGroupsByName(session.Groups, "menu_my_account_view_profile")
|
|
||||||
for _, group := range groups {
|
|
||||||
for index, step := range group.Steps {
|
|
||||||
t.Logf("step %v with input %v", index, step.Input)
|
|
||||||
cont, err := en.Exec(ctx, []byte(step.Input))
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
t.Errorf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
@ -549,7 +521,7 @@ func TestMyAccount_View_Profile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_MyAddress(t *testing.T) {
|
func TestMyAccount_MyAddress(t *testing.T) {
|
||||||
en, fn := enginetest.TestEngine(sessionID)
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -583,3 +555,34 @@ func TestMyAccount_MyAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMyAccount_View_Profile(t *testing.T) {
|
||||||
|
en, fn, _ := enginetest.TestEngine(sessionID)
|
||||||
|
defer fn()
|
||||||
|
ctx := context.Background()
|
||||||
|
sessions := testData
|
||||||
|
for _, session := range sessions {
|
||||||
|
groups := driver.FilterGroupsByName(session.Groups, "menu_my_account_view_profile")
|
||||||
|
for _, group := range groups {
|
||||||
|
for index, step := range group.Steps {
|
||||||
|
t.Logf("step %v with input %v", index, step.Input)
|
||||||
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !cont {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w := bytes.NewBuffer(nil)
|
||||||
|
if _, err := en.Flush(ctx, w); err != nil {
|
||||||
|
t.Errorf("Test case '%s' failed during Flush: %v", group.Name, err)
|
||||||
|
}
|
||||||
|
b := w.Bytes()
|
||||||
|
if !bytes.Equal(b, []byte(step.ExpectedContent)) {
|
||||||
|
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -291,7 +291,7 @@
|
|||||||
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
|
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "Female",
|
"input": "1",
|
||||||
"expectedContent": "Please enter your PIN:"
|
"expectedContent": "Please enter your PIN:"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -399,7 +399,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "9",
|
"input": "9",
|
||||||
"expectedContent": "Thank you for using Sarafu. Goodbye!"
|
"expectedContent": "Thank you for using Sarafu. Goodbye!{{.Variable}}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -424,7 +424,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1234",
|
"input": "1234",
|
||||||
"expectedContent": "My profile:\nName: foo bar\nGender: Female\nAge: 79\nLocation: Kilifi\nYou provide: Bananas\n\n0:Back"
|
"expectedContent": "My profile:\nName: foo bar\nGender: male\nAge: 79\nLocation: Kilifi\nYou provide: Bananas\n\n0:Back"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
|
Loading…
Reference in New Issue
Block a user