Files
MuyueWorkspace/internal/skills/skills_test.go
Augustin 3494f6b40d
All checks were successful
CI / build (push) Successful in 2m37s
feat: security hardening, tests, doctor command, CI update, CHANGELOG
- Add AES-256-GCM encryption for API keys (internal/secret)
- Add dangerous command detection in terminal
- Add muyue doctor command for system health checks
- Add scanner TTL cache, orchestrator history mutex, shared HTTP client
- Deduplicate MCP config generation, refactor skills YAML parser
- Add XDG-compliant config dir with legacy migration
- Add cleanup on all TUI quit paths
- Add 8 test files (config, workflow, skills, orchestrator, version,
  platform, scanner, secret)
- Update CI to actions/setup-go@v5
- Add CHANGELOG.md, update README and Makefile

🤖 Generated with Crush

Assisted-by: GLM-5.1 via Crush <crush@charm.land>
2026-04-20 19:56:07 +02:00

201 lines
4.2 KiB
Go

package skills
import (
"os"
"path/filepath"
"testing"
)
func TestParseSkillWithYAML(t *testing.T) {
data := []byte(`---
name: test-skill
description: A test skill
author: test
version: "1.0"
target: both
tags:
- test
- demo
---
# Test Skill Content
This is the body.
`)
skill, err := parseSkill(data)
if err != nil {
t.Fatalf("parseSkill failed: %v", err)
}
if skill.Description != "A test skill" {
t.Errorf("Expected 'A test skill', got %s", skill.Description)
}
if skill.Author != "test" {
t.Errorf("Expected 'test', got %s", skill.Author)
}
if skill.Version != "1.0" {
t.Errorf("Expected '1.0', got %s", skill.Version)
}
if skill.Target != "both" {
t.Errorf("Expected 'both', got %s", skill.Target)
}
if len(skill.Tags) != 2 {
t.Errorf("Expected 2 tags, got %d", len(skill.Tags))
}
if skill.Content == "" {
t.Error("Content should not be empty")
}
}
func TestParseSkillNoFrontmatter(t *testing.T) {
data := []byte("Just plain content here")
skill, err := parseSkill(data)
if err != nil {
t.Fatalf("parseSkill failed: %v", err)
}
if skill.Content != "Just plain content here" {
t.Errorf("Unexpected content: %s", skill.Content)
}
}
func TestParseSkillIncompleteFrontmatter(t *testing.T) {
data := []byte("---\nname: incomplete\n---\nBody content")
skill, err := parseSkill(data)
if err != nil {
t.Fatalf("parseSkill failed: %v", err)
}
if skill.Content != "Body content" {
t.Errorf("Expected 'Body content', got %s", skill.Content)
}
}
func TestRenderSkill(t *testing.T) {
skill := &Skill{
Name: "test",
Description: "A test",
Author: "author",
Version: "1.0",
Target: "both",
Tags: []string{"a", "b"},
Content: "Body",
}
rendered := renderSkill(skill)
if rendered == "" {
t.Error("Rendered skill should not be empty")
}
if len(rendered) < 20 {
t.Error("Rendered skill seems too short")
}
}
func TestListEmpty(t *testing.T) {
tmpDir := t.TempDir()
origHome := os.Getenv("HOME")
os.Setenv("HOME", tmpDir)
defer os.Setenv("HOME", origHome)
skills, err := List()
if err != nil {
t.Fatalf("List failed: %v", err)
}
if len(skills) != 0 {
t.Errorf("Expected 0 skills, got %d", len(skills))
}
}
func TestCreateAndGet(t *testing.T) {
tmpDir := t.TempDir()
origHome := os.Getenv("HOME")
os.Setenv("HOME", tmpDir)
defer os.Setenv("HOME", origHome)
skill := &Skill{
Name: "test-skill",
Description: "Test description",
Content: "Test content body",
Author: "tester",
Version: "0.1",
Target: "both",
}
if err := Create(skill); err != nil {
t.Fatalf("Create failed: %v", err)
}
dir, _ := SkillsDir()
skillPath := filepath.Join(dir, "test-skill", "SKILL.md")
if _, err := os.Stat(skillPath); os.IsNotExist(err) {
t.Error("Skill file should exist")
}
got, err := Get("test-skill")
if err != nil {
t.Fatalf("Get failed: %v", err)
}
if got.Name != "test-skill" {
t.Errorf("Expected test-skill, got %s", got.Name)
}
}
func TestDelete(t *testing.T) {
tmpDir := t.TempDir()
origHome := os.Getenv("HOME")
os.Setenv("HOME", tmpDir)
defer os.Setenv("HOME", origHome)
skill := &Skill{
Name: "to-delete",
Description: "Will be deleted",
Content: "content",
Target: "both",
}
Create(skill)
if err := Delete("to-delete"); err != nil {
t.Fatalf("Delete failed: %v", err)
}
_, err := Get("to-delete")
if err == nil {
t.Error("Skill should be deleted")
}
}
func TestBuildAIGeneratePrompt(t *testing.T) {
prompt := BuildAIGeneratePrompt("docker", "Set up Docker", "both")
if prompt == "" {
t.Error("Prompt should not be empty")
}
if len(prompt) < 50 {
t.Error("Prompt seems too short")
}
}
func TestInstallBuiltinSkills(t *testing.T) {
tmpDir := t.TempDir()
origHome := os.Getenv("HOME")
os.Setenv("HOME", tmpDir)
defer os.Setenv("HOME", origHome)
if err := InstallBuiltinSkills(); err != nil {
t.Fatalf("InstallBuiltinSkills failed: %v", err)
}
skills, err := List()
if err != nil {
t.Fatalf("List failed: %v", err)
}
if len(skills) == 0 {
t.Error("Expected at least one builtin skill")
}
found := false
for _, s := range skills {
if s.Name == "env-setup" {
found = true
}
}
if !found {
t.Error("Expected env-setup skill")
}
}