Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

pattern_test.go
package tools

import (
	"context"
	"os"
	"path/filepath"
	"testing"
)

func testExistingPattern(t *testing.T, ctx context.Context, testDB string) {
	t.Helper()
	record := 60
	sleep := 1740
	input := PatternInput{
		DBPath:        testDB,
		RecordSeconds: &record,
		SleepSeconds:  &sleep,
	}

	output, err := CreateOrUpdatePattern(ctx, input)
	if err != nil {
		t.Fatalf("Expected no error, got: %v", err)
	}

	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)
}

func testUniquePattern(t *testing.T, ctx context.Context, testDB string) {
	t.Helper()
	record := 999
	sleep := 888
	input := PatternInput{
		DBPath:        testDB,
		RecordSeconds: &record,
		SleepSeconds:  &sleep,
	}

	output, err := CreateOrUpdatePattern(ctx, input)
	if err != nil {
		t.Fatalf("Expected no error, got: %v", err)
	}
	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)

	testIdempotentCreate(t, ctx, testDB, record, sleep, firstID)
}

func testIdempotentCreate(t *testing.T, ctx context.Context, testDB string, record, sleep int, expectedID string) {
	t.Helper()
	input2 := PatternInput{
		DBPath:        testDB,
		RecordSeconds: &record,
		SleepSeconds:  &sleep,
	}

	output2, err2 := CreateOrUpdatePattern(ctx, input2)
	if err2 != nil {
		t.Fatalf("Expected no error on duplicate, got: %v", err2)
	}
	if output2.Pattern.ID != expectedID {
		t.Errorf("Expected same pattern ID '%s', got '%s'", expectedID, output2.Pattern.ID)
	}
	t.Logf("Idempotent test passed - returned same ID: %s", output2.Pattern.ID)
}

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)
	}
	ctx := context.Background()

	t.Run("CreateDuplicatePattern", func(t *testing.T) {
		testExistingPattern(t, ctx, testDB)
	})
	t.Run("CreateUniquePattern", func(t *testing.T) {
		testUniquePattern(t, ctx, testDB)
	})
}

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)
	}
	ctx := context.Background()

	// Test invalid inputs for create (no ID = create mode)
	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{
				DBPath:        testDB,
				RecordSeconds: &tt.recordSeconds,
				SleepSeconds:  &tt.sleepSeconds,
			}

			_, err := CreateOrUpdatePattern(ctx, 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)
	}
	ctx := context.Background()

	t.Run("UpdateNonExistentPattern", func(t *testing.T) {
		id := "NONEXISTENT1"
		record := 100
		input := PatternInput{
			DBPath:        testDB,
			ID:            &id,
			RecordSeconds: &record,
		}

		_, err := CreateOrUpdatePattern(ctx, input)
		if err == nil {
			t.Error("Expected error for non-existent pattern")
		}
	})

	t.Run("UpdateNoFields", func(t *testing.T) {
		id := "IBv_KxDGsNQs"
		input := PatternInput{
			DBPath: testDB,
			ID:     &id,
		}

		_, err := CreateOrUpdatePattern(ctx, input)
		if err == nil {
			t.Error("Expected error when no fields provided")
		}
	})
}