Skip to content

Commit

Permalink
fixture updated
Browse files Browse the repository at this point in the history
  • Loading branch information
vishvamsinh28 committed Nov 4, 2024
1 parent 3837d4b commit db84460
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 175 deletions.
135 changes: 49 additions & 86 deletions tests/build-rss.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,37 @@ 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');
const { createMockData } = require('./fixtures/rssData');

describe('rssFeed', () => {
const testOutputDir = path.join(__dirname, '..', 'public', 'test-output');
const outputPath = 'test-output/rss.xml';

beforeAll(async () => {
try {
await fs.promises.mkdir(testOutputDir, { recursive: true });
} catch (err) {
throw new Error(`Error while creating temp dir: ${err.message}`);
}
await fs.promises.mkdir(testOutputDir, { recursive: true });
});

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}`);
}
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);
});

afterEach(() => {
jest.resetModules();
});

it('should generate RSS feed and write to file', async () => {
jest.doMock('../config/posts.json', () => mockRssData, { virtual: true });
const mockData = createMockData({
blogPosts: [
{ title: 'Featured Post 1', slug: '/blog/featured-post-1', date: '2023-07-05', featured: true, cover: '/img/cover1.jpg' },
{ title: 'Non-Featured Post 1', slug: '/blog/non-featured-post-1', date: '2023-07-04', featured: false },
],
});

await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined()
jest.doMock('../config/posts.json', () => mockData, { virtual: true });

await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).resolves.toBeUndefined();

const filePath = path.join(__dirname, '..', 'public', outputPath);
expect(fs.existsSync(filePath)).toBe(true);
Expand All @@ -43,83 +42,51 @@ 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();

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]).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();

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]).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');
});
const mockData = createMockData({
blogPosts: [
{ title: 'Non-Featured Post 1', slug: '/blog/non-featured-post-1', date: '2023-07-04', featured: false },
{ title: 'Featured Post 1', slug: '/blog/featured-post-1', date: '2023-07-05', featured: true },
],
});

it('should set correct enclosure type based on image extension', async () => {
jest.doMock('../config/posts.json', () => mockRssData, { virtual: true });
jest.doMock('../config/posts.json', () => mockData, { virtual: true });

await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined()
await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).resolves.toBeUndefined();

const filePath = path.join(__dirname, '..', 'public', outputPath);
const fileContent = fs.readFileSync(filePath, 'utf8');
const parsedContent = parser.parse(fileContent);
const itemTitles = parsedContent.rss.channel.item.map(item => item.title);

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"');
expect(itemTitles[0]).toBe('Featured Post 1');
});

it('should catch and handle errors when write operation fails', async () => {
jest.doMock('../config/posts.json', () => mockRssData, { virtual: true });

const invalidOutputPath = "invalid/path";

await expect(rssFeed(type, title, desc, invalidOutputPath)).rejects.toThrow(/ENOENT|EACCES/);
it('should sort posts by date in descending order', async () => {
const mockData = createMockData({
blogPosts: [
{ title: 'Post with Newer Date', slug: '/blog/newer-date', date: '2023-07-06', featured: false },
{ title: 'Post with Older Date', slug: '/blog/older-date', date: '2023-07-04', featured: false },
],
});

});
jest.doMock('../config/posts.json', () => mockData, { virtual: true });

it('should throw an error when posts.json is malformed', async () => {
jest.doMock('../config/posts.json', () => {
return { invalidKey: [] };
}, { virtual: true });
await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).resolves.toBeUndefined();

await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed');
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]).toBe('Post with Newer Date');
expect(itemTitles[1]).toBe('Post with Older Date');
});

it('should handle empty posts array', async () => {
const emptyMockData = { blog: [] };
const emptyMockData = createMockData({ blogPosts: [] });
jest.doMock('../config/posts.json', () => emptyMockData, { virtual: true });

await expect(rssFeed(type, title, desc, outputPath)).resolves.toBeUndefined()
await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).resolves.toBeUndefined();

const filePath = path.join(__dirname, '..', 'public', outputPath);
const fileContent = fs.readFileSync(filePath, 'utf8');
Expand All @@ -128,18 +95,14 @@ describe('rssFeed', () => {
});

it('should throw an error when post is missing required fields', async () => {
const mockData = createMockData({
blogPosts: [
{ slug: '/blog/incomplete-post', date: '2024-07-05', featured: false },
],
}, false);

jest.doMock('../config/posts.json', () => incompletePostMockData, { virtual: true });

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 });

await expect(rssFeed(type, title, desc, outputPath)).rejects.toThrow('Failed to generate RSS feed: Missing date in posts: Post without Date');
jest.doMock('../config/posts.json', () => mockData, { virtual: true });

await expect(rssFeed('blog', 'Test Blog RSS', 'Test blog RSS feed', outputPath)).rejects.toThrow('Missing required fields');
});
});
125 changes: 36 additions & 89 deletions tests/fixtures/rssData.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,40 @@
const mockRssData = {
blog: [
{
title: 'Non-Featured Post 1',
slug: '/blog/non-featured-post-1',
excerpt: 'This is a non-featured post',
date: '2023-07-05',
featured: false,
},
{
title: 'Test Post 1',
slug: '/blog/test-post-1',
excerpt: 'This is a featured test post',
date: '2023-07-07',
featured: true,
cover: '/img/test-cover.jpg',
},
{
title: 'Another Featured Post',
slug: '/blog/another-featured-post',
excerpt: 'This is another featured post',
date: '2023-07-06',
featured: true,
cover: '/img/test-cover.svg',
},
{
title: 'Non-Featured Post 2',
slug: '/blog/non-featured-post-2',
excerpt: 'This is another non-featured post',
date: '2023-07-03',
featured: false,
cover: '/img/test-cover.webp',
},
{
title: 'Non-Featured Post 3',
slug: '/blog/non-featured-post-3',
excerpt: 'This is yet another non-featured post',
date: '2023-07-04',
featured: false,
cover: '/img/test-cover.png',
},
{
title: 'Post with Special Characters: & < > "',
slug: '/blog/special-chars',
excerpt: 'Testing HTML entities & encoding',
date: '2023-07-06T12:00:00Z',
featured: false,
},
{
title: 'Post with UTC Date Format',
slug: '/blog/utc-date-format',
excerpt: 'This post uses a UTC date format',
date: 'Wed, 05 Jul 2023 12:00:00 GMT',
featured: false,
},
],
};
function createMockPost({
title,
slug,
excerpt,
date,
featured,
cover,
} = {}, useDefaults = true) {
const post = {};

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,
},
],
};
if (useDefaults) {
post.title = title ?? 'Default Post Title';
post.slug = slug ?? '/blog/default-post';
post.excerpt = excerpt ?? 'This is a default excerpt';
post.date = date ?? new Date().toISOString();
post.featured = featured ?? false;
} else {
if (title !== undefined) post.title = title;
if (slug !== undefined) post.slug = slug;
if (excerpt !== undefined) post.excerpt = excerpt;
if (date !== undefined) post.date = date;
if (featured !== undefined) post.featured = featured;
}

const incompletePostMockData = {
blog: [
{
slug: '/blog/incomplete-post',
excerpt: 'This post is incomplete',
date: '2024-07-05',
featured: false,
},
],
};
if (cover !== undefined) post.cover = cover;
return post;
}

const type = 'blog';
const title = 'Test Blog RSS';
const desc = 'Test blog RSS feed';
const outputPath = 'test-output/blog.xml';
function createMockData({
blogPosts = [],
} = {}, useDefaults = true) {
return {
blog: blogPosts.map(post => createMockPost(post, useDefaults)),
};
}

module.exports = { mockRssData, title, type, desc, outputPath, missingDateMockData, incompletePostMockData };
module.exports = {
createMockPost,
createMockData,
};

0 comments on commit db84460

Please sign in to comment.