From f73b7a8b04595cabbff4944e0b13fe57842f38f4 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Wed, 16 Oct 2024 22:40:40 +0300 Subject: [PATCH 01/38] setup api responses --- internal/handlers/server/api.go | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 internal/handlers/server/api.go diff --git a/internal/handlers/server/api.go b/internal/handlers/server/api.go new file mode 100644 index 0000000..646458c --- /dev/null +++ b/internal/handlers/server/api.go @@ -0,0 +1,60 @@ +package server + +type ( + OKResponse struct { + Ok bool `json:"ok"` + Description string `json:"description"` + Result map[string]any `json:"result"` + } + + ErrResponse struct { + Ok bool `json:"ok"` + Description string `json:"description"` + ErrCode string `json:"errorCode"` + } + + TransferRequest struct { + From string `json:"from" validate:"required,eth_addr_checksum"` + To string `json:"to" validate:"required,eth_addr_checksum"` + TokenAddress string `json:"tokenAddress" validate:"required,eth_addr_checksum"` + Amount string `json:"amount" validate:"required,number,gt=0"` + } + + PoolSwapRequest struct { + From string `json:"from" validate:"required,eth_addr_checksum"` + FromTokenAddress string `json:"fromTokenAddress" validate:"required,eth_addr_checksum"` + ToTokenAddress string `json:"toTokenAddress" validate:"required,eth_addr_checksum"` + PoolAddress string `json:"poolAddress" validate:"required,eth_addr_checksum"` + Amount string `json:"amount" validate:"required,number,gt=0"` + } + + PoolDepositRequest struct { + From string `json:"from" validate:"required,eth_addr_checksum"` + TokenAddress string `json:"tokenAddress" validate:"required,eth_addr_checksum"` + PoolAddress string `json:"poolAddress" validate:"required,eth_addr_checksum"` + Amount string `json:"amount" validate:"required,number,gt=0"` + } + + AccountAddressParam struct { + Address string `param:"address" validate:"required,eth_addr_checksum"` + } + + TrackingIDParam struct { + TrackingID string `param:"trackingId" validate:"required,uuid"` + } + + OTXByAccountRequest struct { + Address string `param:"address" validate:"required,eth_addr_checksum"` + PerPage int `query:"perPage" validate:"required,number,gt=0"` + Cursor int `query:"cursor" validate:"number"` + Next bool `query:"next"` + } +) + +const ( + ErrCodeInternalServerError = "E01" + ErrCodeInvalidJSON = "E02" + ErrCodeInvalidAPIKey = "E03" + ErrCodeValidationFailed = "E04" + ErrCodeAccountNotExists = "E05" +) From 4f043628358f5e3edb7c73ae239b17f07eee8869 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 17 Oct 2024 16:08:18 +0300 Subject: [PATCH 02/38] pass error description to error response --- internal/handlers/server/accountservice.go | 116 ++++++++++++++++++--- 1 file changed, 103 insertions(+), 13 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 1ddf7e7..7bb3dee 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -2,6 +2,7 @@ package server import ( "encoding/json" + "fmt" "io" "net/http" @@ -9,17 +10,21 @@ import ( "git.grassecon.net/urdt/ussd/internal/models" ) +var apiResponse struct { + Ok bool `json:"ok"` + Description string `json:"description"` +} + type AccountServiceInterface interface { CheckBalance(publicKey string) (*models.BalanceResponse, error) - CreateAccount() (*models.AccountResponse, error) + CreateAccount() (*OKResponse, *ErrResponse) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) + TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) } type AccountService struct { } -// CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID. -// // Parameters: // - trackingId: A unique identifier for the account.This should be obtained from a previous call to // CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the @@ -28,9 +33,9 @@ type AccountService struct { // 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. // - 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) (*models.TrackStatusResponse, error) { - resp, err := http.Get(config.TrackStatusURL + trackingId) + resp, err := http.Get(config.BalanceURL + trackingId) if err != nil { return nil, err } @@ -40,12 +45,67 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackSt if err != nil { return nil, err } + var trackResp models.TrackStatusResponse err = json.Unmarshal(body, &trackResp) if err != nil { return nil, err } return &trackResp, nil + +} + +func (as *AccountService) TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) { + var errResponse ErrResponse + var okResponse OKResponse + var err error + // Construct the URL with the path parameter + url := fmt.Sprintf("%s/%s", config.TrackURL, publicKey) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + // Set headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-GE-KEY", "xd") + + // Send the request + resp, err := http.DefaultClient.Do(req) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + defer resp.Body.Close() + + // Read the response body + body, err := io.ReadAll(resp.Body) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + + // Step 2: Unmarshal into the generic struct + err = json.Unmarshal([]byte(body), &apiResponse) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + if apiResponse.Ok { + err = json.Unmarshal([]byte(body), &okResponse) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + return &okResponse, nil + } else { + err := json.Unmarshal([]byte(body), &errResponse) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + return nil, &errResponse + } } // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint. @@ -75,20 +135,50 @@ func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceRespons // 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. // If no error occurs, this will be nil. -func (as *AccountService) CreateAccount() (*models.AccountResponse, error) { - resp, err := http.Post(config.CreateAccountURL, "application/json", nil) +func (as *AccountService) CreateAccount() (*OKResponse, *ErrResponse) { + + var errResponse ErrResponse + var okResponse OKResponse + var err error + + // Create a new request + req, err := http.NewRequest("POST", config.CreateAccountURL, nil) if err != nil { - return nil, err + errResponse.Description = err.Error() + return nil, &errResponse + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-GE-KEY", "xd") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse } defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) if err != nil { - return nil, err + errResponse.Description = err.Error() + return nil, &errResponse } - var accountResp models.AccountResponse - err = json.Unmarshal(body, &accountResp) + err = json.Unmarshal([]byte(body), &apiResponse) if err != nil { - return nil, err + return nil, &errResponse + } + if apiResponse.Ok { + err = json.Unmarshal([]byte(body), &okResponse) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + return &okResponse, nil + } else { + err := json.Unmarshal([]byte(body), &errResponse) + if err != nil { + errResponse.Description = err.Error() + return nil, &errResponse + } + return nil, &errResponse } - return &accountResp, nil } From b8e12e5215ec48c49dc7673a0dd9509a155df5e1 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:01:21 +0300 Subject: [PATCH 03/38] update api endpoints --- config/config.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index 0571503..a035d24 100644 --- a/config/config.go +++ b/config/config.go @@ -1,10 +1,7 @@ package config - - const ( - CreateAccountURL = "https://custodial.sarafu.africa/api/account/create" - TrackStatusURL = "https://custodial.sarafu.africa/api/track/" - BalanceURL = "https://custodial.sarafu.africa/api/account/status/" + CreateAccountURL = "http://localhost:5003/api/v2/account/create" + BalanceURL = "https://custodial.sarafu.africa/api/account/status/" + TrackURL = "http://localhost:5003/api/v2/account/status" ) - From 81c4189c8eaf254bec11a7a78681dc83e9d8b1ad Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:02:08 +0300 Subject: [PATCH 04/38] update tests --- internal/handlers/ussd/menuhandler_test.go | 142 +++++++++++---------- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 0bde51a..97c0dee 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -15,6 +15,7 @@ import ( "git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/state" + "git.grassecon.net/urdt/ussd/internal/handlers/server" "git.grassecon.net/urdt/ussd/internal/mocks" "git.grassecon.net/urdt/ussd/internal/models" "git.grassecon.net/urdt/ussd/internal/utils" @@ -78,68 +79,75 @@ func TestCreateAccount(t *testing.T) { if err != nil { t.Logf(err.Error()) } - // Create required mocks - mockDataStore := new(mocks.MockUserDataStore) - mockCreateAccountService := new(mocks.MockAccountService) - expectedResult := resource.Result{} - accountCreatedFlag, err := fm.GetFlag("flag_account_created") - + flag_account_created, err := fm.GetFlag("flag_account_created") if err != nil { t.Logf(err.Error()) } - expectedResult.FlagSet = append(expectedResult.FlagSet, accountCreatedFlag) // Define session ID and mock data sessionId := "session123" - typ := utils.DATA_ACCOUNT_CREATED - fakeError := db.ErrNotFound{} - // Create context with session ID + notFoundErr := db.ErrNotFound{} ctx := context.WithValue(context.Background(), "SessionId", sessionId) - // Define expected interactions with the mock - mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte("123"), fakeError) - expectedAccountResp := &models.AccountResponse{ - Ok: true, - Result: struct { - CustodialId json.Number `json:"custodialId"` - PublicKey string `json:"publicKey"` - TrackingId string `json:"trackingId"` - }{ - CustodialId: "12", - PublicKey: "0x8E0XSCSVA", - TrackingId: "d95a7e83-196c-4fd0-866fSGAGA", + tests := []struct { + name string + serverResponse *server.OKResponse + expectedResult resource.Result + }{ + { + name: "Test account creation success", + serverResponse: &server.OKResponse{ + Ok: true, + Description: "Account creation successed", + Result: map[string]any{ + "trackingId": "1234567890", + "publicKey": "1235QERYU", + }, + }, + expectedResult: resource.Result{ + FlagSet: []uint32{flag_account_created}, + }, }, } - mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil) - data := map[utils.DataTyp]string{ - utils.DATA_TRACKING_ID: expectedAccountResp.Result.TrackingId, - utils.DATA_PUBLIC_KEY: expectedAccountResp.Result.PublicKey, - utils.DATA_CUSTODIAL_ID: expectedAccountResp.Result.CustodialId.String(), + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + mockDataStore := new(mocks.MockUserDataStore) + mockCreateAccountService := new(mocks.MockAccountService) + + // Create a Handlers instance with the mock data store + h := &Handlers{ + userdataStore: mockDataStore, + accountService: mockCreateAccountService, + flagManager: fm.parser, + } + + data := map[utils.DataTyp]string{ + utils.DATA_TRACKING_ID: tt.serverResponse.Result["trackingId"].(string), + utils.DATA_PUBLIC_KEY: tt.serverResponse.Result["publicKey"].(string), + } + + mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_ACCOUNT_CREATED).Return([]byte(""), notFoundErr) + mockCreateAccountService.On("CreateAccount").Return(tt.serverResponse, nil) + + for key, value := range data { + mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil) + } + + // Call the method you want to test + res, err := h.CreateAccount(ctx, "create_account", []byte("some-input")) + + // Assert that no errors occurred + assert.NoError(t, err) + + // Assert that the account created flag has been set to the result + assert.Equal(t, res, tt.expectedResult, "Expected result should be equal to the actual result") + + // Assert that expectations were met + mockDataStore.AssertExpectations(t) + }) } - - for key, value := range data { - mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil) - } - - // Create a Handlers instance with the mock data store - h := &Handlers{ - userdataStore: mockDataStore, - accountService: mockCreateAccountService, - flagManager: fm.parser, - } - - // Call the method you want to test - res, err := h.CreateAccount(ctx, "create_account", []byte("some-input")) - - // Assert that no errors occurred - assert.NoError(t, err) - - //Assert that the account created flag has been set to the result - assert.Equal(t, res, expectedResult, "Expected result should be equal to the actual result") - - // Assert that expectations were met - mockDataStore.AssertExpectations(t) } func TestWithPersister(t *testing.T) { @@ -1072,12 +1080,20 @@ func TestCheckAccountStatus(t *testing.T) { tests := []struct { name string input []byte + serverResponse *server.OKResponse response *models.TrackStatusResponse expectedResult resource.Result }{ { - name: "Test when account status is Success", + name: "Test when account is on the Sarafu network", input: []byte("TrackingId1234"), + serverResponse: &server.OKResponse{ + Ok: true, + Description: "Account creation successed", + Result: map[string]any{ + "active": true, + }, + }, response: &models.TrackStatusResponse{ Ok: true, Result: struct { @@ -1104,17 +1120,7 @@ func TestCheckAccountStatus(t *testing.T) { }, }, { - name: "Test when fetching account status is not Success", - input: []byte("TrackingId1234"), - response: &models.TrackStatusResponse{ - Ok: false, - }, - expectedResult: resource.Result{ - FlagSet: []uint32{flag_api_error}, - }, - }, - { - name: "Test when checking account status api call is a SUCCESS but an account is not yet ready", + name: "Test when the account is not yet on the sarafu network", input: []byte("TrackingId1234"), response: &models.TrackStatusResponse{ Ok: true, @@ -1129,13 +1135,20 @@ func TestCheckAccountStatus(t *testing.T) { }{ Transaction: Transaction{ CreatedAt: time.Now(), - Status: "IN_NETWORK", + Status: "SUCCESS", TransferValue: json.Number("0.5"), TxHash: "0x123abc456def", TxType: "transfer", }, }, }, + serverResponse: &server.OKResponse{ + Ok: true, + Description: "Account creation successed", + Result: map[string]any{ + "active": false, + }, + }, expectedResult: resource.Result{ FlagSet: []uint32{flag_account_pending}, FlagReset: []uint32{flag_api_error, flag_account_success}, @@ -1155,9 +1168,10 @@ func TestCheckAccountStatus(t *testing.T) { status := tt.response.Result.Transaction.Status // Define expected interactions with the mock - mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_TRACKING_ID).Return(tt.input, nil) + mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return(tt.input, nil) mockCreateAccountService.On("CheckAccountStatus", string(tt.input)).Return(tt.response, nil) + mockCreateAccountService.On("TrackAccountStatus", string(tt.input)).Return(tt.serverResponse, nil) mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status)).Return(nil).Maybe() // Call the method under test From 128a354b34f2ed7f2eb44d99054dc4ac9d161a2c Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:03:48 +0300 Subject: [PATCH 05/38] use api structs --- internal/handlers/ussd/menuhandler.go | 48 +++++++++++---------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 6059dd4..adf4111 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -27,6 +27,8 @@ var ( logg = logging.NewVanilla().WithDomain("ussdmenuhandler") scriptDir = path.Join("services", "registration") translationDir = path.Join(scriptDir, "locale") + okResponse *server.OKResponse + errResponse *server.ErrResponse ) // FlagManager handles centralized flag management @@ -136,11 +138,16 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r } func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error { - accountResp, err := h.accountService.CreateAccount() + okResponse, errResponse := h.accountService.CreateAccount() + if errResponse != nil { + return nil + } + trackingId := okResponse.Result["trackingId"].(string) + publicKey := okResponse.Result["publicKey"].(string) + data := map[utils.DataTyp]string{ - utils.DATA_TRACKING_ID: accountResp.Result.TrackingId, - utils.DATA_PUBLIC_KEY: accountResp.Result.PublicKey, - utils.DATA_CUSTODIAL_ID: accountResp.Result.CustodialId.String(), + utils.DATA_TRACKING_ID: trackingId, + utils.DATA_PUBLIC_KEY: publicKey, } for key, value := range data { @@ -152,7 +159,7 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r } flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") res.FlagSet = append(res.FlagSet, flag_account_created) - return err + return nil } @@ -191,7 +198,6 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou } flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") - accountPIN := string(input) // Validate that the PIN is a 4-digit number if !isValidPIN(accountPIN) { @@ -368,7 +374,6 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou if !ok { return res, fmt.Errorf("missing session") } - if len(input) == 4 { yob := string(input) store := h.userdataStore @@ -411,7 +416,6 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re if !ok { return res, fmt.Errorf("missing session") } - gender := strings.Split(symbol, "_")[1] store := h.userdataStore err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender)) @@ -430,7 +434,6 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) if !ok { return res, fmt.Errorf("missing session") } - if len(input) > 0 { offerings := string(input) store := h.userdataStore @@ -456,7 +459,6 @@ func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byt // 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) { var res resource.Result - flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") res.FlagReset = append(res.FlagReset, flag_account_authorized) @@ -466,12 +468,10 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input // CheckIdentifier retrieves the PublicKey from the JSON data file. func (h *Handlers) CheckIdentifier(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 publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) @@ -485,12 +485,10 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte func (h *Handlers) Authorize(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") flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") @@ -542,28 +540,20 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b return res, fmt.Errorf("missing session") } store := h.userdataStore - trackingId, err := store.ReadEntry(ctx, sessionId, utils.DATA_TRACKING_ID) + publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) if err != nil { return res, err } - - accountStatus, err := h.accountService.CheckAccountStatus(string(trackingId)) - if err != nil { - fmt.Println("Error checking account status:", err) - return res, err - } - if !accountStatus.Ok { - res.FlagSet = append(res.FlagSet, flag_api_error) + okResponse, errResponse = h.accountService.TrackAccountStatus(string(publicKey)) + if errResponse != nil { return res, err } res.FlagReset = append(res.FlagReset, flag_api_error) - status := accountStatus.Result.Transaction.Status - - err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status)) - if err != nil { - return res, nil + isActive := okResponse.Result["active"].(bool) + if !ok { + return res, err } - if accountStatus.Result.Transaction.Status == "SUCCESS" { + if isActive { res.FlagSet = append(res.FlagSet, flag_account_success) res.FlagReset = append(res.FlagReset, flag_account_pending) } else { From 1c57c95d93efdf6d26a795f1987a9da8a712bac2 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:04:02 +0300 Subject: [PATCH 06/38] use api structs --- internal/mocks/servicemock.go | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/internal/mocks/servicemock.go b/internal/mocks/servicemock.go index d828045..7796b77 100644 --- a/internal/mocks/servicemock.go +++ b/internal/mocks/servicemock.go @@ -1,6 +1,7 @@ package mocks import ( + "git.grassecon.net/urdt/ussd/internal/handlers/server" "git.grassecon.net/urdt/ussd/internal/models" "github.com/stretchr/testify/mock" ) @@ -10,9 +11,19 @@ type MockAccountService struct { mock.Mock } -func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) { +func (m *MockAccountService) CreateAccount() (*server.OKResponse, *server.ErrResponse) { args := m.Called() - return args.Get(0).(*models.AccountResponse), args.Error(1) + okResponse, ok := args.Get(0).(*server.OKResponse) + errResponse, err := args.Get(1).(*server.ErrResponse) + + if ok { + return okResponse, nil + } + + if err { + return nil, errResponse + } + return nil, nil } func (m *MockAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { @@ -23,4 +34,17 @@ func (m *MockAccountService) CheckBalance(publicKey string) (*models.BalanceResp func (m *MockAccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { args := m.Called(trackingId) return args.Get(0).(*models.TrackStatusResponse), args.Error(1) -} \ No newline at end of file +} + +func (m *MockAccountService) TrackAccountStatus(publicKey string) (*server.OKResponse, *server.ErrResponse) { + args := m.Called(publicKey) + okResponse, ok := args.Get(0).(*server.OKResponse) + errResponse, err := args.Get(1).(*server.ErrResponse) + if ok { + return okResponse, nil + } + if err { + return nil, errResponse + } + return nil, nil +} From 353e24de33e79f79705b9022edc6a59ce3ce4245 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:04:43 +0300 Subject: [PATCH 07/38] define api structs --- internal/models/accountresponse.go | 17 ++++++----------- internal/models/trackstatusresponse.go | 3 +-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/internal/models/accountresponse.go b/internal/models/accountresponse.go index 1422a20..efcc30b 100644 --- a/internal/models/accountresponse.go +++ b/internal/models/accountresponse.go @@ -1,15 +1,10 @@ package models -import ( - "encoding/json" - -) - type AccountResponse struct { - Ok bool `json:"ok"` - Result struct { - CustodialId json.Number `json:"custodialId"` - PublicKey string `json:"publicKey"` - TrackingId string `json:"trackingId"` + Ok bool `json:"ok"` + Description string `json:"description"` // Include the description field + Result struct { + PublicKey string `json:"publicKey"` + TrackingId string `json:"trackingId"` } `json:"result"` -} \ No newline at end of file +} diff --git a/internal/models/trackstatusresponse.go b/internal/models/trackstatusresponse.go index 6054281..667c544 100644 --- a/internal/models/trackstatusresponse.go +++ b/internal/models/trackstatusresponse.go @@ -5,7 +5,6 @@ import ( "time" ) - type TrackStatusResponse struct { Ok bool `json:"ok"` Result struct { @@ -17,4 +16,4 @@ type TrackStatusResponse struct { TxType string `json:"txType"` } } `json:"result"` -} \ No newline at end of file +} From b8860478b6f469572ec13f68b4d07215cbf4a9f9 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:36:51 +0300 Subject: [PATCH 08/38] implement expected structs --- internal/handlers/server/accountservice.go | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 451c661..c284d63 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -187,19 +187,13 @@ func (as *AccountService) CreateAccount() (*OKResponse, *ErrResponse) { } } -func (tas *TestAccountService) CreateAccount() (*models.AccountResponse, error) { - return &models.AccountResponse{ - Ok: true, - Result: struct { - CustodialId json.Number `json:"custodialId"` - PublicKey string `json:"publicKey"` - TrackingId string `json:"trackingId"` - }{ - CustodialId: json.Number("182"), - PublicKey: "0x48ADca309b5085852207FAaf2816eD72B52F527C", - TrackingId: "28ebe84d-b925-472c-87ae-bbdfa1fb97be", - }, +func (tas *TestAccountService) CreateAccount() (*OKResponse, *ErrResponse) { + return &OKResponse{ + Ok: true, + Description: "Account creation request received successfully", + Result: map[string]any{"publicKey": "0x48ADca309b5085852207FAaf2816eD72B52F527C", "trackingId": "28ebe84d-b925-472c-87ae-bbdfa1fb97be"}, }, nil + } func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { @@ -218,6 +212,16 @@ func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceRe return balanceResponse, nil } +func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) { + return &OKResponse{ + Ok: true, + Description: "Account creation succeeded", + Result: map[string]any{ + "active": true, + }, + }, nil +} + func (tas *TestAccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { trackResponse := &models.TrackStatusResponse{ Ok: true, From f643aa4d14091a13f62bee23b73d736de7170bac Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Fri, 18 Oct 2024 17:37:04 +0300 Subject: [PATCH 09/38] update tests --- internal/handlers/ussd/menuhandler_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index de1a481..f84ca06 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -1082,7 +1082,7 @@ func TestCheckAccountStatus(t *testing.T) { input: []byte("TrackingId1234"), serverResponse: &server.OKResponse{ Ok: true, - Description: "Account creation successed", + Description: "Account creation succeeded", Result: map[string]any{ "active": true, }, @@ -1137,7 +1137,7 @@ func TestCheckAccountStatus(t *testing.T) { }, serverResponse: &server.OKResponse{ Ok: true, - Description: "Account creation successed", + Description: "Account creation succeeded", Result: map[string]any{ "active": false, }, From 367d3f0593c4ed5621a32e4187bfb0558be200ac Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:07:32 +0300 Subject: [PATCH 10/38] remove manually added api.go file --- internal/handlers/server/api.go | 60 --------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 internal/handlers/server/api.go diff --git a/internal/handlers/server/api.go b/internal/handlers/server/api.go deleted file mode 100644 index 646458c..0000000 --- a/internal/handlers/server/api.go +++ /dev/null @@ -1,60 +0,0 @@ -package server - -type ( - OKResponse struct { - Ok bool `json:"ok"` - Description string `json:"description"` - Result map[string]any `json:"result"` - } - - ErrResponse struct { - Ok bool `json:"ok"` - Description string `json:"description"` - ErrCode string `json:"errorCode"` - } - - TransferRequest struct { - From string `json:"from" validate:"required,eth_addr_checksum"` - To string `json:"to" validate:"required,eth_addr_checksum"` - TokenAddress string `json:"tokenAddress" validate:"required,eth_addr_checksum"` - Amount string `json:"amount" validate:"required,number,gt=0"` - } - - PoolSwapRequest struct { - From string `json:"from" validate:"required,eth_addr_checksum"` - FromTokenAddress string `json:"fromTokenAddress" validate:"required,eth_addr_checksum"` - ToTokenAddress string `json:"toTokenAddress" validate:"required,eth_addr_checksum"` - PoolAddress string `json:"poolAddress" validate:"required,eth_addr_checksum"` - Amount string `json:"amount" validate:"required,number,gt=0"` - } - - PoolDepositRequest struct { - From string `json:"from" validate:"required,eth_addr_checksum"` - TokenAddress string `json:"tokenAddress" validate:"required,eth_addr_checksum"` - PoolAddress string `json:"poolAddress" validate:"required,eth_addr_checksum"` - Amount string `json:"amount" validate:"required,number,gt=0"` - } - - AccountAddressParam struct { - Address string `param:"address" validate:"required,eth_addr_checksum"` - } - - TrackingIDParam struct { - TrackingID string `param:"trackingId" validate:"required,uuid"` - } - - OTXByAccountRequest struct { - Address string `param:"address" validate:"required,eth_addr_checksum"` - PerPage int `query:"perPage" validate:"required,number,gt=0"` - Cursor int `query:"cursor" validate:"number"` - Next bool `query:"next"` - } -) - -const ( - ErrCodeInternalServerError = "E01" - ErrCodeInvalidJSON = "E02" - ErrCodeInvalidAPIKey = "E03" - ErrCodeValidationFailed = "E04" - ErrCodeAccountNotExists = "E05" -) From 5b0a38351325bcf43eae700f5a06ac4e8bd8883b Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:09:37 +0300 Subject: [PATCH 11/38] use importable api structs --- internal/handlers/server/accountservice.go | 29 ++++++++++++---------- internal/handlers/ussd/menuhandler_test.go | 14 +++++++---- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index c284d63..39d1c66 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -9,18 +9,19 @@ import ( "git.grassecon.net/urdt/ussd/config" "git.grassecon.net/urdt/ussd/internal/models" + "github.com/grassrootseconomics/eth-custodial/pkg/api" ) -var apiResponse struct { +type ApiResponse struct { Ok bool `json:"ok"` Description string `json:"description"` } type AccountServiceInterface interface { CheckBalance(publicKey string) (*models.BalanceResponse, error) - CreateAccount() (*OKResponse, *ErrResponse) + CreateAccount() (*api.OKResponse, *api.ErrResponse) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) - TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) + TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) } type AccountService struct { @@ -59,9 +60,9 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackSt } -func (as *AccountService) TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) { - var errResponse ErrResponse - var okResponse OKResponse +func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { + var errResponse api.ErrResponse + var okResponse api.OKResponse var err error // Construct the URL with the path parameter url := fmt.Sprintf("%s/%s", config.TrackURL, publicKey) @@ -90,6 +91,7 @@ func (as *AccountService) TrackAccountStatus(publicKey string) (*OKResponse, *Er } // Step 2: Unmarshal into the generic struct + var apiResponse ApiResponse err = json.Unmarshal([]byte(body), &apiResponse) if err != nil { errResponse.Description = err.Error() @@ -139,10 +141,10 @@ func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceRespons // 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. // If no error occurs, this will be nil. -func (as *AccountService) CreateAccount() (*OKResponse, *ErrResponse) { +func (as *AccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { - var errResponse ErrResponse - var okResponse OKResponse + var errResponse api.ErrResponse + var okResponse api.OKResponse var err error // Create a new request @@ -166,6 +168,7 @@ func (as *AccountService) CreateAccount() (*OKResponse, *ErrResponse) { errResponse.Description = err.Error() return nil, &errResponse } + var apiResponse ApiResponse err = json.Unmarshal([]byte(body), &apiResponse) if err != nil { return nil, &errResponse @@ -187,8 +190,8 @@ func (as *AccountService) CreateAccount() (*OKResponse, *ErrResponse) { } } -func (tas *TestAccountService) CreateAccount() (*OKResponse, *ErrResponse) { - return &OKResponse{ +func (tas *TestAccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { + return &api.OKResponse{ Ok: true, Description: "Account creation request received successfully", Result: map[string]any{"publicKey": "0x48ADca309b5085852207FAaf2816eD72B52F527C", "trackingId": "28ebe84d-b925-472c-87ae-bbdfa1fb97be"}, @@ -212,8 +215,8 @@ func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceRe return balanceResponse, nil } -func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*OKResponse, *ErrResponse) { - return &OKResponse{ +func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { + return &api.OKResponse{ Ok: true, Description: "Account creation succeeded", Result: map[string]any{ diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index f84ca06..d78f526 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -20,6 +20,7 @@ import ( "git.grassecon.net/urdt/ussd/internal/models" "git.grassecon.net/urdt/ussd/internal/utils" "github.com/alecthomas/assert/v2" + "github.com/grassrootseconomics/eth-custodial/pkg/api" testdataloader "github.com/peteole/testdata-loader" "github.com/stretchr/testify/require" ) @@ -74,6 +75,8 @@ func TestCreateAccount(t *testing.T) { } // Create required mocks flag_account_created, err := fm.GetFlag("flag_account_created") + //flag_api_call_error, err := fm.GetFlag("flag_api_call_error,") + flag_api_call_error, _ := fm.GetFlag("flag_api_call_error") if err != nil { t.Logf(err.Error()) } @@ -85,12 +88,12 @@ func TestCreateAccount(t *testing.T) { tests := []struct { name string - serverResponse *server.OKResponse + serverResponse *api.OKResponse expectedResult resource.Result }{ { name: "Test account creation success", - serverResponse: &server.OKResponse{ + serverResponse: &api.OKResponse{ Ok: true, Description: "Account creation successed", Result: map[string]any{ @@ -100,6 +103,7 @@ func TestCreateAccount(t *testing.T) { }, expectedResult: resource.Result{ FlagSet: []uint32{flag_account_created}, + FlagReset: []uint32{flag_api_call_error}, }, }, } @@ -1073,14 +1077,14 @@ func TestCheckAccountStatus(t *testing.T) { tests := []struct { name string input []byte - serverResponse *server.OKResponse + serverResponse *api.OKResponse response *models.TrackStatusResponse expectedResult resource.Result }{ { name: "Test when account is on the Sarafu network", input: []byte("TrackingId1234"), - serverResponse: &server.OKResponse{ + serverResponse: &api.OKResponse{ Ok: true, Description: "Account creation succeeded", Result: map[string]any{ @@ -1135,7 +1139,7 @@ func TestCheckAccountStatus(t *testing.T) { }, }, }, - serverResponse: &server.OKResponse{ + serverResponse: &api.OKResponse{ Ok: true, Description: "Account creation succeeded", Result: map[string]any{ From d81bc0eefb78ba78eac2c61dcdfb1e1413822766 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:10:01 +0300 Subject: [PATCH 12/38] use importable api structs --- internal/handlers/ussd/menuhandler.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 3efcbb1..0fc30cc 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -3,6 +3,7 @@ package ussd import ( "bytes" "context" + "errors" "fmt" "path" "regexp" @@ -10,6 +11,7 @@ import ( "strings" "git.defalsify.org/vise.git/asm" + "github.com/grassrootseconomics/eth-custodial/pkg/api" "git.defalsify.org/vise.git/cache" "git.defalsify.org/vise.git/db" @@ -27,8 +29,8 @@ var ( logg = logging.NewVanilla().WithDomain("ussdmenuhandler") scriptDir = path.Join("services", "registration") translationDir = path.Join(scriptDir, "locale") - okResponse *server.OKResponse - errResponse *server.ErrResponse + okResponse *api.OKResponse + errResponse *api.ErrResponse ) // FlagManager handles centralized flag management @@ -138,12 +140,19 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r } func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error { + flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") + flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") okResponse, errResponse := h.accountService.CreateAccount() if errResponse != nil { - return nil + if !errResponse.Ok { + res.FlagSet = append(res.FlagSet, flag_api_call_error) + return nil + } + return errors.New(errResponse.Description) } trackingId := okResponse.Result["trackingId"].(string) publicKey := okResponse.Result["publicKey"].(string) + res.FlagReset = append(res.FlagReset, flag_api_call_error) data := map[utils.DataTyp]string{ utils.DATA_TRACKING_ID: trackingId, @@ -157,7 +166,6 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r return err } } - flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") res.FlagSet = append(res.FlagSet, flag_account_created) return nil @@ -546,6 +554,9 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b } okResponse, errResponse = h.accountService.TrackAccountStatus(string(publicKey)) if errResponse != nil { + if !errResponse.Ok { + res.FlagSet = append(res.FlagSet, flag_api_error) + } return res, err } res.FlagReset = append(res.FlagReset, flag_api_error) From 4beeb9986a3050dbe75c790ace6243a4c6e9b140 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:10:23 +0300 Subject: [PATCH 13/38] use importable api structs --- internal/mocks/servicemock.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/mocks/servicemock.go b/internal/mocks/servicemock.go index 7796b77..0cf07c6 100644 --- a/internal/mocks/servicemock.go +++ b/internal/mocks/servicemock.go @@ -1,8 +1,8 @@ package mocks import ( - "git.grassecon.net/urdt/ussd/internal/handlers/server" "git.grassecon.net/urdt/ussd/internal/models" + "github.com/grassrootseconomics/eth-custodial/pkg/api" "github.com/stretchr/testify/mock" ) @@ -11,10 +11,10 @@ type MockAccountService struct { mock.Mock } -func (m *MockAccountService) CreateAccount() (*server.OKResponse, *server.ErrResponse) { +func (m *MockAccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { args := m.Called() - okResponse, ok := args.Get(0).(*server.OKResponse) - errResponse, err := args.Get(1).(*server.ErrResponse) + okResponse, ok := args.Get(0).(*api.OKResponse) + errResponse, err := args.Get(1).(*api.ErrResponse) if ok { return okResponse, nil @@ -36,10 +36,10 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (*models.Trac return args.Get(0).(*models.TrackStatusResponse), args.Error(1) } -func (m *MockAccountService) TrackAccountStatus(publicKey string) (*server.OKResponse, *server.ErrResponse) { +func (m *MockAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { args := m.Called(publicKey) - okResponse, ok := args.Get(0).(*server.OKResponse) - errResponse, err := args.Get(1).(*server.ErrResponse) + okResponse, ok := args.Get(0).(*api.OKResponse) + errResponse, err := args.Get(1).(*api.ErrResponse) if ok { return okResponse, nil } From 66d2e2e838b13aacc90cfd9314f51047dd18b387 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:10:42 +0300 Subject: [PATCH 14/38] add custodial api structs --- go.mod | 12 +++++++++--- go.sum | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1f67f34..e104186 100644 --- a/go.mod +++ b/go.mod @@ -1,27 +1,33 @@ module git.grassecon.net/urdt/ussd -go 1.22.6 +go 1.23.0 + +toolchain go1.23.2 require ( git.defalsify.org/vise.git v0.1.0-rc.3.0.20240923162317-c20d557a3dbb github.com/alecthomas/assert/v2 v2.2.2 github.com/peteole/testdata-loader v0.3.0 gopkg.in/leonelquinteros/gotext.v1 v1.3.1 + ) +require github.com/grassrootseconomics/eth-custodial v1.3.0-beta // indirect + require ( 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/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible 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/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 github.com/x448/float16 v0.8.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + ) diff --git a/go.sum b/go.sum index 0eccb60..a3feb64 100644 --- a/go.sum +++ b/go.sum @@ -10,10 +10,14 @@ github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YV 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/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/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/grassrootseconomics/eth-custodial v1.3.0-beta h1:twrMBhl89GqDUL9PlkzQxMP/6OST1BByrNDj+rqXDmU= +github.com/grassrootseconomics/eth-custodial v1.3.0-beta/go.mod h1:7uhRcdnJplX4t6GKCEFkbeDhhjlcaGJeJqevbcvGLZo= github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo= github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -24,6 +28,8 @@ github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVY 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/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= From acd0af25c6e84322f3cb46ec7f43928d0f24affa Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 11:11:04 +0300 Subject: [PATCH 15/38] catch api call error --- services/registration/create_pin.vis | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/registration/create_pin.vis b/services/registration/create_pin.vis index e0e330f..44d2cf1 100644 --- a/services/registration/create_pin.vis +++ b/services/registration/create_pin.vis @@ -1,4 +1,6 @@ LOAD create_account 0 +RELOAD create_account +CATCH api_failure flag_api_call_error 1 CATCH account_creation_failed flag_account_creation_failed 1 MOUT exit 0 HALT From 9c75942b0b8d3533664eb6a8816e5f999fd6ed07 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Mon, 21 Oct 2024 16:54:16 +0300 Subject: [PATCH 16/38] chore: remove commented code --- internal/handlers/ussd/menuhandler_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index d78f526..3b4b00f 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -75,7 +75,6 @@ func TestCreateAccount(t *testing.T) { } // Create required mocks flag_account_created, err := fm.GetFlag("flag_account_created") - //flag_api_call_error, err := fm.GetFlag("flag_api_call_error,") flag_api_call_error, _ := fm.GetFlag("flag_api_call_error") if err != nil { t.Logf(err.Error()) @@ -102,7 +101,7 @@ func TestCreateAccount(t *testing.T) { }, }, expectedResult: resource.Result{ - FlagSet: []uint32{flag_account_created}, + FlagSet: []uint32{flag_account_created}, FlagReset: []uint32{flag_api_call_error}, }, }, From b9a63f3c6feb15b9d895f18aee4861e333f0fc0c Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Tue, 22 Oct 2024 21:30:48 +0300 Subject: [PATCH 17/38] merge dep --- go.mod | 15 +++++++++++++-- go.sum | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 7654709..1225673 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,20 @@ require ( ) -require github.com/joho/godotenv v1.5.1 // indirect +require github.com/joho/godotenv v1.5.1 -require github.com/grassrootseconomics/eth-custodial v1.3.0-beta // indirect +require ( + github.com/grassrootseconomics/eth-custodial v1.3.0-beta + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.7.1 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/text v0.18.0 // indirect +) require ( github.com/alecthomas/participle/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index 1d1de2d..d566e2c 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -git.defalsify.org/vise.git v0.1.0-rc.3.0.20240923162317-c20d557a3dbb h1:6P4kxihcwMjDKzvUFC6t2zGNb7MDW+l/ACGlSAN1N8Y= -git.defalsify.org/vise.git v0.1.0-rc.3.0.20240923162317-c20d557a3dbb/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M= -git.defalsify.org/vise.git v0.2.0 h1:X2ZgiGRq4C+9qOlDMP0b/oE5QHjVQNT4aEFZB88ST0Q= -git.defalsify.org/vise.git v0.2.0/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M= git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b h1:dxBplsIlzJHV+5EH+gzB+w08Blt7IJbb2jeRe1OEjLU= git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= @@ -12,8 +8,8 @@ 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/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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= @@ -26,25 +22,51 @@ github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qf github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= +github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY= github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk= +github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s= +github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 3179ec1f62d46eda15240866d007131b5e11b755 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Tue, 22 Oct 2024 21:35:52 +0300 Subject: [PATCH 18/38] add local track endpoint --- config/config.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index dba0da7..43466c3 100644 --- a/config/config.go +++ b/config/config.go @@ -6,11 +6,13 @@ var ( CreateAccountURL string TrackStatusURL string BalanceURL string + TrackURL string ) // LoadConfig initializes the configuration values after environment variables are loaded. func LoadConfig() { - CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "https://custodial.sarafu.africa/api/account/create") + CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "http://localhost:5003/api/v2/account/create") TrackStatusURL = initializers.GetEnv("TRACK_STATUS_URL", "https://custodial.sarafu.africa/api/track/") BalanceURL = initializers.GetEnv("BALANCE_URL", "https://custodial.sarafu.africa/api/account/status/") + TrackURL = initializers.GetEnv("TRACK_URL", "http://localhost:5003/api/v2/account/status") } From 5f2c6cce163e0605f57179d9c2fbd7bc9cf2619a Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Tue, 22 Oct 2024 21:36:28 +0300 Subject: [PATCH 19/38] add required track endpoint --- .env.example | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 97d3317..ab370a7 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,7 @@ DB_SSLMODE=disable DB_TIMEZONE=Africa/Nairobi #External API Calls -CREATE_ACCOUNT_URL=https://custodial.sarafu.africa/api/account/create +CREATE_ACCOUNT_URL=http://localhost:5003/api/v2/account/create TRACK_STATUS_URL=https://custodial.sarafu.africa/api/track/ BALANCE_URL=https://custodial.sarafu.africa/api/account/status/ +TRACK_URL=http://localhost:5003/api/v2/account/status From fb32dde136d2587b55638fece25f78a455750d57 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Wed, 23 Oct 2024 12:45:10 +0300 Subject: [PATCH 20/38] run go mod tidy --- go.mod | 13 ++++++++++++- go.sum | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 38be305..3349bf8 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,18 @@ require ( gopkg.in/leonelquinteros/gotext.v1 v1.3.1 ) -require github.com/joho/godotenv v1.5.1 // indirect +require ( + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.7.0 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/joho/godotenv v1.5.1 + github.com/kr/text v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/text v0.18.0 // indirect +) require ( github.com/alecthomas/participle/v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index 2abec41..ef40172 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -git.defalsify.org/vise.git v0.1.0-rc.3.0.20240923162317-c20d557a3dbb h1:6P4kxihcwMjDKzvUFC6t2zGNb7MDW+l/ACGlSAN1N8Y= -git.defalsify.org/vise.git v0.1.0-rc.3.0.20240923162317-c20d557a3dbb/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M= -git.defalsify.org/vise.git v0.2.0 h1:X2ZgiGRq4C+9qOlDMP0b/oE5QHjVQNT4aEFZB88ST0Q= -git.defalsify.org/vise.git v0.2.0/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M= git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b h1:dxBplsIlzJHV+5EH+gzB+w08Blt7IJbb2jeRe1OEjLU= git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= @@ -12,6 +8,8 @@ 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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -22,23 +20,50 @@ github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qf github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.0 h1:FG6VLIdzvAPhnYqP14sQ2xhFLkiUQHCs6ySqO91kF4g= +github.com/jackc/pgx/v5 v5.7.0/go.mod h1:awP1KNnjylvpxHuHP63gzjhnGkI1iw+PMoIwvoleN/8= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY= github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk= +github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s= +github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From b41e52af63c845386946845238e99548b78bc0bc Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Wed, 23 Oct 2024 12:45:54 +0300 Subject: [PATCH 21/38] pass context.Context --- internal/handlers/server/accountservice.go | 19 ++++++++++--------- internal/handlers/ussd/menuhandler.go | 12 ++++++------ internal/mocks/servicemock.go | 8 +++++--- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 5b71e6f..f86c2fb 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -1,6 +1,7 @@ package server import ( + "context" "encoding/json" "io" "net/http" @@ -11,9 +12,9 @@ import ( ) type AccountServiceInterface interface { - CheckBalance(publicKey string) (*models.BalanceResponse, error) - CreateAccount() (*models.AccountResponse, error) - CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) + CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) + CreateAccount(ctx context.Context) (*models.AccountResponse, error) + CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) } type AccountService struct { @@ -33,7 +34,7 @@ type TestAccountService struct { // - 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. // If no error occurs, this will be nil. -func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { +func (as *AccountService) CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) { resp, err := http.Get(config.TrackStatusURL + trackingId) if err != nil { return nil, err @@ -55,7 +56,7 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackSt // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint. // Parameters: // - publicKey: The public key associated with the account whose balance needs to be checked. -func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { +func (as *AccountService) CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) { resp, err := http.Get(config.BalanceURL + publicKey) if err != nil { return nil, err @@ -79,7 +80,7 @@ func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceRespons // 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. // If no error occurs, this will be nil. -func (as *AccountService) CreateAccount() (*models.AccountResponse, error) { +func (as *AccountService) CreateAccount(ctx context.Context) (*models.AccountResponse, error) { resp, err := http.Post(config.CreateAccountURL, "application/json", nil) if err != nil { return nil, err @@ -97,7 +98,7 @@ func (as *AccountService) CreateAccount() (*models.AccountResponse, error) { return &accountResp, nil } -func (tas *TestAccountService) CreateAccount() (*models.AccountResponse, error) { +func (tas *TestAccountService) CreateAccount(ctx context.Context) (*models.AccountResponse, error) { return &models.AccountResponse{ Ok: true, Result: struct { @@ -112,7 +113,7 @@ func (tas *TestAccountService) CreateAccount() (*models.AccountResponse, error) }, nil } -func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { +func (tas *TestAccountService) CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) { balanceResponse := &models.BalanceResponse{ Ok: true, @@ -128,7 +129,7 @@ func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceRe return balanceResponse, nil } -func (tas *TestAccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { +func (tas *TestAccountService) CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) { trackResponse := &models.TrackStatusResponse{ Ok: true, Result: struct { diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 36d1ad5..03351c0 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -136,7 +136,7 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r } func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error { - accountResp, err := h.accountService.CreateAccount() + accountResp, err := h.accountService.CreateAccount(ctx) data := map[utils.DataTyp]string{ utils.DATA_TRACKING_ID: accountResp.Result.TrackingId, utils.DATA_PUBLIC_KEY: accountResp.Result.PublicKey, @@ -547,7 +547,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b return res, err } - accountStatus, err := h.accountService.CheckAccountStatus(string(trackingId)) + accountStatus, err := h.accountService.CheckAccountStatus(string(trackingId),ctx) if err != nil { fmt.Println("Error checking account status:", err) return res, err @@ -656,7 +656,7 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( return res, err } - balanceResponse, err := h.accountService.CheckBalance(string(publicKey)) + balanceResponse, err := h.accountService.CheckBalance(string(publicKey),ctx) if err != nil { return res, nil } @@ -688,7 +688,7 @@ func (h *Handlers) FetchCustodialBalances(ctx context.Context, sym string, input return res, err } - balanceResponse, err := h.accountService.CheckBalance(string(publicKey)) + balanceResponse, err := h.accountService.CheckBalance(string(publicKey),ctx) if err != nil { return res, nil } @@ -806,7 +806,7 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res store := h.userdataStore publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) - balanceResp, err := h.accountService.CheckBalance(string(publicKey)) + balanceResp, err := h.accountService.CheckBalance(string(publicKey),ctx) if err != nil { return res, nil } @@ -836,7 +836,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) amountStr := string(input) - balanceRes, err := h.accountService.CheckBalance(string(publicKey)) + balanceRes, err := h.accountService.CheckBalance(string(publicKey),ctx) balanceStr := balanceRes.Result.Balance if !balanceRes.Ok { diff --git a/internal/mocks/servicemock.go b/internal/mocks/servicemock.go index d828045..8c2b4ea 100644 --- a/internal/mocks/servicemock.go +++ b/internal/mocks/servicemock.go @@ -1,6 +1,8 @@ package mocks import ( + "context" + "git.grassecon.net/urdt/ussd/internal/models" "github.com/stretchr/testify/mock" ) @@ -10,17 +12,17 @@ type MockAccountService struct { mock.Mock } -func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) { +func (m *MockAccountService) CreateAccount(ctx context.Context) (*models.AccountResponse, error) { args := m.Called() return args.Get(0).(*models.AccountResponse), args.Error(1) } -func (m *MockAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { +func (m *MockAccountService) CheckBalance(publicKey string,ctx context.Context) (*models.BalanceResponse, error) { args := m.Called(publicKey) return args.Get(0).(*models.BalanceResponse), args.Error(1) } -func (m *MockAccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { +func (m *MockAccountService) CheckAccountStatus(trackingId string,ctx context.Context) (*models.TrackStatusResponse, error) { args := m.Called(trackingId) return args.Get(0).(*models.TrackStatusResponse), args.Error(1) } \ No newline at end of file From 9bc9d04a49c591869692b8c59fd4ed0aa8e81087 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 10:00:38 +0300 Subject: [PATCH 22/38] use errresponse and okresponse for deserialization --- internal/handlers/server/accountservice.go | 97 ++++++++-------------- 1 file changed, 34 insertions(+), 63 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 39d1c66..6ae9630 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -2,6 +2,7 @@ package server import ( "encoding/json" + "errors" "fmt" "io" "net/http" @@ -12,16 +13,17 @@ import ( "github.com/grassrootseconomics/eth-custodial/pkg/api" ) -type ApiResponse struct { - Ok bool `json:"ok"` - Description string `json:"description"` -} +var ( + okResponse api.OKResponse + errResponse api.ErrResponse + EMPTY_RESPONSE = 0 +) type AccountServiceInterface interface { CheckBalance(publicKey string) (*models.BalanceResponse, error) - CreateAccount() (*api.OKResponse, *api.ErrResponse) + CreateAccount() (*api.OKResponse, error) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) - TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) + TrackAccountStatus(publicKey string) (*api.OKResponse, error) } type AccountService struct { @@ -60,58 +62,42 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackSt } -func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { - var errResponse api.ErrResponse - var okResponse api.OKResponse +func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { var err error // Construct the URL with the path parameter url := fmt.Sprintf("%s/%s", config.TrackURL, publicKey) req, err := http.NewRequest("GET", url, nil) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } - // Set headers + req.Header.Set("Content-Type", "application/json") req.Header.Set("X-GE-KEY", "xd") - // Send the request resp, err := http.DefaultClient.Do(req) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } defer resp.Body.Close() - // Read the response body body, err := io.ReadAll(resp.Body) if err != nil { errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } - - // Step 2: Unmarshal into the generic struct - var apiResponse ApiResponse - err = json.Unmarshal([]byte(body), &apiResponse) + err = json.Unmarshal([]byte(body), &okResponse) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse - } - if apiResponse.Ok { - err = json.Unmarshal([]byte(body), &okResponse) - if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse - } - return &okResponse, nil - } else { err := json.Unmarshal([]byte(body), &errResponse) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } - return nil, &errResponse + return nil, errors.New(errResponse.Description) } + if len(okResponse.Result) == EMPTY_RESPONSE { + return nil, errors.New("Empty api result") + } + return &okResponse, nil + } // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint. @@ -141,17 +127,13 @@ func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceRespons // 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. // If no error occurs, this will be nil. -func (as *AccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { - - var errResponse api.ErrResponse - var okResponse api.OKResponse +func (as *AccountService) CreateAccount() (*api.OKResponse, error) { var err error // Create a new request req, err := http.NewRequest("POST", config.CreateAccountURL, nil) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } req.Header.Set("Content-Type", "application/json") req.Header.Set("X-GE-KEY", "xd") @@ -159,38 +141,29 @@ func (as *AccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { resp, err := http.DefaultClient.Do(req) if err != nil { errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } - var apiResponse ApiResponse - err = json.Unmarshal([]byte(body), &apiResponse) + err = json.Unmarshal([]byte(body), &okResponse) if err != nil { - return nil, &errResponse - } - if apiResponse.Ok { - err = json.Unmarshal([]byte(body), &okResponse) - if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse - } - return &okResponse, nil - } else { err := json.Unmarshal([]byte(body), &errResponse) if err != nil { - errResponse.Description = err.Error() - return nil, &errResponse + return nil, err } - return nil, &errResponse + return nil, errors.New(errResponse.Description) } + if len(okResponse.Result) == EMPTY_RESPONSE { + return nil, errors.New("Empty api result") + } + return &okResponse, nil } -func (tas *TestAccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { +func (tas *TestAccountService) CreateAccount() (*api.OKResponse, error) { return &api.OKResponse{ Ok: true, Description: "Account creation request received successfully", @@ -200,7 +173,6 @@ func (tas *TestAccountService) CreateAccount() (*api.OKResponse, *api.ErrRespons } func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { - balanceResponse := &models.BalanceResponse{ Ok: true, Result: struct { @@ -211,11 +183,10 @@ func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceRe Nonce: json.Number("0"), }, } - return balanceResponse, nil } -func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { +func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { return &api.OKResponse{ Ok: true, Description: "Account creation succeeded", From 08e709f1b349f1bbe51c829c852977d0eab3743c Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 10:02:15 +0300 Subject: [PATCH 23/38] check for error responses --- internal/handlers/ussd/menuhandler.go | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 0fc30cc..e7f52eb 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -3,7 +3,6 @@ package ussd import ( "bytes" "context" - "errors" "fmt" "path" "regexp" @@ -141,24 +140,17 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error { flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") - flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") - okResponse, errResponse := h.accountService.CreateAccount() - if errResponse != nil { - if !errResponse.Ok { - res.FlagSet = append(res.FlagSet, flag_api_call_error) - return nil - } - return errors.New(errResponse.Description) + okResponse, err := h.accountService.CreateAccount() + if err != nil { + return err } trackingId := okResponse.Result["trackingId"].(string) publicKey := okResponse.Result["publicKey"].(string) - res.FlagReset = append(res.FlagReset, flag_api_call_error) data := map[utils.DataTyp]string{ utils.DATA_TRACKING_ID: trackingId, utils.DATA_PUBLIC_KEY: publicKey, } - for key, value := range data { store := h.userdataStore err := store.WriteEntry(ctx, sessionId, key, []byte(value)) @@ -552,11 +544,9 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b if err != nil { return res, err } - okResponse, errResponse = h.accountService.TrackAccountStatus(string(publicKey)) - if errResponse != nil { - if !errResponse.Ok { - res.FlagSet = append(res.FlagSet, flag_api_error) - } + okResponse, err = h.accountService.TrackAccountStatus(string(publicKey)) + if err != nil { + res.FlagSet = append(res.FlagSet, flag_api_error) return res, err } res.FlagReset = append(res.FlagReset, flag_api_error) From 308ca99fb082d646aa34aae5610841232fbb8df4 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 10:02:32 +0300 Subject: [PATCH 24/38] remove reload account creation --- services/registration/create_pin.vis | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/registration/create_pin.vis b/services/registration/create_pin.vis index 44d2cf1..e0e330f 100644 --- a/services/registration/create_pin.vis +++ b/services/registration/create_pin.vis @@ -1,6 +1,4 @@ LOAD create_account 0 -RELOAD create_account -CATCH api_failure flag_api_call_error 1 CATCH account_creation_failed flag_account_creation_failed 1 MOUT exit 0 HALT From d74a4cc33ba5fb1c04f2a6b1a03062ea1f8cc0e7 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 10:10:03 +0300 Subject: [PATCH 25/38] update service mock method signatures --- internal/mocks/servicemock.go | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/internal/mocks/servicemock.go b/internal/mocks/servicemock.go index 0cf07c6..0b56314 100644 --- a/internal/mocks/servicemock.go +++ b/internal/mocks/servicemock.go @@ -11,19 +11,9 @@ type MockAccountService struct { mock.Mock } -func (m *MockAccountService) CreateAccount() (*api.OKResponse, *api.ErrResponse) { +func (m *MockAccountService) CreateAccount() (*api.OKResponse, error) { args := m.Called() - okResponse, ok := args.Get(0).(*api.OKResponse) - errResponse, err := args.Get(1).(*api.ErrResponse) - - if ok { - return okResponse, nil - } - - if err { - return nil, errResponse - } - return nil, nil + return args.Get(0).(*api.OKResponse), args.Error(1) } func (m *MockAccountService) CheckBalance(publicKey string) (*models.BalanceResponse, error) { @@ -36,15 +26,7 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (*models.Trac return args.Get(0).(*models.TrackStatusResponse), args.Error(1) } -func (m *MockAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, *api.ErrResponse) { +func (m *MockAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { args := m.Called(publicKey) - okResponse, ok := args.Get(0).(*api.OKResponse) - errResponse, err := args.Get(1).(*api.ErrResponse) - if ok { - return okResponse, nil - } - if err { - return nil, errResponse - } - return nil, nil + return args.Get(0).(*api.OKResponse), args.Error(1) } From 9f2d57ea0361c1d131b55a9d5080456eb80535d1 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 10:10:14 +0300 Subject: [PATCH 26/38] update tests --- internal/handlers/ussd/menuhandler_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 3b4b00f..8828690 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -75,11 +75,9 @@ func TestCreateAccount(t *testing.T) { } // Create required mocks flag_account_created, err := fm.GetFlag("flag_account_created") - flag_api_call_error, _ := fm.GetFlag("flag_api_call_error") if err != nil { t.Logf(err.Error()) } - // Define session ID and mock data sessionId := "session123" notFoundErr := db.ErrNotFound{} @@ -101,8 +99,7 @@ func TestCreateAccount(t *testing.T) { }, }, expectedResult: resource.Result{ - FlagSet: []uint32{flag_account_created}, - FlagReset: []uint32{flag_api_call_error}, + FlagSet: []uint32{flag_account_created}, }, }, } From 579b46db65b858b25f5196215f11ed08eeb120d5 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 24 Oct 2024 14:34:12 +0300 Subject: [PATCH 27/38] Replace the public key with the sessionId --- internal/handlers/ussd/menuhandler.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 36d1ad5..bdb9fb7 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -906,7 +906,7 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) ( return res, nil } -// GetSender retrieves the public key from the Gdbm Db +// GetSender returns the sessionId (phoneNumber) func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result @@ -915,10 +915,7 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res return res, fmt.Errorf("missing session") } - store := h.userdataStore - publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) - - res.Content = string(publicKey) + res.Content = string(sessionId) return res, nil } @@ -955,13 +952,12 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input [] // TODO // Use the amount, recipient and sender to call the API and initialize the transaction store := h.userdataStore - publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT) recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT) - res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey)) + res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(sessionId)) account_authorized_flag, err := h.flagManager.GetFlag("flag_account_authorized") if err != nil { From 6200728435c09aa010f65a66862fbcd2e6420bb8 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 24 Oct 2024 14:45:15 +0300 Subject: [PATCH 28/38] Updated the menuhander test --- internal/handlers/ussd/menuhandler_test.go | 27 +++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 38c468c..bd72d65 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -509,12 +509,8 @@ func TestGetSender(t *testing.T) { mockStore := new(mocks.MockUserDataStore) // Define test data - sessionId := "session123" + sessionId := "254712345678" ctx := context.WithValue(context.Background(), "SessionId", sessionId) - publicKey := "0xcasgatweksalw1018221" - - // Set up the expected behavior of the mock - mockStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil) // Create the Handlers instance with the mock store h := &Handlers{ @@ -522,11 +518,10 @@ func TestGetSender(t *testing.T) { } // Call the method - res, _ := h.GetSender(ctx, "max_amount", []byte("check_balance")) - - //Assert that the public key from readentry operation is what was set as the result content. - assert.Equal(t, publicKey, res.Content) + res, _ := h.GetSender(ctx, "get_sender", []byte("")) + //Assert that the sessionId is what was set as the result content. + assert.Equal(t, sessionId, res.Content) } func TestGetAmount(t *testing.T) { @@ -1284,7 +1279,7 @@ func TestResetInvalidAmount(t *testing.T) { } func TestInitiateTransaction(t *testing.T) { - sessionId := "session123" + sessionId := "254712345678" fm, err := NewFlagManager(flagsPath) @@ -1307,30 +1302,26 @@ func TestInitiateTransaction(t *testing.T) { tests := []struct { name string input []byte - PublicKey []byte Recipient []byte Amount []byte status string expectedResult resource.Result }{ { - name: "Test amount reset", - PublicKey: []byte("0x1241527192"), - Amount: []byte("0.002CELO"), + name: "Test initiate transaction", + Amount: []byte("0.002 CELO"), Recipient: []byte("0x12415ass27192"), expectedResult: resource.Result{ FlagReset: []uint32{account_authorized_flag}, - Content: "Your request has been sent. 0x12415ass27192 will receive 0.002CELO from 0x1241527192.", + Content: "Your request has been sent. 0x12415ass27192 will receive 0.002 CELO from 254712345678.", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Define expected interactions with the mock - mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return(tt.PublicKey, nil) mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_AMOUNT).Return(tt.Amount, nil) mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_RECIPIENT).Return(tt.Recipient, nil) - //mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_AMOUNT, []byte("")).Return(nil) // Call the method under test res, _ := h.InitiateTransaction(ctx, "transaction_reset_amount", tt.input) @@ -1343,10 +1334,8 @@ func TestInitiateTransaction(t *testing.T) { // Assert that expectations were met mockDataStore.AssertExpectations(t) - }) } - } func TestQuit(t *testing.T) { From 75459f852b8b5b8df43a2ccb1cf05db1e159c877 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 24 Oct 2024 15:12:57 +0300 Subject: [PATCH 29/38] Return the full balance string --- internal/handlers/ussd/menuhandler.go | 7 ++++++- services/registration/locale/swa/default.po | 4 +++- services/registration/main | 2 +- services/registration/main_swa | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 36d1ad5..ce56a58 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -650,6 +650,10 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( return res, fmt.Errorf("missing session") } + code := codeFromCtx(ctx) + l := gotext.NewLocale(translationDir, code) + l.AddDomain("default") + store := h.userdataStore publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) if err != nil { @@ -666,7 +670,8 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( } res.FlagReset = append(res.FlagReset, flag_api_error) balance := balanceResponse.Result.Balance - res.Content = balance + + res.Content = l.Get("Balance: %s\n", balance) return res, nil } diff --git a/services/registration/locale/swa/default.po b/services/registration/locale/swa/default.po index 5289dd7..0a3909b 100644 --- a/services/registration/locale/swa/default.po +++ b/services/registration/locale/swa/default.po @@ -7,6 +7,8 @@ msgstr "Ombi lako limetumwa. %s atapokea %s kutoka kwa %s." msgid "Thank you for using Sarafu. Goodbye!" msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" - msgid "For more help,please call: 0757628885" msgstr "Kwa usaidizi zaidi,piga: 0757628885" + +msgid "Balance: %s\n" +msgstr "Salio: %s\n" diff --git a/services/registration/main b/services/registration/main index bf15ea5..afae8c1 100644 --- a/services/registration/main +++ b/services/registration/main @@ -1 +1 @@ -Balance: {{.check_balance}} +{{.check_balance}} \ No newline at end of file diff --git a/services/registration/main_swa b/services/registration/main_swa index b72abf0..afae8c1 100644 --- a/services/registration/main_swa +++ b/services/registration/main_swa @@ -1 +1 @@ -Salio: {{.check_balance}} +{{.check_balance}} \ No newline at end of file From 39c0560abef514ca1fa49083444f8874146e6c4f Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 24 Oct 2024 15:21:48 +0300 Subject: [PATCH 30/38] Updated the test --- internal/handlers/ussd/menuhandler_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 38c468c..672a4fa 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -1625,7 +1625,6 @@ func TestValidateRecipient(t *testing.T) { } func TestCheckBalance(t *testing.T) { - sessionId := "session123" publicKey := "0X13242618721" fm, _ := NewFlagManager(flagsPath) @@ -1655,7 +1654,7 @@ func TestCheckBalance(t *testing.T) { }, }, { - name: "Test when checking a balance is a success", + name: "Test when checking a balance is a success", balanceResonse: &models.BalanceResponse{ Ok: true, Result: struct { @@ -1667,7 +1666,7 @@ func TestCheckBalance(t *testing.T) { }, }, expectedResult: resource.Result{ - Content: "0.003 CELO", + Content: "Balance: 0.003 CELO\n", FlagReset: []uint32{flag_api_error}, }, }, @@ -1700,10 +1699,8 @@ func TestCheckBalance(t *testing.T) { //Assert that the result set to content is what was expected assert.Equal(t, res, tt.expectedResult, "Result should contain flags set according to user input") - }) } - } func TestGetProfile(t *testing.T) { From abc01b7cee44a3bf39f2874b9a0f787b663c8de1 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 16:21:34 +0300 Subject: [PATCH 31/38] change to local setup endpoint --- config/config.go | 2 +- internal/handlers/server/accountservice.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index 43466c3..0ba88a4 100644 --- a/config/config.go +++ b/config/config.go @@ -11,7 +11,7 @@ var ( // LoadConfig initializes the configuration values after environment variables are loaded. func LoadConfig() { - CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "http://localhost:5003/api/v2/account/create") + CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "http://localhost:5003/api/v2/account/creates") TrackStatusURL = initializers.GetEnv("TRACK_STATUS_URL", "https://custodial.sarafu.africa/api/track/") BalanceURL = initializers.GetEnv("BALANCE_URL", "https://custodial.sarafu.africa/api/account/status/") TrackURL = initializers.GetEnv("TRACK_URL", "http://localhost:5003/api/v2/account/status") diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 6ae9630..9534520 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -14,9 +14,8 @@ import ( ) var ( - okResponse api.OKResponse - errResponse api.ErrResponse - EMPTY_RESPONSE = 0 + okResponse api.OKResponse + errResponse api.ErrResponse ) type AccountServiceInterface interface { @@ -93,7 +92,7 @@ func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, } return nil, errors.New(errResponse.Description) } - if len(okResponse.Result) == EMPTY_RESPONSE { + if len(okResponse.Result) == 0 { return nil, errors.New("Empty api result") } return &okResponse, nil @@ -150,6 +149,7 @@ func (as *AccountService) CreateAccount() (*api.OKResponse, error) { return nil, err } err = json.Unmarshal([]byte(body), &okResponse) + if err != nil { err := json.Unmarshal([]byte(body), &errResponse) if err != nil { @@ -157,7 +157,7 @@ func (as *AccountService) CreateAccount() (*api.OKResponse, error) { } return nil, errors.New(errResponse.Description) } - if len(okResponse.Result) == EMPTY_RESPONSE { + if len(okResponse.Result) == 0 { return nil, errors.New("Empty api result") } return &okResponse, nil From 2b34a0900c3640a994a3f75b2927382018b8c932 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 16:35:53 +0300 Subject: [PATCH 32/38] check for status code and unmarshal on errResponse --- internal/handlers/server/accountservice.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index 9534520..27896e7 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -84,14 +84,17 @@ func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, errResponse.Description = err.Error() return nil, err } - err = json.Unmarshal([]byte(body), &okResponse) - if err != nil { + if resp.StatusCode >= http.StatusBadRequest { err := json.Unmarshal([]byte(body), &errResponse) if err != nil { return nil, err } return nil, errors.New(errResponse.Description) } + err = json.Unmarshal([]byte(body), &okResponse) + if err != nil { + return nil, err + } if len(okResponse.Result) == 0 { return nil, errors.New("Empty api result") } @@ -148,15 +151,17 @@ func (as *AccountService) CreateAccount() (*api.OKResponse, error) { if err != nil { return nil, err } - err = json.Unmarshal([]byte(body), &okResponse) - - if err != nil { + if resp.StatusCode >= http.StatusBadRequest { err := json.Unmarshal([]byte(body), &errResponse) if err != nil { return nil, err } return nil, errors.New(errResponse.Description) } + err = json.Unmarshal([]byte(body), &okResponse) + if err != nil { + return nil, err + } if len(okResponse.Result) == 0 { return nil, errors.New("Empty api result") } From c796bbdcfcc535cd05fc14d552c0d02dea27a996 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 16:36:09 +0300 Subject: [PATCH 33/38] correct create endpoint --- config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 0ba88a4..43466c3 100644 --- a/config/config.go +++ b/config/config.go @@ -11,7 +11,7 @@ var ( // LoadConfig initializes the configuration values after environment variables are loaded. func LoadConfig() { - CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "http://localhost:5003/api/v2/account/creates") + CreateAccountURL = initializers.GetEnv("CREATE_ACCOUNT_URL", "http://localhost:5003/api/v2/account/create") TrackStatusURL = initializers.GetEnv("TRACK_STATUS_URL", "https://custodial.sarafu.africa/api/track/") BalanceURL = initializers.GetEnv("BALANCE_URL", "https://custodial.sarafu.africa/api/account/status/") TrackURL = initializers.GetEnv("TRACK_URL", "http://localhost:5003/api/v2/account/status") From 69a4530269f35d428aff1cd66ea41464ba7b257e Mon Sep 17 00:00:00 2001 From: carlos Date: Thu, 24 Oct 2024 15:41:47 +0200 Subject: [PATCH 34/38] Delete services/registration/locale/swa/default.mo remove dev file --- services/registration/locale/swa/default.mo | Bin 67 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 services/registration/locale/swa/default.mo diff --git a/services/registration/locale/swa/default.mo b/services/registration/locale/swa/default.mo deleted file mode 100644 index e0ceea9b640e4a5c6a1f3b961292aa843b9d620c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ycmca7#4?ou2pEA_28dOFm>Gz5fS47CEr6H>i0yzF20&^(Qgd?h89efH5*YxXiUslj From cff50538fa60feddda030b7535a7681cd89b1044 Mon Sep 17 00:00:00 2001 From: carlos Date: Thu, 24 Oct 2024 15:45:29 +0200 Subject: [PATCH 35/38] Delete cover.out delete cover.out --- cover.out | 738 ------------------------------------------------------ 1 file changed, 738 deletions(-) delete mode 100644 cover.out diff --git a/cover.out b/cover.out deleted file mode 100644 index 8f9f054..0000000 --- a/cover.out +++ /dev/null @@ -1,738 +0,0 @@ -mode: set -git.grassecon.net/urdt/ussd/cmd/main.go:22.13,50.16 18 0 -git.grassecon.net/urdt/ussd/cmd/main.go:50.16,53.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:55.2,56.16 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:56.16,59.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:61.2,62.16 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:62.16,65.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:67.2,68.16 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:68.16,71.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:73.2,74.9 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:74.9,77.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:79.2,83.16 4 0 -git.grassecon.net/urdt/ussd/cmd/main.go:83.16,86.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:88.2,89.16 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:89.16,92.3 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:94.2,96.17 3 0 -git.grassecon.net/urdt/ussd/cmd/main.go:96.17,98.3 1 0 -git.grassecon.net/urdt/ussd/cmd/main.go:100.2,101.16 2 0 -git.grassecon.net/urdt/ussd/cmd/main.go:101.16,104.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:30.66,32.2 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:34.62,36.2 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:38.13,66.17 20 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:66.17,68.3 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:70.2,72.16 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:72.16,75.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:77.2,78.16 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:78.16,81.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:83.2,84.16 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:84.16,87.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:88.2,91.9 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:91.9,93.3 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:95.2,99.16 4 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:99.16,102.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:104.2,105.16 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:105.16,108.3 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:109.2,126.12 10 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:126.12,127.10 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:128.19,128.19 0 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:129.20,129.20 0 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:131.3,131.16 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:134.2,134.11 1 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:134.11,136.17 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:136.17,140.4 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:141.3,142.17 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:142.17,146.4 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:147.3,148.17 2 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:148.17,152.4 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:153.3,155.17 3 0 -git.grassecon.net/urdt/ussd/cmd/async/main.go:155.17,159.4 3 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:31.66,33.9 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:33.9,35.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:36.2,36.40 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:36.40,38.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:40.2,41.23 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:41.23,43.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:45.2,45.25 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:48.62,50.9 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:50.9,52.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:53.2,53.40 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:53.40,55.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:57.2,60.21 3 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:60.21,62.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:64.2,64.41 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:67.13,93.17 18 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:93.17,95.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:97.2,99.16 3 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:99.16,102.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:104.2,105.16 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:105.16,108.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:110.2,111.16 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:111.16,114.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:115.2,118.9 3 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:118.9,120.3 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:122.2,125.16 3 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:125.16,128.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:130.2,131.16 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:131.16,134.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:136.2,137.16 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:137.16,140.3 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:141.2,156.12 11 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:156.12,157.10 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:158.19,158.19 0 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:159.20,159.20 0 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:161.3,161.18 1 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:163.2,164.16 2 0 -git.grassecon.net/urdt/ussd/cmd/africastalking/main.go:164.16,166.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:32.102,34.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:34.16,36.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:37.2,40.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:40.16,42.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:44.2,46.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:46.16,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:52.2,52.24 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:58.91,61.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:61.16,63.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:64.2,67.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:67.16,69.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:71.2,73.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:73.16,75.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:78.2,78.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:87.76,89.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:89.16,91.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:92.2,95.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:95.16,97.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:99.2,101.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:101.16,103.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:105.2,105.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:21.159,29.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:31.40,33.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:33.16,35.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:38.117,42.2 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:44.81,52.16 6 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:52.16,55.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:57.2,60.9 4 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:60.9,63.18 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:63.18,65.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:66.3,66.28 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:68.2,69.28 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:69.28,71.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:72.2,75.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:75.16,78.18 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:78.18,80.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:81.3,81.18 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:84.2,85.17 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:88.81,92.2 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:94.79,97.2 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:99.55,101.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:103.62,105.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:16.64,19.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:19.16,21.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:22.2,22.24 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:34.156,36.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:36.16,38.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:39.2,44.8 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:47.68,49.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:51.56,53.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:55.69,57.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:57.16,59.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:60.2,98.26 38 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:102.66,106.2 3 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:28.13,54.17 18 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:54.17,56.3 1 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:58.2,60.16 3 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:60.16,63.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:65.2,66.16 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:66.16,69.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:71.2,72.16 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:72.16,75.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:76.2,79.9 3 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:79.9,81.3 1 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:83.2,86.16 3 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:86.16,89.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:91.2,92.16 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:92.16,95.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:97.2,98.16 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:98.16,101.3 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:102.2,117.12 11 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:117.12,118.10 1 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:119.19,119.19 0 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:120.20,120.20 0 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:122.3,122.18 1 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:124.2,125.16 2 0 -git.grassecon.net/urdt/ussd/cmd/http/main.go:125.16,127.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:32.102,34.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:34.16,36.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:37.2,40.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:40.16,42.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:44.2,46.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:46.16,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:52.2,52.24 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:58.91,61.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:61.16,63.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:64.2,67.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:67.16,69.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:71.2,73.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:73.16,75.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:78.2,78.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:87.76,89.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:89.16,91.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:92.2,95.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:95.16,97.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:99.2,101.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:101.16,103.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:105.2,105.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:38.59,41.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:41.16,43.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:45.2,47.8 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:51.62,53.2 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:64.84,65.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:65.26,67.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:68.2,76.15 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:83.34,86.2 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:88.67,89.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:89.17,90.33 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:92.2,93.10 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:96.97,99.17 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:99.17,102.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:103.2,105.32 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:105.32,108.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:109.2,113.15 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:117.104,123.32 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:123.32,125.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:126.2,130.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:130.16,132.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:133.2,135.17 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:138.108,146.31 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:146.31,149.17 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:149.17,151.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:153.2,155.12 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:162.106,166.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:166.9,168.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:169.2,171.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:171.16,172.25 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:172.25,175.18 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:175.18,177.5 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:180.2,180.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:184.100,189.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:189.9,191.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:193.2,197.29 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:197.29,200.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:202.2,205.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:205.16,207.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:208.2,208.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:211.105,214.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:214.9,216.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:217.2,220.26 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:220.26,222.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:222.8,224.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:226.2,226.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:229.109,234.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:234.9,236.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:237.2,242.29 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:242.29,245.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:246.2,248.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:248.16,250.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:251.2,251.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:254.109,257.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:257.9,259.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:260.2,264.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:264.16,266.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:267.2,267.38 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:267.38,269.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:269.8,271.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:272.2,273.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:273.16,275.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:276.2,276.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:282.102,290.9 6 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:290.9,292.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:293.2,295.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:295.16,297.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:299.2,299.36 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:299.36,303.3 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:303.8,305.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:307.2,307.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:311.46,313.34 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:313.34,316.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:317.2,317.13 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:321.106,325.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:325.9,327.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:328.2,328.20 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:328.20,332.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:332.17,334.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:337.2,337.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:341.107,345.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:345.9,347.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:349.2,349.20 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:349.20,353.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:353.17,355.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:356.8,358.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:360.2,360.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:364.100,368.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:368.9,370.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:372.2,372.21 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:372.21,376.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:376.17,378.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:381.2,381.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:385.105,389.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:389.9,391.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:393.2,393.20 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:393.20,397.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:397.17,399.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:402.2,402.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:406.103,411.9 5 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:411.9,413.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:415.2,418.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:418.16,420.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:422.2,422.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:426.106,430.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:430.9,432.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:434.2,434.20 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:434.20,438.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:438.17,440.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:443.2,443.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:447.109,454.2 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:457.115,464.2 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:467.108,471.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:471.9,473.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:475.2,480.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:485.102,490.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:490.9,492.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:494.2,500.16 6 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:500.16,502.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:503.2,503.21 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:503.21,504.37 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:504.37,505.54 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:505.54,508.5 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:508.10,511.5 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:512.9,516.4 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:517.8,519.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:520.2,520.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:524.110,529.2 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:533.111,541.9 6 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:541.9,543.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:544.2,546.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:546.16,548.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:550.2,551.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:551.16,554.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:555.2,555.23 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:555.23,558.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:559.2,563.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:563.16,565.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:566.2,566.58 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:566.58,569.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:569.8,572.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:573.2,573.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:577.97,589.2 8 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:592.105,604.2 8 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:607.102,615.16 6 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:615.16,619.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:621.2,621.20 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:621.20,623.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:623.8,625.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:627.2,627.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:631.110,638.2 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:642.105,649.9 5 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:649.9,651.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:653.2,655.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:655.16,657.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:659.2,660.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:660.16,662.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:663.2,663.25 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:663.25,666.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:667.2,671.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:674.115,679.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:679.9,681.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:682.2,687.16 5 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:687.16,689.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:691.2,692.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:692.16,694.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:695.2,695.25 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:695.25,698.3 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:699.2,702.21 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:703.12,704.59 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:705.19,706.69 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:707.10,708.8 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:710.2,710.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:714.110,719.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:719.9,721.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:723.2,727.22 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:727.22,729.25 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:729.25,734.4 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:735.3,737.17 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:737.17,739.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:742.2,742.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:747.109,752.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:752.9,754.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:756.2,760.16 5 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:760.16,762.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:764.2,765.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:765.16,767.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:769.2,771.17 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:775.115,780.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:780.9,782.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:784.2,787.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:787.16,789.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:791.2,793.17 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:798.102,803.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:803.9,805.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:806.2,810.16 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:810.16,812.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:813.2,817.17 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:822.107,827.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:827.9,829.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:831.2,841.16 7 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:841.16,843.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:844.2,848.28 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:848.28,850.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:851.2,852.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:852.16,854.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:857.2,859.22 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:859.22,863.3 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:865.2,866.16 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:866.16,870.3 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:872.2,872.32 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:872.32,876.3 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:878.2,880.16 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:880.16,882.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:884.2,884.17 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:888.105,892.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:892.9,894.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:895.2,900.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:904.102,908.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:908.9,910.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:912.2,917.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:921.102,925.9 3 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:925.9,927.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:928.2,933.17 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:938.108,942.9 4 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:942.9,944.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:946.2,954.16 7 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:954.16,956.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:957.2,958.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:958.16,960.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:961.2,963.17 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:968.112,972.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:972.9,974.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:976.2,991.16 10 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:991.16,993.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:995.2,996.17 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:999.107,1003.9 4 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1003.9,1005.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1006.2,1007.9 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1007.9,1009.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1010.2,1011.19 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1011.19,1013.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1013.8,1015.3 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1018.2,1018.60 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1018.60,1019.33 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1019.33,1021.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1022.3,1022.23 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1024.2,1035.32 9 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1035.32,1036.32 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1036.32,1038.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1038.9,1040.4 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1044.2,1045.25 2 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1045.25,1046.51 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1046.51,1048.4 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1048.9,1050.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1052.2,1052.23 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1053.13,1057.4 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1058.13,1062.4 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1063.10,1067.4 1 1 -git.grassecon.net/urdt/ussd/internal/handlers/ussd/menuhandler.go:1070.2,1070.17 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:14.42,16.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:18.33,21.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:23.30,26.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:28.55,30.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:32.45,35.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:37.75,40.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:42.47,44.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:46.68,49.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:51.71,54.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:56.32,59.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:13.79,16.2 2 1 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:18.94,21.2 2 1 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:23.105,26.2 2 1 -git.grassecon.net/urdt/ussd/internal/mocks/userdbmock.go:16.113,19.2 2 1 -git.grassecon.net/urdt/ussd/internal/mocks/userdbmock.go:21.118,24.2 2 1 -git.grassecon.net/urdt/ussd/internal/utils/age.go:7.51,13.29 6 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:13.29,15.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:16.2,18.30 3 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:18.30,20.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:21.2,21.12 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:32.39,35.2 2 1 -git.grassecon.net/urdt/ussd/internal/utils/db.go:28.37,32.2 3 0 -git.grassecon.net/urdt/ussd/internal/utils/db.go:34.47,37.2 2 0 -git.grassecon.net/urdt/ussd/internal/utils/isocode.go:9.38,11.2 1 1 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:20.107,25.2 4 0 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:27.112,32.2 4 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:14.42,16.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:18.33,21.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:23.30,26.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:28.55,30.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:32.45,35.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:37.75,40.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:42.47,44.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:46.68,49.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:51.71,54.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/dbmock.go:56.32,59.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:13.79,16.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:18.94,21.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/servicemock.go:23.105,26.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/userdbmock.go:16.113,19.2 2 0 -git.grassecon.net/urdt/ussd/internal/mocks/userdbmock.go:21.118,24.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:20.38,21.16 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:21.16,23.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:24.2,24.24 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:27.76,30.8 3 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:30.8,33.3 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:34.2,36.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:36.16,38.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:39.2,42.12 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:45.35,46.19 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:46.19,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:51.35,52.19 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:52.19,54.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:55.2,56.14 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:59.46,62.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:64.54,67.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:69.57,72.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:74.37,79.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:81.40,86.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:88.63,93.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:95.80,100.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:102.78,107.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:109.39,115.2 5 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:27.86,36.2 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:38.73,40.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:42.79,44.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:46.47,48.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:35.82,40.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:42.93,46.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:46.16,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:49.2,51.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:54.81,58.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:58.16,60.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:61.2,61.30 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:64.91,67.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:67.16,69.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:70.2,71.17 2 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:74.81,75.26 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:75.26,76.44 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:78.2,81.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:81.16,83.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:84.2,84.27 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:87.51,89.16 2 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:89.16,91.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:92.2,92.12 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:95.45,99.47 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:99.47,101.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:102.2,102.12 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:7.51,13.29 6 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:13.29,15.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:16.2,18.30 3 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:18.30,20.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:21.2,21.12 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:32.39,35.2 2 0 -git.grassecon.net/urdt/ussd/internal/utils/db.go:28.37,32.2 3 0 -git.grassecon.net/urdt/ussd/internal/utils/db.go:34.47,37.2 2 0 -git.grassecon.net/urdt/ussd/internal/utils/isocode.go:9.38,11.2 1 0 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:20.107,25.2 4 0 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:27.112,32.2 4 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:21.159,29.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:31.40,33.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:33.16,35.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:38.117,42.2 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:44.81,52.16 6 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:52.16,55.3 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:57.2,60.9 4 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:60.9,63.18 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:63.18,65.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:66.3,66.28 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:68.2,69.28 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:69.28,71.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:72.2,75.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:75.16,78.18 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:78.18,80.4 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:81.3,81.18 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:84.2,85.17 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:88.81,92.2 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:94.79,97.2 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:99.55,101.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/base.go:103.62,105.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:16.64,19.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:19.16,21.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:22.2,22.24 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:34.156,36.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:36.16,38.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:39.2,44.8 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:47.68,49.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:51.56,53.2 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:55.69,57.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:57.16,59.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:60.2,98.26 38 0 -git.grassecon.net/urdt/ussd/internal/handlers/handlerservice.go:102.66,106.2 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:32.102,34.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:34.16,36.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:37.2,40.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:40.16,42.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:44.2,46.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:46.16,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:52.2,52.24 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:58.91,61.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:61.16,63.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:64.2,67.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:67.16,69.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:71.2,73.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:73.16,75.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:78.2,78.26 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:87.76,89.16 2 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:89.16,91.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:92.2,95.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:95.16,97.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:99.2,101.16 3 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:101.16,103.3 1 0 -git.grassecon.net/urdt/ussd/internal/handlers/server/accountservice.go:105.2,105.26 1 0 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:14.71,18.2 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:20.82,32.16 7 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:32.16,36.3 3 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:37.2,39.16 3 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:39.16,43.3 3 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:45.2,46.13 2 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:47.11,48.13 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:49.99,50.13 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:51.10,52.13 1 0 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:55.2,55.17 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:55.17,58.3 2 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:60.2,63.16 4 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:63.16,66.3 2 0 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:68.2,69.16 2 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:69.16,72.3 2 0 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:75.99,79.18 3 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:79.18,81.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:81.8,83.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:85.2,86.16 2 1 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:86.16,88.3 1 0 -git.grassecon.net/urdt/ussd/internal/http/at_session_handler.go:90.2,91.17 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:21.69,23.9 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:23.9,25.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:26.2,27.13 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:27.13,29.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:30.2,30.15 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:33.65,35.9 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:35.9,37.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:38.2,40.16 3 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:40.16,42.3 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:43.2,43.15 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:50.66,54.2 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:56.80,61.16 5 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:61.16,64.3 2 0 -git.grassecon.net/urdt/ussd/internal/http/server.go:65.2,65.8 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:68.77,81.16 8 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:81.16,84.3 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:85.2,87.16 3 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:87.16,91.3 3 0 -git.grassecon.net/urdt/ussd/internal/http/server.go:93.2,94.13 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:95.27,96.13 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:97.30,98.13 1 0 -git.grassecon.net/urdt/ussd/internal/http/server.go:99.30,100.13 1 0 -git.grassecon.net/urdt/ussd/internal/http/server.go:101.10,102.13 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:105.2,105.17 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:105.17,108.3 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:110.2,114.16 5 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:114.16,117.3 2 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:118.2,118.17 1 1 -git.grassecon.net/urdt/ussd/internal/http/server.go:118.17,121.3 2 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:16.62,18.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:20.76,22.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:24.75,26.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:28.37,30.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:21.100,23.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:25.56,27.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:29.118,31.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:33.98,35.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:37.97,39.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:41.41,43.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:45.72,47.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requestparsermock.go:9.66,11.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requestparsermock.go:13.62,15.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:11.57,13.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:15.63,19.2 3 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:21.43,23.2 1 1 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:25.51,25.52 0 1 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:20.38,21.16 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:21.16,23.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:24.2,24.24 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:27.76,30.8 3 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:30.8,33.3 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:34.2,36.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:36.16,38.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:39.2,42.12 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:45.35,46.19 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:46.19,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:51.35,52.19 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:52.19,54.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:55.2,56.14 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:59.46,62.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:64.54,67.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:69.57,72.2 2 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:74.37,79.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:81.40,86.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:88.63,93.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:95.80,100.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:102.78,107.2 4 0 -git.grassecon.net/urdt/ussd/internal/storage/gdbm.go:109.39,115.2 5 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:27.86,36.2 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:38.73,40.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:42.79,44.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storage.go:46.47,48.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:35.82,40.2 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:42.93,46.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:46.16,48.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:49.2,51.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:54.81,58.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:58.16,60.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:61.2,61.30 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:64.91,67.16 3 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:67.16,69.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:70.2,71.17 2 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:74.81,75.26 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:75.26,76.44 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:78.2,81.16 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:81.16,83.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:84.2,84.27 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:87.51,89.16 2 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:89.16,91.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:92.2,92.12 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:95.45,99.47 4 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:99.47,101.3 1 0 -git.grassecon.net/urdt/ussd/internal/storage/storageservice.go:102.2,102.12 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:7.51,13.29 6 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:13.29,15.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:16.2,18.30 3 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:18.30,20.3 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:21.2,21.12 1 0 -git.grassecon.net/urdt/ussd/internal/utils/age.go:32.39,35.2 2 0 -git.grassecon.net/urdt/ussd/internal/utils/db.go:28.37,32.2 3 0 -git.grassecon.net/urdt/ussd/internal/utils/db.go:34.47,37.2 2 0 -git.grassecon.net/urdt/ussd/internal/utils/isocode.go:9.38,11.2 1 0 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:20.107,25.2 4 0 -git.grassecon.net/urdt/ussd/internal/utils/userStore.go:27.112,32.2 4 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:16.62,18.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:20.76,22.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:24.75,26.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/enginemock.go:28.37,30.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:21.100,23.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:25.56,27.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:29.118,31.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:33.98,35.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:37.97,39.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:41.41,43.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requesthandlermock.go:45.72,47.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requestparsermock.go:9.66,11.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/requestparsermock.go:13.62,15.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:11.57,13.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:15.63,19.2 3 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:21.43,23.2 1 0 -git.grassecon.net/urdt/ussd/internal/mocks/httpmocks/writermock.go:25.51,25.52 0 0 From 5c75e35fe0e8ff81f251df52965af5063090addc Mon Sep 17 00:00:00 2001 From: carlos Date: Thu, 24 Oct 2024 15:45:52 +0200 Subject: [PATCH 36/38] Delete coverage.html delete cover.html --- coverage.html | 2961 ------------------------------------------------- 1 file changed, 2961 deletions(-) delete mode 100644 coverage.html diff --git a/coverage.html b/coverage.html deleted file mode 100644 index a448bc0..0000000 --- a/coverage.html +++ /dev/null @@ -1,2961 +0,0 @@ - - - - - - africastalking: Go Coverage Report - - - -
- -
- not tracked - - not covered - covered - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - From 383f074cae99a2a72f17a926f3bb3b823055b469 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 17:32:08 +0300 Subject: [PATCH 37/38] update method signatures --- internal/handlers/server/accountservice.go | 28 +++++++--------------- internal/handlers/ussd/menuhandler.go | 10 ++++---- internal/mocks/servicemock.go | 6 ++--- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/internal/handlers/server/accountservice.go b/internal/handlers/server/accountservice.go index d449f2f..1b5272a 100644 --- a/internal/handlers/server/accountservice.go +++ b/internal/handlers/server/accountservice.go @@ -20,10 +20,10 @@ var ( ) type AccountServiceInterface interface { - CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) + CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) CreateAccount(ctx context.Context) (*api.OKResponse, error) - CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) - TrackAccountStatus(publicKey string) (*api.OKResponse, error) + CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) + TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) } type AccountService struct { @@ -41,7 +41,7 @@ type TestAccountService struct { // - 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. // If no error occurs, this will be nil -func (as *AccountService) CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) { +func (as *AccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) { resp, err := http.Get(config.BalanceURL + trackingId) if err != nil { return nil, err @@ -62,7 +62,7 @@ func (as *AccountService) CheckAccountStatus(trackingId string, ctx context.Cont } -func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { +func (as *AccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) { var err error // Construct the URL with the path parameter url := fmt.Sprintf("%s/%s", config.TrackURL, publicKey) @@ -106,7 +106,7 @@ func (as *AccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint. // Parameters: // - publicKey: The public key associated with the account whose balance needs to be checked. -func (as *AccountService) CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) { +func (as *AccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) { resp, err := http.Get(config.BalanceURL + publicKey) if err != nil { return nil, err @@ -178,7 +178,7 @@ func (tas *TestAccountService) CreateAccount(ctx context.Context) (*api.OKRespon } -func (tas *TestAccountService) CheckBalance(publicKey string, ctx context.Context) (*models.BalanceResponse, error) { +func (tas *TestAccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) { balanceResponse := &models.BalanceResponse{ Ok: true, Result: struct { @@ -192,7 +192,7 @@ func (tas *TestAccountService) CheckBalance(publicKey string, ctx context.Contex return balanceResponse, nil } -func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { +func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) { return &api.OKResponse{ Ok: true, Description: "Account creation succeeded", @@ -202,17 +202,7 @@ func (tas *TestAccountService) TrackAccountStatus(publicKey string) (*api.OKResp }, nil } -func (tas *TestAccountService) TrackAccountStatus(publicKey ,) (*api.OKResponse, error) { - return &api.OKResponse{ - Ok: true, - Description: "Account creation succeeded", - Result: map[string]any{ - "active": true, - }, - }, nil -} - -func (tas *TestAccountService) CheckAccountStatus(trackingId string, ctx context.Context) (*models.TrackStatusResponse, error) { +func (tas *TestAccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) { trackResponse := &models.TrackStatusResponse{ Ok: true, Result: struct { diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 4c03d7b..cb9f8fd 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -544,7 +544,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b if err != nil { return res, err } - okResponse, err = h.accountService.TrackAccountStatus(string(publicKey),ctx) + okResponse, err = h.accountService.TrackAccountStatus(ctx, string(publicKey)) if err != nil { res.FlagSet = append(res.FlagSet, flag_api_error) return res, err @@ -651,7 +651,7 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( return res, err } - balanceResponse, err := h.accountService.CheckBalance(string(publicKey),ctx) + balanceResponse, err := h.accountService.CheckBalance(ctx, string(publicKey)) if err != nil { return res, nil } @@ -684,7 +684,7 @@ func (h *Handlers) FetchCustodialBalances(ctx context.Context, sym string, input return res, err } - balanceResponse, err := h.accountService.CheckBalance(string(publicKey),ctx) + balanceResponse, err := h.accountService.CheckBalance(ctx, string(publicKey)) if err != nil { return res, nil } @@ -802,7 +802,7 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res store := h.userdataStore publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) - balanceResp, err := h.accountService.CheckBalance(string(publicKey),ctx) + balanceResp, err := h.accountService.CheckBalance(ctx, string(publicKey)) if err != nil { return res, nil } @@ -832,7 +832,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) amountStr := string(input) - balanceRes, err := h.accountService.CheckBalance(string(publicKey),ctx) + balanceRes, err := h.accountService.CheckBalance(ctx, string(publicKey)) balanceStr := balanceRes.Result.Balance if !balanceRes.Ok { diff --git a/internal/mocks/servicemock.go b/internal/mocks/servicemock.go index b7d44e7..9aab44d 100644 --- a/internal/mocks/servicemock.go +++ b/internal/mocks/servicemock.go @@ -18,17 +18,17 @@ func (m *MockAccountService) CreateAccount(ctx context.Context) (*api.OKResponse return args.Get(0).(*api.OKResponse), args.Error(1) } -func (m *MockAccountService) CheckBalance(publicKey string,ctx context.Context) (*models.BalanceResponse, error) { +func (m *MockAccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) { args := m.Called(publicKey) return args.Get(0).(*models.BalanceResponse), args.Error(1) } -func (m *MockAccountService) CheckAccountStatus(trackingId string,ctx context.Context) (*models.TrackStatusResponse, error) { +func (m *MockAccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) { args := m.Called(trackingId) return args.Get(0).(*models.TrackStatusResponse), args.Error(1) } -func (m *MockAccountService) TrackAccountStatus(publicKey string) (*api.OKResponse, error) { +func (m *MockAccountService) TrackAccountStatus(ctx context.Context,publicKey string) (*api.OKResponse, error) { args := m.Called(publicKey) return args.Get(0).(*api.OKResponse), args.Error(1) } From 6e7b46666e13525065d7005b9918bb3eb2eb0e03 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 24 Oct 2024 17:34:42 +0300 Subject: [PATCH 38/38] ensure mod match with master --- go.mod | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 76aaf74..7112503 100644 --- a/go.mod +++ b/go.mod @@ -12,13 +12,7 @@ require ( ) -require ( - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.0 // indirect - github.com/jackc/puddle/v2 v2.2.1 // indirect - github.com/joho/godotenv v1.5.1 - github.com/kr/text v0.2.0 +require github.com/joho/godotenv v1.5.1 require ( github.com/grassrootseconomics/eth-custodial v1.3.0-beta @@ -32,11 +26,6 @@ require ( golang.org/x/sync v0.8.0 // indirect golang.org/x/text v0.18.0 // indirect ) - github.com/rogpeppe/go-internal v1.13.1 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.18.0 // indirect -) require ( github.com/alecthomas/participle/v2 v2.0.0 // indirect @@ -55,3 +44,5 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) + +