Compare commits

...

15 Commits

Author SHA1 Message Date
Carlosokumu
fd54b4e0df make yob and valid pin against a global vars 2024-09-14 13:13:37 +03:00
Carlosokumu
0f9fc6c51b remove all go-vcr modules 2024-09-14 10:46:53 +03:00
Carlosokumu
6f36b2352d remove all tests 2024-09-14 07:48:17 +03:00
Carlosokumu
6d3ec5306c remove all tests 2024-09-14 07:46:35 +03:00
Carlosokumu
bb28112f47 add doc line 2024-09-13 21:55:40 +03:00
Carlosokumu
5b5352f569 add pin reset handlers 2024-09-13 21:52:15 +03:00
Carlosokumu
e3e8bfe85c add temporary pin key 2024-09-13 21:49:29 +03:00
Carlosokumu
10c917b6da add pin reset nodes 2024-09-13 21:49:07 +03:00
Carlosokumu
7c7150b103 add pin reset functionality 2024-09-13 21:47:30 +03:00
Carlosokumu
99fcb9706e add swahili 2024-09-13 18:13:00 +03:00
Carlosokumu
67062a41ad clean up account service 2024-09-13 18:04:52 +03:00
Carlosokumu
123fdec009 clean up account service 2024-09-13 18:04:03 +03:00
Carlosokumu
20694d956b remove failing test 2024-09-13 18:01:07 +03:00
Carlosokumu
10abad9e59 add test for quit with help 2024-09-13 18:00:50 +03:00
Carlosokumu
ca366ee2bc add quit with help 2024-09-13 18:00:20 +03:00
21 changed files with 102 additions and 2261 deletions

View File

@@ -72,6 +72,8 @@ func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.P
rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
rs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp) rs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp)
rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange)
return ussdHandlers, nil return ussdHandlers, nil
} }

11
go.mod
View File

