mirror of https://github.com/thumbsup/thumbsup
chore(core): refactor SEO into testable module
parent
6886c262db
commit
31b85fc0e1
@ -0,0 +1,47 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
class SEO {
|
||||
constructor (output, seoLocation, rootAlbum) {
|
||||
this.output = output
|
||||
this.seoPrefix = seoLocation + (seoLocation.endsWith('/') ? '' : '/')
|
||||
this.album = rootAlbum
|
||||
}
|
||||
|
||||
robots () {
|
||||
return `User-Agent: *\nDisallow:\nSitemap: ${this.seoPrefix}sitemap.xml\n`
|
||||
}
|
||||
|
||||
sitemap () {
|
||||
const now = new Date().toISOString()
|
||||
const prefix = this.seoPrefix
|
||||
// gather all album pages
|
||||
const urls = []
|
||||
addAlbumUrls(urls, this.album)
|
||||
// create one <url> section per album
|
||||
const xml = urls.map(url => `
|
||||
<url>
|
||||
<loc>${prefix}${url}</loc>
|
||||
<lastmod>${now}</lastmod>
|
||||
</url>`)
|
||||
// return the full document
|
||||
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${xml.join('')}
|
||||
</urlset>
|
||||
`
|
||||
}
|
||||
|
||||
writeFiles () {
|
||||
const robotsFile = path.join(this.output, 'robots.txt')
|
||||
const sitemapFile = path.join(this.output, 'sitemap.xml')
|
||||
fs.writeFileSync(robotsFile, this.robots())
|
||||
fs.writeFileSync(sitemapFile, this.sitemap())
|
||||
}
|
||||
}
|
||||
|
||||
function addAlbumUrls (list, album) {
|
||||
list.push(album.url)
|
||||
album.albums.forEach(subAlbum => addAlbumUrls(list, subAlbum))
|
||||
}
|
||||
|
||||
module.exports = SEO
|
@ -0,0 +1,53 @@
|
||||
const should = require('should/as-function')
|
||||
const SEO = require('../../src/website/seo')
|
||||
const Album = require('../../src/model/album')
|
||||
|
||||
describe('SEO', function () {
|
||||
it('normalises the SEO location path (no slash)', function () {
|
||||
const location = 'https://example.com'
|
||||
const seo = new SEO('output', location, new Album('test'))
|
||||
should(seo.seoPrefix).eql('https://example.com/')
|
||||
})
|
||||
|
||||
it('normalises the SEO location path (slash)', function () {
|
||||
const location = 'https://example.com/'
|
||||
const seo = new SEO('output', location, new Album('test'))
|
||||
should(seo.seoPrefix).eql('https://example.com/')
|
||||
})
|
||||
|
||||
describe('robots.txt', function () {
|
||||
it('allows all user agents', function () {
|
||||
const seo = new SEO('output', 'https://example.com', new Album('test'))
|
||||
const robots = seo.robots()
|
||||
should(robots.includes('User-Agent: *')).eql(true)
|
||||
})
|
||||
|
||||
it('points to the Sitemap', function () {
|
||||
const seo = new SEO('output', 'https://example.com', new Album('test'))
|
||||
const robots = seo.robots()
|
||||
should(robots.includes('Sitemap: https://example.com/sitemap.xml')).eql(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('sitemap.xml', function () {
|
||||
it('includes the root album', function () {
|
||||
const album = new Album('test')
|
||||
album.finalize()
|
||||
const seo = new SEO('output', 'https://example.com', album)
|
||||
const sitemap = seo.sitemap()
|
||||
should(sitemap.includes('<loc>https://example.com/index.html</loc>')).eql(true)
|
||||
})
|
||||
|
||||
it('includes nested albums', function () {
|
||||
const album = new Album({
|
||||
albums: [new Album('a'), new Album('b')]
|
||||
})
|
||||
album.finalize()
|
||||
const seo = new SEO('output', 'https://example.com', album)
|
||||
const sitemap = seo.sitemap()
|
||||
should(sitemap.includes('<loc>https://example.com/index.html</loc>')).eql(true)
|
||||
should(sitemap.includes('<loc>https://example.com/a.html</loc>')).eql(true)
|
||||
should(sitemap.includes('<loc>https://example.com/b.html</loc>')).eql(true)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue