add balance to voucher list #89
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -5,7 +5,7 @@ go 1.23.4
 | 
			
		||||
require (
 | 
			
		||||
	git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66
 | 
			
		||||
	git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20250417111317-2953f4c2f32e
 | 
			
		||||
	git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624090744-339ba854c997
 | 
			
		||||
	git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a
 | 
			
		||||
	git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306
 | 
			
		||||
	git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694
 | 
			
		||||
	github.com/alecthomas/assert/v2 v2.2.2
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							@ -12,6 +12,14 @@ git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624074830-
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624074830-5aa032400c12/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624090744-339ba854c997 h1:8bCKyYoV4YiVBvCZlRclc3aQlBYpWhgtM35mvniDFD8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624090744-339ba854c997/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250626065419-57ee409f9629 h1:ew3vCFrLS/7/8uULTTPCbsHzFntQ6X68SScnBEy3pl0=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250626065419-57ee409f9629/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213135-50ee455e7069 h1:re+hdr5NAC6JqhyvjMCkgX17fFi0u3Mawc6RBnBJW8I=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213135-50ee455e7069/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-12940bb5f284 h1:2zMU9jPd6xEO6oY9oxr84sdT9G3d09eyAkjVBAz9eco=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-12940bb5f284/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a h1:KuhJ/WY4RCGmrXUA680ciaponM4vM5zBOJfnCpUo2fc=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306 h1:Jo+yWysWw/N5BJQtAyEMN8ePVvAyPHv+JG4lQti+1N4=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306/go.mod h1:FdLwYtzsjOIcDiW4uDgDYnB4Wdzq12uJUe0QHSSPbSo=
 | 
			
		||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 h1:DjJlBSz0S13acft5XZDWk7ZYnzElym0xLMYEVgyNJ+E=
 | 
			
		||||
 | 
			
		||||
@ -2575,55 +2575,10 @@ func (h *MenuHandlers) persistLanguageCode(ctx context.Context, code string) err
 | 
			
		||||
	return h.persistInitialLanguageCode(ctx, sessionId, code)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// constructAccountAlias retrieves and alias based on the first and family name
 | 
			
		||||
// and writes the result in DATA_ACCOUNT_ALIAS
 | 
			
		||||
func (h *MenuHandlers) constructAccountAlias(ctx context.Context) error {
 | 
			
		||||
	var alias string
 | 
			
		||||
	store := h.userdataStore
 | 
			
		||||
	sessionId, ok := ctx.Value("SessionId").(string)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return fmt.Errorf("missing session")
 | 
			
		||||
	}
 | 
			
		||||
	firstName, err := store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if db.IsNotFound(err) {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	familyName, err := store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if db.IsNotFound(err) {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	pubKey, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if db.IsNotFound(err) {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	aliasInput := fmt.Sprintf("%s%s", firstName, familyName)
 | 
			
		||||
	aliasResult, err := h.accountService.RequestAlias(ctx, string(pubKey), aliasInput)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logg.ErrorCtxf(ctx, "failed to retrieve alias", "alias", aliasInput, "error_alias_request", err)
 | 
			
		||||
		return fmt.Errorf("Failed to retrieve alias: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	alias = aliasResult.Alias
 | 
			
		||||
	//Store the alias
 | 
			
		||||
	err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS, []byte(alias))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logg.ErrorCtxf(ctx, "failed to write account alias", "key", storedb.DATA_ACCOUNT_ALIAS, "value", alias, "error", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RequestCustomAlias requests an ENS based alias name based on a user's input,then saves it as temporary value
 | 
			
		||||
func (h *MenuHandlers) RequestCustomAlias(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
			
		||||
	var res resource.Result
 | 
			
		||||
	var alias string
 | 
			
		||||
	sessionId, ok := ctx.Value("SessionId").(string)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return res, fmt.Errorf("missing session")
 | 
			
		||||
@ -2648,28 +2603,45 @@ func (h *MenuHandlers) RequestCustomAlias(ctx context.Context, sym string, input
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return res, err
 | 
			
		||||
		}
 | 
			
		||||
		pubKey, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
 | 
			
		||||
		publicKey, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if db.IsNotFound(err) {
 | 
			
		||||
				return res, nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		sanitizedInput := sanitizeAliasHint(string(input))
 | 
			
		||||
		aliasResult, err := h.accountService.RequestAlias(ctx, string(pubKey), sanitizedInput)
 | 
			
		||||
		// Check if an alias already exists
 | 
			
		||||
		existingAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS)
 | 
			
		||||
		if err == nil && len(existingAlias) > 0 {
 | 
			
		||||
			logg.InfoCtxf(ctx, "Current alias", "alias", string(existingAlias))
 | 
			
		||||
			// Update existing alias
 | 
			
		||||
			aliasResult, err := h.accountService.UpdateAlias(ctx, sanitizedInput, string(publicKey))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				res.FlagSet = append(res.FlagSet, flag_api_error)
 | 
			
		||||
			logg.ErrorCtxf(ctx, "failed to retrieve alias", "alias", string(aliasHint), "error_alias_request", err)
 | 
			
		||||
				logg.ErrorCtxf(ctx, "failed to update alias", "alias", sanitizedInput, "error", err)
 | 
			
		||||
				return res, nil
 | 
			
		||||
			}
 | 
			
		||||
			alias = aliasResult.Alias
 | 
			
		||||
			logg.InfoCtxf(ctx, "Updated alias", "alias", alias)
 | 
			
		||||
		} else {
 | 
			
		||||
			logg.InfoCtxf(ctx, "Registering a new alias", "err", err)
 | 
			
		||||
			// Register a new alias
 | 
			
		||||
			aliasResult, err := h.accountService.RequestAlias(ctx, string(publicKey), sanitizedInput)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				res.FlagSet = append(res.FlagSet, flag_api_error)
 | 
			
		||||
				logg.ErrorCtxf(ctx, "failed to retrieve alias", "alias", sanitizedInput, "error_alias_request", err)
 | 
			
		||||
				return res, nil
 | 
			
		||||
			}
 | 
			
		||||
			res.FlagReset = append(res.FlagReset, flag_api_error)
 | 
			
		||||
 | 
			
		||||
		alias := aliasResult.Alias
 | 
			
		||||
			alias = aliasResult.Alias
 | 
			
		||||
			logg.InfoCtxf(ctx, "Suggested alias", "alias", alias)
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		//Store the returned alias,wait for user to confirm it as new account alias
 | 
			
		||||
		logg.InfoCtxf(ctx, "Final suggested alias", "alias", alias)
 | 
			
		||||
		err = store.WriteEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS, []byte(alias))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logg.ErrorCtxf(ctx, "failed to write account alias", "key", storedb.DATA_TEMPORARY_VALUE, "value", alias, "error", err)
 | 
			
		||||
			logg.ErrorCtxf(ctx, "failed to write suggested alias", "key", storedb.DATA_SUGGESTED_ALIAS, "value", alias, "error", err)
 | 
			
		||||
			return res, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -2697,7 +2669,8 @@ func (h *MenuHandlers) GetSuggestedAlias(ctx context.Context, sym string, input
 | 
			
		||||
		return res, fmt.Errorf("missing session")
 | 
			
		||||
	}
 | 
			
		||||
	suggestedAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
	if err != nil && len(suggestedAlias) <= 0 {
 | 
			
		||||
		logg.ErrorCtxf(ctx, "failed to read suggested alias", "key", storedb.DATA_SUGGESTED_ALIAS, "error", err)
 | 
			
		||||
		return res, nil
 | 
			
		||||
	}
 | 
			
		||||
	res.Content = string(suggestedAlias)
 | 
			
		||||
 | 
			
		||||
@ -3175,97 +3175,6 @@ func TestResetUnregisteredNumber(t *testing.T) {
 | 
			
		||||
	assert.Equal(t, expectedResult, res)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestConstructAccountAlias(t *testing.T) {
 | 
			
		||||
	ctx, store := InitializeTestStore(t)
 | 
			
		||||
	sessionId := "session123"
 | 
			
		||||
	mockAccountService := new(mocks.MockAccountService)
 | 
			
		||||
 | 
			
		||||
	ctx = context.WithValue(ctx, "SessionId", sessionId)
 | 
			
		||||
 | 
			
		||||
	h := &MenuHandlers{
 | 
			
		||||
		userdataStore:  store,
 | 
			
		||||
		accountService: mockAccountService,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name          string
 | 
			
		||||
		firstName     string
 | 
			
		||||
		familyName    string
 | 
			
		||||
		publicKey     string
 | 
			
		||||
		expectedAlias string
 | 
			
		||||
		aliasResponse *models.RequestAliasResult
 | 
			
		||||
		aliasError    error
 | 
			
		||||
		expectedError error
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:          "Valid alias construction",
 | 
			
		||||
			firstName:     "John",
 | 
			
		||||
			familyName:    "Doe",
 | 
			
		||||
			publicKey:     "pubkey123",
 | 
			
		||||
			expectedAlias: "JohnDoeAlias",
 | 
			
		||||
			aliasResponse: &models.RequestAliasResult{Alias: "JohnDoeAlias"},
 | 
			
		||||
			aliasError:    nil,
 | 
			
		||||
			expectedError: nil,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:          "Account service fails to return alias",
 | 
			
		||||
			firstName:     "Jane",
 | 
			
		||||
			familyName:    "Smith",
 | 
			
		||||
			publicKey:     "pubkey456",
 | 
			
		||||
			expectedAlias: "",
 | 
			
		||||
			aliasResponse: nil,
 | 
			
		||||
			aliasError:    fmt.Errorf("service unavailable"),
 | 
			
		||||
			expectedError: fmt.Errorf("Failed to retrieve alias: service unavailable"),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			if tt.firstName != "" {
 | 
			
		||||
				err := store.WriteEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(tt.firstName))
 | 
			
		||||
				require.NoError(t, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if tt.familyName != "" {
 | 
			
		||||
				err := store.WriteEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(tt.familyName))
 | 
			
		||||
				require.NoError(t, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if tt.publicKey != "" {
 | 
			
		||||
				err := store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(tt.publicKey))
 | 
			
		||||
				require.NoError(t, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			aliasInput := fmt.Sprintf("%s%s", tt.firstName, tt.familyName)
 | 
			
		||||
 | 
			
		||||
			// Mock service behavior
 | 
			
		||||
			mockAccountService.On(
 | 
			
		||||
				"RequestAlias",
 | 
			
		||||
				tt.publicKey,
 | 
			
		||||
				aliasInput,
 | 
			
		||||
			).Return(tt.aliasResponse, tt.aliasError)
 | 
			
		||||
 | 
			
		||||
			// Call the function under test
 | 
			
		||||
			err := h.constructAccountAlias(ctx)
 | 
			
		||||
 | 
			
		||||
			// Assertions
 | 
			
		||||
			if tt.expectedError != nil {
 | 
			
		||||
				assert.EqualError(t, err, tt.expectedError.Error())
 | 
			
		||||
			} else {
 | 
			
		||||
				assert.NoError(t, err)
 | 
			
		||||
				if tt.expectedAlias != "" {
 | 
			
		||||
					storedAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
 | 
			
		||||
					require.NoError(t, err)
 | 
			
		||||
					assert.Equal(t, tt.expectedAlias, string(storedAlias))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Ensure mock expectations were met
 | 
			
		||||
			mockAccountService.AssertExpectations(t)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestInsertProfileItems(t *testing.T) {
 | 
			
		||||
	ctx, store := InitializeTestStore(t)
 | 
			
		||||
	sessionId := "session123"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user