feat: команда /help — справка по всем командам бота
This commit is contained in:
@@ -198,8 +198,11 @@ func (a *App) handleIncoming(inc chat.Incoming) {
|
||||
|
||||
// update/status — команды бинаря вне машины состояний задач.
|
||||
// /status перехватываем только без числового аргумента (/status N — статус задачи).
|
||||
if cmdName(text) == "/update" || (cmdName(text) == "/status" && !hasArg(text)) {
|
||||
a.handleUpdateCommand(ctx, uid, text)
|
||||
// /help — справка по всем командам (тоже команда бинаря, вне задач).
|
||||
if cmdName(text) == "/help" ||
|
||||
cmdName(text) == "/update" ||
|
||||
(cmdName(text) == "/status" && !hasArg(text)) {
|
||||
a.handleBinaryCommand(ctx, uid, text)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -342,16 +345,37 @@ func (a *App) autoCheckOnce(ctx context.Context) {
|
||||
a.send(ctx, uid, msg)
|
||||
}
|
||||
|
||||
// handleUpdateCommand — маршрутизация /update и /status.
|
||||
func (a *App) handleUpdateCommand(ctx context.Context, uid chat.UserID, text string) {
|
||||
// handleBinaryCommand — маршрутизация бинарных команд: /help, /update, /status.
|
||||
func (a *App) handleBinaryCommand(ctx context.Context, uid chat.UserID, text string) {
|
||||
switch cmdName(text) {
|
||||
case "/status":
|
||||
a.handleStatusCmd(ctx, uid)
|
||||
case "/update":
|
||||
a.handleUpdateCmd(ctx, uid)
|
||||
case "/help":
|
||||
a.handleHelpCmd(ctx, uid)
|
||||
}
|
||||
}
|
||||
|
||||
// helpText — текст команды /help.
|
||||
const helpText = "⚡ **Ratatoskr** — помогу продумать задачу и запущу агента.\n\n" +
|
||||
"**Команды:**\n" +
|
||||
"`/start` — новая задача\n" +
|
||||
"`/cancel` — отменить текущую\n" +
|
||||
"`/skip` — хватит вопросов, предложить черновик\n" +
|
||||
"`/retry N` — перезапустить задачу `N`\n" +
|
||||
"`/status N` — статус задачи `N`\n" +
|
||||
"`/continue N` — продолжить задачу `N`\n" +
|
||||
"`/status` — статус бинаря и обновления\n" +
|
||||
"`/update` — применить обновление\n" +
|
||||
"`/help` — эта справка\n\n" +
|
||||
"Просто опишите задачу — я помогу её продумать."
|
||||
|
||||
// handleHelpCmd отвечает списком команд.
|
||||
func (a *App) handleHelpCmd(ctx context.Context, uid chat.UserID) {
|
||||
a.send(ctx, uid, helpText)
|
||||
}
|
||||
|
||||
// handleStatusCmd отвечает текущей версией и результатом последней проверки.
|
||||
func (a *App) handleStatusCmd(ctx context.Context, uid chat.UserID) {
|
||||
if a.Config.Update.Enabled && a.Updater != nil {
|
||||
|
||||
@@ -163,3 +163,33 @@ func TestNew_UpdateWiring(t *testing.T) {
|
||||
t.Errorf("Token = %q, want embedded-update-token (вшитый приоритетнее)", a2.Updater.Token)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHelp_IsBinaryCommand проверяет, что /help распознаётся cmdName и, значит,
|
||||
// в handleIncoming попадёт в бинарную ветку (не в машину состояний задач).
|
||||
// Косвенно: /help не должен иметь аргумента-номера задачи (как /status N).
|
||||
func TestHelp_IsBinaryCommand(t *testing.T) {
|
||||
if got := cmdName("/help"); got != "/help" {
|
||||
t.Errorf("cmdName(/help) = %q, want /help", got)
|
||||
}
|
||||
if hasArg("/help") {
|
||||
t.Errorf("/help не должен требовать аргумент")
|
||||
}
|
||||
if got := cmdName("/help foo"); got != "/help" {
|
||||
t.Errorf("cmdName(/help foo) = %q, want /help", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHelpText_ContainsCommands проверяет, что справка упоминает все команды.
|
||||
func TestHelpText_ContainsCommands(t *testing.T) {
|
||||
for _, cmd := range []string{
|
||||
"/start", "/cancel", "/skip", "/retry", "/status", "/continue",
|
||||
"/update", "/help",
|
||||
} {
|
||||
if !strings.Contains(helpText, cmd) {
|
||||
t.Errorf("helpText не упоминает команду %s", cmd)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(helpText, "Ratatoskr") {
|
||||
t.Errorf("helpText не содержит имени бота")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user