Feat: multi content authoring (#4139)
This commit is contained in:
59
cypress/integration/common/i18n.js
Normal file
59
cypress/integration/common/i18n.js
Normal file
@ -0,0 +1,59 @@
|
||||
import { newPost, populateEntry, publishEntry, flushClockAndSave } from '../../utils/steps';
|
||||
|
||||
const enterTranslation = str => {
|
||||
cy.get(`[id^="title-field"]`)
|
||||
.first()
|
||||
.clear({ force: true });
|
||||
cy.get(`[id^="title-field"]`)
|
||||
.first()
|
||||
.type(str, { force: true });
|
||||
};
|
||||
|
||||
const createAndTranslate = entry => {
|
||||
newPost();
|
||||
// fill the main entry
|
||||
populateEntry(entry, () => undefined);
|
||||
|
||||
// fill the translation
|
||||
cy.get('.Pane2').within(() => {
|
||||
enterTranslation('de');
|
||||
|
||||
cy.contains('span', 'Writing in DE').click();
|
||||
cy.contains('span', 'fr').click();
|
||||
|
||||
enterTranslation('fr');
|
||||
});
|
||||
};
|
||||
|
||||
export const updateTranslation = () => {
|
||||
cy.get('.Pane2').within(() => {
|
||||
enterTranslation('fr fr');
|
||||
|
||||
cy.contains('span', 'Writing in FR').click();
|
||||
cy.contains('span', 'de').click();
|
||||
|
||||
enterTranslation('de de');
|
||||
});
|
||||
flushClockAndSave();
|
||||
};
|
||||
|
||||
export const assertTranslation = () => {
|
||||
cy.get('.Pane2').within(() => {
|
||||
cy.get(`[id^="title-field"]`).should('have.value', 'de');
|
||||
|
||||
cy.contains('span', 'Writing in DE').click();
|
||||
cy.contains('span', 'fr').click();
|
||||
|
||||
cy.get(`[id^="title-field"]`).should('have.value', 'fr');
|
||||
});
|
||||
};
|
||||
|
||||
export const createEntryTranslateAndPublish = entry => {
|
||||
createAndTranslate(entry);
|
||||
publishEntry();
|
||||
};
|
||||
|
||||
export const createEntryTranslateAndSave = entry => {
|
||||
createAndTranslate(entry);
|
||||
flushClockAndSave();
|
||||
};
|
54
cypress/integration/common/i18n_editorial_workflow_spec.js
Normal file
54
cypress/integration/common/i18n_editorial_workflow_spec.js
Normal file
@ -0,0 +1,54 @@
|
||||
import '../../utils/dismiss-local-backup';
|
||||
import {
|
||||
login,
|
||||
goToWorkflow,
|
||||
updateWorkflowStatus,
|
||||
exitEditor,
|
||||
publishWorkflowEntry,
|
||||
goToEntry,
|
||||
updateWorkflowStatusInEditor,
|
||||
publishEntryInEditor,
|
||||
assertPublishedEntryInEditor,
|
||||
assertUnpublishedEntryInEditor,
|
||||
assertUnpublishedChangesInEditor,
|
||||
} from '../../utils/steps';
|
||||
import { createEntryTranslateAndSave, assertTranslation, updateTranslation } from './i18n';
|
||||
import { workflowStatus, editorStatus, publishTypes } from '../../utils/constants';
|
||||
|
||||
export default function({ entry, getUser }) {
|
||||
const structures = ['multiple_folders', 'multiple_files', 'single_file'];
|
||||
structures.forEach(structure => {
|
||||
it(`can create and publish entry with translation in ${structure} mode`, () => {
|
||||
cy.task('updateConfig', { i18n: { structure } });
|
||||
|
||||
login(getUser());
|
||||
|
||||
createEntryTranslateAndSave(entry);
|
||||
assertUnpublishedEntryInEditor();
|
||||
exitEditor();
|
||||
goToWorkflow();
|
||||
updateWorkflowStatus(entry, workflowStatus.draft, workflowStatus.ready);
|
||||
publishWorkflowEntry(entry);
|
||||
goToEntry(entry);
|
||||
assertTranslation();
|
||||
assertPublishedEntryInEditor();
|
||||
});
|
||||
|
||||
it(`can update translated entry in ${structure} mode`, () => {
|
||||
cy.task('updateConfig', { i18n: { structure: 'multiple_folders' } });
|
||||
|
||||
login(getUser());
|
||||
|
||||
createEntryTranslateAndSave(entry);
|
||||
assertUnpublishedEntryInEditor();
|
||||
updateWorkflowStatusInEditor(editorStatus.ready);
|
||||
publishEntryInEditor(publishTypes.publishNow);
|
||||
exitEditor();
|
||||
goToEntry(entry);
|
||||
assertTranslation();
|
||||
assertPublishedEntryInEditor();
|
||||
updateTranslation();
|
||||
assertUnpublishedChangesInEditor();
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import fixture from './common/i18n_editorial_workflow_spec';
|
||||
|
||||
const backend = 'test';
|
||||
|
||||
describe(`I18N Test Backend Editorial Workflow`, () => {
|
||||
const taskResult = { data: {} };
|
||||
|
||||
before(() => {
|
||||
Cypress.config('defaultCommandTimeout', 4000);
|
||||
cy.task('setupBackend', {
|
||||
backend,
|
||||
options: {
|
||||
publish_mode: 'editorial_workflow',
|
||||
i18n: {
|
||||
locales: ['en', 'de', 'fr'],
|
||||
},
|
||||
collections: [
|
||||
{
|
||||
folder: 'content/i18n',
|
||||
i18n: true,
|
||||
fields: [{ i18n: true }, {}, { i18n: 'duplicate' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.task('teardownBackend', { backend });
|
||||
});
|
||||
|
||||
const entry = {
|
||||
title: 'first title',
|
||||
body: 'first body',
|
||||
};
|
||||
|
||||
fixture({ entry, getUser: () => taskResult.data.user });
|
||||
});
|
@ -0,0 +1,148 @@
|
||||
import * as specUtils from './common/spec_utils';
|
||||
import { login } from '../utils/steps';
|
||||
import { createEntryTranslateAndPublish } from './common/i18n';
|
||||
|
||||
const backend = 'proxy';
|
||||
const mode = 'fs';
|
||||
|
||||
const expectedEnContent = `---
|
||||
template: post
|
||||
title: first title
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
description: first description
|
||||
category: first category
|
||||
tags:
|
||||
- tag1
|
||||
---
|
||||
`;
|
||||
|
||||
const expectedDeContent = `---
|
||||
title: de
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
---
|
||||
`;
|
||||
|
||||
const expectedFrContent = `---
|
||||
title: fr
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
---
|
||||
`;
|
||||
|
||||
const contentSingleFile = `---
|
||||
en:
|
||||
template: post
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
title: first title
|
||||
description: first description
|
||||
category: first category
|
||||
tags:
|
||||
- tag1
|
||||
body: first body
|
||||
de:
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
title: de
|
||||
fr:
|
||||
date: 1970-01-01T00:00:00.000Z
|
||||
title: fr
|
||||
---
|
||||
`;
|
||||
|
||||
describe(`I18N Proxy Backend Simple Workflow - '${mode}' mode`, () => {
|
||||
const taskResult = { data: {} };
|
||||
|
||||
const entry = {
|
||||
title: 'first title',
|
||||
body: 'first body',
|
||||
description: 'first description',
|
||||
category: 'first category',
|
||||
tags: 'tag1',
|
||||
};
|
||||
|
||||
before(() => {
|
||||
specUtils.before(
|
||||
taskResult,
|
||||
{
|
||||
mode,
|
||||
publish_mode: 'simple',
|
||||
i18n: {
|
||||
locales: ['en', 'de', 'fr'],
|
||||
},
|
||||
collections: [{ i18n: true, fields: [{}, { i18n: true }, {}, { i18n: 'duplicate' }] }],
|
||||
},
|
||||
backend,
|
||||
);
|
||||
Cypress.config('taskTimeout', 15 * 1000);
|
||||
Cypress.config('defaultCommandTimeout', 5 * 1000);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
specUtils.after(taskResult, backend);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
specUtils.beforeEach(taskResult, backend);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
specUtils.afterEach(taskResult, backend);
|
||||
});
|
||||
|
||||
it('can create entry with translation in locale_folders mode', () => {
|
||||
cy.task('updateConfig', { i18n: { structure: 'multiple_folders' } });
|
||||
|
||||
login(taskResult.data.user);
|
||||
|
||||
createEntryTranslateAndPublish(entry);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/en/1970-01-01-first-title.md`).should(
|
||||
'contain',
|
||||
expectedEnContent,
|
||||
);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/de/1970-01-01-first-title.md`).should(
|
||||
'eq',
|
||||
expectedDeContent,
|
||||
);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/fr/1970-01-01-first-title.md`).should(
|
||||
'eq',
|
||||
expectedFrContent,
|
||||
);
|
||||
});
|
||||
|
||||
it('can create entry with translation in single_file mode', () => {
|
||||
cy.task('updateConfig', { i18n: { structure: 'multiple_files' } });
|
||||
|
||||
login(taskResult.data.user);
|
||||
|
||||
createEntryTranslateAndPublish(entry);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/1970-01-01-first-title.en.md`).should(
|
||||
'contain',
|
||||
expectedEnContent,
|
||||
);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/1970-01-01-first-title.de.md`).should(
|
||||
'eq',
|
||||
expectedDeContent,
|
||||
);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/1970-01-01-first-title.fr.md`).should(
|
||||
'eq',
|
||||
expectedFrContent,
|
||||
);
|
||||
});
|
||||
|
||||
it('can create entry with translation in locale_file_extensions mode', () => {
|
||||
cy.task('updateConfig', { i18n: { structure: 'single_file' } });
|
||||
|
||||
login(taskResult.data.user);
|
||||
|
||||
createEntryTranslateAndPublish(entry);
|
||||
|
||||
cy.readFile(`${taskResult.data.tempDir}/content/posts/1970-01-01-first-title.md`).should(
|
||||
'eq',
|
||||
contentSingleFile,
|
||||
);
|
||||
});
|
||||
});
|
@ -67,7 +67,7 @@ function codeBlock(content) {
|
||||
<div>
|
||||
<div></div>
|
||||
<div>
|
||||
<div><label>Code Block</label>
|
||||
<div><label>Code Block </label>
|
||||
<div><button><span><svg>
|
||||
<path></path>
|
||||
</svg></span></button>
|
||||
|
@ -6,7 +6,7 @@ const backend = 'proxy';
|
||||
const mode = 'fs';
|
||||
|
||||
describe(`Proxy Backend Simple Workflow - '${mode}' mode`, () => {
|
||||
let taskResult = { data: {} };
|
||||
const taskResult = { data: {} };
|
||||
|
||||
before(() => {
|
||||
specUtils.before(taskResult, { publish_mode: 'simple', mode }, backend);
|
||||
|
Reference in New Issue
Block a user