package searchreplace import ( "testing" "time" "git.nakama.town/fmartingr/butterrobot/internal/model" ) func TestSearchReplace(t *testing.T) { // Create plugin instance p := New() // Test cases tests := []struct { name string command string originalText string expectedResult string expectActions bool }{ { name: "Simple replacement", command: "s/hello/world/", originalText: "hello everyone", expectedResult: "world everyone", expectActions: true, }, { name: "Case-insensitive replacement", command: "s/HELLO/world/i", originalText: "Hello everyone", expectedResult: "world everyone", expectActions: true, }, { name: "Global replacement", command: "s/a/X/g", originalText: "banana", expectedResult: "bXnXnX", expectActions: true, }, { name: "No change", command: "s/nothing/something/", originalText: "test message", expectedResult: "test message", expectActions: true, // We send a "no changes" message }, { name: "Not a search/replace command", command: "hello", originalText: "test message", expectedResult: "", expectActions: false, }, { name: "Invalid pattern", command: "s/(/)/", originalText: "test message", expectedResult: "error", expectActions: true, // We send an error message }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Create message msg := &model.Message{ Text: tc.command, Chat: "test-chat", ReplyTo: "original-message-id", Date: time.Now(), Channel: &model.Channel{ Platform: "test", }, Raw: map[string]interface{}{ "message": map[string]interface{}{ "reply_to_message": map[string]interface{}{ "text": tc.originalText, }, }, }, } // Process message actions := p.OnMessage(msg, nil) // Check results if tc.expectActions { if len(actions) == 0 { t.Fatalf("Expected actions but got none") } action := actions[0] if action.Type != model.ActionSendMessage { t.Fatalf("Expected send message action but got %v", action.Type) } if tc.expectedResult == "error" { // Just checking that we got an error message if action.Message == nil || action.Message.Text == "" { t.Fatalf("Expected error message but got empty message") } } else if tc.originalText == tc.expectedResult { // Check if we got the "no changes" message if action.Message == nil || action.Message.Text != "No changes were made to the original message." { t.Fatalf("Expected 'no changes' message but got: %s", action.Message.Text) } } else { // Check actual replacement result if action.Message == nil || action.Message.Text != tc.expectedResult { t.Fatalf("Expected result: %s, got: %s", tc.expectedResult, action.Message.Text) } } } else if len(actions) > 0 { t.Fatalf("Expected no actions but got %d", len(actions)) } }) } } func TestPerformReplacement(t *testing.T) { p := New() // Test cases for the performReplacement function tests := []struct { name string text string search string replace string flags string expected string expectErr bool }{ { name: "Simple replacement", text: "Hello World", search: "Hello", replace: "Hi", flags: "", expected: "Hi World", expectErr: false, }, { name: "Case insensitive", text: "Hello World", search: "hello", replace: "Hi", flags: "i", expected: "Hi World", expectErr: false, }, { name: "Global replacement", text: "one two one two", search: "one", replace: "1", flags: "g", expected: "1 two 1 two", expectErr: false, }, { name: "No match", text: "Hello World", search: "Goodbye", replace: "Hi", flags: "", expected: "Hello World", expectErr: false, }, { name: "Invalid regex", text: "Hello World", search: "(", replace: "Hi", flags: "n", // treat as regex expected: "", expectErr: true, }, { name: "Escape special chars by default", text: "Hello (World)", search: "(World)", replace: "[Earth]", flags: "", expected: "Hello [Earth]", expectErr: false, }, { name: "Regex mode with n flag", text: "Hello (World)", search: "\\(World\\)", replace: "[Earth]", flags: "n", expected: "Hello [Earth]", expectErr: false, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { result, err := p.performReplacement(tc.text, tc.search, tc.replace, tc.flags) if tc.expectErr { if err == nil { t.Fatalf("Expected error but got none") } } else if err != nil { t.Fatalf("Unexpected error: %v", err) } else if result != tc.expected { t.Fatalf("Expected result: %s, got: %s", tc.expected, result) } }) } }