Skip to content

Commit

Permalink
fix(core): offending RFC4287 (DIYgod#9441)
Browse files Browse the repository at this point in the history
* fix(core): offending RFC4287

should not leave `<updated>` blank when `<published>` is not blank
these two fields MUST conform to the "date-time" production in RFC3339

Signed-off-by: Rongrong <15956627+Rongronggg9@users.noreply.github.com>

* test(common-utils): complete tests

Signed-off-by: Rongrong <15956627+Rongronggg9@users.noreply.github.com>

* test(template): restrict expected value of `pubDate`

Signed-off-by: Rongrong <15956627+Rongronggg9@users.noreply.github.com>
  • Loading branch information
Rongronggg9 authored Apr 2, 2022
1 parent 63b3b04 commit 5b35471
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
10 changes: 8 additions & 2 deletions lib/middleware/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const art = require('art-template');
const path = require('path');
const config = require('@/config').value;
const typeRegex = /\.(atom|rss|debug\.json)$/;
const { collapseWhitespace } = require('@/utils/common-utils');
const { collapseWhitespace, convertDateToISO8601 } = require('@/utils/common-utils');

module.exports = async (ctx, next) => {
if (ctx.headers['user-agent'] && ctx.headers['user-agent'].includes('Reeder')) {
Expand All @@ -28,7 +28,8 @@ module.exports = async (ctx, next) => {
if (!ctx.body) {
let template;

switch (ctx.state.type[1]) {
const outputType = ctx.state.type[1];
switch (outputType) {
case 'atom':
template = path.resolve(__dirname, '../views/atom.art');
break;
Expand Down Expand Up @@ -66,6 +67,11 @@ module.exports = async (ctx, next) => {
item.itunes_duration =
Math.floor(item.itunes_duration / 3600) + ':' + (Math.floor((item.itunes_duration % 3600) / 60) / 100).toFixed(2).slice(-2) + ':' + (((item.itunes_duration % 3600) % 60) / 100).toFixed(2).slice(-2);
}

if (outputType === 'atom') {
item.pubDate = convertDateToISO8601(item.pubDate);
item.updated = convertDateToISO8601(item.updated);
}
});
}

Expand Down
14 changes: 14 additions & 0 deletions lib/utils/common-utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { parseDate } = require('@/utils/parse-date');

// convert a string into title case
const toTitleCase = (str) =>
str
Expand All @@ -17,7 +19,19 @@ const collapseWhitespace = (str) => {
return str;
};

const convertDateToISO8601 = (date) => {
if (!date) {
return date;
}
if (typeof date !== 'object') {
// some routes may call `.toUTCString()` before passing the date to ctx...
date = parseDate(date);
}
return date.toISOString();
};

module.exports = {
toTitleCase,
collapseWhitespace,
convertDateToISO8601,
};
6 changes: 4 additions & 2 deletions lib/views/atom.art
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
<id>{{ $e.guid || $e.id || $e.link }}</id>
<title><![CDATA[{{@ $e.title }}]]></title>

<published>{{ $e.pubDate || $e.updated }}</published>
<updated>{{ $e.updated }}</updated>
{{ if ($e.pubDate && $e.updated) }}
<published>{{ $e.pubDate }}</published>
{{ /if }}
<updated>{{ $e.updated || $e.pubDate }}</updated>

{{ if $e.author }}
<author>
Expand Down
6 changes: 4 additions & 2 deletions test/middleware/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ afterAll(() => {
});

describe('template', () => {
const expectPubDate = new Date(1546272000000 - 10 * 1000);

it(`.rss`, async () => {
const response1 = await request.get('/test/1.rss');
const parsed1 = await parser.parseString(response1.text);
Expand All @@ -25,7 +27,7 @@ describe('template', () => {
expect(parsed1.items[0]).toEqual(expect.any(Object));
expect(parsed1.items[0].title).toEqual(expect.any(String));
expect(parsed1.items[0].link).toEqual(expect.any(String));
expect(parsed1.items[0].pubDate).toEqual(expect.any(String));
expect(parsed1.items[0].pubDate).toBe(expectPubDate.toUTCString());
expect(parsed1.items[0].author).toEqual(expect.any(String));
expect(parsed1.items[0].content).toEqual(expect.any(String));
expect(parsed1.items[0].guid).toEqual(expect.any(String));
Expand Down Expand Up @@ -54,7 +56,7 @@ describe('template', () => {
expect(parsed.items[0]).toEqual(expect.any(Object));
expect(parsed.items[0].title).toEqual(expect.any(String));
expect(parsed.items[0].link).toEqual(expect.any(String));
expect(parsed.items[0].pubDate).toEqual(expect.any(String));
expect(parsed.items[0].pubDate).toBe(expectPubDate.toISOString());
expect(parsed.items[0].author).toEqual(expect.any(String));
expect(parsed.items[0].content).toEqual(expect.any(String));
expect(parsed.items[0].id).toEqual(expect.any(String));
Expand Down
29 changes: 29 additions & 0 deletions test/utils/common-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,33 @@ describe('common-utils', () => {
it('toTitleCase', () => {
expect(utils.toTitleCase('RSSHub IS AS aweSOme aS henry')).toBe('Rsshub Is As Awesome As Henry');
});

it('convertDateToISO8601', () => {
expect(utils.convertDateToISO8601('')).toBe('');
expect(utils.convertDateToISO8601(null)).toBe(null);
expect(utils.convertDateToISO8601(undefined)).toBe(undefined);

const date = new Date('2019-01-01');
const expected = date.toISOString();
expect(utils.convertDateToISO8601(date)).toBe(expected);
expect(utils.convertDateToISO8601(date.toISOString())).toBe(expected);
expect(utils.convertDateToISO8601(date.toUTCString())).toBe(expected);
expect(utils.convertDateToISO8601(date.toLocaleString())).toBe(expected);
expect(utils.convertDateToISO8601('Tue, 01 Jan 2019 08:00:00 UTC+8')).toBe(expected);

expect(utils.convertDateToISO8601('Tue, 01 Jan 2019 00:00:00')).toBe(new Date(date.getTime() + new Date().getTimezoneOffset() * 60 * 1000).toISOString());
// need to pass a function in order to use `toThrow`
expect(() => {
utils.convertDateToISO8601('something invalid');
}).toThrow(RangeError);
});

it('collapseWhitespace', () => {
expect(utils.collapseWhitespace('')).toBe('');
expect(utils.collapseWhitespace(null)).toBe(null);
expect(utils.collapseWhitespace(undefined)).toBe(undefined);
expect(utils.collapseWhitespace(' \n\n\n ')).toBe('');
expect(utils.collapseWhitespace('a string already collapsed')).toBe('a string already collapsed');
expect(utils.collapseWhitespace(' \n a lot of whitespaces and \n\n\n\n linebreaks \n\n ')).toBe('a lot of whitespaces and linebreaks');
});
});

0 comments on commit 5b35471

Please sign in to comment.