package tools
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func TestCreateOrUpdatePattern_CreateDuplicate(t *testing.T) {
testDB := filepath.Join("..", "db", "test.duckdb")
if _, err := os.Stat(testDB); os.IsNotExist(err) {
t.Skipf("Test database not found at %s", testDB)
}
SetDBPath(testDB)
ctx := context.Background()
t.Run("CreateDuplicatePattern", func(t *testing.T) {
record := 60
sleep := 1740
input := PatternInput{
RecordSeconds: &record,
SleepSeconds: &sleep,
}
result, output, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if result == nil {
t.Fatal("Expected non-nil result")
}
if output.Pattern.ID != "IBv_KxDGsNQs" {
t.Errorf("Expected existing pattern ID 'IBv_KxDGsNQs', got '%s'", output.Pattern.ID)
}
if output.Pattern.RecordS != 60 {
t.Errorf("Expected record_s 60, got %d", output.Pattern.RecordS)
}
if output.Pattern.SleepS != 1740 {
t.Errorf("Expected sleep_s 1740, got %d", output.Pattern.SleepS)
}
if output.Message == "" {
t.Error("Expected non-empty message")
}
t.Logf("Message: %s", output.Message)
})
t.Run("CreateUniquePattern", func(t *testing.T) {
record := 999
sleep := 888
input := PatternInput{
RecordSeconds: &record,
SleepSeconds: &sleep,
}
result, output, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if result == nil {
t.Fatal("Expected non-nil result")
}
firstID := output.Pattern.ID
if firstID == "" {
t.Fatal("Expected non-empty ID")
}
if output.Pattern.RecordS != 999 {
t.Errorf("Expected record_s 999, got %d", output.Pattern.RecordS)
}
if output.Pattern.SleepS != 888 {
t.Errorf("Expected sleep_s 888, got %d", output.Pattern.SleepS)
}
t.Logf("Created pattern ID: %s", firstID)
result2, output2, err2 := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if err2 != nil {
t.Fatalf("Expected no error on duplicate, got: %v", err2)
}
if result2 == nil {
t.Fatal("Expected non-nil result")
}
if output2.Pattern.ID != firstID {
t.Errorf("Expected same pattern ID '%s', got '%s'", firstID, output2.Pattern.ID)
}
t.Logf("Idempotent test passed - returned same ID: %s", output2.Pattern.ID)
})
}
func TestCreateOrUpdatePattern_Validation(t *testing.T) {
testDB := filepath.Join("..", "db", "test.duckdb")
if _, err := os.Stat(testDB); os.IsNotExist(err) {
t.Skipf("Test database not found at %s", testDB)
}
SetDBPath(testDB)
ctx := context.Background()
tests := []struct {
name string
recordSeconds int
sleepSeconds int
wantError bool
}{
{"ZeroRecordSeconds", 0, 100, true},
{"NegativeRecordSeconds", -10, 100, true},
{"ZeroSleepSeconds", 100, 0, true},
{"NegativeSleepSeconds", 100, -10, true},
{"ValidInputs", 10, 20, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
input := PatternInput{
RecordSeconds: &tt.recordSeconds,
SleepSeconds: &tt.sleepSeconds,
}
_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if (err != nil) != tt.wantError {
t.Errorf("Expected error=%v, got error=%v", tt.wantError, err != nil)
}
})
}
}
func TestCreateOrUpdatePattern_Update(t *testing.T) {
testDB := filepath.Join("..", "db", "test.duckdb")
if _, err := os.Stat(testDB); os.IsNotExist(err) {
t.Skipf("Test database not found at %s", testDB)
}
SetDBPath(testDB)
ctx := context.Background()
t.Run("UpdateNonExistentPattern", func(t *testing.T) {
id := "NONEXISTENT1"
record := 100
input := PatternInput{
ID: &id,
RecordSeconds: &record,
}
_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if err == nil {
t.Error("Expected error for non-existent pattern")
}
})
t.Run("UpdateNoFields", func(t *testing.T) {
id := "IBv_KxDGsNQs"
input := PatternInput{
ID: &id,
}
_, _, err := CreateOrUpdatePattern(ctx, &mcp.CallToolRequest{}, input)
if err == nil {
t.Error("Expected error when no fields provided")
}
})
}