Files
CyberStrikeAI/internal/workflow/package/exporter_test.go
T
chenchen acfacfe1b3 feat(工作流):支持本地图编排策略包导入导出 (#195)
* docs: define local workflow package mvp

* docs: fix workflow package api contract

* feat: add local workflow package mvp

* feat(workflow): add package API client

* feat(workflow): add package import interface

* feat(workflow): connect package import flow

* fix(workflow): map package validation errors

* fix(workflow): handle import key generation errors

* feat(workflow): localize package import states

* fix(workflow): reset package import modal on open

---------

Co-authored-by: ruanmingchen <“ruanm@chenchen”>
2026-07-14 11:28:37 +08:00

59 lines
2.0 KiB
Go

package workflowpackage
import (
"archive/zip"
"bytes"
"strings"
"testing"
"time"
)
func testDocument() Document {
return Document{
ID: "web-src-hunting",
Name: "Web SRC 猎洞",
Description: "面向 SRC Web 资产的侦察与漏洞候选流程",
Version: 18,
Enabled: true,
GraphJSON: `{"nodes":[{"id":"start-1","type":"start","label":"开始","position":{"x":0,"y":0},"config":{}},{"id":"out-1","type":"output","label":"输出","position":{"x":0,"y":120},"config":{"output_key":"result","source_binding":{"from":"inputs","field":"message"}}}],"edges":[{"id":"e1","source":"start-1","target":"out-1"}],"config":{"schema_version":1}}`,
UpdatedAt: time.Date(2026, 7, 13, 10, 0, 0, 0, time.UTC),
}
}
func TestExportIsDeterministicAndSelfDescribing(t *testing.T) {
first, firstMeta, err := Export(testDocument())
if err != nil {
t.Fatalf("first export: %v", err)
}
second, secondMeta, err := Export(testDocument())
if err != nil {
t.Fatalf("second export: %v", err)
}
if !bytes.Equal(first, second) {
t.Fatal("identical document must produce byte-identical package")
}
if firstMeta.PackageHash != secondMeta.PackageHash || !strings.HasPrefix(firstMeta.PackageHash, "sha256:") {
t.Fatalf("unexpected deterministic package hash: %#v / %#v", firstMeta, secondMeta)
}
zr, err := zip.NewReader(bytes.NewReader(first), int64(len(first)))
if err != nil {
t.Fatalf("open package: %v", err)
}
if len(zr.File) != 3 {
t.Fatalf("zip entry count = %d, want 3", len(zr.File))
}
wantNames := []string{"checksums.sha256", "manifest.json", "workflows/web-src-hunting.json"}
for i, f := range zr.File {
if f.Name != wantNames[i] {
t.Fatalf("entry %d = %q, want %q", i, f.Name, wantNames[i])
}
}
if firstMeta.SourceRevision != 18 {
t.Fatalf("source revision = %d, want 18", firstMeta.SourceRevision)
}
if !strings.HasPrefix(firstMeta.ContentHash, "sha256:") || !strings.HasPrefix(firstMeta.GraphHash, "sha256:") {
t.Fatalf("content/graph hashes must be sha256: %#v", firstMeta)
}
}