all repos

rss-tools @ 70f8cb68d68020ffbcd4b0b5d602cefaa36e5a2a

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
moviefeed: dont make any requests to the actual api, 14 days ago
1
package moviefeed
2
3
import (
4
	"encoding/xml"
5
	"errors"
6
	"net/http"
7
	"net/http/httptest"
8
	"strings"
9
	"testing"
10
	"time"
11
12
	"olexsmir.xyz/rss-tools/app/atom"
13
	"olexsmir.xyz/x/is"
14
)
15
16
type fakeEpisodeAPI struct {
17
	episodes map[string][]TMDBEpisode
18
	errs     map[string]error
19
}
20
21
func (f fakeEpisodeAPI) FetchEpisodesForShow(showID string) ([]TMDBEpisode, error) {
22
	if err, ok := f.errs[showID]; ok {
23
		return nil, err
24
	}
25
	if episodes, ok := f.episodes[showID]; ok {
26
		return episodes, nil
27
	}
28
	return nil, nil
29
}
30
31
func TestHandleMoviesRendersFeedFromConfiguredShows(t *testing.T) {
32
	episodes := []TMDBEpisode{
33
		{
34
			ID:            1001,
35
			Name:          "Episode 1",
36
			Overview:      "E1",
37
			AirDate:       "2026-04-20",
38
			EpisodeNumber: 1,
39
			SeasonNumber:  1,
40
			StillPath:     "/e1.jpg",
41
			ShowName:      "Test Show",
42
			ShowID:        "101",
43
		},
44
		{
45
			ID:            1002,
46
			Name:          "Episode 2",
47
			Overview:      "E2",
48
			AirDate:       "2026-04-21",
49
			EpisodeNumber: 2,
50
			SeasonNumber:  1,
51
			StillPath:     "",
52
			ShowName:      "Test Show",
53
			ShowID:        "101",
54
		},
55
	}
56
57
	mf := &moviefeed{
58
		api: fakeEpisodeAPI{
59
			episodes: map[string][]TMDBEpisode{
60
				"tt123": episodes,
61
			},
62
		},
63
		shows: []string{"tt123"},
64
	}
65
66
	mux := http.NewServeMux()
67
	mux.HandleFunc("GET /movies", mf.handleMovies)
68
69
	req := httptest.NewRequest(http.MethodGet, "/movies", nil)
70
	rr := httptest.NewRecorder()
71
	mux.ServeHTTP(rr, req)
72
73
	is.Equal(t, rr.Code, http.StatusOK)
74
	if got := rr.Header().Get("Content-Type"); !strings.Contains(got, "application/atom+xml") {
75
		t.Fatalf("expected atom response content-type, got %q", got)
76
	}
77
78
	var feed atom.Feed
79
	is.Err(t, xml.NewDecoder(rr.Body).Decode(&feed), nil)
80
	is.Equal(t, feed.Title, "moviefeed")
81
	is.Equal(t, len(feed.Entry), 2)
82
	is.Equal(t, strings.Contains(feed.Entry[0].Title, "S1E2"), true)
83
	is.Equal(t, feed.Entry[0].Content.Type, "text")
84
	is.Equal(t, len(feed.Entry[1].Link), 2)
85
	is.Equal(t, feed.Entry[1].Link[1].Rel, "enclosure")
86
	is.Equal(t, feed.Entry[1].Link[1].Type, "image/jpeg")
87
	is.Equal(t, feed.Entry[1].Link[1].Length, uint(0))
88
	is.Equal(t, feed.Entry[1].Link[1].Href, "https://image.tmdb.org/t/p/w500/e1.jpg")
89
	is.Equal(t, feed.Entry[1].Content.Type, "xhtml")
90
}
91
92
func TestHandleMoviesContinuesWhenOneShowFails(t *testing.T) {
93
	episodes := []TMDBEpisode{
94
		{
95
			ID:            1001,
96
			Name:          "Episode 1",
97
			Overview:      "E1",
98
			AirDate:       "2026-04-20",
99
			EpisodeNumber: 1,
100
			SeasonNumber:  1,
101
			StillPath:     "/e1.jpg",
102
			ShowName:      "Test Show",
103
			ShowID:        "101",
104
		},
105
		{
106
			ID:            1002,
107
			Name:          "Episode 2",
108
			Overview:      "E2",
109
			AirDate:       "2026-04-21",
110
			EpisodeNumber: 2,
111
			SeasonNumber:  1,
112
			StillPath:     "",
113
			ShowName:      "Test Show",
114
			ShowID:        "101",
115
		},
116
	}
117
118
	mf := &moviefeed{
119
		api: fakeEpisodeAPI{
120
			episodes: map[string][]TMDBEpisode{
121
				"tt123": episodes,
122
			},
123
			errs: map[string]error{
124
				"bad-show": errors.New("boom"),
125
			},
126
		},
127
		shows: []string{"bad-show", "tt123"},
128
	}
129
130
	mux := http.NewServeMux()
131
	mux.HandleFunc("GET /movies", mf.handleMovies)
132
133
	req := httptest.NewRequest(http.MethodGet, "/movies", nil)
134
	rr := httptest.NewRecorder()
135
	mux.ServeHTTP(rr, req)
136
137
	is.Equal(t, rr.Code, http.StatusOK)
138
139
	var feed atom.Feed
140
	is.Err(t, xml.NewDecoder(rr.Body).Decode(&feed), nil)
141
	is.Equal(t, len(feed.Entry), 2)
142
}
143
144
func TestFilterRecentEpisodes(t *testing.T) {
145
	now := time.Now()
146
	recent := now.AddDate(0, 0, -5).Format(dateFormat)
147
	old := now.AddDate(0, 0, -40).Format(dateFormat)
148
149
	episodes := filterRecentEpisodes([]TMDBEpisode{
150
		{AirDate: recent, Name: "recent"},
151
		{AirDate: old, Name: "old"},
152
		{AirDate: "", Name: "missing"},
153
	})
154
155
	is.Equal(t, 1, len(episodes))
156
	is.Equal(t, "recent", episodes[0].Name)
157
}
158
159
func TestEpisodeContentIncludesImageInBody(t *testing.T) {
160
	content, contentType := episodeContent(TMDBEpisode{
161
		Name:      "Episode 1",
162
		Overview:  "E1",
163
		StillPath: "/e1.jpg",
164
	})
165
166
	is.Equal(t, contentType, "xhtml")
167
	is.Equal(t, strings.Contains(content, "<body>"), true)
168
	is.Equal(t, strings.Contains(content, `<img src="https://image.tmdb.org/t/p/w500/e1.jpg" alt="Episode 1"`), true)
169
	is.Equal(t, strings.Contains(content, "</body>"), true)
170
}