From 3a46fda769941e196b0e62ad12a4924782de9dd1 Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Sat, 28 Sep 2024 12:26:37 +0300
Subject: [PATCH] use save_temporary_pin and updated tests

---
 internal/handlers/handlerservice.go          |  7 +--
 internal/handlers/ussd/menuhandler.go        | 59 +++++++-------------
 internal/handlers/ussd/menuhandler_test.go   | 51 +++--------------
 services/registration/account_creation.vis   |  2 +-
 services/registration/confirm_create_pin.vis |  4 +-
 services/registration/create_pin.vis         |  4 +-
 6 files changed, 38 insertions(+), 89 deletions(-)

diff --git a/internal/handlers/handlerservice.go b/internal/handlers/handlerservice.go
index 3dffe16..1a556cc 100644
--- a/internal/handlers/handlerservice.go
+++ b/internal/handlers/handlerservice.go
@@ -60,8 +60,8 @@ func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) {
 	ussdHandlers = ussdHandlers.WithPersister(ls.Pe)
 	ls.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage)
 	ls.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount)
-	ls.DbRs.AddLocalFunc("save_pin", ussdHandlers.SavePin)
-	ls.DbRs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin)
+	ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
+	ls.DbRs.AddLocalFunc("verify_create_pin", ussdHandlers.VerifyCreatePin)
 	ls.DbRs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier)
 	ls.DbRs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus)
 	ls.DbRs.AddLocalFunc("authorize_account", ussdHandlers.Authorize)
@@ -89,11 +89,10 @@ func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) {
 	ls.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
 	ls.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
 	ls.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
-	ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
 	ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin)
 	ls.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange)
 	ls.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp)
-	ls.DbRs.AddLocalFunc("get_vouchers",ussdHandlers.GetVoucherList)
+	ls.DbRs.AddLocalFunc("get_vouchers", ussdHandlers.GetVoucherList)
 
 	return ussdHandlers, nil
 }
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 5ebdaa5..165a456 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -180,34 +180,6 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 	return res, nil
 }
 
-// SavePin persists the user's PIN choice into the filesystem
-func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	var res resource.Result
-	var err error
-
-	sessionId, ok := ctx.Value("SessionId").(string)
-	if !ok {
-		return res, fmt.Errorf("missing session")
-	}
-
-	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
-
-	accountPIN := string(input)
-	// Validate that the PIN is a 4-digit number
-	if !isValidPIN(accountPIN) {
-		res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
-		return res, nil
-	}
-
-	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
-	store := h.userdataStore
-	err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
-	if err != nil {
-		return res, err
-	}
-	return res, nil
-}
-
 func (h *Handlers) VerifyNewPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 	_, ok := ctx.Value("SessionId").(string)
@@ -226,6 +198,9 @@ func (h *Handlers) VerifyNewPin(ctx context.Context, sym string, input []byte) (
 	return res, nil
 }
 
+// SaveTemporaryPin saves the valid PIN input to the DATA_TEMPORARY_PIN
+// during the account creation process
+// and during the change PIN process
 func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	var err error
@@ -234,6 +209,7 @@ func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byt
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
+
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 
 	accountPIN := string(input)
@@ -243,16 +219,19 @@ func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byt
 		res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
 		return res, nil
 	}
+
+	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
+
 	store := h.userdataStore
 	err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(accountPIN))
 	if err != nil {
 		return res, err
 	}
+
 	return res, nil
 }
 
-
-func (h *Handlers) GetVoucherList(ctx context.Context,sym string,input []byte) (resource.Result,error){
+func (h *Handlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	vouchers := []string{
 		"SRF",
@@ -283,9 +262,9 @@ func (h *Handlers) GetVoucherList(ctx context.Context,sym string,input []byte) (
 	for i, voucher := range vouchers {
 		numberedVouchers = append(numberedVouchers, fmt.Sprintf("%d:%s", i+1, voucher))
 	}
-	res.Content = strings.Join(numberedVouchers,"\n")
+	res.Content = strings.Join(numberedVouchers, "\n")
 
-	return res,nil
+	return res, nil
 }
 
 func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) {
@@ -313,10 +292,10 @@ func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byt
 	return res, nil
 }
 
-// VerifyPin checks whether the confirmation PIN is similar to the account PIN
-// If similar, it sets the USERFLAG_PIN_SET flag allowing the user
+// VerifyCreatePin checks whether the confirmation PIN is similar to the temporary PIN
+// If similar, it sets the USERFLAG_PIN_SET flag and writes the account PIN allowing the user
 // to access the main menu
-func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+func (h *Handlers) VerifyCreatePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 
 	flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin")
@@ -328,14 +307,13 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 		return res, fmt.Errorf("missing session")
 	}
 
-	//AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
 	store := h.userdataStore
-	AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
+	temporaryPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN)
 	if err != nil {
 		return res, err
 	}
 
