tests-refactor #137
| @ -12,6 +12,7 @@ DB_SSLMODE=disable | |||||||
| DB_TIMEZONE=Africa/Nairobi | DB_TIMEZONE=Africa/Nairobi | ||||||
| 
 | 
 | ||||||
| #External API Calls | #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/ | TRACK_STATUS_URL=https://custodial.sarafu.africa/api/track/ | ||||||
| BALANCE_URL=https://custodial.sarafu.africa/api/account/status/ | 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 | 	CreateAccountURL string | ||||||
| 	TrackStatusURL   string | 	TrackStatusURL   string | ||||||
| 	BalanceURL       string | 	BalanceURL       string | ||||||
|  |     TrackURL         string | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // LoadConfig initializes the configuration values after environment variables are loaded.
 | // LoadConfig initializes the configuration values after environment variables are loaded.
 | ||||||
| func LoadConfig() { | 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/") | 	TrackStatusURL = initializers.GetEnv("TRACK_STATUS_URL", "https://custodial.sarafu.africa/api/track/") | ||||||
| 	BalanceURL = initializers.GetEnv("BALANCE_URL", "https://custodial.sarafu.africa/api/account/status/") | 	BalanceURL = initializers.GetEnv("BALANCE_URL", "https://custodial.sarafu.africa/api/account/status/") | ||||||
|  |     TrackURL = initializers.GetEnv("TRACK_URL", "http://localhost:5003/api/v2/account/status") | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,20 +1,25 @@ | |||||||
| module git.grassecon.net/urdt/ussd | module git.grassecon.net/urdt/ussd | ||||||
| 
 | 
 | ||||||
| go 1.22.6 | go 1.23.0 | ||||||
|  | 
 | ||||||
|  | toolchain go1.23.2 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b | 	git.defalsify.org/vise.git v0.2.1-0.20241017112704-307fa6fcdc6b | ||||||
| 	github.com/alecthomas/assert/v2 v2.2.2 | 	github.com/alecthomas/assert/v2 v2.2.2 | ||||||
| 	github.com/peteole/testdata-loader v0.3.0 | 	github.com/peteole/testdata-loader v0.3.0 | ||||||
| 	gopkg.in/leonelquinteros/gotext.v1 v1.3.1 | 	gopkg.in/leonelquinteros/gotext.v1 v1.3.1 | ||||||
|  | 
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | require github.com/joho/godotenv v1.5.1 | ||||||
|  | 
 | ||||||
| require ( | require ( | ||||||
|  | 	github.com/grassrootseconomics/eth-custodial v1.3.0-beta | ||||||
| 	github.com/jackc/pgpassfile v1.0.0 // indirect | 	github.com/jackc/pgpassfile v1.0.0 // indirect | ||||||
| 	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect | 	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect | ||||||
| 	github.com/jackc/pgx/v5 v5.7.0 // indirect | 	github.com/jackc/pgx/v5 v5.7.1 // indirect | ||||||
| 	github.com/jackc/puddle/v2 v2.2.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/kr/text v0.2.0 // indirect | ||||||
| 	github.com/rogpeppe/go-internal v1.13.1 // indirect | 	github.com/rogpeppe/go-internal v1.13.1 // indirect | ||||||
| 	golang.org/x/crypto v0.27.0 // indirect | 	golang.org/x/crypto v0.27.0 // indirect | ||||||
| @ -26,15 +31,18 @@ require ( | |||||||
| 	github.com/alecthomas/participle/v2 v2.0.0 // indirect | 	github.com/alecthomas/participle/v2 v2.0.0 // indirect | ||||||
| 	github.com/alecthomas/repr v0.2.0 // indirect | 	github.com/alecthomas/repr v0.2.0 // indirect | ||||||
| 	github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // 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/fxamacker/cbor/v2 v2.4.0 // indirect | ||||||
| 	github.com/gofrs/uuid v4.4.0+incompatible | 	github.com/gofrs/uuid v4.4.0+incompatible | ||||||
| 	github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect | 	github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect | ||||||
| 	github.com/hexops/gotextdiff v1.0.3 // indirect | 	github.com/hexops/gotextdiff v1.0.3 // indirect | ||||||
| 	github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // 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/objx v0.5.2 // indirect | ||||||
| 	github.com/stretchr/testify v1.9.0 | 	github.com/stretchr/testify v1.9.0 | ||||||
| 	github.com/x448/float16 v0.8.4 // indirect | 	github.com/x448/float16 v0.8.4 // indirect | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
|  | 
 | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								go.sum
									
									
									
									
									
								
							| @ -10,12 +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/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/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.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.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= | ||||||
| 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/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 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= | ||||||
| github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= | 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 h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= | ||||||
| github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= | 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 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo= | ||||||
| github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= | 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 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= | ||||||
| @ -24,10 +26,10 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI | |||||||
| github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= | 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 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= | ||||||
| github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= | 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.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= | ||||||
| github.com/jackc/pgx/v5 v5.7.0/go.mod h1:awP1KNnjylvpxHuHP63gzjhnGkI1iw+PMoIwvoleN/8= | github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= | ||||||
| github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= | github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= | ||||||
| github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= | 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 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= | ||||||
| github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= | 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 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | ||||||
| @ -40,8 +42,9 @@ github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNL | |||||||
| github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A= | 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 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I= | ||||||
| github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U= | 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.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 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= | ||||||
| github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= | 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.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
|  | |||||||
| @ -1,25 +1,36 @@ | |||||||
| package server | package server | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"git.grassecon.net/urdt/ussd/config" | 	"git.grassecon.net/urdt/ussd/config" | ||||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | 	"git.grassecon.net/urdt/ussd/internal/models" | ||||||
|  | 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	okResponse  api.OKResponse | ||||||
|  | 	errResponse api.ErrResponse | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type AccountServiceInterface interface { | type AccountServiceInterface interface { | ||||||
| 	CheckBalance(publicKey string) (*models.BalanceResponse, error) | 	CheckBalance(ctx context.Context, publicKey string) (*models.BalanceResponse, error) | ||||||
| 	CreateAccount() (*models.AccountResponse, error) | 	CreateAccount(ctx context.Context) (*api.OKResponse, error) | ||||||
| 	CheckAccountStatus(trackingId string) (*models.TrackStatusResponse, error) | 	CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) | ||||||
|  | 	TrackAccountStatus(ctx context.Context, publicKey string) (*api.OKResponse, error) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type AccountService struct { | type AccountService struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID.
 | type TestAccountService struct { | ||||||
| //
 | } | ||||||
|  | 
 | ||||||
| // Parameters:
 | // Parameters:
 | ||||||
| //   - trackingId: A unique identifier for the account.This should be obtained from a previous call to
 | //   - 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
 | //     CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the
 | ||||||
| @ -28,9 +39,9 @@ type AccountService struct { | |||||||
| // Returns:
 | // 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.
 | //   - 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.
 | //   - 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) { | func (as *AccountService) CheckAccountStatus(ctx context.Context, trackingId string) (*models.TrackStatusResponse, error) { | ||||||
| 	resp, err := http.Get(config.TrackStatusURL + trackingId) | 	resp, err := http.Get(config.BalanceURL + trackingId) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @ -40,18 +51,61 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (*models.TrackSt | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	var trackResp models.TrackStatusResponse | 	var trackResp models.TrackStatusResponse | ||||||
| 	err = json.Unmarshal(body, &trackResp) | 	err = json.Unmarshal(body, &trackResp) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &trackResp, nil | 	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.
 | // CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint.
 | ||||||
| // Parameters:
 | // Parameters:
 | ||||||
| //   - publicKey: The public key associated with the account whose balance needs to be checked.
 | //   - 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) | 	resp, err := http.Get(config.BalanceURL + publicKey) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @ -75,20 +129,98 @@ func (as *AccountService) CheckBalance(publicKey string) (*models.BalanceRespons | |||||||
| //     If there is an error during the request or processing, this will be nil.
 | //     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.
 | //   - 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) CreateAccount() (*models.AccountResponse, error) { | func (as *AccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) { | ||||||
| 	resp, err := http.Post(config.CreateAccountURL, "application/json", nil) | 	var err error | ||||||
|  | 
 | ||||||
|  | 	// Create a new request
 | ||||||
|  | 	req, err := http.NewRequest("POST", config.CreateAccountURL, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		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() | 	defer resp.Body.Close() | ||||||
|  | 
 | ||||||
| 	body, err := io.ReadAll(resp.Body) | 	body, err := io.ReadAll(resp.Body) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	var accountResp models.AccountResponse | 	if resp.StatusCode >= http.StatusBadRequest { | ||||||
| 	err = json.Unmarshal(body, &accountResp) | 		err := json.Unmarshal([]byte(body), &errResponse) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"git.defalsify.org/vise.git/asm" | 	"git.defalsify.org/vise.git/asm" | ||||||
|  | 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||||
| 
 | 
 | ||||||
| 	"git.defalsify.org/vise.git/cache" | 	"git.defalsify.org/vise.git/cache" | ||||||
| 	"git.defalsify.org/vise.git/db" | 	"git.defalsify.org/vise.git/db" | ||||||
| @ -27,6 +28,8 @@ var ( | |||||||
| 	logg           = logging.NewVanilla().WithDomain("ussdmenuhandler") | 	logg           = logging.NewVanilla().WithDomain("ussdmenuhandler") | ||||||
| 	scriptDir      = path.Join("services", "registration") | 	scriptDir      = path.Join("services", "registration") | ||||||
| 	translationDir = path.Join(scriptDir, "locale") | 	translationDir = path.Join(scriptDir, "locale") | ||||||
|  | 	okResponse     *api.OKResponse | ||||||
|  | 	errResponse    *api.ErrResponse | ||||||
| 	backOption     = []byte("0") | 	backOption     = []byte("0") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -137,13 +140,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 { | func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error { | ||||||
| 	accountResp, err := h.accountService.CreateAccount() | 	flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") | ||||||
| 	data := map[utils.DataTyp]string{ | 	okResponse, err := h.accountService.CreateAccount(ctx) | ||||||
| 		utils.DATA_TRACKING_ID:  accountResp.Result.TrackingId, | 	if err != nil { | ||||||
| 		utils.DATA_PUBLIC_KEY:   accountResp.Result.PublicKey, | 		return err | ||||||
| 		utils.DATA_CUSTODIAL_ID: accountResp.Result.CustodialId.String(), |  | ||||||
| 	} | 	} | ||||||
|  | 	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 { | 	for key, value := range data { | ||||||
| 		store := h.userdataStore | 		store := h.userdataStore | ||||||
| 		err := store.WriteEntry(ctx, sessionId, key, []byte(value)) | 		err := store.WriteEntry(ctx, sessionId, key, []byte(value)) | ||||||
| @ -151,9 +159,8 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") |  | ||||||
| 	res.FlagSet = append(res.FlagSet, flag_account_created) | 	res.FlagSet = append(res.FlagSet, flag_account_created) | ||||||
| 	return err | 	return nil | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -192,7 +199,6 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") | 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") | ||||||
| 
 |  | ||||||
| 	accountPIN := string(input) | 	accountPIN := string(input) | ||||||
| 	// Validate that the PIN is a 4-digit number
 | 	// Validate that the PIN is a 4-digit number
 | ||||||
| 	if !isValidPIN(accountPIN) { | 	if !isValidPIN(accountPIN) { | ||||||
| @ -374,7 +380,6 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou | |||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if len(input) == 4 { | 	if len(input) == 4 { | ||||||
| 		yob := string(input) | 		yob := string(input) | ||||||
| 		store := h.userdataStore | 		store := h.userdataStore | ||||||
| @ -440,7 +445,6 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) | |||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if len(input) > 0 { | 	if len(input) > 0 { | ||||||
| 		offerings := string(input) | 		offerings := string(input) | ||||||
| 		store := h.userdataStore | 		store := h.userdataStore | ||||||
| @ -466,7 +470,6 @@ func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byt | |||||||
| // ResetAccountAuthorized resets the account authorization flag after a successful PIN entry.
 | // 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) { | func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||||
| 	var res resource.Result | 	var res resource.Result | ||||||
| 
 |  | ||||||
| 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") | 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") | ||||||
| 
 | 
 | ||||||
| 	res.FlagReset = append(res.FlagReset, flag_account_authorized) | 	res.FlagReset = append(res.FlagReset, flag_account_authorized) | ||||||
| @ -476,12 +479,10 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input | |||||||
| // CheckIdentifier retrieves the PublicKey from the JSON data file.
 | // CheckIdentifier retrieves the PublicKey from the JSON data file.
 | ||||||
| func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) { | func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||||
| 	var res resource.Result | 	var res resource.Result | ||||||
| 
 |  | ||||||
| 	sessionId, ok := ctx.Value("SessionId").(string) | 	sessionId, ok := ctx.Value("SessionId").(string) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	store := h.userdataStore | 	store := h.userdataStore | ||||||
| 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | ||||||
| 
 | 
 | ||||||
| @ -495,12 +496,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) { | func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||||
| 	var res resource.Result | 	var res resource.Result | ||||||
| 	var err error | 	var err error | ||||||
| 
 |  | ||||||
| 	sessionId, ok := ctx.Value("SessionId").(string) | 	sessionId, ok := ctx.Value("SessionId").(string) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") | 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") | ||||||
| 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") | 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") | ||||||
| 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") | 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") | ||||||
| @ -552,28 +551,21 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b | |||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 	store := h.userdataStore | 	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 { | 	if err != nil { | ||||||
| 		return res, err | 		return res, err | ||||||
| 	} | 	} | ||||||
| 
 | 	okResponse, err = h.accountService.TrackAccountStatus(ctx, string(publicKey)) | ||||||
| 	accountStatus, err := h.accountService.CheckAccountStatus(string(trackingId)) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fmt.Println("Error checking account status:", err) |  | ||||||
| 		return res, err |  | ||||||
| 	} |  | ||||||
| 	if !accountStatus.Ok { |  | ||||||
| 		res.FlagSet = append(res.FlagSet, flag_api_error) | 		res.FlagSet = append(res.FlagSet, flag_api_error) | ||||||
| 		return res, err | 		return res, err | ||||||
| 	} | 	} | ||||||
| 	res.FlagReset = append(res.FlagReset, flag_api_error) | 	res.FlagReset = append(res.FlagReset, flag_api_error) | ||||||
| 	status := accountStatus.Result.Transaction.Status | 	isActive := okResponse.Result["active"].(bool) | ||||||
| 
 | 	if !ok { | ||||||
| 	err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status)) | 		return res, err | ||||||
| 	if err != nil { |  | ||||||
| 		return res, nil |  | ||||||
| 	} | 	} | ||||||
| 	if accountStatus.Result.Transaction.Status == "SUCCESS" { | 	if isActive { | ||||||
| 		res.FlagSet = append(res.FlagSet, flag_account_success) | 		res.FlagSet = append(res.FlagSet, flag_account_success) | ||||||
| 		res.FlagReset = append(res.FlagReset, flag_account_pending) | 		res.FlagReset = append(res.FlagReset, flag_account_pending) | ||||||
| 	} else { | 	} else { | ||||||
| @ -660,13 +652,17 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( | |||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	code := codeFromCtx(ctx) | ||||||
|  | 	l := gotext.NewLocale(translationDir, code) | ||||||
|  | 	l.AddDomain("default") | ||||||
|  | 
 | ||||||
| 	store := h.userdataStore | 	store := h.userdataStore | ||||||
| 	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | 	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return res, err | 		return res, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	balanceResponse, err := h.accountService.CheckBalance(string(publicKey)) | 	balanceResponse, err := h.accountService.CheckBalance(ctx, string(publicKey)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return res, nil | 		return res, nil | ||||||
| 	} | 	} | ||||||
| @ -676,7 +672,8 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) ( | |||||||
| 	} | 	} | ||||||
| 	res.FlagReset = append(res.FlagReset, flag_api_error) | 	res.FlagReset = append(res.FlagReset, flag_api_error) | ||||||
| 	balance := balanceResponse.Result.Balance | 	balance := balanceResponse.Result.Balance | ||||||
| 	res.Content = balance | 
 | ||||||
|  | 	res.Content = l.Get("Balance: %s\n", balance) | ||||||
| 
 | 
 | ||||||
| 	return res, nil | 	return res, nil | ||||||
| } | } | ||||||
| @ -698,7 +695,7 @@ func (h *Handlers) FetchCustodialBalances(ctx context.Context, sym string, input | |||||||
| 		return res, err | 		return res, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	balanceResponse, err := h.accountService.CheckBalance(string(publicKey)) | 	balanceResponse, err := h.accountService.CheckBalance(ctx, string(publicKey)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return res, nil | 		return res, nil | ||||||
| 	} | 	} | ||||||
| @ -816,7 +813,7 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res | |||||||
| 	store := h.userdataStore | 	store := h.userdataStore | ||||||
| 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) | ||||||
| 
 | 
 | ||||||
| 	balanceResp, err := h.accountService.CheckBalance(string(publicKey)) | 	balanceResp, err := h.accountService.CheckBalance(ctx, string(publicKey)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return res, nil | 		return res, nil | ||||||
| 	} | 	} | ||||||
| @ -846,7 +843,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) | |||||||
| 
 | 
 | ||||||
| 	amountStr := string(input) | 	amountStr := string(input) | ||||||
| 
 | 
 | ||||||
| 	balanceRes, err := h.accountService.CheckBalance(string(publicKey)) | 	balanceRes, err := h.accountService.CheckBalance(ctx, string(publicKey)) | ||||||
| 	balanceStr := balanceRes.Result.Balance | 	balanceStr := balanceRes.Result.Balance | ||||||
| 
 | 
 | ||||||
| 	if !balanceRes.Ok { | 	if !balanceRes.Ok { | ||||||
| @ -916,7 +913,7 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) ( | |||||||
| 	return res, nil | 	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) { | func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||||
| 	var res resource.Result | 	var res resource.Result | ||||||
| 
 | 
 | ||||||
| @ -925,10 +922,7 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res | |||||||
| 		return res, fmt.Errorf("missing session") | 		return res, fmt.Errorf("missing session") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	store := h.userdataStore | 	res.Content = string(sessionId) | ||||||
| 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) |  | ||||||
| 
 |  | ||||||
| 	res.Content = string(publicKey) |  | ||||||
| 
 | 
 | ||||||
| 	return res, nil | 	return res, nil | ||||||
| } | } | ||||||
| @ -965,13 +959,12 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input [] | |||||||
| 	// TODO
 | 	// TODO
 | ||||||
| 	// Use the amount, recipient and sender to call the API and initialize the transaction
 | 	// Use the amount, recipient and sender to call the API and initialize the transaction
 | ||||||
| 	store := h.userdataStore | 	store := h.userdataStore | ||||||
| 	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) |  | ||||||
| 
 | 
 | ||||||
| 	amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT) | 	amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT) | ||||||
| 
 | 
 | ||||||
| 	recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT) | 	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") | 	account_authorized_flag, err := h.flagManager.GetFlag("flag_account_authorized") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"git.grassecon.net/urdt/ussd/internal/utils" | 	"git.grassecon.net/urdt/ussd/internal/utils" | ||||||
| 	"github.com/alecthomas/assert/v2" | 	"github.com/alecthomas/assert/v2" | ||||||
|  | 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||||
| 	testdataloader "github.com/peteole/testdata-loader" | 	testdataloader "github.com/peteole/testdata-loader" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
| ) | ) | ||||||
| @ -73,49 +74,41 @@ func TestCreateAccount(t *testing.T) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Logf(err.Error()) | 		t.Logf(err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	// Create required mocks
 | 	// Create required mocks
 | ||||||
| 	mockDataStore := new(mocks.MockUserDataStore) | 	flag_account_created, err := fm.GetFlag("flag_account_created") | ||||||
| 	mockCreateAccountService := new(mocks.MockAccountService) |  | ||||||
| 	expectedResult := resource.Result{} |  | ||||||
| 	accountCreatedFlag, err := fm.GetFlag("flag_account_created") |  | ||||||
| 
 |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Logf(err.Error()) | 		t.Logf(err.Error()) | ||||||
| 	} | 	} | ||||||
| 	expectedResult.FlagSet = append(expectedResult.FlagSet, accountCreatedFlag) |  | ||||||
| 
 |  | ||||||
