mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-19 05:09:41 +02:00
Page creation basics (#7)
* Page cration basics * remove unused code * add client-side Header validation * remove static method * rm await duplication
This commit is contained in:
parent
5c0560a2ed
commit
073772c047
17 changed files with 476 additions and 93 deletions
|
@ -13,6 +13,7 @@
|
||||||
"@babel/polyfill": "^7.0.0",
|
"@babel/polyfill": "^7.0.0",
|
||||||
"body-parser": "latest",
|
"body-parser": "latest",
|
||||||
"codex.editor": "^2.0.11",
|
"codex.editor": "^2.0.11",
|
||||||
|
"codex.editor.header": "^2.0.5",
|
||||||
"cookie-parser": "~1.4.3",
|
"cookie-parser": "~1.4.3",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
"express": "~4.16.0",
|
"express": "~4.16.0",
|
||||||
|
|
27
public/dist/editor.bundle.js
vendored
27
public/dist/editor.bundle.js
vendored
File diff suppressed because one or more lines are too long
4
public/dist/main.bundle.js
vendored
4
public/dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/main.css
vendored
2
public/dist/main.css
vendored
|
@ -1 +1 @@
|
||||||
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}:root{--color-line-gray:#e8e8eb;--color-link-active:#388ae5;--color-text-main:#1d202b;--color-text-second:#7b7e89;--layout-padding-horisontal:40px;--layout-width-aside:250px;--layout-width-main-col:650px}.docs{display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 40px;padding:0 var(--layout-padding-horisontal)}.docs__aside{width:250px;width:var(--layout-width-aside)}.docs__content{-webkit-box-flex:2;-ms-flex-positive:2;flex-grow:2;word-wrap:break-word}.docs__content-inner{margin:0 auto;max-width:650px;max-width:var(--layout-width-main-col)}.docs__aside,.docs__content{padding:40px 0}.docs-header{border-bottom:1px solid #e8e8eb;border-bottom:1px solid var(--color-line-gray);display:-webkit-box;display:-ms-flexbox;display:flex;font-size:15.8px;line-height:50px;padding:0 40px;padding:0 var(--layout-padding-horisontal)}.docs-header a{display:inline-block;text-decoration:none}.docs-header__logo{color:inherit;font-weight:700}.docs-header__menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin:0 0 0 auto}.docs-header__menu li{list-style:none;margin-left:20px}.docs-header__menu a:not(.docs-header__button){color:inherit}.docs-header__menu a:not(.docs-header__button):hover{color:#388ae5;color:var(--color-link-active)}.docs-header__button{background:#388ae5;background:var(--color-link-active);border-radius:3px;color:#fff;display:inline-block;font-size:14px;line-height:1em;padding:9px 15px}.docs-header__button svg{margin:0 .3em 0 -.05em}.docs-header__button:hover{background:#387ecc}.docs-header__button{margin:auto 30px auto auto}.docs-aside{color:#7b7e89;color:var(--color-text-second);font-size:15px}.docs-aside a{text-decoration:none}.docs-aside__section{margin-bottom:30px}.docs-aside__section-title{color:#388ae5;color:var(--color-link-active);margin-bottom:15px}.docs-aside__section-list{list-style:none;padding-left:0}.docs-aside__section-list a{color:inherit;display:inline-block;padding:8px 0}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#1d202b;color:var(--color-text-main);font-family:system-ui,-apple-system,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Helvetica,Arial,Verdana}svg{fill:currentColor}
|
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}:root{--color-line-gray:#e8e8eb;--color-link-active:#388ae5;--color-text-main:#1d202b;--color-text-second:#7b7e89;--layout-padding-horisontal:40px;--layout-padding-vertical:40px;--layout-width-aside:250px;--layout-width-main-col:650px}.docs{display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 40px;padding:0 var(--layout-padding-horisontal)}.docs__aside{width:250px;width:var(--layout-width-aside)}.docs__content{-webkit-box-flex:2;-ms-flex-positive:2;flex-grow:2;word-wrap:break-word}.docs__content-inner{margin:0 auto;max-width:650px;max-width:var(--layout-width-main-col)}.docs__aside,.docs__content{padding:40px 0;padding:var(--layout-padding-vertical) 0}.docs-header{border-bottom:1px solid #e8e8eb;border-bottom:1px solid var(--color-line-gray);display:-webkit-box;display:-ms-flexbox;display:flex;font-size:15.8px;line-height:50px;padding:0 40px;padding:0 var(--layout-padding-horisontal)}.docs-header a{display:inline-block;text-decoration:none}.docs-header__logo{color:inherit;font-weight:700}.docs-header__menu{display:-webkit-box;display:-ms-flexbox;display:flex;margin:0 0 0 auto}.docs-header__menu li{list-style:none;margin-left:20px}.docs-header__menu a:not(.docs-header__button){color:inherit}.docs-header__menu a:not(.docs-header__button):hover{color:#388ae5;color:var(--color-link-active)}.docs-header__button{background:#388ae5;background:var(--color-link-active);border-radius:3px;color:#fff;display:inline-block;font-size:14px;line-height:1em;padding:9px 15px}.docs-header__button svg{margin:0 .3em 0 -.05em}.docs-header__button:hover{background:#387ecc}.docs-header__button{margin:auto 30px auto auto}.docs-aside{color:#7b7e89;color:var(--color-text-second);font-size:15px}.docs-aside a{text-decoration:none}.docs-aside__section{margin-bottom:30px}.docs-aside__section-title{color:#388ae5;color:var(--color-link-active);margin-bottom:15px}.docs-aside__section-list{list-style:none;padding-left:0}.docs-aside__section-list a{color:inherit;display:inline-block;padding:8px 0}.writing-header{background:#fff;-webkit-box-shadow:0 3px 10px #fff;box-shadow:0 3px 10px #fff;display:-webkit-box;display:-ms-flexbox;display:flex;margin-top:-40px;margin-top:calc(-1 * var(--layout-padding-vertical));padding:15px 0;position:-webkit-sticky;position:sticky;top:0;z-index:2}.writing-header__save{background:#388ae5;background:var(--color-link-active);border-radius:3px;color:#fff;display:inline-block;font-size:14px;line-height:1em;padding:9px 15px}.writing-header__save svg{margin:0 .3em 0 -.05em}.writing-header__save:hover{background:#387ecc}.writing-header__save{margin-left:auto}.writing-header__left{color:#7b7e89;color:var(--color-text-second);margin:auto 0}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#1d202b;color:var(--color-text-main);font-family:system-ui,-apple-system,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Helvetica,Arial,Verdana}svg{fill:currentColor}
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Pages {
|
||||||
* @returns {['title', 'body']}
|
* @returns {['title', 'body']}
|
||||||
*/
|
*/
|
||||||
static get REQUIRED_FIELDS() {
|
static get REQUIRED_FIELDS() {
|
||||||
return ['title', 'body'];
|
return [ 'body' ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,23 +48,47 @@ class Pages {
|
||||||
* @returns {Promise<Page>}
|
* @returns {Promise<Page>}
|
||||||
*/
|
*/
|
||||||
static async insert(data) {
|
static async insert(data) {
|
||||||
if (!Pages.validate(data)) {
|
try {
|
||||||
throw new Error('Invalid request format');
|
Pages.validate(data);
|
||||||
|
|
||||||
|
const page = new Model(data);
|
||||||
|
|
||||||
|
return page.save();
|
||||||
|
} catch (validationError) {
|
||||||
|
throw new Error(validationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = new Model(data);
|
|
||||||
|
|
||||||
return page.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check PageData object for required fields
|
* Check PageData object for required fields
|
||||||
*
|
*
|
||||||
* @param {PageData} data
|
* @param {PageData} data
|
||||||
* @returns {boolean}
|
* @throws {Error} - validation error
|
||||||
*/
|
*/
|
||||||
static validate(data) {
|
static validate(data) {
|
||||||
return Pages.REQUIRED_FIELDS.every(field => typeof data[field] !== 'undefined');
|
const allRequiredFields = Pages.REQUIRED_FIELDS.every(field => typeof data[field] !== 'undefined');
|
||||||
|
|
||||||
|
if (!allRequiredFields) {
|
||||||
|
throw new Error('Some of required fields is missed');
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasBlocks = data.body && data.body.blocks && Array.isArray(data.body.blocks) && data.body.blocks.length > 0;
|
||||||
|
|
||||||
|
if (!hasBlocks) {
|
||||||
|
throw new Error('Page body is invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasHeaderAsFirstBlock = data.body.blocks[0].type === 'header';
|
||||||
|
|
||||||
|
if (!hasHeaderAsFirstBlock) {
|
||||||
|
throw new Error('First page Block must be a Header');
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerIsNotEmpty = data.body.blocks[0].data.text.replace('<br>', '').trim() !== '';
|
||||||
|
|
||||||
|
if (!headerIsNotEmpty) {
|
||||||
|
throw new Error('Please, fill page Header');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,42 @@
|
||||||
import CodeXEditor from 'codex.editor';
|
import CodeXEditor from 'codex.editor';
|
||||||
|
import Header from 'codex.editor.header';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for working with Editor.js
|
||||||
|
*/
|
||||||
export default class Editor {
|
export default class Editor {
|
||||||
|
/**
|
||||||
|
* Creates Editor instance
|
||||||
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.editor = new CodeXEditor();
|
this.editor = new CodeXEditor({
|
||||||
|
tools: {
|
||||||
|
header: {
|
||||||
|
class: Header,
|
||||||
|
config: {
|
||||||
|
placeholder: 'Enter a title'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: '',
|
||||||
|
level: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return Editor data
|
||||||
|
* @return {Promise.<{}>}
|
||||||
|
*/
|
||||||
|
save() {
|
||||||
|
return this.editor.saver.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,115 @@
|
||||||
/**
|
/**
|
||||||
* Module for pages create/edit
|
* Module for pages create/edit
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @typedef {object} editorData
|
||||||
|
* @property {{type, data}[]} blocks - array of Blocks
|
||||||
|
* @property {string} version - used Editor version
|
||||||
|
* @property {number} time - saving time
|
||||||
|
*/
|
||||||
|
|
||||||
export default class Writing {
|
export default class Writing {
|
||||||
|
/**
|
||||||
|
* Creates base properties
|
||||||
|
*/
|
||||||
constructor(){
|
constructor(){
|
||||||
this.editorWrapper = null;
|
|
||||||
this.editor = null;
|
this.editor = null;
|
||||||
|
this.nodes = {
|
||||||
|
editorWrapper: null,
|
||||||
|
saveButton: null,
|
||||||
|
parentIdSelector: null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by ModuleDispatcher to initialize module from DOM
|
* Called by ModuleDispatcher to initialize module from DOM
|
||||||
|
* @param {object} settings - module settings
|
||||||
|
* @param {HTMLElement} moduleEl - module element
|
||||||
*/
|
*/
|
||||||
init(config, moduleEl) {
|
init(settings, moduleEl) {
|
||||||
this.editorWrapper = document.createElement('div');
|
/**
|
||||||
this.editorWrapper.id = 'codex-editor';
|
* Create Editor
|
||||||
|
*/
|
||||||
|
this.nodes.editorWrapper = document.createElement('div');
|
||||||
|
this.nodes.editorWrapper.id = 'codex-editor';
|
||||||
|
|
||||||
moduleEl.appendChild(this.editorWrapper);
|
moduleEl.appendChild(this.nodes.editorWrapper);
|
||||||
|
|
||||||
this.loadEditor().then((editor) => {
|
this.loadEditor().then((editor) => {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
})
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate form elements
|
||||||
|
*/
|
||||||
|
this.nodes.saveButton = moduleEl.querySelector('[name="js-submit"]');
|
||||||
|
this.nodes.saveButton.addEventListener('click', () => {
|
||||||
|
this.saveButtonClicked();
|
||||||
|
});
|
||||||
|
this.nodes.parentIdSelector = moduleEl.querySelector('[name="parent"]');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads class for working with Editor
|
||||||
|
* @return {Promise<Editor>}
|
||||||
|
*/
|
||||||
async loadEditor(){
|
async loadEditor(){
|
||||||
const {default: Editor} = await import(/* webpackChunkName: "editor" */ './../classes/editor');
|
const {default: Editor} = await import(/* webpackChunkName: "editor" */ './../classes/editor');
|
||||||
|
|
||||||
return new Editor();
|
return new Editor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all writing form data
|
||||||
|
* @throws {Error} - validation error
|
||||||
|
* @return {Promise.<{parent: string, body: {editorData}}>}
|
||||||
|
*/
|
||||||
|
async getData(){
|
||||||
|
const editorData = await this.editor.save();
|
||||||
|
const firstBlock = editorData.blocks.length ? editorData.blocks[0] : null;
|
||||||
|
const title = firstBlock && firstBlock.type === 'header' ? firstBlock.data.text : null;
|
||||||
|
|
||||||
|
if (!title) {
|
||||||
|
throw new Error('Entry should start with Header');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
parent: this.nodes.parentIdSelector.value,
|
||||||
|
body: editorData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for clicks on the Save button
|
||||||
|
*/
|
||||||
|
async saveButtonClicked(){
|
||||||
|
try {
|
||||||
|
const writingData = await this.getData();
|
||||||
|
|
||||||
|
try {
|
||||||
|
let response = await fetch('/page', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(writingData),
|
||||||
|
});
|
||||||
|
|
||||||
|
response = await response.json();
|
||||||
|
|
||||||
|
if (response.success){
|
||||||
|
document.location = '/page/' + response.result._id;
|
||||||
|
} else {
|
||||||
|
alert(response.error);
|
||||||
|
console.log('Validation failed:', response.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (sendingError) {
|
||||||
|
console.log('Saving request failed:', sendingError);
|
||||||
|
}
|
||||||
|
} catch (savingError){
|
||||||
|
alert(savingError);
|
||||||
|
console.log('Saving error: ', savingError);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/frontend/styles/components/writing.pcss
Normal file
20
src/frontend/styles/components/writing.pcss
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
.writing-header {
|
||||||
|
display: flex;
|
||||||
|
padding: 15px 0;
|
||||||
|
margin-top: calc(-1 * var(--layout-padding-vertical));
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 2;
|
||||||
|
box-shadow: 0 3px 10px #fff;
|
||||||
|
|
||||||
|
&__save {
|
||||||
|
@apply --button;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left {
|
||||||
|
margin: auto 0;
|
||||||
|
color: var(--color-text-second);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,6 @@
|
||||||
|
|
||||||
&__aside,
|
&__aside,
|
||||||
&__content {
|
&__content {
|
||||||
padding: 40px 0;
|
padding: var(--layout-padding-vertical) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
@import url('layout.pcss');
|
@import url('layout.pcss');
|
||||||
@import url('components/header.pcss');
|
@import url('components/header.pcss');
|
||||||
@import url('components/aside.pcss');
|
@import url('components/aside.pcss');
|
||||||
|
@import url('components/writing.pcss');
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: system-ui, Helvetica, Arial, Verdana;
|
font-family: system-ui, Helvetica, Arial, Verdana;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Site layout sizes
|
* Site layout sizes
|
||||||
*/
|
*/
|
||||||
--layout-padding-horisontal: 40px;
|
--layout-padding-horisontal: 40px;
|
||||||
|
--layout-padding-vertical: 40px;
|
||||||
--layout-width-aside: 250px;
|
--layout-width-aside: 250px;
|
||||||
--layout-width-main-col: 650px;
|
--layout-width-main-col: 650px;
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,10 @@ class Page {
|
||||||
* @param {PageData} pageData
|
* @param {PageData} pageData
|
||||||
*/
|
*/
|
||||||
set data(pageData) {
|
set data(pageData) {
|
||||||
const {title, body, parent} = pageData;
|
const {body, parent} = pageData;
|
||||||
|
|
||||||
this.title = title || this.title;
|
|
||||||
this.body = body || this.body;
|
this.body = body || this.body;
|
||||||
|
this.title = this.extractTitleFromBody();
|
||||||
this._parent = parent || this._parent;
|
this._parent = parent || this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,16 @@ class Page {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract first header from editor data
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
extractTitleFromBody() {
|
||||||
|
const headerBlock = this.body ? this.body.blocks.find(block => block.type === 'header') : '';
|
||||||
|
|
||||||
|
return headerBlock ? headerBlock.data.text : '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link given page as parent
|
* Link given page as parent
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,7 +7,11 @@ const Pages = require('../controllers/pages');
|
||||||
* Create new page form
|
* Create new page form
|
||||||
*/
|
*/
|
||||||
router.get('/page/new', async (req, res) => {
|
router.get('/page/new', async (req, res) => {
|
||||||
res.render('pages/form');
|
let pagesAvailable = await Pages.getAll();
|
||||||
|
|
||||||
|
res.render('pages/form', {
|
||||||
|
pagesAvailable
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,25 @@
|
||||||
{% extends 'layout.twig' %}
|
{% extends 'layout.twig' %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
<style>
|
||||||
|
.docs-header__button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<section data-module="writing">
|
<section data-module="writing">
|
||||||
|
<header class="writing-header">
|
||||||
|
<span class="writing-header__left">
|
||||||
|
New Page at the
|
||||||
|
<select name="parent">
|
||||||
|
<option value="0">Root</option>
|
||||||
|
{% for page in pagesAvailable %}
|
||||||
|
<option value="{{ page._id }}">{{ page.title }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
<span class="writing-header__save" name="js-submit">
|
||||||
|
Save
|
||||||
|
</span>
|
||||||
|
</header>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -11,7 +11,7 @@ describe('Page model', () => {
|
||||||
let {data} = page;
|
let {data} = page;
|
||||||
|
|
||||||
expect(data._id).to.be.undefined;
|
expect(data._id).to.be.undefined;
|
||||||
expect(data.title).to.be.undefined;
|
expect(data.title).to.be.empty;
|
||||||
expect(data.body).to.be.undefined;
|
expect(data.body).to.be.undefined;
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
|
|
||||||
|
@ -20,11 +20,23 @@ describe('Page model', () => {
|
||||||
data = page.data;
|
data = page.data;
|
||||||
|
|
||||||
expect(data._id).to.be.undefined;
|
expect(data._id).to.be.undefined;
|
||||||
expect(data.title).to.be.undefined;
|
expect(data.title).to.be.empty;
|
||||||
expect(data.body).to.be.undefined;
|
expect(data.body).to.be.undefined;
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
|
|
||||||
const initialData = {_id: 'page_id', title: 'Test page', body: 'Test page body'};
|
const initialData = {
|
||||||
|
_id: 'page_id',
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
page = new Page(initialData);
|
page = new Page(initialData);
|
||||||
|
|
||||||
|
@ -33,19 +45,27 @@ describe('Page model', () => {
|
||||||
data = page.data;
|
data = page.data;
|
||||||
|
|
||||||
expect(data._id).to.equal(initialData._id);
|
expect(data._id).to.equal(initialData._id);
|
||||||
expect(data.title).to.equal(initialData.title);
|
expect(data.title).to.equal(initialData.body.blocks[0].data.text);
|
||||||
expect(data.body).to.equal(initialData.body);
|
expect(data.body).to.deep.equal(initialData.body);
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
|
|
||||||
expect(json._id).to.equal(initialData._id);
|
expect(json._id).to.equal(initialData._id);
|
||||||
expect(json.title).to.equal(initialData.title);
|
expect(json.title).to.equal(initialData.body.blocks[0].data.text);
|
||||||
expect(json.body).to.equal(initialData.body);
|
expect(json.body).to.deep.equal(initialData.body);
|
||||||
expect(json.parent).to.be.undefined;
|
expect(json.parent).to.be.undefined;
|
||||||
|
|
||||||
const update = {
|
const update = {
|
||||||
_id: 12345,
|
_id: 12345,
|
||||||
title: 'Test page',
|
body: {
|
||||||
body: 'Test page body'
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Updated page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
page.data = update;
|
page.data = update;
|
||||||
|
@ -53,19 +73,30 @@ describe('Page model', () => {
|
||||||
data = page.data;
|
data = page.data;
|
||||||
|
|
||||||
expect(data._id).to.equal(initialData._id);
|
expect(data._id).to.equal(initialData._id);
|
||||||
expect(data.title).to.equal(update.title);
|
expect(data.title).to.equal(update.body.blocks[0].data.text);
|
||||||
expect(data.body).to.equal(update.body);
|
expect(data.body).to.equal(update.body);
|
||||||
expect(data.parent).to.be.undefined;
|
expect(data.parent).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Saving, updating and deleting model in the database', async () => {
|
it('Saving, updating and deleting model in the database', async () => {
|
||||||
const initialData = {title: 'Test page', body: 'Test page body'};
|
const initialData = {
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
const page = new Page(initialData);
|
const page = new Page(initialData);
|
||||||
|
|
||||||
let savedPage = await page.save();
|
let savedPage = await page.save();
|
||||||
|
|
||||||
expect(savedPage._id).not.be.undefined;
|
expect(savedPage._id).not.be.undefined;
|
||||||
expect(savedPage.title).to.equal(initialData.title);
|
expect(savedPage.title).to.equal(initialData.body.blocks[0].data.text);
|
||||||
expect(savedPage.body).to.equal(initialData.body);
|
expect(savedPage.body).to.equal(initialData.body);
|
||||||
expect(page._id).not.be.undefined;
|
expect(page._id).not.be.undefined;
|
||||||
|
|
||||||
|
@ -73,9 +104,20 @@ describe('Page model', () => {
|
||||||
|
|
||||||
expect(insertedPage._id).to.equal(page._id);
|
expect(insertedPage._id).to.equal(page._id);
|
||||||
expect(insertedPage.title).to.equal(page.title);
|
expect(insertedPage.title).to.equal(page.title);
|
||||||
expect(insertedPage.body).to.equal(page.body);
|
expect(insertedPage.body).to.deep.equal(page.body);
|
||||||
|
|
||||||
const updateData = {title: 'Updated test page', body: 'Updated test page body'};
|
const updateData = {
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Updated page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
page.data = updateData;
|
page.data = updateData;
|
||||||
await page.save();
|
await page.save();
|
||||||
|
@ -85,8 +127,8 @@ describe('Page model', () => {
|
||||||
const updatedPage = await pages.findOne({_id: page._id});
|
const updatedPage = await pages.findOne({_id: page._id});
|
||||||
|
|
||||||
expect(updatedPage._id).to.equal(savedPage._id);
|
expect(updatedPage._id).to.equal(savedPage._id);
|
||||||
expect(updatedPage.title).to.equal(updateData.title);
|
expect(updatedPage.title).to.equal(updateData.body.blocks[0].data.text);
|
||||||
expect(updatedPage.body).to.equal(updateData.body);
|
expect(updatedPage.body).to.deep.equal(updateData.body);
|
||||||
|
|
||||||
await page.destroy();
|
await page.destroy();
|
||||||
|
|
||||||
|
@ -98,7 +140,18 @@ describe('Page model', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Static get method', async () => {
|
it('Static get method', async () => {
|
||||||
const initialData = {title: 'Test page', body: 'Test page body'};
|
const initialData = {
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Test Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
const page = new Page(initialData);
|
const page = new Page(initialData);
|
||||||
|
|
||||||
const savedPage = await page.save();
|
const savedPage = await page.save();
|
||||||
|
@ -108,16 +161,38 @@ describe('Page model', () => {
|
||||||
const {data} = foundPage;
|
const {data} = foundPage;
|
||||||
|
|
||||||
expect(data._id).to.equal(savedPage._id);
|
expect(data._id).to.equal(savedPage._id);
|
||||||
expect(data.title).to.equal(initialData.title);
|
expect(data.title).to.equal(initialData.body.blocks[0].data.text);
|
||||||
expect(data.body).to.equal(initialData.body);
|
expect(data.body).to.deep.equal(initialData.body);
|
||||||
|
|
||||||
await page.destroy();
|
await page.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Static getAll method', async () => {
|
it('Static getAll method', async () => {
|
||||||
const pagesToSave = [
|
const pagesToSave = [
|
||||||
new Page({title: 'Page 1', body: 'Page 1 body'}),
|
new Page({
|
||||||
new Page({title: 'Page 2', body: 'Page 2 body'})
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page 1 header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Page({
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page 2 header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
const savedPages = await Promise.all(pagesToSave.map(page => page.save()));
|
const savedPages = await Promise.all(pagesToSave.map(page => page.save()));
|
||||||
|
@ -126,16 +201,42 @@ describe('Page model', () => {
|
||||||
|
|
||||||
expect(foundPages.length).to.equal(2);
|
expect(foundPages.length).to.equal(2);
|
||||||
foundPages.forEach((page, i) => {
|
foundPages.forEach((page, i) => {
|
||||||
expect(page.title).to.equal(pagesToSave[i].title);
|
expect(page.title).to.equal(pagesToSave[i].body.blocks[0].data.text);
|
||||||
expect(page.body).to.equal(pagesToSave[i].body);
|
expect(page.body).to.deep.equal(pagesToSave[i].body);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Parent pages', async () => {
|
it('Parent pages', async () => {
|
||||||
const parent = new Page({title: 'Parent page', body: 'Parent page body'});
|
const parent = new Page(
|
||||||
|
{
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Parent page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
const {_id: parentId} = await parent.save();
|
const {_id: parentId} = await parent.save();
|
||||||
|
|
||||||
const child = new Page({title: 'Child page', body: 'Child page body'});
|
const child = new Page(
|
||||||
|
{
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Child page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
child.parent = parent;
|
child.parent = parent;
|
||||||
|
|
||||||
|
@ -144,8 +245,8 @@ describe('Page model', () => {
|
||||||
const testedParent = await child.parent;
|
const testedParent = await child.parent;
|
||||||
|
|
||||||
expect(testedParent._id).to.equal(parentId);
|
expect(testedParent._id).to.equal(parentId);
|
||||||
expect(testedParent.title).to.equal(parent.title);
|
expect(testedParent.title).to.equal(parent.body.blocks[0].data.text);
|
||||||
expect(testedParent.body).to.equal(parent.body);
|
expect(testedParent.body).to.deep.equal(parent.body);
|
||||||
|
|
||||||
const children = await parent.children;
|
const children = await parent.children;
|
||||||
|
|
||||||
|
@ -154,12 +255,31 @@ describe('Page model', () => {
|
||||||
const testedChild = children.pop();
|
const testedChild = children.pop();
|
||||||
|
|
||||||
expect(testedChild._id).to.equal(childId);
|
expect(testedChild._id).to.equal(childId);
|
||||||
expect(testedChild.title).to.equal(child.title);
|
expect(testedChild.title).to.equal(child.body.blocks[0].data.text);
|
||||||
expect(testedChild.body).to.equal(child.body);
|
expect(testedChild.body).to.deep.equal(child.body);
|
||||||
expect(testedChild._parent).to.equal(child._parent);
|
expect(testedChild._parent).to.equal(child._parent);
|
||||||
expect(testedChild._parent).to.equal(parent._id);
|
expect(testedChild._parent).to.equal(parent._id);
|
||||||
|
|
||||||
parent.destroy();
|
parent.destroy();
|
||||||
child.destroy();
|
child.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Extracting title from page body', async () => {
|
||||||
|
const pageData = {
|
||||||
|
body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const page = new Page(pageData);
|
||||||
|
|
||||||
|
expect(page.title).to.equal(pageData.body.blocks[0].data.text);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,12 +15,20 @@ describe('Pages REST: ', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Creating page', async () => {
|
it('Creating page', async () => {
|
||||||
const title = 'Test page';
|
const body = {
|
||||||
const body = 'Test page body';
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
const res = await agent
|
const res = await agent
|
||||||
.put('/page')
|
.put('/page')
|
||||||
.send({title, body});
|
.send({body});
|
||||||
|
|
||||||
expect(res).to.have.status(200);
|
expect(res).to.have.status(200);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
@ -29,15 +37,15 @@ describe('Pages REST: ', () => {
|
||||||
|
|
||||||
expect(success).to.be.true;
|
expect(success).to.be.true;
|
||||||
expect(result._id).to.be.a('string');
|
expect(result._id).to.be.a('string');
|
||||||
expect(result.title).to.equal(title);
|
expect(result.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(result.body).to.equal(body);
|
expect(result.body).to.deep.equal(body);
|
||||||
|
|
||||||
const createdPage = await model.get(result._id);
|
const createdPage = await model.get(result._id);
|
||||||
|
|
||||||
expect(createdPage).not.be.null;
|
expect(createdPage).not.be.null;
|
||||||
expect(createdPage._id).to.equal(result._id);
|
expect(createdPage._id).to.equal(result._id);
|
||||||
expect(createdPage.title).to.equal(title);
|
expect(createdPage.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(createdPage.body).to.equal(body);
|
expect(createdPage.body).to.deep.equal(body);
|
||||||
|
|
||||||
createdPage.destroy();
|
createdPage.destroy();
|
||||||
});
|
});
|
||||||
|
@ -53,16 +61,24 @@ describe('Pages REST: ', () => {
|
||||||
const {success, error} = res.body;
|
const {success, error} = res.body;
|
||||||
|
|
||||||
expect(success).to.be.false;
|
expect(success).to.be.false;
|
||||||
expect(error).to.equal('Invalid request format');
|
expect(error).to.equal('Error: Some of required fields is missed');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Finding page', async () => {
|
it('Finding page', async () => {
|
||||||
const title = 'Test page';
|
const body = {
|
||||||
const body = 'Test page body';
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
const put = await agent
|
const put = await agent
|
||||||
.put('/page')
|
.put('/page')
|
||||||
.send({title, body});
|
.send({body});
|
||||||
|
|
||||||
expect(put).to.have.status(200);
|
expect(put).to.have.status(200);
|
||||||
expect(put).to.be.json;
|
expect(put).to.be.json;
|
||||||
|
@ -81,8 +97,8 @@ describe('Pages REST: ', () => {
|
||||||
const foundPage = await model.get(_id);
|
const foundPage = await model.get(_id);
|
||||||
|
|
||||||
expect(foundPage._id).to.equal(_id);
|
expect(foundPage._id).to.equal(_id);
|
||||||
expect(foundPage.title).to.equal(title);
|
expect(foundPage.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(foundPage.body).to.equal(body);
|
expect(foundPage.body).to.deep.equal(body);
|
||||||
|
|
||||||
foundPage.destroy();
|
foundPage.destroy();
|
||||||
});
|
});
|
||||||
|
@ -100,24 +116,40 @@ describe('Pages REST: ', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Updating page', async () => {
|
it('Updating page', async () => {
|
||||||
const title = 'Test page';
|
const body = {
|
||||||
const body = 'Test page body';
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
let res = await agent
|
let res = await agent
|
||||||
.put('/page')
|
.put('/page')
|
||||||
.send({title, body});
|
.send({body});
|
||||||
|
|
||||||
expect(res).to.have.status(200);
|
expect(res).to.have.status(200);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
|
||||||
const {result: {_id}} = res.body;
|
const {result: {_id}} = res.body;
|
||||||
|
|
||||||
const updatedTitle = 'Updated test page';
|
const updatedBody = {
|
||||||
const updatedBody = 'Updated test page body';
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Updated page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
res = await agent
|
res = await agent
|
||||||
.post(`/page/${_id}`)
|
.post(`/page/${_id}`)
|
||||||
.send({title: updatedTitle, body: updatedBody});
|
.send({body: updatedBody});
|
||||||
|
|
||||||
expect(res).to.have.status(200);
|
expect(res).to.have.status(200);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
@ -126,26 +158,35 @@ describe('Pages REST: ', () => {
|
||||||
|
|
||||||
expect(success).to.be.true;
|
expect(success).to.be.true;
|
||||||
expect(result._id).to.equal(_id);
|
expect(result._id).to.equal(_id);
|
||||||
expect(result.title).not.equal(title);
|
expect(result.title).not.equal(body.blocks[0].data.text);
|
||||||
expect(result.title).to.equal(updatedTitle);
|
expect(result.title).to.equal(updatedBody.blocks[0].data.text);
|
||||||
expect(result.body).not.equal(body);
|
expect(result.body).not.equal(body);
|
||||||
expect(result.body).to.equal(updatedBody);
|
expect(result.body).to.deep.equal(updatedBody);
|
||||||
|
|
||||||
const updatedPage = await model.get(_id);
|
const updatedPage = await model.get(_id);
|
||||||
|
|
||||||
expect(updatedPage._id).to.equal(_id);
|
expect(updatedPage._id).to.equal(_id);
|
||||||
expect(updatedPage.title).not.equal(title);
|
expect(updatedPage.title).not.equal(body.blocks[0].data.text);
|
||||||
expect(updatedPage.title).to.equal(updatedTitle);
|
expect(updatedPage.title).to.equal(updatedBody.blocks[0].data.text);
|
||||||
expect(updatedPage.body).not.equal(body);
|
expect(updatedPage.body).not.equal(body);
|
||||||
expect(updatedPage.body).to.equal(updatedBody);
|
expect(updatedPage.body).to.deep.equal(updatedBody);
|
||||||
|
|
||||||
updatedPage.destroy();
|
updatedPage.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Updating page with not existing id', async () => {
|
it('Updating page with not existing id', async () => {
|
||||||
const res = await agent
|
const res = await agent
|
||||||
. post('/page/not-existing-id')
|
.post('/page/not-existing-id')
|
||||||
.send({title: 'Updated title', body: 'Updated body'});
|
.send({body: {
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}});
|
||||||
|
|
||||||
expect(res).to.have.status(400);
|
expect(res).to.have.status(400);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
@ -157,12 +198,20 @@ describe('Pages REST: ', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Removing page', async () => {
|
it('Removing page', async () => {
|
||||||
const title = 'Test page';
|
const body = {
|
||||||
const body = 'Test page body';
|
blocks: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
data: {
|
||||||
|
text: 'Page header'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
let res = await agent
|
let res = await agent
|
||||||
.put('/page')
|
.put('/page')
|
||||||
.send({title, body});
|
.send({body});
|
||||||
|
|
||||||
expect(res).to.have.status(200);
|
expect(res).to.have.status(200);
|
||||||
expect(res).to.be.json;
|
expect(res).to.be.json;
|
||||||
|
@ -179,8 +228,8 @@ describe('Pages REST: ', () => {
|
||||||
|
|
||||||
expect(success).to.be.true;
|
expect(success).to.be.true;
|
||||||
expect(result._id).to.be.undefined;
|
expect(result._id).to.be.undefined;
|
||||||
expect(result.title).to.equal(title);
|
expect(result.title).to.equal(body.blocks[0].data.text);
|
||||||
expect(result.body).to.equal(body);
|
expect(result.body).to.deep.equal(body);
|
||||||
|
|
||||||
const deletedPage = await model.get(_id);
|
const deletedPage = await model.get(_id);
|
||||||
|
|
||||||
|
|
|
@ -1453,6 +1453,10 @@ code-point-at@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||||
|
|
||||||
|
codex.editor.header@^2.0.5:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/codex.editor.header/-/codex.editor.header-2.0.5.tgz#fe0cc7d710b090e877499b7d9951ea36fddfbdc9"
|
||||||
|
|
||||||
codex.editor@^2.0.11:
|
codex.editor@^2.0.11:
|
||||||
version "2.0.11"
|
version "2.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/codex.editor/-/codex.editor-2.0.11.tgz#c45bb2c85888f96c129a6bfb01b0268f06768e15"
|
resolved "https://registry.yarnpkg.com/codex.editor/-/codex.editor-2.0.11.tgz#c45bb2c85888f96c129a6bfb01b0268f06768e15"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue