Skip to content

Commit

Permalink
feat: read translation slugs from frontmatter (#43)
Browse files Browse the repository at this point in the history
* chore: enhance translate node test
* chore: enhance translateNode
* feat: resolute translations via nodes
  • Loading branch information
openscript committed Jul 7, 2022
1 parent 6ddf58b commit 4245b62
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 114 deletions.
228 changes: 128 additions & 100 deletions src/onCreateNode/translateNode.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import fs from 'fs/promises';
import { PluginOptions } from '../../types';
import { translateNode } from './translateNode';

jest.mock('fs/promises');

const options: PluginOptions = {
defaultLocale: `en-US`,
siteUrl: '',
Expand All @@ -21,8 +18,8 @@ const options: PluginOptions = {
messages: {},
},
{
locale: `zh-CN`,
prefix: `zh`,
locale: `fr-FR`,
prefix: `fr`,
slugs: {},
messages: {},
},
Expand All @@ -31,109 +28,156 @@ const options: PluginOptions = {
};

const node = {
parent: '1',
id: 'm0',
parent: '0',
internal: {
type: 'MarkdownRemark',
},
frontmatter: {
title: '',
title: 'Impressum',
},
};

let createNodeField = jest.fn();
const allNodes = [
{
id: '0',
internal: {
type: 'File',
},
base: 'imprint.de.md',
relativeDirectory: 'pages',
dir: '/tmp/project/content/pages',
absolutePath: '/tmp/project/content/pages/imprint.de.md',
children: ['m0'],
},
{
id: '1',
internal: {
type: 'File',
},
base: 'another.de.md',
relativeDirectory: 'pages',
dir: '/tmp/project/content/pages',
absolutePath: '/tmp/project/content/pages/another.de.md',
},
{
id: '2',
internal: {
type: 'File',
},
base: 'imprint.en.md',
relativeDirectory: 'pages',
dir: '/tmp/project/content/pages',
absolutePath: '/tmp/project/content/pages/imprint.en.md',
children: ['m2'],
},
{
id: '3',
internal: {
type: 'File',
},
base: 'imprint.fr.md',
relativeDirectory: 'pages',
dir: '/tmp/project/content/pages',
absolutePath: '/tmp/project/content/pages/imprint.fr.md',
children: ['m1'],
},
{
id: '4',
internal: {
type: 'File',
},
base: 'more.de.md',
relativeDirectory: 'sections/special',
dir: '/tmp/project/content/sections',
absolutePath: '/tmp/project/content/sections/special/more.de.md',
},
{ ...node },
{
id: 'm1',
parent: '0',
internal: {
type: 'MarkdownRemark',
},
frontmatter: {
title: 'Imprimer',
},
},
{
id: 'm2',
parent: '0',
internal: {
type: 'MarkdownRemark',
},
frontmatter: {
title: 'Imprint',
},
},
];

const createNodeField = jest.fn();
const getNode = jest.fn().mockImplementation((id: string) => allNodes.find((n) => n.id === id));
const getNodes = jest.fn().mockReturnValue(allNodes);
const args: any = {
getNode,
getNodes,
node,
actions: {
createNodeField,
},
};

describe('translateNode', () => {
beforeEach(() => {
createNodeField = jest.fn();
jest.clearAllMocks();
});

it('should create nodes with translation information', async () => {
fs.readdir = jest.fn().mockReturnValue(['page.en.md', 'page.zh-CN.md']);

const parentNode = {
name: 'page.de.md',
relativeDirectory: 'pages',
absolutePath: '/tmp/project/content/pages/page.de.md',
};

const args: any = {
getNode: jest.fn().mockReturnValue(parentNode),
node,
actions: {
createNodeField,
},
};

await translateNode(args, options);

expect(createNodeField).toHaveBeenNthCalledWith(1, { node, name: 'locale', value: 'de-CH' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'page' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'imprint' });
expect(createNodeField).toHaveBeenNthCalledWith(3, { node, name: 'kind', value: 'pages' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'page' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/pages/page' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/pages/impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(6, { node, name: 'pathPrefix', value: 'de' });
expect(createNodeField).toHaveBeenNthCalledWith(7, {
node,
name: 'translations',
value: [
{ locale: 'en-US', path: '/pages/page' },
{ locale: 'zh-CN', path: '/zh/pages/page' },
{ locale: 'en-US', path: '/pages/imprint' },
{ locale: 'fr-FR', path: '/fr/pages/imprimer' },
],
});
});

it('should create nodes with accurate kind description', async () => {
fs.readdir = jest.fn().mockReturnValue(['section.en.md', 'section.zh-CN.md']);

const parentNode = {
name: 'section.de.md',
relativeDirectory: 'sections/special',
absolutePath: '/tmp/project/content/sections/special/section.de.md',
};

const args: any = {
getNode: jest.fn().mockReturnValue(parentNode),
node,
actions: {
createNodeField,
it('should create nodes which are nested in folders', async () => {
const currentNode = {
parent: '4',
internal: {
type: 'MarkdownRemark',
},
};

await translateNode(args, options);

expect(createNodeField).toHaveBeenNthCalledWith(1, { node, name: 'locale', value: 'de-CH' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'section' });
expect(createNodeField).toHaveBeenNthCalledWith(3, { node, name: 'kind', value: 'sections/special' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'section' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/sections/special/section' });
expect(createNodeField).toHaveBeenNthCalledWith(6, { node, name: 'pathPrefix', value: 'de' });
const currentArgs = {
...args,
node: currentNode,
};
await translateNode(currentArgs, options);

expect(createNodeField).toHaveBeenNthCalledWith(1, { node: currentNode, name: 'locale', value: 'de-CH' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node: currentNode, name: 'filename', value: 'more' });
expect(createNodeField).toHaveBeenNthCalledWith(3, { node: currentNode, name: 'kind', value: 'sections/special' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node: currentNode, name: 'slug', value: 'more' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node: currentNode, name: 'path', value: '/de/sections/special/more' });
expect(createNodeField).toHaveBeenNthCalledWith(6, { node: currentNode, name: 'pathPrefix', value: 'de' });
expect(createNodeField).toHaveBeenNthCalledWith(7, {
node,
node: currentNode,
name: 'translations',
value: [
{ locale: 'en-US', path: '/sections/special/section' },
{ locale: 'zh-CN', path: '/zh/sections/special/section' },
],
value: [],
});
});

it('should remote blacklisted path segments when translating nodes', async () => {
fs.readdir = jest.fn().mockReturnValue(['page.en.md', 'page.zh-CN.md']);

const parentNode = {
name: 'page.de.md',
relativeDirectory: 'pages',
absolutePath: '/tmp/project/content/pages/page.de.md',
};

const args: any = {
getNode: jest.fn().mockReturnValue(parentNode),
node,
actions: {
createNodeField,
},
};

const currentOptions: PluginOptions = {
...options,
pathBlacklist: [`/pages`],
Expand All @@ -142,38 +186,22 @@ describe('translateNode', () => {
await translateNode(args, currentOptions);

expect(createNodeField).toHaveBeenNthCalledWith(1, { node, name: 'locale', value: 'de-CH' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'page' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'imprint' });
expect(createNodeField).toHaveBeenNthCalledWith(3, { node, name: 'kind', value: 'pages' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'page' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/page' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(6, { node, name: 'pathPrefix', value: 'de' });
expect(createNodeField).toHaveBeenNthCalledWith(7, {
node,
name: 'translations',
value: [
{ locale: 'en-US', path: '/page' },
{ locale: 'zh-CN', path: '/zh/page' },
{ locale: 'en-US', path: '/imprint' },
{ locale: 'fr-FR', path: '/fr/imprimer' },
],
});
});

it('should translate slugs', async () => {
fs.readdir = jest.fn().mockReturnValue(['imprint.en.md', 'imprint.fr.md']);

const parentNode = {
name: 'imprint.de.md',
relativeDirectory: 'pages',
absolutePath: '/tmp/project/content/pages/imprint.de.md',
};

const args: any = {
getNode: jest.fn().mockReturnValue(parentNode),
node,
actions: {
createNodeField,
},
};

const currentOptions: PluginOptions = {
defaultLocale: `en-US`,
siteUrl: '',
Expand All @@ -188,15 +216,15 @@ describe('translateNode', () => {
locale: `de-CH`,
prefix: `de`,
slugs: {
'/imprint': '/impressum',
'/pages': '/seiten',
},
messages: {},
},
{
locale: `fr-FR`,
prefix: `fr`,
slugs: {
'/imprint': '/imprimer',
'/pages': '/feuilles', // I know it's not a literal translation
},
messages: {},
},
Expand All @@ -209,15 +237,15 @@ describe('translateNode', () => {
expect(createNodeField).toHaveBeenNthCalledWith(1, { node, name: 'locale', value: 'de-CH' });
expect(createNodeField).toHaveBeenNthCalledWith(2, { node, name: 'filename', value: 'imprint' });
expect(createNodeField).toHaveBeenNthCalledWith(3, { node, name: 'kind', value: 'pages' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'imprint' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/pages/impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(4, { node, name: 'slug', value: 'impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(5, { node, name: 'path', value: '/de/seiten/impressum' });
expect(createNodeField).toHaveBeenNthCalledWith(6, { node, name: 'pathPrefix', value: 'de' });
expect(createNodeField).toHaveBeenNthCalledWith(7, {
node,
name: 'translations',
value: [
{ locale: 'en-US', path: '/pages/imprint' },
{ locale: 'fr-FR', path: '/fr/pages/imprimer' },
{ locale: 'fr-FR', path: '/fr/feuilles/imprimer' },
],
});
});
Expand Down
Loading

0 comments on commit 4245b62

Please sign in to comment.