Skip to content

Commit c488ff5

Browse files
author
Arpith Siromoney
committed
refactor: Move all test data to YAML files
Extracted hardcoded test data from both JS and Go tests into shared YAML files in testdata/ directory. This ensures both test suites use exactly the same test data. Changes: - Added new test data to testdata/test-cases.yaml: - redis_key_prefix_tests - build_article_key_tests - process_article_tests - extract_article_ids_tests - generate_article_body_tests - Updated src/lib/feedUtils.test.js to use YAML data for all tests - Updated feedfetcher/utils_test.go to use YAML data for all tests All tests passing: - JavaScript: 29 tests ✓ (7 articleUtils + 22 feedUtils) - Go: 38 tests ✓ (7 articles + 31 utils)
1 parent 6170eb9 commit c488ff5

File tree

3 files changed

+245
-107
lines changed

3 files changed

+245
-107
lines changed

feedfetcher/utils_test.go

Lines changed: 140 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4477
func TestBuildRequestHeaders(t *testing.T) {
@@ -84,23 +117,55 @@ func TestBuildRedisKeys(t *testing.T) {
84117
}
85118

86119
func 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

95140
func 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

149214
func 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

176248
func 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:\ngot: %+v\nwant: %+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:\ngot: %+v\nwant: %+v", result, tc.Expected)
265+
}
266+
})
193267
}
194268
}
195269

196270
func 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:\ngot: %+v\nwant: %+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:\ngot: %+v\nwant: %+v", parsed, tc.Input)
297+
}
298+
})
217299
}
218300
}

src/lib/feedUtils.test.js

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,21 @@ testCases.redis_keys_tests.forEach((testCase) => {
4949
});
5050

5151
// Test buildArticleKey
52-
test('buildArticleKey creates correct format', () => {
53-
const hashValue = '13a0bebeed5b348147d880a1a4917587';
54-
const result = feedUtils.buildArticleKey(hashValue);
55-
assert.strictEqual(result, `${feedUtils.REDIS_ARTICLE_PREFIX}${hashValue}`);
52+
testCases.build_article_key_tests.forEach((testCase) => {
53+
test(testCase.description, () => {
54+
const result = feedUtils.buildArticleKey(testCase.input);
55+
assert.strictEqual(result, testCase.expected,
56+
`Article key mismatch: got ${result}, expected ${testCase.expected}`);
57+
});
5658
});
5759

5860
// Test Redis key prefix constants
59-
test('Redis prefix constants are defined', () => {
60-
assert.strictEqual(feedUtils.REDIS_FEED_PREFIX, 'feed:');
61-
assert.strictEqual(feedUtils.REDIS_ARTICLES_PREFIX, 'articles:');
62-
assert.strictEqual(feedUtils.REDIS_ARTICLE_PREFIX, 'article:');
61+
testCases.redis_key_prefix_tests.forEach((testCase) => {
62+
test(testCase.description, () => {
63+
const constantValue = feedUtils[testCase.key];
64+
assert.strictEqual(constantValue, testCase.expected,
65+
`${testCase.key} mismatch: got ${constantValue}, expected ${testCase.expected}`);
66+
});
6367
});
6468

6569
// Test shouldStoreArticle
@@ -84,53 +88,47 @@ testCases.article_validation_tests.forEach((testCase) => {
8488
});
8589

8690
// Test processArticle
87-
test('processArticle adds hash, score, and feedurl', () => {
88-
const article = {
89-
guid: 'https://xkcd.com/3153/',
90-
title: 'Test Article',
91-
pubDate: '2025-10-10T00:00:00Z',
92-
};
93-
const feedURI = 'https://xkcd.com/atom.xml';
94-
95-
const result = feedUtils.processArticle(article, feedURI, hash, score);
96-
97-
assert.strictEqual(result.hash, '13a0bebeed5b348147d880a1a4917587');
98-
assert.strictEqual(result.score, 1760054400000);
99-
assert.strictEqual(result.feedurl, feedURI);
100-
assert.strictEqual(result.guid, article.guid);
101-
assert.strictEqual(result.title, article.title);
91+
testCases.process_article_tests.forEach((testCase) => {
92+
test(testCase.description, () => {
93+
const result = feedUtils.processArticle(
94+
testCase.input.article,
95+
testCase.input.feedURI,
96+
hash,
97+
score
98+
);
99+
100+
assert.strictEqual(result.hash, testCase.expected.hash,
101+
`Hash mismatch: got ${result.hash}, expected ${testCase.expected.hash}`);
102+
assert.strictEqual(result.score, testCase.expected.score,
103+
`Score mismatch: got ${result.score}, expected ${testCase.expected.score}`);
104+
assert.strictEqual(result.feedurl, testCase.expected.feedurl,
105+
`FeedURL mismatch: got ${result.feedurl}, expected ${testCase.expected.feedurl}`);
106+
assert.strictEqual(result.guid, testCase.expected.guid,
107+
`GUID mismatch: got ${result.guid}, expected ${testCase.expected.guid}`);
108+
assert.strictEqual(result.title, testCase.expected.title,
109+
`Title mismatch: got ${result.title}, expected ${testCase.expected.title}`);
110+
});
102111
});
103112

104113
// Test extractArticleIds
105-
test('extractArticleIds strips article: prefix', () => {
106-
const keys = [
107-
'article:13a0bebeed5b348147d880a1a4917587',
108-
'article:21664da7ee05988c62d1f516f3442411',
109-
'article:3fa08ba1591ba3683e87265ee9300946',
110-
];
111-
112-
const result = feedUtils.extractArticleIds(keys);
113-
114-
assert.deepStrictEqual(result, [
115-
'13a0bebeed5b348147d880a1a4917587',
116-
'21664da7ee05988c62d1f516f3442411',
117-
'3fa08ba1591ba3683e87265ee9300946',
118-
]);
114+
testCases.extract_article_ids_tests.forEach((testCase) => {
115+
test(testCase.description, () => {
116+
const result = feedUtils.extractArticleIds(testCase.input);
117+
assert.deepStrictEqual(result, testCase.expected,
118+
`Article IDs mismatch: got ${JSON.stringify(result)}, expected ${JSON.stringify(testCase.expected)}`);
119+
});
119120
});
120121

121122
// Test generateArticleBody
122-
test('generateArticleBody produces valid JSON', () => {
123-
const article = {
124-
guid: 'test-guid',
125-
title: 'Test Article',
126-
hash: 'abc123',
127-
score: 1234567890,
128-
};
129-
130-
const result = feedUtils.generateArticleBody(article);
131-
const parsed = JSON.parse(result);
132-
133-
assert.deepStrictEqual(parsed, article);
123+
testCases.generate_article_body_tests.forEach((testCase) => {
124+
test(testCase.description, () => {
125+
const result = feedUtils.generateArticleBody(testCase.input);
126+
const parsed = JSON.parse(result);
127+
128+
// Verify it produces valid JSON and round-trips correctly
129+
assert.deepStrictEqual(parsed, testCase.input,
130+
`Article body mismatch: got ${JSON.stringify(parsed)}, expected ${JSON.stringify(testCase.input)}`);
131+
});
134132
});
135133

136134
// Print summary

0 commit comments

Comments
 (0)