Compare commits
2 Commits
lash/rever
...
address-se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c3d90c374
|
||
|
|
4011bc18b6
|
@@ -1,18 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func NormalizeHex(s string) (string, error) {
|
||||
if len(s) >= 2 {
|
||||
if s[:2] == "0x" {
|
||||
s = s[2:]
|
||||
}
|
||||
}
|
||||
r, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(r), nil
|
||||
}
|
||||
9
go.mod
9
go.mod
@@ -7,17 +7,19 @@ toolchain go1.23.2
|
||||
require (
|
||||
git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b
|
||||
github.com/alecthomas/assert/v2 v2.2.2
|
||||
github.com/grassrootseconomics/eth-custodial v1.3.0-beta
|
||||
github.com/peteole/testdata-loader v0.3.0
|
||||
gopkg.in/leonelquinteros/gotext.v1 v1.3.1
|
||||
|
||||
)
|
||||
|
||||
require github.com/joho/godotenv v1.5.1
|
||||
|
||||
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/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
|
||||
@@ -40,4 +42,7 @@ require (
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/config"
|
||||
"git.grassecon.net/urdt/ussd/internal/models"
|
||||
@@ -30,6 +31,9 @@ type AccountServiceInterface interface {
|
||||
type AccountService struct {
|
||||
}
|
||||
|
||||
type TestAccountService struct {
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -183,3 +187,88 @@ func (as *AccountService) FetchVouchers(ctx context.Context, publicKey string) (
|
||||
}
|
||||
return &holdings, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) {
|
||||
return &api.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(ctx context.Context, publicKey string) (*models.BalanceResponse, error) {
|
||||
balanceResponse := &models.BalanceResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Balance string `json:"balance"`
|
||||
Nonce json.Number `json:"nonce"`
|
||||
}{
|
||||
Balance: "0.003 CELO",
|
||||
Nonce: json.Number("0"),
|
||||
},
|
||||
}
|
||||
return balanceResponse, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) {
|
||||
return &api.OKResponse{
|
||||
Ok: true,
|
||||
Description: "Account creation succeeded",
|
||||
Result: map[string]any{
|
||||
"active": true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) {
|
||||
trackResponse := &models.TrackStatusResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Transaction struct {
|
||||
CreatedAt time.Time "json:\"createdAt\""
|
||||
Status string "json:\"status\""
|
||||
TransferValue json.Number "json:\"transferValue\""
|
||||
TxHash string "json:\"txHash\""
|
||||
TxType string "json:\"txType\""
|
||||
}
|
||||
}{
|
||||
Transaction: models.Transaction{
|
||||
CreatedAt: time.Now(),
|
||||
Status: "SUCCESS",
|
||||
TransferValue: json.Number("0.5"),
|
||||
TxHash: "0x123abc456def",
|
||||
TxType: "transfer",
|
||||
},
|
||||
},
|
||||
}
|
||||
return trackResponse, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) (*models.VoucherHoldingResponse, error) {
|
||||
return &models.VoucherHoldingResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Holdings []struct {
|
||||
ContractAddress string `json:"contractAddress"`
|
||||
TokenSymbol string `json:"tokenSymbol"`
|
||||
TokenDecimals string `json:"tokenDecimals"`
|
||||
Balance string `json:"balance"`
|
||||
} `json:"holdings"`
|
||||
}{
|
||||
Holdings: []struct {
|
||||
ContractAddress string `json:"contractAddress"`
|
||||
TokenSymbol string `json:"tokenSymbol"`
|
||||
TokenDecimals string `json:"tokenDecimals"`
|
||||
Balance string `json:"balance"`
|
||||
}{
|
||||
{
|
||||
ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee",
|
||||
TokenSymbol: "SRF",
|
||||
TokenDecimals: "6",
|
||||
Balance: "2745987",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"git.defalsify.org/vise.git/state"
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
||||
"git.grassecon.net/urdt/ussd/common"
|
||||
"gopkg.in/leonelquinteros/gotext.v1"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
||||
@@ -33,7 +32,6 @@ var (
|
||||
translationDir = path.Join(scriptDir, "locale")
|
||||
okResponse *api.OKResponse
|
||||
errResponse *api.ErrResponse
|
||||
backOption = []byte("0")
|
||||
)
|
||||
|
||||
// FlagManager handles centralized flag management
|
||||
@@ -154,22 +152,15 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
|
||||
data := map[utils.DataTyp]string{
|
||||
utils.DATA_TRACKING_ID: trackingId,
|
||||
utils.DATA_PUBLIC_KEY: publicKey,
|
||||
utils.DATA_ADDRESS: sessionId,
|
||||
}
|
||||
store := h.userdataStore
|
||||
for key, value := range data {
|
||||
err = store.WriteEntry(ctx, sessionId, key, []byte(value))
|
||||
store := h.userdataStore
|
||||
err := store.WriteEntry(ctx, sessionId, key, []byte(value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
publicKeyNormalized, err := common.NormalizeHex(publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = store.WriteEntry(ctx, publicKeyNormalized, utils.DATA_PUBLIC_KEY_REVERSE, []byte(sessionId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.FlagSet = append(res.FlagSet, flag_account_created)
|
||||
return nil
|
||||
|
||||
@@ -330,9 +321,6 @@ func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte)
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
if len(input) > 0 {
|
||||
if bytes.Equal(input, backOption) {
|
||||
return res, nil
|
||||
}
|
||||
firstName := string(input)
|
||||
store := h.userdataStore
|
||||
err = store.WriteEntry(ctx, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
|
||||
@@ -352,10 +340,8 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
|
||||
if !ok {
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
|
||||
if len(input) > 0 {
|
||||
if bytes.Equal(input, backOption) {
|
||||
return res, nil
|
||||
}
|
||||
familyName := string(input)
|
||||
store := h.userdataStore
|
||||
err = store.WriteEntry(ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
|
||||
@@ -397,10 +383,8 @@ func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (
|
||||
if !ok {
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
|
||||
if len(input) > 0 {
|
||||
if bytes.Equal(input, backOption) {
|
||||
return res, nil
|
||||
}
|
||||
location := string(input)
|
||||
store := h.userdataStore
|
||||
err = store.WriteEntry(ctx, sessionId, utils.DATA_LOCATION, []byte(location))
|
||||
@@ -421,9 +405,6 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
|
||||
if !ok {
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
if bytes.Equal(input, backOption) {
|
||||
return res, nil
|
||||
}
|
||||
gender := strings.Split(symbol, "_")[1]
|
||||
store := h.userdataStore
|
||||
err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
|
||||
@@ -552,6 +533,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
okResponse, err = h.accountService.TrackAccountStatus(ctx, string(publicKey))
|
||||
if err != nil {
|
||||
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||
|
||||
@@ -15,12 +15,10 @@ 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/testutil/mocks"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil/testservice"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
||||
"git.grassecon.net/urdt/ussd/common"
|
||||
"github.com/alecthomas/assert/v2"
|
||||
"github.com/grassrootseconomics/eth-custodial/pkg/api"
|
||||
testdataloader "github.com/peteole/testdata-loader"
|
||||
@@ -34,7 +32,7 @@ var (
|
||||
|
||||
func TestNewHandlers(t *testing.T) {
|
||||
fm, err := NewFlagManager(flagsPath)
|
||||
accountService := testservice.TestAccountService{}
|
||||
accountService := server.TestAccountService{}
|
||||
if err != nil {
|
||||
t.Logf(err.Error())
|
||||
}
|
||||
@@ -97,7 +95,7 @@ func TestCreateAccount(t *testing.T) {
|
||||
Description: "Account creation successed",
|
||||
Result: map[string]any{
|
||||
"trackingId": "1234567890",
|
||||
"publicKey": "0xD3adB33f",
|
||||
"publicKey": "1235QERYU",
|
||||
},
|
||||
},
|
||||
expectedResult: resource.Result{
|
||||
@@ -118,10 +116,9 @@ func TestCreateAccount(t *testing.T) {
|
||||
flagManager: fm.parser,
|
||||
}
|
||||
|
||||
publicKey := tt.serverResponse.Result["publicKey"].(string)
|
||||
data := map[utils.DataTyp]string{
|
||||
utils.DATA_TRACKING_ID: tt.serverResponse.Result["trackingId"].(string),
|
||||
utils.DATA_PUBLIC_KEY: publicKey,
|
||||
utils.DATA_PUBLIC_KEY: tt.serverResponse.Result["publicKey"].(string),
|
||||
}
|
||||
|
||||
mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_ACCOUNT_CREATED).Return([]byte(""), notFoundErr)
|
||||
@@ -130,12 +127,6 @@ func TestCreateAccount(t *testing.T) {
|
||||
for key, value := range data {
|
||||
mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil)
|
||||
}
|
||||
publicKeyNormalized, err := common.NormalizeHex(publicKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mockDataStore.On("WriteEntry", ctx, publicKeyNormalized, utils.DATA_PUBLIC_KEY_REVERSE, []byte(sessionId)).Return(nil)
|
||||
|
||||
// Call the method you want to test
|
||||
res, err := h.CreateAccount(ctx, "create_account", []byte("some-input"))
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"git.defalsify.org/vise.git/engine"
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil/mocks/httpmocks"
|
||||
"git.grassecon.net/urdt/ussd/internal/mocks/httpmocks"
|
||||
)
|
||||
|
||||
// invalidRequestType is a custom type to test invalid request scenarios
|
||||
|
||||
@@ -13,8 +13,6 @@ import (
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil/testservice"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil/testtag"
|
||||
testdataloader "github.com/peteole/testdata-loader"
|
||||
)
|
||||
|
||||
@@ -82,12 +80,12 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if testtag.AccountService == nil {
|
||||
testtag.AccountService = &server.AccountService{}
|
||||
if AccountService == nil {
|
||||
AccountService = &server.AccountService{}
|
||||
}
|
||||
|
||||
switch testtag.AccountService.(type) {
|
||||
case *testservice.TestAccountService:
|
||||
switch AccountService.(type) {
|
||||
case *server.TestAccountService:
|
||||
go func() {
|
||||
eventChannel <- false
|
||||
}()
|
||||
@@ -100,7 +98,7 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
|
||||
panic("Unknown account service type")
|
||||
}
|
||||
|
||||
hl, err := lhs.GetHandler(testtag.AccountService)
|
||||
hl, err := lhs.GetHandler(AccountService)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
|
||||
11
internal/testutil/offlinetest.go
Normal file
11
internal/testutil/offlinetest.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build !online
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||
)
|
||||
|
||||
var (
|
||||
AccountService server.AccountServiceInterface = &server.TestAccountService{}
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
// +build online
|
||||
|
||||
package testtag
|
||||
package testutil
|
||||
|
||||
import "git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
package testservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/internal/models"
|
||||
"github.com/grassrootseconomics/eth-custodial/pkg/api"
|
||||
)
|
||||
|
||||
type TestAccountService struct {
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) {
|
||||
return &api.OKResponse{
|
||||
Ok: true,
|
||||
Description: "Account creation succeeded",
|
||||
Result: map[string]any{
|
||||
"trackingId": "075ccc86-f6ef-4d33-97d5-e91cfb37aa0d",
|
||||
"publicKey": "0x623EFAFa8868df4B934dd12a8B26CB3Dd75A7AdD",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) {
|
||||
balanceResponse := &models.BalanceResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Balance string `json:"balance"`
|
||||
Nonce json.Number `json:"nonce"`
|
||||
}{
|
||||
Balance: "0.003 CELO",
|
||||
Nonce: json.Number("0"),
|
||||
},
|
||||
}
|
||||
|
||||
return balanceResponse, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) {
|
||||
trackResponse := &models.TrackStatusResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Transaction struct {
|
||||
CreatedAt time.Time "json:\"createdAt\""
|
||||
Status string "json:\"status\""
|
||||
TransferValue json.Number "json:\"transferValue\""
|
||||
TxHash string "json:\"txHash\""
|
||||
TxType string "json:\"txType\""
|
||||
}
|
||||
}{
|
||||
Transaction: models.Transaction{
|
||||
CreatedAt: time.Now(),
|
||||
Status: "SUCCESS",
|
||||
TransferValue: json.Number("0.5"),
|
||||
TxHash: "0x123abc456def",
|
||||
TxType: "transfer",
|
||||
},
|
||||
},
|
||||
}
|
||||
return trackResponse, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) {
|
||||
return &api.OKResponse{
|
||||
Ok: true,
|
||||
Description: "Account creation succeeded",
|
||||
Result: map[string]any{
|
||||
"active": true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) (*models.VoucherHoldingResponse, error) {
|
||||
return &models.VoucherHoldingResponse{
|
||||
Ok: true,
|
||||
Result: struct {
|
||||
Holdings []struct {
|
||||
ContractAddress string `json:"contractAddress"`
|
||||
TokenSymbol string `json:"tokenSymbol"`
|
||||
TokenDecimals string `json:"tokenDecimals"`
|
||||
Balance string `json:"balance"`
|
||||
} `json:"holdings"`
|
||||
}{
|
||||
Holdings: []struct {
|
||||
ContractAddress string `json:"contractAddress"`
|
||||
TokenSymbol string `json:"tokenSymbol"`
|
||||
TokenDecimals string `json:"tokenDecimals"`
|
||||
Balance string `json:"balance"`
|
||||
}{
|
||||
{
|
||||
ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee",
|
||||
TokenSymbol: "SRF",
|
||||
TokenDecimals: "6",
|
||||
Balance: "2745987",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
// +build !online
|
||||
|
||||
package testtag
|
||||
|
||||
import (
|
||||
"git.grassecon.net/urdt/ussd/internal/handlers/server"
|
||||
accountservice "git.grassecon.net/urdt/ussd/internal/testutil/testservice"
|
||||
)
|
||||
|
||||
var (
|
||||
AccountService server.AccountServiceInterface = &accountservice.TestAccountService{}
|
||||
)
|
||||
@@ -28,7 +28,7 @@ const (
|
||||
DATA_ACTIVE_SYM
|
||||
DATA_TEMPORARY_BAL
|
||||
DATA_ACTIVE_BAL
|
||||
DATA_PUBLIC_KEY_REVERSE
|
||||
DATA_ADDRESS
|
||||
)
|
||||
|
||||
func typToBytes(typ DataTyp) []byte {
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"git.grassecon.net/urdt/ussd/driver"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil"
|
||||
"git.grassecon.net/urdt/ussd/internal/testutil/driver"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
CATCH incorrect_pin flag_incorrect_pin 1
|
||||
CATCH profile_update_success flag_allow_update 1
|
||||
LOAD save_familyname 0
|
||||
RELOAD save_familyname
|
||||
MOUT back 0
|
||||
HALT
|
||||
LOAD save_familyname 0
|
||||
RELOAD save_familyname
|
||||
INCMP _ 0
|
||||
INCMP pin_entry *
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
CATCH incorrect_pin flag_incorrect_pin 1
|
||||
CATCH profile_update_success flag_allow_update 1
|
||||
LOAD save_location 0
|
||||
MOUT back 0
|
||||
HALT
|
||||
LOAD save_location 0
|
||||
RELOAD save_location
|
||||
INCMP _ 0
|
||||
INCMP pin_entry *
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
CATCH incorrect_pin flag_incorrect_pin 1
|
||||
CATCH profile_update_success flag_allow_update 1
|
||||
LOAD save_firstname 0
|
||||
RELOAD save_firstname
|
||||
MOUT back 0
|
||||
HALT
|
||||
LOAD save_firstname 0
|
||||
RELOAD save_firstname
|
||||
INCMP _ 0
|
||||
INCMP pin_entry *
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user