fix: computeTrend division by zero, add tests for trend and currency parsing, add username to settings

This commit is contained in:
2026-06-25 01:58:27 +03:30
parent 88ccc6aa68
commit 85587d563d
4 changed files with 104 additions and 18 deletions

View File

@@ -6,6 +6,7 @@ import (
"math"
"strings"
"time"
"unicode"
"github.com/go-telegram/bot/models"
@@ -179,6 +180,20 @@ func (h *Handler) handleSetRateMsg(ctx context.Context, msg *models.Message) {
h.sendText(ctx, msg.Chat.ID, fmt.Sprintf("Hourly rate set to %s%.2f", currencySymbol(st.Currency), st.HourlyRate))
}
// parseCurrencyInput validates and normalizes currency input (symbol + code).
func parseCurrencyInput(s string) (string, string) {
parts := strings.Fields(s)
if len(parts) < 2 {
return "", "Please provide both symbol and code.\nUsage: /setcurrency <symbol> <code>\nExamples:\n/setcurrency $ USD\n/setcurrency T Toman\n/setcurrency IRR Rial"
}
for _, p := range parts[:2] {
if len(p) > 10 || strings.ContainsFunc(p, unicode.IsControl) {
return "", "Invalid currency. Use short printable strings like $ USD, T Toman, IRR Rial."
}
}
return parts[0] + " " + parts[1], ""
}
// handleSetCurrencyMsg handles /setcurrency <symbol> <code>.
func (h *Handler) handleSetCurrencyMsg(ctx context.Context, msg *models.Message) {
args := strings.TrimSpace(strings.TrimPrefix(msg.Text, "/setcurrency"))
@@ -192,20 +207,11 @@ func (h *Handler) handleSetCurrencyMsg(ctx context.Context, msg *models.Message)
h.sendText(ctx, msg.Chat.ID, fmt.Sprintf("Current currency: %s\nUsage: /setcurrency <symbol> <code>\nExamples:\n/setcurrency $ USD\n/setcurrency T Toman\n/setcurrency IRR Rial", st.Currency))
return
}
parts := strings.Fields(args)
if len(parts) < 2 {
h.sendText(ctx, msg.Chat.ID, "Please provide both symbol and code.\nUsage: /setcurrency <symbol> <code>\nExamples:\n/setcurrency $ USD\n/setcurrency T Toman\n/setcurrency IRR Rial")
currency, errMsg := parseCurrencyInput(args)
if errMsg != "" {
h.sendText(ctx, msg.Chat.ID, errMsg)
return
}
if len(parts[0]) > 10 || strings.ContainsFunc(parts[0], func(r rune) bool { return r < 32 || r > 126 }) {
h.sendText(ctx, msg.Chat.ID, "Invalid currency symbol. Use a short printable string like $, €, £.")
return
}
if len(parts[1]) > 10 || strings.ContainsFunc(parts[1], func(r rune) bool { return r < 32 || r > 126 }) {
h.sendText(ctx, msg.Chat.ID, "Invalid currency code.")
return
}
currency := parts[0] + " " + parts[1]
user, err := h.getOrCreateUser(msg.Chat.ID)
if err != nil {
h.sendText(ctx, msg.Chat.ID, "Error loading profile")