More autogenerated tests!
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMsgParser_Validation(t *testing.T) {
|
||||
@@ -349,3 +350,372 @@ func TestMsgParser_BuildsMsgCorrectly(t *testing.T) {
|
||||
}
|
||||
|
||||
var _ = context.Background // for import
|
||||
|
||||
func TestMsgParser_MultiCharCsign(t *testing.T) {
|
||||
origConfig := Config
|
||||
Config = myConfig{
|
||||
Csign: "!!!",
|
||||
ForwardChannels: struct {
|
||||
Games string `json:"games,omitempty"`
|
||||
Phrases string `json:"phrases,omitempty"`
|
||||
Webapp string `json:"webapp,omitempty"`
|
||||
WebappGo string `json:"webapp-go,omitempty"`
|
||||
Craniac string `json:"craniac,omitempty"`
|
||||
}{
|
||||
Games: "games",
|
||||
Phrases: "phrases",
|
||||
Webapp: "webapp",
|
||||
WebappGo: "webapp-go",
|
||||
Craniac: "craniac",
|
||||
},
|
||||
ForwardsMax: 5,
|
||||
}
|
||||
defer func() { Config = origConfig }()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
csign string
|
||||
expected string
|
||||
}{
|
||||
{"double char csign !!", "!!karma", "!!", "phrases"},
|
||||
{"triple char csign !!!", "!!!friday", "!!!", "phrases"},
|
||||
{"slash csign /", "/help", "/", "craniac"},
|
||||
{"dot csign .", ".status", ".", "craniac"},
|
||||
{"message shorter than csign", "!", "!!", "craniac"},
|
||||
{"message equal to csign", "!!", "!!", "craniac"},
|
||||
{"message longer than csign", "!!!test", "!!!", "craniac"},
|
||||
{"russian with multi char csign", "!!!погода", "!!!", "webapp-go"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := determineChannel(tt.message, tt.csign)
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %s, got %s", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_FwdcntLoopPrevention(t *testing.T) {
|
||||
origConfig := Config
|
||||
Config = myConfig{
|
||||
Csign: "!",
|
||||
ForwardsMax: 5,
|
||||
}
|
||||
defer func() { Config = origConfig }()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fwdcnt int64
|
||||
expected bool // true = should be discarded
|
||||
}{
|
||||
{"fwdcnt 0 allowed", 0, false},
|
||||
{"fwdcnt 1 allowed", 1, false},
|
||||
{"fwdcnt 5 allowed", 5, false},
|
||||
{"fwdcnt 6 discarded", 6, true},
|
||||
{"fwdcnt 10 discarded", 10, true},
|
||||
{"fwdcnt 100 discarded", 100, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
shouldDiscard := tt.fwdcnt > Config.ForwardsMax
|
||||
if shouldDiscard != tt.expected {
|
||||
t.Errorf("fwdcnt=%d: expected discard=%v, got %v", tt.fwdcnt, tt.expected, shouldDiscard)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_DefaultCsignFromConfig(t *testing.T) {
|
||||
origConfig := Config
|
||||
Config = myConfig{
|
||||
Csign: "!",
|
||||
ForwardChannels: struct {
|
||||
Games string `json:"games,omitempty"`
|
||||
Phrases string `json:"phrases,omitempty"`
|
||||
Webapp string `json:"webapp,omitempty"`
|
||||
WebappGo string `json:"webapp-go,omitempty"`
|
||||
Craniac string `json:"craniac,omitempty"`
|
||||
}{
|
||||
Phrases: "phrases",
|
||||
},
|
||||
}
|
||||
defer func() { Config = origConfig }()
|
||||
|
||||
// When csign is empty in message, it should use Config.Csign
|
||||
message := "!karma"
|
||||
csign := ""
|
||||
|
||||
if csign == "" {
|
||||
csign = Config.Csign
|
||||
}
|
||||
|
||||
result := determineChannel(message, csign)
|
||||
if result != "phrases" {
|
||||
t.Errorf("expected phrases, got %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_KarmaAnswerFlag(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
command string
|
||||
expectAnswer bool
|
||||
}{
|
||||
{"karma without args sets answer", "karma", true},
|
||||
// Note: "karma user" (with arg) doesn't match "karma " pattern, so Answer is NOT set
|
||||
{"karma with space and arg", "karma user", false},
|
||||
{"russian karma without args", "карма", true},
|
||||
// Note: Russian karma with args requires different handling due to UTF-8 encoding
|
||||
{"friday no answer", "friday", false},
|
||||
{"fortune no answer", "fortune", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Simulate the karma answer logic (checks for exact match)
|
||||
isExactKarma := tt.command == "karma" || tt.command == "карма"
|
||||
shouldSetAnswer := isExactKarma
|
||||
|
||||
if shouldSetAnswer != tt.expectAnswer {
|
||||
t.Errorf("command=%s: expected answer=%v, got %v", tt.command, tt.expectAnswer, shouldSetAnswer)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_EmptyCommandAfterCsign(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
csign string
|
||||
expected string
|
||||
}{
|
||||
{"just csign", "!", "!", "craniac"},
|
||||
{"csign with space", "! ", "!", "craniac"},
|
||||
{"double csign", "!!", "!!", "craniac"},
|
||||
{"double csign with space", "!! ", "!!", "craniac"},
|
||||
{"slash with space", "/ ", "/", "craniac"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := determineChannel(tt.message, tt.csign)
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %s, got %s", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_MoreRussianCommands(t *testing.T) {
|
||||
origConfig := Config
|
||||
Config = myConfig{
|
||||
Csign: "!",
|
||||
ForwardChannels: struct {
|
||||
Games string `json:"games,omitempty"`
|
||||
Phrases string `json:"phrases,omitempty"`
|
||||
Webapp string `json:"webapp,omitempty"`
|
||||
WebappGo string `json:"webapp-go,omitempty"`
|
||||
Craniac string `json:"craniac,omitempty"`
|
||||
}{
|
||||
Games: "games",
|
||||
Phrases: "phrases",
|
||||
WebappGo: "webapp-go",
|
||||
},
|
||||
}
|
||||
defer func() { Config = origConfig }()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
expected string
|
||||
}{
|
||||
// Russian weather commands
|
||||
{"russian pogoda", "!погода", "webapp-go"},
|
||||
{"russian pogodka", "!погодка", "webapp-go"},
|
||||
{"russian pogadka", "!погадка", "webapp-go"},
|
||||
{"russian pogoda with city", "!погода Москва", "webapp-go"},
|
||||
|
||||
// Russian games commands
|
||||
{"russian kopat", "!копать", "games"},
|
||||
{"russian ryba", "!рыба", "games"},
|
||||
{"russian ribka", "!рыбка", "games"},
|
||||
{"russian rybalka", "!рыбалка", "games"},
|
||||
|
||||
// Russian phrases commands
|
||||
{"russian friday", "!пятница", "phrases"},
|
||||
{"russian proverb", "!пословица", "phrases"},
|
||||
{"russian fortune", "!фортунка", "phrases"},
|
||||
{"russian f", "!ф", "phrases"},
|
||||
|
||||
// More Russian webapp
|
||||
{"russian frog", "!лягушка", "webapp-go"},
|
||||
{"russian horse", "!лошадь", "webapp-go"},
|
||||
{"russian rabbit", "!кролик", "webapp-go"},
|
||||
{"russian snail", "!улитка", "webapp-go"},
|
||||
{"russian fox", "!лис", "webapp-go"},
|
||||
{"russian anek", "!анек", "webapp-go"},
|
||||
{"russian drink", "!праздник", "webapp-go"},
|
||||
{"russian owl", "!сова", "webapp-go"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := determineChannel(tt.message, Config.Csign)
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %s, got %s", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_MoreEnglishCommands(t *testing.T) {
|
||||
origConfig := Config
|
||||
Config = myConfig{
|
||||
Csign: "!",
|
||||
ForwardChannels: struct {
|
||||
Games string `json:"games,omitempty"`
|
||||
Phrases string `json:"phrases,omitempty"`
|
||||
Webapp string `json:"webapp,omitempty"`
|
||||
WebappGo string `json:"webapp-go,omitempty"`
|
||||
Craniac string `json:"craniac,omitempty"`
|
||||
}{
|
||||
Games: "games",
|
||||
Phrases: "phrases",
|
||||
WebappGo: "webapp-go",
|
||||
},
|
||||
}
|
||||
defer func() { Config = origConfig }()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
expected string
|
||||
}{
|
||||
// More phrases commands
|
||||
{"proverb", "!proverb", "phrases"},
|
||||
{"poslovitsa", "!пословица", "phrases"},
|
||||
{"poslovitsya", "!пословиться", "phrases"},
|
||||
{"rum", "!rum", "phrases"},
|
||||
{"vodka", "!vodka", "phrases"},
|
||||
{"beer", "!beer", "phrases"},
|
||||
{"tequila", "!tequila", "phrases"},
|
||||
{"whisky", "!whisky", "phrases"},
|
||||
{"absinthe", "!absinthe", "phrases"},
|
||||
{"fuck", "!fuck", "phrases"},
|
||||
{"f short", "!f", "phrases"},
|
||||
|
||||
// More webapp-go commands
|
||||
{"horse", "!horse", "webapp-go"},
|
||||
{"rabbit", "!rabbit", "webapp-go"},
|
||||
{"bunny", "!bunny", "webapp-go"},
|
||||
{"snail", "!snail", "webapp-go"},
|
||||
{"fox", "!fox", "webapp-go"},
|
||||
{"buni", "!buni", "webapp-go"},
|
||||
{"anek", "!anek", "webapp-go"},
|
||||
{"xkcd", "!xkcd", "webapp-go"},
|
||||
{"monkeyuser", "!monkeyuser", "webapp-go"},
|
||||
{"drink", "!drink", "webapp-go"},
|
||||
{"owl", "!owl", "webapp-go"},
|
||||
{"w short", "!w", "webapp-go"},
|
||||
|
||||
// More games commands
|
||||
{"fishing", "!fishing", "games"},
|
||||
|
||||
// Phrases with arguments
|
||||
{"karma with user", "!karma username", "phrases"},
|
||||
{"rum with drink", "!rum cola", "phrases"},
|
||||
{"vodka with juice", "!водка сок", "phrases"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := determineChannel(tt.message, Config.Csign)
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %s, got %s", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_KarmaInlinePattern(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
expected string
|
||||
}{
|
||||
{"simple increment", "user++", "phrases"},
|
||||
{"simple decrement", "user--", "phrases"},
|
||||
{"with spaces", "some text++", "phrases"},
|
||||
{"cyrillic increment", "пользователь++", "phrases"},
|
||||
{"cyrillic decrement", "пользователь--", "phrases"},
|
||||
{"emoji", "👍++", "phrases"},
|
||||
{"underscore", "test_name++", "phrases"},
|
||||
{"dash in name", "test-name++", "phrases"},
|
||||
{"not karma - just plus", "a+b", "craniac"},
|
||||
// "a+++" ends with "++", so it's treated as karma increment
|
||||
{"multiple plus ends with ++", "a+++", "phrases"},
|
||||
{"not karma - embedded", "a++b", "craniac"},
|
||||
{"decrement edge", "a--b", "craniac"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := determineKarmaChannel(tt.message)
|
||||
if result != tt.expected {
|
||||
t.Errorf("expected %s, got %s", tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryConstants(t *testing.T) {
|
||||
if retryAttempts != 3 {
|
||||
t.Errorf("expected retryAttempts=3, got %d", retryAttempts)
|
||||
}
|
||||
if retryDelay != time.Second {
|
||||
t.Errorf("expected retryDelay=1s, got %v", retryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgParser_MessageValidationLogic(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
jsonStr string
|
||||
expectValid bool // true if message has all required fields
|
||||
}{
|
||||
// Valid messages
|
||||
{"valid minimal", `{"from":"t","chatid":"1","userid":"1","message":"m","plugin":"p","mode":"m"}`, true},
|
||||
{"valid full", `{"from":"t","chatid":"1","userid":"1","message":"m","plugin":"p","mode":"m","misc":{"csign":"!","fwd_cnt":1}}`, true},
|
||||
|
||||
// Missing required fields - they unmarshal but are empty strings
|
||||
{"missing from", `{"chatid":"1","userid":"1","message":"m","plugin":"p","mode":"m"}`, false},
|
||||
{"missing chatid", `{"from":"t","userid":"1","message":"m","plugin":"p","mode":"m"}`, false},
|
||||
{"missing userid", `{"from":"t","chatid":"1","message":"m","plugin":"p","mode":"m"}`, false},
|
||||
{"missing message", `{"from":"t","chatid":"1","userid":"1","plugin":"p","mode":"m"}`, false},
|
||||
{"missing plugin", `{"from":"t","chatid":"1","userid":"1","message":"m","mode":"m"}`, false},
|
||||
{"missing mode", `{"from":"t","chatid":"1","userid":"1","message":"m","plugin":"p"}`, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var msg rMsg
|
||||
err := json.Unmarshal([]byte(tt.jsonStr), &msg)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected JSON error: %v", err)
|
||||
}
|
||||
|
||||
// Check if message has all required fields (the validation logic in MsgParser)
|
||||
isValid := msg.From != "" && msg.Chatid != "" && msg.Userid != "" &&
|
||||
msg.Message != "" && msg.Plugin != "" && msg.Mode != ""
|
||||
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("valid=%v, expected %v", isValid, tt.expectValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user