package httpapi_test import ( "bytes" "mime/multipart" "net/http" "net/url" "strings" "testing" "git.vakhrushev.me/av/jellybit/internal/httpapi" "git.vakhrushev.me/av/jellybit/internal/ingest" "git.vakhrushev.me/av/jellybit/internal/store" ) // Веб-форма с выбранным .torrent-файлом → приём по байтам (TorrentData). func TestUIAddTorrentFile(t *testing.T) { ing := &fakeIngestor{res: ingest.Result{DownloadID: tid, State: store.StateCatched}} srv := newServer(t, httpapi.Deps{Ingestor: ing, Commander: &fakeCommander{}, Reader: &fakeReader{}}) var body bytes.Buffer mw := multipart.NewWriter(&body) _ = mw.WriteField("source", "") // источник пуст — используется файл fw, _ := mw.CreateFormFile("torrent", "dune.torrent") torrentBytes := []byte("d8:announce…bytes") _, _ = fw.Write(torrentBytes) _ = mw.Close() resp, err := noRedirectClient().Post(srv.URL+"/ui/downloads", mw.FormDataContentType(), &body) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusSeeOther { t.Fatalf("status = %d, want 303", resp.StatusCode) } if !bytes.Equal(ing.lastReq.TorrentData, torrentBytes) { t.Errorf("TorrentData не проброшен в ingest: %q", ing.lastReq.TorrentData) } } // Без файла — прежний текстовый путь (Source), TorrentData пуст. func TestUIAddTextNoFile(t *testing.T) { ing := &fakeIngestor{res: ingest.Result{DownloadID: tid, State: store.StateCatched}} srv := newServer(t, httpapi.Deps{Ingestor: ing, Commander: &fakeCommander{}, Reader: &fakeReader{}}) var body bytes.Buffer mw := multipart.NewWriter(&body) _ = mw.WriteField("source", "magnet:?xt=urn:btih:abc") _ = mw.Close() resp, err := noRedirectClient().Post(srv.URL+"/ui/downloads", mw.FormDataContentType(), &body) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusSeeOther { t.Fatalf("status = %d, want 303", resp.StatusCode) } if len(ing.lastReq.TorrentData) != 0 { t.Errorf("TorrentData должен быть пуст без файла") } if !strings.HasPrefix(ing.lastReq.Source, "magnet:") { t.Errorf("source не проброшен: %q", ing.lastReq.Source) } } // Обычная (не-multipart) urlencoded-отправка тоже работает (ErrNotMultipart // глотается, поля уже в PostForm) — устойчивость к curl/старой странице. func TestUIAddUrlencoded(t *testing.T) { ing := &fakeIngestor{res: ingest.Result{DownloadID: tid, State: store.StateCatched}} srv := newServer(t, httpapi.Deps{Ingestor: ing, Commander: &fakeCommander{}, Reader: &fakeReader{}}) resp, err := noRedirectClient().PostForm(srv.URL+"/ui/downloads", url.Values{ "source": {"magnet:?xt=urn:btih:abc"}, }) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusSeeOther { t.Fatalf("status = %d, want 303", resp.StatusCode) } if !strings.HasPrefix(ing.lastReq.Source, "magnet:") { t.Errorf("urlencoded source не проброшен: %q", ing.lastReq.Source) } }