diff --git a/go.mod b/go.mod index 7836057..1ce7f3c 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 1064bb8..c369628 100644 --- a/go.sum +++ b/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= diff --git a/handlers/application/menuhandler.go b/handlers/application/menuhandler.go index 94748eb..0effbec 100644 --- a/handlers/application/menuhandler.go +++ b/handlers/application/menuhandler.go @@ -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) - 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) - return res, nil + // 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 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 + logg.InfoCtxf(ctx, "Suggested alias", "alias", alias) } - res.FlagReset = append(res.FlagReset, flag_api_error) - - 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) diff --git a/handlers/application/menuhandler_test.go b/handlers/application/menuhandler_test.go index 48ee27b..0463e01 100644 --- a/handlers/application/menuhandler_test.go +++ b/handlers/application/menuhandler_test.go @@ -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"