menu-voucherlist #101
| @ -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 | ||||
|  | ||||
| @ -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") | ||||
| } | ||||
|  | ||||
							
								
								
									
										27
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,29 +1,48 @@ | ||||
| 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.2.1-0.20241017112704-307fa6fcdc6b | ||||
| 	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/joho/godotenv v1.5.1 // indirect | ||||
| 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/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 | ||||
| 	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 | ||||
| 
 | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										44
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								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,33 +8,65 @@ 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= | ||||
| 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= | ||||
| 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= | ||||
|  | ||||
| @ -1,7 +1,10 @@ | ||||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| @ -9,12 +12,19 @@ import ( | ||||
| 
 | ||||
| 	"git.grassecon.net/urdt/ussd/config" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	okResponse  api.OKResponse | ||||
| 	errResponse api.ErrResponse | ||||
| ) | ||||
| 
 | ||||
| type AccountServiceInterface interface { | ||||
| 	CheckBalance(publicKey string) (*models.BalanceResponse, error) | ||||
| 	CreateAccount() (*models.AccountResponse, error) | ||||
| 	CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) | ||||
| 	CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) | ||||
| 	CreateAccount(ctx context.Context) (*api.OKResponse, error) | ||||
| 	CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) | ||||
| 	TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) | ||||
| 	FetchVouchers(publicKey string) (*models.VoucherHoldingResponse, error) | ||||
| } | ||||
| 
 | ||||
