all repos

rss-tools @ 2bf041f98c81d4974d119c551a63fca6d8d4c006

get rss feed from sources that(i need and) dont provide one

rss-tools/sources/moviefeed/moviefeed_test.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
add tests for moviefeed, 1 month ago
1
package moviefeed
2
3
import (
4
	"encoding/xml"
5
	"fmt"
6
	"net/http"
7
	"net/http/httptest"
8
	"net/url"
9
	"strings"
10
	"testing"
11
	"time"
12
13
	"olexsmir.xyz/rss-tools/app"
14
	"olexsmir.xyz/x/is"
15
)
16
17
func TestHandleMoviesRendersFeedForRequestedID(t *testing.T) {
18
	server, client := newTMDBStub(t)
19
	defer server.Close()
20
21
	mf := &moviefeed{
22
		api:   NewTMDBAPI("test-key", client),
23
		shows: nil,
24
	}
25
26
	mux := http.NewServeMux()
27
	mux.HandleFunc("GET /movies/{rest...}", mf.handleMovies)
28
29
	req := httptest.NewRequest(http.MethodGet, "/movies/tt123", nil)
30
	rr := httptest.NewRecorder()
31
	mux.ServeHTTP(rr, req)
32
33
	is.Equal(t, rr.Code, http.StatusOK)
34
	if got := rr.Header().Get("Content-Type"); !strings.Contains(got, "application/atom+xml") {
35
		t.Fatalf("expected atom response content-type, got %q", got)
36
	}
37
38
	var feed app.AtomFeed
39
	is.Err(t, xml.NewDecoder(rr.Body).Decode(&feed), nil)
40
	is.Equal(t, feed.Title, "Episodes from tt123")
41
	is.Equal(t, feed.ID, "moviefeed-tt123")
42
	is.Equal(t, len(feed.Entries), 3)                                  // two episodes + one image entry
43
	is.Equal(t, strings.Contains(feed.Entries[0].Title, "S1E2"), true) // newest first
44
	is.Equal(t, feed.Entries[2].ID, "tmdb-101-s1e1-img")
45
}
46
47
func TestHandleMoviesUsesConfiguredShowsForEmptyPath(t *testing.T) {
48
	server, client := newTMDBStub(t)
49
	defer server.Close()
50
51
	mf := &moviefeed{
52
		api:   NewTMDBAPI("test-key", client),
53
		shows: []string{"tt123"},
54
	}
55
56
	mux := http.NewServeMux()
57
	mux.HandleFunc("GET /movies/{rest...}", mf.handleMovies)
58
59
	req := httptest.NewRequest(http.MethodGet, "/movies/", nil)
60
	rr := httptest.NewRecorder()
61
	mux.ServeHTTP(rr, req)
62
63
	is.Equal(t, rr.Code, http.StatusOK)
64
65
	var feed app.AtomFeed
66
	is.Err(t, xml.NewDecoder(rr.Body).Decode(&feed), nil)
67
	is.Equal(t, feed.ID, "moviefeed-tt123")
68
}
69
70
func TestHandleMoviesReturnsBadRequestWhenNoIDs(t *testing.T) {
71
	mf := &moviefeed{
72
		api:   NewTMDBAPI("test-key", http.DefaultClient),
73
		shows: nil,
74
	}
75
76
	mux := http.NewServeMux()
77
	mux.HandleFunc("GET /movies/{rest...}", mf.handleMovies)
78
79
	req := httptest.NewRequest(http.MethodGet, "/movies/", nil)
80
	rr := httptest.NewRecorder()
81
	mux.ServeHTTP(rr, req)
82
83
	is.Equal(t, rr.Code, http.StatusBadRequest)
84
	is.Equal(t, strings.Contains(rr.Body.String(), "no movie IDs provided"), true)
85
}
86
87
func TestFetchEpisodesForShowFiltersRecentAndMapsFields(t *testing.T) {
88
	server, client := newTMDBStub(t)
89
	defer server.Close()
90
91
	api := NewTMDBAPI("test-key", client)
92
	episodes, err := api.FetchEpisodesForShow("tt123")
93
	is.Err(t, err, nil)
94
95
	is.Equal(t, len(episodes), 2) // old episode is filtered out
96
	is.Equal(t, episodes[0].ShowID, "101")
97
	is.Equal(t, episodes[0].ShowName, "Test Show")
98
}
99
100
func newTMDBStub(t *testing.T) (*httptest.Server, *http.Client) {
101
	t.Helper()
102
103
	recentDay := time.Now().AddDate(0, 0, -7).Format(dateFormat)
104
	newestDay := time.Now().AddDate(0, 0, -1).Format(dateFormat)
105
	oldDay := time.Now().AddDate(0, 0, -45).Format(dateFormat)
106
107
	mux := http.NewServeMux()
108
	mux.HandleFunc("/3/find/tt123", func(w http.ResponseWriter, r *http.Request) {
109
		if got := r.URL.Query().Get("external_source"); got != "imdb_id" {
110
			t.Fatalf("unexpected external_source query: %q", got)
111
		}
112
		if got := r.URL.Query().Get("api_key"); got != "test-key" {
113
			t.Fatalf("unexpected api_key query: %q", got)
114
		}
115
		_, _ = w.Write([]byte(`{"tv_results":[{"id":101}]}`))
116
	})
117
118
	mux.HandleFunc("/3/tv/101", func(w http.ResponseWriter, r *http.Request) {
119
		if got := r.URL.Query().Get("api_key"); got != "test-key" {
120
			t.Fatalf("unexpected api_key query: %q", got)
121
		}
122
		_, _ = w.Write([]byte(`{"id":101,"name":"Test Show","number_of_seasons":1}`))
123
	})
124
125
	mux.HandleFunc("/3/tv/101/season/1", func(w http.ResponseWriter, r *http.Request) {
126
		if got := r.URL.Query().Get("api_key"); got != "test-key" {
127
			t.Fatalf("unexpected api_key query: %q", got)
128
		}
129
		body := fmt.Sprintf(`{
130
			"episodes": [
131
				{"id": 1001, "name": "Episode 1", "overview": "E1", "air_date": %q, "episode_number": 1, "season_number": 1, "still_path": "/e1.jpg"},
132
				{"id": 1002, "name": "Episode 2", "overview": "E2", "air_date": %q, "episode_number": 2, "season_number": 1, "still_path": ""},
133
				{"id": 1003, "name": "Episode old", "overview": "old", "air_date": %q, "episode_number": 3, "season_number": 1, "still_path": ""}
134
			]
135
		}`, recentDay, newestDay, oldDay)
136
		_, _ = w.Write([]byte(body))
137
	})
138
139
	server := httptest.NewServer(mux)
140
	target, err := url.Parse(server.URL)
141
	is.Err(t, err, nil)
142
143
	client := &http.Client{
144
		Transport: rewriteTransport{target: target},
145
	}
146
	return server, client
147
}
148
149
type rewriteTransport struct {
150
	target *url.URL
151
}
152
153
func (t rewriteTransport) RoundTrip(req *http.Request) (*http.Response, error) {
154
	clone := req.Clone(req.Context())
155
	copiedURL := *clone.URL
156
	copiedURL.Scheme = t.target.Scheme
157
	copiedURL.Host = t.target.Host
158
	clone.URL = &copiedURL
159
	clone.Host = t.target.Host
160
	return http.DefaultTransport.RoundTrip(clone)
161
}