diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-29 18:08:57 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-29 18:08:57 +0000 |
commit | aa99514d5c37e08c0fa49d03212ccdc943b8d31e (patch) | |
tree | c67201d92846b800995fc771c54760d0bf9ce0ae /spec/frontend | |
parent | 3aaaf9cd8ecda9552407ffd59e52403696133bab (diff) | |
download | gitlab-ce-aa99514d5c37e08c0fa49d03212ccdc943b8d31e.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
7 files changed, 218 insertions, 6 deletions
diff --git a/spec/frontend/pipelines/components/dag/dag_spec.js b/spec/frontend/pipelines/components/dag/dag_spec.js index 015076c5691..7bb760be3a8 100644 --- a/spec/frontend/pipelines/components/dag/dag_spec.js +++ b/spec/frontend/pipelines/components/dag/dag_spec.js @@ -2,7 +2,7 @@ import { mount, shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import axios from '~/lib/utils/axios_utils'; import waitForPromises from 'helpers/wait_for_promises'; -import { GlAlert } from '@gitlab/ui'; +import { GlAlert, GlEmptyState } from '@gitlab/ui'; import Dag from '~/pipelines/components/dag/dag.vue'; import DagGraph from '~/pipelines/components/dag/dag_graph.vue'; import DagAnnotations from '~/pipelines/components/dag/dag_annotations.vue'; @@ -16,7 +16,14 @@ import { LOAD_FAILURE, UNSUPPORTED_DATA, } from '~/pipelines/components/dag//constants'; -import { mockBaseData, tooSmallGraph, unparseableGraph, singleNote, multiNote } from './mock_data'; +import { + mockBaseData, + tooSmallGraph, + unparseableGraph, + graphWithoutDependencies, + singleNote, + multiNote, +} from './mock_data'; describe('Pipeline DAG graph wrapper', () => { let wrapper; @@ -26,6 +33,7 @@ describe('Pipeline DAG graph wrapper', () => { const getGraph = () => wrapper.find(DagGraph); const getNotes = () => wrapper.find(DagAnnotations); const getErrorText = type => wrapper.vm.$options.errorTexts[type]; + const getEmptyState = () => wrapper.find(GlEmptyState); const dataPath = '/root/test/pipelines/90/dag.json'; @@ -35,7 +43,11 @@ describe('Pipeline DAG graph wrapper', () => { } wrapper = method(Dag, { - propsData, + propsData: { + emptySvgPath: '/my-svg', + dagDocPath: '/my-doc', + ...propsData, + }, data() { return { showFailureAlert: false, @@ -64,6 +76,10 @@ describe('Pipeline DAG graph wrapper', () => { expect(getAlert().text()).toBe(getErrorText(DEFAULT)); expect(getGraph().exists()).toBe(false); }); + + it('does not render the empty state', () => { + expect(getEmptyState().exists()).toBe(false); + }); }); describe('when there is a dataUrl', () => { @@ -83,6 +99,10 @@ describe('Pipeline DAG graph wrapper', () => { expect(getGraph().exists()).toBe(false); }); }); + + it('does not render the empty state', () => { + expect(getEmptyState().exists()).toBe(false); + }); }); describe('the data fetch succeeds but the parse fails', () => { @@ -101,6 +121,10 @@ describe('Pipeline DAG graph wrapper', () => { expect(getGraph().exists()).toBe(false); }); }); + + it('does not render the empty state', () => { + expect(getEmptyState().exists()).toBe(false); + }); }); describe('and the data fetch and parse succeeds', () => { @@ -119,6 +143,15 @@ describe('Pipeline DAG graph wrapper', () => { expect(getGraph().exists()).toBe(true); }); }); + + it('does not render the empty state', () => { + return wrapper.vm + .$nextTick() + .then(waitForPromises) + .then(() => { + expect(getEmptyState().exists()).toBe(false); + }); + }); }); describe('the data fetch and parse succeeds, but the resulting graph is too small', () => { @@ -137,6 +170,42 @@ describe('Pipeline DAG graph wrapper', () => { expect(getGraph().exists()).toBe(false); }); }); + + it('does not show the empty dag graph state', () => { + return wrapper.vm + .$nextTick() + .then(waitForPromises) + .then(() => { + expect(getEmptyState().exists()).toBe(false); + }); + }); + }); + + describe('the data fetch and parse succeeds, but the resulting graph is empty', () => { + beforeEach(() => { + mock.onGet(dataPath).replyOnce(200, graphWithoutDependencies); + createComponent({ graphUrl: dataPath }, mount); + }); + + it('does not render an error alert or the graph', () => { + return wrapper.vm + .$nextTick() + .then(waitForPromises) + .then(() => { + expect(getAllAlerts().length).toBe(1); + expect(getAlert().text()).toContain('This feature is currently in beta.'); + expect(getGraph().exists()).toBe(false); + }); + }); + + it('shows the empty dag graph state', () => { + return wrapper.vm + .$nextTick() + .then(waitForPromises) + .then(() => { + expect(getEmptyState().exists()).toBe(true); + }); + }); }); }); diff --git a/spec/frontend/pipelines/components/dag/mock_data.js b/spec/frontend/pipelines/components/dag/mock_data.js index e1733736755..3b39b9cd21c 100644 --- a/spec/frontend/pipelines/components/dag/mock_data.js +++ b/spec/frontend/pipelines/components/dag/mock_data.js @@ -83,6 +83,46 @@ export const tooSmallGraph = { ], }; +export const graphWithoutDependencies = { + stages: [ + { + name: 'test', + groups: [ + { + name: 'jest', + size: 2, + jobs: [{ name: 'jest 1/2' }, { name: 'jest 2/2' }], + }, + { + name: 'rspec', + size: 1, + jobs: [{ name: 'rspec' }], + }, + ], + }, + { + name: 'fixtures', + groups: [ + { + name: 'frontend fixtures', + size: 1, + jobs: [{ name: 'frontend fixtures' }], + }, + ], + }, + { + name: 'un-needed', + groups: [ + { + name: 'un-needed', + size: 1, + jobs: [{ name: 'un-needed' }], + }, + ], + }, + ], +}; + export const unparseableGraph = [ { name: 'test', diff --git a/spec/frontend/vue_shared/components/rich_content_editor/mock_data.js b/spec/frontend/vue_shared/components/rich_content_editor/mock_data.js index 5d7695e9664..f6d2717e117 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/mock_data.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/mock_data.js @@ -6,6 +6,27 @@ const buildMockTextNode = literal => { }; }; +const buildMockTextNodeWithAdjacentInlineCode = isForward => { + const direction = isForward ? 'next' : 'prev'; + const literalOpen = '['; + const literalClose = ' file]: https://file.com/file.md'; + return { + literal: isForward ? literalOpen : literalClose, + type: 'text', + [direction]: { + literal: 'raw', + tickCount: 1, + type: 'code', + [direction]: { + literal: isForward ? literalClose : literalOpen, + [direction]: { + literal: null, + }, + }, + }, + }; +}; + const buildMockListNode = literal => { return { firstChild: { @@ -23,6 +44,9 @@ export const kramdownListNode = buildMockListNode('TOC'); export const normalListNode = buildMockListNode('Just another bullet point'); export const kramdownTextNode = buildMockTextNode('{:toc}'); +export const identifierTextNode = buildMockTextNode('[Some text]: https://link.com'); +export const identifierInlineCodeTextEnteringNode = buildMockTextNodeWithAdjacentInlineCode(true); +export const identifierInlineCodeTextExitingNode = buildMockTextNodeWithAdjacentInlineCode(false); export const normalTextNode = buildMockTextNode('This is just normal text.'); const uneditableOpenToken = { @@ -40,4 +64,5 @@ export const originToken = { content: '{:.no_toc .hidden-md .hidden-lg}', }; export const uneditableOpenTokens = [uneditableOpenToken, originToken]; +export const uneditableCloseTokens = [originToken, uneditableCloseToken]; export const uneditableTokens = [...uneditableOpenTokens, uneditableCloseToken]; diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js index 2daca6500c5..51a42e0ff26 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js @@ -1,6 +1,7 @@ import { buildUneditableOpenTokens, buildUneditableCloseToken, + buildUneditableCloseTokens, buildUneditableTokens, } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; @@ -8,6 +9,7 @@ import { originToken, uneditableOpenTokens, uneditableCloseToken, + uneditableCloseTokens, uneditableTokens, } from '../../mock_data'; @@ -27,6 +29,15 @@ describe('Build Uneditable Token renderer helper', () => { }); }); + describe('buildUneditableCloseTokens', () => { + it('returns a 2-item array of tokens with the originToken prepended to a close token', () => { + const result = buildUneditableCloseTokens(originToken); + + expect(result).toHaveLength(2); + expect(result).toStrictEqual(uneditableCloseTokens); + }); + }); + describe('buildUneditableTokens', () => { it('returns a 3-item array of tokens with the originToken wrapped in the middle', () => { const result = buildUneditableTokens(originToken); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_text_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_text_spec.js new file mode 100644 index 00000000000..257a37d1af8 --- /dev/null +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_text_spec.js @@ -0,0 +1,61 @@ +import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_identifier_text'; +import { + buildUneditableOpenTokens, + buildUneditableCloseTokens, + buildUneditableTokens, +} from '~/vue_shared/components/rich_content_editor/services/renderers//build_uneditable_token'; + +import { + identifierTextNode, + identifierInlineCodeTextEnteringNode, + identifierInlineCodeTextExitingNode, + normalTextNode, +} from '../../mock_data'; + +describe('Render Identifier Text renderer', () => { + describe('canRender', () => { + it('should return true when the argument `literal` has identifier syntax', () => { + expect(renderer.canRender(identifierTextNode)).toBe(true); + }); + + it('should return true when the argument `literal` has identifier syntax and forward adjacent inline code', () => { + expect(renderer.canRender(identifierInlineCodeTextEnteringNode)).toBe(true); + }); + + it('should return true when the argument `literal` has identifier syntax and backward adjacent inline code', () => { + expect(renderer.canRender(identifierInlineCodeTextExitingNode)).toBe(true); + }); + + it('should return false when the argument `literal` lacks identifier syntax', () => { + expect(renderer.canRender(normalTextNode)).toBe(false); + }); + }); + + describe('render', () => { + const origin = jest.fn(); + + it('should return uneditable tokens for basic identifier syntax', () => { + const context = { origin }; + + expect(renderer.render(identifierTextNode, context)).toStrictEqual( + buildUneditableTokens(origin()), + ); + }); + + it('should return uneditable open tokens for non-basic inline code identifier syntax when entering', () => { + const context = { origin }; + + expect(renderer.render(identifierInlineCodeTextEnteringNode, context)).toStrictEqual( + buildUneditableOpenTokens(origin()), + ); + }); + + it('should return uneditable close tokens for non-basic inline code identifier syntax when exiting', () => { + const context = { origin }; + + expect(renderer.render(identifierInlineCodeTextExitingNode, context)).toStrictEqual( + buildUneditableCloseTokens(origin()), + ); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js index 8b8a8459ca2..8199cb9ef7b 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js @@ -23,13 +23,17 @@ describe('Render Kramdown List renderer', () => { it('should return uneditable open tokens when entering', () => { const context = { entering: true, origin }; - expect(renderer.render(context)).toStrictEqual(buildUneditableOpenTokens(origin())); + expect(renderer.render(kramdownListNode, context)).toStrictEqual( + buildUneditableOpenTokens(origin()), + ); }); it('should return an uneditable close tokens when exiting', () => { const context = { entering: false, origin }; - expect(renderer.render(context)).toStrictEqual(buildUneditableCloseToken(origin())); + expect(renderer.render(kramdownListNode, context)).toStrictEqual( + buildUneditableCloseToken(origin()), + ); }); }); }); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js index d52febad436..65015c4e548 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js @@ -20,7 +20,9 @@ describe('Render Kramdown Text renderer', () => { it('should return uneditable tokens', () => { const context = { origin }; - expect(renderer.render(context)).toStrictEqual(buildUneditableTokens(origin())); + expect(renderer.render(kramdownTextNode, context)).toStrictEqual( + buildUneditableTokens(origin()), + ); }); }); }); |