test(17-03): add unit tests for bot command handlers

- Test extractArg parsing for all command formats
- Test isPrivateChat detection (private vs group vs supergroup)
- Test commandHelp contains all 8 commands with descriptions
- Test storageToEngine conversion fidelity
- Test New constructor wires startedAt correctly
This commit is contained in:
salvacybersec
2026-04-06 17:35:23 +03:00
parent 9ad58534fc
commit 202473a799

96
pkg/bot/handlers_test.go Normal file
View File

@@ -0,0 +1,96 @@
package bot
import (
"strings"
"testing"
"github.com/mymmrac/telego"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/salvacybersec/keyhunter/pkg/storage"
)
func TestExtractArg(t *testing.T) {
tests := []struct {
input string
want string
}{
{"/help", ""},
{"/scan /tmp/repo", "/tmp/repo"},
{"/verify 42", "42"},
{"/key 99 ", "99"},
{"/recon --sources=github,gitlab", "--sources=github,gitlab"},
{"", ""},
}
for _, tt := range tests {
got := extractArg(tt.input)
assert.Equal(t, tt.want, got, "extractArg(%q)", tt.input)
}
}
func TestIsPrivateChat(t *testing.T) {
private := &telego.Message{Chat: telego.Chat{Type: "private"}}
group := &telego.Message{Chat: telego.Chat{Type: "group"}}
supergroup := &telego.Message{Chat: telego.Chat{Type: "supergroup"}}
assert.True(t, isPrivateChat(private))
assert.False(t, isPrivateChat(group))
assert.False(t, isPrivateChat(supergroup))
}
func TestCommandHelpContainsAllCommands(t *testing.T) {
expectedCommands := []string{"/help", "/scan", "/verify", "/recon", "/status", "/stats", "/providers", "/key"}
require.Len(t, commandHelp, len(expectedCommands), "commandHelp should have %d entries", len(expectedCommands))
for _, expected := range expectedCommands {
found := false
for _, c := range commandHelp {
if strings.HasPrefix(c.Cmd, expected) {
found = true
assert.NotEmpty(t, c.Desc, "command %s should have a description", expected)
break
}
}
assert.True(t, found, "command %s should be in commandHelp", expected)
}
}
func TestCommandHelpDescriptionsNonEmpty(t *testing.T) {
for _, c := range commandHelp {
assert.NotEmpty(t, c.Desc, "command %s must have a description", c.Cmd)
}
}
func TestStorageToEngine(t *testing.T) {
sf := storageToEngine(dummyStorageFinding())
assert.Equal(t, "openai", sf.ProviderName)
assert.Equal(t, "sk-****abcd", sf.KeyMasked)
assert.Equal(t, "test.txt", sf.Source)
assert.Equal(t, "file", sf.SourceType)
assert.Equal(t, 10, sf.LineNumber)
}
// TestNewBot verifies the constructor wires all dependencies.
func TestNewBot(t *testing.T) {
b := New(nil, Deps{})
require.NotNil(t, b)
assert.False(t, b.startedAt.IsZero(), "startedAt should be set")
assert.True(t, b.lastScan.IsZero(), "lastScan should be zero initially")
}
// --- helpers ---
func dummyStorageFinding() storage.Finding {
return storage.Finding{
ID: 1,
ProviderName: "openai",
KeyValue: "sk-realkey1234",
KeyMasked: "sk-****abcd",
Confidence: "high",
SourcePath: "test.txt",
SourceType: "file",
LineNumber: 10,
}
}