-
-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added test for build-rss.js #3101
Conversation
✅ Deploy Preview for asyncapi-website ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-3101--asyncapi-website.netlify.app/ |
@vishvamsinh28 Statement and branch coverage aren't 100% for this file. |
@anshgoyalevil updated the test, now it has 98.33% coverage. I will push another change to make it 100% |
There's still room for improvement, @vishvamsinh28 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (4)
tests/fixtures/rssData.js (2)
45-61
: Enhance date validation test cases.The current test data covers basic date validation, but consider adding more edge cases:
- Invalid date formats
- Malformed dates
- Different timezone formats
Consider adding these test cases:
const missingDateMockData = { blog: [ // ... existing entries + { + title: 'Post with Invalid Date', + slug: '/blog/invalid-date', + excerpt: 'This post has an invalid date', + date: 'not-a-date', + featured: false, + }, + { + title: 'Post with Malformed Date', + slug: '/blog/malformed-date', + excerpt: 'This post has a malformed date', + date: '2023-13-45', + featured: false, + }, ], };
63-72
: Expand incomplete post test scenarios.Consider adding more test cases for other missing required fields:
- Missing excerpt
- Missing slug
- Empty string values
Consider expanding the test cases:
const incompletePostMockData = { blog: [ // ... existing entry + { + title: 'Post with Empty Excerpt', + slug: '/blog/empty-excerpt', + excerpt: '', + date: '2023-07-05', + featured: false, + }, + { + title: 'Post with Missing Slug', + excerpt: 'This post is missing a slug', + date: '2023-07-05', + featured: false, + }, ], };scripts/build-rss.js (1)
83-83
: Consider calculating the actual image size for enclosureUsing a dummy value for
enclosure["@length"]
may lead to inaccurate metadata in the RSS feed. If feasible, calculate the actual file size of the image to provide precise information.tests/build-rss.test.js (1)
92-94
: Usepath.join
to construct file paths for consistencyInstead of hardcoding
"invalid/path"
, usepath.join
to create file paths. This ensures cross-platform compatibility and consistency throughout your code.Suggested change:
-const invalidOutputPath = "invalid/path"; +const invalidOutputPath = path.join('invalid', 'path');
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
scripts/build-rss.js
(2 hunks)tests/build-rss.test.js
(1 hunks)tests/fixtures/rssData.js
(1 hunks)
🧰 Additional context used
📓 Learnings (2)
scripts/build-rss.js (1)
Learnt from: akshatnema
PR: asyncapi/website#3101
File: scripts/build-rss.js:4-6
Timestamp: 2024-11-01T09:35:23.912Z
Learning: Converting `getAllPosts()` to asynchronous in `scripts/build-rss.js` causes the existing build system to fail.
tests/build-rss.test.js (1)
Learnt from: akshatnema
PR: asyncapi/website#3101
File: tests/build-rss.test.js:25-27
Timestamp: 2024-11-01T09:55:20.531Z
Learning: In `tests/build-rss.test.js`, replacing `jest.resetModules()` with `jest.resetAllMocks()` in the `afterEach()` block causes errors. It is necessary to use `jest.resetModules()` to reset the module registry between tests in this file.
🔇 Additional comments (12)
tests/fixtures/rssData.js (1)
74-79
: Verify output path compatibility.
The hardcoded output path 'test-output/blog.xml'
might need validation to ensure:
- The directory exists or can be created
- The path is compatible across different operating systems
Let's verify the output directory existence and path compatibility:
scripts/build-rss.js (3)
1-1
: Good use of fs.promises
for asynchronous operations
Importing fs.promises
enables the use of async/await with file system operations, improving code readability and avoiding callback complexities.
5-5
: Consistency maintained in getAllPosts()
function
Retaining the synchronous nature of getAllPosts()
aligns with the existing build system requirements, preventing potential build failures.
18-34
: Efficient filtering and sorting of posts
Filtering out posts without dates and sorting them prior to processing ensures that only valid and relevant posts are included, enhancing reliability.
tests/build-rss.test.js (8)
25-27
: jest.resetModules()
is appropriately used
Using jest.resetModules()
in the afterEach
hook ensures that the module registry is reset between tests. This is necessary in your test setup to properly mock modules without caching issues.
29-38
: Test case for RSS feed generation is well-implemented
The test effectively validates that the RSS feed is generated and written to the correct file path. It correctly mocks posts.json
and asserts the existence and basic content of the generated RSS file.
40-71
: Tests for post prioritization and sorting are comprehensive
The tests verify that featured posts are prioritized and that posts are sorted by date in descending order. The use of regular expressions to extract titles serves the purpose, but consider the potential fragility of regex parsing with XML content.
127-133
: Error handling tests are thorough and validate expected failures
The test correctly checks that the rssFeed
function throws an error when encountering a post missing the date field during sorting. This ensures that error handling is functioning as expected.
108-117
: Test for handling an empty posts array is effective
The test verifies that the rssFeed
function can handle an empty posts array without errors, and that the generated RSS feed does not contain any <item>
elements.
119-125
: Properly testing for missing required fields
The test ensures that an error is thrown when a post is missing required fields, confirming that the function validates input data correctly.
99-105
: Malformed posts.json
error handling is appropriately tested
This test case validates that the function throws a meaningful error when posts.json
is malformed, which is crucial for debugging and maintaining data integrity.
89-97
: Effective testing of write operation failures
By providing an invalid output path, the test confirms that the function properly rejects and throws an error when the write operation fails, ensuring robust error handling.
tests/fixtures/rssData.js
Outdated
const mockRssData = { | ||
blog: [ | ||
{ | ||
title: 'Non-Featured Post 1', | ||
slug: '/blog/non-featured-post-1', | ||
excerpt: 'This is a non-featured post', | ||
date: '2024-07-05', | ||
featured: false, | ||
}, | ||
{ | ||
title: 'Test Post 1', | ||
slug: '/blog/test-post-1', | ||
excerpt: 'This is a featured test post', | ||
date: '2024-07-07', | ||
featured: true, | ||
cover: '/img/test-cover.jpg', | ||
}, | ||
{ | ||
title: 'Another Featured Post', | ||
slug: '/blog/another-featured-post', | ||
excerpt: 'This is another featured post', | ||
date: '2024-07-06', | ||
featured: true, | ||
cover: '/img/test-cover.svg', | ||
}, | ||
{ | ||
title: 'Non-Featured Post 2', | ||
slug: '/blog/non-featured-post-2', | ||
excerpt: 'This is another non-featured post', | ||
date: '2024-07-03', | ||
featured: false, | ||
cover: '/img/test-cover.webp', | ||
}, | ||
{ | ||
title: 'Non-Featured Post 3', | ||
slug: '/blog/non-featured-post-3', | ||
excerpt: 'This is yet another non-featured post', | ||
date: '2024-07-04', | ||
featured: false, | ||
cover: '/img/test-cover.png', | ||
}, | ||
], | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider enhancing test coverage with additional edge cases.
The mock data could be improved by:
- Using past dates instead of future dates to prevent test failures over time
- Including test cases with special characters in titles and excerpts
- Adding test cases with different date formats (ISO 8601, UTC, etc.)
Consider applying these changes:
const mockRssData = {
blog: [
{
title: 'Non-Featured Post 1',
slug: '/blog/non-featured-post-1',
excerpt: 'This is a non-featured post',
- date: '2024-07-05',
+ date: '2023-07-05',
featured: false,
},
+ {
+ title: 'Post with Special Characters: & < > "',
+ slug: '/blog/special-chars',
+ excerpt: 'Testing HTML entities & encoding',
+ date: '2023-07-06T12:00:00Z',
+ featured: false,
+ },
// ... rest of the entries with updated past dates
],
};
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishvamsinh28 Kindly apply this suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
scripts/build-rss.js
Outdated
if (invalidPosts.length > 0) { | ||
throw new Error('Missing required fields in post data'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error message to include missing post details
Including the titles or slugs of posts missing required fields in the error message aids in debugging and identifying problematic entries.
Apply this diff to improve the error message:
if (invalidPosts.length > 0) {
- throw new Error('Missing required fields in post data');
+ throw new Error(`Missing required fields in posts: ${invalidPosts.map(p => p.title || p.slug).join(', ')}`);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (invalidPosts.length > 0) { | |
throw new Error('Missing required fields in post data'); | |
} | |
if (invalidPosts.length > 0) { | |
throw new Error(`Missing required fields in posts: ${invalidPosts.map(p => p.title || p.slug).join(', ')}`); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishvamsinh28 Kindly apply this suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
it('should set correct enclosure type based on image extension', async () => { | ||
jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); | ||
|
||
await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() | ||
|
||
const filePath = path.join(__dirname, '..', 'public', outputPath); | ||
const fileContent = fs.readFileSync(filePath, 'utf8'); | ||
|
||
expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.png"'); | ||
expect(fileContent).toContain('type="image/png"'); | ||
expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.svg"'); | ||
expect(fileContent).toContain('type="image/svg+xml"'); | ||
expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.webp"'); | ||
expect(fileContent).toContain('type="image/webp"'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using an XML parser instead of regex for parsing RSS feed
Parsing XML with regex can be brittle and may fail with valid XML that doesn't match the regex pattern. To improve robustness and maintainability, use an XML parser like fast-xml-parser
or xml2js
.
Example refactoring using fast-xml-parser
:
+const { XMLParser } = require('fast-xml-parser');
+const parser = new XMLParser({ ignoreAttributes: false });
// ...
const fileContent = fs.readFileSync(filePath, 'utf8');
-const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g);
+const parsedContent = parser.parse(fileContent);
+const items = parsedContent.rss.channel.item;
expect(items[0].enclosure.url).toBe('https://www.asyncapi.com/img/test-cover.png');
expect(items[0].enclosure.type).toBe('image/png');
// Continue with other assertions
This approach enhances reliability and readability of your tests.
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishvamsinh28 Kindly apply this suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishvamsinh28 Have you made changes for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
tests/build-rss.test.js
Outdated
const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); | ||
const outputPath = 'test-output/rss.xml'; | ||
|
||
beforeAll(() => { | ||
if (!fs.existsSync(testOutputDir)) { | ||
fs.mkdirSync(testOutputDir, { recursive: true }); | ||
} | ||
}); | ||
|
||
afterAll(() => { | ||
if (fs.existsSync(testOutputDir)) { | ||
fs.readdirSync(testOutputDir).forEach(file => { | ||
fs.unlinkSync(path.join(testOutputDir, file)); | ||
}); | ||
fs.rmdirSync(testOutputDir); | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using asynchronous file operations in setup and teardown
In the beforeAll
and afterAll
hooks, synchronous file operations like fs.mkdirSync
, fs.readdirSync
, fs.unlinkSync
, and fs.rmdirSync
are used. While this is acceptable for small tests, using asynchronous versions can improve performance and prevent blocking the event loop.
You can refactor the setup and teardown to use asynchronous methods:
-beforeAll(() => {
- if (!fs.existsSync(testOutputDir)) {
- fs.mkdirSync(testOutputDir, { recursive: true });
- }
-});
+beforeAll(async () => {
+ try {
+ await fs.promises.mkdir(testOutputDir, { recursive: true });
+ } catch (err) {
+ // Handle error if necessary
+ }
+});
-afterAll(() => {
- if (fs.existsSync(testOutputDir)) {
- fs.readdirSync(testOutputDir).forEach(file => {
- fs.unlinkSync(path.join(testOutputDir, file));
- });
- fs.rmdirSync(testOutputDir);
- }
-});
+afterAll(async () => {
+ try {
+ const files = await fs.promises.readdir(testOutputDir);
+ await Promise.all(files.map(file => fs.promises.unlink(path.join(testOutputDir, file))));
+ await fs.promises.rmdir(testOutputDir);
+ } catch (err) {
+ // Handle error if necessary
+ }
+});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); | |
const outputPath = 'test-output/rss.xml'; | |
beforeAll(() => { | |
if (!fs.existsSync(testOutputDir)) { | |
fs.mkdirSync(testOutputDir, { recursive: true }); | |
} | |
}); | |
afterAll(() => { | |
if (fs.existsSync(testOutputDir)) { | |
fs.readdirSync(testOutputDir).forEach(file => { | |
fs.unlinkSync(path.join(testOutputDir, file)); | |
}); | |
fs.rmdirSync(testOutputDir); | |
} | |
}); | |
const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); | |
const outputPath = 'test-output/rss.xml'; | |
beforeAll(async () => { | |
try { | |
await fs.promises.mkdir(testOutputDir, { recursive: true }); | |
} catch (err) { | |
// Handle error if necessary | |
} | |
}); | |
afterAll(async () => { | |
try { | |
const files = await fs.promises.readdir(testOutputDir); | |
await Promise.all(files.map(file => fs.promises.unlink(path.join(testOutputDir, file)))); | |
await fs.promises.rmdir(testOutputDir); | |
} catch (err) { | |
// Handle error if necessary | |
} | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vishvamsinh28 Apply this suggestion if it doesn't breaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akshatnema Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (1)
package.json (1)
73-73
: Consider upgrading fast-xml-parser to latest patch version.While version 4.5.0 works, consider upgrading to the latest patch version (4.5.5) for potential bug fixes and security updates.
Apply this diff:
- "fast-xml-parser": "^4.5.0", + "fast-xml-parser": "^4.5.5",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (4)
package.json
(1 hunks)scripts/build-rss.js
(2 hunks)tests/build-rss.test.js
(1 hunks)tests/fixtures/rssData.js
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- scripts/build-rss.js
- tests/build-rss.test.js
🔇 Additional comments (2)
tests/fixtures/rssData.js (1)
88-93
: LGTM!
The configuration constants and exports are well-structured and include all necessary components.
package.json (1)
73-73
: Verify the fast-xml-parser usage in the codebase.
The addition of fast-xml-parser as a dependency is appropriate for XML parsing needs in the RSS feed generation.
Let's verify its usage:
✅ Verification successful
Based on the search results, I can see that fast-xml-parser
is used in tests/build-rss.test.js
for parsing XML content in RSS feed tests. Let me verify if there are any other usages in the codebase:
Let me check the implementation of build-rss.js to fully understand how fast-xml-parser is used:
The fast-xml-parser dependency is only used in tests for validation purposes
The fast-xml-parser
package is only used in tests/build-rss.test.js
to parse and validate the XML output generated by build-rss.js
. The actual RSS feed generation uses jgexml/json2xml
package. The addition of fast-xml-parser
as a dependency is appropriate and correctly scoped for testing purposes.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of fast-xml-parser in the codebase
# Expected: Usage in build-rss.js and related test files
# Test: Search for imports/requires of fast-xml-parser
rg -l "require.*fast-xml-parser|from.*fast-xml-parser"
# Test: Search for XMLParser usage (common class from this library)
rg "XMLParser|parse[^d]|validate|build"
Length of output: 219586
Script:
#!/bin/bash
# Search for the actual build-rss.js file to see its implementation
rg -l "build-rss"
# Get content of build-rss.js and test file
cat tests/build-rss.test.js
Length of output: 5997
Script:
#!/bin/bash
# Get content of build-rss.js implementation
cat scripts/build-rss.js
Length of output: 3431
const incompletePostMockData = { | ||
blog: [ | ||
{ | ||
slug: '/blog/incomplete-post', | ||
excerpt: 'This post is incomplete', | ||
date: '2024-07-05', | ||
featured: false, | ||
}, | ||
], | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance incomplete post test cases and fix future date.
Two suggestions for improvement:
- Replace the future date with a past date
- Add more incomplete data scenarios
const incompletePostMockData = {
blog: [
{
slug: '/blog/incomplete-post',
excerpt: 'This post is incomplete',
- date: '2024-07-05',
+ date: '2023-07-05',
featured: false,
},
+ {
+ title: 'Missing Excerpt Post',
+ slug: '/blog/no-excerpt',
+ date: '2023-07-06',
+ featured: false,
+ },
+ {
+ title: 'Missing Slug Post',
+ excerpt: 'This post has no slug',
+ date: '2023-07-07',
+ featured: false,
+ },
],
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const incompletePostMockData = { | |
blog: [ | |
{ | |
slug: '/blog/incomplete-post', | |
excerpt: 'This post is incomplete', | |
date: '2024-07-05', | |
featured: false, | |
}, | |
], | |
}; | |
const incompletePostMockData = { | |
blog: [ | |
{ | |
slug: '/blog/incomplete-post', | |
excerpt: 'This post is incomplete', | |
date: '2023-07-05', | |
featured: false, | |
}, | |
{ | |
title: 'Missing Excerpt Post', | |
slug: '/blog/no-excerpt', | |
date: '2023-07-06', | |
featured: false, | |
}, | |
{ | |
title: 'Missing Slug Post', | |
excerpt: 'This post has no slug', | |
date: '2023-07-07', | |
featured: false, | |
}, | |
], | |
}; |
const missingDateMockData = { | ||
blog: [ | ||
{ | ||
title: 'Post without Date', | ||
slug: '/blog/no-date-post', | ||
excerpt: 'This post is missing a date', | ||
featured: false, | ||
}, | ||
{ | ||
title: 'Valid Post', | ||
slug: '/blog/valid-post', | ||
excerpt: 'This post has a valid date', | ||
date: '2024-07-05', | ||
featured: true, | ||
}, | ||
], | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace future dates with past dates to prevent test failures.
Using future dates in tests can cause failures when the date passes. Consider using past dates consistently.
{
title: 'Valid Post',
slug: '/blog/valid-post',
excerpt: 'This post has a valid date',
- date: '2024-07-05',
+ date: '2023-07-05',
featured: true,
},
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const missingDateMockData = { | |
blog: [ | |
{ | |
title: 'Post without Date', | |
slug: '/blog/no-date-post', | |
excerpt: 'This post is missing a date', | |
featured: false, | |
}, | |
{ | |
title: 'Valid Post', | |
slug: '/blog/valid-post', | |
excerpt: 'This post has a valid date', | |
date: '2024-07-05', | |
featured: true, | |
}, | |
], | |
}; | |
const missingDateMockData = { | |
blog: [ | |
{ | |
title: 'Post without Date', | |
slug: '/blog/no-date-post', | |
excerpt: 'This post is missing a date', | |
featured: false, | |
}, | |
{ | |
title: 'Valid Post', | |
slug: '/blog/valid-post', | |
excerpt: 'This post has a valid date', | |
date: '2023-07-05', | |
featured: true, | |
}, | |
], | |
}; |
const mockRssData = { | ||
blog: [ | ||
{ | ||
title: 'Non-Featured Post 1', | ||
slug: '/blog/non-featured-post-1', | ||
excerpt: 'This is a non-featured post', | ||
date: '2023-07-05', | ||
featured: false, | ||
}, | ||
{ | ||
title: 'Test Post 1', | ||
slug: '/blog/test-post-1', | ||
excerpt: 'This is a featured test post', | ||
date: '2023-07-07', | ||
featured: true, | ||
cover: '/img/test-cover.jpg', | ||
}, | ||
{ | ||
title: 'Another Featured Post', | ||
slug: '/blog/another-featured-post', | ||
excerpt: 'This is another featured post', | ||
date: '2023-07-06', | ||
featured: true, | ||
cover: '/img/test-cover.svg', | ||
}, | ||
{ | ||
title: 'Non-Featured Post 2', | ||
slug: '/blog/non-featured-post-2', | ||
excerpt: 'This is another non-featured post', | ||
date: '2023-07-03', | ||
featured: false, | ||
cover: '/img/test-cover.webp', | ||
}, | ||
{ | ||
title: 'Non-Featured Post 3', | ||
slug: '/blog/non-featured-post-3', | ||
excerpt: 'This is yet another non-featured post', | ||
date: '2023-07-04', | ||
featured: false, | ||
cover: '/img/test-cover.png', | ||
}, | ||
{ | ||
title: 'Post with Special Characters: & < > "', | ||
slug: '/blog/special-chars', | ||
excerpt: 'Testing HTML entities & encoding', | ||
date: '2023-07-06T12:00:00Z', | ||
featured: false, | ||
}, | ||
{ | ||
title: 'Post with UTC Date Format', | ||
slug: '/blog/utc-date-format', | ||
excerpt: 'This post uses a UTC date format', | ||
date: 'Wed, 05 Jul 2023 12:00:00 GMT', | ||
featured: false, | ||
}, | ||
], | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding more edge cases to strengthen test coverage.
The mock data has good variety including special characters, different date formats, and image types. Consider enhancing it with these additional edge cases:
- Empty strings for title/excerpt
- Very long text content
- International characters (UTF-8)
- Malformed URLs in slug/cover
const mockRssData = {
blog: [
+ {
+ title: '', // Empty title edge case
+ slug: '/blog/empty-title',
+ excerpt: 'Testing empty title handling',
+ date: '2023-07-01',
+ featured: false,
+ },
+ {
+ title: '国际化标题 - インターナショナル', // International characters
+ slug: '/blog/international',
+ excerpt: '测试国际化内容 - テスト',
+ date: '2023-07-02',
+ featured: false,
+ },
+ {
+ title: 'Malformed URL Test',
+ slug: '/blog/bad url#$%^', // Invalid URL characters
+ excerpt: 'Testing URL handling',
+ date: '2023-07-03',
+ featured: false,
+ cover: 'invalid://cover.jpg',
+ },
// ... existing entries
],
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const mockRssData = { | |
blog: [ | |
{ | |
title: 'Non-Featured Post 1', | |
slug: '/blog/non-featured-post-1', | |
excerpt: 'This is a non-featured post', | |
date: '2023-07-05', | |
featured: false, | |
}, | |
{ | |
title: 'Test Post 1', | |
slug: '/blog/test-post-1', | |
excerpt: 'This is a featured test post', | |
date: '2023-07-07', | |
featured: true, | |
cover: '/img/test-cover.jpg', | |
}, | |
{ | |
title: 'Another Featured Post', | |
slug: '/blog/another-featured-post', | |
excerpt: 'This is another featured post', | |
date: '2023-07-06', | |
featured: true, | |
cover: '/img/test-cover.svg', | |
}, | |
{ | |
title: 'Non-Featured Post 2', | |
slug: '/blog/non-featured-post-2', | |
excerpt: 'This is another non-featured post', | |
date: '2023-07-03', | |
featured: false, | |
cover: '/img/test-cover.webp', | |
}, | |
{ | |
title: 'Non-Featured Post 3', | |
slug: '/blog/non-featured-post-3', | |
excerpt: 'This is yet another non-featured post', | |
date: '2023-07-04', | |
featured: false, | |
cover: '/img/test-cover.png', | |
}, | |
{ | |
title: 'Post with Special Characters: & < > "', | |
slug: '/blog/special-chars', | |
excerpt: 'Testing HTML entities & encoding', | |
date: '2023-07-06T12:00:00Z', | |
featured: false, | |
}, | |
{ | |
title: 'Post with UTC Date Format', | |
slug: '/blog/utc-date-format', | |
excerpt: 'This post uses a UTC date format', | |
date: 'Wed, 05 Jul 2023 12:00:00 GMT', | |
featured: false, | |
}, | |
], | |
}; | |
const mockRssData = { | |
blog: [ | |
{ | |
title: '', // Empty title edge case | |
slug: '/blog/empty-title', | |
excerpt: 'Testing empty title handling', | |
date: '2023-07-01', | |
featured: false, | |
}, | |
{ | |
title: '国际化标题 - インターナショナル', // International characters | |
slug: '/blog/international', | |
excerpt: '测试国际化内容 - テスト', | |
date: '2023-07-02', | |
featured: false, | |
}, | |
{ | |
title: 'Malformed URL Test', | |
slug: '/blog/bad url#$%^', // Invalid URL characters | |
excerpt: 'Testing URL handling', | |
date: '2023-07-03', | |
featured: false, | |
cover: 'invalid://cover.jpg', | |
}, | |
{ | |
title: 'Non-Featured Post 1', | |
slug: '/blog/non-featured-post-1', | |
excerpt: 'This is a non-featured post', | |
date: '2023-07-05', | |
featured: false, | |
}, | |
{ | |
title: 'Test Post 1', | |
slug: '/blog/test-post-1', | |
excerpt: 'This is a featured test post', | |
date: '2023-07-07', | |
featured: true, | |
cover: '/img/test-cover.jpg', | |
}, | |
{ | |
title: 'Another Featured Post', | |
slug: '/blog/another-featured-post', | |
excerpt: 'This is another featured post', | |
date: '2023-07-06', | |
featured: true, | |
cover: '/img/test-cover.svg', | |
}, | |
{ | |
title: 'Non-Featured Post 2', | |
slug: '/blog/non-featured-post-2', | |
excerpt: 'This is another non-featured post', | |
date: '2023-07-03', | |
featured: false, | |
cover: '/img/test-cover.webp', | |
}, | |
{ | |
title: 'Non-Featured Post 3', | |
slug: '/blog/non-featured-post-3', | |
excerpt: 'This is yet another non-featured post', | |
date: '2023-07-04', | |
featured: false, | |
cover: '/img/test-cover.png', | |
}, | |
{ | |
title: 'Post with Special Characters: & < > "', | |
slug: '/blog/special-chars', | |
excerpt: 'Testing HTML entities & encoding', | |
date: '2023-07-06T12:00:00Z', | |
featured: false, | |
}, | |
{ | |
title: 'Post with UTC Date Format', | |
slug: '/blog/utc-date-format', | |
excerpt: 'This post uses a UTC date format', | |
date: 'Wed, 05 Jul 2023 12:00:00 GMT', | |
featured: false, | |
}, | |
], | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These cases will not occur.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akshatnema, understood. Thank you for the clarification.
✏️ Learnings added
Learnt from: akshatnema
PR: asyncapi/website#3101
File: tests/fixtures/rssData.js:1-57
Timestamp: 2024-11-01T13:32:15.167Z
Learning: In the `tests/fixtures/rssData.js` file of the `@asyncapi/website` project, tests for edge cases such as empty strings for title or excerpt, very long text content, international characters (UTF-8), or malformed URLs in `slug` or `cover` are not necessary because these cases will not occur.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (4)
tests/fixtures/rssData.js (2)
1-27
: Consider refactoring for better maintainability.The function could be more concise and maintainable:
- Handle
cover
consistently with other properties- Use object spread for cleaner code
function createMockPost({ title, slug, excerpt, date, featured, cover, } = {}, useDefaults = true) { - const post = {}; + if (useDefaults) { + return { + title: title ?? 'Default Post Title', + slug: slug ?? '/blog/default-post', + excerpt: excerpt ?? 'This is a default excerpt', + date: date ?? '2023-07-01', + featured: featured ?? false, + ...(cover !== undefined && { cover }), + }; + } - if (useDefaults) { - post.title = title ?? 'Default Post Title'; - post.slug = slug ?? '/blog/default-post'; - post.excerpt = excerpt ?? 'This is a default excerpt'; - post.date = date ?? new Date().toISOString(); - post.featured = featured ?? false; - } else { - if (title !== undefined) post.title = title; - if (slug !== undefined) post.slug = slug; - if (excerpt !== undefined) post.excerpt = excerpt; - if (date !== undefined) post.date = date; - if (featured !== undefined) post.featured = featured; - } - - if (cover !== undefined) post.cover = cover; - return post; + return { + ...(title !== undefined && { title }), + ...(slug !== undefined && { slug }), + ...(excerpt !== undefined && { excerpt }), + ...(date !== undefined && { date }), + ...(featured !== undefined && { featured }), + ...(cover !== undefined && { cover }), + }; }
37-40
: Fix trailing comma style.Remove the trailing comma to comply with the project's style guidelines.
module.exports = { createMockPost, - createMockData, + createMockData };🧰 Tools
🪛 eslint
[error] 39-39: Delete
,
(prettier/prettier)
tests/build-rss.test.js (2)
26-108
: Test coverage looks good, consider adding a few more edge cases.The current test suite is well-structured with good coverage of main scenarios. Consider adding these additional test cases:
- Malformed XML validation
- Invalid file path handling
- Network-related issues with cover images
Example test case for malformed XML validation:
it('should generate valid XML output', async () => { const mockData = createMockData({ blogPosts: [ { title: 'Post with Special Characters & <>', slug: '/blog/special', date: '2023-07-05', featured: true }, ], }); jest.doMock('../config/posts.json', () => mockData, { virtual: true }); await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).resolves.toBeUndefined(); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); // This will throw if XML is malformed expect(() => parser.parse(fileContent)).not.toThrow(); });🧰 Tools
🪛 eslint
[error] 106-106: Replace
'Missing·required·fields'
with⏎······'Missing·required·fields'⏎····
(prettier/prettier)
106-106
: Minor formatting improvement needed.Update the line to match the project's formatting rules:
- await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).rejects.toThrow('Missing required fields'); + await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).rejects.toThrow( + 'Missing required fields' + );🧰 Tools
🪛 eslint
[error] 106-106: Replace
'Missing·required·fields'
with⏎······'Missing·required·fields'⏎····
(prettier/prettier)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
tests/build-rss.test.js
(1 hunks)tests/fixtures/rssData.js
(1 hunks)
🧰 Additional context used
📓 Learnings (1)
tests/build-rss.test.js (1)
Learnt from: akshatnema
PR: asyncapi/website#3101
File: tests/build-rss.test.js:25-27
Timestamp: 2024-11-01T09:55:20.531Z
Learning: In `tests/build-rss.test.js`, replacing `jest.resetModules()` with `jest.resetAllMocks()` in the `afterEach()` block causes errors. It is necessary to use `jest.resetModules()` to reset the module registry between tests in this file.
🪛 eslint
tests/build-rss.test.js
[error] 106-106: Replace 'Missing·required·fields'
with ⏎······'Missing·required·fields'⏎····
(prettier/prettier)
tests/fixtures/rssData.js
[error] 39-39: Delete ,
(prettier/prettier)
🔇 Additional comments (3)
tests/fixtures/rssData.js (1)
29-35
: LGTM!
The function is well-structured and correctly implements the mock data generation logic.
tests/build-rss.test.js (2)
1-7
: LGTM! Well-structured imports and parser configuration.
The imports are complete and the XMLParser is properly configured to handle RSS feed attributes.
8-24
: LGTM! Well-implemented test suite setup and teardown.
- Proper use of async/await for file operations
- Correct cleanup of test files
- Appropriate use of
jest.resetModules()
as required for this test suite
tests/fixtures/rssData.js
Outdated
post.title = title ?? 'Default Post Title'; | ||
post.slug = slug ?? '/blog/default-post'; | ||
post.excerpt = excerpt ?? 'This is a default excerpt'; | ||
post.date = date ?? new Date().toISOString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace dynamic default date with a static one.
Using new Date().toISOString()
as a default value makes tests non-deterministic and could cause failures over time. Consider using a static past date instead.
- post.date = date ?? new Date().toISOString();
+ post.date = date ?? '2023-07-01';
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
post.date = date ?? new Date().toISOString(); | |
post.date = date ?? '2023-07-01'; |
db84460
to
3837d4b
Compare
package.json
Outdated
@@ -70,6 +70,7 @@ | |||
"clsx": "^2.1.0", | |||
"cssnano": "^6.0.3", | |||
"dotenv": "^16.4.4", | |||
"fast-xml-parser": "^4.5.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be pushed to devDependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
tests/build-rss.test.js (3)
1-6
: Reorder imports for better organization.Consider reordering the imports following the convention: built-in modules, then external modules, then local modules.
const fs = require('fs'); const path = require('path'); +const { XMLParser } = require('fast-xml-parser'); const rssFeed = require('../scripts/build-rss'); -const { XMLParser } = require('fast-xml-parser'); const parser = new XMLParser({ ignoreAttributes: false }); const { mockRssData, title, type, desc, missingDateMockData, incompletePostMockData } = require('./fixtures/rssData');🧰 Tools
🪛 eslint
[error] 4-4: Expected 1 empty line after require statement not followed by another require.
(import/newline-after-import)
[error] 4-4:
fast-xml-parser
import should occur before import of../scripts/build-rss
(import/order)
85-99
: Use XML parser for enclosure assertions.For consistency with other tests and more reliable XML parsing, consider using the XML parser instead of string matching.
const fileContent = fs.readFileSync(filePath, 'utf8'); +const parsedContent = parser.parse(fileContent); +const items = parsedContent.rss.channel.item; -expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.png"'); -expect(fileContent).toContain('type="image/png"'); +expect(items[0].enclosure.url).toBe('https://www.asyncapi.com/img/test-cover.png'); +expect(items[0].enclosure.type).toBe('image/png'); // Apply similar changes for other assertions🧰 Tools
🪛 eslint
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert
;
(prettier/prettier)
34-145
: Address formatting inconsistencies.There are several formatting issues that should be addressed:
- Missing semicolons (lines 38, 78, 88, 123)
- Inconsistent string quotes (line 104)
- Extra whitespace and newlines
Consider running Prettier to automatically fix these formatting issues.
🧰 Tools
🪛 eslint
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete
⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert
;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete
··
(prettier/prettier)
[error] 50-50: Delete
··
(prettier/prettier)
[error] 53-53: Delete
··
(prettier/prettier)
[error] 55-55: Replace
item
with(item)
(prettier/prettier)
[error] 56-56: Delete
··
(prettier/prettier)
[error] 59-59: Delete
··
(prettier/prettier)
[error] 65-65: Delete
··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete
··
(prettier/prettier)
[error] 70-70: Delete
··
(prettier/prettier)
[error] 73-73: Delete
··
(prettier/prettier)
[error] 75-75: Replace
item
with(item)
(prettier/prettier)
[error] 76-76: Delete
··
(prettier/prettier)
[error] 78-78: Insert
;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert
;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace
"invalid/path"
with'invalid/path'
(prettier/prettier)
[error] 106-107: Delete
⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace
'../config/posts.json',
with⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert
··
(prettier/prettier)
[error] 113-113: Replace
},·{·virtual:·true·}
with··},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 116-117: Delete
⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert
;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 131-132: Delete
⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete
⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete
⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-144: Replace
'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date');⏎
with⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····);
(prettier/prettier)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
package.json
(1 hunks)tests/build-rss.test.js
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
📓 Learnings (1)
tests/build-rss.test.js (1)
Learnt from: akshatnema
PR: asyncapi/website#3101
File: tests/build-rss.test.js:25-27
Timestamp: 2024-11-01T09:55:20.531Z
Learning: In `tests/build-rss.test.js`, replacing `jest.resetModules()` with `jest.resetAllMocks()` in the `afterEach()` block causes errors. It is necessary to use `jest.resetModules()` to reset the module registry between tests in this file.
🪛 eslint
tests/build-rss.test.js
[error] 4-4: Expected 1 empty line after require statement not followed by another require.
(import/newline-after-import)
[error] 4-4: fast-xml-parser
import should occur before import of ../scripts/build-rss
(import/order)
[error] 8-8: 'describe' is not defined.
(no-undef)
[error] 12-12: 'beforeAll' is not defined.
(no-undef)
[error] 20-20: 'afterAll' is not defined.
(no-undef)
[error] 23-23: Replace file
with (file)
(prettier/prettier)
[error] 30-30: 'afterEach' is not defined.
(no-undef)
[error] 31-31: 'jest' is not defined.
(no-undef)
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete ⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert ;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete ··
(prettier/prettier)
[error] 50-50: Delete ··
(prettier/prettier)
[error] 53-53: Delete ··
(prettier/prettier)
[error] 55-55: Replace item
with (item)
(prettier/prettier)
[error] 56-56: Delete ··
(prettier/prettier)
[error] 59-59: Delete ··
(prettier/prettier)
[error] 65-65: Delete ··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete ··
(prettier/prettier)
[error] 70-70: Delete ··
(prettier/prettier)
[error] 73-73: Delete ··
(prettier/prettier)
[error] 75-75: Replace item
with (item)
(prettier/prettier)
[error] 76-76: Delete ··
(prettier/prettier)
[error] 78-78: Insert ;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert ;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace "invalid/path"
with 'invalid/path'
(prettier/prettier)
[error] 106-107: Delete ⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace '../config/posts.json',
with ⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert ··
(prettier/prettier)
[error] 113-113: Replace },·{·virtual:·true·}
with ··},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 116-117: Delete ⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert ;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 131-132: Delete ⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete ⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete ⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-144: Replace 'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date');⏎
with ⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····);
(prettier/prettier)
🔇 Additional comments (2)
tests/build-rss.test.js (2)
8-32
: LGTM! Well-structured test setup and teardown.
The implementation follows best practices:
- Uses async file operations with proper error handling
- Ensures proper cleanup of test files
- Correctly uses
jest.resetModules()
to reset the module registry between tests
🧰 Tools
🪛 eslint
[error] 8-8: 'describe' is not defined.
(no-undef)
[error] 12-12: 'beforeAll' is not defined.
(no-undef)
[error] 20-20: 'afterAll' is not defined.
(no-undef)
[error] 23-23: Replace file
with (file)
(prettier/prettier)
[error] 30-30: 'afterEach' is not defined.
(no-undef)
[error] 31-31: 'jest' is not defined.
(no-undef)
34-145
: LGTM! Comprehensive test coverage.
The test suite provides excellent coverage of both happy paths and error cases:
- Validates RSS feed generation and file writing
- Tests post prioritization and sorting
- Handles various error scenarios
- Verifies enclosure types
- Tests empty posts and missing fields
🧰 Tools
🪛 eslint
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete ⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert ;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete ··
(prettier/prettier)
[error] 50-50: Delete ··
(prettier/prettier)
[error] 53-53: Delete ··
(prettier/prettier)
[error] 55-55: Replace item
with (item)
(prettier/prettier)
[error] 56-56: Delete ··
(prettier/prettier)
[error] 59-59: Delete ··
(prettier/prettier)
[error] 65-65: Delete ··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete ··
(prettier/prettier)
[error] 70-70: Delete ··
(prettier/prettier)
[error] 73-73: Delete ··
(prettier/prettier)
[error] 75-75: Replace item
with (item)
(prettier/prettier)
[error] 76-76: Delete ··
(prettier/prettier)
[error] 78-78: Insert ;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert ;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace "invalid/path"
with 'invalid/path'
(prettier/prettier)
[error] 106-107: Delete ⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace '../config/posts.json',
with ⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert ··
(prettier/prettier)
[error] 113-113: Replace },·{·virtual:·true·}
with ··},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 116-117: Delete ⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert ;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 131-132: Delete ⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete ⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete ⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-144: Replace 'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date');⏎
with ⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····);
(prettier/prettier)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
tests/build-rss.test.js (3)
1-6
: Reorder imports following convention.The imports should be ordered as: built-in modules, external dependencies, and then local modules.
const fs = require('fs'); const path = require('path'); +const { XMLParser } = require('fast-xml-parser'); const rssFeed = require('../scripts/build-rss'); -const { XMLParser } = require('fast-xml-parser'); const parser = new XMLParser({ ignoreAttributes: false }); const { mockRssData, title, type, desc, missingDateMockData, incompletePostMockData } = require('./fixtures/rssData');🧰 Tools
🪛 eslint
[error] 4-4: Expected 1 empty line after require statement not followed by another require.
(import/newline-after-import)
[error] 4-4:
fast-xml-parser
import should occur before import of../scripts/build-rss
(import/order)
34-146
: Comprehensive test coverage with room for improvement.The test suite covers essential scenarios including:
- Basic RSS feed generation
- Featured posts prioritization
- Date-based sorting
- Error handling
- Edge cases
However, there's inconsistency in XML content validation.
Consider using the XML parser consistently across all tests, particularly in the enclosure type test:
it('should set correct enclosure type based on image extension', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined(); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); + const parsedContent = parser.parse(fileContent); + const items = parsedContent.rss.channel.item; - expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.png"'); - expect(fileContent).toContain('type="image/png"'); + expect(items[0].enclosure.url).toBe('https://www.asyncapi.com/img/test-cover.png'); + expect(items[0].enclosure.type).toBe('image/png'); // Apply similar changes for other enclosure assertions });🧰 Tools
🪛 eslint
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete
⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert
;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete
··
(prettier/prettier)
[error] 50-50: Delete
··
(prettier/prettier)
[error] 53-53: Delete
··
(prettier/prettier)
[error] 55-55: Replace
item
with(item)
(prettier/prettier)
[error] 56-56: Delete
··
(prettier/prettier)
[error] 59-59: Delete
··
(prettier/prettier)
[error] 65-65: Delete
··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete
··
(prettier/prettier)
[error] 70-70: Delete
··
(prettier/prettier)
[error] 73-73: Delete
··
(prettier/prettier)
[error] 75-75: Replace
item
with(item)
(prettier/prettier)
[error] 76-76: Delete
··
(prettier/prettier)
[error] 78-78: Insert
;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert
;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace
"invalid/path"
with'invalid/path'
(prettier/prettier)
[error] 106-107: Delete
⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace
'../config/posts.json',
with⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert
··
(prettier/prettier)
[error] 113-113: Replace
····},·{·virtual:·true·}
with······},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 115-116: Delete
⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert
;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 132-133: Delete
⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete
⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete
⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-143: Replace
'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'
with⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····
(prettier/prettier)
[error] 144-146: Replace
⏎··});⏎··
with··});
(prettier/prettier)
1-146
: Run prettier to fix formatting issues.There are several formatting inconsistencies flagged by the linter:
- Missing semicolons
- Inconsistent quote usage
- Extra whitespace
Run the project's formatter to fix these issues:
npm run format # or yarn format
🧰 Tools
🪛 eslint
[error] 4-4: Expected 1 empty line after require statement not followed by another require.
(import/newline-after-import)
[error] 4-4:
fast-xml-parser
import should occur before import of../scripts/build-rss
(import/order)
[error] 8-8: 'describe' is not defined.
(no-undef)
[error] 12-12: 'beforeAll' is not defined.
(no-undef)
[error] 20-20: 'afterAll' is not defined.
(no-undef)
[error] 23-23: Replace
file
with(file)
(prettier/prettier)
[error] 30-30: 'afterEach' is not defined.
(no-undef)
[error] 31-31: 'jest' is not defined.
(no-undef)
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete
⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert
;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete
··
(prettier/prettier)
[error] 50-50: Delete
··
(prettier/prettier)
[error] 53-53: Delete
··
(prettier/prettier)
[error] 55-55: Replace
item
with(item)
(prettier/prettier)
[error] 56-56: Delete
··
(prettier/prettier)
[error] 59-59: Delete
··
(prettier/prettier)
[error] 65-65: Delete
··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete
··
(prettier/prettier)
[error] 70-70: Delete
··
(prettier/prettier)
[error] 73-73: Delete
··
(prettier/prettier)
[error] 75-75: Replace
item
with(item)
(prettier/prettier)
[error] 76-76: Delete
··
(prettier/prettier)
[error] 78-78: Insert
;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert
;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace
"invalid/path"
with'invalid/path'
(prettier/prettier)
[error] 106-107: Delete
⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace
'../config/posts.json',
with⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert
··
(prettier/prettier)
[error] 113-113: Replace
····},·{·virtual:·true·}
with······},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 115-116: Delete
⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert
;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 132-133: Delete
⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete
⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete
⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-143: Replace
'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'
with⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····
(prettier/prettier)
[error] 144-146: Replace
⏎··});⏎··
with··});
(prettier/prettier)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
tests/build-rss.test.js
(1 hunks)
🧰 Additional context used
📓 Learnings (1)
tests/build-rss.test.js (1)
Learnt from: akshatnema
PR: asyncapi/website#3101
File: tests/build-rss.test.js:25-27
Timestamp: 2024-11-01T09:55:20.531Z
Learning: In `tests/build-rss.test.js`, replacing `jest.resetModules()` with `jest.resetAllMocks()` in the `afterEach()` block causes errors. It is necessary to use `jest.resetModules()` to reset the module registry between tests in this file.
🪛 eslint
tests/build-rss.test.js
[error] 4-4: Expected 1 empty line after require statement not followed by another require.
(import/newline-after-import)
[error] 4-4: fast-xml-parser
import should occur before import of ../scripts/build-rss
(import/order)
[error] 8-8: 'describe' is not defined.
(no-undef)
[error] 12-12: 'beforeAll' is not defined.
(no-undef)
[error] 20-20: 'afterAll' is not defined.
(no-undef)
[error] 23-23: Replace file
with (file)
(prettier/prettier)
[error] 30-30: 'afterEach' is not defined.
(no-undef)
[error] 31-31: 'jest' is not defined.
(no-undef)
[error] 34-34: 'it' is not defined.
(no-undef)
[error] 35-36: Delete ⏎····
(prettier/prettier)
[error] 36-36: 'jest' is not defined.
(no-undef)
[error] 38-38: Insert ;
(prettier/prettier)
[error] 46-46: 'it' is not defined.
(no-undef)
[error] 47-47: 'jest' is not defined.
(no-undef)
[error] 48-48: Delete ··
(prettier/prettier)
[error] 50-50: Delete ··
(prettier/prettier)
[error] 53-53: Delete ··
(prettier/prettier)
[error] 55-55: Replace item
with (item)
(prettier/prettier)
[error] 56-56: Delete ··
(prettier/prettier)
[error] 59-59: Delete ··
(prettier/prettier)
[error] 65-65: Delete ··
(prettier/prettier)
[error] 66-66: 'it' is not defined.
(no-undef)
[error] 67-67: 'jest' is not defined.
(no-undef)
[error] 68-68: Delete ··
(prettier/prettier)
[error] 70-70: Delete ··
(prettier/prettier)
[error] 73-73: Delete ··
(prettier/prettier)
[error] 75-75: Replace item
with (item)
(prettier/prettier)
[error] 76-76: Delete ··
(prettier/prettier)
[error] 78-78: Insert ;
(prettier/prettier)
[error] 85-85: 'it' is not defined.
(no-undef)
[error] 86-86: 'jest' is not defined.
(no-undef)
[error] 88-88: Insert ;
(prettier/prettier)
[error] 101-101: 'it' is not defined.
(no-undef)
[error] 102-102: 'jest' is not defined.
(no-undef)
[error] 104-104: Replace "invalid/path"
with 'invalid/path'
(prettier/prettier)
[error] 106-107: Delete ⏎
(prettier/prettier)
[error] 110-110: 'it' is not defined.
(no-undef)
[error] 111-111: 'jest' is not defined.
(no-undef)
[error] 111-111: Replace '../config/posts.json',
with ⏎······'../config/posts.json',⏎·····
(prettier/prettier)
[error] 112-112: Insert ··
(prettier/prettier)
[error] 113-113: Replace ····},·{·virtual:·true·}
with ······},⏎······{·virtual:·true·}⏎····
(prettier/prettier)
[error] 115-116: Delete ⏎
(prettier/prettier)
[error] 119-119: 'it' is not defined.
(no-undef)
[error] 121-121: 'jest' is not defined.
(no-undef)
[error] 123-123: Insert ;
(prettier/prettier)
[error] 131-131: 'it' is not defined.
(no-undef)
[error] 132-133: Delete ⏎
(prettier/prettier)
[error] 133-133: 'jest' is not defined.
(no-undef)
[error] 136-137: Delete ⏎
(prettier/prettier)
[error] 139-139: 'it' is not defined.
(no-undef)
[error] 139-140: Delete ⏎
(prettier/prettier)
[error] 141-141: 'jest' is not defined.
(no-undef)
[error] 143-143: Replace 'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'
with ⏎······'Failed·to·generate·RSS·feed:·Missing·date·in·posts:·Post·without·Date'⏎····
(prettier/prettier)
[error] 144-146: Replace ⏎··});⏎··
with ··});
(prettier/prettier)
🔇 Additional comments (1)
tests/build-rss.test.js (1)
12-32
: Well-structured test setup and teardown!
The implementation shows good practices:
- Uses async/await for file operations
- Includes proper error handling
- Ensures cleanup after tests
- Correctly uses
jest.resetModules()
to reset the module registry between tests
🧰 Tools
🪛 eslint
[error] 12-12: 'beforeAll' is not defined.
(no-undef)
[error] 20-20: 'afterAll' is not defined.
(no-undef)
[error] 23-23: Replace file
with (file)
(prettier/prettier)
[error] 30-30: 'afterEach' is not defined.
(no-undef)
[error] 31-31: 'jest' is not defined.
(no-undef)
/rtm |
This PR adds test for build-rss.js script
Summary by CodeRabbit
New Features
Bug Fixes