-	if bytes.Equal(input, AccountPin) {
+	if bytes.Equal(input, temporaryPin) {
 		res.FlagSet = []uint32{flag_valid_pin}
 		res.FlagReset = []uint32{flag_pin_mismatch}
 		res.FlagSet = append(res.FlagSet, flag_pin_set)
@@ -343,6 +321,11 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 		res.FlagSet = []uint32{flag_pin_mismatch}
 	}
 
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(temporaryPin))
+	if err != nil {
+		return res, err
+	}
+
 	return res, nil
 }
 
diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 83e6f0c..1ce8b51 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -171,7 +171,7 @@ func TestSaveFamilyname(t *testing.T) {
 	mockStore.AssertExpectations(t)
 }
 
-func TestSavePin(t *testing.T) {
+func TestSaveTemporaryPIn(t *testing.T) {
 	fm, err := NewFlagManager(flagsPath)
 	mockStore := new(mocks.MockUserDataStore)
 	if err != nil {
@@ -213,10 +213,10 @@ func TestSavePin(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 
 			// Set up the expected behavior of the mock
-			mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(tt.input)).Return(nil)
+			mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(tt.input)).Return(nil)
 
 			// Call the method
-			res, err := h.SavePin(ctx, "save_pin", tt.input)
+			res, err := h.SaveTemporaryPin(ctx, "save_pin", tt.input)
 
 			if err != nil {
 				t.Error(err)
@@ -937,7 +937,7 @@ func TestVerifyYob(t *testing.T) {
 	}
 }
 
-func TestVerifyPin(t *testing.T) {
+func TestVerifyCreatePin(t *testing.T) {
 	fm, err := NewFlagManager(flagsPath)
 
 	if err != nil {
@@ -986,7 +986,7 @@ func TestVerifyPin(t *testing.T) {
 		},
 	}
 
-	typ := utils.DATA_ACCOUNT_PIN
+	typ := utils.DATA_TEMPORARY_PIN
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -994,8 +994,11 @@ func TestVerifyPin(t *testing.T) {
 			// Define expected interactions with the mock
 			mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte(firstSetPin), nil)
 
+			// Set up the expected behavior of the mock
+			mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(firstSetPin)).Return(nil)
+
 			// Call the method under test
-			res, err := h.VerifyPin(ctx, "verify_pin", []byte(tt.input))
+			res, err := h.VerifyCreatePin(ctx, "verify_create_pin", []byte(tt.input))
 
 			// Assert that no errors occurred
 			assert.NoError(t, err)
@@ -1693,42 +1696,6 @@ func TestVerifyNewPin(t *testing.T) {
 
 }
 
-func TestSaveTemporaryPIn(t *testing.T) {
-
-	fm, err := NewFlagManager(flagsPath)
-
-	if err != nil {
-		t.Logf(err.Error())
-	}
-
-	// Create a new instance of UserDataStore
-	mockStore := new(mocks.MockUserDataStore)
-
-	// Define test data
-	sessionId := "session123"
-	PIN := "1234"
-	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
-
-	// Set up the expected behavior of the mock
-	mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(PIN)).Return(nil)
-
-	// Create the Handlers instance with the mock store
-	h := &Handlers{
-		userdataStore: mockStore,
-		flagManager:   fm.parser,
-	}
-
-	// Call the method
-	res, err := h.SaveTemporaryPin(ctx, "save_temporary_pin", []byte(PIN))
-
-	// Assert results
-	assert.NoError(t, err)
-	assert.Equal(t, resource.Result{}, res)
-
-	// Assert all expectations were met
-	mockStore.AssertExpectations(t)
-}
-
 func TestConfirmPin(t *testing.T) {
 	sessionId := "session123"
 
diff --git a/services/registration/account_creation.vis b/services/registration/account_creation.vis
index f4f326b..380fe6d 100644
--- a/services/registration/account_creation.vis
+++ b/services/registration/account_creation.vis
@@ -1,4 +1,4 @@
-RELOAD verify_pin
+RELOAD verify_create_pin
 CATCH create_pin_mismatch flag_pin_mismatch 1
 LOAD quit 0
 HALT
diff --git a/services/registration/confirm_create_pin.vis b/services/registration/confirm_create_pin.vis
index 1235916..1a3173c 100644
--- a/services/registration/confirm_create_pin.vis
+++ b/services/registration/confirm_create_pin.vis
@@ -1,4 +1,4 @@
-LOAD save_pin 0
+LOAD save_temporary_pin 0
 HALT
-LOAD verify_pin 8
+LOAD verify_create_pin 8
 INCMP account_creation *
diff --git a/services/registration/create_pin.vis b/services/registration/create_pin.vis
index e0e330f..c76e1bf 100644
--- a/services/registration/create_pin.vis
+++ b/services/registration/create_pin.vis
@@ -2,8 +2,8 @@ LOAD create_account 0
 CATCH account_creation_failed flag_account_creation_failed 1
 MOUT exit 0
 HALT
-LOAD save_pin 0
-RELOAD save_pin
+LOAD save_temporary_pin 0
+RELOAD save_temporary_pin
 CATCH . flag_incorrect_pin 1
 INCMP quit 0
 INCMP confirm_create_pin *