Files
clawgo/pkg/api/server_skills_test.go
2026-03-15 15:31:00 +08:00

94 lines
2.5 KiB
Go

package api
import (
"archive/zip"
"bytes"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
func TestImportSkillArchiveFromMultipartSucceedsForSmallArchive(t *testing.T) {
t.Parallel()
var archive bytes.Buffer
zw := zip.NewWriter(&archive)
entry, err := zw.Create("demo/SKILL.md")
if err != nil {
t.Fatalf("create entry: %v", err)
}
if _, err := entry.Write([]byte("# Demo\n")); err != nil {
t.Fatalf("write entry: %v", err)
}
if err := zw.Close(); err != nil {
t.Fatalf("close zip: %v", err)
}
req := multipartRequest(t, "demo.zip", archive.Bytes())
skillsDir := t.TempDir()
imported, err := importSkillArchiveFromMultipart(req, skillsDir)
if err != nil {
t.Fatalf("import archive: %v", err)
}
if len(imported) != 1 || imported[0] != "demo" {
t.Fatalf("unexpected imported skills: %+v", imported)
}
if _, err := os.Stat(filepath.Join(skillsDir, "demo", "SKILL.md")); err != nil {
t.Fatalf("expected imported SKILL.md: %v", err)
}
}
func TestExtractArchiveRejectsOversizedExpandedEntry(t *testing.T) {
t.Parallel()
var archive bytes.Buffer
zw := zip.NewWriter(&archive)
entry, err := zw.Create("demo/SKILL.md")
if err != nil {
t.Fatalf("create entry: %v", err)
}
if _, err := entry.Write(bytes.Repeat([]byte("a"), int(skillArchiveMaxSingleFile+1))); err != nil {
t.Fatalf("write entry: %v", err)
}
if err := zw.Close(); err != nil {
t.Fatalf("close zip: %v", err)
}
archivePath := filepath.Join(t.TempDir(), "demo.zip")
if err := os.WriteFile(archivePath, archive.Bytes(), 0o644); err != nil {
t.Fatalf("write archive: %v", err)
}
err = extractArchive(archivePath, t.TempDir(), &archiveExtractLimits{
maxFiles: skillArchiveMaxFiles,
maxSingleFile: skillArchiveMaxSingleFile,
maxExpanded: skillArchiveMaxExpanded,
})
if err == nil || !strings.Contains(err.Error(), "size limit") {
t.Fatalf("expected size limit error, got %v", err)
}
}
func multipartRequest(t *testing.T, filename string, body []byte) *http.Request {
t.Helper()
var form bytes.Buffer
mw := multipart.NewWriter(&form)
part, err := mw.CreateFormFile("file", filename)
if err != nil {
t.Fatalf("create form file: %v", err)
}
if _, err := part.Write(body); err != nil {
t.Fatalf("write form file: %v", err)
}
if err := mw.Close(); err != nil {
t.Fatalf("close multipart writer: %v", err)
}
req := httptest.NewRequest("POST", "/api/skills", &form)
req.Header.Set("Content-Type", mw.FormDataContentType())
req.ContentLength = int64(form.Len())
return req
}