wip-flag-migration #28
@ -16,7 +16,6 @@ import (
|
|||||||
"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/handlers/server"
|
"git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||||
"git.grassecon.net/urdt/ussd/internal/models"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
"git.grassecon.net/urdt/ussd/internal/utils"
|
||||||
"github.com/graygnuorg/go-gdbm"
|
"github.com/graygnuorg/go-gdbm"
|
||||||
"gopkg.in/leonelquinteros/gotext.v1"
|
"gopkg.in/leonelquinteros/gotext.v1"
|
||||||
@ -53,10 +52,14 @@ type FSData struct {
|
|||||||
St *state.State
|
St *state.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FlagParserInterface interface {
|
||||||
|
GetFlag(key string) (uint32, error)
|
||||||
|
}
|
||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
Alfred-mk marked this conversation as resolved
|
|||||||
fs *FSData
|
fs *FSData
|
||||||
db *gdbm.Database
|
db *gdbm.Database
|
||||||
parser *asm.FlagParser
|
parser FlagParserInterface
|
||||||
accountFileHandler utils.AccountFileHandlerInterface
|
accountFileHandler utils.AccountFileHandlerInterface
|
||||||
accountService server.AccountServiceInterface
|
accountService server.AccountServiceInterface
|
||||||
}
|
}
|
||||||
@ -107,8 +110,16 @@ func (h *Handlers) PreloadFlags(flagKeys []string) (map[string]uint32, error) {
|
|||||||
|
|
||||||
// SetLanguage sets the language across the menu
|
// SetLanguage sets the language across the menu
|
||||||
func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
inputStr := string(input)
|
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_language_set"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
inputStr := string(input)
|
||||||
switch inputStr {
|
switch inputStr {
|
||||||
case "0":
|
case "0":
|
||||||
res.FlagSet = []uint32{state.FLAG_LANG}
|
res.FlagSet = []uint32{state.FLAG_LANG}
|
||||||
@ -119,7 +130,7 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_LANGUAGE_SET)
|
res.FlagSet = append(res.FlagSet, flags["flag_language_set"])
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -130,7 +141,14 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
|
|||||||
func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
err := h.accountFileHandler.EnsureFileExists()
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_account_created", "flag_account_creation_failed"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.accountFileHandler.EnsureFileExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -143,7 +161,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
|
|||||||
|
|
||||||
accountResp, err := h.accountService.CreateAccount()
|
accountResp, err := h.accountService.CreateAccount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATION_FAILED)
|
res.FlagSet = append(res.FlagSet, flags["flag_account_creation_failed"])
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
data := map[string]string{
|
data := map[string]string{
|
||||||
@ -160,13 +178,19 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATED)
|
res.FlagSet = append(res.FlagSet, flags["flag_account_created"])
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SavePin persists the user's PIN choice into the filesystem
|
// SavePin persists the user's PIN choice into the filesystem
|
||||||
func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
flagKeys := []string{"flag_incorrect_pin"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
accountPIN := string(input)
|
accountPIN := string(input)
|
||||||
|
|
||||||
// accountData, err := h.accountFileHandler.ReadAccountData()
|
// accountData, err := h.accountFileHandler.ReadAccountData()
|
||||||
@ -176,11 +200,11 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
|
|||||||
|
|
||||||
// Validate that the PIN is a 4-digit number
|
// Validate that the PIN is a 4-digit number
|
||||||
if !isValidPIN(accountPIN) {
|
if !isValidPIN(accountPIN) {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTPIN)
|
res.FlagSet = append(res.FlagSet, flags["flag_incorrect_pin"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN)
|
res.FlagReset = append(res.FlagReset, flags["flag_incorrect_pin"])
|
||||||
//accountData["AccountPIN"] = accountPIN
|
//accountData["AccountPIN"] = accountPIN
|
||||||
|
|
||||||
key := []byte(AccountPin)
|
key := []byte(AccountPin)
|
||||||
@ -200,18 +224,26 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
|
|||||||
func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
menuOption := string(input)
|
menuOption := string(input)
|
||||||
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_allow_update", "flag_single_edit"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
switch menuOption {
|
switch menuOption {
|
||||||
case "2":
|
case "2":
|
||||||
res.FlagReset = append(res.FlagSet, models.USERFLAG_ALLOW_UPDATE)
|
res.FlagReset = append(res.FlagSet, flags["flag_allow_update"])
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_SINGLE_EDIT)
|
res.FlagSet = append(res.FlagSet, flags["flag_single_edit"])
|
||||||
case "3":
|
case "3":
|
||||||
res.FlagReset = append(res.FlagSet, models.USERFLAG_ALLOW_UPDATE)
|
res.FlagReset = append(res.FlagSet, flags["flag_allow_update"])
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_SINGLE_EDIT)
|
res.FlagSet = append(res.FlagSet, flags["flag_single_edit"])
|
||||||
case "4":
|
case "4":
|
||||||
res.FlagReset = append(res.FlagSet, models.USERFLAG_ALLOW_UPDATE)
|
res.FlagReset = append(res.FlagSet, flags["flag_allow_update"])
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_SINGLE_EDIT)
|
res.FlagSet = append(res.FlagSet, flags["flag_single_edit"])
|
||||||
default:
|
default:
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_SINGLE_EDIT)
|
res.FlagReset = append(res.FlagReset, flags["flag_single_edit"])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -222,20 +254,27 @@ func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []b
|
|||||||
// to access the main menu
|
// to access the main menu
|
||||||
func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
pin, err := h.db.Fetch([]byte(AccountPin))
|
|
||||||
if err == nil {
|
// Preload the required flags
|
||||||
if bytes.Equal(input, pin) {
|
flagKeys := []string{"flag_valid_pin", "flag_pin_mismatch", "flag_pin_set"}
|
||||||
res.FlagSet = []uint32{models.USERFLAG_VALIDPIN}
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
res.FlagReset = []uint32{models.USERFLAG_PINMISMATCH}
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_PIN_SET)
|
|
||||||
} else {
|
|
||||||
res.FlagSet = []uint32{models.USERFLAG_PINMISMATCH}
|
|
||||||
}
|
|
||||||
} else if errors.Is(err, gdbm.ErrItemNotFound) {
|
|
||||||
//PIN not set yet
|
|
||||||
} else {
|
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accountData, err := h.accountFileHandler.ReadAccountData()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Equal(input, []byte(accountData["AccountPIN"])) {
|
||||||
|
res.FlagSet = []uint32{flags["flag_valid_pin"]}
|
||||||
|
res.FlagReset = []uint32{flags["flag_pin_mismatch"]}
|
||||||
|
res.FlagSet = append(res.FlagSet, flags["flag_pin_set"])
|
||||||
|
} else {
|
||||||
|
res.FlagSet = []uint32{flags["flag_pin_mismatch"]}
|
||||||
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,14 +426,30 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte)
|
|||||||
// ResetAllowUpdate resets the allowupdate flag that allows a user to update profile data.
|
// ResetAllowUpdate resets the allowupdate flag that allows a user to update profile data.
|
||||||
func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_ALLOW_UPDATE)
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_allow_update"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_allow_update"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetAccountAuthorized resets the account authorization flag after a successful PIN entry.
|
// ResetAccountAuthorized resets the account authorization flag after a successful PIN entry.
|
||||||
func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_AUTHORIZED)
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_account_authorized"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_account_authorized"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,12 +475,6 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
|
|||||||
// It sets the required flags that control the flow.
|
// It sets the required flags that control the flow.
|
||||||
func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
//pin := string(input)
|
|
||||||
|
|
||||||
// accountData, err := h.accountFileHandler.ReadAccountData()
|
|
||||||
// if err != nil {
|
|
||||||
// return res, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Preload the required flags
|
// Preload the required flags
|
||||||
flagKeys := []string{"flag_incorrect_pin", "flag_account_authorized", "flag_allow_update"}
|
flagKeys := []string{"flag_incorrect_pin", "flag_account_authorized", "flag_allow_update"}
|
||||||
@ -434,6 +483,13 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pin := string(input)
|
||||||
|
|
||||||
|
accountData, err := h.accountFileHandler.ReadAccountData()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
storedpin, err := h.db.Fetch([]byte(AccountPin))
|
storedpin, err := h.db.Fetch([]byte(AccountPin))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(input) == 4 {
|
if len(input) == 4 {
|
||||||
@ -477,7 +533,15 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
|
|||||||
// ResetIncorrectPin resets the incorrect pin flag after a new PIN attempt.
|
// ResetIncorrectPin resets the incorrect pin flag after a new PIN attempt.
|
||||||
func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN)
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_incorrect_pin"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_incorrect_pin"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +550,21 @@ func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []by
|
|||||||
func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flags
|
||||||
|
|
||||||
|
flagKeys := []string{"flag_account_success", "flag_account_pending"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_account_success", "flag_account_pending"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// accountData, err := h.accountFileHandler.ReadAccountData()
|
// accountData, err := h.accountFileHandler.ReadAccountData()
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return res, err
|
// return res, err
|
||||||
@ -501,6 +580,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error checking account status:", err)
|
fmt.Println("Error checking account status:", err)
|
||||||
return res, err
|
return res, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//accountData["Status"] = status
|
//accountData["Status"] = status
|
||||||
@ -511,11 +591,11 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if status == "SUCCESS" {
|
if status == "SUCCESS" {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS)
|
res.FlagSet = append(res.FlagSet, flags["flag_account_success"])
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING)
|
res.FlagReset = append(res.FlagReset, flags["flag_account_pending"])
|
||||||
} else {
|
} else {
|
||||||
res.FlagReset = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS)
|
res.FlagReset = append(res.FlagSet, flags["flag_account_success"])
|
||||||
res.FlagSet = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING)
|
res.FlagSet = append(res.FlagReset, flags["flag_account_pending"])
|
||||||
}
|
}
|
||||||
|
|
||||||
// err = h.accountFileHandler.WriteAccountData(accountData)
|
// err = h.accountFileHandler.WriteAccountData(accountData)
|
||||||
@ -530,30 +610,45 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
|
|||||||
func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_account_authorized"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
code := codeFromCtx(ctx)
|
||||||
l := gotext.NewLocale(translationDir, code)
|
l := gotext.NewLocale(translationDir, code)
|
||||||
l.AddDomain("default")
|
l.AddDomain("default")
|
||||||
|
|
||||||
res.Content = l.Get("Thank you for using Sarafu. Goodbye!")
|
res.Content = l.Get("Thank you for using Sarafu. Goodbye!")
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_AUTHORIZED)
|
res.FlagReset = append(res.FlagReset, flags["flag_account_authorized"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyYob verifies the length of the given input
|
// VerifyYob verifies the length of the given input
|
||||||
func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_incorrect_date_format"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
date := string(input)
|
date := string(input)
|
||||||
_, err := strconv.Atoi(date)
|
_, err = strconv.Atoi(date)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If conversion fails, input is not numeric
|
// If conversion fails, input is not numeric
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT)
|
res.FlagSet = append(res.FlagSet, flags["flag_incorrect_date_format"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(date) == 4 {
|
if len(date) == 4 {
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT)
|
res.FlagReset = append(res.FlagReset, flags["flag_incorrect_date_format"])
|
||||||
} else {
|
} else {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT)
|
res.FlagSet = append(res.FlagSet, flags["flag_incorrect_date_format"])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -562,7 +657,15 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res
|
|||||||
// ResetIncorrectYob resets the incorrect date format flag after a new attempt
|
// ResetIncorrectYob resets the incorrect date format flag after a new attempt
|
||||||
func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT)
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_incorrect_date_format"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_incorrect_date_format"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,11 +691,19 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
|
|||||||
// ValidateRecipient validates that the given input is a valid phone number.
|
// ValidateRecipient validates that the given input is a valid phone number.
|
||||||
func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
recipient := string(input)
|
||||||
|
|
||||||
|
accountData, err := h.accountFileHandler.ReadAccountData()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
recipient := string(input)
|
recipient := string(input)
|
||||||
if recipient != "0" {
|
if recipient != "0" {
|
||||||
// mimic invalid number check
|
// mimic invalid number check
|
||||||
if recipient == "000" {
|
if recipient == "000" {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_RECIPIENT)
|
res.FlagSet = append(res.FlagSet, flags["flag_invalid_recipient"])
|
||||||
res.Content = recipient
|
res.Content = recipient
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -612,6 +723,14 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
|
|||||||
// as well as the invalid flags
|
// as well as the invalid flags
|
||||||
func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_invalid_recipient", "flag_invalid_recipient_with_invite"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
err := h.db.Delete([]byte(Amount))
|
err := h.db.Delete([]byte(Amount))
|
||||||
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -620,7 +739,8 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
|
|||||||
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_RECIPIENT, models.USERFLAG_INVALID_RECIPIENT_WITH_INVITE)
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_invalid_recipient"], flags["flag_invalid_recipient_with_invite"])
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -628,11 +748,21 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
|
|||||||
// ResetTransactionAmount resets the transaction amount and invalid flag
|
// ResetTransactionAmount resets the transaction amount and invalid flag
|
||||||
func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_invalid_amount"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
err := h.db.Delete([]byte(Amount))
|
err := h.db.Delete([]byte(Amount))
|
||||||
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_AMOUNT)
|
|
||||||
|
res.FlagReset = append(res.FlagReset, flags["flag_invalid_amount"])
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,13 +789,22 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
|
|||||||
// it is not more than the current balance.
|
// it is not more than the current balance.
|
||||||
func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_invalid_amount"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
amountStr := string(input)
|
amountStr := string(input)
|
||||||
publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
|
publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
balanceStr, err := h.accountService.CheckBalance(string(publicKey))
|
balanceStr, err := h.accountService.CheckBalance(string(publicKey))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -685,20 +824,20 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
|
|||||||
re := regexp.MustCompile(`^(\d+(\.\d+)?)\s*(?:CELO)?$`)
|
re := regexp.MustCompile(`^(\d+(\.\d+)?)\s*(?:CELO)?$`)
|
||||||
matches := re.FindStringSubmatch(strings.TrimSpace(amountStr))
|
matches := re.FindStringSubmatch(strings.TrimSpace(amountStr))
|
||||||
if len(matches) < 2 {
|
if len(matches) < 2 {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT)
|
res.FlagSet = append(res.FlagSet, flags["flag_invalid_amount"])
|
||||||
res.Content = amountStr
|
res.Content = amountStr
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
inputAmount, err := strconv.ParseFloat(matches[1], 64)
|
inputAmount, err := strconv.ParseFloat(matches[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT)
|
res.FlagSet = append(res.FlagSet, flags["flag_invalid_amount"])
|
||||||
res.Content = amountStr
|
res.Content = amountStr
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if inputAmount > balanceValue {
|
if inputAmount > balanceValue {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT)
|
res.FlagSet = append(res.FlagSet, flags["flag_invalid_amount"])
|
||||||
res.Content = amountStr
|
res.Content = amountStr
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -795,6 +934,14 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
|
|||||||
// gracefully exiting the session.
|
// gracefully exiting the session.
|
||||||
func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
res := resource.Result{}
|
res := resource.Result{}
|
||||||
|
|
||||||
|
// Preload the required flag
|
||||||
|
flagKeys := []string{"flag_account_authorized"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
code := codeFromCtx(ctx)
|
||||||
l := gotext.NewLocale(translationDir, code)
|
l := gotext.NewLocale(translationDir, code)
|
||||||
l.AddDomain("default")
|
l.AddDomain("default")
|
||||||
@ -811,7 +958,7 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
res.Content = l.Get("Your account balance is %s", balance)
|
res.Content = l.Get("Your account balance is %s", balance)
|
||||||
res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_AUTHORIZED)
|
res.FlagReset = append(res.FlagReset, flags["flag_account_authorized"])
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,7 +969,12 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
|
|||||||
code := codeFromCtx(ctx)
|
code := codeFromCtx(ctx)
|
||||||
l := gotext.NewLocale(translationDir, code)
|
l := gotext.NewLocale(translationDir, code)
|
||||||
l.AddDomain("default")
|
l.AddDomain("default")
|
||||||
|
// Preload the required flags
|
||||||
|
flagKeys := []string{"flag_invalid_recipient"}
|
||||||
|
flags, err := h.PreloadFlags(flagKeys)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
// Use the amount, recipient and sender to call the API and initialize the transaction
|
// Use the amount, recipient and sender to call the API and initialize the transaction
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@ type MockAccountService struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MockFlagParser struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockFlagParser) GetFlag(key string) (uint32, error) {
|
||||||
|
args := m.Called(key)
|
||||||
|
return args.Get(0).(uint32), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
|
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
|
||||||
args := m.Called()
|
args := m.Called()
|
||||||
return args.Get(0).(*models.AccountResponse), args.Error(1)
|
return args.Get(0).(*models.AccountResponse), args.Error(1)
|
||||||
@ -70,11 +79,20 @@ func TestCreateAccount(t *testing.T) {
|
|||||||
// Set up expectations for the mock account service
|
// Set up expectations for the mock account service
|
||||||
mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)
|
mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)
|
||||||
|
|
||||||
|
mockParser := new(MockFlagParser)
|
||||||
|
|
||||||
|
flag_account_created := uint32(1)
|
||||||
|
flag_account_creation_failed := uint32(2)
|
||||||
|
|
||||||
|
mockParser.On("GetFlag", "flag_account_created").Return(flag_account_created, nil)
|
||||||
|
mockParser.On("GetFlag", "flag_account_creation_failed").Return(flag_account_creation_failed, nil)
|
||||||
|
|
||||||
// Initialize Handlers with mock account service
|
// Initialize Handlers with mock account service
|
||||||
h := &Handlers{
|
h := &Handlers{
|
||||||
fs: &FSData{Path: accountFilePath},
|
fs: &FSData{Path: accountFilePath},
|
||||||
accountFileHandler: accountFileHandler,
|
accountFileHandler: accountFileHandler,
|
||||||
accountService: mockAccountService,
|
accountService: mockAccountService,
|
||||||
|
parser: mockParser,
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -87,7 +105,7 @@ func TestCreateAccount(t *testing.T) {
|
|||||||
name: "New account creation",
|
name: "New account creation",
|
||||||
existingData: nil,
|
existingData: nil,
|
||||||
expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
FlagSet: []uint32{models.USERFLAG_ACCOUNT_CREATED},
|
FlagSet: []uint32{flag_account_created},
|
||||||
},
|
},
|
||||||
expectedData: map[string]string{
|
expectedData: map[string]string{
|
||||||
"TrackingId": "test-tracking-id",
|
"TrackingId": "test-tracking-id",
|
||||||
@ -248,10 +266,16 @@ func TestSavePin(t *testing.T) {
|
|||||||
|
|
||||||
// Create a new AccountFileHandler and set it in the Handlers struct
|
// Create a new AccountFileHandler and set it in the Handlers struct
|
||||||
accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
|
accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
|
||||||
|
mockParser := new(MockFlagParser)
|
||||||
|
|
||||||
h := &Handlers{
|
h := &Handlers{
|
||||||
accountFileHandler: accountFileHandler,
|
accountFileHandler: accountFileHandler,
|
||||||
|
parser: mockParser,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag_incorrect_pin := uint32(1)
|
||||||
|
mockParser.On("GetFlag", "flag_incorrect_pin").Return(flag_incorrect_pin, nil)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
input []byte
|
input []byte
|
||||||
@ -272,21 +296,21 @@ func TestSavePin(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Invalid PIN - non-numeric",
|
name: "Invalid PIN - non-numeric",
|
||||||
input: []byte("12ab"),
|
input: []byte("12ab"),
|
||||||
expectedFlags: []uint32{models.USERFLAG_INCORRECTPIN},
|
expectedFlags: []uint32{flag_incorrect_pin},
|
||||||
expectedData: initialAccountData, // No changes expected
|
expectedData: initialAccountData, // No changes expected
|
||||||
expectedErrors: false,
|
expectedErrors: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid PIN - less than 4 digits",
|
name: "Invalid PIN - less than 4 digits",
|
||||||
input: []byte("123"),
|
input: []byte("123"),
|
||||||
expectedFlags: []uint32{models.USERFLAG_INCORRECTPIN},
|
expectedFlags: []uint32{flag_incorrect_pin},
|
||||||
expectedData: initialAccountData, // No changes expected
|
expectedData: initialAccountData, // No changes expected
|
||||||
expectedErrors: false,
|
expectedErrors: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid PIN - more than 4 digits",
|
name: "Invalid PIN - more than 4 digits",
|
||||||
input: []byte("12345"),
|
input: []byte("12345"),
|
||||||
expectedFlags: []uint32{models.USERFLAG_INCORRECTPIN},
|
expectedFlags: []uint32{flag_incorrect_pin},
|
||||||
expectedData: initialAccountData, // No changes expected
|
expectedData: initialAccountData, // No changes expected
|
||||||
expectedErrors: false,
|
expectedErrors: false,
|
||||||
},
|
},
|
||||||
@ -294,7 +318,6 @@ func TestSavePin(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
// Ensure the file exists before running the test
|
|
||||||
err := accountFileHandler.EnsureFileExists()
|
err := accountFileHandler.EnsureFileExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to ensure account file exists: %v", err)
|
t.Fatalf("Failed to ensure account file exists: %v", err)
|
||||||
@ -906,12 +929,12 @@ func TestGetProfileInfo(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Profile with Not Provided Fields",
|
name: "Profile with Not Provided Fields",
|
||||||
accountData: map[string]string{
|
accountData: map[string]string{
|
||||||
"FirstName": "Not provided",
|
"FirstName": "Not provided",
|
||||||
"FamilyName": "Doe",
|
"FamilyName": "Doe",
|
||||||
"Gender": "Female",
|
"Gender": "Female",
|
||||||
"YOB": "1995",
|
"YOB": "1995",
|
||||||
"Location": "Not provided",
|
"Location": "Not provided",
|
||||||
"Offerings": "Service B",
|
"Offerings": "Service B",
|
||||||
},
|
},
|
||||||
readError: nil,
|
readError: nil,
|
||||||
expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
@ -925,12 +948,12 @@ func TestGetProfileInfo(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Profile with YOB as Not provided",
|
name: "Profile with YOB as Not provided",
|
||||||
accountData: map[string]string{
|
accountData: map[string]string{
|
||||||
"FirstName": "Not provided",
|
"FirstName": "Not provided",
|
||||||
"FamilyName": "Doe",
|
"FamilyName": "Doe",
|
||||||
"Gender": "Female",
|
"Gender": "Female",
|
||||||
"YOB": "Not provided",
|
"YOB": "Not provided",
|
||||||
"Location": "Not provided",
|
"Location": "Not provided",
|
||||||
"Offerings": "Service B",
|
"Offerings": "Service B",
|
||||||
},
|
},
|
||||||
readError: nil,
|
readError: nil,
|
||||||
expectedResult: resource.Result{
|
expectedResult: resource.Result{
|
||||||
|
Loading…
Reference in New Issue
Block a user
I don't think mutex is needed here, it will be loaded once (before threads) and only read from then right?