| 	// Define session ID and mock data
 | 	// Define session ID and mock data
 | ||||||
| 	sessionId := "session123" | 	sessionId := "session123" | ||||||
| 	typ := utils.DATA_ACCOUNT_CREATED | 	notFoundErr := db.ErrNotFound{} | ||||||
| 	fakeError := db.ErrNotFound{} |  | ||||||
| 	// Create context with session ID
 |  | ||||||
| 	ctx := context.WithValue(context.Background(), "SessionId", sessionId) | 	ctx := context.WithValue(context.Background(), "SessionId", sessionId) | ||||||
| 
 | 
 | ||||||
| 	// Define expected interactions with the mock
 | 	tests := []struct { | ||||||
| 	mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte("123"), fakeError) | 		name           string | ||||||
| 	expectedAccountResp := &models.AccountResponse{ | 		serverResponse *api.OKResponse | ||||||
| 		Ok: true, | 		expectedResult resource.Result | ||||||
| 		Result: struct { |  | ||||||
| 			CustodialId json.Number `json:"custodialId"` |  | ||||||
| 			PublicKey   string      `json:"publicKey"` |  | ||||||
| 			TrackingId  string      `json:"trackingId"` |  | ||||||
| 	}{ | 	}{ | ||||||
| 			CustodialId: "12", | 		{ | ||||||
| 			PublicKey:   "0x8E0XSCSVA", | 			name: "Test account creation success", | ||||||
| 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA", | 			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) | 	for _, tt := range tests { | ||||||
| 	data := map[utils.DataTyp]string{ | 		t.Run(tt.name, func(t *testing.T) { | ||||||
| 		utils.DATA_TRACKING_ID:  expectedAccountResp.Result.TrackingId, |  | ||||||
| 		utils.DATA_PUBLIC_KEY:   expectedAccountResp.Result.PublicKey, |  | ||||||
| 		utils.DATA_CUSTODIAL_ID: expectedAccountResp.Result.CustodialId.String(), |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	for key, value := range data { | 			mockDataStore := new(mocks.MockUserDataStore) | ||||||
| 		mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil) | 			mockCreateAccountService := new(mocks.MockAccountService) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 			// Create a Handlers instance with the mock data store
 | 			// Create a Handlers instance with the mock data store
 | ||||||
| 			h := &Handlers{ | 			h := &Handlers{ | ||||||
| @ -124,17 +117,31 @@ func TestCreateAccount(t *testing.T) { | |||||||
| 				flagManager:    fm.parser, | 				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
 | 			// Call the method you want to test
 | ||||||
| 			res, err := h.CreateAccount(ctx, "create_account", []byte("some-input")) | 			res, err := h.CreateAccount(ctx, "create_account", []byte("some-input")) | ||||||
| 
 | 
 | ||||||
| 			// Assert that no errors occurred
 | 			// Assert that no errors occurred
 | ||||||
| 			assert.NoError(t, err) | 			assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	//Assert that the account created flag has been set to the result
 | 			// 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
 | 			// Assert that expectations were met
 | ||||||
| 			mockDataStore.AssertExpectations(t) | 			mockDataStore.AssertExpectations(t) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestWithPersister(t *testing.T) { | func TestWithPersister(t *testing.T) { | ||||||
| @ -510,12 +517,8 @@ func TestGetSender(t *testing.T) { | |||||||
| 	mockStore := new(mocks.MockUserDataStore) | 	mockStore := new(mocks.MockUserDataStore) | ||||||
| 
 | 
 | ||||||
| 	// Define test data
 | 	// Define test data
 | ||||||
| 	sessionId := "session123" | 	sessionId := "254712345678" | ||||||
| 	ctx := context.WithValue(context.Background(), "SessionId", sessionId) | 	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
 | 	// Create the Handlers instance with the mock store
 | ||||||
| 	h := &Handlers{ | 	h := &Handlers{ | ||||||
| @ -523,11 +526,10 @@ func TestGetSender(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Call the method
 | 	// Call the method
 | ||||||
| 	res, _ := h.GetSender(ctx, "max_amount", []byte("check_balance")) | 	res, _ := h.GetSender(ctx, "get_sender", []byte("")) | ||||||
| 
 |  | ||||||
| 	//Assert that the public key from readentry operation  is what was set as the result content.
 |  | ||||||
| 	assert.Equal(t, publicKey, res.Content) |  | ||||||
| 
 | 
 | ||||||
|  | 	//Assert that the sessionId is what was set as the result content.
 | ||||||
|  | 	assert.Equal(t, sessionId, res.Content) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetAmount(t *testing.T) { | func TestGetAmount(t *testing.T) { | ||||||
| @ -1067,12 +1069,20 @@ func TestCheckAccountStatus(t *testing.T) { | |||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		name           string | 		name           string | ||||||
| 		input          []byte | 		input          []byte | ||||||
|  | 		serverResponse *api.OKResponse | ||||||
| 		response       *models.TrackStatusResponse | 		response       *models.TrackStatusResponse | ||||||
| 		expectedResult resource.Result | 		expectedResult resource.Result | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			name:  "Test when account status is Success", | 			name:  "Test when account is on the Sarafu network", | ||||||
| 			input: []byte("TrackingId1234"), | 			input: []byte("TrackingId1234"), | ||||||
|  | 			serverResponse: &api.OKResponse{ | ||||||
|  | 				Ok:          true, | ||||||
|  | 				Description: "Account creation succeeded", | ||||||
|  | 				Result: map[string]any{ | ||||||
|  | 					"active": true, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
| 			response: &models.TrackStatusResponse{ | 			response: &models.TrackStatusResponse{ | ||||||
| 				Ok: true, | 				Ok: true, | ||||||
| 				Result: struct { | 				Result: struct { | ||||||
| @ -1099,17 +1109,7 @@ func TestCheckAccountStatus(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name:  "Test when fetching  account status is not  Success", | 			name:  "Test when the account is not  yet on the sarafu network", | ||||||
| 			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", |  | ||||||
| 			input: []byte("TrackingId1234"), | 			input: []byte("TrackingId1234"), | ||||||
| 			response: &models.TrackStatusResponse{ | 			response: &models.TrackStatusResponse{ | ||||||
| 				Ok: true, | 				Ok: true, | ||||||
| @ -1124,13 +1124,20 @@ func TestCheckAccountStatus(t *testing.T) { | |||||||
| 				}{ | 				}{ | ||||||
| 					Transaction: models.Transaction{ | 					Transaction: models.Transaction{ | ||||||
| 						CreatedAt:     time.Now(), | 						CreatedAt:     time.Now(), | ||||||
| 						Status:        "IN_NETWORK", | 						Status:        "SUCCESS", | ||||||
| 						TransferValue: json.Number("0.5"), | 						TransferValue: json.Number("0.5"), | ||||||
| 						TxHash:        "0x123abc456def", | 						TxHash:        "0x123abc456def", | ||||||
| 						TxType:        "transfer", | 						TxType:        "transfer", | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  | 			serverResponse: &api.OKResponse{ | ||||||
|  | 				Ok:          true, | ||||||
|  | 				Description: "Account creation succeeded", | ||||||
|  | 				Result: map[string]any{ | ||||||
|  | 					"active": false, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
| 			expectedResult: resource.Result{ | 			expectedResult: resource.Result{ | ||||||
| 				FlagSet:   []uint32{flag_account_pending}, | 				FlagSet:   []uint32{flag_account_pending}, | ||||||
| 				FlagReset: []uint32{flag_api_error, flag_account_success}, | 				FlagReset: []uint32{flag_api_error, flag_account_success}, | ||||||
| @ -1150,9 +1157,10 @@ func TestCheckAccountStatus(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 			status := tt.response.Result.Transaction.Status | 			status := tt.response.Result.Transaction.Status | ||||||
| 			// Define expected interactions with the mock
 | 			// 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("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() | 			mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status)).Return(nil).Maybe() | ||||||
| 
 | 
 | ||||||
| 			// Call the method under test
 | 			// Call the method under test
 | ||||||
| @ -1285,7 +1293,7 @@ func TestResetInvalidAmount(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestInitiateTransaction(t *testing.T) { | func TestInitiateTransaction(t *testing.T) { | ||||||
| 	sessionId := "session123" | 	sessionId := "254712345678" | ||||||
| 
 | 
 | ||||||
| 	fm, err := NewFlagManager(flagsPath) | 	fm, err := NewFlagManager(flagsPath) | ||||||
| 
 | 
 | ||||||
| @ -1308,30 +1316,26 @@ func TestInitiateTransaction(t *testing.T) { | |||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		name           string | 		name           string | ||||||
| 		input          []byte | 		input          []byte | ||||||
| 		PublicKey      []byte |  | ||||||
| 		Recipient      []byte | 		Recipient      []byte | ||||||
| 		Amount         []byte | 		Amount         []byte | ||||||
| 		status         string | 		status         string | ||||||
| 		expectedResult resource.Result | 		expectedResult resource.Result | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			name:      "Test amount reset", | 			name:      "Test initiate transaction", | ||||||
| 			PublicKey: []byte("0x1241527192"), | 			Amount:    []byte("0.002 CELO"), | ||||||
| 			Amount:    []byte("0.002CELO"), |  | ||||||
| 			Recipient: []byte("0x12415ass27192"), | 			Recipient: []byte("0x12415ass27192"), | ||||||
| 			expectedResult: resource.Result{ | 			expectedResult: resource.Result{ | ||||||
| 				FlagReset: []uint32{account_authorized_flag}, | 				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 { | 	for _, tt := range tests { | ||||||
| 		t.Run(tt.name, func(t *testing.T) { | 		t.Run(tt.name, func(t *testing.T) { | ||||||
| 			// Define expected interactions with the mock
 | 			// 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_AMOUNT).Return(tt.Amount, nil) | ||||||
| 			mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_RECIPIENT).Return(tt.Recipient, 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
 | 			// Call the method under test
 | ||||||
| 			res, _ := h.InitiateTransaction(ctx, "transaction_reset_amount", tt.input) | 			res, _ := h.InitiateTransaction(ctx, "transaction_reset_amount", tt.input) | ||||||
| @ -1344,10 +1348,8 @@ func TestInitiateTransaction(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 			// Assert that expectations were met
 | 			// Assert that expectations were met
 | ||||||
| 			mockDataStore.AssertExpectations(t) | 			mockDataStore.AssertExpectations(t) | ||||||
| 
 |  | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestQuit(t *testing.T) { | func TestQuit(t *testing.T) { | ||||||
| @ -1626,7 +1628,6 @@ func TestValidateRecipient(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCheckBalance(t *testing.T) { | func TestCheckBalance(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	sessionId := "session123" | 	sessionId := "session123" | ||||||
| 	publicKey := "0X13242618721" | 	publicKey := "0X13242618721" | ||||||
| 	fm, _ := NewFlagManager(flagsPath) | 	fm, _ := NewFlagManager(flagsPath) | ||||||
| @ -1668,7 +1669,7 @@ func TestCheckBalance(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResult: resource.Result{ | 			expectedResult: resource.Result{ | ||||||
| 				Content:   "0.003 CELO", | 				Content:   "Balance: 0.003 CELO\n", | ||||||
| 				FlagReset: []uint32{flag_api_error}, | 				FlagReset: []uint32{flag_api_error}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| @ -1701,10 +1702,8 @@ func TestCheckBalance(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 			//Assert that the result set to content is what was expected
 | 			//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") | 			assert.Equal(t, res, tt.expectedResult, "Result should contain flags set according to user input") | ||||||
| 
 |  | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetProfile(t *testing.T) { | func TestGetProfile(t *testing.T) { | ||||||
|  | |||||||
| @ -1,14 +1,9 @@ | |||||||
| package models | package models | ||||||
| 
 | 
 | ||||||
| import ( |  | ||||||
| 	"encoding/json" |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type AccountResponse struct { | type AccountResponse struct { | ||||||
| 	Ok          bool   `json:"ok"` | 	Ok          bool   `json:"ok"` | ||||||
|  | 	Description string `json:"description"` // Include the description field
 | ||||||
| 	Result      struct { | 	Result      struct { | ||||||
| 		CustodialId json.Number `json:"custodialId"` |  | ||||||
| 		PublicKey  string `json:"publicKey"` | 		PublicKey  string `json:"publicKey"` | ||||||
| 		TrackingId string `json:"trackingId"` | 		TrackingId string `json:"trackingId"` | ||||||
| 	} `json:"result"` | 	} `json:"result"` | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ import ( | |||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 |  | ||||||
| type Transaction struct { | type Transaction struct { | ||||||
| 	CreatedAt     time.Time   `json:"createdAt"` | 	CreatedAt     time.Time   `json:"createdAt"` | ||||||
| 	Status        string      `json:"status"` | 	Status        string      `json:"status"` | ||||||
|  | |||||||
| @ -1,7 +1,10 @@ | |||||||
| package mocks | package mocks | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  | 
 | ||||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | 	"git.grassecon.net/urdt/ussd/internal/models" | ||||||
|  | 	"github.com/grassrootseconomics/eth-custodial/pkg/api" | ||||||
| 	"github.com/stretchr/testify/mock" | 	"github.com/stretchr/testify/mock" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -10,17 +13,22 @@ type MockAccountService struct { | |||||||
| 	mock.Mock | 	mock.Mock | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) { | func (m *MockAccountService) CreateAccount(ctx context.Context) (*api.OKResponse, error) { | ||||||
| 	args := m.Called() | 	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) | 	args := m.Called(publicKey) | ||||||
| 	return args.Get(0).(*models.BalanceResponse), args.Error(1) | 	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) | 	args := m.Called(trackingId) | ||||||
| 	return args.Get(0).(*models.TrackStatusResponse), args.Error(1) | 	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) | ||||||
|  | } | ||||||
|  | |||||||
| @ -7,6 +7,8 @@ msgstr "Ombi lako limetumwa. %s atapokea %s kutoka kwa %s." | |||||||
| msgid "Thank you for using Sarafu. Goodbye!" | msgid "Thank you for using Sarafu. Goodbye!" | ||||||
| msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" | msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| msgid "For more help,please call: 0757628885" | msgid "For more help,please call: 0757628885" | ||||||
| msgstr "Kwa usaidizi zaidi,piga: 0757628885" | msgstr "Kwa usaidizi zaidi,piga: 0757628885" | ||||||
|  | 
 | ||||||
|  | msgid "Balance: %s\n" | ||||||
|  | msgstr "Salio: %s\n" | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| Balance: {{.check_balance}} | {{.check_balance}} | ||||||
| @ -1 +1 @@ | |||||||
| Salio: {{.check_balance}} | {{.check_balance}} | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
What is this backoption please?
The backOption is used to check if the input was "0" in the edit profile information context,then we should not consider that a valid profile information entry.
I understand, but wouldnt the INCMP take care of avoiding that?