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:
96
pkg/bot/handlers_test.go
Normal file
96
pkg/bot/handlers_test.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user