aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-11-30 13:12:45 +0100
committerArmand Philippot <git@armandphilippot.com>2023-11-30 14:54:06 +0100
commitf7e6f42216c3cbeab9add475a61bb407c6be3519 (patch)
tree6c02d5aaaf794af1e1aadd2e3b46aac5b2c57b93 /src/utils
parent9c6265b33a7bb31936e3c9d6dcf415e11a6db752 (diff)
refactor(pages): refine RSS feed
* add favicon * add item categories * add item image * add item author * add item update date (it seems `date` is used as update date by Feed) * change copyright format * fix ESlint errors * fix atom and json links
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/helpers/rss.test.ts35
-rw-r--r--src/utils/helpers/rss.ts31
2 files changed, 59 insertions, 7 deletions
diff --git a/src/utils/helpers/rss.test.ts b/src/utils/helpers/rss.test.ts
new file mode 100644
index 0000000..b04f6d3
--- /dev/null
+++ b/src/utils/helpers/rss.test.ts
@@ -0,0 +1,35 @@
+import { describe, expect, it } from '@jest/globals';
+import { CONFIG } from '../config';
+import { ROUTES } from '../constants';
+import { generateFeed } from './rss';
+
+describe('generate-feed', () => {
+ /* eslint-disable max-statements */
+ it('generates a rss feed', async () => {
+ const feed = await generateFeed();
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(10);
+
+ expect(feed.options.author).toStrictEqual({
+ name: CONFIG.name,
+ email: process.env.APP_AUTHOR_EMAIL,
+ link: CONFIG.url,
+ });
+ expect(feed.options.copyright).toBe(
+ `\u00A9 ${CONFIG.copyright.startYear} - ${CONFIG.copyright.endYear} ${CONFIG.name} - CC BY SA`
+ );
+ expect(feed.options.description).toBe(process.env.APP_FEED_DESCRIPTION);
+ expect(feed.options.favicon).toBe(`${CONFIG.url}/favicon.ico`);
+ expect(feed.options.feedLinks).toStrictEqual({
+ json: `${CONFIG.url}${ROUTES.RSS}.json`,
+ atom: `${CONFIG.url}${ROUTES.RSS}/atom`,
+ });
+ expect(feed.options.generator).toBe('Feed & NextJS');
+ expect(feed.options.language).toBe(CONFIG.locales.defaultLocale);
+ expect(feed.options.link).toBe(CONFIG.url);
+ expect(feed.options.title).toBe(`${CONFIG.name} | ${CONFIG.baseline}`);
+ expect(feed.items.length).toBeGreaterThan(0);
+ });
+ /* eslint-enable max-statements */
+});
diff --git a/src/utils/helpers/rss.ts b/src/utils/helpers/rss.ts
index 82fa1ee..9e98a38 100644
--- a/src/utils/helpers/rss.ts
+++ b/src/utils/helpers/rss.ts
@@ -11,7 +11,7 @@ import { ROUTES } from '../constants';
/**
* Retrieve the data for all the articles.
*
- * @returns {Promise<ArticlePreview[]>} - All the articles.
+ * @returns {Promise<ArticlePreview[]>} All the articles.
*/
const getAllArticles = async (): Promise<ArticlePreview[]> => {
const totalPosts = await fetchPostsCount();
@@ -25,7 +25,7 @@ const getAllArticles = async (): Promise<ArticlePreview[]> => {
/**
* Generate a new feed.
*
- * @returns {Promise<Feed>} - The feed.
+ * @returns {Promise<Feed>} The feed.
*/
export const generateFeed = async (): Promise<Feed> => {
const author = {
@@ -33,15 +33,16 @@ export const generateFeed = async (): Promise<Feed> => {
email: process.env.APP_AUTHOR_EMAIL,
link: CONFIG.url,
};
- const copyright = `${CONFIG.name} CC BY SA ${CONFIG.copyright.startYear} - ${CONFIG.copyright.endYear}`;
+ const copyright = `\u00A9 ${CONFIG.copyright.startYear} - ${CONFIG.copyright.endYear} ${CONFIG.name} - CC BY SA`;
const title = `${CONFIG.name} | ${CONFIG.baseline}`;
const feed = new Feed({
author,
copyright,
description: process.env.APP_FEED_DESCRIPTION,
+ favicon: `${CONFIG.url}/favicon.ico`,
feedLinks: {
- json: `${CONFIG.url}${ROUTES.RSS}/json`,
+ json: `${CONFIG.url}${ROUTES.RSS}.json`,
atom: `${CONFIG.url}${ROUTES.RSS}/atom`,
},
generator: 'Feed & NextJS',
@@ -53,16 +54,32 @@ export const generateFeed = async (): Promise<Feed> => {
const articles = await getAllArticles();
- articles.forEach((article) => {
+ for (const article of articles) {
feed.addItem({
+ author: [author],
+ category: article.meta.thematics?.map((thematic) => {
+ return {
+ domain: `${CONFIG.url}${thematic.url}`,
+ name: thematic.name,
+ };
+ }),
content: article.intro,
- date: new Date(article.meta.dates.publication),
+ copyright,
+ date: new Date(
+ article.meta.dates.update ?? article.meta.dates.publication
+ ),
description: article.intro,
id: `${article.id}`,
+ image: article.meta.cover
+ ? {
+ url: article.meta.cover.src,
+ }
+ : undefined,
link: `${CONFIG.url}${ROUTES.ARTICLE}/${article.slug}`,
+ published: new Date(article.meta.dates.publication),
title: article.title,
});
- });
+ }
return feed;
};