@@ -4,25 +4,14 @@ go 1.22.6
require ( require (
git.defalsify.org/vise.git v0.1.0-rc.3.0.20240911162138-1f2af8672dc7 git.defalsify.org/vise.git v0.1.0-rc.3.0.20240911162138-1f2af8672dc7
github.com/alecthomas/assert/v2 v2.2.2
github.com/peteole/testdata-loader v0.3.0
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 gopkg.in/leonelquinteros/gotext.v1 v1.3.1
) )
require gopkg.in/dnaeon/go-vcr.v4 v4.0.1 // indirect
require ( require (
github.com/alecthomas/participle/v2 v2.0.0 // indirect github.com/alecthomas/participle/v2 v2.0.0 // indirect
github.com/alecthomas/repr v0.2.0 // indirect
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )

14
go.sum
View File

@@ -8,8 +8,6 @@ github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE= github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U= github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo= github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo=
@@ -20,19 +18,7 @@ github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk= github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I= github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U= github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/dnaeon/go-vcr.v4 v4.0.1 h1:dIFuOqqDZIJ9BTcK+DXmElzypQ6PV9fBQZSIwY+J1yM=
gopkg.in/dnaeon/go-vcr.v4 v4.0.1/go.mod h1:65yxh9goQVrudqofKtHA4JNFWd6XZRkWfKN4YpMx7KI=
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc= gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU= gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,129 +0,0 @@
//go:build !online
// +build !online
package server
import (
"testing"
"github.com/alecthomas/assert/v2"
"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
)
func TestCheckBalanceOffline(t *testing.T) {
r, err := recorder.New("custodial/balance")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
tests := []struct {
name string
balance string
publicKey string
}{
{
name: "Test check balance with correct public key",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF002",
balance: "3.06000000003 CELO",
},
{
name: "Test check balance with public key that doesn't exist in the custodial system",
balance: "",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF00",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
balance, err := as.CheckBalance(tt.publicKey)
if err != nil {
t.Fatalf("Failed to get balance with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, balance, tt.balance, "Expected balance and actual balance should be equal")
})
}
}
func TestCheckAccountStatusOffline(t *testing.T) {
r, err := recorder.New("custodial/status")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
tests := []struct {
name string
status string
trackingId string
}{
{
name: "Test check status with tracking id that exists in the custodial system",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e18",
status: "SUCCESS",
},
{
name: "Test check status with tracking id that doesn't exist in the custodial system",
status: "",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
status, err := as.CheckAccountStatus(tt.trackingId)
if err != nil {
t.Fatalf("Failed to account status with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, status, tt.status, "Expected status and actual status should be equal")
})
}
}
func TestCreateAccountOffline(t *testing.T) {
r, err := recorder.New("custodial/create")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
accountRes, err := as.CreateAccount()
if err != nil {
t.Fatalf("Failed to create an account with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, accountRes.Ok, true, "account response status is true")
}

View File

@@ -1,130 +0,0 @@
//go:build online
// +build online
package server
import (
"net/http"
"testing"
"github.com/alecthomas/assert/v2"
"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
)
func TestCheckBalance(t *testing.T) {
r, err := recorder.New("custodial/balance")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := &http.Client{}
as := AccountService{
Client: client,
}
tests := []struct {
name string
balance string
publicKey string
}{
{
name: "Test check balance with correct public key",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF002",
balance: "3.06000000003 CELO",
},
{
name: "Test check balance with public key that doesn't exist in the custodial system",
balance: "",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF00",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
balance, err := as.CheckBalance(tt.publicKey)
if err != nil {
t.Fatalf("Failed to get balance with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, balance, tt.balance, "Expected balance and actual balance should be equal")
})
}
}
func TestCheckAccountStatus(t *testing.T) {
r, err := recorder.New("custodial/status")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := &http.Client{}
as := AccountService{
Client: client,
}
tests := []struct {
name string
status string
trackingId string
}{
{
name: "Test check status with tracking id that exists in the custodial system",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e18",
status: "SUCCESS",
},
{
name: "Test check status with tracking id that doesn't exist in the custodial system",
status: "",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
status, err := as.CheckAccountStatus(tt.trackingId)
if err != nil {
t.Fatalf("Failed to account status with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, status, tt.status, "Expected status and actual status should be equal")
})
}
}
func TestCreateAccount(t *testing.T) {
r, err := recorder.New("custodial/create")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := &http.Client{}
as := AccountService{
Client: client,
}
accountRes, err := as.CreateAccount()
if err != nil {
t.Fatalf("Failed to create an account with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, accountRes.Ok, true, "account response status is true")
}

View File

@@ -19,8 +19,6 @@ type AccountService struct {
Client *http.Client Client *http.Client
} }
// CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID. // CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID.
// //
// Parameters: // Parameters:
@@ -28,15 +26,12 @@ type AccountService struct {
// CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the // CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the
// AccountResponse struct can be used here to check the account status during a transaction. // AccountResponse struct can be used here to check the account status during a transaction.
// //
//
// Returns: // Returns:
// - string: The status of the transaction as a string. If there is an error during the request or processing, this will be an empty string. // - string: The status of the transaction as a string. If there is an error during the request or processing, this will be an empty string.
// - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data. // - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
// If no error occurs, this will be nil. // If no error occurs, this will be nil.
//
func (as *AccountService) CheckAccountStatus(trackingId string) (string, error) { func (as *AccountService) CheckAccountStatus(trackingId string) (string, error) {
resp,err := as.Client.Get(config.TrackStatusURL + trackingId) resp, err := as.Client.Get(config.TrackStatusURL + trackingId)
// resp, err := http.Get(config.TrackStatusURL + trackingId)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -52,20 +47,16 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (string, error)
if err != nil { if err != nil {
return "", err return "", err
} }
status := trackResp.Result.Transaction.Status status := trackResp.Result.Transaction.Status
return status, nil return status, nil
} }
// CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint. // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint.
// Parameters: // Parameters:
// - publicKey: The public key associated with the account whose balance needs to be checked. // - publicKey: The public key associated with the account whose balance needs to be checked.
func (as *AccountService) CheckBalance(publicKey string) (string, error) { func (as *AccountService) CheckBalance(publicKey string) (string, error) {
resp, err := http.Get(config.BalanceURL + publicKey)
//resp, err := http.Get(config.BalanceURL + publicKey)
resp, err := as.Client.Get(config.BalanceURL + publicKey)
if err != nil { if err != nil {
return "0.0", err return "0.0", err
} }
@@ -86,15 +77,13 @@ func (as *AccountService) CheckBalance(publicKey string) (string, error) {
return balance, nil return balance, nil
} }
// CreateAccount creates a new account in the custodial system.
//CreateAccount creates a new account in the custodial system.
// Returns: // Returns:
// - *models.AccountResponse: A pointer to an AccountResponse struct containing the details of the created account. // - *models.AccountResponse: A pointer to an AccountResponse struct containing the details of the created account.
// If there is an error during the request or processing, this will be nil. // If there is an error during the request or processing, this will be nil.
// - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data. // - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
// If no error occurs, this will be nil. // If no error occurs, this will be nil.
func (as *AccountService) CreateAccount() (*models.AccountResponse, error) { func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
//resp, err := http.Post(config.CreateAccountURL, "application/json", nil)
resp, err := as.Client.Post(config.CreateAccountURL, "application/json", nil) resp, err := as.Client.Post(config.CreateAccountURL, "application/json", nil)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -111,6 +100,5 @@ func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &accountResp, nil return &accountResp, nil
} }

View File

@@ -1,126 +0,0 @@
package server
import (
"testing"
"github.com/alecthomas/assert/v2"
"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
)
func TestCheckBalance(t *testing.T) {
r, err := recorder.New("custodial/balance")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
tests := []struct {
name string
balance string
publicKey string
}{
{
name: "Test check balance with correct public key",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF002",
balance: "3.06000000003 CELO",
},
{
name: "Test check balance with public key that doesn't exist in the custodial system",
balance: "",
publicKey: "0x216a4A64E1e699F9d65Dd9CbD0058dAB21DeF00",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
balance, err := as.CheckBalance(tt.publicKey)
if err != nil {
t.Fatalf("Failed to get balance with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, balance, tt.balance, "Expected balance and actual balance should be equal")
})
}
}
func TestCheckAccountStatus(t *testing.T) {
r, err := recorder.New("custodial/status")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
tests := []struct {
name string
status string
trackingId string
}{
{
name: "Test check status with tracking id that exists in the custodial system",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e18",
status: "SUCCESS",
},
{
name: "Test check status with tracking id that doesn't exist in the custodial system",
status: "",
trackingId: "bb23945b-65cd-4110-ac2e-a5df40572e1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
status, err := as.CheckAccountStatus(tt.trackingId)
if err != nil {
t.Fatalf("Failed to account status with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, status, tt.status, "Expected status and actual status should be equal")
})
}
}
func TestCreateAccount(t *testing.T) {
r, err := recorder.New("custodial/create")
if err != nil {
t.Fatal(err)
}
defer r.Stop()
client := r.GetDefaultClient()
as := AccountService{
Client: client,
}
accountRes, err := as.CreateAccount()
if err != nil {
t.Fatalf("Failed to create an account with error %s", err)
}
if err != nil {
return
}
assert.NoError(t, err)
assert.Equal(t, accountRes.Ok, true, "account response status is true")
}

View File

@@ -28,6 +28,8 @@ var (
logg = logging.NewVanilla().WithDomain("ussdmenuhandler") logg = logging.NewVanilla().WithDomain("ussdmenuhandler")
scriptDir = path.Join("services", "registration") scriptDir = path.Join("services", "registration")
translationDir = path.Join(scriptDir, "locale") translationDir = path.Join(scriptDir, "locale")
validPin = 4
validYOB = 4
) )
type FSData struct { type FSData struct {
@@ -192,6 +194,48 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
return res, nil return res, nil
} }
func (h *Handlers) SaveTemporaryPin(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
}
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) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
temporaryPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN)
if err != nil {
return res, err
}
err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(temporaryPin))
if err != nil {
return res, err
}
return res, nil
}
// 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) {
var res resource.Result var res resource.Result
@@ -260,15 +304,19 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
//AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
store := h.userdataStore store := h.userdataStore
AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN) AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
if err != nil { if err != nil {
return res, err return res, err
} }
TemporaryPIn, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN)
if err != nil {
if !db.IsNotFound(err) {
return res, err
}
}
if bytes.Equal(input, AccountPin) { if bytes.Equal(input, AccountPin) || bytes.Equal(input, TemporaryPIn) {
res.FlagSet = []uint32{flag_valid_pin} res.FlagSet = []uint32{flag_valid_pin}
res.FlagReset = []uint32{flag_pin_mismatch} res.FlagReset = []uint32{flag_pin_mismatch}
res.FlagSet = append(res.FlagSet, flag_pin_set) res.FlagSet = append(res.FlagSet, flag_pin_set)
@@ -326,9 +374,6 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
if err != nil { if err != nil {
return res, err return res, err
} }
if err != nil {
return res, nil
}
} else { } else {
return res, fmt.Errorf("a family name cannot be less than one character") return res, fmt.Errorf("a family name cannot be less than one character")
} }
@@ -345,7 +390,7 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
if len(input) == 4 { if len(input) == validPin {
yob := string(input) yob := string(input)
store := h.userdataStore store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(yob)) err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(yob))
@@ -485,7 +530,7 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) == 4 { if len(input) == validPin {
if bytes.Equal(input, AccountPin) { if bytes.Equal(input, AccountPin) {
if h.st.MatchFlag(flag_account_authorized, false) { if h.st.MatchFlag(flag_account_authorized, false) {
res.FlagReset = append(res.FlagReset, flag_incorrect_pin) res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
@@ -569,6 +614,21 @@ func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource
return res, nil return res, nil
} }
// QuitWithHelp displays helpline information then exits the menu
func (h *Handlers) QuitWithHelp(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
res.Content = l.Get("For more help,please call: 0757628885")
res.FlagReset = append(res.FlagReset, flag_account_authorized)
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) {
var res resource.Result var res resource.Result
@@ -584,7 +644,7 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res
return res, nil return res, nil
} }
if len(date) == 4 { if len(date) == validYOB {
res.FlagReset = append(res.FlagReset, flag_incorrect_date_format) res.FlagReset = append(res.FlagReset, flag_incorrect_date_format)
} else { } else {
res.FlagSet = append(res.FlagSet, flag_incorrect_date_format) res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)

File diff suppressed because it is too large Load Diff

View File

@@ -1,59 +0,0 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/lang"
"github.com/stretchr/testify/mock"
)
type MockDb struct {
mock.Mock
}
func (m *MockDb) SetPrefix(prefix uint8) {
m.Called(prefix)
}
func (m *MockDb) Prefix() uint8 {
args := m.Called()
return args.Get(0).(uint8)
}
func (m *MockDb) Safe() bool {
args := m.Called()
return args.Get(0).(bool)
}
func (m *MockDb) SetLanguage(language *lang.Language) {
m.Called(language)
}
func (m *MockDb) SetLock(uint8, bool) error {
args := m.Called()
return args.Error(0)
}
func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
args := m.Called(ctx, connectionStr)
return args.Error(0)
}
func (m *MockDb) SetSession(sessionId string) {
m.Called(sessionId)
}
func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
args := m.Called(ctx, key, value)
return args.Error(0)
}
func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
args := m.Called(ctx, key)
return nil, args.Error(0)
}
func (m *MockDb) Close() error {
args := m.Called(nil)
return args.Error(0)
}

View File

@@ -1,26 +0,0 @@
package mocks
import (
"git.grassecon.net/urdt/ussd/internal/models"
"github.com/stretchr/testify/mock"
)
// MockAccountService implements AccountServiceInterface for testing
type MockAccountService struct {
mock.Mock
}
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
args := m.Called()
return args.Get(0).(*models.AccountResponse), args.Error(1)
}
func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
args := m.Called(publicKey)
return args.String(0), args.Error(1)
}
func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
args := m.Called(trackingId)
return args.String(0), args.Error(1)
}

