Use to build proper go unit tests for services, models, and controllers
/plugin marketplace add griffnb/claude-plugins/plugin install backend@claude-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
โ ๏ธ ABSOLUTE RULE - NO EXCEPTIONS: This project follows strict TDD (Test-Driven Development).
โ WRONG:
1. Write implementation
2. Write tests later
3. Maybe forget tests
โ
CORRECT:
1. Write test first (see it fail - RED)
2. Write minimal implementation (make it pass - GREEN)
3. Refactor if needed (keep it passing - REFACTOR)
4. Commit with tests passing
assert (lib/testtools/assert/assert.go) for assertionstesting_service.Builder to build objects, be sure to extend this as objects change// Step 1: Write test FIRST (RED)
func TestExampleHere(t *testing.T) {
t.Run("Case 1", func(t *testing.T) {
// Arrange
client := NewOpenAIClient("test-key", "gpt-4")
req := llm.CreateVectorStoreRequest{Name: "test"}
// Act
result, err := client.CreateVectorStore(context.Background(), req)
// Assert
assert.Equal(t, "test", result.Name)
})
t.Run("Case 2", func(t *testing.T) {
// Arrange
client := NewOpenAIClient("test-key", "gpt-4")
req := llm.CreateVectorStoreRequest{Name: "test"}
// Act
result, err := client.CreateVectorStore(context.Background(), req)
// Assert
assert.Equal(t, "test", result.Name)
})
t.Run("Case 3", func(t *testing.T) {
// Arrange
client := NewOpenAIClient("test-key", "gpt-4")
req := llm.CreateVectorStoreRequest{Name: "test"}
// Act
result, err := client.CreateVectorStore(context.Background(), req)
// Assert
assert.Equal(t, "test", result.Name)
})
}
// Step 2: Run test - it FAILS (RED) โ
// Step 3: Write implementation to make it pass (GREEN) โ
// Step 4: Refactor if needed (REFACTOR) โ
// Step 5: Commit with passing tests โ
Every controller should have tests that verify functionality. Use the testing_service.TestRequest pattern for creating test requests:
package example_controller
import (
"net/http"
"net/url"
"testing"
"github.com/CrowdShield/atlas-go/internal/common/system_testing"
"github.com/CrowdShield/atlas-go/internal/models/example"
"github.com/CrowdShield/atlas-go/internal/services/testing_service"
)
func init() {
system_testing.BuildSystem()
}
func TestExampleIndex(t *testing.T) {
req, err := testing_service.NewGETRequest[[]*example.ExampleJoined]("/", nil)
if err != nil {
t.Fatalf("Failed to create test request: %v", err)
}
err = req.WithAdmin() // or WithAccount() for public endpoints
if err != nil {
t.Fatalf("Failed to create test request: %v", err)
}
resp, errCode, err := req.Do(exampleIndex)
if err != nil {
t.Fatalf("Request failed: %v", err)
}
if errCode != http.StatusOK {
t.Fatalf("Expected status code 200, got %d", errCode)
}
// Additional assertions on resp...
}
Every controller with a search.go file must have a search test to ensure the search configuration doesn't break:
func TestExampleSearch(t *testing.T) {
params := url.Values{}
params.Add("q", "search term")
req, err := testing_service.NewGETRequest[[]*example.ExampleJoined]("/", params)
if err != nil {
t.Fatalf("Failed to create test request: %v", err)
}
err = req.WithAdmin() // or WithAccount() depending on controller type
if err != nil {
t.Fatalf("Failed to create test request: %v", err)
}
resp, errCode, err := req.Do(exampleIndex)
if err != nil {
t.Fatalf("Request failed: %v", err)
}
if errCode != http.StatusOK {
t.Fatalf("Expected status code 200, got %d", errCode)
}
// Search should not crash - results can be empty, that's OK
}
Admin Controllers: Use req.WithAdmin() for testing admin endpoints:
err = req.WithAdmin() // Creates test admin user with ROLE_ADMIN
Public Controllers: Use req.WithAccount() for testing public authenticated endpoints:
err = req.WithAccount() // Creates test account user with ROLE_FAMILY_ADMIN
Custom Users: Pass specific user objects if needed:
adminUser := admin.New()
adminUser.Role.Set(constants.ROLE_READ_ADMIN)
adminUser.Save(nil)
err = req.WithAdmin(adminUser)
GET Requests with Query Parameters:
params := url.Values{}
params.Add("name", "test")
params.Add("limit", "10")
req, err := testing_service.NewGETRequest[ResponseType]("/", params)
POST Requests with JSON Body:
body := map[string]any{}{
"name": "Test Item",
"status": "active",
}
req, err := testing_service.NewPOSTRequest[ResponseType]("/", nil, body)
IMPORTANT if you are testing model updates or creation, the format is
body := map[string]any{}{
"data":map[string]any{
"name": "Test Item",
"status": "active",
}
}
PUT Requests for Updates:
body := map[string]interface{}{
"name": "Updated Name",
}
req, err := testing_service.NewPUTRequest[ResponseType]("/uuid-of-object", nil, body)
system_testing.BuildSystem() in init() for database setupdefer testtools.CleanupModel(x) if creating modelsTestAccountIndex_WithValidUser_ReturnsAccountsAll tests must be run through #code_tools to ensure proper environment setup:
** DO NOT RUN YOUR OWN COMMANDS, ONLY USE #code_tools
ALL Tests must pass before committing changes, they must be in the commit message as proof
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.