You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
thumbsup/test/website/pages.spec.js

186 lines
6.6 KiB
JavaScript

const _ = require('lodash')
const should = require('should/as-function')
const pages = require('../../src/website/pages')
const Album = require('../../src/model/album')
const fixtures = require('../fixtures')
const opts = {
input: '/source',
output: '/dest'
}
const themeSettings = {
some: 'value'
}
function pageSize (pageSize) {
return Object.assign({}, opts, { albumPageSize: pageSize })
}
function albumWithFiles (count) {
const file = fixtures.photo({ path: 'photo.jpg' })
const files = new Array(count).fill(file)
const album = new Album({ files })
album.finalize({})
return album
}
describe('Pages', function () {
describe('Single album', function () {
it('has a default page structure', function () {
const album = new Album('Album')
album.finalize(opts)
const model = pages.create(album, opts, themeSettings)
should(model.length).eql(1)
should(model[0].path).eql('index.html')
should(model[0].gallery.input).eql('/source')
should(model[0].settings).eql(themeSettings)
should(model[0].home).eql(album)
should(model[0].album).eql(album)
})
})
describe('Nested albums', function () {
it('generates 1 page per album', function () {
const b = new Album('B')
const c = new Album('C')
const a = new Album({ title: 'A', albums: [b, c] })
const model = pages.create(a, opts, themeSettings)
should(model.length).eql(3)
should(model[0].album).eql(a)
should(model[1].album).eql(b)
should(model[2].album).eql(c)
})
it('supports deep nesting', function () {
const c = new Album('C')
const b = new Album({ title: 'B', albums: [c] })
const a = new Album({ title: 'A', albums: [b] })
const model = pages.create(a, opts, themeSettings)
should(model.length).eql(3)
should(model[0].album).eql(a)
should(model[1].album).eql(b)
should(model[2].album).eql(c)
})
})
describe('Breadcrumbs', function () {
it('does not include the current album', function () {
const album = new Album('A')
const model = pages.create(album, opts, themeSettings)
should(model[0].breadcrumbs).eql([])
})
// TODO: only keep the relevant Breadcrumb properties (title, url)
// To avoid serializing the entire albums again
// (could be a breaking change for custom themes)
it('includes all parent albums, in order', function () {
const c = new Album('C')
const b = new Album({ title: 'B', albums: [c] })
const a = new Album({ title: 'A', albums: [b] })
const model = pages.create(a, opts, themeSettings)
should(model[2].breadcrumbs).eql([a, b])
})
})
describe('pagination', function () {
describe('navigation array', function () {
it('has an empty array if the album size is not specified', function () {
const album = albumWithFiles(2)
const models = pages.create(album, pageSize(null), themeSettings)
should(models[0].pagination.length).eql(0)
})
it('has a single item if all files fit in the page size', function () {
const album = albumWithFiles(5)
const models = pages.create(album, pageSize(10), themeSettings)
should(models[0].pagination.length).eql(1)
})
it('has multiple item if several pages are required', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
should(models[0].pagination.length).eql(3)
})
it('uses one-based indexes for easy rendering', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
const indexes = _.map(models[0].pagination, 'index')
should(indexes).eql([1, 2, 3])
})
it('includes links to all pages', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
const urls = _.map(models[0].pagination, 'url')
should(urls).eql(['index.html', 'index2.html', 'index3.html'])
})
it('highlights the current page', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
album.finalize()
should(_.map(models[0].pagination, 'current')).eql([true, false, false])
should(_.map(models[1].pagination, 'current')).eql([false, true, false])
should(_.map(models[2].pagination, 'current')).eql([false, false, true])
})
})
describe('page view-models', function () {
it('handles an even number of files', function () {
const album = albumWithFiles(4)
const models = pages.create(album, pageSize(2), themeSettings)
should(models.length).eql(2)
})
it('handles an odd number of files', function () {
const album = albumWithFiles(5)
const models = pages.create(album, pageSize(2), themeSettings)
should(models.length).eql(3)
})
it('uses the normal album path for the first page', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
should(models[0].path).eql('index.html')
})
it('uses the page index as a suffix for other pages', function () {
const album = albumWithFiles(6)
const models = pages.create(album, pageSize(2), themeSettings)
should(models[0].path).eql('index.html')
should(models[1].path).eql('index2.html')
should(models[2].path).eql('index3.html')
})
it('renders 1 album per page, with a subset of the files', function () {
const fileA = fixtures.photo({ path: 'A' })
const fileB = fixtures.photo({ path: 'B' })
const album = new Album({ files: [fileA, fileA, fileB, fileB] })
album.finalize()
const models = pages.create(album, pageSize(2), themeSettings)
should(models[0].album.files).eql([fileA, fileA])
should(models[1].album.files).eql([fileB, fileB])
})
it('is compatible with nested albums', function () {
const file = fixtures.photo({ path: 'A' })
const album = new Album({
files: [file, file, file, file],
albums: [new Album({
title: 'nested',
files: [file, file, file, file]
})]
})
album.finalize({})
const models = pages.create(album, pageSize(2), themeSettings)
should(models[0].path).eql('index.html')
should(models[1].path).eql('index2.html')
should(models[2].path).eql('nested.html')
should(models[3].path).eql('nested2.html')
})
})
})
})