Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/blob')
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap14
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap2
-rw-r--r--spec/frontend/blob/components/blob_edit_header_spec.js2
-rw-r--r--spec/frontend/blob/components/blob_header_filepath_spec.js8
-rw-r--r--spec/frontend/blob/line_highlighter_spec.js275
-rw-r--r--spec/frontend/blob/viewer/index_spec.js1
6 files changed, 295 insertions, 7 deletions
diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
index 46a5631b028..d698ee72ea4 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_filepath_spec.js.snap
@@ -20,12 +20,6 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = `
foo/bar/dummy.md
</strong>
- <small
- class="mr-2"
- >
- a lot
- </small>
-
<clipboard-button-stub
category="tertiary"
cssclass="btn-clipboard btn-transparent lh-100 position-static"
@@ -36,5 +30,13 @@ exports[`Blob Header Filepath rendering matches the snapshot 1`] = `
tooltipplacement="top"
variant="default"
/>
+
+ <small
+ class="mr-2"
+ >
+ a lot
+ </small>
+
+ <!---->
</div>
`;
diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
index db9684239a1..22bec77276b 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
@@ -17,7 +17,7 @@ exports[`Blob Header Default Actions rendering matches the snapshot 1`] = `
</div>
<div
- class="gl-display-none gl-sm-display-flex"
+ class="gl-sm-display-flex file-actions"
>
<viewer-switcher-stub
value="simple"
diff --git a/spec/frontend/blob/components/blob_edit_header_spec.js b/spec/frontend/blob/components/blob_edit_header_spec.js
index ac3080c65a5..910fc5c946d 100644
--- a/spec/frontend/blob/components/blob_edit_header_spec.js
+++ b/spec/frontend/blob/components/blob_edit_header_spec.js
@@ -44,6 +44,8 @@ describe('Blob Header Editing', () => {
const inputComponent = wrapper.find(GlFormInput);
const newValue = 'bar.txt';
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({
name: newValue,
});
diff --git a/spec/frontend/blob/components/blob_header_filepath_spec.js b/spec/frontend/blob/components/blob_header_filepath_spec.js
index d935f73c0d1..8220b598ff6 100644
--- a/spec/frontend/blob/components/blob_header_filepath_spec.js
+++ b/spec/frontend/blob/components/blob_header_filepath_spec.js
@@ -1,3 +1,4 @@
+import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import BlobHeaderFilepath from '~/blob/components/blob_header_filepath.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
@@ -24,6 +25,8 @@ describe('Blob Header Filepath', () => {
wrapper.destroy();
});
+ const findBadge = () => wrapper.find(GlBadge);
+
describe('rendering', () => {
it('matches the snapshot', () => {
createComponent();
@@ -54,6 +57,11 @@ describe('Blob Header Filepath', () => {
expect(wrapper.vm.blobSize).toBe('a lot');
});
+ it('renders LFS badge if LFS if enabled', () => {
+ createComponent({ storedExternally: true, externalStorage: 'lfs' });
+ expect(findBadge().text()).toBe('LFS');
+ });
+
it('renders a slot and prepends its contents to the existing one', () => {
const slotContent = 'Foo Bar';
createComponent(
diff --git a/spec/frontend/blob/line_highlighter_spec.js b/spec/frontend/blob/line_highlighter_spec.js
new file mode 100644
index 00000000000..330f1f3137e
--- /dev/null
+++ b/spec/frontend/blob/line_highlighter_spec.js
@@ -0,0 +1,275 @@
+/* eslint-disable no-return-assign, no-new, no-underscore-dangle */
+
+import $ from 'jquery';
+import LineHighlighter from '~/blob/line_highlighter';
+import * as utils from '~/lib/utils/common_utils';
+
+describe('LineHighlighter', () => {
+ const testContext = {};
+
+ const clickLine = (number, eventData = {}) => {
+ if ($.isEmptyObject(eventData)) {
+ return $(`#L${number}`).click();
+ }
+ const e = $.Event('click', eventData);
+ return $(`#L${number}`).trigger(e);
+ };
+ beforeEach(() => {
+ loadFixtures('static/line_highlighter.html');
+ testContext.class = new LineHighlighter();
+ testContext.css = testContext.class.highlightLineClass;
+ return (testContext.spies = {
+ __setLocationHash__: jest
+ .spyOn(testContext.class, '__setLocationHash__')
+ .mockImplementation(() => {}),
+ });
+ });
+
+ describe('behavior', () => {
+ it('highlights one line given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L13' });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('highlights one line given in the URL hash with given CSS class name', () => {
+ const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
+
+ expect(hiliter.highlightLineClass).toBe('hilite');
+ expect($('#LC13')).toHaveClass('hilite');
+ expect($('#LC13')).not.toHaveClass('hll');
+ });
+
+ it('highlights a range of lines given in the URL hash', () => {
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect($(`.${testContext.css}`).length).toBe(21);
+ for (let line = 5; line <= 25; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('highlights a range of lines given in the URL hash using GitHub format', () => {
+ new LineHighlighter({ hash: '#L5-L25' });
+
+ expect($(`.${testContext.css}`).length).toBe(21);
+ for (let line = 5; line <= 25; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('scrolls to the first highlighted line on initial load', () => {
+ jest.spyOn(utils, 'scrollToElement');
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect(utils.scrollToElement).toHaveBeenCalledWith('#L5', expect.anything());
+ });
+
+ it('discards click events', () => {
+ const clickSpy = jest.fn();
+
+ $('a[data-line-number]').click(clickSpy);
+
+ clickLine(13);
+
+ expect(clickSpy.mock.calls[0][0].isDefaultPrevented()).toEqual(true);
+ });
+
+ it('handles garbage input from the hash', () => {
+ const func = () => {
+ return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
+ };
+
+ expect(func).not.toThrow();
+ });
+
+ it('handles hashchange event', () => {
+ const highlighter = new LineHighlighter();
+
+ jest.spyOn(highlighter, 'highlightHash').mockImplementation(() => {});
+
+ window.dispatchEvent(new Event('hashchange'), 'L15');
+
+ expect(highlighter.highlightHash).toHaveBeenCalled();
+ });
+ });
+
+ describe('clickHandler', () => {
+ it('handles clicking on a child icon element', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ $('#L13 [data-testid="link-icon"]').mousedown().click();
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ describe('without shiftKey', () => {
+ it('highlights one line when clicked', () => {
+ clickLine(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('unhighlights previously highlighted lines', () => {
+ clickLine(13);
+ clickLine(20);
+
+ expect($('#LC13')).not.toHaveClass(testContext.css);
+ expect($('#LC20')).toHaveClass(testContext.css);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with shiftKey', () => {
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13);
+ clickLine(20, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect(spy).toHaveBeenCalledWith(13, 20);
+ });
+
+ describe('without existing highlight', () => {
+ it('highlights the clicked line', () => {
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ expect($(`.${testContext.css}`).length).toBe(1);
+ });
+
+ it('sets the hash', () => {
+ const spy = jest.spyOn(testContext.class, 'setHash');
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect(spy).toHaveBeenCalledWith(13);
+ });
+ });
+
+ describe('with existing single-line highlight', () => {
+ it('uses existing line as last line when target is lesser', () => {
+ clickLine(20);
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 15; line <= 20; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses existing line as first line when target is greater', () => {
+ clickLine(5);
+ clickLine(10, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+
+ describe('with existing multi-line highlight', () => {
+ beforeEach(() => {
+ clickLine(10, {
+ shiftKey: true,
+ });
+ clickLine(13, {
+ shiftKey: true,
+ });
+ });
+
+ it('uses target as first line when it is less than existing first line', () => {
+ clickLine(5, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 5; line <= 10; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+
+ it('uses target as last line when it is greater than existing first line', () => {
+ clickLine(15, {
+ shiftKey: true,
+ });
+
+ expect($(`.${testContext.css}`).length).toBe(6);
+ for (let line = 10; line <= 15; line += 1) {
+ expect($(`#LC${line}`)).toHaveClass(testContext.css);
+ }
+ });
+ });
+ });
+ });
+
+ describe('hashToRange', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.hashToRange;
+ });
+
+ it('extracts a single line number from the hash', () => {
+ expect(testContext.subject('#L5')).toEqual([5, null]);
+ });
+
+ it('extracts a range of line numbers from the hash', () => {
+ expect(testContext.subject('#L5-15')).toEqual([5, 15]);
+ });
+
+ it('returns [null, null] when the hash is not a line number', () => {
+ expect(testContext.subject('#foo')).toEqual([null, null]);
+ });
+ });
+
+ describe('highlightLine', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.highlightLine;
+ });
+
+ it('highlights the specified line', () => {
+ testContext.subject(13);
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+
+ it('accepts a String-based number', () => {
+ testContext.subject('13');
+
+ expect($('#LC13')).toHaveClass(testContext.css);
+ });
+ });
+
+ describe('setHash', () => {
+ beforeEach(() => {
+ testContext.subject = testContext.class.setHash;
+ });
+
+ it('sets the location hash for a single line', () => {
+ testContext.subject(5);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
+ });
+
+ it('sets the location hash for a range', () => {
+ testContext.subject(5, 15);
+
+ expect(testContext.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
+ });
+ });
+});
diff --git a/spec/frontend/blob/viewer/index_spec.js b/spec/frontend/blob/viewer/index_spec.js
index 061ac7ad167..9e9f866d40c 100644
--- a/spec/frontend/blob/viewer/index_spec.js
+++ b/spec/frontend/blob/viewer/index_spec.js
@@ -21,6 +21,7 @@ describe('Blob viewer', () => {
setTestTimeout(2000);
beforeEach(() => {
+ window.gon.features = { refactorBlobViewer: false }; // This file is based on the old (non-refactored) blob viewer
jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
$.fn.extend(jQueryMock);
mock = new MockAdapter(axios);