diff options
Diffstat (limited to 'spec/frontend/ide/components/repo_editor_spec.js')
-rw-r--r-- | spec/frontend/ide/components/repo_editor_spec.js | 240 |
1 files changed, 88 insertions, 152 deletions
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js index 9a30fd5f5c3..b44651481e9 100644 --- a/spec/frontend/ide/components/repo_editor_spec.js +++ b/spec/frontend/ide/components/repo_editor_spec.js @@ -1,8 +1,8 @@ -import { shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { editor as monacoEditor, Range } from 'monaco-editor'; import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; +import { shallowMount } from '@vue/test-utils'; import '~/behaviors/markdown/render_gfm'; import waitForPromises from 'helpers/wait_for_promises'; import { exampleConfigs, exampleFiles } from 'jest/ide/lib/editorconfig/mock_data'; @@ -11,57 +11,54 @@ import { EditorMarkdownExtension } from '~/editor/extensions/source_editor_markd import { EditorMarkdownPreviewExtension } from '~/editor/extensions/source_editor_markdown_livepreview_ext'; import SourceEditor from '~/editor/source_editor'; import RepoEditor from '~/ide/components/repo_editor.vue'; -import { - leftSidebarViews, - FILE_VIEW_MODE_EDITOR, - FILE_VIEW_MODE_PREVIEW, - viewerTypes, -} from '~/ide/constants'; +import { leftSidebarViews, FILE_VIEW_MODE_PREVIEW, viewerTypes } from '~/ide/constants'; import ModelManager from '~/ide/lib/common/model_manager'; import service from '~/ide/services'; import { createStoreOptions } from '~/ide/stores'; import axios from '~/lib/utils/axios_utils'; import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue'; import SourceEditorInstance from '~/editor/source_editor_instance'; -import { spyOnApi } from 'jest/editor/helpers'; import { file } from '../helpers'; const PREVIEW_MARKDOWN_PATH = '/foo/bar/preview_markdown'; const CURRENT_PROJECT_ID = 'gitlab-org/gitlab'; -const defaultFileProps = { - ...file('file.txt'), - content: 'hello world', - active: true, - tempFile: true, +const dummyFile = { + text: { + ...file('file.txt'), + content: 'hello world', + active: true, + tempFile: true, + }, + markdown: { + ...file('sample.md'), + projectId: 'namespace/project', + path: 'sample.md', + content: 'hello world', + tempFile: true, + active: true, + }, + binary: { + ...file('file.dat'), + content: '🐱', // non-ascii binary content, + tempFile: true, + active: true, + }, + empty: { + ...file('empty'), + tempFile: false, + content: '', + raw: '', + }, }; + const createActiveFile = (props) => { return { - ...defaultFileProps, + ...dummyFile.text, ...props, }; }; -const dummyFile = { - markdown: (() => - createActiveFile({ - projectId: 'namespace/project', - path: 'sample.md', - name: 'sample.md', - }))(), - binary: (() => - createActiveFile({ - name: 'file.dat', - content: '🐱', // non-ascii binary content, - }))(), - empty: (() => - createActiveFile({ - tempFile: false, - content: '', - raw: '', - }))(), -}; - const prepareStore = (state, activeFile) => { const localState = { openFiles: [activeFile], @@ -109,7 +106,7 @@ describe('RepoEditor', () => { vm.$once('editorSetup', resolve); }); - const createComponent = async ({ state = {}, activeFile = defaultFileProps } = {}) => { + const createComponent = async ({ state = {}, activeFile = dummyFile.text } = {}) => { const store = prepareStore(state, activeFile); wrapper = shallowMount(RepoEditor, { store, @@ -187,7 +184,7 @@ describe('RepoEditor', () => { mock = new MockAdapter(axios); mock.onPost(/(.*)\/preview_markdown/).reply(200, { - body: `<p>${defaultFileProps.content}</p>`, + body: `<p>${dummyFile.text.content}</p>`, }); }); @@ -196,11 +193,8 @@ describe('RepoEditor', () => { }); describe('when files is markdown', () => { - let layoutSpy; - beforeEach(async () => { await createComponent({ activeFile }); - layoutSpy = jest.spyOn(wrapper.vm.editor, 'layout'); }); it('renders an Edit and a Preview Tab', () => { @@ -214,11 +208,7 @@ describe('RepoEditor', () => { it('renders markdown for tempFile', async () => { findPreviewTab().trigger('click'); await waitForPromises(); - expect(wrapper.find(ContentViewer).html()).toContain(defaultFileProps.content); - }); - - it('should not trigger layout', async () => { - expect(layoutSpy).not.toHaveBeenCalled(); + expect(wrapper.find(ContentViewer).html()).toContain(dummyFile.text.content); }); describe('when file changes to non-markdown file', () => { @@ -229,10 +219,6 @@ describe('RepoEditor', () => { it('should hide tabs', () => { expect(findTabs()).toHaveLength(0); }); - - it('should trigger refresh dimensions', async () => { - expect(layoutSpy).toHaveBeenCalledTimes(1); - }); }); }); @@ -292,55 +278,20 @@ describe('RepoEditor', () => { expect(vm.editor.methods[fn]).toBe('EditorWebIde'); }); }); - - it.each` - prefix | activeFile | viewer | shouldHaveMarkdownExtension - ${'Should not'} | ${createActiveFile()} | ${viewerTypes.edit} | ${false} - ${'Should'} | ${dummyFile.markdown} | ${viewerTypes.edit} | ${true} - ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.edit} | ${false} - ${'Should not'} | ${createActiveFile()} | ${viewerTypes.diff} | ${false} - ${'Should not'} | ${dummyFile.markdown} | ${viewerTypes.diff} | ${false} - ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.diff} | ${false} - ${'Should not'} | ${createActiveFile()} | ${viewerTypes.mr} | ${false} - ${'Should not'} | ${dummyFile.markdown} | ${viewerTypes.mr} | ${false} - ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.mr} | ${false} - `( - '$prefix install markdown extension for $activeFile.name in $viewer viewer', - async ({ activeFile, viewer, shouldHaveMarkdownExtension } = {}) => { - await createComponent({ state: { viewer }, activeFile }); - - if (shouldHaveMarkdownExtension) { - expect(applyExtensionSpy).toHaveBeenCalledWith({ - definition: EditorMarkdownPreviewExtension, - setupOptions: { previewMarkdownPath: PREVIEW_MARKDOWN_PATH }, - }); - // TODO: spying on extensions causes Jest to blow up, so we have to assert on - // the public property the extension adds, as opposed to the args passed to the ctor - expect(wrapper.vm.editor.markdownPreview.path).toBe(PREVIEW_MARKDOWN_PATH); - } else { - expect(applyExtensionSpy).not.toHaveBeenCalledWith( - wrapper.vm.editor, - expect.any(EditorMarkdownExtension), - ); - } - }, - ); }); describe('setupEditor', () => { - beforeEach(async () => { + it('creates new model on load', async () => { await createComponent(); - }); - - it('creates new model on load', () => { // We always create two models per file to be able to build a diff of changes expect(createModelSpy).toHaveBeenCalledTimes(2); // The model with the most recent changes is the last one const [content] = createModelSpy.mock.calls[1]; - expect(content).toBe(defaultFileProps.content); + expect(content).toBe(dummyFile.text.content); }); - it('does not create a new model on subsequent calls to setupEditor and re-uses the already-existing model', () => { + it('does not create a new model on subsequent calls to setupEditor and re-uses the already-existing model', async () => { + await createComponent(); const existingModel = vm.model; createModelSpy.mockClear(); @@ -350,7 +301,8 @@ describe('RepoEditor', () => { expect(vm.model).toBe(existingModel); }); - it('updates state with the value of the model', () => { + it('updates state with the value of the model', async () => { + await createComponent(); const newContent = 'As Gregor Samsa\n awoke one morning\n'; vm.model.setValue(newContent); @@ -359,7 +311,8 @@ describe('RepoEditor', () => { expect(vm.file.content).toBe(newContent); }); - it('sets head model as staged file', () => { + it('sets head model as staged file', async () => { + await createComponent(); vm.modelManager.dispose(); const addModelSpy = jest.spyOn(ModelManager.prototype, 'addModel'); @@ -371,52 +324,54 @@ describe('RepoEditor', () => { expect(addModelSpy).toHaveBeenCalledWith(vm.file, vm.$store.state.stagedFiles[0]); }); - }); - - describe('editor updateDimensions', () => { - let updateDimensionsSpy; - beforeEach(async () => { - await createComponent(); - const ext = extensionsStore.get('EditorWebIde'); - updateDimensionsSpy = jest.fn(); - spyOnApi(ext, { - updateDimensions: updateDimensionsSpy, - }); - }); - it('calls updateDimensions only when panelResizing is false', async () => { - expect(updateDimensionsSpy).not.toHaveBeenCalled(); - expect(vm.$store.state.panelResizing).toBe(false); // default value - - vm.$store.state.panelResizing = true; - await nextTick(); - - expect(updateDimensionsSpy).not.toHaveBeenCalled(); - - vm.$store.state.panelResizing = false; - await nextTick(); - - expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); - - vm.$store.state.panelResizing = true; - await nextTick(); - - expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); - }); - - it('calls updateDimensions when rightPane is toggled', async () => { - expect(updateDimensionsSpy).not.toHaveBeenCalled(); - expect(vm.$store.state.rightPane.isOpen).toBe(false); // default value - - vm.$store.state.rightPane.isOpen = true; - await nextTick(); + it.each` + prefix | activeFile | viewer | shouldHaveMarkdownExtension + ${'Should not'} | ${dummyFile.text} | ${viewerTypes.edit} | ${false} + ${'Should'} | ${dummyFile.markdown} | ${viewerTypes.edit} | ${true} + ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.edit} | ${false} + ${'Should not'} | ${dummyFile.text} | ${viewerTypes.diff} | ${false} + ${'Should not'} | ${dummyFile.markdown} | ${viewerTypes.diff} | ${false} + ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.diff} | ${false} + ${'Should not'} | ${dummyFile.text} | ${viewerTypes.mr} | ${false} + ${'Should not'} | ${dummyFile.markdown} | ${viewerTypes.mr} | ${false} + ${'Should not'} | ${dummyFile.empty} | ${viewerTypes.mr} | ${false} + `( + '$prefix install markdown extension for $activeFile.name in $viewer viewer', + async ({ activeFile, viewer, shouldHaveMarkdownExtension } = {}) => { + await createComponent({ state: { viewer }, activeFile }); - expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); + if (shouldHaveMarkdownExtension) { + expect(applyExtensionSpy).toHaveBeenCalledWith({ + definition: EditorMarkdownPreviewExtension, + setupOptions: { previewMarkdownPath: PREVIEW_MARKDOWN_PATH }, + }); + // TODO: spying on extensions causes Jest to blow up, so we have to assert on + // the public property the extension adds, as opposed to the args passed to the ctor + expect(wrapper.vm.editor.markdownPreview.path).toBe(PREVIEW_MARKDOWN_PATH); + } else { + expect(applyExtensionSpy).not.toHaveBeenCalledWith( + wrapper.vm.editor, + expect.any(EditorMarkdownExtension), + ); + } + }, + ); - vm.$store.state.rightPane.isOpen = false; - await nextTick(); + it('fetches the live preview extension even if markdown is not the first opened file', async () => { + const textFile = dummyFile.text; + const mdFile = dummyFile.markdown; + const previewExtConfig = { + definition: EditorMarkdownPreviewExtension, + setupOptions: { previewMarkdownPath: PREVIEW_MARKDOWN_PATH }, + }; + await createComponent({ activeFile: textFile }); + applyExtensionSpy.mockClear(); + + await wrapper.setProps({ file: mdFile }); + await waitForPromises(); - expect(updateDimensionsSpy).toHaveBeenCalledTimes(2); + expect(applyExtensionSpy).toHaveBeenCalledWith(previewExtConfig); }); }); @@ -439,7 +394,6 @@ describe('RepoEditor', () => { }); describe('files in preview mode', () => { - let updateDimensionsSpy; const changeViewMode = (viewMode) => vm.$store.dispatch('editor/updateFileEditor', { path: vm.file.path, @@ -451,12 +405,6 @@ describe('RepoEditor', () => { activeFile: dummyFile.markdown, }); - const ext = extensionsStore.get('EditorWebIde'); - updateDimensionsSpy = jest.fn(); - spyOnApi(ext, { - updateDimensions: updateDimensionsSpy, - }); - changeViewMode(FILE_VIEW_MODE_PREVIEW); await nextTick(); }); @@ -465,15 +413,6 @@ describe('RepoEditor', () => { expect(vm.showEditor).toBe(false); expect(findEditor().isVisible()).toBe(false); }); - - it('updates dimensions when switching view back to edit', async () => { - expect(updateDimensionsSpy).not.toHaveBeenCalled(); - - changeViewMode(FILE_VIEW_MODE_EDITOR); - await nextTick(); - - expect(updateDimensionsSpy).toHaveBeenCalled(); - }); }); describe('initEditor', () => { @@ -487,7 +426,7 @@ describe('RepoEditor', () => { it('does not fetch file information for temp entries', async () => { await createComponent({ - activeFile: createActiveFile(), + activeFile: dummyFile.text, }); expect(vm.getFileData).not.toHaveBeenCalled(); @@ -506,7 +445,7 @@ describe('RepoEditor', () => { it('does not initialize editor for files already with content when shouldHideEditor is `true`', async () => { await createComponent({ - activeFile: createActiveFile(), + activeFile: dummyFile.text, }); await hideEditorAndRunFn(); @@ -677,9 +616,6 @@ describe('RepoEditor', () => { activeFile: setFileName('bar.md'), }); - vm.setupEditor(); - - await waitForPromises(); // set cursor to line 2, column 1 vm.editor.setSelection(new Range(2, 1, 2, 1)); vm.editor.focus(); |