Files
soft_quay/core/downloader/task_test.go
T

90 lines
2.6 KiB
Go

package downloader
import (
"errors"
"path/filepath"
"testing"
)
func TestTaskValidateAndDerivedPaths(t *testing.T) {
task := validTaskForTest()
if err := task.Validate(); err != nil {
t.Fatalf("Validate() error = %v", err)
}
paths, err := DeriveTaskPaths(filepath.Join(t.TempDir(), "downloads"), task.RequestID)
if err != nil {
t.Fatalf("DeriveTaskPaths() error = %v", err)
}
for _, path := range []string{
paths.Metadata,
paths.Backup,
paths.Part,
paths.Completed,
} {
relative, err := filepath.Rel(paths.Root, path)
if err != nil || relative == ".." {
t.Fatalf("derived path escapes root: %s", path)
}
}
}
func TestTaskRejectsInvalidFields(t *testing.T) {
tests := []struct {
name string
mutate func(*Task)
}{
{name: "request id", mutate: func(task *Task) { task.RequestID = "../escape" }},
{name: "app id", mutate: func(task *Task) { task.AppID = "Bad App" }},
{name: "URL", mutate: func(task *Task) { task.URL = "http://example.invalid/app.zip" }},
{name: "state", mutate: func(task *Task) { task.Status = "unknown" }},
{name: "negative done", mutate: func(task *Task) { task.Done = -1 }},
{name: "done exceeds total", mutate: func(task *Task) { task.Done = task.Total + 1 }},
{name: "unknown total value", mutate: func(task *Task) {
task.TotalKnown = false
task.Total = 10
}},
{name: "weak etag", mutate: func(task *Task) {
task.Validator = EntityValidator{ETag: `W/"weak"`}
}},
{name: "failed without code", mutate: func(task *Task) {
task.Status = StatusFailed
task.ErrorCode = ""
}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
task := validTaskForTest()
test.mutate(&task)
if err := task.Validate(); !errors.Is(err, ErrInvalidTask) {
t.Fatalf("Validate() error = %v, want %v", err, ErrInvalidTask)
}
})
}
}
func TestValidatorsMatchRejectsDifferentKinds(t *testing.T) {
expected := EntityValidator{ETag: `"v1"`}
if validatorsMatch(expected, EntityValidator{LastModified: "Wed, 16 Jul 2026 10:00:00 GMT"}) {
t.Fatal("ETag unexpectedly matched Last-Modified")
}
if validatorsMatch(expected, EntityValidator{ETag: `"v2"`}) {
t.Fatal("different ETags matched")
}
if !validatorsMatch(expected, EntityValidator{}) {
t.Fatal("absent response validator should not contradict If-Range")
}
}
func validTaskForTest() Task {
return Task{
SchemaVersion: TaskSchemaVersion,
RequestID: "request-001",
AppID: "json-parser",
URL: "https://download.invalid/json-parser.zip",
Status: StatusQueued,
TotalKnown: true,
Total: 42,
CreatedAt: "2026-07-16T00:00:00Z",
}
}