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')
-rw-r--r--spec/frontend/alert_management/components/alert_management_detail_spec.js39
-rw-r--r--spec/frontend/ide/components/new_dropdown/modal_spec.js27
-rw-r--r--spec/frontend/monitoring/components/variables_section_spec.js4
-rw-r--r--spec/frontend/monitoring/mock_data.js12
-rw-r--r--spec/frontend/monitoring/store/getters_spec.js5
-rw-r--r--spec/frontend/monitoring/utils_spec.js3
-rw-r--r--spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestions_spec.js102
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_selector_spec.js112
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_svg_spec.js27
10 files changed, 281 insertions, 55 deletions
diff --git a/spec/frontend/alert_management/components/alert_management_detail_spec.js b/spec/frontend/alert_management/components/alert_management_detail_spec.js
index 2758014aaa7..5234be0bf07 100644
--- a/spec/frontend/alert_management/components/alert_management_detail_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_detail_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import AlertDetails from '~/alert_management/components/alert_details.vue';
@@ -11,18 +11,20 @@ describe('AlertDetails', () => {
const newIssuePath = 'root/alerts/-/issues/new';
function mountComponent({
- data = { alert: {} },
+ data,
createIssueFromAlertEnabled = false,
loading = false,
+ mountMethod = shallowMount,
+ stubs = {},
} = {}) {
- wrapper = shallowMount(AlertDetails, {
+ wrapper = mountMethod(AlertDetails, {
propsData: {
alertId: 'alertId',
projectPath: 'projectPath',
newIssuePath,
},
data() {
- return data;
+ return { alert: { ...mockAlert }, ...data };
},
provide: {
glFeatures: { createIssueFromAlertEnabled },
@@ -36,6 +38,7 @@ describe('AlertDetails', () => {
},
},
},
+ stubs,
});
}
@@ -149,5 +152,33 @@ describe('AlertDetails', () => {
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
});
+
+ describe('header', () => {
+ const findHeader = () => wrapper.find('[data-testid="alert-header"]');
+ const stubs = { TimeAgoTooltip: '<span>now</span>' };
+
+ describe('individual header fields', () => {
+ describe.each`
+ severity | createdAt | monitoringTool | result
+ ${'MEDIUM'} | ${'2020-04-17T23:18:14.996Z'} | ${null} | ${'Medium • Reported now'}
+ ${'INFO'} | ${'2020-04-17T23:18:14.996Z'} | ${'Datadog'} | ${'Info • Reported now by Datadog'}
+ `(
+ `When severity=$severity, createdAt=$createdAt, monitoringTool=$monitoringTool`,
+ ({ severity, createdAt, monitoringTool, result }) => {
+ beforeEach(() => {
+ mountComponent({
+ data: { alert: { ...mockAlert, severity, createdAt, monitoringTool } },
+ mountMethod: mount,
+ stubs,
+ });
+ });
+
+ it('header text is shown correctly', () => {
+ expect(findHeader().text()).toBe(result);
+ });
+ },
+ );
+ });
+ });
});
});
diff --git a/spec/frontend/ide/components/new_dropdown/modal_spec.js b/spec/frontend/ide/components/new_dropdown/modal_spec.js
index 23da4df188b..597574bdeed 100644
--- a/spec/frontend/ide/components/new_dropdown/modal_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/modal_spec.js
@@ -91,22 +91,31 @@ describe('new file modal component', () => {
expect(vm.entryName).toBe('test-path');
});
- it('updated name', () => {
- vm.name = 'index.js';
+ it('does not reset entryName to its old value if empty', () => {
+ vm.entryName = 'hello';
+ vm.entryName = '';
- expect(vm.entryName).toBe('index.js');
+ expect(vm.entryName).toBe('');
+ });
+ });
+
+ describe('open', () => {
+ it('sets entryName to path provided if modalType is rename', () => {
+ vm.open('rename', 'test-path');
+
+ expect(vm.entryName).toBe('test-path');
});
- it('removes leading/trailing spaces when found in the new name', () => {
- vm.entryName = ' index.js ';
+ it("appends '/' to the path if modalType isn't rename", () => {
+ vm.open('blob', 'test-path');
- expect(vm.entryName).toBe('index.js');
+ expect(vm.entryName).toBe('test-path/');
});
- it('does not remove internal spaces in the file name', () => {
- vm.entryName = ' In Praise of Idleness.txt ';
+ it('leaves entryName blank if no path is provided', () => {
+ vm.open('blob');
- expect(vm.entryName).toBe('In Praise of Idleness.txt');
+ expect(vm.entryName).toBe('');
});
});
});
diff --git a/spec/frontend/monitoring/components/variables_section_spec.js b/spec/frontend/monitoring/components/variables_section_spec.js
index 7271beea50a..51c0e192c58 100644
--- a/spec/frontend/monitoring/components/variables_section_spec.js
+++ b/spec/frontend/monitoring/components/variables_section_spec.js
@@ -15,8 +15,8 @@ describe('Metrics dashboard/variables section component', () => {
let store;
let wrapper;
const sampleVariables = {
- label1: 'pod',
- label2: 'main',
+ 'var-label1': 'pod',
+ 'var-label2': 'main',
};
const createShallowWrapper = () => {
diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js
index 2fa88dfa87a..a8443c08b00 100644
--- a/spec/frontend/monitoring/mock_data.js
+++ b/spec/frontend/monitoring/mock_data.js
@@ -642,7 +642,7 @@ const generateMockTemplatingData = data => {
const responseForSimpleTextVariable = {
simpleText: {
- label: 'simpleText',
+ label: 'var-simpleText',
type: 'text',
value: 'Simple text',
},
@@ -650,7 +650,7 @@ const responseForSimpleTextVariable = {
const responseForAdvTextVariable = {
advText: {
- label: 'Variable 4',
+ label: 'var-Variable 4',
type: 'text',
value: 'default',
},
@@ -658,7 +658,7 @@ const responseForAdvTextVariable = {
const responseForSimpleCustomVariable = {
simpleCustom: {
- label: 'simpleCustom',
+ label: 'var-simpleCustom',
options: [
{
default: false,
@@ -682,7 +682,7 @@ const responseForSimpleCustomVariable = {
const responseForAdvancedCustomVariableWithoutOptions = {
advCustomWithoutOpts: {
- label: 'advCustomWithoutOpts',
+ label: 'var-advCustomWithoutOpts',
options: [],
type: 'custom',
},
@@ -690,7 +690,7 @@ const responseForAdvancedCustomVariableWithoutOptions = {
const responseForAdvancedCustomVariableWithoutLabel = {
advCustomWithoutLabel: {
- label: 'advCustomWithoutLabel',
+ label: 'var-advCustomWithoutLabel',
options: [
{
default: false,
@@ -710,7 +710,7 @@ const responseForAdvancedCustomVariableWithoutLabel = {
const responseForAdvancedCustomVariable = {
...responseForSimpleCustomVariable,
advCustomNormal: {
- label: 'Advanced Var',
+ label: 'var-Advanced Var',
options: [
{
default: false,
diff --git a/spec/frontend/monitoring/store/getters_spec.js b/spec/frontend/monitoring/store/getters_spec.js
index f07ae4c5a1e..e3ee9ffb2bc 100644
--- a/spec/frontend/monitoring/store/getters_spec.js
+++ b/spec/frontend/monitoring/store/getters_spec.js
@@ -327,7 +327,8 @@ describe('Monitoring store Getters', () => {
describe('getCustomVariablesArray', () => {
let state;
const sampleVariables = {
- label1: 'pod',
+ 'var-label1': 'pod',
+ 'var-label2': 'env',
};
beforeEach(() => {
@@ -340,7 +341,7 @@ describe('Monitoring store Getters', () => {
mutations[types.SET_PROM_QUERY_VARIABLES](state, sampleVariables);
const variablesArray = getters.getCustomVariablesArray(state);
- expect(variablesArray).toEqual(['label1', 'pod']);
+ expect(variablesArray).toEqual(['label1', 'pod', 'label2', 'env']);
});
it('transforms the promVariables object to an empty array when no keys are present', () => {
diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js
index 21597033e0a..52fd776e67e 100644
--- a/spec/frontend/monitoring/utils_spec.js
+++ b/spec/frontend/monitoring/utils_spec.js
@@ -192,9 +192,10 @@ describe('monitoring/utils', () => {
direction: 'left',
anchor: 'top',
pod: 'POD',
+ 'var-pod': 'POD',
});
- expect(promCustomVariablesFromUrl()).toEqual(expect.objectContaining({ pod: 'POD' }));
+ expect(promCustomVariablesFromUrl()).toEqual(expect.objectContaining({ 'var-pod': 'POD' }));
});
it('returns an empty object when no custom variables are present', () => {
diff --git a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
index f7b1f041ef2..dd24ecf707d 100644
--- a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
+++ b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
@@ -2,10 +2,7 @@ import Vue from 'vue';
import { mount } from '@vue/test-utils';
import { formatDate } from '~/lib/utils/datetime_utility';
import RelatedIssuableItem from '~/vue_shared/components/issue/related_issuable_item.vue';
-import {
- defaultAssignees,
- defaultMilestone,
-} from '../../../../javascripts/vue_shared/components/issue/related_issuable_mock_data';
+import { defaultAssignees, defaultMilestone } from './related_issuable_mock_data';
describe('RelatedIssuableItem', () => {
let wrapper;
diff --git a/spec/frontend/vue_shared/components/markdown/suggestions_spec.js b/spec/frontend/vue_shared/components/markdown/suggestions_spec.js
new file mode 100644
index 00000000000..34ccdf38b00
--- /dev/null
+++ b/spec/frontend/vue_shared/components/markdown/suggestions_spec.js
@@ -0,0 +1,102 @@
+import Vue from 'vue';
+import SuggestionsComponent from '~/vue_shared/components/markdown/suggestions.vue';
+
+const MOCK_DATA = {
+ suggestions: [
+ {
+ id: 1,
+ appliable: true,
+ applied: false,
+ current_user: {
+ can_apply: true,
+ },
+ diff_lines: [
+ {
+ can_receive_suggestion: false,
+ line_code: null,
+ meta_data: null,
+ new_line: null,
+ old_line: 5,
+ rich_text: '-test',
+ text: '-test',
+ type: 'old',
+ },
+ {
+ can_receive_suggestion: true,
+ line_code: null,
+ meta_data: null,
+ new_line: 5,
+ old_line: null,
+ rich_text: '+new test',
+ text: '+new test',
+ type: 'new',
+ },
+ ],
+ },
+ ],
+ noteHtml: `
+ <div class="suggestion">
+ <div class="line">-oldtest</div>
+ </div>
+ <div class="suggestion">
+ <div class="line">+newtest</div>
+ </div>
+ `,
+ isApplied: false,
+ helpPagePath: 'path_to_docs',
+};
+
+describe('Suggestion component', () => {
+ let vm;
+ let diffTable;
+
+ beforeEach(done => {
+ const Component = Vue.extend(SuggestionsComponent);
+
+ vm = new Component({
+ propsData: MOCK_DATA,
+ }).$mount();
+
+ diffTable = vm.generateDiff(0).$mount().$el;
+
+ jest.spyOn(vm, 'renderSuggestions').mockImplementation(() => {});
+ vm.renderSuggestions();
+ Vue.nextTick(done);
+ });
+
+ describe('mounted', () => {
+ it('renders a flash container', () => {
+ expect(vm.$el.querySelector('.js-suggestions-flash')).not.toBeNull();
+ });
+
+ it('renders a container for suggestions', () => {
+ expect(vm.$refs.container).not.toBeNull();
+ });
+
+ it('renders suggestions', () => {
+ expect(vm.renderSuggestions).toHaveBeenCalled();
+ expect(vm.$el.innerHTML.includes('oldtest')).toBe(true);
+ expect(vm.$el.innerHTML.includes('newtest')).toBe(true);
+ });
+ });
+
+ describe('generateDiff', () => {
+ it('generates a diff table', () => {
+ expect(diffTable.querySelector('.md-suggestion-diff')).not.toBeNull();
+ });
+
+ it('generates a diff table that contains contents the suggested lines', () => {
+ MOCK_DATA.suggestions[0].diff_lines.forEach(line => {
+ const text = line.text.substring(1);
+
+ expect(diffTable.innerHTML.includes(text)).toBe(true);
+ });
+ });
+
+ it('generates a diff table with the correct line number for each suggested line', () => {
+ const lines = diffTable.querySelectorAll('.old_line');
+
+ expect(parseInt([...lines][0].innerHTML, 10)).toBe(5);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
new file mode 100644
index 00000000000..29bced394dc
--- /dev/null
+++ b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
@@ -0,0 +1,112 @@
+import Vue from 'vue';
+import { head } from 'lodash';
+
+import { GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui';
+import { mount, createLocalVue } from '@vue/test-utils';
+import { trimText } from 'helpers/text_helper';
+import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
+import ProjectSelector from '~/vue_shared/components/project_selector/project_selector.vue';
+
+const localVue = createLocalVue();
+
+describe('ProjectSelector component', () => {
+ let wrapper;
+ let vm;
+ const allProjects = getJSONFixture('static/projects.json');
+ const searchResults = allProjects.slice(0, 5);
+ let selected = [];
+ selected = selected.concat(allProjects.slice(0, 3)).concat(allProjects.slice(5, 8));
+
+ const findSearchInput = () => wrapper.find(GlSearchBoxByType).find('input');
+
+ beforeEach(() => {
+ wrapper = mount(Vue.extend(ProjectSelector), {
+ localVue,
+ propsData: {
+ projectSearchResults: searchResults,
+ selectedProjects: selected,
+ showNoResultsMessage: false,
+ showMinimumSearchQueryMessage: false,
+ showLoadingIndicator: false,
+ showSearchErrorMessage: false,
+ },
+ attachToDocument: true,
+ });
+
+ ({ vm } = wrapper);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders the search results', () => {
+ expect(wrapper.findAll('.js-project-list-item').length).toBe(5);
+ });
+
+ it(`triggers a search when the search input value changes`, () => {
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ const query = 'my test query!';
+ const searchInput = findSearchInput();
+
+ searchInput.setValue(query);
+ searchInput.trigger('input');
+
+ expect(vm.$emit).toHaveBeenCalledWith('searched', query);
+ });
+
+ it(`includes a placeholder in the search box`, () => {
+ const searchInput = findSearchInput();
+
+ expect(searchInput.attributes('placeholder')).toBe('Search your projects');
+ });
+
+ it(`triggers a "bottomReached" event when user has scrolled to the bottom of the list`, () => {
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ wrapper.find(GlInfiniteScroll).vm.$emit('bottomReached');
+
+ expect(vm.$emit).toHaveBeenCalledWith('bottomReached');
+ });
+
+ it(`triggers a "projectClicked" event when a project is clicked`, () => {
+ jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ wrapper.find(ProjectListItem).vm.$emit('click', head(searchResults));
+
+ expect(vm.$emit).toHaveBeenCalledWith('projectClicked', head(searchResults));
+ });
+
+ it(`shows a "no results" message if showNoResultsMessage === true`, () => {
+ wrapper.setProps({ showNoResultsMessage: true });
+
+ return vm.$nextTick().then(() => {
+ const noResultsEl = wrapper.find('.js-no-results-message');
+
+ expect(noResultsEl.exists()).toBe(true);
+ expect(trimText(noResultsEl.text())).toEqual('Sorry, no projects matched your search');
+ });
+ });
+
+ it(`shows a "minimum search query" message if showMinimumSearchQueryMessage === true`, () => {
+ wrapper.setProps({ showMinimumSearchQueryMessage: true });
+
+ return vm.$nextTick().then(() => {
+ const minimumSearchEl = wrapper.find('.js-minimum-search-query-message');
+
+ expect(minimumSearchEl.exists()).toBe(true);
+ expect(trimText(minimumSearchEl.text())).toEqual('Enter at least three characters to search');
+ });
+ });
+
+ it(`shows a error message if showSearchErrorMessage === true`, () => {
+ wrapper.setProps({ showSearchErrorMessage: true });
+
+ return vm.$nextTick().then(() => {
+ const errorMessageEl = wrapper.find('.js-search-error-message');
+
+ expect(errorMessageEl.exists()).toBe(true);
+ expect(trimText(errorMessageEl.text())).toEqual(
+ 'Something went wrong, unable to search projects',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_svg_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_svg_spec.js
deleted file mode 100644
index ee6c2e2cc46..00000000000
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_svg_spec.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import UserAvatarSvg from '~/vue_shared/components/user_avatar/user_avatar_svg.vue';
-
-describe('User Avatar Svg Component', () => {
- describe('Initialization', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarSvg, {
- propsData: {
- size: 99,
- svg:
- '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M1.707 15.707C1.077z"/></svg>',
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should have <svg> as a child element', () => {
- expect(wrapper.element.tagName).toEqual('svg');
- expect(wrapper.html()).toContain('<path');
- });
- });
-});