diff options
author | Tim Zallmann <tzallmann@gitlab.com> | 2018-04-03 11:36:16 +0200 |
---|---|---|
committer | Tim Zallmann <tzallmann@gitlab.com> | 2018-04-03 11:36:16 +0200 |
commit | 9ac851cc52297fdd338dc98da90d43cb3e56d046 (patch) | |
tree | f1755a371a7f60a93f71f4f083873fc0f362e1b0 | |
parent | 9b395ca5496ab6368af33a236c220f0660d3bf2c (diff) | |
download | gitlab-ce-tz-ide-markdown-preview.tar.gz |
Added Tests for new componenttz-ide-markdown-preview
12 files changed, 158 insertions, 28 deletions
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index c77aabd3fb5..cd5b7fec4a6 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -66,7 +66,6 @@ export default { class="multi-file-edit-pane-content" :file="activeFile" /> - <ide-status-bar :file="activeFile" /> diff --git a/app/assets/javascripts/ide/components/repo_file_buttons.vue b/app/assets/javascripts/ide/components/ide_file_buttons.vue index 2aaade75adf..6d07329df71 100644 --- a/app/assets/javascripts/ide/components/repo_file_buttons.vue +++ b/app/assets/javascripts/ide/components/ide_file_buttons.vue @@ -38,7 +38,7 @@ export default { v-tooltip :href="file.blamePath" :title="__('Blame')" - class="btn btn-xs btn-transparent" + class="btn btn-xs btn-transparent blame" > <icon name="blame" @@ -49,7 +49,7 @@ export default { v-tooltip :href="file.commitsPath" :title="__('History')" - class="btn btn-xs btn-transparent" + class="btn btn-xs btn-transparent history" > <icon name="history" @@ -60,7 +60,7 @@ export default { v-tooltip :href="file.permalink" :title="__('Permalink')" - class="btn btn-xs btn-transparent" + class="btn btn-xs btn-transparent permalink" > <icon name="link" @@ -71,9 +71,9 @@ export default { v-tooltip :href="file.rawPath" target="_blank" - class="btn btn-xs btn-transparent prepend-left-10" + class="btn btn-xs btn-transparent prepend-left-10 raw" rel="noopener noreferrer" - title:="rawDownloadButtonLabel"> + :title="rawDownloadButtonLabel"> <icon name="download" :size="16" diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue index 3f607cf85da..97f047f053f 100644 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -2,10 +2,10 @@ /* global monaco */ import { mapState, mapActions } from 'vuex'; import flash from '~/flash'; -import ContentViewer from '~/vue_shared/components/content_viewer/index.vue'; +import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue'; import monacoLoader from '../monaco_loader'; import Editor from '../lib/editor'; -import IdeFileButtons from './repo_file_buttons.vue'; +import IdeFileButtons from './ide_file_buttons.vue'; export default { components: { @@ -158,12 +158,18 @@ export default { <a href="javascript:void(0);" @click.prevent="setFileViewMode({ file, viewMode: 'edit' })"> - Edit + <template v-if="viewer === 'editor'"> + {{ __('Edit') }} + </template> + <template v-else> + {{ __('Review') }} + </template> </a> </li> - <li :class="file.viewMode==='preview' ? 'active':''"> + <li + v-if="file.previewMode" + :class="file.viewMode==='preview' ? 'active':''"> <a - v-if="file.previewMode" href="javascript:void(0);" @click.prevent="setFileViewMode({ file, viewMode:'preview' })"> {{ file.previewMode.previewTitle }} diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js index 1827badb642..f6757c79614 100644 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -28,6 +28,7 @@ export default { rawPath: data.raw_path, binary: data.binary, renderError: data.render_error, + html: data.html, }); }, [types.SET_FILE_RAW_DATA](state, { file, raw }) { diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index e67d97c3966..e02c6780ae2 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -59,6 +59,7 @@ export const decorateData = entity => { base64 = false, previewMode, file_lock, + html, } = entity; return { @@ -81,6 +82,7 @@ export const decorateData = entity => { base64, previewMode, file_lock, + html, }; }; diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/index.vue b/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue index 75f8fa30e0b..b51ab89765c 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/index.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue @@ -1,6 +1,6 @@ <script> import { viewerInformationForPath } from './lib/viewer_utils'; -import MarkdownViewer from './markdown_viewer.vue'; +import MarkdownViewer from './viewers/markdown_viewer.vue'; export default { components: { @@ -17,7 +17,8 @@ export default { }, projectId: { type: String, - required: true, + required: false, + default: '', }, }, computed: { @@ -31,6 +32,7 @@ export default { <template> <div class="preview-container"> <markdown-viewer + ref="markdownViewer" v-if="previewInfo.id === 'markdown'" :project-id="projectId" :content="content" diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/markdown_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue index c4ebeec11bf..e1064992dfd 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/markdown_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue @@ -31,20 +31,20 @@ export default { methods: { fetchMarkdownPreview() { const text = this.content; - const that = this; + axios .post(`${gon.relative_url_root}/${this.projectId}/preview_markdown`, { text, }) .then(({ data }) => { - that.previewContent = data.body; + this.previewContent = data.body; this.$nextTick(() => { $(this.$refs['markdown-preview']).renderGFM(); }); }) .catch( - () => (that.previewContent = __('An error occurred while fetching markdown preview')), + () => (this.previewContent = __('An error occurred while fetching markdown preview')), ); }, }, diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 4a6b896d969..97690a8aeb7 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -322,7 +322,7 @@ } .ide-btn-group { - padding: $gl-padding-top $gl-vert-padding; + padding: $gl-padding-4 $gl-vert-padding; } .ide-status-bar { diff --git a/spec/javascripts/ide/components/ide_file_buttons_spec.js b/spec/javascripts/ide/components/ide_file_buttons_spec.js index 3d0dd979c71..8ac8d1b2acf 100644 --- a/spec/javascripts/ide/components/ide_file_buttons_spec.js +++ b/spec/javascripts/ide/components/ide_file_buttons_spec.js @@ -1,5 +1,5 @@ import Vue from 'vue'; -import repoFileButtons from '~/ide/components/repo_file_buttons.vue'; +import repoFileButtons from '~/ide/components/ide_file_buttons.vue'; import createVueComponent from '../../helpers/vue_mount_component_helper'; import { file } from '../helpers'; @@ -23,7 +23,7 @@ describe('RepoFileButtons', () => { vm.$destroy(); }); - it('renders Raw, Blame, History, Permalink and Preview toggle', done => { + it('renders Raw, Blame, History and Permalink', done => { vm = createComponent(); vm.$nextTick(() => { @@ -32,12 +32,28 @@ describe('RepoFileButtons', () => { const history = vm.$el.querySelector('.history'); expect(raw.href).toMatch(`/${activeFile.rawPath}`); - expect(raw.textContent.trim()).toEqual('Raw'); + expect(raw.getAttribute('data-original-title')).toEqual('Raw'); expect(blame.href).toMatch(`/${activeFile.blamePath}`); - expect(blame.textContent.trim()).toEqual('Blame'); + expect(blame.getAttribute('data-original-title')).toEqual('Blame'); expect(history.href).toMatch(`/${activeFile.commitsPath}`); - expect(history.textContent.trim()).toEqual('History'); - expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink'); + expect(history.getAttribute('data-original-title')).toEqual('History'); + expect(vm.$el.querySelector('.permalink').getAttribute('data-original-title')).toEqual( + 'Permalink', + ); + + done(); + }); + }); + + it('renders Download', done => { + activeFile.binary = true; + vm = createComponent(); + + vm.$nextTick(() => { + const raw = vm.$el.querySelector('.raw'); + + expect(raw.href).toMatch(`/${activeFile.rawPath}`); + expect(raw.getAttribute('data-original-title')).toEqual('Download'); done(); }); diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js index ae657e8c881..c6709670178 100644 --- a/spec/javascripts/ide/components/repo_editor_spec.js +++ b/spec/javascripts/ide/components/repo_editor_spec.js @@ -19,7 +19,6 @@ describe('RepoEditor', () => { f.active = true; f.tempFile = true; - f.html = 'testing'; vm.$store.state.openFiles.push(f); vm.$store.state.entries[f.path] = f; vm.monaco = true; @@ -47,6 +46,61 @@ describe('RepoEditor', () => { }); }); + it('renders only an edit tab', done => { + Vue.nextTick(() => { + const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav.nav-links li'); + expect(tabs.length).toBe(1); + expect(tabs[0].textContent.trim()).toBe('Edit'); + + done(); + }); + }); + + describe('when file is markdown', () => { + beforeEach(done => { + vm.file.previewMode = { + id: 'markdown', + previewTitle: 'Preview Markdown', + }; + + vm.$nextTick(done); + }); + + it('renders an Edit and a Preview Tab', done => { + Vue.nextTick(() => { + const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav.nav-links li'); + expect(tabs.length).toBe(2); + expect(tabs[0].textContent.trim()).toBe('Edit'); + expect(tabs[1].textContent.trim()).toBe('Preview Markdown'); + + done(); + }); + }); + }); + + describe('when file is markdown and viewer mode is review', () => { + beforeEach(done => { + vm.file.previewMode = { + id: 'markdown', + previewTitle: 'Preview Markdown', + }; + vm.$store.state.viewer = 'diff'; + + vm.$nextTick(done); + }); + + it('renders an Edit and a Preview Tab', done => { + Vue.nextTick(() => { + const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav.nav-links li'); + expect(tabs.length).toBe(2); + expect(tabs[0].textContent.trim()).toBe('Review'); + expect(tabs[1].textContent.trim()).toBe('Preview Markdown'); + + done(); + }); + }); + }); + describe('when open file is binary and not raw', () => { beforeEach(done => { vm.file.binary = true; @@ -57,10 +111,6 @@ describe('RepoEditor', () => { it('does not render the IDE', () => { expect(vm.shouldHideEditor).toBeTruthy(); }); - - it('shows activeFile html', () => { - expect(vm.$el.textContent).toContain('testing'); - }); }); describe('createEditorInstance', () => { diff --git a/spec/javascripts/ide/stores/mutations/file_spec.js b/spec/javascripts/ide/stores/mutations/file_spec.js index 131380248e8..751d51616ee 100644 --- a/spec/javascripts/ide/stores/mutations/file_spec.js +++ b/spec/javascripts/ide/stores/mutations/file_spec.js @@ -154,4 +154,15 @@ describe('Multi-file store file mutations', () => { expect(localFile.changed).toBeTruthy(); }); }); + + describe('SET_FILE_VIEWMODE', () => { + it('updates file view mode', () => { + mutations.SET_FILE_VIEWMODE(localState, { + file: localFile, + viewMode: 'preview', + }); + + expect(localFile.viewMode).toBe('preview'); + }); + }); }); diff --git a/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js b/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js new file mode 100644 index 00000000000..04c171bf968 --- /dev/null +++ b/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js @@ -0,0 +1,43 @@ +import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import contentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; + +describe('ContentViewer', () => { + let vm; + let mock; + + function createComponent(props) { + const ContentViewer = Vue.extend(contentViewer); + vm = mountComponent(ContentViewer, props); + } + + afterEach(() => { + vm.$destroy(); + if (mock) mock.restore(); + }); + + it('markdown preview renders + loads rendered markdown from server', done => { + mock = new MockAdapter(axios); + mock.onPost(`${gon.relative_url_root}//preview_markdown`).reply(200, { + body: '<b>testing</b>', + }); + + createComponent({ + path: 'test.md', + content: '* Test', + }); + + const previewContainer = vm.$el.querySelector('.md-previewer'); + expect(previewContainer.textContent).toBe('Loading ...'); + + vm.$nextTick(() => { + setTimeout(() => { + expect(previewContainer.textContent).toContain('testing'); + + done(); + }); + }); + }); +}); |