@@ -39,6 +39,39 @@ type UtilsTestCases struct {
3939 Input * Article `yaml:"input"`
4040 Expected bool `yaml:"expected"`
4141 } `yaml:"article_validation_tests"`
42+
43+ RedisKeyPrefixTests []struct {
44+ Description string `yaml:"description"`
45+ Key string `yaml:"key"`
46+ Expected string `yaml:"expected"`
47+ } `yaml:"redis_key_prefix_tests"`
48+
49+ BuildArticleKeyTests []struct {
50+ Description string `yaml:"description"`
51+ Input string `yaml:"input"`
52+ Expected string `yaml:"expected"`
53+ } `yaml:"build_article_key_tests"`
54+
55+ ProcessArticleTests []struct {
56+ Description string `yaml:"description"`
57+ Input struct {
58+ Article Article `yaml:"article"`
59+ FeedURI string `yaml:"feedURI"`
60+ } `yaml:"input"`
61+ Expected Article `yaml:"expected"`
62+ } `yaml:"process_article_tests"`
63+
64+ ExtractArticleIdsTests []struct {
65+ Description string `yaml:"description"`
66+ Input []string `yaml:"input"`
67+ Expected []string `yaml:"expected"`
68+ } `yaml:"extract_article_ids_tests"`
69+
70+ GenerateArticleBodyTests []struct {
71+ Description string `yaml:"description"`
72+ Input Article `yaml:"input"`
73+ ExpectedJSON bool `yaml:"expected_json"`
74+ } `yaml:"generate_article_body_tests"`
4275}
4376
4477func TestBuildRequestHeaders (t * testing.T ) {
@@ -84,23 +117,55 @@ func TestBuildRedisKeys(t *testing.T) {
84117}
85118
86119func TestBuildArticleKey (t * testing.T ) {
87- hashValue := "13a0bebeed5b348147d880a1a4917587"
88- result := BuildArticleKey (hashValue )
89- expected := RedisArticlePrefix + hashValue
90- if result != expected {
91- t .Errorf ("Article key mismatch: got %s, want %s" , result , expected )
120+ data , err := os .ReadFile ("../testdata/test-cases.yaml" )
121+ if err != nil {
122+ t .Fatalf ("Failed to read test data: %v" , err )
123+ }
124+
125+ var testCases UtilsTestCases
126+ if err := yaml .Unmarshal (data , & testCases ); err != nil {
127+ t .Fatalf ("Failed to parse test data: %v" , err )
128+ }
129+
130+ for _ , tc := range testCases .BuildArticleKeyTests {
131+ t .Run (tc .Description , func (t * testing.T ) {
132+ result := BuildArticleKey (tc .Input )
133+ if result != tc .Expected {
134+ t .Errorf ("Article key mismatch: got %s, want %s" , result , tc .Expected )
135+ }
136+ })
92137 }
93138}
94139
95140func TestRedisKeyPrefixConstants (t * testing.T ) {
96- if RedisFeedPrefix != "feed:" {
97- t .Errorf ("RedisFeedPrefix: got %s, want feed:" , RedisFeedPrefix )
141+ data , err := os .ReadFile ("../testdata/test-cases.yaml" )
142+ if err != nil {
143+ t .Fatalf ("Failed to read test data: %v" , err )
98144 }
99- if RedisArticlesPrefix != "articles:" {
100- t .Errorf ("RedisArticlesPrefix: got %s, want articles:" , RedisArticlesPrefix )
145+
146+ var testCases UtilsTestCases
147+ if err := yaml .Unmarshal (data , & testCases ); err != nil {
148+ t .Fatalf ("Failed to parse test data: %v" , err )
101149 }
102- if RedisArticlePrefix != "article:" {
103- t .Errorf ("RedisArticlePrefix: got %s, want article:" , RedisArticlePrefix )
150+
151+ for _ , tc := range testCases .RedisKeyPrefixTests {
152+ t .Run (tc .Description , func (t * testing.T ) {
153+ var actual string
154+ switch tc .Key {
155+ case "REDIS_FEED_PREFIX" :
156+ actual = RedisFeedPrefix
157+ case "REDIS_ARTICLES_PREFIX" :
158+ actual = RedisArticlesPrefix
159+ case "REDIS_ARTICLE_PREFIX" :
160+ actual = RedisArticlePrefix
161+ default :
162+ t .Fatalf ("Unknown constant key: %s" , tc .Key )
163+ }
164+
165+ if actual != tc .Expected {
166+ t .Errorf ("%s mismatch: got %s, want %s" , tc .Key , actual , tc .Expected )
167+ }
168+ })
104169 }
105170}
106171
@@ -147,72 +212,89 @@ func TestIsValidArticle(t *testing.T) {
147212}
148213
149214func TestProcessArticle (t * testing.T ) {
150- article := Article {
151- GUID : "https://xkcd.com/3153/" ,
152- Title : "Test Article" ,
153- PubDate : "2024-10-10T00:00:00Z" ,
215+ data , err := os .ReadFile ("../testdata/test-cases.yaml" )
216+ if err != nil {
217+ t .Fatalf ("Failed to read test data: %v" , err )
154218 }
155- feedURI := "https://xkcd.com/atom.xml"
156-
157- result := ProcessArticle (article , feedURI )
158219
159- if result .Hash != "13a0bebeed5b348147d880a1a4917587" {
160- t .Errorf ("Hash mismatch: got %s" , result .Hash )
161- }
162- if result .Score != 1728518400000 {
163- t .Errorf ("Score mismatch: got %d" , result .Score )
164- }
165- if result .FeedURL != feedURI {
166- t .Errorf ("FeedURL mismatch: got %s" , result .FeedURL )
167- }
168- if result .GUID != article .GUID {
169- t .Errorf ("GUID mismatch: got %s" , result .GUID )
220+ var testCases UtilsTestCases
221+ if err := yaml .Unmarshal (data , & testCases ); err != nil {
222+ t .Fatalf ("Failed to parse test data: %v" , err )
170223 }
171- if result .Title != article .Title {
172- t .Errorf ("Title mismatch: got %s" , result .Title )
224+
225+ for _ , tc := range testCases .ProcessArticleTests {
226+ t .Run (tc .Description , func (t * testing.T ) {
227+ result := ProcessArticle (tc .Input .Article , tc .Input .FeedURI )
228+
229+ if result .Hash != tc .Expected .Hash {
230+ t .Errorf ("Hash mismatch: got %s, want %s" , result .Hash , tc .Expected .Hash )
231+ }
232+ if result .Score != tc .Expected .Score {
233+ t .Errorf ("Score mismatch: got %d, want %d" , result .Score , tc .Expected .Score )
234+ }
235+ if result .FeedURL != tc .Expected .FeedURL {
236+ t .Errorf ("FeedURL mismatch: got %s, want %s" , result .FeedURL , tc .Expected .FeedURL )
237+ }
238+ if result .GUID != tc .Expected .GUID {
239+ t .Errorf ("GUID mismatch: got %s, want %s" , result .GUID , tc .Expected .GUID )
240+ }
241+ if result .Title != tc .Expected .Title {
242+ t .Errorf ("Title mismatch: got %s, want %s" , result .Title , tc .Expected .Title )
243+ }
244+ })
173245 }
174246}
175247
176248func TestExtractArticleIds (t * testing.T ) {
177- keys := []string {
178- "article:13a0bebeed5b348147d880a1a4917587" ,
179- "article:21664da7ee05988c62d1f516f3442411" ,
180- "article:3fa08ba1591ba3683e87265ee9300946" ,
249+ data , err := os .ReadFile ("../testdata/test-cases.yaml" )
250+ if err != nil {
251+ t .Fatalf ("Failed to read test data: %v" , err )
181252 }
182253
183- result := ExtractArticleIds (keys )
184-
185- expected := []string {
186- "13a0bebeed5b348147d880a1a4917587" ,
187- "21664da7ee05988c62d1f516f3442411" ,
188- "3fa08ba1591ba3683e87265ee9300946" ,
254+ var testCases UtilsTestCases
255+ if err := yaml .Unmarshal (data , & testCases ); err != nil {
256+ t .Fatalf ("Failed to parse test data: %v" , err )
189257 }
190258
191- if ! reflect .DeepEqual (result , expected ) {
192- t .Errorf ("ExtractArticleIds mismatch:\n got: %+v\n want: %+v" , result , expected )
259+ for _ , tc := range testCases .ExtractArticleIdsTests {
260+ t .Run (tc .Description , func (t * testing.T ) {
261+ result := ExtractArticleIds (tc .Input )
262+
263+ if ! reflect .DeepEqual (result , tc .Expected ) {
264+ t .Errorf ("ExtractArticleIds mismatch:\n got: %+v\n want: %+v" , result , tc .Expected )
265+ }
266+ })
193267 }
194268}
195269
196270func TestGenerateArticleBody (t * testing.T ) {
197- article := Article {
198- GUID : "test-guid" ,
199- Title : "Test Article" ,
200- Hash : "abc123" ,
201- Score : 1234567890 ,
202- }
203-
204- result , err := GenerateArticleBody (article )
271+ data , err := os .ReadFile ("../testdata/test-cases.yaml" )
205272 if err != nil {
206- t .Fatalf ("GenerateArticleBody failed : %v" , err )
273+ t .Fatalf ("Failed to read test data : %v" , err )
207274 }
208275
209- var parsed Article
210- if err := json .Unmarshal ([] byte ( result ) , & parsed ); err != nil {
211- t .Fatalf ("Failed to parse generated JSON : %v" , err )
276+ var testCases UtilsTestCases
277+ if err := yaml .Unmarshal (data , & testCases ); err != nil {
278+ t .Fatalf ("Failed to parse test data : %v" , err )
212279 }
213280
214- if parsed .GUID != article .GUID || parsed .Title != article .Title ||
215- parsed .Hash != article .Hash || parsed .Score != article .Score {
216- t .Errorf ("Parsed article doesn't match original:\n got: %+v\n want: %+v" , parsed , article )
281+ for _ , tc := range testCases .GenerateArticleBodyTests {
282+ t .Run (tc .Description , func (t * testing.T ) {
283+ result , err := GenerateArticleBody (tc .Input )
284+ if err != nil {
285+ t .Fatalf ("GenerateArticleBody failed: %v" , err )
286+ }
287+
288+ var parsed Article
289+ if err := json .Unmarshal ([]byte (result ), & parsed ); err != nil {
290+ t .Fatalf ("Failed to parse generated JSON: %v" , err )
291+ }
292+
293+ // Verify round-trip
294+ if parsed .GUID != tc .Input .GUID || parsed .Title != tc .Input .Title ||
295+ parsed .Hash != tc .Input .Hash || parsed .Score != tc .Input .Score {
296+ t .Errorf ("Parsed article doesn't match original:\n got: %+v\n want: %+v" , parsed , tc .Input )
297+ }
298+ })
217299 }
218300}
0 commit comments