rdev/internal/adapter/cockroach/provisioner_test.go
jordan c59d348040 chore: prepare for composable monorepo template implementation
This commit captures the current state before implementing the composable
monorepo template system. Key changes included:

Infrastructure:
- Add CockroachDB provisioner adapter for database provisioning
- Add Redis provisioner adapter for cache provisioning
- Add build events system with PostgreSQL storage
- Add WebSocket endpoint for real-time build progress

Code agent improvements:
- Fix Claude Code adapter to use default allowed tools instead of dangerously-skip-permissions
- Add context-aware stream closing for cancellation support
- Improve parser tests for edge cases

Build system:
- Add build event constants and metrics
- Remove deprecated git_operations.go (replaced by pod_git_operations.go)
- Add rollback logic for multi-step provisioning operations

Documentation:
- Add composable-monorepo feature documentation
- Add DNS/Cloudflare service documentation
- Update deployment and troubleshooting guides

Cookbooks:
- Add fullstack-app cookbook
- Refactor landing-test with shared library

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:39:28 -07:00

124 lines
2.8 KiB
Go

package cockroach
import (
"testing"
)
func TestSanitizeIdentifier(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"simple", "simple"},
{"with-dash", "with_dash"},
{"with_underscore", "with_underscore"},
{"UPPERCASE", "uppercase"},
{"MixedCase", "mixedcase"},
{"with spaces", "with_spaces"},
{"with.dots", "with_dots"},
{"123numeric", "123numeric"},
{"special!@#$%", "special_____"},
{"", ""},
{"project-abc-123", "project_abc_123"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
result := sanitizeIdentifier(tt.input)
if result != tt.expected {
t.Errorf("sanitizeIdentifier(%q) = %q, want %q", tt.input, result, tt.expected)
}
})
}
}
func TestQuoteIdent(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"simple", `"simple"`},
{"with space", `"with space"`},
{`with"quote`, `"with""quote"`},
{"", `""`},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
result := quoteIdent(tt.input)
if result != tt.expected {
t.Errorf("quoteIdent(%q) = %q, want %q", tt.input, result, tt.expected)
}
})
}
}
func TestGenerateToken(t *testing.T) {
// Test that tokens are generated with correct length
lengths := []int{16, 32, 64}
for _, length := range lengths {
token, err := generateToken(length)
if err != nil {
t.Errorf("generateToken(%d) returned error: %v", length, err)
continue
}
// Hex encoding doubles the length
expectedLen := length * 2
if len(token) != expectedLen {
t.Errorf("generateToken(%d) returned token of length %d, want %d", length, len(token), expectedLen)
}
}
// Test that tokens are unique
token1, _ := generateToken(32)
token2, _ := generateToken(32)
if token1 == token2 {
t.Error("generateToken returned duplicate tokens")
}
}
func TestDatabaseNameFor(t *testing.T) {
p := &Provisioner{}
tests := []struct {
projectID string
expected string
}{
{"myproject", "project_myproject"},
{"my-project", "project_my_project"},
{"MY_PROJECT", "project_my_project"},
{"123", "project_123"},
}
for _, tt := range tests {
t.Run(tt.projectID, func(t *testing.T) {
result := p.databaseNameFor(tt.projectID)
if result != tt.expected {
t.Errorf("databaseNameFor(%q) = %q, want %q", tt.projectID, result, tt.expected)
}
})
}
}
func TestUsernameFor(t *testing.T) {
p := &Provisioner{}
tests := []struct {
projectID string
expected string
}{
{"myproject", "project_myproject"},
{"my-project", "project_my_project"},
{"MY_PROJECT", "project_my_project"},
}
for _, tt := range tests {
t.Run(tt.projectID, func(t *testing.T) {
result := p.usernameFor(tt.projectID)
if result != tt.expected {
t.Errorf("usernameFor(%q) = %q, want %q", tt.projectID, result, tt.expected)
}
})
}
}