Compare commits

..

2 Commits

Author SHA1 Message Date
Carlosokumu
4c3d90c374 Merge branch 'master' into address-sessionId 2024-10-26 15:10:51 +03:00
Carlosokumu
4011bc18b6 define address key 2024-10-25 17:45:32 +03:00
24 changed files with 135 additions and 185 deletions

View File

@@ -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
View File

@@ -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
)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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"))

View File

@@ -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

View File

@@ -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)

View File

@@ -0,0 +1,11 @@
// +build !online
package testutil
import (
"git.grassecon.net/urdt/ussd/internal/handlers/server"
)
var (
AccountService server.AccountServiceInterface = &server.TestAccountService{}
)

View File

@@ -1,6 +1,6 @@
// +build online
package testtag
package testutil
import "git.grassecon.net/urdt/ussd/internal/handlers/server"

View File

@@ -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
}

View File

@@ -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{}
)

View File

@@ -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 {

View File

@@ -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"
)

View File

@@ -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 *

View File

@@ -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 *

View File

@@ -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 *