rss email digests over ssh because you're a cool kid
herald.dunkirk.sh
go
rss
rss-reader
ssh
charm
1package config
2
3import (
4 "testing"
5)
6
7func TestValidate_NoEmail(t *testing.T) {
8 cfg := &ParsedConfig{
9 CronExpr: "0 8 * * *",
10 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
11 }
12 err := Validate(cfg)
13 if err != ErrNoEmail {
14 t.Errorf("expected ErrNoEmail, got %v", err)
15 }
16}
17
18func TestValidate_BadEmail(t *testing.T) {
19 cfg := &ParsedConfig{
20 Email: "not-an-email",
21 CronExpr: "0 8 * * *",
22 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
23 }
24 err := Validate(cfg)
25 if err != ErrBadEmail {
26 t.Errorf("expected ErrBadEmail, got %v", err)
27 }
28}
29
30func TestValidate_GoodEmail(t *testing.T) {
31 validEmails := []string{
32 "user@example.com",
33 "test.user@example.com",
34 "user+tag@example.com",
35 "user@sub.example.com",
36 }
37
38 for _, email := range validEmails {
39 cfg := &ParsedConfig{
40 Email: email,
41 CronExpr: "0 8 * * *",
42 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
43 }
44 err := Validate(cfg)
45 if err != nil {
46 t.Errorf("email %s should be valid, got error: %v", email, err)
47 }
48 }
49}
50
51func TestValidate_NoCron(t *testing.T) {
52 cfg := &ParsedConfig{
53 Email: "user@example.com",
54 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
55 }
56 err := Validate(cfg)
57 if err != ErrNoCron {
58 t.Errorf("expected ErrNoCron, got %v", err)
59 }
60}
61
62func TestValidate_BadCron(t *testing.T) {
63 invalidCrons := []string{
64 "invalid",
65 "* * * *", // too few fields
66 "60 * * * *", // minute out of range
67 "* 25 * * *", // hour out of range
68 }
69
70 for _, cron := range invalidCrons {
71 cfg := &ParsedConfig{
72 Email: "user@example.com",
73 CronExpr: cron,
74 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
75 }
76 err := Validate(cfg)
77 if err != ErrBadCron {
78 t.Errorf("cron %q should be invalid, got error: %v", cron, err)
79 }
80 }
81}
82
83func TestValidate_GoodCron(t *testing.T) {
84 validCrons := []string{
85 "0 8 * * *",
86 "*/5 * * * *",
87 "0 0 * * 0",
88 "0 12 1 * *",
89 "30 14 * * 1-5",
90 }
91
92 for _, cron := range validCrons {
93 cfg := &ParsedConfig{
94 Email: "user@example.com",
95 CronExpr: cron,
96 Feeds: []FeedEntry{{URL: "https://example.com/feed.xml"}},
97 }
98 err := Validate(cfg)
99 if err != nil {
100 t.Errorf("cron %q should be valid, got error: %v", cron, err)
101 }
102 }
103}
104
105func TestValidate_NoFeeds(t *testing.T) {
106 cfg := &ParsedConfig{
107 Email: "user@example.com",
108 CronExpr: "0 8 * * *",
109 Feeds: []FeedEntry{},
110 }
111 err := Validate(cfg)
112 if err != ErrNoFeeds {
113 t.Errorf("expected ErrNoFeeds, got %v", err)
114 }
115}
116
117func TestValidate_BadFeedURL(t *testing.T) {
118 invalidURLs := []string{
119 "not-a-url",
120 "://missing-scheme.com",
121 "http://",
122 }
123
124 for _, url := range invalidURLs {
125 cfg := &ParsedConfig{
126 Email: "user@example.com",
127 CronExpr: "0 8 * * *",
128 Feeds: []FeedEntry{{URL: url}},
129 }
130 err := Validate(cfg)
131 if err != ErrBadFeedURL {
132 t.Errorf("URL %q should be invalid, got error: %v", url, err)
133 }
134 }
135}
136
137func TestValidate_GoodFeedURL(t *testing.T) {
138 validURLs := []string{
139 "https://example.com/feed.xml",
140 "http://example.com/rss",
141 "https://sub.example.com/atom.xml",
142 "https://example.com:8080/feed",
143 "https://example.com/path/to/feed.xml",
144 }
145
146 for _, url := range validURLs {
147 cfg := &ParsedConfig{
148 Email: "user@example.com",
149 CronExpr: "0 8 * * *",
150 Feeds: []FeedEntry{{URL: url}},
151 }
152 err := Validate(cfg)
153 if err != nil {
154 t.Errorf("URL %q should be valid, got error: %v", url, err)
155 }
156 }
157}
158
159func TestValidate_MultipleFeeds(t *testing.T) {
160 cfg := &ParsedConfig{
161 Email: "user@example.com",
162 CronExpr: "0 8 * * *",
163 Feeds: []FeedEntry{
164 {URL: "https://feed1.com/rss"},
165 {URL: "https://feed2.com/atom"},
166 {URL: "https://feed3.com/json"},
167 },
168 }
169 err := Validate(cfg)
170 if err != nil {
171 t.Errorf("valid config failed: %v", err)
172 }
173}
174
175func TestValidate_CompleteConfig(t *testing.T) {
176 cfg := &ParsedConfig{
177 Email: "user@example.com",
178 CronExpr: "0 9 * * *",
179 Digest: true,
180 Inline: false,
181 Feeds: []FeedEntry{
182 {URL: "https://blog.example.com/feed.xml", Name: "Example Blog"},
183 {URL: "https://news.example.com/rss"},
184 },
185 }
186 err := Validate(cfg)
187 if err != nil {
188 t.Errorf("complete valid config failed: %v", err)
189 }
190}