mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-05 16:15:43 +00:00
83 lines
2.7 KiB
Go
83 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/GopeedLab/gopeed/pkg/base"
|
|
"github.com/GopeedLab/gopeed/pkg/download"
|
|
restmodel "github.com/GopeedLab/gopeed/pkg/rest/model"
|
|
)
|
|
|
|
func TestResolveThenCreateWithDownloadOptions(t *testing.T) {
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Disposition", `attachment; filename="payload.txt"`)
|
|
w.Header().Set("Content-Length", "4")
|
|
_, _ = w.Write([]byte("test"))
|
|
}))
|
|
t.Cleanup(upstream.Close)
|
|
d := download.NewDownloader(&download.DownloaderConfig{StorageDir: t.TempDir()})
|
|
if err := d.Setup(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := d.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
// Resolving must work even when the default download directory is unusable.
|
|
blocked := filepath.Join(t.TempDir(), "not-a-directory")
|
|
if err := os.WriteFile(blocked, nil, 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
current, err := d.GetConfig()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
config := *current
|
|
config.DownloadDir = blocked
|
|
config.MaxRunning = 0 // Inspect the created task before it starts downloading.
|
|
if err := d.PutConfig(&config); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
service, err := NewService(d)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
resolved := serviceTestRequest[*download.ResolveResult](t, service, http.MethodPost, "/api/v1/resolve", &restmodel.ResolveTask{
|
|
Req: &base.Request{URL: upstream.URL},
|
|
})
|
|
if resolved.ID == "" || resolved.Res.Size != 4 || resolved.Res.Files[0].Name != "payload.txt" {
|
|
t.Fatalf("unexpected resolved resource: %+v", resolved)
|
|
}
|
|
dir := filepath.Join(t.TempDir(), "chosen-after-resolve")
|
|
opts := &base.Options{Path: dir, Name: "renamed.txt", SelectFiles: []int{0}}
|
|
id := serviceTestRequest[string](t, service, http.MethodPost, "/api/v1/tasks", &restmodel.CreateTask{Rid: resolved.ID, Opts: opts})
|
|
task := serviceTestRequest[*download.Task](t, service, http.MethodGet, "/api/v1/tasks/"+id, nil)
|
|
if task.Meta.Opts.Path != dir || task.Meta.Opts.Name != opts.Name || !reflect.DeepEqual(task.Meta.Opts.SelectFiles, opts.SelectFiles) {
|
|
t.Fatalf("creation lost submitted download options: %+v", task.Meta.Opts)
|
|
}
|
|
}
|
|
|
|
func serviceTestRequest[T any](t *testing.T, service *Service, method, path string, body any) T {
|
|
t.Helper()
|
|
encoded, err := json.Marshal(body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
status, response := service.JSON(method, path, nil, encoded, nil)
|
|
var result restmodel.Result[T]
|
|
if err := json.Unmarshal(response, &result); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if status != http.StatusOK || result.Code != restmodel.CodeOk {
|
|
t.Fatalf("%s %s failed: status=%d response=%s", method, path, status, response)
|
|
}
|
|
return result.Data
|
|
}
|