package main import ( "context" "encoding/json" "errors" "fmt" "io" "local/storage" "net/http" "net/http/httptest" "os" "strings" "testing" "time" "github.com/mmcdole/gofeed" ) type stringReaderCloser struct { io.Reader } func mockReadClose(s string) io.ReadCloser { reader := strings.NewReader(s) return stringReaderCloser{Reader: reader} } func (src stringReaderCloser) Close() error { return nil } func fakeRSSServer() *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(` Item Title https://roosterteeth.com/episode/rooster-teeth-podcast-2019-549 Tue, 18 Jun 2019 19:00:00 +0000 Gavin Free discuss raditation, toilet paper face, Chris's continued haircuts, and more on this week's RT Podcast! magnet:-xt1 magnet:-xt2 link `)) })) } func TestMainLoopCtx(t *testing.T) { ctx, can := context.WithCancel(context.Background()) can() c := &Config{ interval: time.Hour, ctx: ctx, } if err := mainLoop(c); err == nil || !strings.Contains(err.Error(), "cancel") { t.Fatal(err) } } func TestConfig(t *testing.T) { was := os.Args[:] defer func() { os.Args = was }() os.Args = []string{"a"} if _, err := config(); err != nil { t.Fatal(err) } os.Args = []string{"a", "-interval", "not a duration"} stderr := os.Stderr f, _ := os.Open("/dev/null") os.Stderr = f defer func() { os.Stderr = stderr }() if _, err := config(); err == nil { t.Fatal(err) } } func TestGetGoFeed(t *testing.T) { s := fakeRSSServer() defer s.Close() f, err := getGoFeed(s.URL) if err != nil { t.Fatal(err) } if len(f.Items) != 1 { t.Fatal(len(f.Items)) } } func TestGetItemContent(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`Hello`)) })) defer s.Close() cases := []struct { item gofeed.Item body string err error }{ { item: gofeed.Item{ Description: "hi", Content: "hi2", }, body: "hi", err: nil, }, { item: gofeed.Item{ Content: "hi2", }, body: "hi2", err: nil, }, { item: gofeed.Item{ Link: s.URL, }, body: "Hello", err: nil, }, } for i, c := range cases { body, err := getItemContent(&c.item) cerrS := fmt.Sprintf("%v", c.err) errS := fmt.Sprintf("%v", err) if cerrS != errS { t.Errorf("[%d] unexpected err %v, want %v", i, err, c.err) } if body != c.body { t.Errorf("[%d] unexpected body %v, want %v", i, body, c.body) } } } func TestIsDone(t *testing.T) { db, _ := storage.New(storage.MAP) db.Set("a", []byte("hi")) if ok, err := isDone(db, "a"); err != nil { t.Fatal(err) } else if !ok { t.Fatal(ok) } if ok, err := isDone(db, "b"); err != nil { t.Fatal(err) } else if ok { t.Fatal(ok) } } func TestGetSessionID(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add(sessionHeader, "id") w.Write([]byte(`Hello`)) })) defer s.Close() session, err := getSessionID(s.URL) if err != nil { t.Fatal(err) } if session != "id" { t.Fatal(session) } } func TestBuildReqBody(t *testing.T) { var want struct { Method string `json:"method"` Arguments struct { Filename string `json:"filename"` DownloadDir string `json:"download-dir"` } `json:"arguments"` } b := buildReqBody("out", "mag") if err := json.NewDecoder(b).Decode(&want); err != nil { t.Fatal(err) } if want.Method != "torrent-add" { t.Fatal(want.Method) } if want.Arguments.Filename != "mag" { t.Fatal(want.Arguments.Filename) } if want.Arguments.DownloadDir != "out" { t.Fatal(want.Arguments.DownloadDir) } } func TestSucceeded(t *testing.T) { cases := []struct { s string err error }{ { s: `{"result":"success"}`, err: nil, }, { s: `this isnt json`, err: errors.New("invalid character 'h' in literal true (expecting 'r')"), }, { s: `{"result":"failure"}`, err: errors.New(`denied: {"result":"failure"}`), }, } for i, c := range cases { err := succeeded(mockReadClose(c.s)) cerrS := fmt.Sprintf("%v", c.err) errS := fmt.Sprintf("%v", err) if cerrS != errS { t.Errorf("[%d] unexpected err %v, want %v", i, err, c.err) } } } func TestFindMagnets(t *testing.T) { cases := []struct { s string l int }{ { s: `here is some magnet:-xt1 and magnet:-xt2 another one link`, l: 3, }, } for i, c := range cases { out := findMagnets(c.s) if len(out) != c.l { t.Errorf("[%d] found %v magnets, want %v", i, len(out), c.l) } } }