Compare commits
9 Commits
802c3f92df
...
64e182fd44
Author | SHA1 | Date | |
---|---|---|---|
64e182fd44 | |||
22d076ea50 | |||
edcbf9979d | |||
a1f31efd19 | |||
20cf7bdb44 | |||
08fcb7cdba | |||
7b5d82c7bf | |||
a64291bb31 | |||
195f003d69 |
2
go.mod
2
go.mod
@ -1,3 +1,5 @@
|
|||||||
module git.grassecon.net/urdt/ussd
|
module git.grassecon.net/urdt/ussd
|
||||||
|
|
||||||
go 1.22.6
|
go 1.22.6
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.9.0 // indirect
|
||||||
|
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
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=
|
86
internal/handlers/server/accountservice.go
Normal file
86
internal/handlers/server/accountservice.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.grassecon.net/urdt/ussd/config"
|
||||||
|
"git.grassecon.net/urdt/ussd/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountServiceInterface interface {
|
||||||
|
CheckBalance(publicKey string) (string, error)
|
||||||
|
CreateAccount() (*models.AccountResponse, error)
|
||||||
|
CheckAccountStatus(trackingId string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountService struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (as *AccountService) CheckAccountStatus(trackingId string) (string, error) {
|
||||||
|
resp, err := http.Get(config.TrackStatusURL + trackingId)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var trackResp models.TrackStatusResponse
|
||||||
|
err = json.Unmarshal(body, &trackResp)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
status := trackResp.Result.Transaction.Status
|
||||||
|
|
||||||
|
return status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (as *AccountService) CheckBalance(publicKey string) (string, error) {
|
||||||
|
|
||||||
|
resp, err := http.Get(config.BalanceURL + publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return "0.0", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "0.0", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var balanceResp models.BalanceResponse
|
||||||
|
err = json.Unmarshal(body, &balanceResp)
|
||||||
|
if err != nil {
|
||||||
|
return "0.0", err
|
||||||
|
}
|
||||||
|
|
||||||
|
balance := balanceResp.Result.Balance
|
||||||
|
return balance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
|
||||||
|
resp, err := http.Post(config.CreateAccountURL, "application/json", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var accountResp models.AccountResponse
|
||||||
|
err = json.Unmarshal(body, &accountResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &accountResp, nil
|
||||||
|
}
|
@ -42,8 +42,9 @@ func (s *ServerAccountCreator) CreateAccount() (*models.AccountResponse, error)
|
|||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
fs *FSData
|
fs *FSData
|
||||||
accountFileHandler *utils.AccountFileHandler
|
|
||||||
accountCreator AccountCreator
|
accountCreator AccountCreator
|
||||||
|
accountFileHandler utils.AccountFileHandlerInterface
|
||||||
|
accountService server.AccountServiceInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandlers(path string, st *state.State) *Handlers {
|
func NewHandlers(path string, st *state.State) *Handlers {
|
||||||
@ -54,6 +55,7 @@ func NewHandlers(path string, st *state.State) *Handlers {
|
|||||||
},
|
},
|
||||||
accountFileHandler: utils.NewAccountFileHandler(path + "_data"),
|
accountFileHandler: utils.NewAccountFileHandler(path + "_data"),
|
||||||
accountCreator: &ServerAccountCreator{},
|
accountCreator: &ServerAccountCreator{},
|
||||||
|
accountService: &server.AccountService{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +96,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accountResp, err := h.accountCreator.CreateAccount()
|
accountResp, err := h.accountService.CreateAccount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATION_FAILED)
|
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATION_FAILED)
|
||||||
return res, err
|
return res, err
|
||||||
|
@ -8,8 +8,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
|
||||||
"git.grassecon.net/urdt/ussd/internal/models"
|
"git.grassecon.net/urdt/ussd/internal/models"
|
||||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
"git.grassecon.net/urdt/ussd/internal/utils"
|
||||||
|
"github.com/alecthomas/assert/v2"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockAccountCreator implements AccountCreator for testing
|
// MockAccountCreator implements AccountCreator for testing
|
||||||
@ -170,6 +173,51 @@ func TestCreateAccount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestCreateAccount_Success(t *testing.T) {
|
||||||
|
mockAccountFileHandler := new(mocks.MockAccountFileHandler)
|
||||||
|
mockCreateAccountService := new(mocks.MockAccountService)
|
||||||
|
|
||||||
|
mockAccountFileHandler.On("EnsureFileExists").Return(nil)
|
||||||
|
|
||||||
|
// Mock that no account data exists
|
||||||
|
mockAccountFileHandler.On("ReadAccountData").Return(nil, nil)
|
||||||
|
|
||||||
|
// Define expected account response after api call
|
||||||
|
expectedAccountResp := &models.AccountResponse{
|
||||||
|
Ok: true,
|
||||||
|
Result: struct {
|
||||||
|
CustodialId json.Number `json:"custodialId"`
|
||||||
|
PublicKey string `json:"publicKey"`
|
||||||
|
TrackingId string `json:"trackingId"`
|
||||||
|
}{
|
||||||
|
CustodialId: "12",
|
||||||
|
PublicKey: "some-public-key",
|
||||||
|
TrackingId: "some-tracking-id",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
|
||||||
|
|
||||||
|
// Mock WriteAccountData to not error
|
||||||
|
mockAccountFileHandler.On("WriteAccountData", mock.Anything).Return(nil)
|
||||||
|
|
||||||
|
handlers := &Handlers{
|
||||||
|
accountService: mockCreateAccountService,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
actualResponse, err := handlers.accountService.CreateAccount()
|
||||||
|
|
||||||
|
// Assert results
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t,expectedAccountResp.Ok,true)
|
||||||
|
assert.Equal(t,expectedAccountResp,actualResponse)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestSavePin(t *testing.T) {
|
func TestSavePin(t *testing.T) {
|
||||||
// Setup
|
// Setup
|
||||||
tempDir, err := os.MkdirTemp("", "test_save_pin")
|
tempDir, err := os.MkdirTemp("", "test_save_pin")
|
||||||
|
44
internal/handlers/ussd/mocks/mocks.go
Normal file
44
internal/handlers/ussd/mocks/mocks.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.grassecon.net/urdt/ussd/internal/models"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockAccountFileHandler struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountFileHandler) EnsureFileExists() error {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountFileHandler) ReadAccountData() (map[string]string, error) {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(map[string]string), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountFileHandler) WriteAccountData(data map[string]string) error {
|
||||||
|
args := m.Called(data)
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockAccountService struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(*models.AccountResponse), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountService) CheckAccountStatus(TrackingId string) (string, error) {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(string), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockAccountService) CheckBalance(PublicKey string) (string, error) {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(string), args.Error(1)
|
||||||
|
}
|
50
internal/utils/filehandler.go
Normal file
50
internal/utils/filehandler.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type AccountFileHandlerInterface interface {
|
||||||
|
EnsureFileExists() error
|
||||||
|
ReadAccountData() (map[string]string, error)
|
||||||
|
WriteAccountData(data map[string]string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type AccountFileHandler2 struct {
|
||||||
|
FilePath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the methods required by AccountFileHandlerInterface.
|
||||||
|
func (afh *AccountFileHandler2) EnsureFileExists() error {
|
||||||
|
f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return f.Close()
|
||||||
|
}
|
||||||
|
func (afh *AccountFileHandler2) ReadAccountData() (map[string]string, error) {
|
||||||
|
jsonData, err := os.ReadFile(afh.FilePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var accountData map[string]string
|
||||||
|
err = json.Unmarshal(jsonData, &accountData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountData, nil
|
||||||
|
}
|
||||||
|
func (afh *AccountFileHandler2) WriteAccountData(data map[string]string) error {
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.WriteFile(afh.FilePath, jsonData, 0644)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user