mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
refs #5091, refs #9192 - This is similar to #9218, in that I'm revealing bits of code that are "controllers" in our codebase. As opposed to routes, services, renderers etc. - This also reveals some code which is identical to the channels controller - There is more to do here, but for now I've got the module split up, and the tests split and improved. - Next I'll split RSS into controller + service, DRY up the controller code, etc
202 lines
8.9 KiB
JavaScript
202 lines
8.9 KiB
JavaScript
var should = require('should'),
|
|
_ = require('lodash'),
|
|
testUtils = require('../../utils'),
|
|
configUtils = require('../../utils/configUtils'),
|
|
|
|
generateFeed = require('../../../server/data/xml/rss/generate-feed');
|
|
|
|
describe('RSS: Generate Feed', function () {
|
|
var data = {},
|
|
// Static set of posts
|
|
posts;
|
|
|
|
before(function () {
|
|
posts = _.cloneDeep(testUtils.DataGenerator.forKnex.posts);
|
|
posts = _.filter(posts, function filter(post) {
|
|
return post.status === 'published' && post.page === false;
|
|
});
|
|
|
|
_.each(posts, function (post, i) {
|
|
post.id = i;
|
|
post.url = '/' + post.slug + '/';
|
|
post.author = {name: 'Joe Bloggs'};
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
configUtils.restore();
|
|
});
|
|
|
|
beforeEach(function () {
|
|
configUtils.set({url: 'http://my-ghost-blog.com'});
|
|
|
|
data.version = '0.6';
|
|
data.siteUrl = 'http://my-ghost-blog.com/';
|
|
data.feedUrl = 'http://my-ghost-blog.com/rss/';
|
|
data.title = 'Test Title';
|
|
data.description = 'Testing Desc';
|
|
data.permalinks = '/:slug/';
|
|
});
|
|
|
|
it('should get the RSS tags correct', function (done) {
|
|
data.results = {posts: [], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// xml & rss tags
|
|
xmlData.should.match(/^<\?xml version="1.0" encoding="UTF-8"\?>/);
|
|
xmlData.should.match(/<rss/);
|
|
xmlData.should.match(/xmlns:dc="http:\/\/purl.org\/dc\/elements\/1.1\/"/);
|
|
xmlData.should.match(/xmlns:content="http:\/\/purl.org\/rss\/1.0\/modules\/content\/"/);
|
|
xmlData.should.match(/xmlns:atom="http:\/\/www.w3.org\/2005\/Atom"/);
|
|
xmlData.should.match(/version="2.0"/);
|
|
xmlData.should.match(/xmlns:media="http:\/\/search.yahoo.com\/mrss\/"/);
|
|
|
|
// channel tags
|
|
xmlData.should.match(/<channel><title><!\[CDATA\[Test Title\]\]><\/title>/);
|
|
xmlData.should.match(/<description><!\[CDATA\[Testing Desc\]\]><\/description>/);
|
|
xmlData.should.match(/<link>http:\/\/my-ghost-blog.com\/<\/link>/);
|
|
xmlData.should.match(/<image><url>http:\/\/my-ghost-blog.com\/favicon.png<\/url><title>Test Title<\/title><link>http:\/\/my-ghost-blog.com\/<\/link><\/image>/);
|
|
xmlData.should.match(/<generator>Ghost 0.6<\/generator>/);
|
|
xmlData.should.match(/<lastBuildDate>.*?<\/lastBuildDate>/);
|
|
xmlData.should.match(/<atom:link href="http:\/\/my-ghost-blog.com\/rss\/" rel="self"/);
|
|
xmlData.should.match(/type="application\/rss\+xml"\/><ttl>60<\/ttl>/);
|
|
xmlData.should.match(/<\/channel><\/rss>$/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should get the item tags correct', function (done) {
|
|
data.results = {posts: posts, meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// item tags
|
|
xmlData.should.match(/<item><title><!\[CDATA\[HTML Ipsum\]\]><\/title>/);
|
|
xmlData.should.match(/<description><!\[CDATA\[<h1>HTML Ipsum Presents<\/h1>/);
|
|
xmlData.should.match(/<link>http:\/\/my-ghost-blog.com\/html-ipsum\/<\/link>/);
|
|
xmlData.should.match(/<image><url>http:\/\/my-ghost-blog.com\/favicon.png<\/url><title>Test Title<\/title><link>http:\/\/my-ghost-blog.com\/<\/link><\/image>/);
|
|
xmlData.should.match(/<guid isPermaLink="false">/);
|
|
xmlData.should.match(/<\/guid><dc:creator><!\[CDATA\[Joe Bloggs\]\]><\/dc:creator>/);
|
|
xmlData.should.match(/<pubDate>Thu, 01 Jan 2015/);
|
|
xmlData.should.match(/<content:encoded><!\[CDATA\[<h1>HTML Ipsum Presents<\/h1><p><strong>Pellentes/);
|
|
xmlData.should.match(/<\/code><\/pre>\]\]><\/content:encoded><\/item>/);
|
|
xmlData.should.not.match(/<author>/);
|
|
|
|
// basic structure check
|
|
var postEnd = '<\/code><\/pre>\]\]><\/content:encoded>',
|
|
firstIndex = xmlData.indexOf(postEnd);
|
|
|
|
// The first title should be before the first content
|
|
xmlData.indexOf('HTML Ipsum').should.be.below(firstIndex);
|
|
// The second title should be after the first content
|
|
xmlData.indexOf('Ghostly Kitchen Sink').should.be.above(firstIndex);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should only return visible tags', function (done) {
|
|
var postWithTags = posts[2];
|
|
postWithTags.tags = [
|
|
{name: 'public', visibility: 'public'},
|
|
{name: 'internal', visibility: 'internal'},
|
|
{name: 'visibility'}
|
|
];
|
|
|
|
data.results = {posts: [postWithTags], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
// item tags
|
|
xmlData.should.match(/<title><!\[CDATA\[Short and Sweet\]\]>/);
|
|
xmlData.should.match(/<description><!\[CDATA\[test stuff/);
|
|
xmlData.should.match(/<content:encoded><!\[CDATA\[<div class="kg-card-markdown"><h2 id="testing">testing<\/h2>\n/);
|
|
xmlData.should.match(/<img src="http:\/\/placekitten.com\/500\/200"/);
|
|
xmlData.should.match(/<media:content url="http:\/\/placekitten.com\/500\/200" medium="image"\/>/);
|
|
xmlData.should.match(/<category><!\[CDATA\[public\]\]/);
|
|
xmlData.should.match(/<category><!\[CDATA\[visibility\]\]/);
|
|
xmlData.should.not.match(/<category><!\[CDATA\[internal\]\]/);
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should use meta_description and image where available', function (done) {
|
|
data.results = {posts: [posts[2]], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// special/optional tags
|
|
xmlData.should.match(/<title><!\[CDATA\[Short and Sweet\]\]>/);
|
|
xmlData.should.match(/<description><!\[CDATA\[test stuff/);
|
|
xmlData.should.match(/<content:encoded><!\[CDATA\[<div class="kg-card-markdown"><h2 id="testing">testing<\/h2>\n/);
|
|
xmlData.should.match(/<img src="http:\/\/placekitten.com\/500\/200"/);
|
|
xmlData.should.match(/<media:content url="http:\/\/placekitten.com\/500\/200" medium="image"\/>/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should use excerpt when no meta_description is set', function (done) {
|
|
data.results = {posts: [posts[0]], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// special/optional tags
|
|
xmlData.should.match(/<title><!\[CDATA\[HTML Ipsum\]\]>/);
|
|
xmlData.should.match(/<description><!\[CDATA\[This is my custom excerpt!/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should process urls correctly', function (done) {
|
|
data.results = {posts: [posts[3]], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// anchor URL - <a href="#nowhere" title="Anchor URL">
|
|
xmlData.should.match(/<a href="#nowhere" title="Anchor URL">/);
|
|
|
|
// relative URL - <a href="/about#nowhere" title="Relative URL">
|
|
xmlData.should.match(/<a href="http:\/\/my-ghost-blog.com\/about#nowhere" title="Relative URL">/);
|
|
|
|
// protocol relative URL - <a href="//somewhere.com/link#nowhere" title="Protocol Relative URL">
|
|
xmlData.should.match(/<a href="\/\/somewhere.com\/link#nowhere" title="Protocol Relative URL">/);
|
|
|
|
// absolute URL - <a href="http://somewhere.com/link#nowhere" title="Absolute URL">
|
|
xmlData.should.match(/<a href="http:\/\/somewhere.com\/link#nowhere" title="Absolute URL">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('should process urls correctly with subdirectory', function (done) {
|
|
configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
|
|
|
|
data.siteUrl = 'http://my-ghost-blog.com/blog/';
|
|
data.feedUrl = 'http://my-ghost-blog.com/blog/rss/';
|
|
data.results = {posts: [posts[3]], meta: {pagination: {pages: 1}}};
|
|
|
|
generateFeed(data).then(function (xmlData) {
|
|
should.exist(xmlData);
|
|
|
|
// anchor URL - <a href="#nowhere" title="Anchor URL">
|
|
xmlData.should.match(/<a href="#nowhere" title="Anchor URL">/);
|
|
|
|
// relative URL - <a href="/about#nowhere" title="Relative URL">
|
|
xmlData.should.match(/<a href="http:\/\/my-ghost-blog.com\/blog\/about#nowhere" title="Relative URL">/);
|
|
|
|
// absolute URL - <a href="http://somewhere.com/link#nowhere" title="Absolute URL">
|
|
xmlData.should.match(/<a href="http:\/\/somewhere.com\/link#nowhere" title="Absolute URL">/);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|