Changeset 0.9.0 (#50)
This commit is contained in:
@@ -1,203 +0,0 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"git.gobha.me/xcaliber/chat-switchboard/database"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
teardown := database.SetupTestDB()
|
||||
code := m.Run()
|
||||
teardown()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ── Note Tool Execution (requires DB) ───────
|
||||
|
||||
func TestNoteCreateExecute(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
database.TruncateAll(t)
|
||||
|
||||
userID := database.SeedTestUser(t, "tooluser", "tool@test.com")
|
||||
channelID := database.SeedTestChannel(t, userID, "Tool Test")
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: userID, ChannelID: channelID}
|
||||
|
||||
tool := Get("note_create")
|
||||
if tool == nil {
|
||||
t.Fatal("note_create not registered")
|
||||
}
|
||||
|
||||
args := `{"title":"Test Note","content":"Created via tool","folder":"/tools","tags":["test","ci"]}`
|
||||
result, err := tool.Execute(ctx, execCtx, args)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(result), &resp); err != nil {
|
||||
t.Fatalf("Invalid JSON result: %v\nRaw: %s", err, result)
|
||||
}
|
||||
|
||||
if resp["id"] == nil || resp["id"] == "" {
|
||||
t.Error("Expected id in result")
|
||||
}
|
||||
if resp["title"] != "Test Note" {
|
||||
t.Errorf("Expected title='Test Note', got %v", resp["title"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoteListExecute(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
database.TruncateAll(t)
|
||||
|
||||
userID := database.SeedTestUser(t, "listuser", "list@test.com")
|
||||
channelID := database.SeedTestChannel(t, userID, "List Test")
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: userID, ChannelID: channelID}
|
||||
|
||||
// Create two notes first
|
||||
createTool := Get("note_create")
|
||||
createTool.Execute(ctx, execCtx, `{"title":"Note A","content":"Alpha","folder":"/a"}`)
|
||||
createTool.Execute(ctx, execCtx, `{"title":"Note B","content":"Beta","folder":"/b"}`)
|
||||
|
||||
// List all
|
||||
listTool := Get("note_list")
|
||||
result, err := listTool.Execute(ctx, execCtx, `{}`)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
json.Unmarshal([]byte(result), &resp)
|
||||
|
||||
count := resp["count"].(float64)
|
||||
if count != 2 {
|
||||
t.Errorf("Expected count=2, got %.0f", count)
|
||||
}
|
||||
|
||||
// List filtered by folder
|
||||
result, err = listTool.Execute(ctx, execCtx, `{"folder":"/a"}`)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute with folder: %v", err)
|
||||
}
|
||||
json.Unmarshal([]byte(result), &resp)
|
||||
count = resp["count"].(float64)
|
||||
if count != 1 {
|
||||
t.Errorf("Expected count=1 for folder /a, got %.0f", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoteSearchExecute(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
database.TruncateAll(t)
|
||||
|
||||
userID := database.SeedTestUser(t, "searchuser", "search@test.com")
|
||||
channelID := database.SeedTestChannel(t, userID, "Search Test")
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: userID, ChannelID: channelID}
|
||||
|
||||
createTool := Get("note_create")
|
||||
createTool.Execute(ctx, execCtx, `{"title":"Kubernetes Guide","content":"How to deploy pods and services"}`)
|
||||
createTool.Execute(ctx, execCtx, `{"title":"Cooking Tips","content":"Season your cast iron pan properly"}`)
|
||||
|
||||
searchTool := Get("note_search")
|
||||
result, err := searchTool.Execute(ctx, execCtx, `{"query":"kubernetes pods"}`)
|
||||
if err != nil {
|
||||
t.Fatalf("Execute: %v", err)
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
json.Unmarshal([]byte(result), &resp)
|
||||
count := resp["count"].(float64)
|
||||
if count != 1 {
|
||||
t.Errorf("Expected 1 search result for 'kubernetes pods', got %.0f", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoteUpdateExecute(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
database.TruncateAll(t)
|
||||
|
||||
userID := database.SeedTestUser(t, "updateuser", "update@test.com")
|
||||
channelID := database.SeedTestChannel(t, userID, "Update Test")
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: userID, ChannelID: channelID}
|
||||
|
||||
// Create a note
|
||||
createTool := Get("note_create")
|
||||
result, _ := createTool.Execute(ctx, execCtx, `{"title":"Original","content":"Original content"}`)
|
||||
|
||||
var created map[string]interface{}
|
||||
json.Unmarshal([]byte(result), &created)
|
||||
noteID := created["id"].(string)
|
||||
|
||||
// Update title
|
||||
updateTool := Get("note_update")
|
||||
result, err := updateTool.Execute(ctx, execCtx, `{"note_id":"`+noteID+`","title":"Renamed"}`)
|
||||
if err != nil {
|
||||
t.Fatalf("Update title: %v", err)
|
||||
}
|
||||
|
||||
var updated map[string]interface{}
|
||||
json.Unmarshal([]byte(result), &updated)
|
||||
if updated["title"] != "Renamed" {
|
||||
t.Errorf("Expected title='Renamed', got %v", updated["title"])
|
||||
}
|
||||
|
||||
// Append content
|
||||
result, err = updateTool.Execute(ctx, execCtx, `{"note_id":"`+noteID+`","content":"\nNew line","mode":"append"}`)
|
||||
if err != nil {
|
||||
t.Fatalf("Append: %v", err)
|
||||
}
|
||||
|
||||
// Verify via direct DB read
|
||||
var row string
|
||||
database.DB.QueryRow("SELECT content FROM notes WHERE id = $1", noteID).Scan(&row)
|
||||
if row != "Original content\nNew line" {
|
||||
t.Errorf("Append: expected concatenated content, got %q", row)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoteCreateMissingRequiredField(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: "test", ChannelID: "test"}
|
||||
|
||||
tool := Get("note_create")
|
||||
// Missing content
|
||||
result, err := tool.Execute(ctx, execCtx, `{"title":"No Content"}`)
|
||||
if err == nil {
|
||||
// Tools return errors in content, not as Go errors
|
||||
var resp map[string]interface{}
|
||||
json.Unmarshal([]byte(result), &resp)
|
||||
if resp["error"] == nil {
|
||||
t.Error("Expected error for missing content")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoteUpdateNonexistent(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
database.TruncateAll(t)
|
||||
|
||||
userID := database.SeedTestUser(t, "ghostuser", "ghost@test.com")
|
||||
|
||||
ctx := context.Background()
|
||||
execCtx := ExecutionContext{UserID: userID, ChannelID: "test"}
|
||||
|
||||
tool := Get("note_update")
|
||||
_, err := tool.Execute(ctx, execCtx, `{"note_id":"00000000-0000-0000-0000-000000000000","title":"Nope"}`)
|
||||
if err == nil {
|
||||
t.Log("Update of nonexistent note should return error or empty result")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user