Commit ccfc0e69 authored by Mark Florian's avatar Mark Florian

Merge branch '241002-edit-drawer' into 'master'

Wire-up EditDrawer with FrontMatterControls

Closes #241003

See merge request gitlab-org/gitlab!41920
parents c528db83 1da27551
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue'; import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
import PublishToolbar from './publish_toolbar.vue'; import PublishToolbar from './publish_toolbar.vue';
import EditHeader from './edit_header.vue'; import EditHeader from './edit_header.vue';
import EditDrawer from './edit_drawer.vue';
import UnsavedChangesConfirmDialog from './unsaved_changes_confirm_dialog.vue'; import UnsavedChangesConfirmDialog from './unsaved_changes_confirm_dialog.vue';
import parseSourceFile from '~/static_site_editor/services/parse_source_file'; import parseSourceFile from '~/static_site_editor/services/parse_source_file';
import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/constants'; import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/constants';
...@@ -15,6 +16,7 @@ export default { ...@@ -15,6 +16,7 @@ export default {
RichContentEditor, RichContentEditor,
PublishToolbar, PublishToolbar,
EditHeader, EditHeader,
EditDrawer,
UnsavedChangesConfirmDialog, UnsavedChangesConfirmDialog,
}, },
props: { props: {
...@@ -48,6 +50,8 @@ export default { ...@@ -48,6 +50,8 @@ export default {
parsedSource: parseSourceFile(this.preProcess(true, this.content)), parsedSource: parseSourceFile(this.preProcess(true, this.content)),
editorMode: EDITOR_TYPES.wysiwyg, editorMode: EDITOR_TYPES.wysiwyg,
isModified: false, isModified: false,
hasMatter: false,
isDrawerOpen: false,
}; };
}, },
imageRepository: imageRepository(), imageRepository: imageRepository(),
...@@ -55,10 +59,19 @@ export default { ...@@ -55,10 +59,19 @@ export default {
editableContent() { editableContent() {
return this.parsedSource.content(this.isWysiwygMode); return this.parsedSource.content(this.isWysiwygMode);
}, },
editableMatter() {
return this.isDrawerOpen ? this.parsedSource.matter() : {};
},
hasSettings() {
return this.hasMatter && this.isWysiwygMode;
},
isWysiwygMode() { isWysiwygMode() {
return this.editorMode === EDITOR_TYPES.wysiwyg; return this.editorMode === EDITOR_TYPES.wysiwyg;
}, },
}, },
created() {
this.refreshEditHelpers();
},
methods: { methods: {
preProcess(isWrap, value) { preProcess(isWrap, value) {
const formattedContent = formatter(value); const formattedContent = formatter(value);
...@@ -67,9 +80,21 @@ export default { ...@@ -67,9 +80,21 @@ export default {
: templater.unwrap(formattedContent); : templater.unwrap(formattedContent);
return templatedContent; return templatedContent;
}, },
refreshEditHelpers() {
this.isModified = this.parsedSource.isModified();
this.hasMatter = this.parsedSource.hasMatter();
},
onDrawerOpen() {
this.isDrawerOpen = true;
this.refreshEditHelpers();
},
onDrawerClose() {
this.isDrawerOpen = false;
this.refreshEditHelpers();
},
onInputChange(newVal) { onInputChange(newVal) {
this.parsedSource.syncContent(newVal, this.isWysiwygMode); this.parsedSource.syncContent(newVal, this.isWysiwygMode);
this.isModified = this.parsedSource.isModified(); this.refreshEditHelpers();
}, },
onModeChange(mode) { onModeChange(mode) {
this.editorMode = mode; this.editorMode = mode;
...@@ -77,6 +102,9 @@ export default { ...@@ -77,6 +102,9 @@ export default {
const preProcessedContent = this.preProcess(this.isWysiwygMode, this.editableContent); const preProcessedContent = this.preProcess(this.isWysiwygMode, this.editableContent);
this.$refs.editor.resetInitialValue(preProcessedContent); this.$refs.editor.resetInitialValue(preProcessedContent);
}, },
onUpdateSettings(settings) {
this.parsedSource.syncMatter(settings);
},
onUploadImage({ file, imageUrl }) { onUploadImage({ file, imageUrl }) {
this.$options.imageRepository.add(file, imageUrl); this.$options.imageRepository.add(file, imageUrl);
}, },
...@@ -93,6 +121,13 @@ export default { ...@@ -93,6 +121,13 @@ export default {
<template> <template>
<div class="d-flex flex-grow-1 flex-column h-100"> <div class="d-flex flex-grow-1 flex-column h-100">
<edit-header class="py-2" :title="title" /> <edit-header class="py-2" :title="title" />
<edit-drawer
v-if="hasMatter"
:is-open="isDrawerOpen"
:settings="editableMatter"
@close="onDrawerClose"
@updateSettings="onUpdateSettings"
/>
<rich-content-editor <rich-content-editor
ref="editor" ref="editor"
:content="editableContent" :content="editableContent"
...@@ -106,9 +141,11 @@ export default { ...@@ -106,9 +141,11 @@ export default {
<unsaved-changes-confirm-dialog :modified="isModified" /> <unsaved-changes-confirm-dialog :modified="isModified" />
<publish-toolbar <publish-toolbar
class="gl-fixed gl-left-0 gl-bottom-0 gl-w-full" class="gl-fixed gl-left-0 gl-bottom-0 gl-w-full"
:has-settings="hasSettings"
:return-url="returnUrl" :return-url="returnUrl"
:saveable="isModified" :saveable="isModified"
:saving-changes="savingChanges" :saving-changes="savingChanges"
@editSettings="onDrawerOpen"
@submit="onSubmit" @submit="onSubmit"
/> />
</div> </div>
......
<script>
import { GlDrawer } from '@gitlab/ui';
import FrontMatterControls from './front_matter_controls.vue';
export default {
components: {
GlDrawer,
FrontMatterControls,
},
props: {
isOpen: {
type: Boolean,
required: true,
},
settings: {
type: Object,
required: true,
},
},
};
</script>
<template>
<gl-drawer class="pt-6" :open="isOpen" @close="$emit('close')">
<template #header>{{ __('Page settings') }}</template>
<template>
<front-matter-controls
:settings="settings"
@updateSettings="$emit('updateSettings', $event)"
/>
</template>
</gl-drawer>
</template>
...@@ -6,6 +6,11 @@ export default { ...@@ -6,6 +6,11 @@ export default {
GlButton, GlButton,
}, },
props: { props: {
hasSettings: {
type: Boolean,
required: false,
default: false,
},
returnUrl: { returnUrl: {
type: String, type: String,
required: false, required: false,
...@@ -31,12 +36,21 @@ export default { ...@@ -31,12 +36,21 @@ export default {
s__('StaticSiteEditor|Return to site') s__('StaticSiteEditor|Return to site')
}}</gl-button> }}</gl-button>
<gl-button <gl-button
v-if="hasSettings"
ref="settings"
:disabled="savingChanges"
@click="$emit('editSettings')"
>
{{ __('Settings') }}
</gl-button>
<gl-button
ref="submit"
variant="success" variant="success"
:disabled="!saveable" :disabled="!saveable"
:loading="savingChanges" :loading="savingChanges"
@click="$emit('submit')" @click="$emit('submit')"
> >
<span>{{ __('Submit Changes') }}</span> {{ __('Submit changes') }}
</gl-button> </gl-button>
</div> </div>
</div> </div>
......
...@@ -17,33 +17,24 @@ const parseSourceFile = raw => { ...@@ -17,33 +17,24 @@ const parseSourceFile = raw => {
const content = (isBody = false) => (isBody ? editable.content.trim() : trimmedEditable()); // gray-matter internally adds an eof newline so we trim to bypass, open issue: https://github.com/jonschlinkert/gray-matter/issues/96 const content = (isBody = false) => (isBody ? editable.content.trim() : trimmedEditable()); // gray-matter internally adds an eof newline so we trim to bypass, open issue: https://github.com/jonschlinkert/gray-matter/issues/96
const matter = () => editable.matter; const matter = () => editable.data;
const syncMatter = newMatter => {
const targetMatter = newMatter.replace(/---/gm, ''); // TODO dynamic delimiter removal vs. hard code
const currentMatter = matter();
const currentContent = content();
const newSource = currentContent.replace(currentMatter, targetMatter);
syncContent(newSource);
editable.matter = newMatter;
};
const matterObject = () => editable.data;
const syncMatterObject = obj => { const syncMatter = settings => {
editable.data = obj; const source = grayMatter.stringify(editable.content, settings);
syncContent(source);
}; };
const isModified = () => trimmedEditable() !== raw; const isModified = () => trimmedEditable() !== raw;
const hasMatter = () => editable.matter.length > 0;
return { return {
matter, matter,
syncMatter, syncMatter,
matterObject,
syncMatterObject,
content, content,
syncContent, syncContent,
isModified, isModified,
hasMatter,
}; };
}; };
......
---
title: Add a front matter editing UI in WYSIWYG mode of the Static Site Editor
merge_request: 41920
author:
type: added
...@@ -18102,6 +18102,9 @@ msgstr "" ...@@ -18102,6 +18102,9 @@ msgstr ""
msgid "Page not found" msgid "Page not found"
msgstr "" msgstr ""
msgid "Page settings"
msgstr ""
msgid "Page was successfully deleted" msgid "Page was successfully deleted"
msgstr "" msgstr ""
...@@ -24336,15 +24339,15 @@ msgstr "" ...@@ -24336,15 +24339,15 @@ msgstr ""
msgid "Submit %{humanized_resource_name}" msgid "Submit %{humanized_resource_name}"
msgstr "" msgstr ""
msgid "Submit Changes"
msgstr ""
msgid "Submit a review" msgid "Submit a review"
msgstr "" msgstr ""
msgid "Submit as spam" msgid "Submit as spam"
msgstr "" msgstr ""
msgid "Submit changes"
msgstr ""
msgid "Submit feedback" msgid "Submit feedback"
msgstr "" msgstr ""
......
...@@ -6,11 +6,13 @@ import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/consta ...@@ -6,11 +6,13 @@ import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/consta
import EditArea from '~/static_site_editor/components/edit_area.vue'; import EditArea from '~/static_site_editor/components/edit_area.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue'; import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue'; import EditHeader from '~/static_site_editor/components/edit_header.vue';
import EditDrawer from '~/static_site_editor/components/edit_drawer.vue';
import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue'; import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
import { import {
sourceContentTitle as title, sourceContentTitle as title,
sourceContentYAML as content, sourceContentYAML as content,
sourceContentHeaderObjYAML as headerSettings,
sourceContentBody as body, sourceContentBody as body,
returnUrl, returnUrl,
} from '../mock_data'; } from '../mock_data';
...@@ -36,6 +38,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => { ...@@ -36,6 +38,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
}; };
const findEditHeader = () => wrapper.find(EditHeader); const findEditHeader = () => wrapper.find(EditHeader);
const findEditDrawer = () => wrapper.find(EditDrawer);
const findRichContentEditor = () => wrapper.find(RichContentEditor); const findRichContentEditor = () => wrapper.find(RichContentEditor);
const findPublishToolbar = () => wrapper.find(PublishToolbar); const findPublishToolbar = () => wrapper.find(PublishToolbar);
const findUnsavedChangesConfirmDialog = () => wrapper.find(UnsavedChangesConfirmDialog); const findUnsavedChangesConfirmDialog = () => wrapper.find(UnsavedChangesConfirmDialog);
...@@ -46,6 +49,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => { ...@@ -46,6 +49,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
it('renders edit header', () => { it('renders edit header', () => {
...@@ -53,6 +57,10 @@ describe('~/static_site_editor/components/edit_area.vue', () => { ...@@ -53,6 +57,10 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
expect(findEditHeader().props('title')).toBe(title); expect(findEditHeader().props('title')).toBe(title);
}); });
it('renders edit drawer', () => {
expect(findEditDrawer().exists()).toBe(true);
});
it('renders rich content editor with a format pass', () => { it('renders rich content editor with a format pass', () => {
expect(findRichContentEditor().exists()).toBe(true); expect(findRichContentEditor().exists()).toBe(true);
expect(findRichContentEditor().props('content')).toBe(formattedBody); expect(findRichContentEditor().props('content')).toBe(formattedBody);
...@@ -148,11 +156,88 @@ describe('~/static_site_editor/components/edit_area.vue', () => { ...@@ -148,11 +156,88 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
}); });
}); });
describe('when content has front matter', () => {
it('renders a closed edit drawer', () => {
expect(findEditDrawer().exists()).toBe(true);
expect(findEditDrawer().props('isOpen')).toBe(false);
});
it('opens the edit drawer', () => {
findPublishToolbar().vm.$emit('editSettings');
return wrapper.vm.$nextTick().then(() => {
expect(findEditDrawer().props('isOpen')).toBe(true);
});
});
it('closes the edit drawer', () => {
findEditDrawer().vm.$emit('close');
return wrapper.vm.$nextTick().then(() => {
expect(findEditDrawer().props('isOpen')).toBe(false);
});
});
it('forwards the matter settings when the drawer is open', () => {
findPublishToolbar().vm.$emit('editSettings');
jest.spyOn(wrapper.vm.parsedSource, 'matter').mockReturnValueOnce(headerSettings);
return wrapper.vm.$nextTick().then(() => {
expect(findEditDrawer().props('settings')).toEqual(headerSettings);
});
});
it('enables toolbar submit button', () => {
expect(findPublishToolbar().props('hasSettings')).toBe(true);
});
it('syncs matter changes regardless of edit mode', () => {
const newSettings = { title: 'test' };
const spySyncParsedSource = jest.spyOn(wrapper.vm.parsedSource, 'syncMatter');
findEditDrawer().vm.$emit('updateSettings', newSettings);
expect(spySyncParsedSource).toHaveBeenCalledWith(newSettings);
});
it('syncs matter changes to content in markdown mode', () => {
wrapper.setData({ editorMode: EDITOR_TYPES.markdown });
const newSettings = { title: 'test' };
findEditDrawer().vm.$emit('updateSettings', newSettings);
return wrapper.vm.$nextTick().then(() => {
expect(findRichContentEditor().props('content')).toContain('title: test');
});
});
});
describe('when content lacks front matter', () => {
beforeEach(() => {
buildWrapper({ content: body });
});
afterEach(() => {
wrapper.destroy();
});
it('does not render edit drawer', () => {
expect(findEditDrawer().exists()).toBe(false);
});
it('does not enable toolbar submit button', () => {
expect(findPublishToolbar().props('hasSettings')).toBe(false);
});
});
describe('when content is submitted', () => { describe('when content is submitted', () => {
it('should format the content', () => { it('should format the content', () => {
findPublishToolbar().vm.$emit('submit', content); findPublishToolbar().vm.$emit('submit', content);
expect(wrapper.emitted('submit')[0][0].content).toBe(`${content} format-pass format-pass`); expect(wrapper.emitted('submit')[0][0].content).toBe(`${content} format-pass format-pass`);
expect(wrapper.emitted('submit').length).toBe(1);
}); });
}); });
}); });
import { shallowMount } from '@vue/test-utils';
import { GlDrawer } from '@gitlab/ui';
import EditDrawer from '~/static_site_editor/components/edit_drawer.vue';
import FrontMatterControls from '~/static_site_editor/components/front_matter_controls.vue';
describe('~/static_site_editor/components/edit_drawer.vue', () => {
let wrapper;
const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(EditDrawer, {
propsData: {
isOpen: false,
settings: { title: 'Some title' },
...propsData,
},
});
};
const findFrontMatterControls = () => wrapper.find(FrontMatterControls);
const findGlDrawer = () => wrapper.find(GlDrawer);
beforeEach(() => {
buildWrapper();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders the GlDrawer', () => {
expect(findGlDrawer().exists()).toBe(true);
});
it('renders the FrontMatterControls', () => {
expect(findFrontMatterControls().exists()).toBe(true);
});
it('forwards the settings to FrontMatterControls', () => {
expect(findFrontMatterControls().props('settings')).toBe(wrapper.props('settings'));
});
it('is closed by default', () => {
expect(findGlDrawer().props('open')).toBe(false);
});
it('can open', () => {
buildWrapper({ isOpen: true });
expect(findGlDrawer().props('open')).toBe(true);
});
it.each`
event | payload | finderFn
${'close'} | ${undefined} | ${findGlDrawer}
${'updateSettings'} | ${{ some: 'data' }} | ${findFrontMatterControls}
`(
'forwards the emitted $event event from the $finderFn with $payload',
({ event, payload, finderFn }) => {
finderFn().vm.$emit(event, payload);
expect(wrapper.emitted(event)[0][0]).toBe(payload);
expect(wrapper.emitted(event).length).toBe(1);
},
);
});
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue'; import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
...@@ -11,6 +10,7 @@ describe('Static Site Editor Toolbar', () => { ...@@ -11,6 +10,7 @@ describe('Static Site Editor Toolbar', () => {
const buildWrapper = (propsData = {}) => { const buildWrapper = (propsData = {}) => {
wrapper = shallowMount(PublishToolbar, { wrapper = shallowMount(PublishToolbar, {
propsData: { propsData: {
hasSettings: false,
saveable: false, saveable: false,
...propsData, ...propsData,
}, },
...@@ -18,7 +18,8 @@ describe('Static Site Editor Toolbar', () => { ...@@ -18,7 +18,8 @@ describe('Static Site Editor Toolbar', () => {
}; };
const findReturnUrlLink = () => wrapper.find({ ref: 'returnUrlLink' }); const findReturnUrlLink = () => wrapper.find({ ref: 'returnUrlLink' });
const findSaveChangesButton = () => wrapper.find(GlButton); const findSaveChangesButton = () => wrapper.find({ ref: 'submit' });
const findEditSettingsButton = () => wrapper.find({ ref: 'settings' });
beforeEach(() => { beforeEach(() => {
buildWrapper(); buildWrapper();
...@@ -28,6 +29,10 @@ describe('Static Site Editor Toolbar', () => { ...@@ -28,6 +29,10 @@ describe('Static Site Editor Toolbar', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('does not render Settings button', () => {
expect(findEditSettingsButton().exists()).toBe(false);
});
it('renders Submit Changes button', () => { it('renders Submit Changes button', () => {
expect(findSaveChangesButton().exists()).toBe(true); expect(findSaveChangesButton().exists()).toBe(true);
}); });
...@@ -51,6 +56,14 @@ describe('Static Site Editor Toolbar', () => { ...@@ -51,6 +56,14 @@ describe('Static Site Editor Toolbar', () => {
expect(findReturnUrlLink().attributes('href')).toBe(returnUrl); expect(findReturnUrlLink().attributes('href')).toBe(returnUrl);
}); });
describe('when providing settings CTA', () => {
it('enables Submit Changes button', () => {
buildWrapper({ hasSettings: true });
expect(findEditSettingsButton().exists()).toBe(true);
});
});
describe('when saveable', () => { describe('when saveable', () => {
it('enables Submit Changes button', () => { it('enables Submit Changes button', () => {
buildWrapper({ saveable: true }); buildWrapper({ saveable: true });
......
...@@ -16,16 +16,12 @@ describe('static_site_editor/services/parse_source_file', () => { ...@@ -16,16 +16,12 @@ describe('static_site_editor/services/parse_source_file', () => {
describe('unmodified front matter', () => { describe('unmodified front matter', () => {
it.each` it.each`
parsedSource | targetFrontMatter parsedSource
${parseSourceFile(content)} | ${yamlFrontMatter} ${parseSourceFile(content)}
${parseSourceFile(contentComplex)} | ${yamlFrontMatter} ${parseSourceFile(contentComplex)}
`( `('returns $targetFrontMatter when frontMatter queried', ({ parsedSource }) => {
'returns $targetFrontMatter when frontMatter queried', expect(parsedSource.matter()).toEqual(yamlFrontMatterObj);
({ parsedSource, targetFrontMatter }) => { });
expect(targetFrontMatter).toContain(parsedSource.matter());
expect(parsedSource.matterObject()).toEqual(yamlFrontMatterObj);
},
);
}); });
describe('unmodified content', () => { describe('unmodified content', () => {
...@@ -69,12 +65,11 @@ describe('static_site_editor/services/parse_source_file', () => { ...@@ -69,12 +65,11 @@ describe('static_site_editor/services/parse_source_file', () => {
`( `(
'returns the correct front matter and modified content', 'returns the correct front matter and modified content',
({ parsedSource, targetContent }) => { ({ parsedSource, targetContent }) => {
expect(yamlFrontMatter).toContain(parsedSource.matter()); expect(parsedSource.matter()).toMatchObject(yamlFrontMatterObj);
parsedSource.syncMatter(newYamlFrontMatter); parsedSource.syncMatter(newYamlFrontMatterObj);
expect(parsedSource.matter()).toBe(newYamlFrontMatter); expect(parsedSource.matter()).toMatchObject(newYamlFrontMatterObj);
expect(parsedSource.matterObject()).toEqual(newYamlFrontMatterObj);
expect(parsedSource.content()).toBe(targetContent); expect(parsedSource.content()).toBe(targetContent);
}, },
); );
...@@ -85,16 +80,19 @@ describe('static_site_editor/services/parse_source_file', () => { ...@@ -85,16 +80,19 @@ describe('static_site_editor/services/parse_source_file', () => {
const newComplexBody = `${complexBody} ${edit}`; const newComplexBody = `${complexBody} ${edit}`;
it.each` it.each`
parsedSource | isModified | targetRaw | targetBody parsedSource | hasMatter | isModified | targetRaw | targetBody
${parseSourceFile(content)} | ${false} | ${content} | ${body} ${parseSourceFile(content)} | ${true} | ${false} | ${content} | ${body}
${parseSourceFile(content)} | ${true} | ${newContent} | ${newBody} ${parseSourceFile(content)} | ${true} | ${true} | ${newContent} | ${newBody}
${parseSourceFile(contentComplex)} | ${false} | ${contentComplex} | ${complexBody} ${parseSourceFile(contentComplex)} | ${true} | ${false} | ${contentComplex} | ${complexBody}
${parseSourceFile(contentComplex)} | ${true} | ${newContentComplex} | ${newComplexBody} ${parseSourceFile(contentComplex)} | ${true} | ${true} | ${newContentComplex} | ${newComplexBody}
${parseSourceFile(body)} | ${false} | ${false} | ${body} | ${body}
${parseSourceFile(body)} | ${false} | ${true} | ${newBody} | ${newBody}
`( `(
'returns $isModified after a $targetRaw sync', 'returns $isModified after a $targetRaw sync',
({ parsedSource, isModified, targetRaw, targetBody }) => { ({ parsedSource, hasMatter, isModified, targetRaw, targetBody }) => {
parsedSource.syncContent(targetRaw); parsedSource.syncContent(targetRaw);
expect(parsedSource.hasMatter()).toBe(hasMatter);
expect(parsedSource.isModified()).toBe(isModified); expect(parsedSource.isModified()).toBe(isModified);
expect(parsedSource.content()).toBe(targetRaw); expect(parsedSource.content()).toBe(targetRaw);
expect(parsedSource.content(true)).toBe(targetBody); expect(parsedSource.content(true)).toBe(targetBody);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment