diff --git a/.istanbul.yml b/.istanbul.yml index 7178a27..7435884 100644 --- a/.istanbul.yml +++ b/.istanbul.yml @@ -1,2 +1,2 @@ instrumentation: - root: lib + root: src diff --git a/package.json b/package.json index 5d2cc6e..3e3438c 100644 --- a/package.json +++ b/package.json @@ -3,31 +3,41 @@ "description": "An extension for using roots with the API-driven Contentful CMS", "version": "0.0.9", "author": "Carrot Creative", + "ava": { + "serial": true, + "verbose": true, + "require": [ + "babel-core/register", + "coffee-script/register" + ] + }, "bugs": { "url": "https://github.com/carrot/roots-contentful/issues" }, "dependencies": { + "ava": "^0.9.2", "babel-runtime": "^6.3.13", - "contentful": "^2.1.0", + "contentful": "^2.1.1", + "deepcopy": "^0.6.1", "pluralize": "^1.2.1", "roots-util": "0.2.x", - "underscore.string": "^3.2.2" + "underscore.string": "^3.2.3" }, "devDependencies": { - "ava": "^0.9.1", - "babel-cli": "^6.3.15", - "babel-core": "^6.3.26", + "ava": "^0.10.0", + "babel-cli": "^6.4.5", + "babel-core": "^6.4.5", "babel-eslint": "^5.0.0-beta6", - "babel-plugin-add-module-exports": "^0.1.2", - "babel-plugin-transform-runtime": "^6.3.13", - "babel-preset-es2015-node5": "^1.1.1", + "babel-plugin-add-module-exports": "^0.1.3-alpha", + "babel-plugin-transform-runtime": "^6.4.3", + "babel-preset-es2015-node5": "^1.1.2", "babel-preset-stage-0": "^6.3.13", "babel-runtime": "^6.3.19", "coffee-script": "^1.10.0", "coveralls": "^2.11.6", "husky": "^0.10.2", "mockery": "1.4.x", - "nyc": "^5.2.0", + "nyc": "^5.3.0", "roots": "3.1.0", "snazzy": "^2.0.1", "standard": "^5.4.1" @@ -62,22 +72,24 @@ "scripts": { "build": "babel src -d lib", "coverage": "nyc report --reporter=lcov", - "coveralls": "coveralls < coverage/lcov.info", - "debug-test": "NODE_DEBUG=request npm run test -- --serial --verbose --fail-fast", + "coveralls": "nyc report --reporter=text-lcov | coveralls", + "debug-test": "npm run test -- --fail-fast", "lint": "standard --verbose | snazzy", "postpublish": "git push --follow-tags", "posttest": "node test/_teardown.js", "prebuild": "npm test", "precommit": "npm run lint -s", "precoverage": "npm run test", - "precoveralls": "npm run coverage", "prerelease": "npm run build", "pretest": "npm run lint -s && node test/_setup.js", "release": "npm publish", - "test": "nyc ava --require babel-core/register --require coffee-script/register" + "test": "nyc ava --verbose --serial --require babel-core/register --require coffee-script/register" }, "standard": { "parser": "babel-eslint", - "ignore": ["test/_setup.js", "test/_teardown.js"] + "ignore": [ + "test/_setup.js", + "test/_teardown.js" + ] } } diff --git a/readme.md b/readme.md index 31366dc..75a1d62 100644 --- a/readme.md +++ b/readme.md @@ -35,6 +35,9 @@ module.exports = contentful access_token: 'YOUR_ACCESS_TOKEN' space_id: 'xxxxxx' + locale: 'tlh' + locales_prefix: + tlh: 'klingon_' content_types: blog_posts: id: 'xxxxxx' @@ -76,15 +79,17 @@ If a `template` option is defined for a Content Type in `app.coffee`, roots will Contentful's [documentation](https://www.contentful.com/developers/documentation/content-delivery-api/#getting-entry) shows the API response when fetching an entry. Your content fields are nested in a `fields` key on the `entry` object. As a convenience, the entry object roots-contentful makes available in your views will have the `fields` key's value set one level higher on the object. System metadata remains accessible on the `sys` key and roots-contentful will raise an error if you have a field named `sys`. Inside your views, the entry object will have this structure: -```json -"entry": { - "title": "Wow. Such title. Much viral", - "author": "The Doge of Venice" - # ... the rest of the fields - "sys": { - "type": "Entry", - "id": "cat" - # ... +```js +{ + "entry": { + "title": "Wow. Such title. Much viral", + "author": "The Doge of Venice" + // ... the rest of the fields + "sys": { + "type": "Entry", + "id": "cat" + # ... + } } } ``` @@ -109,6 +114,29 @@ Required. The space ID containing the content you wish to retrieve. Optional. (Boolean) Allows you use the Contentful Preview API. Also able to be accessed by setting the environment variable `CONTENTFUL_ENV` to `"develop"` (preview api) or `"production"` (default cdn). +#### locales +Locales allow you to request your content in a different language, `tlh` is Klingon. + +##### Global locale +Optional. (String or Array) Defines locale for all content_types. +String: `'tlh'` +Array: `['en-es', 'tlh']` +Wildcard: `'*'` - grabs all locales from contentful + +##### content_type specific locale +Optional. (String) Define content_types locale, will override global locale. Add `locale: 'tlh'` to any of your content types and you'll retrieve that post in the specific locale. + +#### locales_prefix +Optional. (Object) Defines the prefix given to a group of locales. + +``` +locales_prefix: + 'tlh': 'klingon_' + 'en-es': 'spanish_' +``` + +Lets say you have 3 global locales defined, `['tlh', 'en-us', 'en-es']`, and above is our defined locales_prefix. Since we did not declare `'en-us'` you can access it with `contentful.en_us_blog_posts`. Similarly you can access each preix according to what you've set in the object above. `'tlh'` would be accessible by `contentful.klingon_blog_posts` and `en-es` by `contentful.spanish_blog_posts`. + #### content_types An object whose key-value pairs correspond to a Contentful Content Types. Each diff --git a/src/extension.js b/src/extension.js index 448d49d..09efb0e 100644 --- a/src/extension.js +++ b/src/extension.js @@ -2,12 +2,15 @@ import path from 'path' import querystring from 'querystring' import contentful from 'contentful' import pluralize from 'pluralize' +import deepcopy from 'deepcopy' import slugify from 'underscore.string/slugify' import underscored from 'underscore.string/underscored' import RootsUtil from 'roots-util' import errors from './errors' import hosts from './hosts' import is_plain_object from './util/is-plain-object' +import exists from './util/exists' +import isUndefined from './util/is-undefined' let client = null // init contentful client @@ -55,17 +58,17 @@ export default class RootsContentful { * @return {Promise} an array for the sorted contentful data */ async setup () { - const { opts: { cache, content_types } } = this + const { opts, opts: { cache } } = this let locals = this.roots.config.locals.contentful // return cached locals if possible if (cache && Object.keys(locals).length) { return locals } - let configuration = await configure_content(content_types) - let content = await get_all_content(configuration) - await set_urls(content) - let entries = await transform_entries(content) - let sorted = await sort_entries(entries) + let configuration = await this::configure_content(opts) + let content = await this::get_all_content(configuration) + await this::set_urls(content) + let entries = await this::transform_entries(content) + let sorted = await this::sort_entries(entries) await this::set_locals(sorted) await this::compile_entries(sorted) await this::write_entries(sorted) @@ -77,26 +80,96 @@ export default class RootsContentful { /** * Configures content types set in app.coffee. Sets default values if * optional config options are missing. - * @param {Array} types - content_types set in app.coffee extension config + * @param {Object} opts - app.coffee extension config * @return {Promise} - returns an array of configured content types */ -async function configure_content (types) { +async function configure_content (opts) { + let types = opts.content_types + let locales = opts.locale + let locale_prefixes = opts.locales_prefix + // consumes types after adding locale and prefixes to types + let _types = [] + // consumes types after adding type paths to types + // & locale prefixes to type names + let localized_types = [] + let global_locale + + // if locales is wildcard, fetch & set locales + if (locales === '*') { + locales = await fetch_all_locales() + } + + // converts type config to an array if + // it is specified as an object if (is_plain_object(types)) { types = convert_types_to_array(types) } - return types.map(async type => { - const { id, name, filters, template, path } = type - if (!id) throw new Error(errors.no_type_id) - type.filters = filters || {} - if (!name || (template && !path)) { - let content_type = await client.contentType(id) - type.name = name || pluralize(underscored(content_type.name)) - if (template) { - type.path = path || (entry => `${name}/${slugify(entry[content_type.displayField])}`) + + // update types to contain locale data + // and prefixes (null checks === ಠ_ಠ) + if (Array.isArray(locales)) { + for (let locale of locales) { + // if locale_prefixes is defined... + let existing_prefix = locale_prefixes != null + // set prefix as locale_prefixes[locale] + // if it exists else... + ? locale_prefixes[locale] + : null + // ...set prefix as underscored locale + let prefix = existing_prefix || `${underscored(locale)}_` + + for (let type of types) { + // type's locale overrides global locale + if (type.locale == null) { + let tmp = deepcopy(type) + tmp.locale = locale + tmp.prefix = prefix + _types.push(tmp) + } else if (type.prefix == null) { + // set prefix, only if it isn't set + type.prefix = prefix + _types.push(type) + } } } - return type - }) + types = _types + } else if (typeof locales === 'string') { + global_locale = true + } + + // validate type ids, set type paths + // and type names, possibly including + // type locale prefixes in type names + for (let type of types) { + if (!type.id) { + throw new Error(errors.no_type_id) + } + if (type.filters == null) { + type.filters = {} + } + if (!type.name || (type.template && !type.path)) { + let content_type = await client.contentType(type.id) + if (type.name == null) { + type.name = pluralize(underscored(content_type.name)).toLowerCase() + } + if (!isUndefined(locale_prefixes)) { + type.name = type.prefix + type.name + } + if (type.template || (locale_prefixes != null)) { + if (type.path == null) { + type.path = entry => `${type.name}/${slugify(entry[content_type.displayField])}` + } + } + } else if (!isUndefined(locale_prefixes)) { + type.name = type.prefix + type.name + } + if (exists(global_locale)) { + type.locale || (type.locale = opts.locale) + } + localized_types.push(Promise.resolve(type)) + } + + return await Promise.all(localized_types) } /** @@ -106,10 +179,11 @@ async function configure_content (types) { * @return {Promise} - returns an array of content types */ function convert_types_to_array (types) { - return Object.keys(types).reduce((results, key) => { + types = Object.keys(types).reduce((results, key) => { results.push({ ...types[key], name: key }) return results }, []) + return types } /** @@ -119,11 +193,11 @@ function convert_types_to_array (types) { */ async function get_all_content (types) { types = await Promise.all(types) - return types.map(async type => { - let content = await fetch_content(type) + for (const type of types) { + const content = await fetch_content(type) type.content = await format_content(content) - return type - }) + } + return types } /** @@ -131,15 +205,26 @@ async function get_all_content (types) { * @param {Object} type - content type object * @return {Promise} - returns response from Contentful API */ -async function fetch_content ({ id, filters }) { +async function fetch_content ({ id, filters, locale }) { let entries = await client.entries({ ...filters, content_type: id, - include: 10 + include: 10, + locale }) return entries } +/** + * Fetch all locales in space + * Used when `*` is used in opts.locales + * @return {Array} locales + */ +async function fetch_all_locales () { + let res = await client.space() + return res.locales.map(locale => locale.code) +} + /** * Formats raw response from Contentful * @param {Object} content - entries API response for a content type @@ -160,6 +245,9 @@ function format_entry (entry) { throw new Error(errors.sys_conflict) } let formatted = { ...entry, ...entry.fields } + if (formatted.sys != null) { + delete formatted.sys + } delete formatted.fields return formatted } @@ -194,10 +282,15 @@ async function set_urls (types) { * @return {Promise} - promise for when complete */ async function set_locals (types) { + let contentful = this.roots.config.locals.contentful types = await Promise.all(types) return types.map(({ name, content }) => { - this.roots.config.locals.contentful[name] = content - return content + if (contentful[name]) { + contentful[name].push(content[0]) + } else { + contentful[name] = content + } + return contentful[name] }) } @@ -249,10 +342,10 @@ async function compile_entries (types) { return compiler.extensions.includes(path.extname(tpl_path).substring(1)) }) return entry._urls.map(_url => { - this.roots.config.locals.entry = { ...entry, _url } + locals.entry = { ...entry, _url } return compiler.renderFile(tpl_path, locals) .then(compiled => { - this.roots.config.locals.entry = null + locals.entry = null return util.write(_url, compiled.result) }) }) diff --git a/src/util/exists.js b/src/util/exists.js new file mode 100644 index 0000000..7c6b41d --- /dev/null +++ b/src/util/exists.js @@ -0,0 +1,3 @@ +export default function exists (thing) { + return typeof thing !== 'undefined' && thing !== null +} diff --git a/src/util/is-undefined.js b/src/util/is-undefined.js new file mode 100644 index 0000000..699841a --- /dev/null +++ b/src/util/is-undefined.js @@ -0,0 +1,3 @@ +export default function isUndefined (thing) { + return thing === void 0 +} diff --git a/test/fixtures/locales--multi/app.coffee b/test/fixtures/locales--multi/app.coffee new file mode 100644 index 0000000..b5f936b --- /dev/null +++ b/test/fixtures/locales--multi/app.coffee @@ -0,0 +1,16 @@ +contentful = require '../../../src' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + access_token: 'YOUR_ACCESS_TOKEN' + space_id: 'aqzq2qya2jm4' + locale: ['en-es', 'tlh'] + content_types: [ + { + id: '6BYT1gNiIEyIw8Og8aQAO6' + } + ] + ) + ] diff --git a/test/fixtures/locales--multi/index.jade b/test/fixtures/locales--multi/index.jade new file mode 100644 index 0000000..4769500 --- /dev/null +++ b/test/fixtures/locales--multi/index.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--multi/package.json b/test/fixtures/locales--multi/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/locales--multi/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/fixtures/locales--prefix/app.coffee b/test/fixtures/locales--prefix/app.coffee new file mode 100644 index 0000000..ac0fba9 --- /dev/null +++ b/test/fixtures/locales--prefix/app.coffee @@ -0,0 +1,19 @@ +contentful = require '../../../src' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + access_token: 'YOUR_ACCESS_TOKEN' + space_id: 'aqzq2qya2jm4' + locale: ['en-es', 'tlh'] + locales_prefix: { + 'tlh': 'klingon_' + } + content_types: [ + { + id: '6BYT1gNiIEyIw8Og8aQAO6' + } + ] + ) + ] diff --git a/test/fixtures/locales--prefix/klingon.jade b/test/fixtures/locales--prefix/klingon.jade new file mode 100644 index 0000000..9c7fe36 --- /dev/null +++ b/test/fixtures/locales--prefix/klingon.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.klingon_blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--prefix/package.json b/test/fixtures/locales--prefix/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/locales--prefix/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/fixtures/locales--prefix/spanish.jade b/test/fixtures/locales--prefix/spanish.jade new file mode 100644 index 0000000..620ac70 --- /dev/null +++ b/test/fixtures/locales--prefix/spanish.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.en_es_blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--scope/about.jade b/test/fixtures/locales--scope/about.jade new file mode 100644 index 0000000..8240f0e --- /dev/null +++ b/test/fixtures/locales--scope/about.jade @@ -0,0 +1 @@ +h1 wow diff --git a/test/fixtures/locales--scope/app.coffee b/test/fixtures/locales--scope/app.coffee new file mode 100644 index 0000000..3e0eb91 --- /dev/null +++ b/test/fixtures/locales--scope/app.coffee @@ -0,0 +1,17 @@ +contentful = require '../../../src' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + access_token: 'YOUR_ACCESS_TOKEN' + space_id: 'aqzq2qya2jm4' + locale: ['tlh'] + content_types: [ + { + id: '6BYT1gNiIEyIw8Og8aQAO6' + locale: 'en-es' + } + ] + ) + ] diff --git a/test/fixtures/locales--scope/index.jade b/test/fixtures/locales--scope/index.jade new file mode 100644 index 0000000..4769500 --- /dev/null +++ b/test/fixtures/locales--scope/index.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--scope/package.json b/test/fixtures/locales--scope/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/locales--scope/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/fixtures/locales--setup/about.jade b/test/fixtures/locales--setup/about.jade new file mode 100644 index 0000000..8240f0e --- /dev/null +++ b/test/fixtures/locales--setup/about.jade @@ -0,0 +1 @@ +h1 wow diff --git a/test/fixtures/locales--setup/app.coffee b/test/fixtures/locales--setup/app.coffee new file mode 100644 index 0000000..e59b2a7 --- /dev/null +++ b/test/fixtures/locales--setup/app.coffee @@ -0,0 +1,16 @@ +contentful = require '../../../src' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + access_token: 'YOUR_ACCESS_TOKEN' + space_id: 'aqzq2qya2jm4' + locale: '*' + content_types: [ + { + id: '6BYT1gNiIEyIw8Og8aQAO6' + } + ] + ) + ] diff --git a/test/fixtures/locales--setup/index.jade b/test/fixtures/locales--setup/index.jade new file mode 100644 index 0000000..4769500 --- /dev/null +++ b/test/fixtures/locales--setup/index.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--setup/package.json b/test/fixtures/locales--setup/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/locales--setup/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/fixtures/locales--single/about.jade b/test/fixtures/locales--single/about.jade new file mode 100644 index 0000000..8240f0e --- /dev/null +++ b/test/fixtures/locales--single/about.jade @@ -0,0 +1 @@ +h1 wow diff --git a/test/fixtures/locales--single/app.coffee b/test/fixtures/locales--single/app.coffee new file mode 100644 index 0000000..49f595c --- /dev/null +++ b/test/fixtures/locales--single/app.coffee @@ -0,0 +1,16 @@ +contentful = require '../../../src' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + access_token: 'YOUR_ACCESS_TOKEN' + space_id: 'aqzq2qya2jm4' + locale: ['tlh'] + content_types: [ + { + id: '6BYT1gNiIEyIw8Og8aQAO6' + } + ] + ) + ] diff --git a/test/fixtures/locales--single/index.jade b/test/fixtures/locales--single/index.jade new file mode 100644 index 0000000..4769500 --- /dev/null +++ b/test/fixtures/locales--single/index.jade @@ -0,0 +1,5 @@ +ul + - for p in contentful.blog_posts + li + h1= p.title + p= p.body diff --git a/test/fixtures/locales--single/package.json b/test/fixtures/locales--single/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/locales--single/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/helpers/index.js b/test/helpers/index.js index 6702a0e..6ece651 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -39,11 +39,26 @@ export function mock_contentful (opts = {}) { opts = { entries: [{ sys: { sys: 'data' }, + locale: 'Default Locale', fields: { title: 'Default Title', body: 'Default Body' } }], + space: { + sys: { + type: 'Space', + id: 'cfexampleapi' + }, + name: 'Contentful Example API', + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }] + }, content_type: { name: 'Blog Post', displayField: 'title' @@ -56,8 +71,16 @@ export function mock_contentful (opts = {}) { contentType () { return Promise.resolve(opts.content_type) }, - entries () { - return Promise.resolve(opts.entries) + space () { + return Promise.resolve(opts.space) + }, + entries (req) { + if (req.locale == null) { + return Promise.resolve(opts.entries) + } + return Promise.resolve(opts.entries.filter( + entry => entry.sys.locale === req.locale + )) } } } diff --git a/test/locales/multi.js b/test/locales/multi.js new file mode 100644 index 0000000..40195ef --- /dev/null +++ b/test/locales/multi.js @@ -0,0 +1,56 @@ +import test from 'ava' +import { + async, + helpers, + mock_contentful, + unmock_contentful, + compile_fixture +} from '../helpers' + +let ctx = {} + +test.before(async t => { + let title = ['Throw Some Ds', "'op Ds chuH", "arrojar algo de Ds'"] + let body = [ + 'Rich boy selling crack', + "mIp loDHom ngev pe'vIl vaj pumDI' qoghlIj", + 'Niño rico venta de crack' + ] + ctx = { ...ctx, title, body } + mock_contentful({ + entries: [{ + fields: { title: title[0], body: body[0] }, + sys: { locale: 'en-US' } + }, { + fields: { title: title[1], body: body[1] }, + sys: { locale: 'tlh' } + }, { + fields: { title: title[2], body: body[2] }, + sys: { locale: 'en-es' } + }], + space: { + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }, { + code: 'en-es', + name: 'Spanish' + }] + } + }) + await ctx::compile_fixture('locales--multi') + ctx.index_path = `${ctx.public_dir}/index.html` +}) + +test('should render an array of global locales', async t => { + t.false(await helpers.file.contains(ctx.index_path, ctx.title[0], { async })) + t.true(await helpers.file.contains(ctx.index_path, ctx.title[1], { async })) + t.true(await helpers.file.contains(ctx.index_path, ctx.title[2], { async })) +}) + +test.after(async t => { + unmock_contentful() +}) diff --git a/test/locales/prefix.js b/test/locales/prefix.js new file mode 100644 index 0000000..ab1e13e --- /dev/null +++ b/test/locales/prefix.js @@ -0,0 +1,60 @@ +import test from 'ava' +import { + async, + helpers, + mock_contentful, + unmock_contentful, + compile_fixture +} from '../helpers' + +let ctx = {} + +test.before(async t => { + let title = ['Throw Some Ds', "'op Ds chuH", "arrojar algo de Ds'"] + let body = [ + 'Rich boy selling crack', + "mIp loDHom ngev pe'vIl vaj pumDI' qoghlIj", + 'Niño rico venta de crack' + ] + ctx = { ...ctx, title, body } + mock_contentful({ + entries: [{ + fields: { title: title[0], body: body[0] }, + sys: { locale: 'en-US' } + }, { + fields: { title: title[1], body: body[1] }, + sys: { locale: 'tlh' } + }, { + fields: { title: title[2], body: body[2] }, + sys: { locale: 'en-es' } + }], + space: { + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }, { + code: 'en-es', + name: 'Spanish' + }] + } + }) + await ctx::compile_fixture('locales--prefix') + ctx.klingon = `${ctx.public_dir}/klingon.html` + ctx.spanish = `${ctx.public_dir}/spanish.html` +}) + +test('should render the content type locale, not the global', async t => { + t.true(await helpers.file.contains(ctx.klingon, ctx.title[1], { async })) + t.true(await helpers.file.contains(ctx.klingon, ctx.body[1], { async })) + t.false(await helpers.file.contains(ctx.klingon, ctx.body[2], { async })) + t.true(await helpers.file.contains(ctx.spanish, ctx.title[2], { async })) + t.true(await helpers.file.contains(ctx.spanish, ctx.body[2], { async })) + t.false(await helpers.file.contains(ctx.spanish, ctx.body[1], { async })) +}) + +test.after(async t => { + unmock_contentful() +}) diff --git a/test/locales/scope.js b/test/locales/scope.js new file mode 100644 index 0000000..64adc73 --- /dev/null +++ b/test/locales/scope.js @@ -0,0 +1,57 @@ +import test from 'ava' +import { + async, + helpers, + mock_contentful, + unmock_contentful, + compile_fixture +} from '../helpers' + +let ctx = {} + +test.before(async t => { + let title = ['Throw Some Ds', "'op Ds chuH", "arrojar algo de Ds'"] + let body = [ + 'Rich boy selling crack', + "mIp loDHom ngev pe'vIl vaj pumDI' qoghlIj", + 'Niño rico venta de crack' + ] + ctx = { ...ctx, title, body } + mock_contentful({ + entries: [{ + fields: { title: title[0], body: body[0] }, + sys: { locale: 'en-US' } + }, { + fields: { title: title[1], body: body[1] }, + sys: { locale: 'tlh' } + }, { + fields: { title: title[2], body: body[2] }, + sys: { locale: 'en-es' } + }], + space: { + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }, { + code: 'en-es', + name: 'Spanish' + }] + } + }) + await ctx::compile_fixture('locales--scope') + ctx.index_path = `${ctx.public_dir}/index.html` +}) + +test('should render the content type locale, not the global', async t => { + t.false(await helpers.file.contains(ctx.index_path, ctx.title[1], { async })) + t.true(await helpers.file.contains(ctx.index_path, ctx.title[2], { async })) + t.false(await helpers.file.contains(ctx.index_path, ctx.body[1], { async })) + t.true(await helpers.file.contains(ctx.index_path, ctx.body[2], { async })) +}) + +test.after(async t => { + unmock_contentful() +}) diff --git a/test/locales/setup.js b/test/locales/setup.js new file mode 100644 index 0000000..6be4970 --- /dev/null +++ b/test/locales/setup.js @@ -0,0 +1,59 @@ +import test from 'ava' +import { + async, + helpers, + mock_contentful, + unmock_contentful, + compile_fixture +} from '../helpers' + +let ctx = {} + +test.before(async t => { + let title = ['Throw Some Ds', "'op Ds chuH", "arrojar algo de Ds'"] + let body = [ + 'Rich boy selling crack', + "mIp loDHom ngev pe'vIl vaj pumDI' qoghlIj", + 'Niño rico venta de crack' + ] + ctx = { ...ctx, title, body } + mock_contentful({ + entries: [{ + fields: { title: title[0], body: body[0] }, + sys: { locale: 'en-US' } + }, { + fields: { title: title[1], body: body[1] }, + sys: { locale: 'tlh' } + }, { + fields: { title: title[2], body: body[2] }, + sys: { locale: 'en-es' } + }], + space: { + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }, { + code: 'en-es', + name: 'Spanish' + }] + } + }) + await ctx::compile_fixture('locales--setup') + ctx.index_path = `${ctx.public_dir}/index.html` +}) + +test('should fetch all locales from * wildcard', async t => { + t.plan(6) + for (let title of ctx.title) { + let body = ctx.body[ctx.title.indexOf(title)] + t.true(await helpers.file.contains(ctx.index_path, title, { async })) + t.true(await helpers.file.contains(ctx.index_path, body, { async })) + } +}) + +test.after(async t => { + unmock_contentful() +}) diff --git a/test/locales/single.js b/test/locales/single.js new file mode 100644 index 0000000..80c98f2 --- /dev/null +++ b/test/locales/single.js @@ -0,0 +1,55 @@ +import test from 'ava' +import { + async, + helpers, + mock_contentful, + unmock_contentful, + compile_fixture +} from '../helpers' + +let ctx = {} + +test.before(async t => { + let title = ['Throw Some Ds', "'op Ds chuH", "arrojar algo de Ds'"] + let body = [ + 'Rich boy selling crack', + "mIp loDHom ngev pe'vIl vaj pumDI' qoghlIj", + 'Niño rico venta de crack' + ] + ctx = { ...ctx, title, body } + mock_contentful({ + entries: [{ + fields: { title: title[0], body: body[0] }, + sys: { locale: 'en-US' } + }, { + fields: { title: title[1], body: body[1] }, + sys: { locale: 'tlh' } + }, { + fields: { title: title[2], body: body[2] }, + sys: { locale: 'en-es' } + }], + space: { + locales: [{ + code: 'en-US', + name: 'English' + }, { + code: 'tlh', + name: 'Klingon' + }, { + code: 'en-es', + name: 'Spanish' + }] + } + }) + await ctx::compile_fixture('locales--single') + ctx.index_path = `${ctx.public_dir}/index.html` +}) + +test('should render a single global', async t => { + t.false(await helpers.file.contains(ctx.index_path, ctx.title[0], { async })) + t.true(await helpers.file.contains(ctx.index_path, ctx.title[1], { async })) +}) + +test.after(async t => { + unmock_contentful() +})