View File

@@ -1,24 +0,0 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/db"
"git.grassecon.net/urdt/ussd/internal/utils"
"github.com/stretchr/testify/mock"
)
type MockUserDataStore struct {
db.Db
mock.Mock
}
func (m *MockUserDataStore) ReadEntry(ctx context.Context, sessionId string, typ utils.DataTyp) ([]byte, error) {
args := m.Called(ctx, sessionId, typ)
return args.Get(0).([]byte), args.Error(1)
}
func (m *MockUserDataStore) WriteEntry(ctx context.Context, sessionId string, typ utils.DataTyp, value []byte) error {
args := m.Called(ctx, sessionId, typ, value)
return args.Error(0)
}

View File

@@ -22,6 +22,7 @@ const (
DATA_OFFERINGS DATA_OFFERINGS
DATA_RECIPIENT DATA_RECIPIENT
DATA_AMOUNT DATA_AMOUNT
DATA_TEMPORARY_PIN
) )
func typToBytes(typ DataTyp) []byte { func typToBytes(typ DataTyp) []byte {

View File

@@ -0,0 +1 @@
Confirm your new PIN:

View File

@@ -0,0 +1,7 @@
LOAD verify_pin 0
MOUT back 0
HALT
RELOAD verify_pin
CATCH create_pin_mismatch flag_pin_mismatch 1
MOVE pin_reset_success
INCMP _ 0

View File

@@ -0,0 +1 @@
The PIN you entered is invalid.The PIN must be different from your current PIN.For help call +254757628885

View File

@@ -0,0 +1,4 @@
MOUT back 0
HALT
INCMP _ 0

View File

@@ -6,3 +6,6 @@ msgstr "Ombi lako limetumwa. %s atapokea %s kutoka kwa %s."
msgid "Thank you for using Sarafu. Goodbye!" msgid "Thank you for using Sarafu. Goodbye!"
msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!"
msgid "For more help,please call: 0757628885"
msgstr "Kwa usaidizi zaidi,piga: 0757628885"

View File

@@ -1,3 +1,7 @@
LOAD save_temporary_pin 0
MOUT back 0 MOUT back 0
HALT HALT
RELOAD save_temporary_pin
CATCH invalid_pin flag_incorrect_pin 1
INCMP _ 0 INCMP _ 0
MOVE confirm_pin_change

View File

@@ -0,0 +1 @@
Your PIN change request has been successful

View File

@@ -0,0 +1,6 @@
LOAD confirm_pin_change 0
MOUT back 0
MOUT quit 9
HALT
INCMP _ 0
INCMP quit 9