package api
import (
"strings"
"testing"
)
// The editor writes only pipelines: one segment under ci/, one of the
// pipeline extensions, nothing else reachable.
func TestPipelinePathStaysInsideCI(t *testing.T) {
for path, ok := range map[string]bool{
"ci/build.json": true,
"ci/checks.yml": true,
"ci/checks.yaml": true,
"ci/nested/x.json": false,
"ci/../main.go": false,
"internal/web/web.go": false,
"ci/.hidden.json": false,
"ci/notes.txt": false,
"ci/": false,
} {
if err := validatePipelinePath(path); (err == nil) != ok {
t.Errorf("validatePipelinePath(%q) = %v, want ok=%v", path, err, ok)
}
}
}
// JSON is judged locally the way the run path would read it; yml with
// no engine passes through to be judged at register time.
func TestPipelineDiagnosticsSpeakPlainly(t *testing.T) {
var d Deps
if diags := d.pipelineDiagnostics("alpha", "ci/x.json", `{"steps":[{"id":"","task":""}]}`); len(diags) != 2 {
t.Fatalf("want name+step findings, got %v", diags)
}
if diags := d.pipelineDiagnostics("alpha", "ci/x.json", "not json"); len(diags) != 1 || !strings.Contains(diags[0], "not JSON") {
t.Fatalf("bad json not named: %v", diags)
}
if diags := d.pipelineDiagnostics("alpha", "ci/x.yml", "whatever:"); diags != nil {
t.Fatalf("no engine must mean no findings, got %v", diags)
}
d.ValidateCIYAML = func(repo, name string, spec []byte) ([]string, error) {
return []string{"line 3: unknown needs"}, nil
}
if diags := d.pipelineDiagnostics("alpha", "ci/x.yml", "x"); len(diags) != 1 || !strings.Contains(diags[0], "line 3") {
t.Fatalf("engine findings lost: %v", diags)
}
}