From 63e8bf5989f7a28b460548c1108380f942d03454 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 21 Jul 2024 22:41:46 +0530 Subject: [PATCH 01/43] added test for build-rss.js --- tests/build-rss.test.js | 109 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 tests/build-rss.test.js diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js new file mode 100644 index 000000000000..2a900f524435 --- /dev/null +++ b/tests/build-rss.test.js @@ -0,0 +1,109 @@ +const fs = require('fs'); +const path = require('path'); +const rssFeed = require('../scripts/build-rss'); + +jest.mock('../config/posts.json', () => ({ + blog: [ + { + title: 'Test Post 1', + slug: '/blog/test-post-1', + excerpt: 'This is a test post', + date: '2024-07-07', + featured: true, + cover: '/img/test-cover.jpg' + }, + { + title: 'Test Post 2', + slug: '/blog/test-post-2', + excerpt: 'This is another test post', + date: '2024-07-07', + featured: false + } + ] +}), { virtual: true }); + +describe('rssFeed', () => { + const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); + + beforeEach(() => { + fs.mkdirSync(testOutputDir, { recursive: true }); + }); + + afterEach(() => { + if (fs.existsSync(testOutputDir)) { + fs.readdirSync(testOutputDir).forEach(file => { + fs.unlinkSync(path.join(testOutputDir, file)); + }); + fs.rmdirSync(testOutputDir); + } + }); + + it('should generate RSS feed and write to file', () => { + const type = 'blog'; + const title = 'Test Blog RSS'; + const desc = 'Test blog RSS feed'; + const outputPath = 'test-output/blog.xml'; + + rssFeed(type, title, desc, outputPath); + + const filePath = path.join(__dirname, '..', 'public', outputPath); + expect(fs.existsSync(filePath)).toBe(true); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain('Test Blog RSS'); + }); + + it('should sort posts by date and featured status', () => { + const type = 'blog'; + const title = 'Test Blog RSS'; + const desc = 'Test blog RSS feed'; + const outputPath = 'test-output/blog.xml'; + + rssFeed(type, title, desc, outputPath); + + const filePath = path.join(__dirname, '..', 'public', outputPath); + const fileContent = fs.readFileSync(filePath, 'utf8'); + + const firstItemIndex = fileContent.indexOf(''); + const secondItemIndex = fileContent.indexOf('', firstItemIndex + 1); + + const firstItemTitleMatch = fileContent.slice(firstItemIndex, secondItemIndex).match(/(.*?)<\/title>/); + const secondItemTitleMatch = fileContent.slice(secondItemIndex).match(/<title>(.*?)<\/title>/); + + expect(firstItemTitleMatch[1]).toBe('Test Post 1'); + expect(secondItemTitleMatch[1]).toBe('Test Post 2'); + }); + + it('should add enclosure for posts with cover image', () => { + const type = 'blog'; + const title = 'Test Blog RSS'; + const desc = 'Test blog RSS feed'; + const outputPath = 'test-output/blog.xml'; + + rssFeed(type, title, desc, outputPath); + + 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.jpg"'); + expect(fileContent).toContain('type="image/jpeg"'); + }); + + it('should set correct enclosure type based on image extension', () => { + const type = 'blog'; + const title = 'Test Blog RSS'; + const desc = 'Test blog RSS feed'; + const outputPath = 'test-output/blog.xml'; + + const posts = require('../config/posts.json'); + posts.blog[0].cover = '/img/test-cover.png'; + + rssFeed(type, title, desc, outputPath); + + 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"'); + }); +}); \ No newline at end of file From aad7bf2414fe8048ac848688182120908f811b82 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 16 Aug 2024 11:58:32 +0530 Subject: [PATCH 02/43] test updated --- tests/build-rss.test.js | 47 ++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 2a900f524435..1fc9ecc7bdf8 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -16,8 +16,32 @@ jest.mock('../config/posts.json', () => ({ title: 'Test Post 2', slug: '/blog/test-post-2', excerpt: 'This is another test post', - date: '2024-07-07', + date: '2024-07-06', featured: false + }, + { + title: 'PNG Post', + slug: '/blog/png-post', + excerpt: 'This is a post with PNG image', + date: '2024-07-05', + featured: false, + cover: '/img/test-cover.png' + }, + { + title: 'SVG Post', + slug: '/blog/svg-post', + excerpt: 'This is a post with SVG image', + date: '2024-07-04', + featured: false, + cover: '/img/test-cover.svg' + }, + { + title: 'WebP Post', + slug: '/blog/webp-post', + excerpt: 'This is a post with WebP image', + date: '2024-07-03', + featured: false, + cover: '/img/test-cover.webp' } ] }), { virtual: true }); @@ -63,15 +87,13 @@ describe('rssFeed', () => { const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - - const firstItemIndex = fileContent.indexOf('<item>'); - const secondItemIndex = fileContent.indexOf('<item>', firstItemIndex + 1); - const firstItemTitleMatch = fileContent.slice(firstItemIndex, secondItemIndex).match(/<title>(.*?)<\/title>/); - const secondItemTitleMatch = fileContent.slice(secondItemIndex).match(/<title>(.*?)<\/title>/); - - expect(firstItemTitleMatch[1]).toBe('Test Post 1'); - expect(secondItemTitleMatch[1]).toBe('Test Post 2'); + const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); + expect(itemTitles[1]).toContain('Test Post 1'); + expect(itemTitles[2]).toContain('Test Post 2'); + expect(itemTitles[3]).toContain('PNG Post'); + expect(itemTitles[4]).toContain('SVG Post'); + expect(itemTitles[5]).toContain('WebP Post'); }); it('should add enclosure for posts with cover image', () => { @@ -95,9 +117,6 @@ describe('rssFeed', () => { const desc = 'Test blog RSS feed'; const outputPath = 'test-output/blog.xml'; - const posts = require('../config/posts.json'); - posts.blog[0].cover = '/img/test-cover.png'; - rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); @@ -105,5 +124,9 @@ describe('rssFeed', () => { 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"'); }); }); \ No newline at end of file From cfd547f49effc7d3851acb90ddb0281eaebdb27e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Thu, 22 Aug 2024 09:49:39 +0530 Subject: [PATCH 03/43] fewe --- tests/build-rss.test.js | 45 ++------------------------------------- tests/fixtures/rssData.js | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 tests/fixtures/rssData.js diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 1fc9ecc7bdf8..09a37ee64fa4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,50 +1,9 @@ const fs = require('fs'); const path = require('path'); const rssFeed = require('../scripts/build-rss'); +const { mockRssData } = require('./fixtures/rssData'); -jest.mock('../config/posts.json', () => ({ - blog: [ - { - title: 'Test Post 1', - slug: '/blog/test-post-1', - excerpt: 'This is a test post', - date: '2024-07-07', - featured: true, - cover: '/img/test-cover.jpg' - }, - { - title: 'Test Post 2', - slug: '/blog/test-post-2', - excerpt: 'This is another test post', - date: '2024-07-06', - featured: false - }, - { - title: 'PNG Post', - slug: '/blog/png-post', - excerpt: 'This is a post with PNG image', - date: '2024-07-05', - featured: false, - cover: '/img/test-cover.png' - }, - { - title: 'SVG Post', - slug: '/blog/svg-post', - excerpt: 'This is a post with SVG image', - date: '2024-07-04', - featured: false, - cover: '/img/test-cover.svg' - }, - { - title: 'WebP Post', - slug: '/blog/webp-post', - excerpt: 'This is a post with WebP image', - date: '2024-07-03', - featured: false, - cover: '/img/test-cover.webp' - } - ] -}), { virtual: true }); +jest.mock('../config/posts.json', () => mockRssData, { virtual: true }) describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js new file mode 100644 index 000000000000..3659c5afeb86 --- /dev/null +++ b/tests/fixtures/rssData.js @@ -0,0 +1,45 @@ +const mockRssData = { + blog: [ + { + title: 'Test Post 1', + slug: '/blog/test-post-1', + excerpt: 'This is a test post', + date: '2024-07-07', + featured: true, + cover: '/img/test-cover.jpg' + }, + { + title: 'Test Post 2', + slug: '/blog/test-post-2', + excerpt: 'This is another test post', + date: '2024-07-06', + featured: false + }, + { + title: 'PNG Post', + slug: '/blog/png-post', + excerpt: 'This is a post with PNG image', + date: '2024-07-05', + featured: false, + cover: '/img/test-cover.png' + }, + { + title: 'SVG Post', + slug: '/blog/svg-post', + excerpt: 'This is a post with SVG image', + date: '2024-07-04', + featured: false, + cover: '/img/test-cover.svg' + }, + { + title: 'WebP Post', + slug: '/blog/webp-post', + excerpt: 'This is a post with WebP image', + date: '2024-07-03', + featured: false, + cover: '/img/test-cover.webp' + } + ] +}; + +module.exports = { mockRssData }; From 5859c79db637da9eac82a4dde1b44512e5a9c3e7 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Thu, 22 Aug 2024 10:09:52 +0530 Subject: [PATCH 04/43] fedge --- tests/build-rss.test.js | 18 +----------------- tests/fixtures/rssData.js | 7 ++++++- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 09a37ee64fa4..41d70518baa5 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const rssFeed = require('../scripts/build-rss'); -const { mockRssData } = require('./fixtures/rssData'); +const { mockRssData, title, type, desc, outputPath } = require('./fixtures/rssData'); jest.mock('../config/posts.json', () => mockRssData, { virtual: true }) @@ -22,10 +22,6 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', () => { - const type = 'blog'; - const title = 'Test Blog RSS'; - const desc = 'Test blog RSS feed'; - const outputPath = 'test-output/blog.xml'; rssFeed(type, title, desc, outputPath); @@ -37,10 +33,6 @@ describe('rssFeed', () => { }); it('should sort posts by date and featured status', () => { - const type = 'blog'; - const title = 'Test Blog RSS'; - const desc = 'Test blog RSS feed'; - const outputPath = 'test-output/blog.xml'; rssFeed(type, title, desc, outputPath); @@ -56,10 +48,6 @@ describe('rssFeed', () => { }); it('should add enclosure for posts with cover image', () => { - const type = 'blog'; - const title = 'Test Blog RSS'; - const desc = 'Test blog RSS feed'; - const outputPath = 'test-output/blog.xml'; rssFeed(type, title, desc, outputPath); @@ -71,10 +59,6 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', () => { - const type = 'blog'; - const title = 'Test Blog RSS'; - const desc = 'Test blog RSS feed'; - const outputPath = 'test-output/blog.xml'; rssFeed(type, title, desc, outputPath); diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 3659c5afeb86..816fa2d64f5b 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -42,4 +42,9 @@ const mockRssData = { ] }; -module.exports = { mockRssData }; +const type = 'blog'; +const title = 'Test Blog RSS'; +const desc = 'Test blog RSS feed'; +const outputPath = 'test-output/blog.xml'; + +module.exports = { mockRssData, title, type, desc, outputPath }; From 44c3b63f467b7aa21784e9ce2ff3884ab4565ebd Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Thu, 22 Aug 2024 10:19:09 +0530 Subject: [PATCH 05/43] fsfa --- scripts/build-rss.js | 99 +++++++++++++++++++++-------------------- tests/build-rss.test.js | 8 +--- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index a5461f5e0baf..ec2080c36350 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -16,60 +16,63 @@ function clean(s) { } module.exports = function rssFeed(type, title, desc, outputPath) { + try { + const posts = getAllPosts()[`${type}`] + .sort((i1, i2) => { + const i1Date = new Date(i1.date) + const i2Date = new Date(i2.date) - const posts = getAllPosts()[`${type}`] - .sort((i1, i2) => { - const i1Date = new Date(i1.date) - const i2Date = new Date(i2.date) + if (i1.featured && !i2.featured) return -1 + if (!i1.featured && i2.featured) return 1 + return i2Date - i1Date + }) - if (i1.featured && !i2.featured) return -1 - if (!i1.featured && i2.featured) return 1 - return i2Date - i1Date - }) + const base = 'https://www.asyncapi.com' + const tracking = '?utm_source=rss'; - const base = 'https://www.asyncapi.com' - const tracking = '?utm_source=rss'; + const feed = {} + const rss = {} + rss['@version'] = '2.0' + rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' + rss.channel = {} + rss.channel.title = title + rss.channel.link = `${base}/${outputPath}` + rss.channel["atom:link"] = {} + rss.channel["atom:link"]["@rel"] = 'self' + rss.channel["atom:link"]["@href"] = rss.channel.link + rss.channel["atom:link"]["@type"] = 'application/rss+xml' + rss.channel.description = desc + rss.channel.language = 'en-gb'; + rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; + rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' + rss.channel.pubDate = new Date().toUTCString() + rss.channel.generator = 'next.js' + rss.channel.item = [] - const feed = {} - const rss = {} - rss['@version'] = '2.0' - rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' - rss.channel = {} - rss.channel.title = title - rss.channel.link = `${base}/${outputPath}` - rss.channel["atom:link"] = {} - rss.channel["atom:link"]["@rel"] = 'self' - rss.channel["atom:link"]["@href"] = rss.channel.link - rss.channel["atom:link"]["@type"] = 'application/rss+xml' - rss.channel.description = desc - rss.channel.language = 'en-gb'; - rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; - rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' - rss.channel.pubDate = new Date().toUTCString() - rss.channel.generator = 'next.js' - rss.channel.item = [] - - for (let post of posts) { - const link = `${base}${post.slug}${tracking}`; - const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } - if (post.cover) { - const enclosure = {}; - enclosure["@url"] = base+post.cover; - enclosure["@length"] = 15026; // dummy value, anything works - enclosure["@type"] = 'image/jpeg'; - if (typeof enclosure["@url"] === 'string') { - let tmp = enclosure["@url"].toLowerCase(); - if (tmp.indexOf('.png')>=0) enclosure["@type"] = 'image/png'; - if (tmp.indexOf('.svg')>=0) enclosure["@type"] = 'image/svg+xml'; - if (tmp.indexOf('.webp')>=0) enclosure["@type"] = 'image/webp'; + for (let post of posts) { + const link = `${base}${post.slug}${tracking}`; + const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } + if (post.cover) { + const enclosure = {}; + enclosure["@url"] = base + post.cover; + enclosure["@length"] = 15026; // dummy value, anything works + enclosure["@type"] = 'image/jpeg'; + if (typeof enclosure["@url"] === 'string') { + let tmp = enclosure["@url"].toLowerCase(); + if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; + if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; + if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; + } + item.enclosure = enclosure; } - item.enclosure = enclosure; + rss.channel.item.push(item) } - rss.channel.item.push(item) - } - feed.rss = rss + feed.rss = rss - const xml = json2xml.getXml(feed,'@','',2) - fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') + const xml = json2xml.getXml(feed, '@', '', 2) + fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') + } catch (err) { + throw new Error(`Failed to generate RSS feed: ${err.message}`); + } }; diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 41d70518baa5..01f042cbfe55 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -3,7 +3,7 @@ const path = require('path'); const rssFeed = require('../scripts/build-rss'); const { mockRssData, title, type, desc, outputPath } = require('./fixtures/rssData'); -jest.mock('../config/posts.json', () => mockRssData, { virtual: true }) +jest.mock('../config/posts.json', () => mockRssData, { virtual: true }); describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); @@ -22,7 +22,6 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', () => { - rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); @@ -33,7 +32,6 @@ describe('rssFeed', () => { }); it('should sort posts by date and featured status', () => { - rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); @@ -48,7 +46,6 @@ describe('rssFeed', () => { }); it('should add enclosure for posts with cover image', () => { - rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); @@ -59,7 +56,6 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', () => { - rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); @@ -72,4 +68,4 @@ describe('rssFeed', () => { expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.webp"'); expect(fileContent).toContain('type="image/webp"'); }); -}); \ No newline at end of file +}); From de5edecf6cd5cf8d3303ff141c36667a4eacf833 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Thu, 22 Aug 2024 10:27:20 +0530 Subject: [PATCH 06/43] test for write operation error --- tests/build-rss.test.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 01f042cbfe55..fb45cdea40b1 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -68,4 +68,45 @@ describe('rssFeed', () => { expect(fileContent).toContain('<enclosure url="https://www.asyncapi.com/img/test-cover.webp"'); expect(fileContent).toContain('type="image/webp"'); }); + + it('should throw error when write operation fails', () => { + const outputPath = "invalid/path" + try{ + rssFeed(type, title, desc, outputPath) + }catch(err){ + expect(err.message).toMatch(/ENOENT|EACCES/); + } + }); + + // it('should handle invalid date formats in posts', () => { + // const invalidDatePost = { + // title: 'Invalid Date Post', + // slug: '/blog/invalid-date', + // date: 'Not a date', + // excerpt: 'This post has an invalid date.', + // }; + // jest.spyOn(require('../config/posts.json'), type).mockReturnValue([...mockRssData[type], invalidDatePost]); + + // expect(() => rssFeed(type, title, desc, outputPath)).not.toThrow(); + + // const filePath = path.join(__dirname, '..', 'public', outputPath); + // const fileContent = fs.readFileSync(filePath, 'utf8'); + // expect(fileContent).toContain('<title>Invalid Date Post'); + // }); + + // it('should handle missing fields in posts', () => { + // const incompletePost = { + // title: 'Incomplete Post', + // // Missing slug and date + // excerpt: 'This post is missing some fields.', + // }; + // jest.spyOn(require('../config/posts.json'), type).mockReturnValue([...mockRssData[type], incompletePost]); + + // expect(() => rssFeed(type, title, desc, outputPath)).not.toThrow(); + + // const filePath = path.join(__dirname, '..', 'public', outputPath); + // const fileContent = fs.readFileSync(filePath, 'utf8'); + // expect(fileContent).toContain('Incomplete Post'); + // }); + }); From bf10b10875fdc64415ebcd2f5d8493bacebe6d40 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 22 Aug 2024 10:36:00 +0530 Subject: [PATCH 07/43] test updated --- tests/build-rss.test.js | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index fb45cdea40b1..97c1c87ef01f 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -78,35 +78,4 @@ describe('rssFeed', () => { } }); - // it('should handle invalid date formats in posts', () => { - // const invalidDatePost = { - // title: 'Invalid Date Post', - // slug: '/blog/invalid-date', - // date: 'Not a date', - // excerpt: 'This post has an invalid date.', - // }; - // jest.spyOn(require('../config/posts.json'), type).mockReturnValue([...mockRssData[type], invalidDatePost]); - - // expect(() => rssFeed(type, title, desc, outputPath)).not.toThrow(); - - // const filePath = path.join(__dirname, '..', 'public', outputPath); - // const fileContent = fs.readFileSync(filePath, 'utf8'); - // expect(fileContent).toContain('Invalid Date Post'); - // }); - - // it('should handle missing fields in posts', () => { - // const incompletePost = { - // title: 'Incomplete Post', - // // Missing slug and date - // excerpt: 'This post is missing some fields.', - // }; - // jest.spyOn(require('../config/posts.json'), type).mockReturnValue([...mockRssData[type], incompletePost]); - - // expect(() => rssFeed(type, title, desc, outputPath)).not.toThrow(); - - // const filePath = path.join(__dirname, '..', 'public', outputPath); - // const fileContent = fs.readFileSync(filePath, 'utf8'); - // expect(fileContent).toContain('Incomplete Post'); - // }); - }); From 1bacff6fd087093a32f8172be4c6f3db91eedff5 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 22 Aug 2024 11:12:59 +0530 Subject: [PATCH 08/43] egrwsdb --- scripts/build-rss.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index ec2080c36350..e1b9e94c299b 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -75,4 +75,4 @@ module.exports = function rssFeed(type, title, desc, outputPath) { } catch (err) { throw new Error(`Failed to generate RSS feed: ${err.message}`); } -}; +}; \ No newline at end of file From 5d8fb6717226121ba1ae9ac5b3c08d14e5a3c15e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 31 Aug 2024 22:30:26 +0530 Subject: [PATCH 09/43] use pretteir for rssData --- tests/fixtures/rssData.js | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 816fa2d64f5b..f49d16766bdf 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -1,45 +1,45 @@ const mockRssData = { - blog: [ - { - title: 'Test Post 1', - slug: '/blog/test-post-1', - excerpt: 'This is a test post', - date: '2024-07-07', - featured: true, - cover: '/img/test-cover.jpg' - }, - { - title: 'Test Post 2', - slug: '/blog/test-post-2', - excerpt: 'This is another test post', - date: '2024-07-06', - featured: false - }, - { - title: 'PNG Post', - slug: '/blog/png-post', - excerpt: 'This is a post with PNG image', - date: '2024-07-05', - featured: false, - cover: '/img/test-cover.png' - }, - { - title: 'SVG Post', - slug: '/blog/svg-post', - excerpt: 'This is a post with SVG image', - date: '2024-07-04', - featured: false, - cover: '/img/test-cover.svg' - }, - { - title: 'WebP Post', - slug: '/blog/webp-post', - excerpt: 'This is a post with WebP image', - date: '2024-07-03', - featured: false, - cover: '/img/test-cover.webp' - } - ] + blog: [ + { + title: 'Test Post 1', + slug: '/blog/test-post-1', + excerpt: 'This is a test post', + date: '2024-07-07', + featured: true, + cover: '/img/test-cover.jpg', + }, + { + title: 'Test Post 2', + slug: '/blog/test-post-2', + excerpt: 'This is another test post', + date: '2024-07-06', + featured: false, + }, + { + title: 'PNG Post', + slug: '/blog/png-post', + excerpt: 'This is a post with PNG image', + date: '2024-07-05', + featured: false, + cover: '/img/test-cover.png', + }, + { + title: 'SVG Post', + slug: '/blog/svg-post', + excerpt: 'This is a post with SVG image', + date: '2024-07-04', + featured: false, + cover: '/img/test-cover.svg', + }, + { + title: 'WebP Post', + slug: '/blog/webp-post', + excerpt: 'This is a post with WebP image', + date: '2024-07-03', + featured: false, + cover: '/img/test-cover.webp', + }, + ], }; const type = 'blog'; From 0d0cb30c366d1836c0840f16e09136d050b4ab88 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 11 Sep 2024 20:03:32 +0530 Subject: [PATCH 10/43] updated rss mock data --- scripts/build-rss.js | 1 - tests/build-rss.test.js | 30 ++++++++++++++++++------- tests/fixtures/rssData.js | 46 +++++++++++++++++++-------------------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index e1b9e94c299b..a8376734ac6e 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -21,7 +21,6 @@ module.exports = function rssFeed(type, title, desc, outputPath) { .sort((i1, i2) => { const i1Date = new Date(i1.date) const i2Date = new Date(i2.date) - if (i1.featured && !i2.featured) return -1 if (!i1.featured && i2.featured) return 1 return i2Date - i1Date diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 97c1c87ef01f..71199574d5bb 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -31,18 +31,32 @@ describe('rssFeed', () => { expect(fileContent).toContain('Test Blog RSS'); }); - it('should sort posts by date and featured status', () => { + it('should prioritize featured posts over non-featured ones', () => { rssFeed(type, title, desc, outputPath); - + const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); + + const itemTitles = fileContent.match(/(.*?)<\/title>/g); + + expect(itemTitles[1]).toContain('Test Post 1'); + expect(itemTitles[2]).toContain('Another Featured Post'); + expect(itemTitles[3]).toContain('Non-Featured Post 1'); + }); + it('should sort posts by date in descending order', () => { + rssFeed(type, title, desc, outputPath); + + const filePath = path.join(__dirname, '..', 'public', outputPath); + const fileContent = fs.readFileSync(filePath, 'utf8'); + const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); + expect(itemTitles[1]).toContain('Test Post 1'); - expect(itemTitles[2]).toContain('Test Post 2'); - expect(itemTitles[3]).toContain('PNG Post'); - expect(itemTitles[4]).toContain('SVG Post'); - expect(itemTitles[5]).toContain('WebP Post'); + expect(itemTitles[2]).toContain('Another Featured Post'); + expect(itemTitles[3]).toContain('Non-Featured Post 1'); + expect(itemTitles[4]).toContain('Non-Featured Post 3'); + expect(itemTitles[5]).toContain('Non-Featured Post 2'); }); it('should add enclosure for posts with cover image', () => { @@ -77,5 +91,5 @@ describe('rssFeed', () => { expect(err.message).toMatch(/ENOENT|EACCES/); } }); - -}); + +}); \ No newline at end of file diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index f49d16766bdf..7c35005634bb 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -1,43 +1,43 @@ 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 test post', + excerpt: 'This is a featured test post', date: '2024-07-07', featured: true, cover: '/img/test-cover.jpg', }, { - title: 'Test Post 2', - slug: '/blog/test-post-2', - excerpt: 'This is another test post', + title: 'Another Featured Post', + slug: '/blog/another-featured-post', + excerpt: 'This is another featured post', date: '2024-07-06', - featured: false, + featured: true, + cover: '/img/test-cover.svg', }, { - title: 'PNG Post', - slug: '/blog/png-post', - excerpt: 'This is a post with PNG image', - date: '2024-07-05', + 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.png', + cover: '/img/test-cover.webp', }, { - title: 'SVG Post', - slug: '/blog/svg-post', - excerpt: 'This is a post with SVG image', + 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.svg', - }, - { - title: 'WebP Post', - slug: '/blog/webp-post', - excerpt: 'This is a post with WebP image', - date: '2024-07-03', - featured: false, - cover: '/img/test-cover.webp', + cover: '/img/test-cover.png', }, ], }; @@ -47,4 +47,4 @@ const title = 'Test Blog RSS'; const desc = 'Test blog RSS feed'; const outputPath = 'test-output/blog.xml'; -module.exports = { mockRssData, title, type, desc, outputPath }; +module.exports = { mockRssData, title, type, desc, outputPath }; \ No newline at end of file From d7e0ac17081cd695eded4a62644ddedbbecb0068 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Wed, 11 Sep 2024 20:06:08 +0530 Subject: [PATCH 11/43] updated rss test --- tests/build-rss.test.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 71199574d5bb..d36a2866c20c 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -59,16 +59,6 @@ describe('rssFeed', () => { expect(itemTitles[5]).toContain('Non-Featured Post 2'); }); - it('should add enclosure for posts with cover image', () => { - rssFeed(type, title, desc, outputPath); - - 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.jpg"'); - expect(fileContent).toContain('type="image/jpeg"'); - }); - it('should set correct enclosure type based on image extension', () => { rssFeed(type, title, desc, outputPath); @@ -91,5 +81,5 @@ describe('rssFeed', () => { expect(err.message).toMatch(/ENOENT|EACCES/); } }); - + }); \ No newline at end of file From fc57c2a3c676540ddb6a83aa4ce2d9fecab8f4ac Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Wed, 11 Sep 2024 20:12:43 +0530 Subject: [PATCH 12/43] udadw --- scripts/build-rss.js | 2 +- tests/build-rss.test.js | 2 +- tests/fixtures/rssData.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index a8376734ac6e..bdd26a5fbc89 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -74,4 +74,4 @@ module.exports = function rssFeed(type, title, desc, outputPath) { } catch (err) { throw new Error(`Failed to generate RSS feed: ${err.message}`); } -}; \ No newline at end of file +}; diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index d36a2866c20c..be4eac0575f4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -82,4 +82,4 @@ describe('rssFeed', () => { } }); -}); \ No newline at end of file +}); diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 7c35005634bb..963a621bf7de 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -47,4 +47,4 @@ const title = 'Test Blog RSS'; const desc = 'Test blog RSS feed'; const outputPath = 'test-output/blog.xml'; -module.exports = { mockRssData, title, type, desc, outputPath }; \ No newline at end of file +module.exports = { mockRssData, title, type, desc, outputPath }; From 1a8aa47b2a2c2e001e1651c9913cb22ca0dc4262 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Wed, 11 Sep 2024 20:17:45 +0530 Subject: [PATCH 13/43] updated imports --- scripts/build-rss.js | 127 ++++++++++++++++++++-------------------- scripts/index.js | 2 +- tests/build-rss.test.js | 2 +- tests/index.test.js | 2 +- 4 files changed, 68 insertions(+), 65 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index bdd26a5fbc89..f00518bd2ee1 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -1,77 +1,80 @@ -const fs = require('fs') -const json2xml = require('jgexml/json2xml') +const fs = require('fs'); +const json2xml = require('jgexml/json2xml'); function getAllPosts() { - return require('../config/posts.json') + return require('../config/posts.json'); } function clean(s) { - s = s.split('<span>').join('') - s = s.split('&').join('&') - s = s.split(''').join("'") - s = s.split('<').join('<') - s = s.split('>').join('>') - s = s.split('"').join('"') - return s + s = s.split('<span>').join(''); + s = s.split('&').join('&'); + s = s.split(''').join("'"); + s = s.split('<').join('<'); + s = s.split('>').join('>'); + s = s.split('"').join('"'); + return s; } -module.exports = function rssFeed(type, title, desc, outputPath) { - try { - const posts = getAllPosts()[`${type}`] - .sort((i1, i2) => { - const i1Date = new Date(i1.date) - const i2Date = new Date(i2.date) - if (i1.featured && !i2.featured) return -1 - if (!i1.featured && i2.featured) return 1 - return i2Date - i1Date - }) +module.exports = { + rssFeed: function rssFeed(type, title, desc, outputPath) { + try { + const posts = getAllPosts()[`${type}`] + .sort((i1, i2) => { + const i1Date = new Date(i1.date); + const i2Date = new Date(i2.date); + if (i1.featured && !i2.featured) return -1; + if (!i1.featured && i2.featured) return 1; + return i2Date - i1Date; + }); - const base = 'https://www.asyncapi.com' - const tracking = '?utm_source=rss'; + const base = 'https://www.asyncapi.com'; + const tracking = '?utm_source=rss'; - const feed = {} - const rss = {} - rss['@version'] = '2.0' - rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' - rss.channel = {} - rss.channel.title = title - rss.channel.link = `${base}/${outputPath}` - rss.channel["atom:link"] = {} - rss.channel["atom:link"]["@rel"] = 'self' - rss.channel["atom:link"]["@href"] = rss.channel.link - rss.channel["atom:link"]["@type"] = 'application/rss+xml' - rss.channel.description = desc - rss.channel.language = 'en-gb'; - rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; - rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' - rss.channel.pubDate = new Date().toUTCString() - rss.channel.generator = 'next.js' - rss.channel.item = [] + const feed = {}; + const rss = {}; + rss['@version'] = '2.0'; + rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom'; + rss.channel = {}; + rss.channel.title = title; + rss.channel.link = `${base}/${outputPath}`; + rss.channel["atom:link"] = {}; + rss.channel["atom:link"]["@rel"] = 'self'; + rss.channel["atom:link"]["@href"] = rss.channel.link; + rss.channel["atom:link"]["@type"] = 'application/rss+xml'; + rss.channel.description = desc; + rss.channel.language = 'en-gb'; + rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; + rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)'; + rss.channel.pubDate = new Date().toUTCString(); + rss.channel.generator = 'next.js'; + rss.channel.item = []; - for (let post of posts) { - const link = `${base}${post.slug}${tracking}`; - const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } - if (post.cover) { - const enclosure = {}; - enclosure["@url"] = base + post.cover; - enclosure["@length"] = 15026; // dummy value, anything works - enclosure["@type"] = 'image/jpeg'; - if (typeof enclosure["@url"] === 'string') { - let tmp = enclosure["@url"].toLowerCase(); - if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; - if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; - if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; + for (let post of posts) { + const link = `${base}${post.slug}${tracking}`; + const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() }; + if (post.cover) { + const enclosure = {}; + enclosure["@url"] = base + post.cover; + enclosure["@length"] = 15026; // dummy value, anything works + enclosure["@type"] = 'image/jpeg'; + if (typeof enclosure["@url"] === 'string') { + let tmp = enclosure["@url"].toLowerCase(); + if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; + if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; + if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; + } + item.enclosure = enclosure; } - item.enclosure = enclosure; + rss.channel.item.push(item); } - rss.channel.item.push(item) - } - feed.rss = rss + feed.rss = rss; - const xml = json2xml.getXml(feed, '@', '', 2) - fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') - } catch (err) { - throw new Error(`Failed to generate RSS feed: ${err.message}`); - } + const xml = json2xml.getXml(feed, '@', '', 2); + fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8'); + } catch (err) { + throw new Error(`Failed to generate RSS feed: ${err.message}`); + } + }, + clean }; diff --git a/scripts/index.js b/scripts/index.js index b37750801266..1bab40e225f7 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -1,4 +1,4 @@ -const rssFeed = require('./build-rss'); +const { rssFeed } = require('./build-rss'); const buildPostList = require('./build-post-list'); const buildCaseStudiesList = require('./casestudies'); const buildAdoptersList = require('./adopters') diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index be4eac0575f4..3527e4503a0a 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,6 +1,6 @@ const fs = require('fs'); const path = require('path'); -const rssFeed = require('../scripts/build-rss'); +const { rssFeed } = require('../scripts/build-rss'); const { mockRssData, title, type, desc, outputPath } = require('./fixtures/rssData'); jest.mock('../config/posts.json', () => mockRssData, { virtual: true }); diff --git a/tests/index.test.js b/tests/index.test.js index 78e2c216958f..96e60119c131 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -1,4 +1,4 @@ -const rssFeed = require('../scripts/build-rss'); +const { rssFeed } = require('../scripts/build-rss'); const buildPostList = require('../scripts/build-post-list'); const buildCaseStudiesList = require('../scripts/casestudies'); const buildAdoptersList = require('../scripts/adopters'); From 5ddb184abc2339ab61f80a7ac87354da54399282 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Wed, 11 Sep 2024 20:20:15 +0530 Subject: [PATCH 14/43] test updated --- scripts/build-rss.js | 127 ++++++++++++++++++++-------------------- scripts/index.js | 2 +- tests/build-rss.test.js | 2 +- tests/index.test.js | 2 +- 4 files changed, 65 insertions(+), 68 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index f00518bd2ee1..bdd26a5fbc89 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -1,80 +1,77 @@ -const fs = require('fs'); -const json2xml = require('jgexml/json2xml'); +const fs = require('fs') +const json2xml = require('jgexml/json2xml') function getAllPosts() { - return require('../config/posts.json'); + return require('../config/posts.json') } function clean(s) { - s = s.split('<span>').join(''); - s = s.split('&').join('&'); - s = s.split(''').join("'"); - s = s.split('<').join('<'); - s = s.split('>').join('>'); - s = s.split('"').join('"'); - return s; + s = s.split('<span>').join('') + s = s.split('&').join('&') + s = s.split(''').join("'") + s = s.split('<').join('<') + s = s.split('>').join('>') + s = s.split('"').join('"') + return s } -module.exports = { - rssFeed: function rssFeed(type, title, desc, outputPath) { - try { - const posts = getAllPosts()[`${type}`] - .sort((i1, i2) => { - const i1Date = new Date(i1.date); - const i2Date = new Date(i2.date); - if (i1.featured && !i2.featured) return -1; - if (!i1.featured && i2.featured) return 1; - return i2Date - i1Date; - }); +module.exports = function rssFeed(type, title, desc, outputPath) { + try { + const posts = getAllPosts()[`${type}`] + .sort((i1, i2) => { + const i1Date = new Date(i1.date) + const i2Date = new Date(i2.date) + if (i1.featured && !i2.featured) return -1 + if (!i1.featured && i2.featured) return 1 + return i2Date - i1Date + }) - const base = 'https://www.asyncapi.com'; - const tracking = '?utm_source=rss'; + const base = 'https://www.asyncapi.com' + const tracking = '?utm_source=rss'; - const feed = {}; - const rss = {}; - rss['@version'] = '2.0'; - rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom'; - rss.channel = {}; - rss.channel.title = title; - rss.channel.link = `${base}/${outputPath}`; - rss.channel["atom:link"] = {}; - rss.channel["atom:link"]["@rel"] = 'self'; - rss.channel["atom:link"]["@href"] = rss.channel.link; - rss.channel["atom:link"]["@type"] = 'application/rss+xml'; - rss.channel.description = desc; - rss.channel.language = 'en-gb'; - rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; - rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)'; - rss.channel.pubDate = new Date().toUTCString(); - rss.channel.generator = 'next.js'; - rss.channel.item = []; + const feed = {} + const rss = {} + rss['@version'] = '2.0' + rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' + rss.channel = {} + rss.channel.title = title + rss.channel.link = `${base}/${outputPath}` + rss.channel["atom:link"] = {} + rss.channel["atom:link"]["@rel"] = 'self' + rss.channel["atom:link"]["@href"] = rss.channel.link + rss.channel["atom:link"]["@type"] = 'application/rss+xml' + rss.channel.description = desc + rss.channel.language = 'en-gb'; + rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; + rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' + rss.channel.pubDate = new Date().toUTCString() + rss.channel.generator = 'next.js' + rss.channel.item = [] - for (let post of posts) { - const link = `${base}${post.slug}${tracking}`; - const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() }; - if (post.cover) { - const enclosure = {}; - enclosure["@url"] = base + post.cover; - enclosure["@length"] = 15026; // dummy value, anything works - enclosure["@type"] = 'image/jpeg'; - if (typeof enclosure["@url"] === 'string') { - let tmp = enclosure["@url"].toLowerCase(); - if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; - if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; - if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; - } - item.enclosure = enclosure; + for (let post of posts) { + const link = `${base}${post.slug}${tracking}`; + const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } + if (post.cover) { + const enclosure = {}; + enclosure["@url"] = base + post.cover; + enclosure["@length"] = 15026; // dummy value, anything works + enclosure["@type"] = 'image/jpeg'; + if (typeof enclosure["@url"] === 'string') { + let tmp = enclosure["@url"].toLowerCase(); + if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; + if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; + if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; } - rss.channel.item.push(item); + item.enclosure = enclosure; } + rss.channel.item.push(item) + } - feed.rss = rss; + feed.rss = rss - const xml = json2xml.getXml(feed, '@', '', 2); - fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8'); - } catch (err) { - throw new Error(`Failed to generate RSS feed: ${err.message}`); - } - }, - clean + const xml = json2xml.getXml(feed, '@', '', 2) + fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') + } catch (err) { + throw new Error(`Failed to generate RSS feed: ${err.message}`); + } }; diff --git a/scripts/index.js b/scripts/index.js index 1bab40e225f7..b37750801266 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -1,4 +1,4 @@ -const { rssFeed } = require('./build-rss'); +const rssFeed = require('./build-rss'); const buildPostList = require('./build-post-list'); const buildCaseStudiesList = require('./casestudies'); const buildAdoptersList = require('./adopters') diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 3527e4503a0a..be4eac0575f4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,6 +1,6 @@ const fs = require('fs'); const path = require('path'); -const { rssFeed } = require('../scripts/build-rss'); +const rssFeed = require('../scripts/build-rss'); const { mockRssData, title, type, desc, outputPath } = require('./fixtures/rssData'); jest.mock('../config/posts.json', () => mockRssData, { virtual: true }); diff --git a/tests/index.test.js b/tests/index.test.js index 96e60119c131..78e2c216958f 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -1,4 +1,4 @@ -const { rssFeed } = require('../scripts/build-rss'); +const rssFeed = require('../scripts/build-rss'); const buildPostList = require('../scripts/build-post-list'); const buildCaseStudiesList = require('../scripts/casestudies'); const buildAdoptersList = require('../scripts/adopters'); From 1eb67901a23b93891b2e7747cfd433c4edbd2989 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 13 Sep 2024 09:22:54 +0530 Subject: [PATCH 15/43] added try catch block for tests --- tests/build-rss.test.js | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index be4eac0575f4..ec2999692515 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -22,7 +22,11 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', () => { - rssFeed(type, title, desc, outputPath); + try { + rssFeed(type, title, desc, outputPath); + } catch (err) { + throw new Error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); @@ -32,26 +36,34 @@ describe('rssFeed', () => { }); it('should prioritize featured posts over non-featured ones', () => { - rssFeed(type, title, desc, outputPath); - + try { + rssFeed(type, title, desc, outputPath); + } catch (err) { + throw new Error('Error encountered during test execution:', err) + } + const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - + const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); - + expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); }); it('should sort posts by date in descending order', () => { - rssFeed(type, title, desc, outputPath); - + try { + rssFeed(type, title, desc, outputPath); + } catch (err) { + throw new Error('Error encountered during test execution:', err) + } + const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - + const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); - + expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); @@ -60,7 +72,11 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', () => { - rssFeed(type, title, desc, outputPath); + try { + rssFeed(type, title, desc, outputPath); + } catch (err) { + throw new Error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -75,9 +91,9 @@ describe('rssFeed', () => { it('should throw error when write operation fails', () => { const outputPath = "invalid/path" - try{ + try { rssFeed(type, title, desc, outputPath) - }catch(err){ + } catch (err) { expect(err.message).toMatch(/ENOENT|EACCES/); } }); From 5e98d501f076aeaed994f512709b24a5d29b50c6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 16 Sep 2024 22:58:37 +0530 Subject: [PATCH 16/43] removed try catch block --- tests/build-rss.test.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index ec2999692515..70ab30c2b6fc 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -22,11 +22,7 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', () => { - try { rssFeed(type, title, desc, outputPath); - } catch (err) { - throw new Error('Error encountered during test execution:', err) - } const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); @@ -36,11 +32,7 @@ describe('rssFeed', () => { }); it('should prioritize featured posts over non-featured ones', () => { - try { rssFeed(type, title, desc, outputPath); - } catch (err) { - throw new Error('Error encountered during test execution:', err) - } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -53,11 +45,7 @@ describe('rssFeed', () => { }); it('should sort posts by date in descending order', () => { - try { rssFeed(type, title, desc, outputPath); - } catch (err) { - throw new Error('Error encountered during test execution:', err) - } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -72,11 +60,7 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', () => { - try { rssFeed(type, title, desc, outputPath); - } catch (err) { - throw new Error('Error encountered during test execution:', err) - } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); From e6258c5a8259f873dff574376a4f5f92e0553cf6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 16 Sep 2024 23:01:48 +0530 Subject: [PATCH 17/43] replaced trown with console.error --- tests/build-rss.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 70ab30c2b6fc..df75db7c2f7b 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -22,7 +22,11 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', () => { + try { rssFeed(type, title, desc, outputPath); + } catch (err) { + console.error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); @@ -32,7 +36,11 @@ describe('rssFeed', () => { }); it('should prioritize featured posts over non-featured ones', () => { + try { rssFeed(type, title, desc, outputPath); + } catch (err) { + console.error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -45,7 +53,11 @@ describe('rssFeed', () => { }); it('should sort posts by date in descending order', () => { + try { rssFeed(type, title, desc, outputPath); + } catch (err) { + console.error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -60,7 +72,11 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', () => { + try { rssFeed(type, title, desc, outputPath); + } catch (err) { + console.error('Error encountered during test execution:', err) + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); From 7c9730f155b9d3db073c03d2d8116838f49500d6 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 16 Sep 2024 23:16:53 +0530 Subject: [PATCH 18/43] using promise for throwign errors --- scripts/build-rss.js | 105 +++++++++++++++++++++------------------- tests/build-rss.test.js | 39 +++++---------- 2 files changed, 65 insertions(+), 79 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index bdd26a5fbc89..e42165352640 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -16,62 +16,65 @@ function clean(s) { } module.exports = function rssFeed(type, title, desc, outputPath) { - try { - const posts = getAllPosts()[`${type}`] - .sort((i1, i2) => { - const i1Date = new Date(i1.date) - const i2Date = new Date(i2.date) - if (i1.featured && !i2.featured) return -1 - if (!i1.featured && i2.featured) return 1 - return i2Date - i1Date - }) + return new Promise((resolve, reject) => { + try { + const posts = getAllPosts()[`${type}`] + .sort((i1, i2) => { + const i1Date = new Date(i1.date) + const i2Date = new Date(i2.date) + if (i1.featured && !i2.featured) return -1 + if (!i1.featured && i2.featured) return 1 + return i2Date - i1Date + }) - const base = 'https://www.asyncapi.com' - const tracking = '?utm_source=rss'; + const base = 'https://www.asyncapi.com' + const tracking = '?utm_source=rss'; - const feed = {} - const rss = {} - rss['@version'] = '2.0' - rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' - rss.channel = {} - rss.channel.title = title - rss.channel.link = `${base}/${outputPath}` - rss.channel["atom:link"] = {} - rss.channel["atom:link"]["@rel"] = 'self' - rss.channel["atom:link"]["@href"] = rss.channel.link - rss.channel["atom:link"]["@type"] = 'application/rss+xml' - rss.channel.description = desc - rss.channel.language = 'en-gb'; - rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; - rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' - rss.channel.pubDate = new Date().toUTCString() - rss.channel.generator = 'next.js' - rss.channel.item = [] + const feed = {} + const rss = {} + rss['@version'] = '2.0' + rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' + rss.channel = {} + rss.channel.title = title + rss.channel.link = `${base}/${outputPath}` + rss.channel["atom:link"] = {} + rss.channel["atom:link"]["@rel"] = 'self' + rss.channel["atom:link"]["@href"] = rss.channel.link + rss.channel["atom:link"]["@type"] = 'application/rss+xml' + rss.channel.description = desc + rss.channel.language = 'en-gb'; + rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; + rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' + rss.channel.pubDate = new Date().toUTCString() + rss.channel.generator = 'next.js' + rss.channel.item = [] - for (let post of posts) { - const link = `${base}${post.slug}${tracking}`; - const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } - if (post.cover) { - const enclosure = {}; - enclosure["@url"] = base + post.cover; - enclosure["@length"] = 15026; // dummy value, anything works - enclosure["@type"] = 'image/jpeg'; - if (typeof enclosure["@url"] === 'string') { - let tmp = enclosure["@url"].toLowerCase(); - if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; - if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; - if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; + for (let post of posts) { + const link = `${base}${post.slug}${tracking}`; + const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } + if (post.cover) { + const enclosure = {}; + enclosure["@url"] = base + post.cover; + enclosure["@length"] = 15026; // dummy value, anything works + enclosure["@type"] = 'image/jpeg'; + if (typeof enclosure["@url"] === 'string') { + let tmp = enclosure["@url"].toLowerCase(); + if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; + if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; + if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; + } + item.enclosure = enclosure; } - item.enclosure = enclosure; + rss.channel.item.push(item) } - rss.channel.item.push(item) - } - feed.rss = rss + feed.rss = rss - const xml = json2xml.getXml(feed, '@', '', 2) - fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') - } catch (err) { - throw new Error(`Failed to generate RSS feed: ${err.message}`); - } + const xml = json2xml.getXml(feed, '@', '', 2) + fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') + resolve(`RSS feed generated successfully at ${outputPath}`); + } catch (err) { + reject(new Error(`Failed to generate RSS feed: ${err.message}`)); + } + }); }; diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index df75db7c2f7b..09e53c24482d 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -21,12 +21,8 @@ describe('rssFeed', () => { } }); - it('should generate RSS feed and write to file', () => { - try { - rssFeed(type, title, desc, outputPath); - } catch (err) { - console.error('Error encountered during test execution:', err) - } + it('should generate RSS feed and write to file', async () => { + await rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); @@ -35,12 +31,8 @@ describe('rssFeed', () => { expect(fileContent).toContain('<title>Test Blog RSS'); }); - it('should prioritize featured posts over non-featured ones', () => { - try { - rssFeed(type, title, desc, outputPath); - } catch (err) { - console.error('Error encountered during test execution:', err) - } + it('should prioritize featured posts over non-featured ones', async () => { + await rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -52,12 +44,8 @@ describe('rssFeed', () => { expect(itemTitles[3]).toContain('Non-Featured Post 1'); }); - it('should sort posts by date in descending order', () => { - try { - rssFeed(type, title, desc, outputPath); - } catch (err) { - console.error('Error encountered during test execution:', err) - } + it('should sort posts by date in descending order', async () => { + await rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -71,12 +59,8 @@ describe('rssFeed', () => { expect(itemTitles[5]).toContain('Non-Featured Post 2'); }); - it('should set correct enclosure type based on image extension', () => { - try { - rssFeed(type, title, desc, outputPath); - } catch (err) { - console.error('Error encountered during test execution:', err) - } + it('should set correct enclosure type based on image extension', async () => { + await rssFeed(type, title, desc, outputPath); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -89,13 +73,12 @@ describe('rssFeed', () => { expect(fileContent).toContain('type="image/webp"'); }); - it('should throw error when write operation fails', () => { - const outputPath = "invalid/path" + it('should catch and handle errors when write operation fails', async () => { + const invalidOutputPath = "invalid/path"; try { - rssFeed(type, title, desc, outputPath) + await rssFeed(type, title, desc, invalidOutputPath); } catch (err) { expect(err.message).toMatch(/ENOENT|EACCES/); } }); - }); From 6e9f0398fa09d622c970a18a4eef87e62502fa1f Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 16 Sep 2024 23:34:11 +0530 Subject: [PATCH 19/43] add error variable --- tests/build-rss.test.js | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 09e53c24482d..137bf643cbf0 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -22,36 +22,55 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', async () => { - await rssFeed(type, title, desc, outputPath); + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err + } const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); const fileContent = fs.readFileSync(filePath, 'utf8'); + + expect(error).toBeUndefined(); expect(fileContent).toContain('Test Blog RSS'); }); it('should prioritize featured posts over non-featured ones', async () => { - await rssFeed(type, title, desc, outputPath); + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); const itemTitles = fileContent.match(/(.*?)<\/title>/g); + expect(error).toBeUndefined(); expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); }); it('should sort posts by date in descending order', async () => { - await rssFeed(type, title, desc, outputPath); + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); + expect(error).toBeUndefined(); expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); @@ -60,11 +79,17 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', async () => { - await rssFeed(type, title, desc, outputPath); + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err + } const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(error).toBeUndefined(); 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"'); From aac6e1319ab3176572fc6ea59ee8abe2e8b203e0 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 16 Sep 2024 23:56:50 +0530 Subject: [PATCH 20/43] updated the test for rss --- tests/build-rss.test.js | 93 +++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 137bf643cbf0..777c384ef69f 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,18 +1,19 @@ const fs = require('fs'); const path = require('path'); const rssFeed = require('../scripts/build-rss'); -const { mockRssData, title, type, desc, outputPath } = require('./fixtures/rssData'); - -jest.mock('../config/posts.json', () => mockRssData, { virtual: true }); +const { mockRssData, title, type, desc } = require('./fixtures/rssData'); describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); + const outputPath = 'test-output/rss.xml'; - beforeEach(() => { - fs.mkdirSync(testOutputDir, { recursive: true }); + beforeAll(() => { + if (!fs.existsSync(testOutputDir)) { + fs.mkdirSync(testOutputDir, { recursive: true }); + } }); - afterEach(() => { + afterAll(() => { if (fs.existsSync(testOutputDir)) { fs.readdirSync(testOutputDir).forEach(file => { fs.unlinkSync(path.join(testOutputDir, file)); @@ -21,24 +22,30 @@ describe('rssFeed', () => { } }); + afterEach(() => { + jest.resetModules(); + }); + it('should generate RSS feed and write to file', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); + let error; try { await rssFeed(type, title, desc, outputPath); } catch (err) { - error = err + error = err; } + expect(error).toBeUndefined(); const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); const fileContent = fs.readFileSync(filePath, 'utf8'); - - expect(error).toBeUndefined(); expect(fileContent).toContain('<rss version="2.0"'); - expect(fileContent).toContain('<title>Test Blog RSS'); }); it('should prioritize featured posts over non-featured ones', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); + let error; try { await rssFeed(type, title, desc, outputPath); @@ -58,6 +65,8 @@ describe('rssFeed', () => { }); it('should sort posts by date in descending order', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); + let error; try { await rssFeed(type, title, desc, outputPath); @@ -79,6 +88,8 @@ describe('rssFeed', () => { }); it('should set correct enclosure type based on image extension', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); + let error; try { await rssFeed(type, title, desc, outputPath); @@ -99,11 +110,69 @@ describe('rssFeed', () => { }); it('should catch and handle errors when write operation fails', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); + const invalidOutputPath = "invalid/path"; + + let error; try { await rssFeed(type, title, desc, invalidOutputPath); } catch (err) { - expect(err.message).toMatch(/ENOENT|EACCES/); + error = err; + } + + expect(error.message).toMatch(/ENOENT|EACCES/); + }); + + it('should throw an error when posts.json is not found', async () => { + jest.doMock('../config/posts.json', () => { + throw new Error('Cannot find module'); + }, { virtual: true }); + + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err; + } + + expect(error).toBeDefined(); + expect(error.message).toContain('Failed to generate RSS feed'); + expect(error.message).toContain('Cannot find module'); + }); + + it('should throw an error when posts.json is malformed', async () => { + jest.doMock('../config/posts.json', () => { + return { invalidKey: [] }; + }, { virtual: true }); + + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err; + } + + expect(error).toBeDefined(); + expect(error.message).toContain('Failed to generate RSS feed'); + expect(error.message).toContain('Cannot read properties of undefined'); + }); + + it('should handle empty posts array', async () => { + const emptyMockData = { blog: [] }; + jest.doMock('../config/posts.json', () => emptyMockData, { virtual: true }); + + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err; } + + expect(error).toBeUndefined(); + const filePath = path.join(__dirname, '..', 'public', outputPath); + const fileContent = fs.readFileSync(filePath, 'utf8'); + expect(fileContent).toContain(''); }); -}); +}); \ No newline at end of file From e06fa474c74583f8f397dad26d1a4a422cf1a519 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 20 Sep 2024 15:22:31 +0530 Subject: [PATCH 21/43] updated test --- scripts/build-rss.js | 7 ++++++- tests/build-rss.test.js | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index e42165352640..99353b878e23 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -2,7 +2,11 @@ const fs = require('fs') const json2xml = require('jgexml/json2xml') function getAllPosts() { - return require('../config/posts.json') + try { + return require('../config/posts.json'); + } catch (err) { + throw new Error('Cannot find posts.json'); + } } function clean(s) { @@ -18,6 +22,7 @@ function clean(s) { module.exports = function rssFeed(type, title, desc, outputPath) { return new Promise((resolve, reject) => { try { + const posts = getAllPosts()[`${type}`] .sort((i1, i2) => { const i1Date = new Date(i1.date) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 777c384ef69f..30f323c74e6b 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -125,20 +125,24 @@ describe('rssFeed', () => { }); it('should throw an error when posts.json is not found', async () => { - jest.doMock('../config/posts.json', () => { - throw new Error('Cannot find module'); - }, { virtual: true }); - - let error; + const postsJsonPath = path.join(__dirname, '..', 'config', 'posts.json'); + const tempPath = path.join(__dirname, '..', 'config', 'posts.json.temp'); + + if (fs.existsSync(postsJsonPath)) { + fs.renameSync(postsJsonPath, tempPath); + } + try { await rssFeed(type, title, desc, outputPath); } catch (err) { - error = err; + expect(err.message).toContain('Failed to generate RSS feed'); + expect(err.message).toContain('Cannot find posts.json'); + } finally { + if (fs.existsSync(tempPath)) { + fs.renameSync(tempPath, postsJsonPath); + } } - - expect(error).toBeDefined(); - expect(error.message).toContain('Failed to generate RSS feed'); - expect(error.message).toContain('Cannot find module'); + }); it('should throw an error when posts.json is malformed', async () => { From 8c939979f55163d21cdb1ead5e5238cb9bcb266c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 23 Sep 2024 17:22:45 +0530 Subject: [PATCH 22/43] fwwfwf --- tests/build-rss.test.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 30f323c74e6b..19f1979a5e4d 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -124,27 +124,6 @@ describe('rssFeed', () => { expect(error.message).toMatch(/ENOENT|EACCES/); }); - it('should throw an error when posts.json is not found', async () => { - const postsJsonPath = path.join(__dirname, '..', 'config', 'posts.json'); - const tempPath = path.join(__dirname, '..', 'config', 'posts.json.temp'); - - if (fs.existsSync(postsJsonPath)) { - fs.renameSync(postsJsonPath, tempPath); - } - - try { - await rssFeed(type, title, desc, outputPath); - } catch (err) { - expect(err.message).toContain('Failed to generate RSS feed'); - expect(err.message).toContain('Cannot find posts.json'); - } finally { - if (fs.existsSync(tempPath)) { - fs.renameSync(tempPath, postsJsonPath); - } - } - - }); - it('should throw an error when posts.json is malformed', async () => { jest.doMock('../config/posts.json', () => { return { invalidKey: [] }; From 6e0b4ceeca15110fc4a4c9dee47ab397085e6f77 Mon Sep 17 00:00:00 2001 From: Ansh Goyal Date: Mon, 23 Sep 2024 12:30:09 +0000 Subject: [PATCH 23/43] revert getAllPosts func changes --- scripts/build-rss.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 99353b878e23..4e2cbad4cc8b 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -2,11 +2,7 @@ const fs = require('fs') const json2xml = require('jgexml/json2xml') function getAllPosts() { - try { - return require('../config/posts.json'); - } catch (err) { - throw new Error('Cannot find posts.json'); - } + return require('../config/posts.json'); } function clean(s) { From a51c36222b72997379882da5d605ee33ed1c52a3 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 28 Sep 2024 15:26:04 +0530 Subject: [PATCH 24/43] wsff --- scripts/build-rss.js | 13 ++++++++++++- tests/build-rss.test.js | 34 ++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 4e2cbad4cc8b..6a9e3d1279be 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -21,6 +21,9 @@ module.exports = function rssFeed(type, title, desc, outputPath) { const posts = getAllPosts()[`${type}`] .sort((i1, i2) => { + if (!i1.date || !i2.date) { + throw new Error('Missing date in post data'); + } const i1Date = new Date(i1.date) const i2Date = new Date(i2.date) if (i1.featured && !i2.featured) return -1 @@ -51,6 +54,9 @@ module.exports = function rssFeed(type, title, desc, outputPath) { rss.channel.item = [] for (let post of posts) { + if (!post.title || !post.slug || !post.excerpt || !post.date) { + throw new Error('Missing required fields in post data'); + } const link = `${base}${post.slug}${tracking}`; const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } if (post.cover) { @@ -71,7 +77,12 @@ module.exports = function rssFeed(type, title, desc, outputPath) { feed.rss = rss - const xml = json2xml.getXml(feed, '@', '', 2) + let xml; + try { + xml = json2xml.getXml(feed, '@', '', 2); + } catch (xmlError) { + throw new Error(`XML conversion error: ${xmlError.message}`); + } fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') resolve(`RSS feed generated successfully at ${outputPath}`); } catch (err) { diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 19f1979a5e4d..d35ae4f2c799 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -119,9 +119,8 @@ describe('rssFeed', () => { await rssFeed(type, title, desc, invalidOutputPath); } catch (err) { error = err; + expect(error.message).toMatch(/ENOENT|EACCES/); } - - expect(error.message).toMatch(/ENOENT|EACCES/); }); it('should throw an error when posts.json is malformed', async () => { @@ -134,11 +133,10 @@ describe('rssFeed', () => { await rssFeed(type, title, desc, outputPath); } catch (err) { error = err; + expect(error).toBeDefined(); + expect(error.message).toContain('Failed to generate RSS feed'); + expect(error.message).toContain('Cannot read properties of undefined'); } - - expect(error).toBeDefined(); - expect(error.message).toContain('Failed to generate RSS feed'); - expect(error.message).toContain('Cannot read properties of undefined'); }); it('should handle empty posts array', async () => { @@ -158,4 +156,28 @@ describe('rssFeed', () => { expect(fileContent).toContain(''); }); + + it('should throw an error when post is missing required fields', async () => { + const incompletePostMockData = { + blog: [ + { + slug: '/blog/incomplete-post', + excerpt: 'This post is incomplete', + date: '2024-07-05', + featured: false, + }, + ], + }; + jest.doMock('../config/posts.json', () => incompletePostMockData, { virtual: true }); + + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err; + expect(error).toBeDefined(); + expect(error.message).toContain('Missing required fields'); + } + }); + }); \ No newline at end of file From 4eb10e340b61524f9ff4240f44c492882045a21f Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 28 Sep 2024 15:33:03 +0530 Subject: [PATCH 25/43] fefe --- scripts/build-rss.js | 7 +------ tests/build-rss.test.js | 16 +++++++++++++++- tests/fixtures/rssData.js | 20 +++++++++++++++++++- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 6a9e3d1279be..05162769d72f 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -77,12 +77,7 @@ module.exports = function rssFeed(type, title, desc, outputPath) { feed.rss = rss - let xml; - try { - xml = json2xml.getXml(feed, '@', '', 2); - } catch (xmlError) { - throw new Error(`XML conversion error: ${xmlError.message}`); - } + const xml = json2xml.getXml(feed, '@', '', 2); fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') resolve(`RSS feed generated successfully at ${outputPath}`); } catch (err) { diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index d35ae4f2c799..3a5225f318c4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const rssFeed = require('../scripts/build-rss'); -const { mockRssData, title, type, desc } = require('./fixtures/rssData'); +const { mockRssData, title, type, desc, missingDateMockData } = require('./fixtures/rssData'); describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); @@ -180,4 +180,18 @@ describe('rssFeed', () => { } }); + it('should throw an error when a post is missing a date field during sorting', async () => { + + jest.doMock('../config/posts.json', () => missingDateMockData, { virtual: true }); + + let error; + try { + await rssFeed(type, title, desc, outputPath); + } catch (err) { + error = err; + expect(error).toBeDefined(); + expect(error.message).toContain('Missing date in post data'); + } + }); + }); \ No newline at end of file diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 963a621bf7de..61587128369e 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -42,9 +42,27 @@ const mockRssData = { ], }; +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 type = 'blog'; const title = 'Test Blog RSS'; const desc = 'Test blog RSS feed'; const outputPath = 'test-output/blog.xml'; -module.exports = { mockRssData, title, type, desc, outputPath }; +module.exports = { mockRssData, title, type, desc, outputPath, missingDateMockData }; From 4e75b0a516588023fc667967cecd8439a506ef61 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 28 Sep 2024 15:50:12 +0530 Subject: [PATCH 26/43] added test cases for errors --- tests/build-rss.test.js | 14 ++------------ tests/fixtures/rssData.js | 13 ++++++++++++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 3a5225f318c4..06e1eea51ed4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const rssFeed = require('../scripts/build-rss'); -const { mockRssData, title, type, desc, missingDateMockData } = require('./fixtures/rssData'); +const { mockRssData, title, type, desc, missingDateMockData, incompletePostMockData } = require('./fixtures/rssData'); describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); @@ -135,7 +135,6 @@ describe('rssFeed', () => { error = err; expect(error).toBeDefined(); expect(error.message).toContain('Failed to generate RSS feed'); - expect(error.message).toContain('Cannot read properties of undefined'); } }); @@ -158,16 +157,7 @@ describe('rssFeed', () => { }); it('should throw an error when post is missing required fields', async () => { - const incompletePostMockData = { - blog: [ - { - slug: '/blog/incomplete-post', - excerpt: 'This post is incomplete', - date: '2024-07-05', - featured: false, - }, - ], - }; + jest.doMock('../config/posts.json', () => incompletePostMockData, { virtual: true }); let error; diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 61587128369e..1c49f4430685 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -60,9 +60,20 @@ const missingDateMockData = { ], }; +const incompletePostMockData = { + blog: [ + { + slug: '/blog/incomplete-post', + excerpt: 'This post is incomplete', + date: '2024-07-05', + featured: false, + }, + ], +}; + const type = 'blog'; const title = 'Test Blog RSS'; const desc = 'Test blog RSS feed'; const outputPath = 'test-output/blog.xml'; -module.exports = { mockRssData, title, type, desc, outputPath, missingDateMockData }; +module.exports = { mockRssData, title, type, desc, outputPath, missingDateMockData, incompletePostMockData }; From d55f55313c5e603df69fb90c369a5ad4911245b0 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 7 Oct 2024 15:56:22 +0530 Subject: [PATCH 27/43] suggested changes applied --- scripts/build-rss.js | 136 +++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 62 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 05162769d72f..47ba14f4ffeb 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -1,4 +1,4 @@ -const fs = require('fs') +const fs = require('fs').promises const json2xml = require('jgexml/json2xml') function getAllPosts() { @@ -15,73 +15,85 @@ function clean(s) { return s } -module.exports = function rssFeed(type, title, desc, outputPath) { - return new Promise((resolve, reject) => { - try { +module.exports = async function rssFeed(type, title, desc, outputPath) { + try { - const posts = getAllPosts()[`${type}`] - .sort((i1, i2) => { - if (!i1.date || !i2.date) { - throw new Error('Missing date in post data'); - } - const i1Date = new Date(i1.date) - const i2Date = new Date(i2.date) - if (i1.featured && !i2.featured) return -1 - if (!i1.featured && i2.featured) return 1 - return i2Date - i1Date - }) + let posts = getAllPosts()[`${type}`] + posts = posts.filter(post => { + if (!post.date) { + return false; + } + return true; + }); + posts.sort((i1, i2) => { + const i1Date = new Date(i1.date) + const i2Date = new Date(i2.date) + if (i1.featured && !i2.featured) return -1 + if (!i1.featured && i2.featured) return 1 + return i2Date - i1Date + }) - const base = 'https://www.asyncapi.com' - const tracking = '?utm_source=rss'; + const base = 'https://www.asyncapi.com' + const tracking = '?utm_source=rss'; - const feed = {} - const rss = {} - rss['@version'] = '2.0' - rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' - rss.channel = {} - rss.channel.title = title - rss.channel.link = `${base}/${outputPath}` - rss.channel["atom:link"] = {} - rss.channel["atom:link"]["@rel"] = 'self' - rss.channel["atom:link"]["@href"] = rss.channel.link - rss.channel["atom:link"]["@type"] = 'application/rss+xml' - rss.channel.description = desc - rss.channel.language = 'en-gb'; - rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; - rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' - rss.channel.pubDate = new Date().toUTCString() - rss.channel.generator = 'next.js' - rss.channel.item = [] + const feed = {} + const rss = {} + rss['@version'] = '2.0' + rss["@xmlns:atom"] = 'http://www.w3.org/2005/Atom' + rss.channel = {} + rss.channel.title = title + rss.channel.link = `${base}/${outputPath}` + rss.channel["atom:link"] = {} + rss.channel["atom:link"]["@rel"] = 'self' + rss.channel["atom:link"]["@href"] = rss.channel.link + rss.channel["atom:link"]["@type"] = 'application/rss+xml' + rss.channel.description = desc + rss.channel.language = 'en-gb'; + rss.channel.copyright = 'Made with :love: by the AsyncAPI Initiative.'; + rss.channel.webMaster = 'info@asyncapi.io (AsyncAPI Initiative)' + rss.channel.pubDate = new Date().toUTCString() + rss.channel.generator = 'next.js' + rss.channel.item = [] - for (let post of posts) { - if (!post.title || !post.slug || !post.excerpt || !post.date) { - throw new Error('Missing required fields in post data'); - } - const link = `${base}${post.slug}${tracking}`; - const item = { title: post.title, description: clean(post.excerpt), link, category: type, guid: { '@isPermaLink': true, '': link }, pubDate: new Date(post.date).toUTCString() } - if (post.cover) { - const enclosure = {}; - enclosure["@url"] = base + post.cover; - enclosure["@length"] = 15026; // dummy value, anything works - enclosure["@type"] = 'image/jpeg'; - if (typeof enclosure["@url"] === 'string') { - let tmp = enclosure["@url"].toLowerCase(); - if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; - if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; - if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; - } - item.enclosure = enclosure; + for (let post of posts) { + if (!post.title || !post.slug || !post.excerpt || !post.date) { + throw new Error('Missing required fields in post data'); + } + const link = `${base}${post.slug}${tracking}`; + const { title, excerpt, date } = post; + const pubDate = new Date(date).toUTCString(); + const description = clean(excerpt); + const guid = { '@isPermaLink': true, '': link }; + const item = { + title, + description, + link, + category: type, + guid, + pubDate + }; + if (post.cover) { + const enclosure = {}; + enclosure["@url"] = base + post.cover; + enclosure["@length"] = 15026; // dummy value, anything works + enclosure["@type"] = 'image/jpeg'; + if (typeof enclosure["@url"] === 'string') { + let tmp = enclosure["@url"].toLowerCase(); + if (tmp.indexOf('.png') >= 0) enclosure["@type"] = 'image/png'; + if (tmp.indexOf('.svg') >= 0) enclosure["@type"] = 'image/svg+xml'; + if (tmp.indexOf('.webp') >= 0) enclosure["@type"] = 'image/webp'; } - rss.channel.item.push(item) + item.enclosure = enclosure; } + rss.channel.item.push(item) + } - feed.rss = rss + feed.rss = rss - const xml = json2xml.getXml(feed, '@', '', 2); - fs.writeFileSync(`./public/${outputPath}`, xml, 'utf8') - resolve(`RSS feed generated successfully at ${outputPath}`); - } catch (err) { - reject(new Error(`Failed to generate RSS feed: ${err.message}`)); - } - }); + const xml = json2xml.getXml(feed, '@', '', 2); + await fs.writeFile(`./public/${outputPath}`, xml, 'utf8'); + return `RSS feed generated successfully at ${outputPath}`; + } catch (err) { + throw new Error(`Failed to generate RSS feed: ${err.message}`); + } }; From d5b6882aeb415a0b163037252184f57194b9e857 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 13 Oct 2024 23:06:06 +0530 Subject: [PATCH 28/43] empty line at end --- tests/build-rss.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 06e1eea51ed4..fc65446dfb49 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -183,5 +183,4 @@ describe('rssFeed', () => { expect(error.message).toContain('Missing date in post data'); } }); - -}); \ No newline at end of file +}); From 49f308adc4474e7887253bd741a9e8b6306ae740 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 17 Oct 2024 11:12:34 +0530 Subject: [PATCH 29/43] replaced throw with promise.reject --- scripts/build-rss.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 47ba14f4ffeb..284236cf0568 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -57,7 +57,7 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { for (let post of posts) { if (!post.title || !post.slug || !post.excerpt || !post.date) { - throw new Error('Missing required fields in post data'); + return Promise.reject(new Error('Missing required fields in post data')); } const link = `${base}${post.slug}${tracking}`; const { title, excerpt, date } = post; @@ -94,6 +94,6 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { await fs.writeFile(`./public/${outputPath}`, xml, 'utf8'); return `RSS feed generated successfully at ${outputPath}`; } catch (err) { - throw new Error(`Failed to generate RSS feed: ${err.message}`); + return Promise.reject(new Error(`Failed to generate RSS feed: ${err.message}`)); } }; From 8a55fa29d86a4430a4fd05da0e0e3ab9d8a45e07 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 23 Oct 2024 16:08:43 +0530 Subject: [PATCH 30/43] test updated --- scripts/build-rss.js | 24 ++++++++++++------------ tests/build-rss.test.js | 19 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 284236cf0568..8add4b2aac10 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -19,19 +19,19 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { try { let posts = getAllPosts()[`${type}`] - posts = posts.filter(post => { - if (!post.date) { - return false; - } - return true; - }); + const missingDatePosts = posts.filter(post => !post.date); + posts = posts.filter(post => post.date); posts.sort((i1, i2) => { - const i1Date = new Date(i1.date) - const i2Date = new Date(i2.date) - if (i1.featured && !i2.featured) return -1 - if (!i1.featured && i2.featured) return 1 - return i2Date - i1Date - }) + const i1Date = new Date(i1.date); + const i2Date = new Date(i2.date); + if (i1.featured && !i2.featured) return -1; + if (!i1.featured && i2.featured) return 1; + return i2Date - i1Date; + }); + + if (missingDatePosts.length > 0) { + return Promise.reject(new Error('Missing date in post data')); + } const base = 'https://www.asyncapi.com' const tracking = '?utm_source=rss'; diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index fc65446dfb49..b3e4437e05f1 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -31,7 +31,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); } catch (err) { error = err; } @@ -48,7 +48,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); } catch (err) { error = err } @@ -69,7 +69,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); } catch (err) { error = err } @@ -92,7 +92,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); } catch (err) { error = err } @@ -116,7 +116,8 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, invalidOutputPath); + await expect(rssFeed(type, title, desc, invalidOutputPath)) + .rejects.toThrow(/ENOENT|EACCES/); } catch (err) { error = err; expect(error.message).toMatch(/ENOENT|EACCES/); @@ -130,7 +131,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed'); } catch (err) { error = err; expect(error).toBeDefined(); @@ -144,7 +145,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); } catch (err) { error = err; } @@ -162,7 +163,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing required fields'); } catch (err) { error = err; expect(error).toBeDefined(); @@ -176,7 +177,7 @@ describe('rssFeed', () => { let error; try { - await rssFeed(type, title, desc, outputPath); + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing date in post data'); } catch (err) { error = err; expect(error).toBeDefined(); From 2ee9f6fc9df744f66727c483f5b100d9698deb89 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 23 Oct 2024 16:19:43 +0530 Subject: [PATCH 31/43] test updted --- scripts/build-rss.js | 1 - tests/build-rss.test.js | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 8add4b2aac10..d238034f6065 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -92,7 +92,6 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { const xml = json2xml.getXml(feed, '@', '', 2); await fs.writeFile(`./public/${outputPath}`, xml, 'utf8'); - return `RSS feed generated successfully at ${outputPath}`; } catch (err) { return Promise.reject(new Error(`Failed to generate RSS feed: ${err.message}`)); } diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index b3e4437e05f1..1f7cca50930f 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -31,7 +31,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() } catch (err) { error = err; } @@ -48,7 +48,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() } catch (err) { error = err } @@ -69,7 +69,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() } catch (err) { error = err } @@ -92,7 +92,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() } catch (err) { error = err } @@ -145,7 +145,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.not.toThrow(); + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() } catch (err) { error = err; } From 6804d6ef6609b66afcc5a18f743b7dc76ab09315 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 23 Oct 2024 16:24:26 +0530 Subject: [PATCH 32/43] rwwq --- tests/build-rss.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 1f7cca50930f..953b9da2badb 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -116,8 +116,7 @@ describe('rssFeed', () => { let error; try { - await expect(rssFeed(type, title, desc, invalidOutputPath)) - .rejects.toThrow(/ENOENT|EACCES/); + await expect(rssFeed(type, title, desc, invalidOutputPath)).rejects.toThrow(/ENOENT|EACCES/); } catch (err) { error = err; expect(error.message).toMatch(/ENOENT|EACCES/); From fd0bb077d6a7e6ff2f8e98683c87abe0ea8bc6f3 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 23 Oct 2024 16:32:29 +0530 Subject: [PATCH 33/43] removed try/catch --- tests/build-rss.test.js | 80 ++++++++--------------------------------- 1 file changed, 14 insertions(+), 66 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 953b9da2badb..91d1de409358 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -29,14 +29,8 @@ describe('rssFeed', () => { it('should generate RSS feed and write to file', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - } catch (err) { - error = err; - } + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - expect(error).toBeUndefined(); const filePath = path.join(__dirname, '..', 'public', outputPath); expect(fs.existsSync(filePath)).toBe(true); const fileContent = fs.readFileSync(filePath, 'utf8'); @@ -46,19 +40,14 @@ describe('rssFeed', () => { it('should prioritize featured posts over non-featured ones', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - } catch (err) { - error = err - } + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() + const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); const itemTitles = fileContent.match(/(.*?)<\/title>/g); - expect(error).toBeUndefined(); expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); @@ -67,19 +56,13 @@ describe('rssFeed', () => { it('should sort posts by date in descending order', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - } catch (err) { - error = err - } + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); - expect(error).toBeUndefined(); expect(itemTitles[1]).toContain('Test Post 1'); expect(itemTitles[2]).toContain('Another Featured Post'); expect(itemTitles[3]).toContain('Non-Featured Post 1'); @@ -90,17 +73,11 @@ describe('rssFeed', () => { it('should set correct enclosure type based on image extension', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - } catch (err) { - error = err - } + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - expect(error).toBeUndefined(); 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"'); @@ -114,13 +91,8 @@ describe('rssFeed', () => { const invalidOutputPath = "invalid/path"; - let error; - try { - await expect(rssFeed(type, title, desc, invalidOutputPath)).rejects.toThrow(/ENOENT|EACCES/); - } catch (err) { - error = err; - expect(error.message).toMatch(/ENOENT|EACCES/); - } + await expect(rssFeed(type, title, desc, invalidOutputPath)).rejects.toThrow(/ENOENT|EACCES/); + }); it('should throw an error when posts.json is malformed', async () => { @@ -128,28 +100,16 @@ describe('rssFeed', () => { return { invalidKey: [] }; }, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed'); - } catch (err) { - error = err; - expect(error).toBeDefined(); - expect(error.message).toContain('Failed to generate RSS feed'); - } + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed'); + }); it('should handle empty posts array', async () => { const emptyMockData = { blog: [] }; jest.doMock('../config/posts.json', () => emptyMockData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - } catch (err) { - error = err; - } + await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - expect(error).toBeUndefined(); const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); expect(fileContent).toContain('<rss version="2.0"'); @@ -160,27 +120,15 @@ describe('rssFeed', () => { jest.doMock('../config/posts.json', () => incompletePostMockData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing required fields'); - } catch (err) { - error = err; - expect(error).toBeDefined(); - expect(error.message).toContain('Missing required fields'); - } + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing required fields'); + }); it('should throw an error when a post is missing a date field during sorting', async () => { jest.doMock('../config/posts.json', () => missingDateMockData, { virtual: true }); - let error; - try { - await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing date in post data'); - } catch (err) { - error = err; - expect(error).toBeDefined(); - expect(error.message).toContain('Missing date in post data'); - } + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing date in post data'); + }); }); From a3dfa93ced24240892eb31840675ef36446dd4e8 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Sun, 27 Oct 2024 21:41:45 +0530 Subject: [PATCH 34/43] fef --- scripts/build-rss.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index d238034f6065..c05d14a71a97 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -56,7 +56,10 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { rss.channel.item = [] for (let post of posts) { - if (!post.title || !post.slug || !post.excerpt || !post.date) { + const invalidPosts = posts.filter(post => + !post.title || !post.slug || !post.excerpt || !post.date + ); + if (invalidPosts.length > 0) { return Promise.reject(new Error('Missing required fields in post data')); } const link = `${base}${post.slug}${tracking}`; From 2312a5730c407edf6377a073c021fea91b814abf Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 15:39:33 +0530 Subject: [PATCH 35/43] replaced promise.reject with throw --- scripts/build-rss.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index c05d14a71a97..444580c344a0 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -30,7 +30,7 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { }); if (missingDatePosts.length > 0) { - return Promise.reject(new Error('Missing date in post data')); + throw new Error('Missing date in post data'); } const base = 'https://www.asyncapi.com' @@ -60,7 +60,7 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { !post.title || !post.slug || !post.excerpt || !post.date ); if (invalidPosts.length > 0) { - return Promise.reject(new Error('Missing required fields in post data')); + throw new Error('Missing required fields in post data'); } const link = `${base}${post.slug}${tracking}`; const { title, excerpt, date } = post; @@ -96,6 +96,6 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { const xml = json2xml.getXml(feed, '@', '', 2); await fs.writeFile(`./public/${outputPath}`, xml, 'utf8'); } catch (err) { - return Promise.reject(new Error(`Failed to generate RSS feed: ${err.message}`)); + throw new Error(`Failed to generate RSS feed: ${err.message}`); } }; From d77cf7a9cf538dc208b1a3eebccdadcdefb60d56 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 15:57:44 +0530 Subject: [PATCH 36/43] fewgge --- scripts/build-rss.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 444580c344a0..17bb4380d2ab 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -55,13 +55,15 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { rss.channel.generator = 'next.js' rss.channel.item = [] + const invalidPosts = posts.filter(post => + !post.title || !post.slug || !post.excerpt || !post.date + ); + + if (invalidPosts.length > 0) { + throw new Error('Missing required fields in post data'); + } + for (let post of posts) { - const invalidPosts = posts.filter(post => - !post.title || !post.slug || !post.excerpt || !post.date - ); - if (invalidPosts.length > 0) { - throw new Error('Missing required fields in post data'); - } const link = `${base}${post.slug}${tracking}`; const { title, excerpt, date } = post; const pubDate = new Date(date).toUTCString(); From bc76d4be0e327d0c5932a4c22f23a86b2958f401 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 17:12:07 +0530 Subject: [PATCH 37/43] fegewg --- scripts/build-rss.js | 6 +++--- tests/build-rss.test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 17bb4380d2ab..933ec63d69d1 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -30,7 +30,7 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { }); if (missingDatePosts.length > 0) { - throw new Error('Missing date in post data'); + throw new Error(`Missing date in posts: ${missingDatePosts.map(p => p.title || p.slug).join(', ')}`); } const base = 'https://www.asyncapi.com' @@ -55,10 +55,10 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { rss.channel.generator = 'next.js' rss.channel.item = [] - const invalidPosts = posts.filter(post => + const invalidPosts = posts.filter(post => !post.title || !post.slug || !post.excerpt || !post.date ); - + if (invalidPosts.length > 0) { throw new Error('Missing required fields in post data'); } diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 91d1de409358..6f07c966afab 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -128,7 +128,7 @@ describe('rssFeed', () => { jest.doMock('../config/posts.json', () => missingDateMockData, { virtual: true }); - await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Missing date in post data'); + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed: Missing date in posts: Post without Date'); }); }); From 5407af07bac31e6542bf582e060ff42428a56f16 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 18:14:06 +0530 Subject: [PATCH 38/43] updated before and after block --- tests/build-rss.test.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 6f07c966afab..367e196ad022 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -7,18 +7,21 @@ describe('rssFeed', () => { const testOutputDir = path.join(__dirname, '..', 'public', 'test-output'); const outputPath = 'test-output/rss.xml'; - beforeAll(() => { - if (!fs.existsSync(testOutputDir)) { - fs.mkdirSync(testOutputDir, { recursive: true }); + beforeAll(async () => { + try { + await fs.promises.mkdir(testOutputDir, { recursive: true }); + } catch (err) { + throw new Error(`Error while creating temp dir: ${err.message}`); } }); - 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) { + throw new Error(`Error while deleting temp dir: ${err.message}`); } }); @@ -125,9 +128,9 @@ describe('rssFeed', () => { }); it('should throw an error when a post is missing a date field during sorting', async () => { - + jest.doMock('../config/posts.json', () => missingDateMockData, { virtual: true }); - + await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed: Missing date in posts: Post without Date'); }); From fb49686501ba6660339a3f0724d9ab65cac0ca0e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 18:29:42 +0530 Subject: [PATCH 39/43] fewgfew --- package-lock.json | 29 +++++++++++++++++++++++++++++ package.json | 1 + scripts/build-rss.js | 2 +- tests/build-rss.test.js | 24 ++++++++++++++---------- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 837177c7acf7..afff3d9c026d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "clsx": "^2.1.0", "cssnano": "^6.0.3", "dotenv": "^16.4.4", + "fast-xml-parser": "^4.5.0", "fs-extra": "^11.2.0", "fuse.js": "^7.0.0", "googleapis": "^133.0.0", @@ -13859,6 +13860,28 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -27471,6 +27494,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT" + }, "node_modules/style-loader": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", diff --git a/package.json b/package.json index 3885874ae365..6af7ec597c27 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "clsx": "^2.1.0", "cssnano": "^6.0.3", "dotenv": "^16.4.4", + "fast-xml-parser": "^4.5.0", "fs-extra": "^11.2.0", "fuse.js": "^7.0.0", "googleapis": "^133.0.0", diff --git a/scripts/build-rss.js b/scripts/build-rss.js index 933ec63d69d1..673da1398fe0 100644 --- a/scripts/build-rss.js +++ b/scripts/build-rss.js @@ -60,7 +60,7 @@ module.exports = async function rssFeed(type, title, desc, outputPath) { ); 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(', ')}`); } for (let post of posts) { diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 367e196ad022..8468bf3365a4 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -1,6 +1,8 @@ const fs = require('fs'); const path = require('path'); 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'); describe('rssFeed', () => { @@ -49,11 +51,12 @@ describe('rssFeed', () => { const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); + const parsedContent = parser.parse(fileContent); + const itemTitles = parsedContent.rss.channel.item.map(item => item.title); - expect(itemTitles[1]).toContain('Test Post 1'); - expect(itemTitles[2]).toContain('Another Featured Post'); - expect(itemTitles[3]).toContain('Non-Featured Post 1'); + expect(itemTitles[0]).toContain('Test Post 1'); + expect(itemTitles[1]).toContain('Another Featured Post'); + expect(itemTitles[2]).toContain('Non-Featured Post 1'); }); it('should sort posts by date in descending order', async () => { @@ -64,13 +67,14 @@ describe('rssFeed', () => { const filePath = path.join(__dirname, '..', 'public', outputPath); const fileContent = fs.readFileSync(filePath, 'utf8'); - const itemTitles = fileContent.match(/<title>(.*?)<\/title>/g); + const parsedContent = parser.parse(fileContent); + const itemTitles = parsedContent.rss.channel.item.map(item => item.title); - expect(itemTitles[1]).toContain('Test Post 1'); - expect(itemTitles[2]).toContain('Another Featured Post'); - expect(itemTitles[3]).toContain('Non-Featured Post 1'); - expect(itemTitles[4]).toContain('Non-Featured Post 3'); - expect(itemTitles[5]).toContain('Non-Featured Post 2'); + expect(itemTitles[0]).toContain('Test Post 1'); + expect(itemTitles[1]).toContain('Another Featured Post'); + expect(itemTitles[2]).toContain('Non-Featured Post 1'); + expect(itemTitles[3]).toContain('Non-Featured Post 3'); + expect(itemTitles[4]).toContain('Non-Featured Post 2'); }); it('should set correct enclosure type based on image extension', async () => { From 1d13e0bc0c73a48df68412c09d80c6ccffb8eee2 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 1 Nov 2024 18:38:49 +0530 Subject: [PATCH 40/43] fixtures updated --- tests/build-rss.test.js | 44 +++++++++++++++++++++------------------ tests/fixtures/rssData.js | 24 ++++++++++++++++----- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 8468bf3365a4..67e042252f00 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -44,37 +44,41 @@ describe('rssFeed', () => { it('should prioritize featured posts over non-featured ones', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - - + + 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 itemTitles = parsedContent.rss.channel.item.map(item => item.title); - - expect(itemTitles[0]).toContain('Test Post 1'); - expect(itemTitles[1]).toContain('Another Featured Post'); - expect(itemTitles[2]).toContain('Non-Featured Post 1'); + + expect(itemTitles[0]).toBe('Test Post 1'); + expect(itemTitles[1]).toBe('Another Featured Post'); + + expect(itemTitles[2]).toBe('Post with Special Characters: & < > "'); + expect(itemTitles[3]).toBe('Post with UTC Date Format'); + expect(itemTitles[4]).toBe('Non-Featured Post 1'); + expect(itemTitles[5]).toBe('Non-Featured Post 3'); }); - + it('should sort posts by date in descending order', async () => { jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); - - await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() - + + 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 itemTitles = parsedContent.rss.channel.item.map(item => item.title); - - expect(itemTitles[0]).toContain('Test Post 1'); - expect(itemTitles[1]).toContain('Another Featured Post'); - expect(itemTitles[2]).toContain('Non-Featured Post 1'); - expect(itemTitles[3]).toContain('Non-Featured Post 3'); - expect(itemTitles[4]).toContain('Non-Featured Post 2'); + + expect(itemTitles[0]).toBe('Test Post 1'); + expect(itemTitles[1]).toBe('Another Featured Post') + expect(itemTitles[2]).toBe('Post with Special Characters: & < > "'); + expect(itemTitles[3]).toBe('Post with UTC Date Format'); + expect(itemTitles[4]).toBe('Non-Featured Post 1'); + expect(itemTitles[5]).toBe('Non-Featured Post 3'); }); it('should set correct enclosure type based on image extension', async () => { diff --git a/tests/fixtures/rssData.js b/tests/fixtures/rssData.js index 1c49f4430685..89717784e51b 100644 --- a/tests/fixtures/rssData.js +++ b/tests/fixtures/rssData.js @@ -4,14 +4,14 @@ const mockRssData = { 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: 'Test Post 1', slug: '/blog/test-post-1', excerpt: 'This is a featured test post', - date: '2024-07-07', + date: '2023-07-07', featured: true, cover: '/img/test-cover.jpg', }, @@ -19,7 +19,7 @@ const mockRssData = { title: 'Another Featured Post', slug: '/blog/another-featured-post', excerpt: 'This is another featured post', - date: '2024-07-06', + date: '2023-07-06', featured: true, cover: '/img/test-cover.svg', }, @@ -27,7 +27,7 @@ const mockRssData = { title: 'Non-Featured Post 2', slug: '/blog/non-featured-post-2', excerpt: 'This is another non-featured post', - date: '2024-07-03', + date: '2023-07-03', featured: false, cover: '/img/test-cover.webp', }, @@ -35,10 +35,24 @@ const mockRssData = { title: 'Non-Featured Post 3', slug: '/blog/non-featured-post-3', excerpt: 'This is yet another non-featured post', - date: '2024-07-04', + 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, + }, ], }; From 51fc2a310d9d8e0d142f6c7c61d0df0775af03fd Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 4 Nov 2024 22:44:09 +0530 Subject: [PATCH 41/43] move package to dev dep --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6af7ec597c27..84f538697d4d 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "clsx": "^2.1.0", "cssnano": "^6.0.3", "dotenv": "^16.4.4", - "fast-xml-parser": "^4.5.0", "fs-extra": "^11.2.0", "fuse.js": "^7.0.0", "googleapis": "^133.0.0", @@ -158,6 +157,7 @@ "remark-cli": "^12.0.1", "remark-lint": "^10.0.0", "remark-mdx": "^3.0.1", - "storybook": "^8.2.4" + "storybook": "^8.2.4", + "fast-xml-parser": "^4.5.0" } } From 9e166aec858b31967fd1717dbca3ff0cb1ae4287 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Mon, 4 Nov 2024 22:50:37 +0530 Subject: [PATCH 42/43] fqefq --- tests/build-rss.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index 67e042252f00..c5fde68e2ab3 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -32,6 +32,7 @@ describe('rssFeed', () => { }); it('should generate RSS feed and write to file', async () => { + jest.doMock('../config/posts.json', () => mockRssData, { virtual: true }); await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined() From 8d0ff17edf880231bd9de9a59750bbec686f4c44 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela <vaghelavishvamsinh11111@gmail.com> Date: Fri, 8 Nov 2024 12:16:15 +0530 Subject: [PATCH 43/43] eqfe --- tests/build-rss.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/build-rss.test.js b/tests/build-rss.test.js index c5fde68e2ab3..7961740fe5c6 100644 --- a/tests/build-rss.test.js +++ b/tests/build-rss.test.js @@ -143,4 +143,5 @@ describe('rssFeed', () => { await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed: Missing date in posts: Post without Date'); }); + });