From 238e4bb31422e6c6754fd77f94a7acfd93ef0a64 Mon Sep 17 00:00:00 2001 From: n0ctal <4c866w5fn9@privaterelay.appleid.com> Date: Thu, 13 Aug 2026 15:41:47 +0500 Subject: [PATCH] refactor(tgbot): share numeric keypad transitions (#6211) Co-authored-by: n0ctal <293235942+n0ctal@users.noreply.github.com> --- internal/web/service/tgbot/numeric_input.go | 18 +++++ .../web/service/tgbot/numeric_input_test.go | 38 +++++++++++ internal/web/service/tgbot/tgbot_router.go | 66 ++----------------- 3 files changed, 62 insertions(+), 60 deletions(-) create mode 100644 internal/web/service/tgbot/numeric_input.go create mode 100644 internal/web/service/tgbot/numeric_input_test.go diff --git a/internal/web/service/tgbot/numeric_input.go b/internal/web/service/tgbot/numeric_input.go new file mode 100644 index 000000000..e9269af8a --- /dev/null +++ b/internal/web/service/tgbot/numeric_input.go @@ -0,0 +1,18 @@ +package tgbot + +// updateNumericInput applies one key from the shared inline number pad. +// Key -2 clears the value, -1 removes the last decimal digit, and 0..9 append +// a digit. Callers retain their own validation and keyboard labels. +func updateNumericInput(value, key int) int { + switch key { + case -2: + return 0 + case -1: + if value > 0 { + return value / 10 + } + return value + default: + return value*10 + key + } +} diff --git a/internal/web/service/tgbot/numeric_input_test.go b/internal/web/service/tgbot/numeric_input_test.go new file mode 100644 index 000000000..9f744b585 --- /dev/null +++ b/internal/web/service/tgbot/numeric_input_test.go @@ -0,0 +1,38 @@ +package tgbot + +import ( + "os" + "strings" + "testing" +) + +func TestUpdateNumericInput(t *testing.T) { + tests := []struct { + name string + value, key int + want int + }{ + {name: "append digit", value: 12, key: 3, want: 123}, + {name: "append zero", value: 12, key: 0, want: 120}, + {name: "backspace", value: 123, key: -1, want: 12}, + {name: "backspace zero", value: 0, key: -1, want: 0}, + {name: "clear", value: 123, key: -2, want: 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := updateNumericInput(tt.value, tt.key); got != tt.want { + t.Fatalf("updateNumericInput(%d, %d) = %d, want %d", tt.value, tt.key, got, tt.want) + } + }) + } +} + +func TestNumericInputTransitionIsUsedByEveryKeypad(t *testing.T) { + source, err := os.ReadFile("tgbot_router.go") + if err != nil { + t.Fatalf("read tgbot_router.go: %v", err) + } + if got := strings.Count(string(source), "updateNumericInput("); got != 6 { + t.Fatalf("numeric keypad transition call sites = %d, want 6", got) + } +} diff --git a/internal/web/service/tgbot/tgbot_router.go b/internal/web/service/tgbot/tgbot_router.go index c45fd3c08..bc45b419d 100644 --- a/internal/web/service/tgbot/tgbot_router.go +++ b/internal/web/service/tgbot/tgbot_router.go @@ -439,16 +439,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 4 { num, err := strconv.Atoi(dataArray[3]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) @@ -509,16 +500,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 3 { num, err := strconv.Atoi(dataArray[2]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) @@ -639,16 +621,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 4 { num, err := strconv.Atoi(dataArray[3]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) @@ -721,16 +694,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 3 { num, err := strconv.Atoi(dataArray[2]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) @@ -827,16 +791,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 4 { num, err := strconv.Atoi(dataArray[3]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) @@ -900,16 +855,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 3 { num, err := strconv.Atoi(dataArray[2]) if err == nil { - switch num { - case -2: - inputNumber = 0 - case -1: - if inputNumber > 0 { - inputNumber = (inputNumber / 10) - } - default: - inputNumber = (inputNumber * 10) + num - } + inputNumber = updateNumericInput(inputNumber, num) } if inputNumber == oldInputNumber { t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))