| @ -24,8 +34,6 @@ type AccountService struct { | ||||
| type TestAccountService 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
 | ||||
| @ -34,9 +42,9 @@ type TestAccountService 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.
 | ||||
| func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { | ||||
| 	resp, err := http.Get(config.TrackStatusURL + trackingId) | ||||
| //     If no error occurs, this will be nil
 | ||||
| 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 | ||||
| 	} | ||||
| @ -46,18 +54,61 @@ 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(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) | ||||
| 	req, err := http.NewRequest("GET", url, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	req.Header.Set("Content-Type", "application/json") | ||||
| 	req.Header.Set("X-GE-KEY", "xd") | ||||
| 
 | ||||
| 	resp, err := http.DefaultClient.Do(req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 
 | ||||
| 	body, err := io.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		errResponse.Description = err.Error() | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	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") | ||||
| 	} | ||||
| 	return &okResponse, nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // 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(ctx context.Context, publicKey string) (*models.BalanceResponse, error) { | ||||
| 	resp, err := http.Get(config.BalanceURL + publicKey) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @ -81,22 +132,43 @@ 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(ctx context.Context) (*api.OKResponse, error) { | ||||
| 	var err error | ||||
| 
 | ||||
| 	// Create a new request
 | ||||
| 	req, err := http.NewRequest("POST", config.CreateAccountURL, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	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, 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 resp.StatusCode >= http.StatusBadRequest { | ||||
| 		err := json.Unmarshal([]byte(body), &errResponse) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	return &accountResp, nil | ||||
| 		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") | ||||
| 	} | ||||
| 	return &okResponse, nil | ||||
| } | ||||
| 
 | ||||
| // FetchVouchers retrieves the token holdings for a given public key from the custodial holdings API endpoint
 | ||||
| @ -116,22 +188,16 @@ func (as *AccountService) FetchVouchers(publicKey string) (*models.VoucherHoldin | ||||
| 	return &holdings, nil | ||||
| } | ||||
| 
 | ||||
| func (tas *TestAccountService) CreateAccount() (*models.AccountResponse, error) { | ||||
| 	return &models.AccountResponse{ | ||||
| func (tas *TestAccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) { | ||||
| 	return &api.OKResponse{ | ||||
| 		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", | ||||
| 		}, | ||||
| 		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) { | ||||
| func (tas *TestAccountService) CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) { | ||||
| 	balanceResponse := &models.BalanceResponse{ | ||||
| 		Ok: true, | ||||
| 		Result: struct { | ||||
| @ -142,11 +208,20 @@ func (tas *TestAccountService) CheckBalance(publicKey string) (*models.BalanceRe | ||||
| 			Nonce:   json.Number("0"), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	return balanceResponse, nil | ||||
| } | ||||
| 
 | ||||
| func (tas *TestAccountService) CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) { | ||||
| 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 { | ||||
|  | ||||
| @ -10,6 +10,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" | ||||
| @ -29,6 +30,8 @@ var ( | ||||
| 	logg           = logging.NewVanilla().WithDomain("ussdmenuhandler") | ||||
| 	scriptDir      = path.Join("services", "registration") | ||||
| 	translationDir = path.Join(scriptDir, "locale") | ||||
| 	okResponse     *api.OKResponse | ||||
| 	errResponse    *api.ErrResponse | ||||
| ) | ||||
| 
 | ||||
| // FlagManager handles centralized flag management
 | ||||
| @ -138,13 +141,18 @@ 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() | ||||
| 	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(), | ||||
| 	flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") | ||||
| 	okResponse, err := h.accountService.CreateAccount(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	trackingId := okResponse.Result["trackingId"].(string) | ||||
| 	publicKey := okResponse.Result["publicKey"].(string) | ||||
| 
 | ||||
| 	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)) | ||||
| @ -152,9 +160,8 @@ 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 err | ||||
| 	return nil | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| @ -355,7 +362,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 | ||||
| @ -398,7 +404,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)) | ||||
| @ -417,7 +422,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 | ||||
| @ -443,7 +447,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) | ||||
| @ -453,12 +456,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) | ||||
| 
 | ||||
| @ -472,12 +473,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") | ||||
| @ -529,28 +528,21 @@ 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)) | ||||
| 	okResponse, err = h.accountService.TrackAccountStatus(ctx, string(publicKey)) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error checking account status:", err) | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if !accountStatus.Ok { | ||||
| 		res.FlagSet = append(res.FlagSet, flag_api_error) | ||||
| 		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 { | ||||
| @ -680,7 +672,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(ctx, string(publicKey)) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
|  | ||||
| @ -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" | ||||
| ) | ||||
| @ -72,49 +73,41 @@ 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"` | ||||
| 	tests := []struct { | ||||
| 		name           string | ||||
| 		serverResponse *api.OKResponse | ||||
| 		expectedResult resource.Result | ||||
| 	}{ | ||||
| 			CustodialId: "12", | ||||
| 			PublicKey:   "0x8E0XSCSVA", | ||||
| 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA", | ||||
| 		{ | ||||
| 			name: "Test account creation success", | ||||
| 			serverResponse: &api.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) { | ||||
| 
 | ||||
| 	for key, value := range data { | ||||
| 		mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil) | ||||
| 	} | ||||
| 			mockDataStore := new(mocks.MockUserDataStore) | ||||
| 			mockCreateAccountService := new(mocks.MockAccountService) | ||||
| 
 | ||||
| 			// Create a Handlers instance with the mock data store
 | ||||
| 			h := &Handlers{ | ||||
| @ -123,6 +116,18 @@ func TestCreateAccount(t *testing.T) { | ||||
| 				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")) | ||||
| 
 | ||||
| @ -130,10 +135,12 @@ func TestCreateAccount(t *testing.T) { | ||||
| 			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.Equal(t, res, tt.expectedResult, "Expected result should be equal to the actual result") | ||||
| 
 | ||||
| 			// Assert that expectations were met
 | ||||
| 			mockDataStore.AssertExpectations(t) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestWithPersister(t *testing.T) { | ||||
| @ -1037,12 +1044,20 @@ func TestCheckAccountStatus(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name           string | ||||
| 		input          []byte | ||||
| 		serverResponse *api.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: &api.OKResponse{ | ||||
| 				Ok:          true, | ||||
| 				Description: "Account creation succeeded", | ||||
| 				Result: map[string]any{ | ||||
| 					"active": true, | ||||
| 				}, | ||||
| 			}, | ||||
| 			response: &models.TrackStatusResponse{ | ||||
| 				Ok: true, | ||||
| 				Result: struct { | ||||
| @ -1069,17 +1084,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, | ||||
| @ -1094,13 +1099,20 @@ func TestCheckAccountStatus(t *testing.T) { | ||||
| 				}{ | ||||
| 					Transaction: models.Transaction{ | ||||
| 						CreatedAt:     time.Now(), | ||||
| 						Status:        "IN_NETWORK", | ||||
| 						Status:        "SUCCESS", | ||||
| 						TransferValue: json.Number("0.5"), | ||||
| 						TxHash:        "0x123abc456def", | ||||
| 						TxType:        "transfer", | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			serverResponse: &api.OKResponse{ | ||||
| 				Ok:          true, | ||||
| 				Description: "Account creation succeeded", | ||||
| 				Result: map[string]any{ | ||||
| 					"active": false, | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedResult: resource.Result{ | ||||
| 				FlagSet:   []uint32{flag_account_pending}, | ||||
| 				FlagReset: []uint32{flag_api_error, flag_account_success}, | ||||
| @ -1120,9 +1132,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
 | ||||
|  | ||||
| @ -1,7 +1,10 @@ | ||||
| package mocks | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 
 | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||
| 	"github.com/stretchr/testify/mock" | ||||
| ) | ||||
| 
 | ||||
| @ -10,21 +13,27 @@ type MockAccountService struct { | ||||
| 	mock.Mock | ||||
| } | ||||
| 
 | ||||
| func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) { | ||||
| func (m *MockAccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) { | ||||
| 	args := m.Called() | ||||
| 	return args.Get(0).(*models.AccountResponse), args.Error(1) | ||||
| 	return args.Get(0).(*api.OKResponse), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m *MockAccountService) CheckBalance(publicKey string) (*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) (*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(ctx context.Context,publicKey string) (*api.OKResponse, error) { | ||||
| 	args := m.Called(publicKey) | ||||
| 	return args.Get(0).(*api.OKResponse), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| func (m *MockAccountService) FetchVouchers(publicKey string) (*models.VoucherHoldingResponse, error) { | ||||
| 	args := m.Called(publicKey) | ||||
| 	return args.Get(0).(*models.VoucherHoldingResponse), args.Error(1) | ||||
|  | ||||
| @ -1,14 +1,9 @@ | ||||
| package models | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 
 | ||||
| ) | ||||
| 
 | ||||
| type AccountResponse struct { | ||||
| 	Ok          bool   `json:"ok"` | ||||
| 	Description string `json:"description"` // Include the description field
 | ||||
| 	Result      struct { | ||||
| 		CustodialId json.Number `json:"custodialId"` | ||||
| 		PublicKey  string `json:"publicKey"` | ||||
| 		TrackingId string `json:"trackingId"` | ||||
| 	} `json:"result"` | ||||
|  | ||||
| @ -4,7 +4,6 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| type Transaction struct { | ||||
| 	CreatedAt     time.Time   `json:"createdAt"` | ||||
| 	Status        string      `json:"status"` | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user