diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-10 12:08:16 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-10 12:08:16 +0000 |
commit | 1fa79760ad2d4bd67f5c5a27f372a7533b9b7c69 (patch) | |
tree | ffdfbd9113743831ff4f1290959a62cf6567fde5 /spec/frontend | |
parent | 82fa8a3d1e8466ef36b58604d20fcc145ea12118 (diff) | |
download | gitlab-ce-1fa79760ad2d4bd67f5c5a27f372a7533b9b7c69.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
5 files changed, 400 insertions, 1 deletions
diff --git a/spec/frontend/blob/3d_viewer/mesh_object_spec.js b/spec/frontend/blob/3d_viewer/mesh_object_spec.js new file mode 100644 index 00000000000..60be285039f --- /dev/null +++ b/spec/frontend/blob/3d_viewer/mesh_object_spec.js @@ -0,0 +1,32 @@ +import { BoxGeometry } from 'three/build/three.module'; +import MeshObject from '~/blob/3d_viewer/mesh_object'; + +describe('Mesh object', () => { + it('defaults to non-wireframe material', () => { + const object = new MeshObject(new BoxGeometry(10, 10, 10)); + + expect(object.material.wireframe).toBeFalsy(); + }); + + it('changes to wirefame material', () => { + const object = new MeshObject(new BoxGeometry(10, 10, 10)); + + object.changeMaterial('wireframe'); + + expect(object.material.wireframe).toBeTruthy(); + }); + + it('scales object down', () => { + const object = new MeshObject(new BoxGeometry(10, 10, 10)); + const { radius } = object.geometry.boundingSphere; + + expect(radius).not.toBeGreaterThan(4); + }); + + it('does not scale object down', () => { + const object = new MeshObject(new BoxGeometry(1, 1, 1)); + const { radius } = object.geometry.boundingSphere; + + expect(radius).toBeLessThan(1); + }); +}); diff --git a/spec/frontend/blob/viewer/index_spec.js b/spec/frontend/blob/viewer/index_spec.js new file mode 100644 index 00000000000..7239f59c6fa --- /dev/null +++ b/spec/frontend/blob/viewer/index_spec.js @@ -0,0 +1,179 @@ +/* eslint-disable no-new */ + +import $ from 'jquery'; +import MockAdapter from 'axios-mock-adapter'; +import BlobViewer from '~/blob/viewer/index'; +import axios from '~/lib/utils/axios_utils'; + +describe('Blob viewer', () => { + let blob; + let mock; + + const jQueryMock = { + tooltip: jest.fn(), + }; + + preloadFixtures('snippets/show.html'); + + beforeEach(() => { + $.fn.extend(jQueryMock); + mock = new MockAdapter(axios); + + loadFixtures('snippets/show.html'); + $('#modal-upload-blob').remove(); + + blob = new BlobViewer(); + + mock.onGet('http://test.host/snippets/1.json?viewer=rich').reply(200, { + html: '<div>testing</div>', + }); + + mock.onGet('http://test.host/snippets/1.json?viewer=simple').reply(200, { + html: '<div>testing</div>', + }); + + jest.spyOn(axios, 'get'); + }); + + afterEach(() => { + mock.restore(); + window.location.hash = ''; + }); + + it('loads source file after switching views', done => { + document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); + + setImmediate(() => { + expect( + document + .querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]') + .classList.contains('hidden'), + ).toBeFalsy(); + + done(); + }); + }); + + it('loads source file when line number is in hash', done => { + window.location.hash = '#L1'; + + new BlobViewer(); + + setImmediate(() => { + expect( + document + .querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]') + .classList.contains('hidden'), + ).toBeFalsy(); + + done(); + }); + }); + + it('doesnt reload file if already loaded', () => { + const asyncClick = () => + new Promise(resolve => { + document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); + + setImmediate(resolve); + }); + + return asyncClick() + .then(() => asyncClick()) + .then(() => { + expect( + document.querySelector('.blob-viewer[data-type="simple"]').getAttribute('data-loaded'), + ).toBe('true'); + }); + }); + + describe('copy blob button', () => { + let copyButton; + + beforeEach(() => { + copyButton = document.querySelector('.js-copy-blob-source-btn'); + }); + + it('disabled on load', () => { + expect(copyButton.classList.contains('disabled')).toBeTruthy(); + }); + + it('has tooltip when disabled', () => { + expect(copyButton.getAttribute('title')).toBe( + 'Switch to the source to copy the file contents', + ); + }); + + it('is blurred when clicked and disabled', () => { + jest.spyOn(copyButton, 'blur').mockImplementation(() => {}); + + copyButton.click(); + + expect(copyButton.blur).toHaveBeenCalled(); + }); + + it('is not blurred when clicked and not disabled', () => { + jest.spyOn(copyButton, 'blur').mockImplementation(() => {}); + + copyButton.classList.remove('disabled'); + copyButton.click(); + + expect(copyButton.blur).not.toHaveBeenCalled(); + }); + + it('enables after switching to simple view', done => { + document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); + + setImmediate(() => { + expect(copyButton.classList.contains('disabled')).toBeFalsy(); + + done(); + }); + }); + + it('updates tooltip after switching to simple view', done => { + document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); + + setImmediate(() => { + expect(copyButton.getAttribute('title')).toBe('Copy file contents'); + + done(); + }); + }); + }); + + describe('switchToViewer', () => { + it('removes active class from old viewer button', () => { + blob.switchToViewer('simple'); + + expect( + document.querySelector('.js-blob-viewer-switch-btn.active[data-viewer="rich"]'), + ).toBeNull(); + }); + + it('adds active class to new viewer button', () => { + const simpleBtn = document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]'); + + jest.spyOn(simpleBtn, 'blur').mockImplementation(() => {}); + + blob.switchToViewer('simple'); + + expect(simpleBtn.classList.contains('active')).toBeTruthy(); + + expect(simpleBtn.blur).toHaveBeenCalled(); + }); + + it('sends AJAX request when switching to simple view', () => { + blob.switchToViewer('simple'); + + expect(axios.get).toHaveBeenCalled(); + }); + + it('does not send AJAX request when switching to rich view', () => { + blob.switchToViewer('simple'); + blob.switchToViewer('rich'); + + expect(axios.get.mock.calls.length).toBe(1); + }); + }); +}); diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js index 2b83f7e7351..15c6b36af03 100644 --- a/spec/frontend/registry/explorer/pages/details_spec.js +++ b/spec/frontend/registry/explorer/pages/details_spec.js @@ -219,7 +219,7 @@ describe('Details Page', () => { dispatchSpy.mockResolvedValue(); wrapper.setData({ currentPage: 2 }); expect(store.dispatch).toHaveBeenCalledWith('requestTagsList', { - id: wrapper.vm.$route.params.id, + params: wrapper.vm.$route.params.id, pagination: { page: 2 }, }); }); diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap new file mode 100644 index 00000000000..4f1d46dffef --- /dev/null +++ b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Snippet Visibility Edit component rendering matches the snapshot 1`] = ` +<div + class="form-group" +> + <label> + + Visibility level + + <gl-link-stub + href="/foo/bar" + target="_blank" + > + <gl-icon-stub + name="question" + size="12" + /> + </gl-link-stub> + </label> + + <gl-form-group-stub + id="visibility-level-setting" + > + <gl-form-radio-group-stub + checked="0" + disabledfield="disabled" + htmlfield="html" + options="" + stacked="" + textfield="text" + valuefield="value" + > + <gl-form-radio-stub + class="mb-3" + value="0" + > + <div + class="d-flex align-items-center" + > + <gl-icon-stub + name="lock" + size="16" + /> + + <span + class="font-weight-bold ml-1" + > + Private + </span> + </div> + </gl-form-radio-stub> + <gl-form-radio-stub + class="mb-3" + value="1" + > + <div + class="d-flex align-items-center" + > + <gl-icon-stub + name="shield" + size="16" + /> + + <span + class="font-weight-bold ml-1" + > + Internal + </span> + </div> + </gl-form-radio-stub> + <gl-form-radio-stub + class="mb-3" + value="2" + > + <div + class="d-flex align-items-center" + > + <gl-icon-stub + name="earth" + size="16" + /> + + <span + class="font-weight-bold ml-1" + > + Public + </span> + </div> + </gl-form-radio-stub> + </gl-form-radio-group-stub> + </gl-form-group-stub> +</div> +`; diff --git a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js new file mode 100644 index 00000000000..5104d742bb3 --- /dev/null +++ b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js @@ -0,0 +1,94 @@ +import SnippetVisibilityEdit from '~/snippets/components/snippet_visibility_edit.vue'; +import { GlFormRadio } from '@gitlab/ui'; +import { SNIPPET_VISIBILITY } from '~/snippets/constants'; +import { mount, shallowMount } from '@vue/test-utils'; + +describe('Snippet Visibility Edit component', () => { + let wrapper; + let radios; + const defaultHelpLink = '/foo/bar'; + const defaultVisibilityLevel = '0'; + + function findElements(sel) { + return wrapper.findAll(sel); + } + + function createComponent( + { + helpLink = defaultHelpLink, + isProjectSnippet = false, + visibilityLevel = defaultVisibilityLevel, + } = {}, + deep = false, + ) { + const method = deep ? mount : shallowMount; + wrapper = method.call(this, SnippetVisibilityEdit, { + propsData: { + helpLink, + isProjectSnippet, + visibilityLevel, + }, + }); + radios = findElements(GlFormRadio); + } + + afterEach(() => { + wrapper.destroy(); + }); + + describe('rendering', () => { + it('matches the snapshot', () => { + createComponent(); + expect(wrapper.element).toMatchSnapshot(); + }); + + it.each` + label | value + ${SNIPPET_VISIBILITY.private.label} | ${`0`} + ${SNIPPET_VISIBILITY.internal.label} | ${`1`} + ${SNIPPET_VISIBILITY.public.label} | ${`2`} + `('should render correct $label label', ({ label, value }) => { + createComponent(); + const radio = radios.at(parseInt(value, 10)); + + expect(radio.attributes('value')).toBe(value); + expect(radio.text()).toContain(label); + }); + + describe('rendered help-text', () => { + it.each` + description | value | label + ${SNIPPET_VISIBILITY.private.description} | ${`0`} | ${SNIPPET_VISIBILITY.private.label} + ${SNIPPET_VISIBILITY.internal.description} | ${`1`} | ${SNIPPET_VISIBILITY.internal.label} + ${SNIPPET_VISIBILITY.public.description} | ${`2`} | ${SNIPPET_VISIBILITY.public.label} + `('should render correct $label description', ({ description, value }) => { + createComponent({}, true); + + const help = findElements('.help-text').at(parseInt(value, 10)); + + expect(help.text()).toBe(description); + }); + + it('renders correct Private description for a project snippet', () => { + createComponent({ isProjectSnippet: true }, true); + + const helpText = findElements('.help-text') + .at(0) + .text(); + + expect(helpText).not.toContain(SNIPPET_VISIBILITY.private.description); + expect(helpText).toBe(SNIPPET_VISIBILITY.private.description_project); + }); + }); + }); + + describe('functionality', () => { + it('pre-selects correct option in the list', () => { + const pos = 1; + + createComponent({ visibilityLevel: `${pos}` }, true); + const radio = radios.at(pos); + expect(radio.find('input[type="radio"]').element.checked).toBe(true); + }); + }); +}); |