summaryrefslogtreecommitdiff
path: root/spec/javascripts
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-11-19 22:11:55 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-11-19 22:11:55 +0000
commit5a8431feceba47fd8e1804d9aa1b1730606b71d5 (patch)
treee5df8e0ceee60f4af8093f5c4c2f934b8abced05 /spec/javascripts
parent4d477238500c347c6553d335d920bedfc5a46869 (diff)
downloadgitlab-ce-5a8431feceba47fd8e1804d9aa1b1730606b71d5.tar.gz
Add latest changes from gitlab-org/gitlab@12-5-stable-ee
Diffstat (limited to 'spec/javascripts')
-rw-r--r--spec/javascripts/boards/board_card_spec.js2
-rw-r--r--spec/javascripts/boards/board_list_common_spec.js15
-rw-r--r--spec/javascripts/boards/board_list_spec.js250
-rw-r--r--spec/javascripts/boards/components/boards_selector_spec.js7
-rw-r--r--spec/javascripts/boards/components/issue_time_estimate_spec.js70
-rw-r--r--spec/javascripts/boards/issue_card_spec.js292
-rw-r--r--spec/javascripts/bootstrap_jquery_spec.js14
-rw-r--r--spec/javascripts/ci_variable_list/ajax_variable_list_spec.js2
-rw-r--r--spec/javascripts/diffs/components/diff_file_spec.js49
-rw-r--r--spec/javascripts/diffs/mock_data/diff_file_unreadable.js244
-rw-r--r--spec/javascripts/dropzone_input_spec.js86
-rw-r--r--spec/javascripts/frequent_items/components/app_spec.js2
-rw-r--r--spec/javascripts/frequent_items/mock_data.js4
-rw-r--r--spec/javascripts/frequent_items/store/actions_spec.js7
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_graph_spec.js152
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_spec.js28
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_util_spec.js298
-rw-r--r--spec/javascripts/ide/components/jobs/stage_spec.js95
-rw-r--r--spec/javascripts/ide/components/repo_editor_spec.js4
-rw-r--r--spec/javascripts/ide/stores/actions/file_spec.js56
-rw-r--r--spec/javascripts/ide/stores/actions/merge_request_spec.js28
-rw-r--r--spec/javascripts/ide/stores/actions/tree_spec.js18
-rw-r--r--spec/javascripts/ide/stores/getters_spec.js55
-rw-r--r--spec/javascripts/ide/stores/modules/commit/actions_spec.js6
-rw-r--r--spec/javascripts/ide/stores/utils_spec.js30
-rw-r--r--spec/javascripts/issue_show/helpers.js11
-rw-r--r--spec/javascripts/lib/utils/tick_formats_spec.js40
-rw-r--r--spec/javascripts/merge_request_spec.js32
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js14
-rw-r--r--spec/javascripts/monitoring/charts/heatmap_spec.js69
-rw-r--r--spec/javascripts/monitoring/charts/time_series_spec.js325
-rw-r--r--spec/javascripts/monitoring/components/dashboard_spec.js432
-rw-r--r--spec/javascripts/monitoring/mock_data.js1097
-rw-r--r--spec/javascripts/monitoring/panel_type_spec.js79
-rw-r--r--spec/javascripts/monitoring/shared/prometheus_header_spec.js26
-rw-r--r--spec/javascripts/monitoring/store/actions_spec.js335
-rw-r--r--spec/javascripts/monitoring/store/mutations_spec.js177
-rw-r--r--spec/javascripts/monitoring/store/utils_spec.js74
-rw-r--r--spec/javascripts/monitoring/utils_spec.js38
-rw-r--r--spec/javascripts/notes/components/comment_form_spec.js301
-rw-r--r--spec/javascripts/notes/components/noteable_discussion_spec.js114
-rw-r--r--spec/javascripts/notes/mock_data.js1256
-rw-r--r--spec/javascripts/notes/stores/collapse_utils_spec.js10
-rw-r--r--spec/javascripts/pipelines/graph/action_component_spec.js81
-rw-r--r--spec/javascripts/pipelines/pipeline_triggerer_spec.js54
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js218
-rw-r--r--spec/javascripts/raven/index_spec.js44
-rw-r--r--spec/javascripts/raven/raven_config_spec.js254
-rw-r--r--spec/javascripts/search_autocomplete_spec.js68
-rw-r--r--spec/javascripts/sidebar/subscriptions_spec.js21
-rw-r--r--spec/javascripts/signin_tabs_memoizer_spec.js46
-rw-r--r--spec/javascripts/syntax_highlight_spec.js8
-rw-r--r--spec/javascripts/test_bundle.js33
-rw-r--r--spec/javascripts/u2f/mock_u2f_device.js18
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js234
-rw-r--r--spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js26
-rw-r--r--spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js74
-rw-r--r--spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js45
-rw-r--r--spec/javascripts/vue_shared/components/icon_spec.js13
-rw-r--r--spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js9
-rw-r--r--spec/javascripts/vue_shared/components/table_pagination_spec.js352
-rw-r--r--spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js120
-rw-r--r--spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js167
63 files changed, 1467 insertions, 6662 deletions
diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js
index 9f441ca319e..51433a58212 100644
--- a/spec/javascripts/boards/board_card_spec.js
+++ b/spec/javascripts/boards/board_card_spec.js
@@ -10,6 +10,7 @@ import eventHub from '~/boards/eventhub';
import '~/boards/models/label';
import '~/boards/models/assignee';
import '~/boards/models/list';
+import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
import boardCard from '~/boards/components/board_card.vue';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
@@ -40,6 +41,7 @@ describe('Board card', () => {
list.issues[0].labels.push(label1);
vm = new BoardCardComp({
+ store,
propsData: {
list,
issue: list.issues[0],
diff --git a/spec/javascripts/boards/board_list_common_spec.js b/spec/javascripts/boards/board_list_common_spec.js
index cb337e4cc83..ada7589b795 100644
--- a/spec/javascripts/boards/board_list_common_spec.js
+++ b/spec/javascripts/boards/board_list_common_spec.js
@@ -10,11 +10,17 @@ import BoardList from '~/boards/components/board_list.vue';
import '~/boards/models/issue';
import '~/boards/models/list';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
+import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
window.Sortable = Sortable;
-export default function createComponent({ done, listIssueProps = {}, componentProps = {} }) {
+export default function createComponent({
+ done,
+ listIssueProps = {},
+ componentProps = {},
+ listProps = {},
+}) {
const el = document.createElement('div');
document.body.appendChild(el);
@@ -24,7 +30,7 @@ export default function createComponent({ done, listIssueProps = {}, componentPr
boardsStore.create();
const BoardListComp = Vue.extend(BoardList);
- const list = new List(listObj);
+ const list = new List({ ...listObj, ...listProps });
const issue = new ListIssue({
title: 'Testing',
id: 1,
@@ -34,11 +40,14 @@ export default function createComponent({ done, listIssueProps = {}, componentPr
assignees: [],
...listIssueProps,
});
- list.issuesSize = 1;
+ if (!Object.prototype.hasOwnProperty.call(listProps, 'issuesSize')) {
+ list.issuesSize = 1;
+ }
list.issues.push(issue);
const component = new BoardListComp({
el,
+ store,
propsData: {
disabled: false,
list,
diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js
index 6774a46ed58..37e96e97279 100644
--- a/spec/javascripts/boards/board_list_spec.js
+++ b/spec/javascripts/boards/board_list_spec.js
@@ -1,156 +1,210 @@
+/* global List */
+
import Vue from 'vue';
import eventHub from '~/boards/eventhub';
import createComponent from './board_list_common_spec';
+import waitForPromises from '../helpers/wait_for_promises';
+
+import '~/boards/models/list';
describe('Board list component', () => {
let mock;
let component;
+ let getIssues;
+ function generateIssues(compWrapper) {
+ for (let i = 1; i < 20; i += 1) {
+ const issue = Object.assign({}, compWrapper.list.issues[0]);
+ issue.id += i;
+ compWrapper.list.issues.push(issue);
+ }
+ }
- beforeEach(done => {
- ({ mock, component } = createComponent({ done }));
- });
+ describe('When Expanded', () => {
+ beforeEach(done => {
+ getIssues = spyOn(List.prototype, 'getIssues').and.returnValue(new Promise(() => {}));
+ ({ mock, component } = createComponent({ done }));
+ });
- afterEach(() => {
- mock.restore();
- });
+ afterEach(() => {
+ mock.restore();
+ component.$destroy();
+ });
- it('renders component', () => {
- expect(component.$el.classList.contains('board-list-component')).toBe(true);
- });
+ it('loads first page of issues', done => {
+ waitForPromises()
+ .then(() => {
+ expect(getIssues).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
- it('renders loading icon', done => {
- component.loading = true;
+ it('renders component', () => {
+ expect(component.$el.classList.contains('board-list-component')).toBe(true);
+ });
+
+ it('renders loading icon', done => {
+ component.loading = true;
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-loading')).not.toBeNull();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-list-loading')).not.toBeNull();
- done();
+ done();
+ });
});
- });
- it('renders issues', () => {
- expect(component.$el.querySelectorAll('.board-card').length).toBe(1);
- });
+ it('renders issues', () => {
+ expect(component.$el.querySelectorAll('.board-card').length).toBe(1);
+ });
- it('sets data attribute with issue id', () => {
- expect(component.$el.querySelector('.board-card').getAttribute('data-issue-id')).toBe('1');
- });
+ it('sets data attribute with issue id', () => {
+ expect(component.$el.querySelector('.board-card').getAttribute('data-issue-id')).toBe('1');
+ });
- it('shows new issue form', done => {
- component.toggleForm();
+ it('shows new issue form', done => {
+ component.toggleForm();
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
+ expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- done();
+ done();
+ });
});
- });
- it('shows new issue form after eventhub event', done => {
- eventHub.$emit(`hide-issue-form-${component.list.id}`);
+ it('shows new issue form after eventhub event', done => {
+ eventHub.$emit(`hide-issue-form-${component.list.id}`);
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
+ expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- done();
+ done();
+ });
});
- });
- it('does not show new issue form for closed list', done => {
- component.list.type = 'closed';
- component.toggleForm();
+ it('does not show new issue form for closed list', done => {
+ component.list.type = 'closed';
+ component.toggleForm();
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).toBeNull();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-new-issue-form')).toBeNull();
- done();
+ done();
+ });
});
- });
- it('shows count list item', done => {
- component.showCount = true;
+ it('shows count list item', done => {
+ component.showCount = true;
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-count')).not.toBeNull();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-list-count')).not.toBeNull();
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing all issues',
- );
+ expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
+ 'Showing all issues',
+ );
- done();
+ done();
+ });
});
- });
- it('sets data attribute with invalid id', done => {
- component.showCount = true;
+ it('sets data attribute with invalid id', done => {
+ component.showCount = true;
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-count').getAttribute('data-issue-id')).toBe(
- '-1',
- );
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-list-count').getAttribute('data-issue-id')).toBe(
+ '-1',
+ );
- done();
+ done();
+ });
});
- });
- it('shows how many more issues to load', done => {
- component.showCount = true;
- component.list.issuesSize = 20;
+ it('shows how many more issues to load', done => {
+ component.showCount = true;
+ component.list.issuesSize = 20;
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing 1 of 20 issues',
- );
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
+ 'Showing 1 of 20 issues',
+ );
- done();
+ done();
+ });
});
- });
-
- it('loads more issues after scrolling', done => {
- spyOn(component.list, 'nextPage');
- component.$refs.list.style.height = '100px';
- component.$refs.list.style.overflow = 'scroll';
- for (let i = 1; i < 20; i += 1) {
- const issue = Object.assign({}, component.list.issues[0]);
- issue.id += i;
- component.list.issues.push(issue);
- }
+ it('loads more issues after scrolling', done => {
+ spyOn(component.list, 'nextPage');
+ component.$refs.list.style.height = '100px';
+ component.$refs.list.style.overflow = 'scroll';
+ generateIssues(component);
+
+ Vue.nextTick(() => {
+ component.$refs.list.scrollTop = 20000;
+
+ waitForPromises()
+ .then(() => {
+ expect(component.list.nextPage).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
- Vue.nextTick(() => {
- component.$refs.list.scrollTop = 20000;
+ it('does not load issues if already loading', done => {
+ component.list.nextPage = spyOn(component.list, 'nextPage').and.returnValue(
+ new Promise(() => {}),
+ );
- setTimeout(() => {
- expect(component.list.nextPage).toHaveBeenCalled();
+ component.onScroll();
+ component.onScroll();
- done();
- });
+ waitForPromises()
+ .then(() => {
+ expect(component.list.nextPage).toHaveBeenCalledTimes(1);
+ })
+ .then(done)
+ .catch(done.fail);
});
- });
- it('does not load issues if already loading', () => {
- component.list.nextPage = spyOn(component.list, 'nextPage').and.returnValue(
- new Promise(() => {}),
- );
+ it('shows loading more spinner', done => {
+ component.showCount = true;
+ component.list.loadingMore = true;
- component.onScroll();
- component.onScroll();
+ Vue.nextTick(() => {
+ expect(component.$el.querySelector('.board-list-count .gl-spinner')).not.toBeNull();
- expect(component.list.nextPage).toHaveBeenCalledTimes(1);
+ done();
+ });
+ });
});
- it('shows loading more spinner', done => {
- component.showCount = true;
- component.list.loadingMore = true;
+ describe('When Collapsed', () => {
+ beforeEach(done => {
+ getIssues = spyOn(List.prototype, 'getIssues').and.returnValue(new Promise(() => {}));
+ ({ mock, component } = createComponent({
+ done,
+ listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
+ }));
+ generateIssues(component);
+ component.scrollHeight = spyOn(component, 'scrollHeight').and.returnValue(0);
+ });
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-count .gl-spinner')).not.toBeNull();
+ afterEach(() => {
+ mock.restore();
+ component.$destroy();
+ });
- done();
+ it('does not load all issues', done => {
+ waitForPromises()
+ .then(() => {
+ // Initial getIssues from list constructor
+ expect(getIssues).toHaveBeenCalledTimes(1);
+ })
+ .then(done)
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/boards/components/boards_selector_spec.js b/spec/javascripts/boards/components/boards_selector_spec.js
index 473cc0612ea..d1f36a0a652 100644
--- a/spec/javascripts/boards/components/boards_selector_spec.js
+++ b/spec/javascripts/boards/components/boards_selector_spec.js
@@ -1,5 +1,4 @@
import Vue from 'vue';
-import BoardService from '~/boards/services/board_service';
import BoardsSelector from '~/boards/components/boards_selector.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants';
@@ -37,7 +36,6 @@ describe('BoardsSelector', () => {
bulkUpdatePath: '',
boardId: '',
});
- window.gl.boardService = new BoardService();
allBoardsResponse = Promise.resolve({
data: boards,
@@ -46,8 +44,8 @@ describe('BoardsSelector', () => {
data: recentBoards,
});
- spyOn(BoardService.prototype, 'allBoards').and.returnValue(allBoardsResponse);
- spyOn(BoardService.prototype, 'recentBoards').and.returnValue(recentBoardsResponse);
+ spyOn(boardsStore, 'allBoards').and.returnValue(allBoardsResponse);
+ spyOn(boardsStore, 'recentBoards').and.returnValue(recentBoardsResponse);
const Component = Vue.extend(BoardsSelector);
vm = mountComponent(
@@ -94,7 +92,6 @@ describe('BoardsSelector', () => {
afterEach(() => {
vm.$destroy();
- window.gl.boardService = undefined;
});
describe('filtering', () => {
diff --git a/spec/javascripts/boards/components/issue_time_estimate_spec.js b/spec/javascripts/boards/components/issue_time_estimate_spec.js
deleted file mode 100644
index de48e3f6091..00000000000
--- a/spec/javascripts/boards/components/issue_time_estimate_spec.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import Vue from 'vue';
-import IssueTimeEstimate from '~/boards/components/issue_time_estimate.vue';
-import boardsStore from '~/boards/stores/boards_store';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
-describe('Issue Time Estimate component', () => {
- let vm;
-
- beforeEach(() => {
- boardsStore.create();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('when limitToHours is false', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = false;
-
- const Component = Vue.extend(IssueTimeEstimate);
- vm = mountComponent(Component, {
- estimate: 374460,
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(vm.$el.querySelector('time').textContent.trim()).toEqual('2w 3d 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(vm.$el.querySelector('.js-issue-time-estimate').textContent).toContain(
- '2 weeks 3 days 1 minute',
- );
- });
-
- it('prevents tooltip xss', done => {
- const alertSpy = spyOn(window, 'alert');
- vm.estimate = 'Foo <script>alert("XSS")</script>';
-
- vm.$nextTick(() => {
- expect(alertSpy).not.toHaveBeenCalled();
- expect(vm.$el.querySelector('time').textContent.trim()).toEqual('0m');
- expect(vm.$el.querySelector('.js-issue-time-estimate').textContent).toContain('0m');
- done();
- });
- });
- });
-
- describe('when limitToHours is true', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = true;
-
- const Component = Vue.extend(IssueTimeEstimate);
- vm = mountComponent(Component, {
- estimate: 374460,
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(vm.$el.querySelector('time').textContent.trim()).toEqual('104h 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(vm.$el.querySelector('.js-issue-time-estimate').textContent).toContain(
- '104 hours 1 minute',
- );
- });
- });
-});
diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js
deleted file mode 100644
index 314e051665e..00000000000
--- a/spec/javascripts/boards/issue_card_spec.js
+++ /dev/null
@@ -1,292 +0,0 @@
-/* global ListAssignee */
-/* global ListLabel */
-/* global ListIssue */
-
-import Vue from 'vue';
-
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import IssueCardInner from '~/boards/components/issue_card_inner.vue';
-import { listObj } from './mock_data';
-
-describe('Issue card component', () => {
- const user = new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- });
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: 'blue',
- text_color: 'white',
- description: 'test',
- });
- let component;
- let issue;
- let list;
-
- beforeEach(() => {
- setFixtures('<div class="test-container"></div>');
-
- list = {
- ...listObj,
- type: 'label',
- };
- issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [list.label],
- assignees: [],
- reference_path: '#1',
- real_path: '/test/1',
- weight: 1,
- });
-
- component = new Vue({
- el: document.querySelector('.test-container'),
- components: {
- 'issue-card': IssueCardInner,
- },
- data() {
- return {
- list,
- issue,
- issueLinkBase: '/test',
- rootPath: '/',
- };
- },
- template: `
- <issue-card
- :issue="issue"
- :list="list"
- :issue-link-base="issueLinkBase"
- :root-path="rootPath"></issue-card>
- `,
- });
- });
-
- it('renders issue title', () => {
- expect(component.$el.querySelector('.board-card-title').textContent).toContain(issue.title);
- });
-
- it('includes issue base in link', () => {
- expect(component.$el.querySelector('.board-card-title a').getAttribute('href')).toContain(
- '/test',
- );
- });
-
- it('includes issue title on link', () => {
- expect(component.$el.querySelector('.board-card-title a').getAttribute('title')).toBe(
- issue.title,
- );
- });
-
- it('does not render confidential icon', () => {
- expect(component.$el.querySelector('.fa-eye-flash')).toBeNull();
- });
-
- it('renders confidential icon', done => {
- component.issue.confidential = true;
-
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.confidential-icon')).not.toBeNull();
- done();
- });
- });
-
- it('renders issue ID with #', () => {
- expect(component.$el.querySelector('.board-card-number').textContent).toContain(`#${issue.id}`);
- });
-
- describe('assignee', () => {
- it('does not render assignee', () => {
- expect(component.$el.querySelector('.board-card-assignee .avatar')).toBeNull();
- });
-
- describe('exists', () => {
- beforeEach(done => {
- component.issue.assignees = [user];
-
- Vue.nextTick(() => done());
- });
-
- it('renders assignee', () => {
- expect(component.$el.querySelector('.board-card-assignee .avatar')).not.toBeNull();
- });
-
- it('sets title', () => {
- expect(component.$el.querySelector('.js-assignee-tooltip').textContent).toContain(
- `${user.name}`,
- );
- });
-
- it('sets users path', () => {
- expect(component.$el.querySelector('.board-card-assignee a').getAttribute('href')).toBe(
- '/test',
- );
- });
-
- it('renders avatar', () => {
- expect(component.$el.querySelector('.board-card-assignee img')).not.toBeNull();
- });
- });
-
- describe('assignee default avatar', () => {
- beforeEach(done => {
- component.issue.assignees = [
- new ListAssignee(
- {
- id: 1,
- name: 'testing 123',
- username: 'test',
- },
- 'default_avatar',
- ),
- ];
-
- Vue.nextTick(done);
- });
-
- it('displays defaults avatar if users avatar is null', () => {
- expect(component.$el.querySelector('.board-card-assignee img')).not.toBeNull();
- expect(component.$el.querySelector('.board-card-assignee img').getAttribute('src')).toBe(
- 'default_avatar?width=24',
- );
- });
- });
- });
-
- describe('multiple assignees', () => {
- beforeEach(done => {
- component.issue.assignees = [
- new ListAssignee({
- id: 2,
- name: 'user2',
- username: 'user2',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 3,
- name: 'user3',
- username: 'user3',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 4,
- name: 'user4',
- username: 'user4',
- avatar: 'test_image',
- }),
- ];
-
- Vue.nextTick(() => done());
- });
-
- it('renders all three assignees', () => {
- expect(component.$el.querySelectorAll('.board-card-assignee .avatar').length).toEqual(3);
- });
-
- describe('more than three assignees', () => {
- beforeEach(done => {
- component.issue.assignees.push(
- new ListAssignee({
- id: 5,
- name: 'user5',
- username: 'user5',
- avatar: 'test_image',
- }),
- );
-
- Vue.nextTick(() => done());
- });
-
- it('renders more avatar counter', () => {
- expect(
- component.$el.querySelector('.board-card-assignee .avatar-counter').innerText.trim(),
- ).toEqual('+2');
- });
-
- it('renders two assignees', () => {
- expect(component.$el.querySelectorAll('.board-card-assignee .avatar').length).toEqual(2);
- });
-
- it('renders 99+ avatar counter', done => {
- for (let i = 5; i < 104; i += 1) {
- const u = new ListAssignee({
- id: i,
- name: 'name',
- username: 'username',
- avatar: 'test_image',
- });
- component.issue.assignees.push(u);
- }
-
- Vue.nextTick(() => {
- expect(
- component.$el.querySelector('.board-card-assignee .avatar-counter').innerText.trim(),
- ).toEqual('99+');
- done();
- });
- });
- });
- });
-
- describe('labels', () => {
- beforeEach(done => {
- component.issue.addLabel(label1);
-
- Vue.nextTick(() => done());
- });
-
- it('does not render list label but renders all other labels', () => {
- expect(component.$el.querySelectorAll('.badge').length).toBe(1);
- });
-
- it('renders label', () => {
- const nodes = [];
- component.$el.querySelectorAll('.badge').forEach(label => {
- nodes.push(label.getAttribute('data-original-title'));
- });
-
- expect(nodes.includes(label1.description)).toBe(true);
- });
-
- it('sets label description as title', () => {
- expect(component.$el.querySelector('.badge').getAttribute('data-original-title')).toContain(
- label1.description,
- );
- });
-
- it('sets background color of button', () => {
- const nodes = [];
- component.$el.querySelectorAll('.badge').forEach(label => {
- nodes.push(label.style.backgroundColor);
- });
-
- expect(nodes.includes(label1.color)).toBe(true);
- });
-
- it('does not render label if label does not have an ID', done => {
- component.issue.addLabel(
- new ListLabel({
- title: 'closed',
- }),
- );
-
- Vue.nextTick()
- .then(() => {
- expect(component.$el.querySelectorAll('.badge').length).toBe(1);
- expect(component.$el.textContent).not.toContain('closed');
-
- done();
- })
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/bootstrap_jquery_spec.js b/spec/javascripts/bootstrap_jquery_spec.js
index 35340a3bc42..6957cf40301 100644
--- a/spec/javascripts/bootstrap_jquery_spec.js
+++ b/spec/javascripts/bootstrap_jquery_spec.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-var */
-
import $ from 'jquery';
import '~/commons/bootstrap';
@@ -10,15 +8,13 @@ describe('Bootstrap jQuery extensions', function() {
});
it('adds the disabled attribute', function() {
- var $input;
- $input = $('input').first();
+ const $input = $('input').first();
$input.disable();
expect($input).toHaveAttr('disabled', 'disabled');
});
return it('adds the disabled class', function() {
- var $input;
- $input = $('input').first();
+ const $input = $('input').first();
$input.disable();
expect($input).toHaveClass('disabled');
@@ -30,15 +26,13 @@ describe('Bootstrap jQuery extensions', function() {
});
it('removes the disabled attribute', function() {
- var $input;
- $input = $('input').first();
+ const $input = $('input').first();
$input.enable();
expect($input).not.toHaveAttr('disabled');
});
return it('removes the disabled class', function() {
- var $input;
- $input = $('input').first();
+ const $input = $('input').first();
$input.enable();
expect($input).not.toHaveClass('disabled');
diff --git a/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js b/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
index b2fe315f6c6..b53e30b6896 100644
--- a/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
+++ b/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import AjaxFormVariableList from '~/ci_variable_list/ajax_variable_list';
-const VARIABLE_PATCH_ENDPOINT = 'http://test.host/frontend-fixtures/builds-project/variables';
+const VARIABLE_PATCH_ENDPOINT = 'http://test.host/frontend-fixtures/builds-project/-/variables';
const HIDE_CLASS = 'hide';
describe('AjaxFormVariableList', () => {
diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js
index 3ca2d1dc934..6ffdb6ba85d 100644
--- a/spec/javascripts/diffs/components/diff_file_spec.js
+++ b/spec/javascripts/diffs/components/diff_file_spec.js
@@ -3,14 +3,15 @@ import DiffFileComponent from '~/diffs/components/diff_file.vue';
import { diffViewerModes, diffViewerErrors } from '~/ide/constants';
import { createStore } from 'ee_else_ce/mr_notes/stores';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import diffFileMockData from '../mock_data/diff_file';
+import diffFileMockDataReadable from '../mock_data/diff_file';
+import diffFileMockDataUnreadable from '../mock_data/diff_file_unreadable';
describe('DiffFile', () => {
let vm;
beforeEach(() => {
vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
- file: JSON.parse(JSON.stringify(diffFileMockData)),
+ file: JSON.parse(JSON.stringify(diffFileMockDataReadable)),
canCurrentUserFork: false,
}).$mount();
});
@@ -81,6 +82,24 @@ describe('DiffFile', () => {
});
});
+ it('should be collapsable for unreadable files', done => {
+ vm.$destroy();
+ vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
+ file: JSON.parse(JSON.stringify(diffFileMockDataUnreadable)),
+ canCurrentUserFork: false,
+ }).$mount();
+
+ vm.renderIt = false;
+ vm.isCollapsed = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.innerText).toContain('This diff is collapsed');
+ expect(vm.$el.querySelectorAll('.js-click-to-expand').length).toEqual(1);
+
+ done();
+ });
+ });
+
it('should be collapsed for renamed files', done => {
vm.renderIt = true;
vm.isCollapsed = false;
@@ -184,5 +203,31 @@ describe('DiffFile', () => {
.then(done)
.catch(done.fail);
});
+
+ it('does not call handleLoadCollapsedDiff if collapsed changed & file is unreadable', done => {
+ vm.$destroy();
+ vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
+ file: JSON.parse(JSON.stringify(diffFileMockDataUnreadable)),
+ canCurrentUserFork: false,
+ }).$mount();
+
+ spyOn(vm, 'handleLoadCollapsedDiff');
+
+ vm.file.highlighted_diff_lines = undefined;
+ vm.file.parallel_diff_lines = [];
+ vm.isCollapsed = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.isCollapsed = false;
+
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(vm.handleLoadCollapsedDiff).not.toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
});
});
diff --git a/spec/javascripts/diffs/mock_data/diff_file_unreadable.js b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
new file mode 100644
index 00000000000..8c2df45988e
--- /dev/null
+++ b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
@@ -0,0 +1,244 @@
+export default {
+ submodule: false,
+ submodule_link: null,
+ blob: {
+ id: '9e10516ca50788acf18c518a231914a21e5f16f7',
+ path: 'CHANGELOG',
+ name: 'CHANGELOG',
+ mode: '100644',
+ readable_text: false,
+ icon: 'file-text-o',
+ },
+ blob_path: 'CHANGELOG',
+ blob_name: 'CHANGELOG',
+ blob_icon: '<i aria-hidden="true" data-hidden="true" class="fa fa-file-text-o fa-fw"></i>',
+ file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ file_path: 'CHANGELOG',
+ new_file: false,
+ deleted_file: false,
+ renamed_file: false,
+ old_path: 'CHANGELOG',
+ new_path: 'CHANGELOG',
+ mode_changed: false,
+ a_mode: '100644',
+ b_mode: '100644',
+ text: true,
+ viewer: {
+ name: 'text',
+ error: null,
+ collapsed: false,
+ },
+ added_lines: 0,
+ removed_lines: 0,
+ diff_refs: {
+ base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a',
+ start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962',
+ head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
+ },
+ content_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
+ stored_externally: null,
+ external_storage: null,
+ old_path_html: 'CHANGELOG',
+ new_path_html: 'CHANGELOG',
+ edit_path: '/gitlab-org/gitlab-test/edit/spooky-stuff/CHANGELOG',
+ view_path: '/gitlab-org/gitlab-test/blob/spooky-stuff/CHANGELOG',
+ replaced_view_path: null,
+ collapsed: false,
+ renderIt: false,
+ too_large: false,
+ context_lines_path:
+ '/gitlab-org/gitlab-test/blob/c48ee0d1bf3b30453f5b32250ce03134beaa6d13/CHANGELOG/diff',
+ highlighted_diff_lines: [
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1',
+ type: 'new',
+ old_line: null,
+ new_line: 1,
+ discussions: [],
+ text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ rich_text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
+ type: 'new',
+ old_line: null,
+ new_line: 2,
+ discussions: [],
+ text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ rich_text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ ],
+ parallel_diff_lines: [
+ {
+ left: {
+ type: 'empty-cell',
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1',
+ type: 'new',
+ old_line: null,
+ new_line: 1,
+ discussions: [],
+ text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ rich_text: '<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ type: 'empty-cell',
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
+ type: 'new',
+ old_line: null,
+ new_line: 2,
+ discussions: [],
+ text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC2" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_Code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: '<span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: '<span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: '<span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: '<span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ right: {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ },
+ ],
+ discussions: [],
+ renderingLines: false,
+};
diff --git a/spec/javascripts/dropzone_input_spec.js b/spec/javascripts/dropzone_input_spec.js
index ef899612b08..125dcdb3763 100644
--- a/spec/javascripts/dropzone_input_spec.js
+++ b/spec/javascripts/dropzone_input_spec.js
@@ -13,54 +13,68 @@ const TEMPLATE = `<form class="gfm-form" data-uploads-path="${TEST_UPLOAD_PATH}"
</form>`;
describe('dropzone_input', () => {
- let form;
- let dropzone;
- let xhr;
- let oldXMLHttpRequest;
+ it('returns null when failed to initialize', () => {
+ const dropzone = dropzoneInput($('<form class="gfm-form"></form>'));
- beforeEach(() => {
- form = $(TEMPLATE);
+ expect(dropzone).toBeNull();
+ });
- dropzone = dropzoneInput(form);
+ it('returns valid dropzone when successfully initialize', () => {
+ const dropzone = dropzoneInput($(TEMPLATE));
- xhr = jasmine.createSpyObj(Object.keys(XMLHttpRequest.prototype));
- oldXMLHttpRequest = window.XMLHttpRequest;
- window.XMLHttpRequest = () => xhr;
+ expect(dropzone.version).toBeTruthy();
});
- afterEach(() => {
- window.XMLHttpRequest = oldXMLHttpRequest;
- });
+ describe('shows error message', () => {
+ let form;
+ let dropzone;
+ let xhr;
+ let oldXMLHttpRequest;
- it('shows error message, when AJAX fails with json', () => {
- xhr = {
- ...xhr,
- statusCode: 400,
- readyState: 4,
- responseText: JSON.stringify({ message: TEST_ERROR_MESSAGE }),
- getResponseHeader: () => 'application/json',
- };
+ beforeEach(() => {
+ form = $(TEMPLATE);
- dropzone.processFile(TEST_FILE);
+ dropzone = dropzoneInput(form);
- xhr.onload();
+ xhr = jasmine.createSpyObj(Object.keys(XMLHttpRequest.prototype));
+ oldXMLHttpRequest = window.XMLHttpRequest;
+ window.XMLHttpRequest = () => xhr;
+ });
- expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
- });
+ afterEach(() => {
+ window.XMLHttpRequest = oldXMLHttpRequest;
+ });
+
+ it('when AJAX fails with json', () => {
+ xhr = {
+ ...xhr,
+ statusCode: 400,
+ readyState: 4,
+ responseText: JSON.stringify({ message: TEST_ERROR_MESSAGE }),
+ getResponseHeader: () => 'application/json',
+ };
+
+ dropzone.processFile(TEST_FILE);
+
+ xhr.onload();
+
+ expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
+ });
- it('shows error message, when AJAX fails with text', () => {
- xhr = {
- ...xhr,
- statusCode: 400,
- readyState: 4,
- responseText: TEST_ERROR_MESSAGE,
- getResponseHeader: () => 'text/plain',
- };
+ it('when AJAX fails with text', () => {
+ xhr = {
+ ...xhr,
+ statusCode: 400,
+ readyState: 4,
+ responseText: TEST_ERROR_MESSAGE,
+ getResponseHeader: () => 'text/plain',
+ };
- dropzone.processFile(TEST_FILE);
+ dropzone.processFile(TEST_FILE);
- xhr.onload();
+ xhr.onload();
- expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
+ expect(form.find('.uploading-error-message').text()).toEqual(TEST_ERROR_MESSAGE);
+ });
});
});
diff --git a/spec/javascripts/frequent_items/components/app_spec.js b/spec/javascripts/frequent_items/components/app_spec.js
index 36dd8604d08..da0427d650a 100644
--- a/spec/javascripts/frequent_items/components/app_spec.js
+++ b/spec/javascripts/frequent_items/components/app_spec.js
@@ -247,7 +247,7 @@ describe('Frequent Items App Component', () => {
.then(() => {
expect(vm.$el.querySelectorAll('.frequent-items-list-container li').length).toBe(
- mockSearchedProjects.length,
+ mockSearchedProjects.data.length,
);
})
.then(done)
diff --git a/spec/javascripts/frequent_items/mock_data.js b/spec/javascripts/frequent_items/mock_data.js
index 3ca5b4c7446..7f7d7b1cdbf 100644
--- a/spec/javascripts/frequent_items/mock_data.js
+++ b/spec/javascripts/frequent_items/mock_data.js
@@ -68,7 +68,7 @@ export const mockFrequentGroups = [
},
];
-export const mockSearchedGroups = [mockRawGroup];
+export const mockSearchedGroups = { data: [mockRawGroup] };
export const mockProcessedSearchedGroups = [mockGroup];
export const mockProject = {
@@ -135,7 +135,7 @@ export const mockFrequentProjects = [
},
];
-export const mockSearchedProjects = [mockRawProject];
+export const mockSearchedProjects = { data: [mockRawProject] };
export const mockProcessedSearchedProjects = [mockProject];
export const unsortedFrequentItems = [
diff --git a/spec/javascripts/frequent_items/store/actions_spec.js b/spec/javascripts/frequent_items/store/actions_spec.js
index 0a8525e77d6..7b065b69cce 100644
--- a/spec/javascripts/frequent_items/store/actions_spec.js
+++ b/spec/javascripts/frequent_items/store/actions_spec.js
@@ -169,7 +169,7 @@ describe('Frequent Items Dropdown Store Actions', () => {
});
it('should dispatch `receiveSearchedItemsSuccess`', done => {
- mock.onGet(/\/api\/v4\/projects.json(.*)$/).replyOnce(200, mockSearchedProjects);
+ mock.onGet(/\/api\/v4\/projects.json(.*)$/).replyOnce(200, mockSearchedProjects, {});
testAction(
actions.fetchSearchedItems,
@@ -178,7 +178,10 @@ describe('Frequent Items Dropdown Store Actions', () => {
[],
[
{ type: 'requestSearchedItems' },
- { type: 'receiveSearchedItemsSuccess', payload: mockSearchedProjects },
+ {
+ type: 'receiveSearchedItemsSuccess',
+ payload: { data: mockSearchedProjects, headers: {} },
+ },
],
done,
);
diff --git a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
deleted file mode 100644
index 563d134ca81..00000000000
--- a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* eslint-disable jasmine/no-suite-dupes, vars-on-top, no-var */
-
-import { scaleLinear, scaleTime } from 'd3-scale';
-import { timeParse } from 'd3-time-format';
-import {
- ContributorsGraph,
- ContributorsMasterGraph,
-} from '~/pages/projects/graphs/show/stat_graph_contributors_graph';
-
-const d3 = { scaleLinear, scaleTime, timeParse };
-
-describe('ContributorsGraph', function() {
- describe('#set_x_domain', function() {
- it('set the x_domain', function() {
- ContributorsGraph.set_x_domain(20);
-
- expect(ContributorsGraph.prototype.x_domain).toEqual(20);
- });
- });
-
- describe('#set_y_domain', function() {
- it('sets the y_domain', function() {
- ContributorsGraph.set_y_domain([{ commits: 30 }]);
-
- expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]);
- });
- });
-
- describe('#init_x_domain', function() {
- it('sets the initial x_domain', function() {
- ContributorsGraph.init_x_domain([{ date: '2013-01-31' }, { date: '2012-01-31' }]);
-
- expect(ContributorsGraph.prototype.x_domain).toEqual(['2012-01-31', '2013-01-31']);
- });
- });
-
- describe('#init_y_domain', function() {
- it('sets the initial y_domain', function() {
- ContributorsGraph.init_y_domain([{ commits: 30 }]);
-
- expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]);
- });
- });
-
- describe('#init_domain', function() {
- it('calls init_x_domain and init_y_domain', function() {
- spyOn(ContributorsGraph, 'init_x_domain');
- spyOn(ContributorsGraph, 'init_y_domain');
- ContributorsGraph.init_domain();
-
- expect(ContributorsGraph.init_x_domain).toHaveBeenCalled();
- expect(ContributorsGraph.init_y_domain).toHaveBeenCalled();
- });
- });
-
- describe('#set_dates', function() {
- it('sets the dates', function() {
- ContributorsGraph.set_dates('2013-12-01');
-
- expect(ContributorsGraph.prototype.dates).toEqual('2013-12-01');
- });
- });
-
- describe('#set_x_domain', function() {
- it("sets the instance's x domain using the prototype's x_domain", function() {
- ContributorsGraph.prototype.x_domain = 20;
- var instance = new ContributorsGraph();
- instance.x = d3
- .scaleTime()
- .range([0, 100])
- .clamp(true);
- spyOn(instance.x, 'domain');
- instance.set_x_domain();
-
- expect(instance.x.domain).toHaveBeenCalledWith(20);
- });
- });
-
- describe('#set_y_domain', function() {
- it("sets the instance's y domain using the prototype's y_domain", function() {
- ContributorsGraph.prototype.y_domain = 30;
- var instance = new ContributorsGraph();
- instance.y = d3
- .scaleLinear()
- .range([100, 0])
- .nice();
- spyOn(instance.y, 'domain');
- instance.set_y_domain();
-
- expect(instance.y.domain).toHaveBeenCalledWith(30);
- });
- });
-
- describe('#set_domain', function() {
- it('calls set_x_domain and set_y_domain', function() {
- var instance = new ContributorsGraph();
- spyOn(instance, 'set_x_domain');
- spyOn(instance, 'set_y_domain');
- instance.set_domain();
-
- expect(instance.set_x_domain).toHaveBeenCalled();
- expect(instance.set_y_domain).toHaveBeenCalled();
- });
- });
-
- describe('#set_data', function() {
- it('sets the data', function() {
- var instance = new ContributorsGraph();
- instance.set_data('20');
-
- expect(instance.data).toEqual('20');
- });
- });
-});
-
-describe('ContributorsMasterGraph', function() {
- // TODO: fix or remove
- // describe("#process_dates", function () {
- // it("gets and parses dates", function () {
- // var graph = new ContributorsMasterGraph();
- // var data = 'random data here';
- // spyOn(graph, 'parse_dates');
- // spyOn(graph, 'get_dates').andReturn("get");
- // spyOn(ContributorsGraph,'set_dates').andCallThrough();
- // graph.process_dates(data);
- // expect(graph.parse_dates).toHaveBeenCalledWith(data);
- // expect(graph.get_dates).toHaveBeenCalledWith(data);
- // expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get");
- // });
- // });
-
- describe('#get_dates', function() {
- it('plucks the date field from data collection', function() {
- var graph = new ContributorsMasterGraph();
- var data = [{ date: '2013-01-01' }, { date: '2012-12-15' }];
-
- expect(graph.get_dates(data)).toEqual(['2013-01-01', '2012-12-15']);
- });
- });
-
- describe('#parse_dates', function() {
- it('parses the dates', function() {
- var graph = new ContributorsMasterGraph();
- var parseDate = d3.timeParse('%Y-%m-%d');
- var data = [{ date: '2013-01-01' }, { date: '2012-12-15' }];
- var correct = [{ date: parseDate(data[0].date) }, { date: parseDate(data[1].date) }];
- graph.parse_dates(data);
-
- expect(data).toEqual(correct);
- });
- });
-});
diff --git a/spec/javascripts/graphs/stat_graph_contributors_spec.js b/spec/javascripts/graphs/stat_graph_contributors_spec.js
deleted file mode 100644
index 2ebb6845a8b..00000000000
--- a/spec/javascripts/graphs/stat_graph_contributors_spec.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import ContributorsStatGraph from '~/pages/projects/graphs/show/stat_graph_contributors';
-import { ContributorsGraph } from '~/pages/projects/graphs/show/stat_graph_contributors_graph';
-
-import { setLanguage } from '../helpers/locale_helper';
-
-describe('ContributorsStatGraph', () => {
- describe('change_date_header', () => {
- beforeAll(() => {
- setLanguage('de');
- });
-
- afterAll(() => {
- setLanguage(null);
- });
-
- it('uses the locale to display date ranges', () => {
- ContributorsGraph.init_x_domain([{ date: '2013-01-31' }, { date: '2012-01-31' }]);
- setFixtures('<div id="date_header"></div>');
- const graph = new ContributorsStatGraph();
-
- graph.change_date_header();
-
- expect(document.getElementById('date_header').innerText).toBe(
- '31. Januar 2012 – 31. Januar 2013',
- );
- });
- });
-});
diff --git a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js
deleted file mode 100644
index 511b660c671..00000000000
--- a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js
+++ /dev/null
@@ -1,298 +0,0 @@
-/* eslint-disable no-var, camelcase, vars-on-top */
-
-import ContributorsStatGraphUtil from '~/pages/projects/graphs/show/stat_graph_contributors_util';
-
-describe('ContributorsStatGraphUtil', function() {
- describe('#parse_log', function() {
- it('returns a correctly parsed log', function() {
- var fake_log = [
- {
- author_email: 'karlo@email.com',
- author_name: 'Karlo Soriano',
- date: '2013-05-09',
- additions: 471,
- },
- {
- author_email: 'dzaporozhets@email.com',
- author_name: 'Dmitriy Zaporozhets',
- date: '2013-05-08',
- additions: 6,
- deletions: 1,
- },
- {
- author_email: 'dzaporozhets@email.com',
- author_name: 'Dmitriy Zaporozhets',
- date: '2013-05-08',
- additions: 19,
- deletions: 3,
- },
- {
- author_email: 'dzaporozhets@email.com',
- author_name: 'Dmitriy Zaporozhets',
- date: '2013-05-08',
- additions: 29,
- deletions: 3,
- },
- ];
-
- var correct_parsed_log = {
- total: [
- { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- ],
- by_author: [
- {
- author_name: 'Karlo Soriano',
- author_email: 'karlo@email.com',
- '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- },
- {
- author_name: 'Dmitriy Zaporozhets',
- author_email: 'dzaporozhets@email.com',
- '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- },
- ],
- };
-
- expect(ContributorsStatGraphUtil.parse_log(fake_log)).toEqual(correct_parsed_log);
- });
- });
-
- describe('#store_data', function() {
- var fake_entry = { author: 'Karlo Soriano', date: '2013-05-09', additions: 471 };
- var fake_total = {};
- var fake_by_author = {};
-
- it('calls #store_commits', function() {
- spyOn(ContributorsStatGraphUtil, 'store_commits');
- ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
-
- expect(ContributorsStatGraphUtil.store_commits).toHaveBeenCalled();
- });
-
- it('calls #store_additions', function() {
- spyOn(ContributorsStatGraphUtil, 'store_additions');
- ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
-
- expect(ContributorsStatGraphUtil.store_additions).toHaveBeenCalled();
- });
-
- it('calls #store_deletions', function() {
- spyOn(ContributorsStatGraphUtil, 'store_deletions');
- ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
-
- expect(ContributorsStatGraphUtil.store_deletions).toHaveBeenCalled();
- });
- });
-
- // TODO: fix or remove
- // describe("#store_commits", function () {
- // var fake_total = "fake_total";
- // var fake_by_author = "fake_by_author";
- //
- // it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- // spyOn(ContributorsStatGraphUtil, 'add');
- // ContributorsStatGraphUtil.store_commits(fake_total, fake_by_author);
- // expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "commits", 1], ["fake_by_author", "commits", 1]]);
- // });
- // });
-
- describe('#add', function() {
- it('adds 1 to current test_field in collection', function() {
- var fake_collection = { test_field: 10 };
- ContributorsStatGraphUtil.add(fake_collection, 'test_field', 1);
-
- expect(fake_collection.test_field).toEqual(11);
- });
-
- it('inits and adds 1 if test_field in collection is not defined', function() {
- var fake_collection = {};
- ContributorsStatGraphUtil.add(fake_collection, 'test_field', 1);
-
- expect(fake_collection.test_field).toEqual(1);
- });
- });
-
- // TODO: fix or remove
- // describe("#store_additions", function () {
- // var fake_entry = {additions: 10};
- // var fake_total= "fake_total";
- // var fake_by_author = "fake_by_author";
- // it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- // spyOn(ContributorsStatGraphUtil, 'add');
- // ContributorsStatGraphUtil.store_additions(fake_entry, fake_total, fake_by_author);
- // expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "additions", 10], ["fake_by_author", "additions", 10]]);
- // });
- // });
-
- // TODO: fix or remove
- // describe("#store_deletions", function () {
- // var fake_entry = {deletions: 10};
- // var fake_total= "fake_total";
- // var fake_by_author = "fake_by_author";
- // it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- // spyOn(ContributorsStatGraphUtil, 'add');
- // ContributorsStatGraphUtil.store_deletions(fake_entry, fake_total, fake_by_author);
- // expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "deletions", 10], ["fake_by_author", "deletions", 10]]);
- // });
- // });
-
- describe('#add_date', function() {
- it('adds a date field to the collection', function() {
- var fake_date = '2013-10-02';
- var fake_collection = {};
- ContributorsStatGraphUtil.add_date(fake_date, fake_collection);
-
- expect(fake_collection[fake_date].date).toEqual('2013-10-02');
- });
- });
-
- describe('#add_author', function() {
- it('adds an author field to the collection', function() {
- var fake_author = { author_name: 'Author', author_email: 'fake@email.com' };
- var fake_author_collection = {};
- var fake_email_collection = {};
- ContributorsStatGraphUtil.add_author(
- fake_author,
- fake_author_collection,
- fake_email_collection,
- );
-
- expect(fake_author_collection[fake_author.author_name].author_name).toEqual('Author');
- expect(fake_email_collection[fake_author.author_email].author_name).toEqual('Author');
- });
- });
-
- describe('#get_total_data', function() {
- it('returns the collection sorted via specified field', function() {
- var fake_parsed_log = {
- total: [
- { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- ],
- by_author: [
- {
- author: 'Karlo Soriano',
- '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- },
- {
- author: 'Dmitriy Zaporozhets',
- '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- },
- ],
- };
- var correct_total_data = [
- { date: '2013-05-08', commits: 3 },
- { date: '2013-05-09', commits: 1 },
- ];
-
- expect(ContributorsStatGraphUtil.get_total_data(fake_parsed_log, 'commits')).toEqual(
- correct_total_data,
- );
- });
- });
-
- describe('#pick_field', function() {
- it('returns the collection with only the specified field and date', function() {
- var fake_parsed_log_total = [
- { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- ];
- ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, 'commits');
- var correct_pick_field_data = [
- { date: '2013-05-09', commits: 1 },
- { date: '2013-05-08', commits: 3 },
- ];
-
- expect(ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, 'commits')).toEqual(
- correct_pick_field_data,
- );
- });
- });
-
- describe('#get_author_data', function() {
- it('returns the log by author sorted by specified field', function() {
- var fake_parsed_log = {
- total: [
- { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- ],
- by_author: [
- {
- author_name: 'Karlo Soriano',
- author_email: 'karlo@email.com',
- '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- },
- {
- author_name: 'Dmitriy Zaporozhets',
- author_email: 'dzaporozhets@email.com',
- '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
- },
- ],
- };
- var correct_author_data = [
- {
- author_name: 'Dmitriy Zaporozhets',
- author_email: 'dzaporozhets@email.com',
- dates: { '2013-05-08': 3 },
- deletions: 7,
- additions: 54,
- commits: 3,
- },
- {
- author_name: 'Karlo Soriano',
- author_email: 'karlo@email.com',
- dates: { '2013-05-09': 1 },
- deletions: 0,
- additions: 471,
- commits: 1,
- },
- ];
-
- expect(ContributorsStatGraphUtil.get_author_data(fake_parsed_log, 'commits')).toEqual(
- correct_author_data,
- );
- });
- });
-
- describe('#parse_log_entry', function() {
- it('adds the corresponding info from the log entry to the author', function() {
- var fake_log_entry = {
- author_name: 'Karlo Soriano',
- author_email: 'karlo@email.com',
- '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
- };
- var correct_parsed_log = {
- author_name: 'Karlo Soriano',
- author_email: 'karlo@email.com',
- dates: { '2013-05-09': 1 },
- deletions: 0,
- additions: 471,
- commits: 1,
- };
-
- expect(ContributorsStatGraphUtil.parse_log_entry(fake_log_entry, 'commits', null)).toEqual(
- correct_parsed_log,
- );
- });
- });
-
- describe('#in_range', function() {
- var date = '2013-05-09';
- it('returns true if date_range is null', function() {
- expect(ContributorsStatGraphUtil.in_range(date, null)).toEqual(true);
- });
-
- it('returns true if date is in range', function() {
- var date_range = [new Date('2013-01-01'), new Date('2013-12-12')];
-
- expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(true);
- });
-
- it('returns false if date is not in range', function() {
- var date_range = [new Date('1999-12-01'), new Date('2000-12-01')];
-
- expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(false);
- });
- });
-});
diff --git a/spec/javascripts/ide/components/jobs/stage_spec.js b/spec/javascripts/ide/components/jobs/stage_spec.js
deleted file mode 100644
index fc3831f2d05..00000000000
--- a/spec/javascripts/ide/components/jobs/stage_spec.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import Vue from 'vue';
-import Stage from '~/ide/components/jobs/stage.vue';
-import { stages, jobs } from '../../mock_data';
-
-describe('IDE pipeline stage', () => {
- const Component = Vue.extend(Stage);
- let vm;
- let stage;
-
- beforeEach(() => {
- stage = {
- ...stages[0],
- id: 0,
- dropdownPath: stages[0].dropdown_path,
- jobs: [...jobs],
- isLoading: false,
- isCollapsed: false,
- };
-
- vm = new Component({
- propsData: { stage },
- });
-
- spyOn(vm, '$emit');
-
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('emits fetch event when mounted', () => {
- expect(vm.$emit).toHaveBeenCalledWith('fetch', vm.stage);
- });
-
- it('renders stages details', () => {
- expect(vm.$el.textContent).toContain(vm.stage.name);
- });
-
- it('renders CI icon', () => {
- expect(vm.$el.querySelector('.ic-status_failed')).not.toBe(null);
- });
-
- describe('collapsed', () => {
- it('emits event when clicking header', done => {
- vm.$el.querySelector('.card-header').click();
-
- vm.$nextTick(() => {
- expect(vm.$emit).toHaveBeenCalledWith('toggleCollapsed', vm.stage.id);
-
- done();
- });
- });
-
- it('toggles collapse status when collapsed', done => {
- vm.stage.isCollapsed = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
-
- done();
- });
- });
-
- it('sets border bottom class when collapsed', done => {
- vm.stage.isCollapsed = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');
-
- done();
- });
- });
- });
-
- it('renders jobs count', () => {
- expect(vm.$el.querySelector('.badge').textContent).toContain('4');
- });
-
- it('renders loading icon when no jobs and isLoading is true', done => {
- vm.stage.isLoading = true;
- vm.stage.jobs = [];
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
-
- done();
- });
- });
-
- it('renders list of jobs', () => {
- expect(vm.$el.querySelectorAll('.ide-job-item').length).toBe(4);
- });
-});
diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js
index d1b43df74b9..21fb5449858 100644
--- a/spec/javascripts/ide/components/repo_editor_spec.js
+++ b/spec/javascripts/ide/components/repo_editor_spec.js
@@ -261,10 +261,10 @@ describe('RepoEditor', () => {
});
it('updates state when model content changed', done => {
- vm.model.setValue('testing 123');
+ vm.model.setValue('testing 123\n');
setTimeout(() => {
- expect(vm.file.content).toBe('testing 123');
+ expect(vm.file.content).toBe('testing 123\n');
done();
});
diff --git a/spec/javascripts/ide/stores/actions/file_spec.js b/spec/javascripts/ide/stores/actions/file_spec.js
index 021c3076094..03d1125c23a 100644
--- a/spec/javascripts/ide/stores/actions/file_spec.js
+++ b/spec/javascripts/ide/stores/actions/file_spec.js
@@ -182,13 +182,25 @@ describe('IDE store file actions', () => {
spyOn(service, 'getFileData').and.callThrough();
localFile = file(`newCreate-${Math.random()}`);
- localFile.url = `project/getFileDataURL`;
store.state.entries[localFile.path] = localFile;
+
+ store.state.currentProjectId = 'test/test';
+ store.state.currentBranchId = 'master';
+
+ store.state.projects['test/test'] = {
+ branches: {
+ master: {
+ commit: {
+ id: '7297abc',
+ },
+ },
+ },
+ };
});
describe('success', () => {
beforeEach(() => {
- mock.onGet(`${RELATIVE_URL_ROOT}/project/getFileDataURL`).replyOnce(
+ mock.onGet(`${RELATIVE_URL_ROOT}/test/test/7297abc/${localFile.path}`).replyOnce(
200,
{
blame_path: 'blame_path',
@@ -210,7 +222,7 @@ describe('IDE store file actions', () => {
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(service.getFileData).toHaveBeenCalledWith(
- `${RELATIVE_URL_ROOT}/project/getFileDataURL`,
+ `${RELATIVE_URL_ROOT}/test/test/7297abc/${localFile.path}`,
);
done();
@@ -229,12 +241,11 @@ describe('IDE store file actions', () => {
.catch(done.fail);
});
- it('sets document title', done => {
+ it('sets document title with the branchId', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
- expect(document.title).toBe('testing getFileData');
-
+ expect(document.title).toBe(`${localFile.path} · master · test/test · GitLab`);
done();
})
.catch(done.fail);
@@ -283,7 +294,7 @@ describe('IDE store file actions', () => {
localFile.path = 'new-shiny-file';
store.state.entries[localFile.path] = localFile;
- mock.onGet(`${RELATIVE_URL_ROOT}/project/getFileDataURL`).replyOnce(
+ mock.onGet(`${RELATIVE_URL_ROOT}/test/test/7297abc/old-dull-file`).replyOnce(
200,
{
blame_path: 'blame_path',
@@ -304,7 +315,7 @@ describe('IDE store file actions', () => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
- expect(document.title).toBe('testing new-shiny-file');
+ expect(document.title).toBe(`new-shiny-file · master · test/test · GitLab`);
done();
})
@@ -314,14 +325,17 @@ describe('IDE store file actions', () => {
describe('error', () => {
beforeEach(() => {
- mock.onGet(`project/getFileDataURL`).networkError();
+ mock.onGet(`${RELATIVE_URL_ROOT}/test/test/7297abc/${localFile.path}`).networkError();
});
it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch');
actions
- .getFileData({ state: store.state, commit() {}, dispatch }, { path: localFile.path })
+ .getFileData(
+ { state: store.state, commit() {}, dispatch, getters: store.getters },
+ { path: localFile.path },
+ )
.then(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred whilst loading the file.',
@@ -455,6 +469,8 @@ describe('IDE store file actions', () => {
beforeEach(() => {
tmpFile = file('tmpFile');
+ tmpFile.content = '\n';
+ tmpFile.raw = '\n';
store.state.entries[tmpFile.path] = tmpFile;
});
@@ -462,10 +478,24 @@ describe('IDE store file actions', () => {
store
.dispatch('changeFileContent', {
path: tmpFile.path,
+ content: 'content\n',
+ })
+ .then(() => {
+ expect(tmpFile.content).toBe('content\n');
+
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('adds a newline to the end of the file if it doesnt already exist', done => {
+ store
+ .dispatch('changeFileContent', {
+ path: tmpFile.path,
content: 'content',
})
.then(() => {
- expect(tmpFile.content).toBe('content');
+ expect(tmpFile.content).toBe('content\n');
done();
})
@@ -510,12 +540,12 @@ describe('IDE store file actions', () => {
store
.dispatch('changeFileContent', {
path: tmpFile.path,
- content: 'content',
+ content: 'content\n',
})
.then(() =>
store.dispatch('changeFileContent', {
path: tmpFile.path,
- content: '',
+ content: '\n',
}),
)
.then(() => {
diff --git a/spec/javascripts/ide/stores/actions/merge_request_spec.js b/spec/javascripts/ide/stores/actions/merge_request_spec.js
index 4dd0c1150eb..a8894c644be 100644
--- a/spec/javascripts/ide/stores/actions/merge_request_spec.js
+++ b/spec/javascripts/ide/stores/actions/merge_request_spec.js
@@ -356,8 +356,30 @@ describe('IDE store merge request actions', () => {
changes: [],
};
store.state.entries = {
- foo: {},
- bar: {},
+ foo: {
+ type: 'blob',
+ },
+ bar: {
+ type: 'blob',
+ },
+ };
+
+ store.state.currentProjectId = 'test/test';
+ store.state.currentBranchId = 'master';
+
+ store.state.projects['test/test'] = {
+ branches: {
+ master: {
+ commit: {
+ id: '7297abc',
+ },
+ },
+ abcbranch: {
+ commit: {
+ id: '29020fc',
+ },
+ },
+ },
};
const originalDispatch = store.dispatch;
@@ -415,9 +437,11 @@ describe('IDE store merge request actions', () => {
it('updates activity bar view and gets file data, if changes are found', done => {
store.state.entries.foo = {
url: 'test',
+ type: 'blob',
};
store.state.entries.bar = {
url: 'test',
+ type: 'blob',
};
testMergeRequestChanges.changes = [
diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js
index 0c3c4147501..e2d8cc195ae 100644
--- a/spec/javascripts/ide/stores/actions/tree_spec.js
+++ b/spec/javascripts/ide/stores/actions/tree_spec.js
@@ -31,7 +31,10 @@ describe('Multi-file store tree actions', () => {
web_url: '',
branches: {
master: {
- workingReference: '1',
+ workingReference: '12345678',
+ commit: {
+ id: '12345678',
+ },
},
},
};
@@ -61,7 +64,7 @@ describe('Multi-file store tree actions', () => {
store
.dispatch('getFiles', basicCallParameters)
.then(() => {
- expect(service.getFiles).toHaveBeenCalledWith('', 'master');
+ expect(service.getFiles).toHaveBeenCalledWith('', '12345678');
done();
})
@@ -99,8 +102,18 @@ describe('Multi-file store tree actions', () => {
store.state.projects = {
'abc/def': {
web_url: `${gl.TEST_HOST}/files`,
+ branches: {
+ 'master-testing': {
+ commit: {
+ id: '12345',
+ },
+ },
+ },
},
};
+ const getters = {
+ findBranch: () => store.state.projects['abc/def'].branches['master-testing'],
+ };
mock.onGet(/(.*)/).replyOnce(500);
@@ -109,6 +122,7 @@ describe('Multi-file store tree actions', () => {
commit() {},
dispatch,
state: store.state,
+ getters,
},
{
projectId: 'abc/def',
diff --git a/spec/javascripts/ide/stores/getters_spec.js b/spec/javascripts/ide/stores/getters_spec.js
index 73a8d993a13..558674cc845 100644
--- a/spec/javascripts/ide/stores/getters_spec.js
+++ b/spec/javascripts/ide/stores/getters_spec.js
@@ -163,20 +163,57 @@ describe('IDE store getters', () => {
describe('currentBranch', () => {
it('returns current projects branch', () => {
- const localGetters = {
- currentProject: {
- branches: {
- master: {
- name: 'master',
- },
+ localState.currentProjectId = 'abcproject';
+ localState.currentBranchId = 'master';
+ localState.projects.abcproject = {
+ name: 'abcproject',
+ branches: {
+ master: {
+ name: 'master',
},
},
};
+ const localGetters = {
+ findBranch: jasmine.createSpy('findBranchSpy'),
+ };
+ getters.currentBranch(localState, localGetters);
+
+ expect(localGetters.findBranch).toHaveBeenCalledWith('abcproject', 'master');
+ });
+ });
+
+ describe('findProject', () => {
+ it('returns the project matching the id', () => {
+ localState.currentProjectId = 'abcproject';
+ localState.projects.abcproject = {
+ name: 'abcproject',
+ };
+
+ expect(getters.findProject(localState)('abcproject').name).toBe('abcproject');
+ });
+ });
+
+ describe('findBranch', () => {
+ let result;
+
+ it('returns the selected branch from a project', () => {
+ localState.currentProjectId = 'abcproject';
localState.currentBranchId = 'master';
+ localState.projects.abcproject = {
+ name: 'abcproject',
+ branches: {
+ master: {
+ name: 'master',
+ },
+ },
+ };
+ const localGetters = {
+ findProject: () => localState.projects.abcproject,
+ };
- expect(getters.currentBranch(localState, localGetters)).toEqual({
- name: 'master',
- });
+ result = getters.findBranch(localState, localGetters)('abcproject', 'master');
+
+ expect(result.name).toBe('master');
});
});
diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
index 95d927065f0..d464f30b947 100644
--- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
@@ -292,6 +292,8 @@ describe('IDE commit module actions', () => {
type: 'blob',
active: true,
lastCommitSha: TEST_COMMIT_SHA,
+ content: '\n',
+ raw: '\n',
};
Object.assign(store.state, {
@@ -359,7 +361,7 @@ describe('IDE commit module actions', () => {
{
action: commitActionTypes.update,
file_path: jasmine.anything(),
- content: undefined,
+ content: '\n',
encoding: jasmine.anything(),
last_commit_id: undefined,
previous_path: undefined,
@@ -386,7 +388,7 @@ describe('IDE commit module actions', () => {
{
action: commitActionTypes.update,
file_path: jasmine.anything(),
- content: undefined,
+ content: '\n',
encoding: jasmine.anything(),
last_commit_id: TEST_COMMIT_SHA,
previous_path: undefined,
diff --git a/spec/javascripts/ide/stores/utils_spec.js b/spec/javascripts/ide/stores/utils_spec.js
index a477d4fc200..37290864e3d 100644
--- a/spec/javascripts/ide/stores/utils_spec.js
+++ b/spec/javascripts/ide/stores/utils_spec.js
@@ -11,6 +11,23 @@ describe('Multi-file store utils', () => {
});
});
+ describe('setPageTitleForFile', () => {
+ it('sets the document page title for the file passed', () => {
+ const f = {
+ path: 'README.md',
+ };
+
+ const state = {
+ currentBranchId: 'master',
+ currentProjectId: 'test/test',
+ };
+
+ utils.setPageTitleForFile(state, f);
+
+ expect(document.title).toBe('README.md · master · test/test · GitLab');
+ });
+ });
+
describe('findIndexOfFile', () => {
let localState;
@@ -597,4 +614,17 @@ describe('Multi-file store utils', () => {
});
});
});
+
+ describe('addFinalNewlineIfNeeded', () => {
+ it('adds a newline if it doesnt already exist', () => {
+ [
+ { input: 'some text', output: 'some text\n' },
+ { input: 'some text\n', output: 'some text\n' },
+ { input: 'some text\n\n', output: 'some text\n\n' },
+ { input: 'some\n text', output: 'some\n text\n' },
+ ].forEach(({ input, output }) => {
+ expect(utils.addFinalNewlineIfNeeded(input)).toEqual(output);
+ });
+ });
+ });
});
diff --git a/spec/javascripts/issue_show/helpers.js b/spec/javascripts/issue_show/helpers.js
index 5d2ced98ae4..951acfd4e10 100644
--- a/spec/javascripts/issue_show/helpers.js
+++ b/spec/javascripts/issue_show/helpers.js
@@ -1,10 +1 @@
-// eslint-disable-next-line import/prefer-default-export
-export const keyboardDownEvent = (code, metaKey = false, ctrlKey = false) => {
- const e = new CustomEvent('keydown');
-
- e.keyCode = code;
- e.metaKey = metaKey;
- e.ctrlKey = ctrlKey;
-
- return e;
-};
+export * from '../../frontend/issue_show/helpers.js';
diff --git a/spec/javascripts/lib/utils/tick_formats_spec.js b/spec/javascripts/lib/utils/tick_formats_spec.js
deleted file mode 100644
index 283989b4fc8..00000000000
--- a/spec/javascripts/lib/utils/tick_formats_spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import { dateTickFormat, initDateFormats } from '~/lib/utils/tick_formats';
-
-import { setLanguage } from '../../helpers/locale_helper';
-
-describe('tick formats', () => {
- describe('dateTickFormat', () => {
- beforeAll(() => {
- setLanguage('de');
- initDateFormats();
- });
-
- afterAll(() => {
- setLanguage(null);
- });
-
- it('returns year for first of January', () => {
- const tick = dateTickFormat(new Date('2001-01-01'));
-
- expect(tick).toBe('2001');
- });
-
- it('returns month for first of February', () => {
- const tick = dateTickFormat(new Date('2001-02-01'));
-
- expect(tick).toBe('Februar');
- });
-
- it('returns day and month for second of February', () => {
- const tick = dateTickFormat(new Date('2001-02-02'));
-
- expect(tick).toBe('2. Feb.');
- });
-
- it('ignores time', () => {
- const tick = dateTickFormat(new Date('2001-02-02 12:34:56'));
-
- expect(tick).toBe('2. Feb.');
- });
- });
-});
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
index 72d6e832aca..54071ccc5c2 100644
--- a/spec/javascripts/merge_request_spec.js
+++ b/spec/javascripts/merge_request_spec.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-return-assign */
-
import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
@@ -22,7 +20,8 @@ describe('MergeRequest', function() {
.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
.reply(200, {});
- return (this.merge = new MergeRequest());
+ this.merge = new MergeRequest();
+ return this.merge;
});
afterEach(() => {
@@ -34,10 +33,30 @@ describe('MergeRequest', function() {
const changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
$('input[type=checkbox]')
+ .first()
+ .attr('checked', true)[0]
+ .dispatchEvent(changeEvent);
+ setTimeout(() => {
+ expect($('.js-task-list-field').val()).toBe(
+ '- [x] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
+ );
+ done();
+ });
+ });
+
+ it('ensure that task with only spaces does not get checked incorrectly', done => {
+ // fixed in 'deckar01-task_list', '2.2.1' gem
+ spyOn($, 'ajax').and.stub();
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]')
+ .last()
.attr('checked', true)[0]
.dispatchEvent(changeEvent);
setTimeout(() => {
- expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
+ expect($('.js-task-list-field').val()).toBe(
+ '- [ ] Task List Item\n- [ ] \n- [x] Task List Item 2\n',
+ );
done();
});
});
@@ -59,7 +78,7 @@ describe('MergeRequest', function() {
`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`,
{
merge_request: {
- description: '- [ ] Task List Item',
+ description: '- [ ] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
lock_version: 0,
update_task: { line_number: lineNumber, line_source: lineSource, index, checked },
},
@@ -70,7 +89,8 @@ describe('MergeRequest', function() {
});
});
- it('shows an error notification when tasklist update failed', done => {
+ // eslint-disable-next-line jasmine/no-disabled-tests
+ xit('shows an error notification when tasklist update failed', done => {
mock
.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
.reply(409, {});
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
index b424cbc866d..73b1ea4d36f 100644
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ b/spec/javascripts/merge_request_tabs_spec.js
@@ -1,4 +1,3 @@
-/* eslint-disable no-var */
import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
@@ -11,9 +10,9 @@ import initMrPage from './helpers/init_vue_mr_page_helper';
describe('MergeRequestTabs', function() {
let mrPageMock;
- var stubLocation = {};
- var setLocation = function(stubs) {
- var defaults = {
+ const stubLocation = {};
+ const setLocation = function(stubs) {
+ const defaults = {
pathname: '',
search: '',
hash: '',
@@ -44,9 +43,9 @@ describe('MergeRequestTabs', function() {
});
describe('opensInNewTab', function() {
- var tabUrl;
- var windowTarget = '_blank';
+ const windowTarget = '_blank';
let clickTabParams;
+ let tabUrl;
beforeEach(function() {
loadFixtures('merge_requests/merge_request_with_task_list.html');
@@ -193,11 +192,10 @@ describe('MergeRequestTabs', function() {
});
it('replaces the current history state', function() {
- var newState;
setLocation({
pathname: '/foo/bar/merge_requests/1',
});
- newState = this.subject('commits');
+ const newState = this.subject('commits');
expect(this.spies.history).toHaveBeenCalledWith(
{
diff --git a/spec/javascripts/monitoring/charts/heatmap_spec.js b/spec/javascripts/monitoring/charts/heatmap_spec.js
new file mode 100644
index 00000000000..9a98fc6fb05
--- /dev/null
+++ b/spec/javascripts/monitoring/charts/heatmap_spec.js
@@ -0,0 +1,69 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlHeatmap } from '@gitlab/ui/dist/charts';
+import Heatmap from '~/monitoring/components/charts/heatmap.vue';
+import { graphDataPrometheusQueryRangeMultiTrack } from '../mock_data';
+
+describe('Heatmap component', () => {
+ let heatmapChart;
+ let store;
+
+ beforeEach(() => {
+ heatmapChart = shallowMount(Heatmap, {
+ propsData: {
+ graphData: graphDataPrometheusQueryRangeMultiTrack,
+ containerWidth: 100,
+ },
+ store,
+ });
+ });
+
+ afterEach(() => {
+ heatmapChart.destroy();
+ });
+
+ describe('wrapped components', () => {
+ describe('GitLab UI heatmap chart', () => {
+ let glHeatmapChart;
+
+ beforeEach(() => {
+ glHeatmapChart = heatmapChart.find(GlHeatmap);
+ });
+
+ it('is a Vue instance', () => {
+ expect(glHeatmapChart.isVueInstance()).toBe(true);
+ });
+
+ it('should display a label on the x axis', () => {
+ expect(heatmapChart.vm.xAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.x_label);
+ });
+
+ it('should display a label on the y axis', () => {
+ expect(heatmapChart.vm.yAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.y_label);
+ });
+
+ // According to the echarts docs https://echarts.apache.org/en/option.html#series-heatmap.data
+ // each row of the heatmap chart is represented by an array inside another parent array
+ // e.g. [[0, 0, 10]], the format represents the column, the row and finally the value
+ // corresponding to the cell
+
+ it('should return chartData with a length of x by y, with a length of 3 per array', () => {
+ const row = heatmapChart.vm.chartData[0];
+
+ expect(row.length).toBe(3);
+ expect(heatmapChart.vm.chartData.length).toBe(30);
+ });
+
+ it('returns a series of labels for the x axis', () => {
+ const { xAxisLabels } = heatmapChart.vm;
+
+ expect(xAxisLabels.length).toBe(5);
+ });
+
+ it('returns a series of labels for the y axis', () => {
+ const { yAxisLabels } = heatmapChart.vm;
+
+ expect(yAxisLabels.length).toBe(6);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/monitoring/charts/time_series_spec.js b/spec/javascripts/monitoring/charts/time_series_spec.js
deleted file mode 100644
index 5c718135b90..00000000000
--- a/spec/javascripts/monitoring/charts/time_series_spec.js
+++ /dev/null
@@ -1,325 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { createStore } from '~/monitoring/stores';
-import { GlLink } from '@gitlab/ui';
-import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
-import { shallowWrapperContainsSlotText } from 'spec/helpers/vue_test_utils_helper';
-import TimeSeries from '~/monitoring/components/charts/time_series.vue';
-import * as types from '~/monitoring/stores/mutation_types';
-import { TEST_HOST } from 'spec/test_constants';
-import MonitoringMock, { deploymentData, mockProjectPath } from '../mock_data';
-
-describe('Time series component', () => {
- const mockSha = 'mockSha';
- const mockWidgets = 'mockWidgets';
- const mockSvgPathContent = 'mockSvgPathContent';
- const projectPath = `${TEST_HOST}${mockProjectPath}`;
- const commitUrl = `${projectPath}/commit/${mockSha}`;
- let mockGraphData;
- let makeTimeSeriesChart;
- let spriteSpy;
- let store;
-
- beforeEach(() => {
- store = createStore();
- store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, MonitoringMock.data);
- store.commit(`monitoringDashboard/${types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS}`, deploymentData);
- [mockGraphData] = store.state.monitoringDashboard.groups[0].metrics;
-
- makeTimeSeriesChart = (graphData, type) =>
- shallowMount(TimeSeries, {
- propsData: {
- graphData: { ...graphData, type },
- containerWidth: 0,
- deploymentData: store.state.monitoringDashboard.deploymentData,
- projectPath,
- },
- slots: {
- default: mockWidgets,
- },
- sync: false,
- store,
- });
-
- spriteSpy = spyOnDependency(TimeSeries, 'getSvgIconPathContent').and.callFake(
- () => new Promise(resolve => resolve(mockSvgPathContent)),
- );
- });
-
- describe('general functions', () => {
- let timeSeriesChart;
-
- beforeEach(() => {
- timeSeriesChart = makeTimeSeriesChart(mockGraphData, 'area-chart');
- });
-
- it('renders chart title', () => {
- expect(timeSeriesChart.find('.js-graph-title').text()).toBe(mockGraphData.title);
- });
-
- it('contains graph widgets from slot', () => {
- expect(timeSeriesChart.find('.js-graph-widgets').text()).toBe(mockWidgets);
- });
-
- it('allows user to override max value label text using prop', () => {
- timeSeriesChart.setProps({ legendMaxText: 'legendMaxText' });
-
- expect(timeSeriesChart.props().legendMaxText).toBe('legendMaxText');
- });
-
- it('allows user to override average value label text using prop', () => {
- timeSeriesChart.setProps({ legendAverageText: 'averageText' });
-
- expect(timeSeriesChart.props().legendAverageText).toBe('averageText');
- });
-
- describe('methods', () => {
- describe('formatTooltipText', () => {
- const mockDate = deploymentData[0].created_at;
- const mockCommitUrl = deploymentData[0].commitUrl;
- const generateSeriesData = type => ({
- seriesData: [
- {
- seriesName: timeSeriesChart.vm.chartData[0].name,
- componentSubType: type,
- value: [mockDate, 5.55555],
- seriesIndex: 0,
- },
- ],
- value: mockDate,
- });
-
- describe('when series is of line type', () => {
- beforeEach(done => {
- timeSeriesChart.vm.formatTooltipText(generateSeriesData('line'));
- timeSeriesChart.vm.$nextTick(done);
- });
-
- it('formats tooltip title', () => {
- expect(timeSeriesChart.vm.tooltip.title).toBe('31 May 2017, 9:23PM');
- });
-
- it('formats tooltip content', () => {
- const name = 'Core Usage';
- const value = '5.556';
- const seriesLabel = timeSeriesChart.find(GlChartSeriesLabel);
-
- expect(seriesLabel.vm.color).toBe('');
- expect(shallowWrapperContainsSlotText(seriesLabel, 'default', name)).toBe(true);
- expect(timeSeriesChart.vm.tooltip.content).toEqual([{ name, value, color: undefined }]);
- expect(
- shallowWrapperContainsSlotText(
- timeSeriesChart.find(GlAreaChart),
- 'tooltipContent',
- value,
- ),
- ).toBe(true);
- });
- });
-
- describe('when series is of scatter type', () => {
- beforeEach(() => {
- timeSeriesChart.vm.formatTooltipText(generateSeriesData('scatter'));
- });
-
- it('formats tooltip title', () => {
- expect(timeSeriesChart.vm.tooltip.title).toBe('31 May 2017, 9:23PM');
- });
-
- it('formats tooltip sha', () => {
- expect(timeSeriesChart.vm.tooltip.sha).toBe('f5bcd1d9');
- });
-
- it('formats tooltip commit url', () => {
- expect(timeSeriesChart.vm.tooltip.commitUrl).toBe(mockCommitUrl);
- });
- });
- });
-
- describe('setSvg', () => {
- const mockSvgName = 'mockSvgName';
-
- beforeEach(done => {
- timeSeriesChart.vm.setSvg(mockSvgName);
- timeSeriesChart.vm.$nextTick(done);
- });
-
- it('gets svg path content', () => {
- expect(spriteSpy).toHaveBeenCalledWith(mockSvgName);
- });
-
- it('sets svg path content', () => {
- timeSeriesChart.vm.$nextTick(() => {
- expect(timeSeriesChart.vm.svgs[mockSvgName]).toBe(`path://${mockSvgPathContent}`);
- });
- });
-
- it('contains an svg object within an array to properly render icon', () => {
- timeSeriesChart.vm.$nextTick(() => {
- expect(timeSeriesChart.vm.chartOptions.dataZoom).toEqual([
- {
- handleIcon: `path://${mockSvgPathContent}`,
- },
- ]);
- });
- });
- });
-
- describe('onResize', () => {
- const mockWidth = 233;
-
- beforeEach(() => {
- spyOn(Element.prototype, 'getBoundingClientRect').and.callFake(() => ({
- width: mockWidth,
- }));
- timeSeriesChart.vm.onResize();
- });
-
- it('sets area chart width', () => {
- expect(timeSeriesChart.vm.width).toBe(mockWidth);
- });
- });
- });
-
- describe('computed', () => {
- describe('chartData', () => {
- let chartData;
- const seriesData = () => chartData[0];
-
- beforeEach(() => {
- ({ chartData } = timeSeriesChart.vm);
- });
-
- it('utilizes all data points', () => {
- const { values } = mockGraphData.queries[0].result[0];
-
- expect(chartData.length).toBe(1);
- expect(seriesData().data.length).toBe(values.length);
- });
-
- it('creates valid data', () => {
- const { data } = seriesData();
-
- expect(
- data.filter(
- ([time, value]) => new Date(time).getTime() > 0 && typeof value === 'number',
- ).length,
- ).toBe(data.length);
- });
-
- it('formats line width correctly', () => {
- expect(chartData[0].lineStyle.width).toBe(2);
- });
- });
-
- describe('chartOptions', () => {
- describe('yAxis formatter', () => {
- let format;
-
- beforeEach(() => {
- format = timeSeriesChart.vm.chartOptions.yAxis.axisLabel.formatter;
- });
-
- it('rounds to 3 decimal places', () => {
- expect(format(0.88888)).toBe('0.889');
- });
- });
- });
-
- describe('scatterSeries', () => {
- it('utilizes deployment data', () => {
- expect(timeSeriesChart.vm.scatterSeries.data).toEqual([
- ['2017-05-31T21:23:37.881Z', 0],
- ['2017-05-30T20:08:04.629Z', 0],
- ['2017-05-30T17:42:38.409Z', 0],
- ]);
-
- expect(timeSeriesChart.vm.scatterSeries.symbolSize).toBe(14);
- });
- });
-
- describe('yAxisLabel', () => {
- it('constructs a label for the chart y-axis', () => {
- expect(timeSeriesChart.vm.yAxisLabel).toBe('CPU');
- });
- });
- });
-
- afterEach(() => {
- timeSeriesChart.destroy();
- });
- });
-
- describe('wrapped components', () => {
- const glChartComponents = [
- {
- chartType: 'area-chart',
- component: GlAreaChart,
- },
- {
- chartType: 'line-chart',
- component: GlLineChart,
- },
- ];
-
- glChartComponents.forEach(dynamicComponent => {
- describe(`GitLab UI: ${dynamicComponent.chartType}`, () => {
- let timeSeriesAreaChart;
- let glChart;
-
- beforeEach(done => {
- timeSeriesAreaChart = makeTimeSeriesChart(mockGraphData, dynamicComponent.chartType);
- glChart = timeSeriesAreaChart.find(dynamicComponent.component);
- timeSeriesAreaChart.vm.$nextTick(done);
- });
-
- it('is a Vue instance', () => {
- expect(glChart.exists()).toBe(true);
- expect(glChart.isVueInstance()).toBe(true);
- });
-
- it('receives data properties needed for proper chart render', () => {
- const props = glChart.props();
-
- expect(props.data).toBe(timeSeriesAreaChart.vm.chartData);
- expect(props.option).toBe(timeSeriesAreaChart.vm.chartOptions);
- expect(props.formatTooltipText).toBe(timeSeriesAreaChart.vm.formatTooltipText);
- expect(props.thresholds).toBe(timeSeriesAreaChart.vm.thresholds);
- });
-
- it('recieves a tooltip title', done => {
- const mockTitle = 'mockTitle';
- timeSeriesAreaChart.vm.tooltip.title = mockTitle;
-
- timeSeriesAreaChart.vm.$nextTick(() => {
- expect(shallowWrapperContainsSlotText(glChart, 'tooltipTitle', mockTitle)).toBe(true);
- done();
- });
- });
-
- describe('when tooltip is showing deployment data', () => {
- beforeEach(done => {
- timeSeriesAreaChart.vm.tooltip.isDeployment = true;
- timeSeriesAreaChart.vm.$nextTick(done);
- });
-
- it('uses deployment title', () => {
- expect(shallowWrapperContainsSlotText(glChart, 'tooltipTitle', 'Deployed')).toBe(true);
- });
-
- it('renders clickable commit sha in tooltip content', done => {
- timeSeriesAreaChart.vm.tooltip.sha = mockSha;
- timeSeriesAreaChart.vm.tooltip.commitUrl = commitUrl;
-
- timeSeriesAreaChart.vm.$nextTick(() => {
- const commitLink = timeSeriesAreaChart.find(GlLink);
-
- expect(shallowWrapperContainsSlotText(commitLink, 'default', mockSha)).toBe(true);
- expect(commitLink.attributes('href')).toEqual(commitUrl);
- done();
- });
- });
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/monitoring/components/dashboard_spec.js b/spec/javascripts/monitoring/components/dashboard_spec.js
index 75df2ce3103..0f20171726c 100644
--- a/spec/javascripts/monitoring/components/dashboard_spec.js
+++ b/spec/javascripts/monitoring/components/dashboard_spec.js
@@ -7,11 +7,12 @@ import Dashboard from '~/monitoring/components/dashboard.vue';
import * as types from '~/monitoring/stores/mutation_types';
import { createStore } from '~/monitoring/stores';
import axios from '~/lib/utils/axios_utils';
-import MonitoringMock, {
+import {
metricsGroupsAPIResponse,
+ mockedQueryResultPayload,
+ mockedQueryResultPayloadCoresTotal,
mockApiEndpoint,
environmentData,
- singleGroupResponse,
dashboardGitResponse,
} from '../mock_data';
@@ -44,12 +45,33 @@ const resetSpy = spy => {
export default propsData;
+function setupComponentStore(component) {
+ component.$store.commit(
+ `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
+ metricsGroupsAPIResponse,
+ );
+
+ // Load 2 panels to the dashboard
+ component.$store.commit(
+ `monitoringDashboard/${types.SET_QUERY_RESULT}`,
+ mockedQueryResultPayload,
+ );
+ component.$store.commit(
+ `monitoringDashboard/${types.SET_QUERY_RESULT}`,
+ mockedQueryResultPayloadCoresTotal,
+ );
+
+ component.$store.commit(
+ `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
+ environmentData,
+ );
+}
+
describe('Dashboard', () => {
let DashboardComponent;
let mock;
let store;
let component;
- let mockGraphData;
beforeEach(() => {
setFixtures(`
@@ -100,6 +122,32 @@ describe('Dashboard', () => {
});
});
+ describe('cluster health', () => {
+ let wrapper;
+
+ beforeEach(done => {
+ wrapper = shallowMount(DashboardComponent, {
+ localVue,
+ sync: false,
+ propsData: { ...propsData, hasMetrics: true },
+ store,
+ });
+
+ // all_dashboards is not defined in health dashboards
+ wrapper.vm.$store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined);
+ wrapper.vm.$nextTick(done);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders correctly', () => {
+ expect(wrapper.isVueInstance()).toBe(true);
+ expect(wrapper.exists()).toBe(true);
+ });
+ });
+
describe('requests information to the server', () => {
let spy;
beforeEach(() => {
@@ -123,25 +171,6 @@ describe('Dashboard', () => {
});
});
- it('hides the legend when showLegend is false', done => {
- component = new DashboardComponent({
- el: document.querySelector('.prometheus-graphs'),
- propsData: {
- ...propsData,
- hasMetrics: true,
- showLegend: false,
- },
- store,
- });
-
- setTimeout(() => {
- expect(component.showEmptyState).toEqual(false);
- expect(component.$el.querySelector('.legend-group')).toEqual(null);
- expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
- done();
- });
- });
-
it('hides the group panels when showPanels is false', done => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
@@ -153,52 +182,66 @@ describe('Dashboard', () => {
store,
});
- setTimeout(() => {
- expect(component.showEmptyState).toEqual(false);
- expect(component.$el.querySelector('.prometheus-panel')).toEqual(null);
- expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
- done();
- });
+ setupComponentStore(component);
+
+ Vue.nextTick()
+ .then(() => {
+ expect(component.showEmptyState).toEqual(false);
+ expect(component.$el.querySelector('.prometheus-panel')).toEqual(null);
+ expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
+
+ done();
+ })
+ .catch(done.fail);
});
- it('renders the environments dropdown with a number of environments', done => {
- component = new DashboardComponent({
- el: document.querySelector('.prometheus-graphs'),
- propsData: {
- ...propsData,
- hasMetrics: true,
- showPanels: false,
- },
- store,
+ describe('when all the requests have been commited by the store', () => {
+ beforeEach(() => {
+ component = new DashboardComponent({
+ el: document.querySelector('.prometheus-graphs'),
+ propsData: {
+ ...propsData,
+ hasMetrics: true,
+ },
+ store,
+ });
+
+ setupComponentStore(component);
});
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
- singleGroupResponse,
- );
+ it('renders the environments dropdown with a number of environments', done => {
+ Vue.nextTick()
+ .then(() => {
+ const dropdownMenuEnvironments = component.$el.querySelectorAll(
+ '.js-environments-dropdown .dropdown-item',
+ );
- Vue.nextTick()
- .then(() => {
- const dropdownMenuEnvironments = component.$el.querySelectorAll(
- '.js-environments-dropdown .dropdown-item',
- );
+ expect(component.environments.length).toEqual(environmentData.length);
+ expect(dropdownMenuEnvironments.length).toEqual(component.environments.length);
- expect(component.environments.length).toEqual(environmentData.length);
- expect(dropdownMenuEnvironments.length).toEqual(component.environments.length);
+ Array.from(dropdownMenuEnvironments).forEach((value, index) => {
+ if (environmentData[index].metrics_path) {
+ expect(value).toHaveAttr('href', environmentData[index].metrics_path);
+ }
+ });
- Array.from(dropdownMenuEnvironments).forEach((value, index) => {
- if (environmentData[index].metrics_path) {
- expect(value).toHaveAttr('href', environmentData[index].metrics_path);
- }
- });
+ done();
+ })
+ .catch(done.fail);
+ });
- done();
- })
- .catch(done.fail);
+ it('renders the environments dropdown with a single active element', done => {
+ Vue.nextTick()
+ .then(() => {
+ const dropdownItems = component.$el.querySelectorAll(
+ '.js-environments-dropdown .dropdown-item.active',
+ );
+
+ expect(dropdownItems.length).toEqual(1);
+ done();
+ })
+ .catch(done.fail);
+ });
});
it('hides the environments dropdown list when there is no environments', done => {
@@ -207,15 +250,17 @@ describe('Dashboard', () => {
propsData: {
...propsData,
hasMetrics: true,
- showPanels: false,
},
store,
});
- component.$store.commit(`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, []);
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
- singleGroupResponse,
+ metricsGroupsAPIResponse,
+ );
+ component.$store.commit(
+ `monitoringDashboard/${types.SET_QUERY_RESULT}`,
+ mockedQueryResultPayload,
);
Vue.nextTick()
@@ -230,7 +275,7 @@ describe('Dashboard', () => {
.catch(done.fail);
});
- it('renders the environments dropdown with a single active element', done => {
+ it('renders the datetimepicker dropdown', done => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
propsData: {
@@ -241,64 +286,16 @@ describe('Dashboard', () => {
store,
});
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
- singleGroupResponse,
- );
+ setupComponentStore(component);
Vue.nextTick()
.then(() => {
- const dropdownItems = component.$el.querySelectorAll(
- '.js-environments-dropdown .dropdown-item.active',
- );
-
- expect(dropdownItems.length).toEqual(1);
+ expect(component.$el.querySelector('.js-time-window-dropdown')).not.toBeNull();
done();
})
.catch(done.fail);
});
- it('hides the dropdown', done => {
- component = new DashboardComponent({
- el: document.querySelector('.prometheus-graphs'),
- propsData: {
- ...propsData,
- hasMetrics: true,
- showPanels: false,
- environmentsEndpoint: '',
- },
- store,
- });
-
- Vue.nextTick(() => {
- const dropdownIsActiveElement = component.$el.querySelectorAll('.environments');
-
- expect(dropdownIsActiveElement.length).toEqual(0);
- done();
- });
- });
-
- it('renders the datetimepicker dropdown', done => {
- component = new DashboardComponent({
- el: document.querySelector('.prometheus-graphs'),
- propsData: {
- ...propsData,
- hasMetrics: true,
- showPanels: false,
- },
- store,
- });
-
- setTimeout(() => {
- expect(component.$el.querySelector('.js-time-window-dropdown')).not.toBeNull();
- done();
- });
- });
-
it('fetches the metrics data with proper time window', done => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
@@ -347,14 +344,21 @@ describe('Dashboard', () => {
el: document.querySelector('.prometheus-graphs'),
propsData: { ...propsData, hasMetrics: true },
store,
+ sync: false,
});
- setTimeout(() => {
- const selectedTimeWindow = component.$el.querySelector('.js-time-window-dropdown .active');
+ setupComponentStore(component);
- expect(selectedTimeWindow.textContent.trim()).toEqual('30 minutes');
- done();
- });
+ Vue.nextTick()
+ .then(() => {
+ const selectedTimeWindow = component.$el.querySelector(
+ '.js-time-window-dropdown .active',
+ );
+
+ expect(selectedTimeWindow.textContent.trim()).toEqual('30 minutes');
+ done();
+ })
+ .catch(done.fail);
});
it('shows an error message if invalid url parameters are passed', done => {
@@ -381,29 +385,36 @@ describe('Dashboard', () => {
describe('drag and drop function', () => {
let wrapper;
let expectedPanelCount; // also called metrics, naming to be improved: https://gitlab.com/gitlab-org/gitlab/issues/31565
+
const findDraggables = () => wrapper.findAll(VueDraggable);
const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled'));
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
- beforeEach(done => {
+ beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
- expectedPanelCount = metricsGroupsAPIResponse.data.reduce(
- (acc, d) => d.metrics.length + acc,
+ expectedPanelCount = metricsGroupsAPIResponse.reduce(
+ (acc, group) => group.panels.length + acc,
0,
);
- store.dispatch('monitoringDashboard/setFeatureFlags', { additionalPanelTypesEnabled: true });
+ });
+ beforeEach(done => {
wrapper = shallowMount(DashboardComponent, {
localVue,
sync: false,
propsData: { ...propsData, hasMetrics: true },
store,
+ attachToDocument: true,
});
- // not using $nextTicket becuase we must wait for the dashboard
- // to be populated with the mock data results.
- setTimeout(done);
+ setupComponentStore(wrapper.vm);
+
+ wrapper.vm.$nextTick(done);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
});
it('wraps vuedraggable', () => {
@@ -442,6 +453,28 @@ describe('Dashboard', () => {
expect(findEnabledDraggables()).toEqual(findDraggables());
});
+ it('metrics can be swapped', done => {
+ const firstDraggable = findDraggables().at(0);
+ const mockMetrics = [...metricsGroupsAPIResponse[0].panels];
+ const value = () => firstDraggable.props('value');
+
+ expect(value().length).toBe(mockMetrics.length);
+ value().forEach((metric, i) => {
+ expect(metric.title).toBe(mockMetrics[i].title);
+ });
+
+ // swap two elements and `input` them
+ [mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
+ firstDraggable.vm.$emit('input', mockMetrics);
+
+ firstDraggable.vm.$nextTick(() => {
+ value().forEach((metric, i) => {
+ expect(metric.title).toBe(mockMetrics[i].title);
+ });
+ done();
+ });
+ });
+
it('shows a remove button, which removes a panel', done => {
expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
@@ -449,8 +482,6 @@ describe('Dashboard', () => {
findFirstDraggableRemoveButton().trigger('click');
wrapper.vm.$nextTick(() => {
- // At present graphs will not be removed in backend
- // See https://gitlab.com/gitlab-org/gitlab/issues/27835
expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1);
done();
});
@@ -466,10 +497,6 @@ describe('Dashboard', () => {
});
});
});
-
- afterEach(() => {
- wrapper.destroy();
- });
});
// https://gitlab.com/gitlab-org/gitlab-ce/issues/66922
@@ -539,42 +566,93 @@ describe('Dashboard', () => {
});
});
- describe('when the window resizes', () => {
+ describe('responds to window resizes', () => {
+ let promPanel;
+ let promGroup;
+ let panelToggle;
+ let chart;
beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
- jasmine.clock().install();
- });
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- it('sets elWidth to page width when the sidebar is resized', done => {
component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
propsData: {
...propsData,
hasMetrics: true,
- showPanels: false,
+ showPanels: true,
},
store,
});
- expect(component.elWidth).toEqual(0);
+ setupComponentStore(component);
- const pageLayoutEl = document.querySelector('.layout-page');
- pageLayoutEl.classList.add('page-with-icon-sidebar');
+ return Vue.nextTick().then(() => {
+ promPanel = component.$el.querySelector('.prometheus-panel');
+ promGroup = promPanel.querySelector('.prometheus-graph-group');
+ panelToggle = promPanel.querySelector('.js-graph-group-toggle');
+ chart = promGroup.querySelector('.position-relative svg');
+ });
+ });
- Vue.nextTick()
- .then(() => {
- jasmine.clock().tick(1000);
- return Vue.nextTick();
- })
- .then(() => {
- expect(component.elWidth).toEqual(pageLayoutEl.clientWidth);
- done();
- })
- .catch(done.fail);
+ it('setting chart size to zero when panel group is hidden', () => {
+ expect(promGroup.style.display).toBe('');
+ expect(chart.clientWidth).toBeGreaterThan(0);
+
+ panelToggle.click();
+ return Vue.nextTick().then(() => {
+ expect(promGroup.style.display).toBe('none');
+ expect(chart.clientWidth).toBe(0);
+ promPanel.style.width = '500px';
+ });
+ });
+
+ it('expanding chart panel group after resize displays chart', () => {
+ panelToggle.click();
+
+ expect(chart.clientWidth).toBeGreaterThan(0);
+ });
+ });
+
+ describe('dashboard edit link', () => {
+ let wrapper;
+ const findEditLink = () => wrapper.find('.js-edit-link');
+
+ beforeEach(done => {
+ mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
+
+ wrapper = shallowMount(DashboardComponent, {
+ localVue,
+ sync: false,
+ attachToDocument: true,
+ propsData: { ...propsData, hasMetrics: true },
+ store,
+ });
+
+ wrapper.vm.$store.commit(
+ `monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
+ dashboardGitResponse,
+ );
+ wrapper.vm.$nextTick(done);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('is not present for the default dashboard', () => {
+ expect(findEditLink().exists()).toBe(false);
+ });
+
+ it('is present for a custom dashboard, and links to its edit_path', done => {
+ const dashboard = dashboardGitResponse[1]; // non-default dashboard
+ const currentDashboard = dashboard.path;
+
+ wrapper.setProps({ currentDashboard });
+ wrapper.vm.$nextTick(() => {
+ expect(findEditLink().exists()).toBe(true);
+ expect(findEditLink().attributes('href')).toBe(dashboard.project_blob_path);
+ done();
+ });
});
});
@@ -619,20 +697,6 @@ describe('Dashboard', () => {
store,
});
- component.$store.dispatch('monitoringDashboard/setFeatureFlags', {
- prometheusEndpoint: false,
- });
-
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
-
- component.$store.commit(
- `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
- singleGroupResponse,
- );
-
component.$store.commit(
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
dashboardGitResponse,
@@ -648,36 +712,4 @@ describe('Dashboard', () => {
});
});
});
-
- describe('when downloading metrics data as CSV', () => {
- beforeEach(() => {
- component = new DashboardComponent({
- propsData: {
- ...propsData,
- },
- store,
- });
- store.commit(
- `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
- MonitoringMock.data,
- );
- [mockGraphData] = component.$store.state.monitoringDashboard.groups[0].metrics;
- });
-
- describe('csvText', () => {
- it('converts metrics data from json to csv', () => {
- const header = `timestamp,${mockGraphData.y_label}`;
- const data = mockGraphData.queries[0].result[0].values;
- const firstRow = `${data[0][0]},${data[0][1]}`;
-
- expect(component.csvText(mockGraphData)).toMatch(`^${header}\r\n${firstRow}`);
- });
- });
-
- describe('downloadCsv', () => {
- it('produces a link with a Blob', () => {
- expect(component.downloadCsv(mockGraphData)).toContain(`blob:`);
- });
- });
- });
});
diff --git a/spec/javascripts/monitoring/mock_data.js b/spec/javascripts/monitoring/mock_data.js
index 17e7314e214..f9cc839bde6 100644
--- a/spec/javascripts/monitoring/mock_data.js
+++ b/spec/javascripts/monitoring/mock_data.js
@@ -1,943 +1,103 @@
-export const mockApiEndpoint = `${gl.TEST_HOST}/monitoring/mock`;
+import {
+ anomalyMockGraphData as importedAnomalyMockGraphData,
+ metricsGroupsAPIResponse as importedMetricsGroupsAPIResponse,
+ environmentData as importedEnvironmentData,
+ dashboardGitResponse as importedDashboardGitResponse,
+} from '../../frontend/monitoring/mock_data';
-export const mockProjectPath = '/frontend-fixtures/environments-project';
+export const anomalyMockGraphData = importedAnomalyMockGraphData;
+export const metricsGroupsAPIResponse = importedMetricsGroupsAPIResponse;
+export const environmentData = importedEnvironmentData;
+export const dashboardGitResponse = importedDashboardGitResponse;
-export const metricsGroupsAPIResponse = {
- success: true,
- data: [
- {
- group: 'Kubernetes',
- priority: 1,
- metrics: [
- {
- id: 5,
- title: 'Memory usage',
- weight: 1,
- queries: [
- {
- query_range: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20',
- label: 'Memory',
- unit: 'MiB',
- result: [
- {
- metric: {},
- values: [
- [1495700554.925, '8.0390625'],
- [1495700614.925, '8.0390625'],
- [1495700674.925, '8.0390625'],
- [1495700734.925, '8.0390625'],
- [1495700794.925, '8.0390625'],
- [1495700854.925, '8.0390625'],
- [1495700914.925, '8.0390625'],
- [1495700974.925, '8.0390625'],
- [1495701034.925, '8.0390625'],
- [1495701094.925, '8.0390625'],
- [1495701154.925, '8.0390625'],
- [1495701214.925, '8.0390625'],
- [1495701274.925, '8.0390625'],
- [1495701334.925, '8.0390625'],
- [1495701394.925, '8.0390625'],
- [1495701454.925, '8.0390625'],
- [1495701514.925, '8.0390625'],
- [1495701574.925, '8.0390625'],
- [1495701634.925, '8.0390625'],
- [1495701694.925, '8.0390625'],
- [1495701754.925, '8.0390625'],
- [1495701814.925, '8.0390625'],
- [1495701874.925, '8.0390625'],
- [1495701934.925, '8.0390625'],
- [1495701994.925, '8.0390625'],
- [1495702054.925, '8.0390625'],
- [1495702114.925, '8.0390625'],
- [1495702174.925, '8.0390625'],
- [1495702234.925, '8.0390625'],
- [1495702294.925, '8.0390625'],
- [1495702354.925, '8.0390625'],
- [1495702414.925, '8.0390625'],
- [1495702474.925, '8.0390625'],
- [1495702534.925, '8.0390625'],
- [1495702594.925, '8.0390625'],
- [1495702654.925, '8.0390625'],
- [1495702714.925, '8.0390625'],
- [1495702774.925, '8.0390625'],
- [1495702834.925, '8.0390625'],
- [1495702894.925, '8.0390625'],
- [1495702954.925, '8.0390625'],
- [1495703014.925, '8.0390625'],
- [1495703074.925, '8.0390625'],
- [1495703134.925, '8.0390625'],
- [1495703194.925, '8.0390625'],
- [1495703254.925, '8.03515625'],
- [1495703314.925, '8.03515625'],
- [1495703374.925, '8.03515625'],
- [1495703434.925, '8.03515625'],
- [1495703494.925, '8.03515625'],
- [1495703554.925, '8.03515625'],
- [1495703614.925, '8.03515625'],
- [1495703674.925, '8.03515625'],
- [1495703734.925, '8.03515625'],
- [1495703794.925, '8.03515625'],
- [1495703854.925, '8.03515625'],
- [1495703914.925, '8.03515625'],
- [1495703974.925, '8.03515625'],
- [1495704034.925, '8.03515625'],
- [1495704094.925, '8.03515625'],
- [1495704154.925, '8.03515625'],
- [1495704214.925, '7.9296875'],
- [1495704274.925, '7.9296875'],
- [1495704334.925, '7.9296875'],
- [1495704394.925, '7.9296875'],
- [1495704454.925, '7.9296875'],
- [1495704514.925, '7.9296875'],
- [1495704574.925, '7.9296875'],
- [1495704634.925, '7.9296875'],
- [1495704694.925, '7.9296875'],
- [1495704754.925, '7.9296875'],
- [1495704814.925, '7.9296875'],
- [1495704874.925, '7.9296875'],
- [1495704934.925, '7.9296875'],
- [1495704994.925, '7.9296875'],
- [1495705054.925, '7.9296875'],
- [1495705114.925, '7.9296875'],
- [1495705174.925, '7.9296875'],
- [1495705234.925, '7.9296875'],
- [1495705294.925, '7.9296875'],
- [1495705354.925, '7.9296875'],
- [1495705414.925, '7.9296875'],
- [1495705474.925, '7.9296875'],
- [1495705534.925, '7.9296875'],
- [1495705594.925, '7.9296875'],
- [1495705654.925, '7.9296875'],
- [1495705714.925, '7.9296875'],
- [1495705774.925, '7.9296875'],
- [1495705834.925, '7.9296875'],
- [1495705894.925, '7.9296875'],
- [1495705954.925, '7.9296875'],
- [1495706014.925, '7.9296875'],
- [1495706074.925, '7.9296875'],
- [1495706134.925, '7.9296875'],
- [1495706194.925, '7.9296875'],
- [1495706254.925, '7.9296875'],
- [1495706314.925, '7.9296875'],
- [1495706374.925, '7.9296875'],
- [1495706434.925, '7.9296875'],
- [1495706494.925, '7.9296875'],
- [1495706554.925, '7.9296875'],
- [1495706614.925, '7.9296875'],
- [1495706674.925, '7.9296875'],
- [1495706734.925, '7.9296875'],
- [1495706794.925, '7.9296875'],
- [1495706854.925, '7.9296875'],
- [1495706914.925, '7.9296875'],
- [1495706974.925, '7.9296875'],
- [1495707034.925, '7.9296875'],
- [1495707094.925, '7.9296875'],
- [1495707154.925, '7.9296875'],
- [1495707214.925, '7.9296875'],
- [1495707274.925, '7.9296875'],
- [1495707334.925, '7.9296875'],
- [1495707394.925, '7.9296875'],
- [1495707454.925, '7.9296875'],
- [1495707514.925, '7.9296875'],
- [1495707574.925, '7.9296875'],
- [1495707634.925, '7.9296875'],
- [1495707694.925, '7.9296875'],
- [1495707754.925, '7.9296875'],
- [1495707814.925, '7.9296875'],
- [1495707874.925, '7.9296875'],
- [1495707934.925, '7.9296875'],
- [1495707994.925, '7.9296875'],
- [1495708054.925, '7.9296875'],
- [1495708114.925, '7.9296875'],
- [1495708174.925, '7.9296875'],
- [1495708234.925, '7.9296875'],
- [1495708294.925, '7.9296875'],
- [1495708354.925, '7.9296875'],
- [1495708414.925, '7.9296875'],
- [1495708474.925, '7.9296875'],
- [1495708534.925, '7.9296875'],
- [1495708594.925, '7.9296875'],
- [1495708654.925, '7.9296875'],
- [1495708714.925, '7.9296875'],
- [1495708774.925, '7.9296875'],
- [1495708834.925, '7.9296875'],
- [1495708894.925, '7.9296875'],
- [1495708954.925, '7.8984375'],
- [1495709014.925, '7.8984375'],
- [1495709074.925, '7.8984375'],
- [1495709134.925, '7.8984375'],
- [1495709194.925, '7.8984375'],
- [1495709254.925, '7.89453125'],
- [1495709314.925, '7.89453125'],
- [1495709374.925, '7.89453125'],
- [1495709434.925, '7.89453125'],
- [1495709494.925, '7.89453125'],
- [1495709554.925, '7.89453125'],
- [1495709614.925, '7.89453125'],
- [1495709674.925, '7.89453125'],
- [1495709734.925, '7.89453125'],
- [1495709794.925, '7.89453125'],
- [1495709854.925, '7.89453125'],
- [1495709914.925, '7.89453125'],
- [1495709974.925, '7.89453125'],
- [1495710034.925, '7.89453125'],
- [1495710094.925, '7.89453125'],
- [1495710154.925, '7.89453125'],
- [1495710214.925, '7.89453125'],
- [1495710274.925, '7.89453125'],
- [1495710334.925, '7.89453125'],
- [1495710394.925, '7.89453125'],
- [1495710454.925, '7.89453125'],
- [1495710514.925, '7.89453125'],
- [1495710574.925, '7.89453125'],
- [1495710634.925, '7.89453125'],
- [1495710694.925, '7.89453125'],
- [1495710754.925, '7.89453125'],
- [1495710814.925, '7.89453125'],
- [1495710874.925, '7.89453125'],
- [1495710934.925, '7.89453125'],
- [1495710994.925, '7.89453125'],
- [1495711054.925, '7.89453125'],
- [1495711114.925, '7.89453125'],
- [1495711174.925, '7.8515625'],
- [1495711234.925, '7.8515625'],
- [1495711294.925, '7.8515625'],
- [1495711354.925, '7.8515625'],
- [1495711414.925, '7.8515625'],
- [1495711474.925, '7.8515625'],
- [1495711534.925, '7.8515625'],
- [1495711594.925, '7.8515625'],
- [1495711654.925, '7.8515625'],
- [1495711714.925, '7.8515625'],
- [1495711774.925, '7.8515625'],
- [1495711834.925, '7.8515625'],
- [1495711894.925, '7.8515625'],
- [1495711954.925, '7.8515625'],
- [1495712014.925, '7.8515625'],
- [1495712074.925, '7.8515625'],
- [1495712134.925, '7.8515625'],
- [1495712194.925, '7.8515625'],
- [1495712254.925, '7.8515625'],
- [1495712314.925, '7.8515625'],
- [1495712374.925, '7.8515625'],
- [1495712434.925, '7.83203125'],
- [1495712494.925, '7.83203125'],
- [1495712554.925, '7.83203125'],
- [1495712614.925, '7.83203125'],
- [1495712674.925, '7.83203125'],
- [1495712734.925, '7.83203125'],
- [1495712794.925, '7.83203125'],
- [1495712854.925, '7.83203125'],
- [1495712914.925, '7.83203125'],
- [1495712974.925, '7.83203125'],
- [1495713034.925, '7.83203125'],
- [1495713094.925, '7.83203125'],
- [1495713154.925, '7.83203125'],
- [1495713214.925, '7.83203125'],
- [1495713274.925, '7.83203125'],
- [1495713334.925, '7.83203125'],
- [1495713394.925, '7.8125'],
- [1495713454.925, '7.8125'],
- [1495713514.925, '7.8125'],
- [1495713574.925, '7.8125'],
- [1495713634.925, '7.8125'],
- [1495713694.925, '7.8125'],
- [1495713754.925, '7.8125'],
- [1495713814.925, '7.8125'],
- [1495713874.925, '7.8125'],
- [1495713934.925, '7.8125'],
- [1495713994.925, '7.8125'],
- [1495714054.925, '7.8125'],
- [1495714114.925, '7.8125'],
- [1495714174.925, '7.8125'],
- [1495714234.925, '7.8125'],
- [1495714294.925, '7.8125'],
- [1495714354.925, '7.80859375'],
- [1495714414.925, '7.80859375'],
- [1495714474.925, '7.80859375'],
- [1495714534.925, '7.80859375'],
- [1495714594.925, '7.80859375'],
- [1495714654.925, '7.80859375'],
- [1495714714.925, '7.80859375'],
- [1495714774.925, '7.80859375'],
- [1495714834.925, '7.80859375'],
- [1495714894.925, '7.80859375'],
- [1495714954.925, '7.80859375'],
- [1495715014.925, '7.80859375'],
- [1495715074.925, '7.80859375'],
- [1495715134.925, '7.80859375'],
- [1495715194.925, '7.80859375'],
- [1495715254.925, '7.80859375'],
- [1495715314.925, '7.80859375'],
- [1495715374.925, '7.80859375'],
- [1495715434.925, '7.80859375'],
- [1495715494.925, '7.80859375'],
- [1495715554.925, '7.80859375'],
- [1495715614.925, '7.80859375'],
- [1495715674.925, '7.80859375'],
- [1495715734.925, '7.80859375'],
- [1495715794.925, '7.80859375'],
- [1495715854.925, '7.80859375'],
- [1495715914.925, '7.80078125'],
- [1495715974.925, '7.80078125'],
- [1495716034.925, '7.80078125'],
- [1495716094.925, '7.80078125'],
- [1495716154.925, '7.80078125'],
- [1495716214.925, '7.796875'],
- [1495716274.925, '7.796875'],
- [1495716334.925, '7.796875'],
- [1495716394.925, '7.796875'],
- [1495716454.925, '7.796875'],
- [1495716514.925, '7.796875'],
- [1495716574.925, '7.796875'],
- [1495716634.925, '7.796875'],
- [1495716694.925, '7.796875'],
- [1495716754.925, '7.796875'],
- [1495716814.925, '7.796875'],
- [1495716874.925, '7.79296875'],
- [1495716934.925, '7.79296875'],
- [1495716994.925, '7.79296875'],
- [1495717054.925, '7.79296875'],
- [1495717114.925, '7.79296875'],
- [1495717174.925, '7.7890625'],
- [1495717234.925, '7.7890625'],
- [1495717294.925, '7.7890625'],
- [1495717354.925, '7.7890625'],
- [1495717414.925, '7.7890625'],
- [1495717474.925, '7.7890625'],
- [1495717534.925, '7.7890625'],
- [1495717594.925, '7.7890625'],
- [1495717654.925, '7.7890625'],
- [1495717714.925, '7.7890625'],
- [1495717774.925, '7.7890625'],
- [1495717834.925, '7.77734375'],
- [1495717894.925, '7.77734375'],
- [1495717954.925, '7.77734375'],
- [1495718014.925, '7.77734375'],
- [1495718074.925, '7.77734375'],
- [1495718134.925, '7.7421875'],
- [1495718194.925, '7.7421875'],
- [1495718254.925, '7.7421875'],
- [1495718314.925, '7.7421875'],
- ],
- },
- ],
- },
- ],
- },
- {
- id: 6,
- title: 'CPU usage',
- y_label: 'CPU',
- weight: 1,
- queries: [
- {
- appearance: {
- line: {
- width: 2,
- },
- },
- query_range:
- 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100',
- label: 'Core Usage',
- unit: 'Cores',
- result: [
- {
- metric: {},
- values: [
- [1495700554.925, '0.0010794445585559514'],
- [1495700614.925, '0.003927214935433527'],
- [1495700674.925, '0.0053045219047619975'],
- [1495700734.925, '0.0048892095238097155'],
- [1495700794.925, '0.005827140952381137'],
- [1495700854.925, '0.00569846906219937'],
- [1495700914.925, '0.004972616802849382'],
- [1495700974.925, '0.005117509523809902'],
- [1495701034.925, '0.00512389061919564'],
- [1495701094.925, '0.005199100501890691'],
- [1495701154.925, '0.005415746394885837'],
- [1495701214.925, '0.005607682788146286'],
- [1495701274.925, '0.005641300000000118'],
- [1495701334.925, '0.0071166279368766495'],
- [1495701394.925, '0.0063242138095234044'],
- [1495701454.925, '0.005793314698235304'],
- [1495701514.925, '0.00703934942237556'],
- [1495701574.925, '0.006357007076123191'],
- [1495701634.925, '0.003753167300126738'],
- [1495701694.925, '0.005018469678430698'],
- [1495701754.925, '0.0045217153371887'],
- [1495701814.925, '0.006140104285714119'],
- [1495701874.925, '0.004818684285714102'],
- [1495701934.925, '0.005079509718955242'],
- [1495701994.925, '0.005059981142498263'],
- [1495702054.925, '0.005269098389538773'],
- [1495702114.925, '0.005269954285714175'],
- [1495702174.925, '0.014199241435795856'],
- [1495702234.925, '0.01511936843111017'],
- [1495702294.925, '0.0060933692920682875'],
- [1495702354.925, '0.004945682380952493'],
- [1495702414.925, '0.005641266666666565'],
- [1495702474.925, '0.005223752857142996'],
- [1495702534.925, '0.005743098505699831'],
- [1495702594.925, '0.00538493380952391'],
- [1495702654.925, '0.005507793883751339'],
- [1495702714.925, '0.005666705714285466'],
- [1495702774.925, '0.006231530000000112'],
- [1495702834.925, '0.006570768635394899'],
- [1495702894.925, '0.005551146666666895'],
- [1495702954.925, '0.005602604737098058'],
- [1495703014.925, '0.00613993580402159'],
- [1495703074.925, '0.004770258764368832'],
- [1495703134.925, '0.005512376671364914'],
- [1495703194.925, '0.005254436666666674'],
- [1495703254.925, '0.0050109839141320505'],
- [1495703314.925, '0.0049478019256960016'],
- [1495703374.925, '0.0037666860965123463'],
- [1495703434.925, '0.004813526061656314'],
- [1495703494.925, '0.005047748095238278'],
- [1495703554.925, '0.00386494081008772'],
- [1495703614.925, '0.004304037408111405'],
- [1495703674.925, '0.004999466661587168'],
- [1495703734.925, '0.004689140476190834'],
- [1495703794.925, '0.004746126153582475'],
- [1495703854.925, '0.004482706382572302'],
- [1495703914.925, '0.004032808931864524'],
- [1495703974.925, '0.005728319047618988'],
- [1495704034.925, '0.004436139179627006'],
- [1495704094.925, '0.004553455714285617'],
- [1495704154.925, '0.003455244285714341'],
- [1495704214.925, '0.004742244761904621'],
- [1495704274.925, '0.005366978571428422'],
- [1495704334.925, '0.004257954837665058'],
- [1495704394.925, '0.005431603259831257'],
- [1495704454.925, '0.0052009214498621986'],
- [1495704514.925, '0.004317201904761618'],
- [1495704574.925, '0.004307384285714157'],
- [1495704634.925, '0.004789801146644822'],
- [1495704694.925, '0.0051429795906706485'],
- [1495704754.925, '0.005322495714285479'],
- [1495704814.925, '0.004512809333244233'],
- [1495704874.925, '0.004953843582568726'],
- [1495704934.925, '0.005812690120858119'],
- [1495704994.925, '0.004997024285714838'],
- [1495705054.925, '0.005246216154439592'],
- [1495705114.925, '0.0063494966618726795'],
- [1495705174.925, '0.005306004342898225'],
- [1495705234.925, '0.005081412857142978'],
- [1495705294.925, '0.00511409523809522'],
- [1495705354.925, '0.0047861001481192'],
- [1495705414.925, '0.005107688228042962'],
- [1495705474.925, '0.005271929582294012'],
- [1495705534.925, '0.004453254502681249'],
- [1495705594.925, '0.005799134293959226'],
- [1495705654.925, '0.005340865929502478'],
- [1495705714.925, '0.004911654761904942'],
- [1495705774.925, '0.005888234873953261'],
- [1495705834.925, '0.005565283333332954'],
- [1495705894.925, '0.005522869047618869'],
- [1495705954.925, '0.005177549737621646'],
- [1495706014.925, '0.0053145810232096465'],
- [1495706074.925, '0.004751095238095275'],
- [1495706134.925, '0.006242077142856976'],
- [1495706194.925, '0.00621034406957871'],
- [1495706254.925, '0.006887592738978596'],
- [1495706314.925, '0.006328128779726213'],
- [1495706374.925, '0.007488363809523927'],
- [1495706434.925, '0.006193758571428157'],
- [1495706494.925, '0.0068798371839706935'],
- [1495706554.925, '0.005757034340423128'],
- [1495706614.925, '0.004571388497294698'],
- [1495706674.925, '0.00620283044923395'],
- [1495706734.925, '0.005607562380952455'],
- [1495706794.925, '0.005506969933620308'],
- [1495706854.925, '0.005621118095238131'],
- [1495706914.925, '0.004876606098698849'],
- [1495706974.925, '0.0047871205988517206'],
- [1495707034.925, '0.00526405939458784'],
- [1495707094.925, '0.005716323800605852'],
- [1495707154.925, '0.005301459523809575'],
- [1495707214.925, '0.0051613042857144905'],
- [1495707274.925, '0.005384792857142714'],
- [1495707334.925, '0.005259719047619222'],
- [1495707394.925, '0.00584101142857182'],
- [1495707454.925, '0.0060066121920326326'],
- [1495707514.925, '0.006359978571428453'],
- [1495707574.925, '0.006315876322151109'],
- [1495707634.925, '0.005590012517198831'],
- [1495707694.925, '0.005517419877137072'],
- [1495707754.925, '0.006089813430348506'],
- [1495707814.925, '0.00466754476190479'],
- [1495707874.925, '0.006059954380517721'],
- [1495707934.925, '0.005085657142856972'],
- [1495707994.925, '0.005897665238095296'],
- [1495708054.925, '0.0062282023199555885'],
- [1495708114.925, '0.00526214553236979'],
- [1495708174.925, '0.0044803300000000644'],
- [1495708234.925, '0.005421443333333592'],
- [1495708294.925, '0.005694326244512144'],
- [1495708354.925, '0.005527721904761457'],
- [1495708414.925, '0.005988819523809819'],
- [1495708474.925, '0.005484704285714448'],
- [1495708534.925, '0.005041123649230085'],
- [1495708594.925, '0.005717767639612059'],
- [1495708654.925, '0.005412954417342863'],
- [1495708714.925, '0.005833343333333254'],
- [1495708774.925, '0.005448135238094969'],
- [1495708834.925, '0.005117341428571432'],
- [1495708894.925, '0.005888345825277833'],
- [1495708954.925, '0.005398543809524135'],
- [1495709014.925, '0.005325611428571416'],
- [1495709074.925, '0.005848668571428527'],
- [1495709134.925, '0.005135003105145044'],
- [1495709194.925, '0.0054551400000003'],
- [1495709254.925, '0.005319472937322171'],
- [1495709314.925, '0.00585677857142792'],
- [1495709374.925, '0.0062146261904759215'],
- [1495709434.925, '0.0067105060904182265'],
- [1495709494.925, '0.005829691904762108'],
- [1495709554.925, '0.005719280952381261'],
- [1495709614.925, '0.005682603793416407'],
- [1495709674.925, '0.0055272846277326934'],
- [1495709734.925, '0.0057123680952386735'],
- [1495709794.925, '0.00520597958075818'],
- [1495709854.925, '0.005584358957263837'],
- [1495709914.925, '0.005601104275197466'],
- [1495709974.925, '0.005991657142857066'],
- [1495710034.925, '0.00553722238095218'],
- [1495710094.925, '0.005127883122696293'],
- [1495710154.925, '0.005498111927534584'],
- [1495710214.925, '0.005609934069084202'],
- [1495710274.925, '0.00459206285714307'],
- [1495710334.925, '0.0047910828571428084'],
- [1495710394.925, '0.0056014671288845685'],
- [1495710454.925, '0.005686936791078528'],
- [1495710514.925, '0.00444480476190448'],
- [1495710574.925, '0.005780394696738921'],
- [1495710634.925, '0.0053107227550210365'],
- [1495710694.925, '0.005096031495761817'],
- [1495710754.925, '0.005451377979091524'],
- [1495710814.925, '0.005328136666667083'],
- [1495710874.925, '0.006020612857143043'],
- [1495710934.925, '0.0061063585714285365'],
- [1495710994.925, '0.006018346015752312'],
- [1495711054.925, '0.005069130952381193'],
- [1495711114.925, '0.005458406190476052'],
- [1495711174.925, '0.00577219190476179'],
- [1495711234.925, '0.005760814645658314'],
- [1495711294.925, '0.005371875716579101'],
- [1495711354.925, '0.0064232666666665834'],
- [1495711414.925, '0.009369806836906667'],
- [1495711474.925, '0.008956864761904692'],
- [1495711534.925, '0.005266849368559271'],
- [1495711594.925, '0.005335111364934262'],
- [1495711654.925, '0.006461778319586945'],
- [1495711714.925, '0.004687939890762393'],
- [1495711774.925, '0.004438831245760684'],
- [1495711834.925, '0.005142786666666613'],
- [1495711894.925, '0.007257734212054963'],
- [1495711954.925, '0.005621991904761494'],
- [1495712014.925, '0.007868689999999862'],
- [1495712074.925, '0.00910970215275738'],
- [1495712134.925, '0.006151004285714278'],
- [1495712194.925, '0.005447120924961522'],
- [1495712254.925, '0.005150705153929503'],
- [1495712314.925, '0.006358108714969314'],
- [1495712374.925, '0.0057725354795696475'],
- [1495712434.925, '0.005232139047619015'],
- [1495712494.925, '0.004932809617949037'],
- [1495712554.925, '0.004511607508499662'],
- [1495712614.925, '0.00440487701522666'],
- [1495712674.925, '0.005479113333333174'],
- [1495712734.925, '0.004726317619047547'],
- [1495712794.925, '0.005582041102958029'],
- [1495712854.925, '0.006381481216082099'],
- [1495712914.925, '0.005474260014095208'],
- [1495712974.925, '0.00567597142857188'],
- [1495713034.925, '0.0064741233333332985'],
- [1495713094.925, '0.005467475714285271'],
- [1495713154.925, '0.004868648393824457'],
- [1495713214.925, '0.005254923286444893'],
- [1495713274.925, '0.005599217150312865'],
- [1495713334.925, '0.005105413720618919'],
- [1495713394.925, '0.007246073333333279'],
- [1495713454.925, '0.005990312380952272'],
- [1495713514.925, '0.005594601853351101'],
- [1495713574.925, '0.004739258673727054'],
- [1495713634.925, '0.003932121428571783'],
- [1495713694.925, '0.005018188268459395'],
- [1495713754.925, '0.004538238095237985'],
- [1495713814.925, '0.00561816643265435'],
- [1495713874.925, '0.0063132584495033586'],
- [1495713934.925, '0.00442385238095213'],
- [1495713994.925, '0.004181795887658453'],
- [1495714054.925, '0.004437759047619037'],
- [1495714114.925, '0.006421748157178241'],
- [1495714174.925, '0.006525143809523842'],
- [1495714234.925, '0.004715904935144247'],
- [1495714294.925, '0.005966040152763461'],
- [1495714354.925, '0.005614535466921674'],
- [1495714414.925, '0.004934375119415906'],
- [1495714474.925, '0.0054122933333327385'],
- [1495714534.925, '0.004926540699612279'],
- [1495714594.925, '0.006124649517134237'],
- [1495714654.925, '0.004629427092013995'],
- [1495714714.925, '0.005117951257607005'],
- [1495714774.925, '0.004868774512685422'],
- [1495714834.925, '0.005310093333333399'],
- [1495714894.925, '0.0054907752286127345'],
- [1495714954.925, '0.004597678117351089'],
- [1495715014.925, '0.0059622552380952'],
- [1495715074.925, '0.005352457072655368'],
- [1495715134.925, '0.005491630952381143'],
- [1495715194.925, '0.006391770078379791'],
- [1495715254.925, '0.005933472857142518'],
- [1495715314.925, '0.005301314285714163'],
- [1495715374.925, '0.0058352959724814165'],
- [1495715434.925, '0.006154755147867044'],
- [1495715494.925, '0.009391935637482038'],
- [1495715554.925, '0.007846462857142592'],
- [1495715614.925, '0.00477608215316353'],
- [1495715674.925, '0.006132865238094998'],
- [1495715734.925, '0.006159762457649516'],
- [1495715794.925, '0.005957307073265968'],
- [1495715854.925, '0.006652319091792501'],
- [1495715914.925, '0.005493557402895287'],
- [1495715974.925, '0.0058652434829145166'],
- [1495716034.925, '0.005627400430468021'],
- [1495716094.925, '0.006240656190475609'],
- [1495716154.925, '0.006305997676168624'],
- [1495716214.925, '0.005388057732783248'],
- [1495716274.925, '0.0052814916048421244'],
- [1495716334.925, '0.00699498614272497'],
- [1495716394.925, '0.00627768693035141'],
- [1495716454.925, '0.0042411487048161145'],
- [1495716514.925, '0.005348647473627653'],
- [1495716574.925, '0.0047176657142853975'],
- [1495716634.925, '0.004437898571428686'],
- [1495716694.925, '0.004923527366927261'],
- [1495716754.925, '0.005131935066048421'],
- [1495716814.925, '0.005046949523809611'],
- [1495716874.925, '0.00547184095238092'],
- [1495716934.925, '0.005224140016380444'],
- [1495716994.925, '0.005297991171665292'],
- [1495717054.925, '0.005492965995623498'],
- [1495717114.925, '0.005754660000000403'],
- [1495717174.925, '0.005949557138639285'],
- [1495717234.925, '0.006091816112534666'],
- [1495717294.925, '0.005554210080192063'],
- [1495717354.925, '0.006411504395279871'],
- [1495717414.925, '0.006319643996609606'],
- [1495717474.925, '0.005539174405717675'],
- [1495717534.925, '0.0053157078842772255'],
- [1495717594.925, '0.005247480952381066'],
- [1495717654.925, '0.004820141620396252'],
- [1495717714.925, '0.005906173868322844'],
- [1495717774.925, '0.006173117219570961'],
- [1495717834.925, '0.005963340952380661'],
- [1495717894.925, '0.005698976627681527'],
- [1495717954.925, '0.004751279096346378'],
- [1495718014.925, '0.005733142379359711'],
- [1495718074.925, '0.004831689010348035'],
- [1495718134.925, '0.005188370476191092'],
- [1495718194.925, '0.004793227554547938'],
- [1495718254.925, '0.003997442857142731'],
- [1495718314.925, '0.004386040132951264'],
- ],
- },
- ],
- },
- ],
- },
- ],
- },
+export const mockApiEndpoint = `${gl.TEST_HOST}/monitoring/mock`;
+
+export const mockedQueryResultPayload = {
+ metricId: '17_system_metrics_kubernetes_container_memory_average',
+ result: [
{
- group: 'NGINX',
- priority: 2,
- metrics: [
- {
- id: 100,
- title: 'Http Error Rate',
- weight: 100,
- queries: [
- {
- query_range:
- 'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"nginx-test-8691397-production-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"nginx-test-8691397-production-.*"}[2m])) * 100',
- label: '5xx errors',
- unit: '%',
- result: [
- {
- metric: {},
- values: [
- [1495700554.925, NaN],
- [1495700614.925, NaN],
- [1495700674.925, NaN],
- [1495700734.925, NaN],
- [1495700794.925, NaN],
- [1495700854.925, NaN],
- [1495700914.925, NaN],
- ],
- },
- ],
- },
- ],
- },
+ metric: {},
+ values: [
+ [1563272065.589, '10.396484375'],
+ [1563272125.589, '10.333984375'],
+ [1563272185.589, '10.333984375'],
+ [1563272245.589, '10.333984375'],
+ [1563272305.589, '10.333984375'],
+ [1563272365.589, '10.333984375'],
+ [1563272425.589, '10.38671875'],
+ [1563272485.589, '10.333984375'],
+ [1563272545.589, '10.333984375'],
+ [1563272605.589, '10.333984375'],
+ [1563272665.589, '10.333984375'],
+ [1563272725.589, '10.333984375'],
+ [1563272785.589, '10.396484375'],
+ [1563272845.589, '10.333984375'],
+ [1563272905.589, '10.333984375'],
+ [1563272965.589, '10.3984375'],
+ [1563273025.589, '10.337890625'],
+ [1563273085.589, '10.34765625'],
+ [1563273145.589, '10.337890625'],
+ [1563273205.589, '10.337890625'],
+ [1563273265.589, '10.337890625'],
+ [1563273325.589, '10.337890625'],
+ [1563273385.589, '10.337890625'],
+ [1563273445.589, '10.337890625'],
+ [1563273505.589, '10.337890625'],
+ [1563273565.589, '10.337890625'],
+ [1563273625.589, '10.337890625'],
+ [1563273685.589, '10.337890625'],
+ [1563273745.589, '10.337890625'],
+ [1563273805.589, '10.337890625'],
+ [1563273865.589, '10.390625'],
+ [1563273925.589, '10.390625'],
],
},
],
- last_update: '2017-05-25T13:18:34.949Z',
};
-export const singleGroupResponse = [
- {
- group: 'System metrics (Kubernetes)',
- priority: 5,
- metrics: [
- {
- title: 'Memory Usage (Total)',
- weight: 0,
- y_label: 'Total Memory Used',
- queries: [
- {
- query_range:
- 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^production-(.*)",namespace="autodevops-deploy-33"}) by (job)) without (job) /1024/1024/1024',
- unit: 'GB',
- label: 'Total',
- result: [
- {
- metric: {},
- values: [
- [1558453960.079, '0.0357666015625'],
- [1558454020.079, '0.035675048828125'],
- [1558454080.079, '0.035152435302734375'],
- [1558454140.079, '0.035221099853515625'],
- [1558454200.079, '0.0352325439453125'],
- [1558454260.079, '0.03479766845703125'],
- [1558454320.079, '0.034793853759765625'],
- [1558454380.079, '0.034931182861328125'],
- [1558454440.079, '0.034816741943359375'],
- [1558454500.079, '0.034816741943359375'],
- [1558454560.079, '0.034816741943359375'],
- ],
- },
- ],
- },
- ],
- id: 15,
- },
- ],
- },
-];
-
-export default metricsGroupsAPIResponse;
-
-export const deploymentData = [
- {
- id: 111,
- iid: 3,
- sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- commitUrl:
- 'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- ref: {
- name: 'master',
- },
- created_at: '2017-05-31T21:23:37.881Z',
- tag: false,
- tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
- 'last?': true,
- },
- {
- id: 110,
- iid: 2,
- sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- commitUrl:
- 'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- ref: {
- name: 'master',
- },
- created_at: '2017-05-30T20:08:04.629Z',
- tag: false,
- tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
- 'last?': false,
- },
- {
- id: 109,
- iid: 1,
- sha: '6511e58faafaa7ad2228990ec57f19d66f7db7c2',
- commitUrl:
- 'http://test.host/frontend-fixtures/environments-project/commit/6511e58faafaa7ad2228990ec57f19d66f7db7c2',
- ref: {
- name: 'update2-readme',
- },
- created_at: '2017-05-30T17:42:38.409Z',
- tag: false,
- tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
- 'last?': false,
- },
-];
-
-export const statePaths = {
- settingsPath: '/root/hello-prometheus/services/prometheus/edit',
- clustersPath: '/root/hello-prometheus/clusters',
- documentationPath: '/help/administration/monitoring/prometheus/index.md',
-};
-
-export const queryWithoutData = {
- title: 'HTTP Error rate',
- weight: 10,
- y_label: 'Http Error Rate',
- queries: [
+export const mockedQueryResultPayloadCoresTotal = {
+ metricId: '13_system_metrics_kubernetes_container_cores_total',
+ result: [
{
- query_range:
- 'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"nginx-test-8691397-production-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"nginx-test-8691397-production-.*"}[2m])) * 100',
- label: '5xx errors',
- unit: '%',
- result: [],
+ metric: {},
+ values: [
+ [1563272065.589, '9.396484375'],
+ [1563272125.589, '9.333984375'],
+ [1563272185.589, '9.333984375'],
+ [1563272245.589, '9.333984375'],
+ [1563272305.589, '9.333984375'],
+ [1563272365.589, '9.333984375'],
+ [1563272425.589, '9.38671875'],
+ [1563272485.589, '9.333984375'],
+ [1563272545.589, '9.333984375'],
+ [1563272605.589, '9.333984375'],
+ [1563272665.589, '9.333984375'],
+ [1563272725.589, '9.333984375'],
+ [1563272785.589, '9.396484375'],
+ [1563272845.589, '9.333984375'],
+ [1563272905.589, '9.333984375'],
+ [1563272965.589, '9.3984375'],
+ [1563273025.589, '9.337890625'],
+ [1563273085.589, '9.34765625'],
+ [1563273145.589, '9.337890625'],
+ [1563273205.589, '9.337890625'],
+ [1563273265.589, '9.337890625'],
+ [1563273325.589, '9.337890625'],
+ [1563273385.589, '9.337890625'],
+ [1563273445.589, '9.337890625'],
+ [1563273505.589, '9.337890625'],
+ [1563273565.589, '9.337890625'],
+ [1563273625.589, '9.337890625'],
+ [1563273685.589, '9.337890625'],
+ [1563273745.589, '9.337890625'],
+ [1563273805.589, '9.337890625'],
+ [1563273865.589, '9.390625'],
+ [1563273925.589, '9.390625'],
+ ],
},
],
};
-export function convertDatesMultipleSeries(multipleSeries) {
- const convertedMultiple = multipleSeries;
- multipleSeries.forEach((column, index) => {
- let convertedResult = [];
- convertedResult = column.queries[0].result.map(resultObj => {
- const convertedMetrics = {};
- convertedMetrics.values = resultObj.values.map(val => ({
- time: new Date(val.time),
- value: val.value,
- }));
- convertedMetrics.metric = resultObj.metric;
- return convertedMetrics;
- });
- convertedMultiple[index].queries[0].result = convertedResult;
- });
- return convertedMultiple;
-}
-
-export const environmentData = [
- {
- id: 34,
- name: 'production',
- state: 'available',
- external_url: 'http://root-autodevops-deploy.my-fake-domain.com',
- environment_type: null,
- stop_action: false,
- metrics_path: '/root/hello-prometheus/environments/34/metrics',
- environment_path: '/root/hello-prometheus/environments/34',
- stop_path: '/root/hello-prometheus/environments/34/stop',
- terminal_path: '/root/hello-prometheus/environments/34/terminal',
- folder_path: '/root/hello-prometheus/environments/folders/production',
- created_at: '2018-06-29T16:53:38.301Z',
- updated_at: '2018-06-29T16:57:09.825Z',
- last_deployment: {
- id: 127,
- },
- },
- {
- id: 35,
- name: 'review/noop-branch',
- state: 'available',
- external_url: 'http://root-autodevops-deploy-review-noop-branc-die93w.my-fake-domain.com',
- environment_type: 'review',
- stop_action: true,
- metrics_path: '/root/hello-prometheus/environments/35/metrics',
- environment_path: '/root/hello-prometheus/environments/35',
- stop_path: '/root/hello-prometheus/environments/35/stop',
- terminal_path: '/root/hello-prometheus/environments/35/terminal',
- folder_path: '/root/hello-prometheus/environments/folders/review',
- created_at: '2018-07-03T18:39:41.702Z',
- updated_at: '2018-07-03T18:44:54.010Z',
- last_deployment: {
- id: 128,
- },
- },
- {
- id: 36,
- name: 'no-deployment/noop-branch',
- state: 'available',
- created_at: '2018-07-04T18:39:41.702Z',
- updated_at: '2018-07-04T18:44:54.010Z',
- },
-];
-
-export const metricsDashboardResponse = {
- dashboard: {
- dashboard: 'Environment metrics',
- priority: 1,
- panel_groups: [
- {
- group: 'System metrics (Kubernetes)',
- priority: 5,
- panels: [
- {
- title: 'Memory Usage (Total)',
- type: 'area-chart',
- y_label: 'Total Memory Used',
- weight: 4,
- metrics: [
- {
- id: 'system_metrics_kubernetes_container_memory_total',
- query_range:
- 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024',
- label: 'Total',
- unit: 'GB',
- metric_id: 12,
- prometheus_endpoint_path: 'http://test',
- },
- ],
- },
- {
- title: 'Core Usage (Total)',
- type: 'area-chart',
- y_label: 'Total Cores',
- weight: 3,
- metrics: [
- {
- id: 'system_metrics_kubernetes_container_cores_total',
- query_range:
- 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)',
- label: 'Total',
- unit: 'cores',
- metric_id: 13,
- },
- ],
- },
- {
- title: 'Memory Usage (Pod average)',
- type: 'line-chart',
- y_label: 'Memory Used per Pod',
- weight: 2,
- metrics: [
- {
- id: 'system_metrics_kubernetes_container_memory_average',
- query_range:
- 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024',
- label: 'Pod average',
- unit: 'MB',
- metric_id: 14,
- },
- ],
- },
- ],
- },
- ],
- },
- status: 'success',
-};
-
-export const dashboardGitResponse = [
- {
- path: 'config/prometheus/common_metrics.yml',
- display_name: 'Common Metrics',
- default: true,
- },
- {
- path: '.gitlab/dashboards/super.yml',
- display_name: 'Custom Dashboard 1',
- default: false,
- },
-];
-
export const graphDataPrometheusQuery = {
title: 'Super Chart A2',
type: 'single-stat',
@@ -975,7 +135,7 @@ export const graphDataPrometheusQuery = {
export const graphDataPrometheusQueryRange = {
title: 'Super Chart A1',
- type: 'area',
+ type: 'area-chart',
weight: 2,
metrics: [
{
@@ -991,7 +151,7 @@ export const graphDataPrometheusQueryRange = {
],
queries: [
{
- metricId: null,
+ metricId: '10',
id: 'metric_a1',
metric_id: 2,
query_range:
@@ -1009,3 +169,82 @@ export const graphDataPrometheusQueryRange = {
},
],
};
+
+export const graphDataPrometheusQueryRangeMultiTrack = {
+ title: 'Super Chart A3',
+ type: 'heatmap',
+ weight: 3,
+ x_label: 'Status Code',
+ y_label: 'Time',
+ metrics: [],
+ queries: [
+ {
+ metricId: '1',
+ id: 'response_metrics_nginx_ingress_throughput_status_code',
+ query_range:
+ 'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[60m])) by (status_code)',
+ unit: 'req / sec',
+ label: 'Status Code',
+ metric_id: 1,
+ prometheus_endpoint_path:
+ '/root/rails_nodb/environments/3/prometheus/api/v1/query_range?query=sum%28rate%28nginx_upstream_responses_total%7Bupstream%3D~%22%25%7Bkube_namespace%7D-%25%7Bci_environment_slug%7D-.%2A%22%7D%5B2m%5D%29%29+by+%28status_code%29',
+ result: [
+ {
+ metric: { status_code: '1xx' },
+ values: [
+ ['2019-08-30T15:00:00.000Z', 0],
+ ['2019-08-30T16:00:00.000Z', 2],
+ ['2019-08-30T17:00:00.000Z', 0],
+ ['2019-08-30T18:00:00.000Z', 0],
+ ['2019-08-30T19:00:00.000Z', 0],
+ ['2019-08-30T20:00:00.000Z', 3],
+ ],
+ },
+ {
+ metric: { status_code: '2xx' },
+ values: [
+ ['2019-08-30T15:00:00.000Z', 1],
+ ['2019-08-30T16:00:00.000Z', 3],
+ ['2019-08-30T17:00:00.000Z', 6],
+ ['2019-08-30T18:00:00.000Z', 10],
+ ['2019-08-30T19:00:00.000Z', 8],
+ ['2019-08-30T20:00:00.000Z', 6],
+ ],
+ },
+ {
+ metric: { status_code: '3xx' },
+ values: [
+ ['2019-08-30T15:00:00.000Z', 1],
+ ['2019-08-30T16:00:00.000Z', 2],
+ ['2019-08-30T17:00:00.000Z', 3],
+ ['2019-08-30T18:00:00.000Z', 3],
+ ['2019-08-30T19:00:00.000Z', 2],
+ ['2019-08-30T20:00:00.000Z', 1],
+ ],
+ },
+ {
+ metric: { status_code: '4xx' },
+ values: [
+ ['2019-08-30T15:00:00.000Z', 2],
+ ['2019-08-30T16:00:00.000Z', 0],
+ ['2019-08-30T17:00:00.000Z', 0],
+ ['2019-08-30T18:00:00.000Z', 2],
+ ['2019-08-30T19:00:00.000Z', 0],
+ ['2019-08-30T20:00:00.000Z', 2],
+ ],
+ },
+ {
+ metric: { status_code: '5xx' },
+ values: [
+ ['2019-08-30T15:00:00.000Z', 0],
+ ['2019-08-30T16:00:00.000Z', 1],
+ ['2019-08-30T17:00:00.000Z', 0],
+ ['2019-08-30T18:00:00.000Z', 0],
+ ['2019-08-30T19:00:00.000Z', 0],
+ ['2019-08-30T20:00:00.000Z', 2],
+ ],
+ },
+ ],
+ },
+ ],
+};
diff --git a/spec/javascripts/monitoring/panel_type_spec.js b/spec/javascripts/monitoring/panel_type_spec.js
deleted file mode 100644
index a2366e74d43..00000000000
--- a/spec/javascripts/monitoring/panel_type_spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import PanelType from '~/monitoring/components/panel_type.vue';
-import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
-import TimeSeriesChart from '~/monitoring/components/charts/time_series.vue';
-import { graphDataPrometheusQueryRange } from './mock_data';
-import { createStore } from '~/monitoring/stores';
-
-describe('Panel Type component', () => {
- let store;
- let panelType;
- const dashboardWidth = 100;
-
- describe('When no graphData is available', () => {
- let glEmptyChart;
- // Deep clone object before modifying
- const graphDataNoResult = JSON.parse(JSON.stringify(graphDataPrometheusQueryRange));
- graphDataNoResult.queries[0].result = [];
-
- beforeEach(() => {
- panelType = shallowMount(PanelType, {
- propsData: {
- clipboardText: 'dashboard_link',
- dashboardWidth,
- graphData: graphDataNoResult,
- },
- });
- });
-
- afterEach(() => {
- panelType.destroy();
- });
-
- describe('Empty Chart component', () => {
- beforeEach(() => {
- glEmptyChart = panelType.find(EmptyChart);
- });
-
- it('is a Vue instance', () => {
- expect(glEmptyChart.isVueInstance()).toBe(true);
- });
-
- it('it receives a graph title', () => {
- const props = glEmptyChart.props();
-
- expect(props.graphTitle).toBe(panelType.vm.graphData.title);
- });
- });
- });
-
- describe('when Graph data is available', () => {
- const exampleText = 'example_text';
-
- beforeEach(() => {
- store = createStore();
- panelType = shallowMount(PanelType, {
- propsData: {
- clipboardText: exampleText,
- dashboardWidth,
- graphData: graphDataPrometheusQueryRange,
- },
- store,
- });
- });
-
- describe('Time Series Chart panel type', () => {
- it('is rendered', () => {
- expect(panelType.find(TimeSeriesChart).isVueInstance()).toBe(true);
- expect(panelType.find(TimeSeriesChart).exists()).toBe(true);
- });
-
- it('sets clipboard text on the dropdown', () => {
- const link = () => panelType.find('.js-chart-link');
- const clipboardText = () => link().element.dataset.clipboardText;
-
- expect(clipboardText()).toBe(exampleText);
- });
- });
- });
-});
diff --git a/spec/javascripts/monitoring/shared/prometheus_header_spec.js b/spec/javascripts/monitoring/shared/prometheus_header_spec.js
new file mode 100644
index 00000000000..9f916a4dfbb
--- /dev/null
+++ b/spec/javascripts/monitoring/shared/prometheus_header_spec.js
@@ -0,0 +1,26 @@
+import { shallowMount } from '@vue/test-utils';
+import PrometheusHeader from '~/monitoring/components/shared/prometheus_header.vue';
+
+describe('Prometheus Header component', () => {
+ let prometheusHeader;
+
+ beforeEach(() => {
+ prometheusHeader = shallowMount(PrometheusHeader, {
+ propsData: {
+ graphTitle: 'graph header',
+ },
+ });
+ });
+
+ afterEach(() => {
+ prometheusHeader.destroy();
+ });
+
+ describe('Prometheus header component', () => {
+ it('should show a title', () => {
+ const title = prometheusHeader.vm.$el.querySelector('.js-graph-title').textContent;
+
+ expect(title).toBe('graph header');
+ });
+ });
+});
diff --git a/spec/javascripts/monitoring/store/actions_spec.js b/spec/javascripts/monitoring/store/actions_spec.js
deleted file mode 100644
index 1bd74f59282..00000000000
--- a/spec/javascripts/monitoring/store/actions_spec.js
+++ /dev/null
@@ -1,335 +0,0 @@
-import axios from '~/lib/utils/axios_utils';
-import MockAdapter from 'axios-mock-adapter';
-import store from '~/monitoring/stores';
-import * as types from '~/monitoring/stores/mutation_types';
-import {
- fetchDashboard,
- receiveMetricsDashboardSuccess,
- receiveMetricsDashboardFailure,
- fetchDeploymentsData,
- fetchEnvironmentsData,
- fetchPrometheusMetrics,
- fetchPrometheusMetric,
- requestMetricsData,
- setEndpoints,
- setGettingStartedEmptyState,
-} from '~/monitoring/stores/actions';
-import storeState from '~/monitoring/stores/state';
-import testAction from 'spec/helpers/vuex_action_helper';
-import { resetStore } from '../helpers';
-import {
- deploymentData,
- environmentData,
- metricsDashboardResponse,
- metricsGroupsAPIResponse,
- dashboardGitResponse,
-} from '../mock_data';
-
-describe('Monitoring store actions', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- resetStore(store);
- mock.restore();
- });
-
- describe('requestMetricsData', () => {
- it('sets emptyState to loading', () => {
- const commit = jasmine.createSpy();
- const { state } = store;
-
- requestMetricsData({ state, commit });
-
- expect(commit).toHaveBeenCalledWith(types.REQUEST_METRICS_DATA);
- });
- });
-
- describe('fetchDeploymentsData', () => {
- it('commits RECEIVE_DEPLOYMENTS_DATA_SUCCESS on error', done => {
- const dispatch = jasmine.createSpy();
- const { state } = store;
- state.deploymentsEndpoint = '/success';
-
- mock.onGet(state.deploymentsEndpoint).reply(200, {
- deployments: deploymentData,
- });
-
- fetchDeploymentsData({ state, dispatch })
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith('receiveDeploymentsDataSuccess', deploymentData);
- done();
- })
- .catch(done.fail);
- });
-
- it('commits RECEIVE_DEPLOYMENTS_DATA_FAILURE on error', done => {
- const dispatch = jasmine.createSpy();
- const { state } = store;
- state.deploymentsEndpoint = '/error';
-
- mock.onGet(state.deploymentsEndpoint).reply(500);
-
- fetchDeploymentsData({ state, dispatch })
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith('receiveDeploymentsDataFailure');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('fetchEnvironmentsData', () => {
- it('commits RECEIVE_ENVIRONMENTS_DATA_SUCCESS on error', done => {
- const dispatch = jasmine.createSpy();
- const { state } = store;
- state.environmentsEndpoint = '/success';
-
- mock.onGet(state.environmentsEndpoint).reply(200, {
- environments: environmentData,
- });
-
- fetchEnvironmentsData({ state, dispatch })
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith('receiveEnvironmentsDataSuccess', environmentData);
- done();
- })
- .catch(done.fail);
- });
-
- it('commits RECEIVE_ENVIRONMENTS_DATA_FAILURE on error', done => {
- const dispatch = jasmine.createSpy();
- const { state } = store;
- state.environmentsEndpoint = '/error';
-
- mock.onGet(state.environmentsEndpoint).reply(500);
-
- fetchEnvironmentsData({ state, dispatch })
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith('receiveEnvironmentsDataFailure');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('Set endpoints', () => {
- let mockedState;
-
- beforeEach(() => {
- mockedState = storeState();
- });
-
- it('should commit SET_ENDPOINTS mutation', done => {
- testAction(
- setEndpoints,
- {
- metricsEndpoint: 'additional_metrics.json',
- deploymentsEndpoint: 'deployments.json',
- environmentsEndpoint: 'deployments.json',
- },
- mockedState,
- [
- {
- type: types.SET_ENDPOINTS,
- payload: {
- metricsEndpoint: 'additional_metrics.json',
- deploymentsEndpoint: 'deployments.json',
- environmentsEndpoint: 'deployments.json',
- },
- },
- ],
- [],
- done,
- );
- });
- });
-
- describe('Set empty states', () => {
- let mockedState;
-
- beforeEach(() => {
- mockedState = storeState();
- });
-
- it('should commit SET_METRICS_ENDPOINT mutation', done => {
- testAction(
- setGettingStartedEmptyState,
- null,
- mockedState,
- [{ type: types.SET_GETTING_STARTED_EMPTY_STATE }],
- [],
- done,
- );
- });
- });
-
- describe('fetchDashboard', () => {
- let dispatch;
- let state;
- const response = metricsDashboardResponse;
-
- beforeEach(() => {
- dispatch = jasmine.createSpy();
- state = storeState();
- state.dashboardEndpoint = '/dashboard';
- });
-
- it('dispatches receive and success actions', done => {
- const params = {};
- mock.onGet(state.dashboardEndpoint).reply(200, response);
-
- fetchDashboard({ state, dispatch }, params)
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith('requestMetricsDashboard');
- expect(dispatch).toHaveBeenCalledWith('receiveMetricsDashboardSuccess', {
- response,
- params,
- });
- done();
- })
- .catch(done.fail);
- });
-
- it('dispatches failure action', done => {
- const params = {};
- mock.onGet(state.dashboardEndpoint).reply(500);
-
- fetchDashboard({ state, dispatch }, params)
- .then(() => {
- expect(dispatch).toHaveBeenCalledWith(
- 'receiveMetricsDashboardFailure',
- new Error('Request failed with status code 500'),
- );
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('receiveMetricsDashboardSuccess', () => {
- let commit;
- let dispatch;
- let state;
-
- beforeEach(() => {
- commit = jasmine.createSpy();
- dispatch = jasmine.createSpy();
- state = storeState();
- });
-
- it('stores groups ', () => {
- const params = {};
- const response = metricsDashboardResponse;
-
- receiveMetricsDashboardSuccess({ state, commit, dispatch }, { response, params });
-
- expect(commit).toHaveBeenCalledWith(
- types.RECEIVE_METRICS_DATA_SUCCESS,
- metricsDashboardResponse.dashboard.panel_groups,
- );
-
- expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetrics', params);
- });
-
- it('sets the dashboards loaded from the repository', () => {
- const params = {};
- const response = metricsDashboardResponse;
-
- response.all_dashboards = dashboardGitResponse;
- receiveMetricsDashboardSuccess({ state, commit, dispatch }, { response, params });
-
- expect(commit).toHaveBeenCalledWith(types.SET_ALL_DASHBOARDS, dashboardGitResponse);
- });
- });
-
- describe('receiveMetricsDashboardFailure', () => {
- let commit;
-
- beforeEach(() => {
- commit = jasmine.createSpy();
- });
-
- it('commits failure action', () => {
- receiveMetricsDashboardFailure({ commit });
-
- expect(commit).toHaveBeenCalledWith(types.RECEIVE_METRICS_DATA_FAILURE, undefined);
- });
-
- it('commits failure action with error', () => {
- receiveMetricsDashboardFailure({ commit }, 'uh-oh');
-
- expect(commit).toHaveBeenCalledWith(types.RECEIVE_METRICS_DATA_FAILURE, 'uh-oh');
- });
- });
-
- describe('fetchPrometheusMetrics', () => {
- let commit;
- let dispatch;
-
- beforeEach(() => {
- commit = jasmine.createSpy();
- dispatch = jasmine.createSpy();
- });
-
- it('commits empty state when state.groups is empty', done => {
- const state = storeState();
- const params = {};
-
- fetchPrometheusMetrics({ state, commit, dispatch }, params)
- .then(() => {
- expect(commit).toHaveBeenCalledWith(types.SET_NO_DATA_EMPTY_STATE);
- expect(dispatch).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
-
- it('dispatches fetchPrometheusMetric for each panel query', done => {
- const params = {};
- const state = storeState();
- state.groups = metricsDashboardResponse.dashboard.panel_groups;
-
- const metric = state.groups[0].panels[0].metrics[0];
-
- fetchPrometheusMetrics({ state, commit, dispatch }, params)
- .then(() => {
- expect(dispatch.calls.count()).toEqual(3);
- expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetric', { metric, params });
- done();
- })
- .catch(done.fail);
-
- done();
- });
- });
-
- describe('fetchPrometheusMetric', () => {
- it('commits prometheus query result', done => {
- const commit = jasmine.createSpy();
- const params = {
- start: '2019-08-06T12:40:02.184Z',
- end: '2019-08-06T20:40:02.184Z',
- };
- const metric = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics[0];
- const state = storeState();
-
- const data = metricsGroupsAPIResponse.data[0].metrics[0].queries[0];
- const response = { data };
- mock.onGet('http://test').reply(200, response);
-
- fetchPrometheusMetric({ state, commit }, { metric, params });
-
- setTimeout(() => {
- expect(commit).toHaveBeenCalledWith(types.SET_QUERY_RESULT, {
- metricId: metric.metric_id,
- result: data.result,
- });
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/monitoring/store/mutations_spec.js b/spec/javascripts/monitoring/store/mutations_spec.js
deleted file mode 100644
index bdddd83358c..00000000000
--- a/spec/javascripts/monitoring/store/mutations_spec.js
+++ /dev/null
@@ -1,177 +0,0 @@
-import mutations from '~/monitoring/stores/mutations';
-import * as types from '~/monitoring/stores/mutation_types';
-import state from '~/monitoring/stores/state';
-import {
- metricsGroupsAPIResponse,
- deploymentData,
- metricsDashboardResponse,
- dashboardGitResponse,
-} from '../mock_data';
-import { uniqMetricsId } from '~/monitoring/stores/utils';
-
-describe('Monitoring mutations', () => {
- let stateCopy;
-
- beforeEach(() => {
- stateCopy = state();
- });
-
- describe(types.RECEIVE_METRICS_DATA_SUCCESS, () => {
- let groups;
-
- beforeEach(() => {
- stateCopy.groups = [];
- groups = metricsGroupsAPIResponse.data;
- });
-
- it('normalizes values', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
-
- const expectedTimestamp = '2017-05-25T08:22:34.925Z';
- const expectedValue = 0.0010794445585559514;
- const [timestamp, value] = stateCopy.groups[0].metrics[0].queries[0].result[0].values[0];
-
- expect(timestamp).toEqual(expectedTimestamp);
- expect(value).toEqual(expectedValue);
- });
-
- it('contains two groups that contains, one of which has two queries sorted by priority', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
-
- expect(stateCopy.groups).toBeDefined();
- expect(stateCopy.groups.length).toEqual(2);
- expect(stateCopy.groups[0].metrics.length).toEqual(2);
- });
-
- it('assigns queries a metric id', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
-
- expect(stateCopy.groups[1].metrics[0].queries[0].metricId).toEqual('100');
- });
-
- it('removes the data if all the values from a query are not defined', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
-
- expect(stateCopy.groups[1].metrics[0].queries[0].result.length).toEqual(0);
- });
-
- it('assigns metric id of null if metric has no id', () => {
- stateCopy.groups = [];
- const noId = groups.map(group => ({
- ...group,
- ...{
- metrics: group.metrics.map(metric => {
- const { id, ...metricWithoutId } = metric;
-
- return metricWithoutId;
- }),
- },
- }));
-
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, noId);
-
- stateCopy.groups.forEach(group => {
- group.metrics.forEach(metric => {
- expect(metric.queries.every(query => query.metricId === null)).toBe(true);
- });
- });
- });
-
- describe('dashboard endpoint enabled', () => {
- const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
-
- beforeEach(() => {
- stateCopy.useDashboardEndpoint = true;
- });
-
- it('aliases group panels to metrics for backwards compatibility', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
-
- expect(stateCopy.groups[0].metrics[0]).toBeDefined();
- });
-
- it('aliases panel metrics to queries for backwards compatibility', () => {
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
-
- expect(stateCopy.groups[0].metrics[0].queries).toBeDefined();
- });
- });
- });
-
- describe(types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS, () => {
- it('stores the deployment data', () => {
- stateCopy.deploymentData = [];
- mutations[types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS](stateCopy, deploymentData);
-
- expect(stateCopy.deploymentData).toBeDefined();
- expect(stateCopy.deploymentData.length).toEqual(3);
- expect(typeof stateCopy.deploymentData[0]).toEqual('object');
- });
- });
-
- describe('SET_ENDPOINTS', () => {
- it('should set all the endpoints', () => {
- mutations[types.SET_ENDPOINTS](stateCopy, {
- metricsEndpoint: 'additional_metrics.json',
- environmentsEndpoint: 'environments.json',
- deploymentsEndpoint: 'deployments.json',
- dashboardEndpoint: 'dashboard.json',
- projectPath: '/gitlab-org/gitlab-foss',
- });
-
- expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
- expect(stateCopy.environmentsEndpoint).toEqual('environments.json');
- expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
- expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
- expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
- });
- });
-
- describe('SET_QUERY_RESULT', () => {
- const metricId = 12;
- const id = 'system_metrics_kubernetes_container_memory_total';
- const result = [{ values: [[0, 1], [1, 1], [1, 3]] }];
-
- beforeEach(() => {
- stateCopy.useDashboardEndpoint = true;
- const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
- mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
- });
-
- it('clears empty state', () => {
- mutations[types.SET_QUERY_RESULT](stateCopy, {
- metricId,
- result,
- });
-
- expect(stateCopy.showEmptyState).toBe(false);
- });
-
- it('sets metricsWithData value', () => {
- const uniqId = uniqMetricsId({ metric_id: metricId, id });
- mutations[types.SET_QUERY_RESULT](stateCopy, {
- metricId: uniqId,
- result,
- });
-
- expect(stateCopy.metricsWithData).toEqual([uniqId]);
- });
-
- it('does not store empty results', () => {
- mutations[types.SET_QUERY_RESULT](stateCopy, {
- metricId,
- result: [],
- });
-
- expect(stateCopy.metricsWithData).toEqual([]);
- });
- });
-
- describe('SET_ALL_DASHBOARDS', () => {
- it('stores the dashboards loaded from the git repository', () => {
- mutations[types.SET_ALL_DASHBOARDS](stateCopy, dashboardGitResponse);
-
- expect(stateCopy.allDashboards).toEqual(dashboardGitResponse);
- });
- });
-});
diff --git a/spec/javascripts/monitoring/store/utils_spec.js b/spec/javascripts/monitoring/store/utils_spec.js
deleted file mode 100644
index 98388ac19f8..00000000000
--- a/spec/javascripts/monitoring/store/utils_spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import { groupQueriesByChartInfo, normalizeMetric, uniqMetricsId } from '~/monitoring/stores/utils';
-
-describe('groupQueriesByChartInfo', () => {
- let input;
- let output;
-
- it('groups metrics with the same chart title and y_axis label', () => {
- input = [
- { title: 'title', y_label: 'MB', queries: [{}] },
- { title: 'title', y_label: 'MB', queries: [{}] },
- { title: 'new title', y_label: 'MB', queries: [{}] },
- ];
-
- output = [
- {
- title: 'title',
- y_label: 'MB',
- queries: [{ metricId: null }, { metricId: null }],
- },
- { title: 'new title', y_label: 'MB', queries: [{ metricId: null }] },
- ];
-
- expect(groupQueriesByChartInfo(input)).toEqual(output);
- });
-
- // Functionality associated with the /additional_metrics endpoint
- it("associates a chart's stringified metric_id with the metric", () => {
- input = [{ id: 3, title: 'new title', y_label: 'MB', queries: [{}] }];
- output = [{ id: 3, title: 'new title', y_label: 'MB', queries: [{ metricId: '3' }] }];
-
- expect(groupQueriesByChartInfo(input)).toEqual(output);
- });
-
- // Functionality associated with the /metrics_dashboard endpoint
- it('aliases a stringified metrics_id on the metric to the metricId key', () => {
- input = [{ title: 'new title', y_label: 'MB', queries: [{ metric_id: 3 }] }];
- output = [{ title: 'new title', y_label: 'MB', queries: [{ metricId: '3', metric_id: 3 }] }];
-
- expect(groupQueriesByChartInfo(input)).toEqual(output);
- });
-});
-
-describe('normalizeMetric', () => {
- [
- { args: [], expected: 'undefined_undefined' },
- { args: [undefined], expected: 'undefined_undefined' },
- { args: [{ id: 'something' }], expected: 'undefined_something' },
- { args: [{ id: 45 }], expected: 'undefined_45' },
- { args: [{ metric_id: 5 }], expected: '5_undefined' },
- { args: [{ metric_id: 'something' }], expected: 'something_undefined' },
- {
- args: [{ metric_id: 5, id: 'system_metrics_kubernetes_container_memory_total' }],
- expected: '5_system_metrics_kubernetes_container_memory_total',
- },
- ].forEach(({ args, expected }) => {
- it(`normalizes metric to "${expected}" with args=${JSON.stringify(args)}`, () => {
- expect(normalizeMetric(...args)).toEqual({ metric_id: expected });
- });
- });
-});
-
-describe('uniqMetricsId', () => {
- [
- { input: { id: 1 }, expected: 'undefined_1' },
- { input: { metric_id: 2 }, expected: '2_undefined' },
- { input: { metric_id: 2, id: 21 }, expected: '2_21' },
- { input: { metric_id: 22, id: 1 }, expected: '22_1' },
- { input: { metric_id: 'aaa', id: '_a' }, expected: 'aaa__a' },
- ].forEach(({ input, expected }) => {
- it(`creates unique metric ID with ${JSON.stringify(input)}`, () => {
- expect(uniqMetricsId(input)).toEqual(expected);
- });
- });
-});
diff --git a/spec/javascripts/monitoring/utils_spec.js b/spec/javascripts/monitoring/utils_spec.js
index 512dd2a0eb3..202b4ec8f2e 100644
--- a/spec/javascripts/monitoring/utils_spec.js
+++ b/spec/javascripts/monitoring/utils_spec.js
@@ -7,9 +7,14 @@ import {
stringToISODate,
ISODateToString,
isValidDate,
+ graphDataValidatorForAnomalyValues,
} from '~/monitoring/utils';
import { timeWindows, timeWindowsKeyNames } from '~/monitoring/constants';
-import { graphDataPrometheusQuery, graphDataPrometheusQueryRange } from './mock_data';
+import {
+ graphDataPrometheusQuery,
+ graphDataPrometheusQueryRange,
+ anomalyMockGraphData,
+} from './mock_data';
describe('getTimeDiff', () => {
function secondsBetween({ start, end }) {
@@ -307,3 +312,34 @@ describe('isDateTimePickerInputValid', () => {
});
});
});
+
+describe('graphDataValidatorForAnomalyValues', () => {
+ let oneQuery;
+ let threeQueries;
+ let fourQueries;
+ beforeEach(() => {
+ oneQuery = graphDataPrometheusQuery;
+ threeQueries = anomalyMockGraphData;
+
+ const queries = [...threeQueries.queries];
+ queries.push(threeQueries.queries[0]);
+ fourQueries = {
+ ...anomalyMockGraphData,
+ queries,
+ };
+ });
+ /*
+ * Anomaly charts can accept results for exactly 3 queries,
+ */
+ it('validates passes with the right query format', () => {
+ expect(graphDataValidatorForAnomalyValues(threeQueries)).toBe(true);
+ });
+
+ it('validation fails for wrong format, 1 metric', () => {
+ expect(graphDataValidatorForAnomalyValues(oneQuery)).toBe(false);
+ });
+
+ it('validation fails for wrong format, more than 3 metrics', () => {
+ expect(graphDataValidatorForAnomalyValues(fourQueries)).toBe(false);
+ });
+});
diff --git a/spec/javascripts/notes/components/comment_form_spec.js b/spec/javascripts/notes/components/comment_form_spec.js
deleted file mode 100644
index 88c86746992..00000000000
--- a/spec/javascripts/notes/components/comment_form_spec.js
+++ /dev/null
@@ -1,301 +0,0 @@
-import $ from 'jquery';
-import Vue from 'vue';
-import Autosize from 'autosize';
-import createStore from '~/notes/stores';
-import CommentForm from '~/notes/components/comment_form.vue';
-import * as constants from '~/notes/constants';
-import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } from '../mock_data';
-import { keyboardDownEvent } from '../../issue_show/helpers';
-
-describe('issue_comment_form component', () => {
- let store;
- let vm;
- const Component = Vue.extend(CommentForm);
- let mountComponent;
-
- beforeEach(() => {
- store = createStore();
- mountComponent = (noteableType = 'issue') =>
- new Component({
- propsData: {
- noteableType,
- },
- store,
- }).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('user is logged in', () => {
- beforeEach(() => {
- store.dispatch('setUserData', userDataMock);
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
-
- vm = mountComponent();
- });
-
- it('should render user avatar with link', () => {
- expect(vm.$el.querySelector('.timeline-icon .user-avatar-link').getAttribute('href')).toEqual(
- userDataMock.path,
- );
- });
-
- describe('handleSave', () => {
- it('should request to save note when note is entered', () => {
- vm.note = 'hello world';
- spyOn(vm, 'saveNote').and.returnValue(new Promise(() => {}));
- spyOn(vm, 'resizeTextarea');
- spyOn(vm, 'stopPolling');
-
- vm.handleSave();
-
- expect(vm.isSubmitting).toEqual(true);
- expect(vm.note).toEqual('');
- expect(vm.saveNote).toHaveBeenCalled();
- expect(vm.stopPolling).toHaveBeenCalled();
- expect(vm.resizeTextarea).toHaveBeenCalled();
- });
-
- it('should toggle issue state when no note', () => {
- spyOn(vm, 'toggleIssueState');
-
- vm.handleSave();
-
- expect(vm.toggleIssueState).toHaveBeenCalled();
- });
-
- it('should disable action button whilst submitting', done => {
- const saveNotePromise = Promise.resolve();
- vm.note = 'hello world';
- spyOn(vm, 'saveNote').and.returnValue(saveNotePromise);
- spyOn(vm, 'stopPolling');
-
- const actionButton = vm.$el.querySelector('.js-action-button');
-
- vm.handleSave();
-
- Vue.nextTick()
- .then(() => {
- expect(actionButton.disabled).toBeTruthy();
- })
- .then(saveNotePromise)
- .then(Vue.nextTick)
- .then(() => {
- expect(actionButton.disabled).toBeFalsy();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('textarea', () => {
- it('should render textarea with placeholder', () => {
- expect(
- vm.$el.querySelector('.js-main-target-form textarea').getAttribute('placeholder'),
- ).toEqual('Write a comment or drag your files here…');
- });
-
- it('should make textarea disabled while requesting', done => {
- const $submitButton = $(vm.$el.querySelector('.js-comment-submit-button'));
- vm.note = 'hello world';
- spyOn(vm, 'stopPolling');
- spyOn(vm, 'saveNote').and.returnValue(new Promise(() => {}));
-
- vm.$nextTick(() => {
- // Wait for vm.note change triggered. It should enable $submitButton.
- $submitButton.trigger('click');
-
- vm.$nextTick(() => {
- // Wait for vm.isSubmitting triggered. It should disable textarea.
- expect(vm.$el.querySelector('.js-main-target-form textarea').disabled).toBeTruthy();
- done();
- });
- });
- });
-
- it('should support quick actions', () => {
- expect(
- vm.$el
- .querySelector('.js-main-target-form textarea')
- .getAttribute('data-supports-quick-actions'),
- ).toEqual('true');
- });
-
- it('should link to markdown docs', () => {
- const { markdownDocsPath } = notesDataMock;
-
- expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual(
- 'Markdown',
- );
- });
-
- it('should link to quick actions docs', () => {
- const { quickActionsDocsPath } = notesDataMock;
-
- expect(
- vm.$el.querySelector(`a[href="${quickActionsDocsPath}"]`).textContent.trim(),
- ).toEqual('quick actions');
- });
-
- it('should resize textarea after note discarded', done => {
- spyOn(Autosize, 'update');
- spyOn(vm, 'discard').and.callThrough();
-
- vm.note = 'foo';
- vm.discard();
-
- Vue.nextTick(() => {
- expect(Autosize.update).toHaveBeenCalled();
- done();
- });
- });
-
- describe('edit mode', () => {
- it('should enter edit mode when arrow up is pressed', () => {
- spyOn(vm, 'editCurrentUserLastNote').and.callThrough();
- vm.$el.querySelector('.js-main-target-form textarea').value = 'Foo';
- vm.$el
- .querySelector('.js-main-target-form textarea')
- .dispatchEvent(keyboardDownEvent(38, true));
-
- expect(vm.editCurrentUserLastNote).toHaveBeenCalled();
- });
-
- it('inits autosave', () => {
- expect(vm.autosave).toBeDefined();
- expect(vm.autosave.key).toEqual(`autosave/Note/Issue/${noteableDataMock.id}`);
- });
- });
-
- describe('event enter', () => {
- it('should save note when cmd+enter is pressed', () => {
- spyOn(vm, 'handleSave').and.callThrough();
- vm.$el.querySelector('.js-main-target-form textarea').value = 'Foo';
- vm.$el
- .querySelector('.js-main-target-form textarea')
- .dispatchEvent(keyboardDownEvent(13, true));
-
- expect(vm.handleSave).toHaveBeenCalled();
- });
-
- it('should save note when ctrl+enter is pressed', () => {
- spyOn(vm, 'handleSave').and.callThrough();
- vm.$el.querySelector('.js-main-target-form textarea').value = 'Foo';
- vm.$el
- .querySelector('.js-main-target-form textarea')
- .dispatchEvent(keyboardDownEvent(13, false, true));
-
- expect(vm.handleSave).toHaveBeenCalled();
- });
- });
- });
-
- describe('actions', () => {
- it('should be possible to close the issue', () => {
- expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual(
- 'Close issue',
- );
- });
-
- it('should render comment button as disabled', () => {
- expect(vm.$el.querySelector('.js-comment-submit-button').getAttribute('disabled')).toEqual(
- 'disabled',
- );
- });
-
- it('should enable comment button if it has note', done => {
- vm.note = 'Foo';
- Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.js-comment-submit-button').getAttribute('disabled'),
- ).toEqual(null);
- done();
- });
- });
-
- it('should update buttons texts when it has note', done => {
- vm.note = 'Foo';
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual(
- 'Comment & close issue',
- );
-
- done();
- });
- });
-
- it('updates button text with noteable type', done => {
- vm.noteableType = constants.MERGE_REQUEST_NOTEABLE_TYPE;
-
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual(
- 'Close merge request',
- );
- done();
- });
- });
-
- describe('when clicking close/reopen button', () => {
- it('should disable button and show a loading spinner', done => {
- const toggleStateButton = vm.$el.querySelector('.js-action-button');
-
- toggleStateButton.click();
- Vue.nextTick(() => {
- expect(toggleStateButton.disabled).toEqual(true);
- expect(toggleStateButton.querySelector('.js-loading-button-icon')).not.toBeNull();
-
- done();
- });
- });
- });
-
- describe('when toggling state', () => {
- it('should update MR count', done => {
- spyOn(vm, 'closeIssue').and.returnValue(Promise.resolve());
-
- const updateMrCountSpy = spyOnDependency(CommentForm, 'refreshUserMergeRequestCounts');
- vm.toggleIssueState();
-
- Vue.nextTick(() => {
- expect(updateMrCountSpy).toHaveBeenCalled();
-
- done();
- });
- });
- });
- });
-
- describe('issue is confidential', () => {
- it('shows information warning', done => {
- store.dispatch('setNoteableData', Object.assign(noteableDataMock, { confidential: true }));
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.confidential-issue-warning')).toBeDefined();
- done();
- });
- });
- });
- });
-
- describe('user is not logged in', () => {
- beforeEach(() => {
- store.dispatch('setUserData', null);
- store.dispatch('setNoteableData', loggedOutnoteableData);
- store.dispatch('setNotesData', notesDataMock);
-
- vm = mountComponent();
- });
-
- it('should render signed out widget', () => {
- expect(vm.$el.textContent.replace(/\s+/g, ' ').trim()).toEqual(
- 'Please register or sign in to reply',
- );
- });
-
- it('should not render submission form', () => {
- expect(vm.$el.querySelector('textarea')).toEqual(null);
- });
- });
-});
diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js
index ea5c57b8a7c..ea1ed3da112 100644
--- a/spec/javascripts/notes/components/noteable_discussion_spec.js
+++ b/spec/javascripts/notes/components/noteable_discussion_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, createLocalVue } from '@vue/test-utils';
import createStore from '~/notes/stores';
import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
@@ -23,7 +23,7 @@ describe('noteable_discussion component', () => {
store.dispatch('setNotesData', notesDataMock);
const localVue = createLocalVue();
- wrapper = shallowMount(noteableDiscussion, {
+ wrapper = mount(noteableDiscussion, {
store,
propsData: { discussion: discussionMock },
localVue,
@@ -35,16 +35,6 @@ describe('noteable_discussion component', () => {
wrapper.destroy();
});
- it('should render user avatar', () => {
- const discussion = { ...discussionMock };
- discussion.diff_file = mockDiffFile;
- discussion.diff_discussion = true;
-
- wrapper.setProps({ discussion, renderDiffFile: true });
-
- expect(wrapper.find('.user-avatar-link').exists()).toBe(true);
- });
-
it('should not render thread header for non diff threads', () => {
expect(wrapper.find('.discussion-header').exists()).toBe(false);
});
@@ -134,105 +124,6 @@ describe('noteable_discussion component', () => {
});
});
- describe('action text', () => {
- const commitId = 'razupaltuff';
- const truncatedCommitId = commitId.substr(0, 8);
- let commitElement;
-
- beforeEach(done => {
- store.state.diffs = {
- projectPath: 'something',
- };
-
- wrapper.setProps({
- discussion: {
- ...discussionMock,
- for_commit: true,
- commit_id: commitId,
- diff_discussion: true,
- diff_file: {
- ...mockDiffFile,
- },
- },
- renderDiffFile: true,
- });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- commitElement = wrapper.find('.commit-sha');
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('for commit threads', () => {
- it('should display a monospace started a thread on commit', () => {
- expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`);
- expect(commitElement.exists()).toBe(true);
- expect(commitElement.text()).toContain(truncatedCommitId);
- });
- });
-
- describe('for diff thread with a commit id', () => {
- it('should display started thread on commit header', done => {
- wrapper.vm.discussion.for_commit = false;
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`);
-
- expect(commitElement).not.toBe(null);
-
- done();
- });
- });
-
- it('should display outdated change on commit header', done => {
- wrapper.vm.discussion.for_commit = false;
- wrapper.vm.discussion.active = false;
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain(
- `started a thread on an outdated change in commit ${truncatedCommitId}`,
- );
-
- expect(commitElement).not.toBe(null);
-
- done();
- });
- });
- });
-
- describe('for diff threads without a commit id', () => {
- it('should show started a thread on the diff text', done => {
- Object.assign(wrapper.vm.discussion, {
- for_commit: false,
- commit_id: null,
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain('started a thread on the diff');
-
- done();
- });
- });
-
- it('should show thread on older version text', done => {
- Object.assign(wrapper.vm.discussion, {
- for_commit: false,
- commit_id: null,
- active: false,
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain('started a thread on an old version of the diff');
-
- done();
- });
- });
- });
- });
-
describe('for resolved thread', () => {
beforeEach(() => {
const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
@@ -262,6 +153,7 @@ describe('noteable_discussion component', () => {
}));
wrapper.setProps({ discussion });
+
wrapper.vm
.$nextTick()
.then(done)
diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js
index dc914ce8355..89e4553092a 100644
--- a/spec/javascripts/notes/mock_data.js
+++ b/spec/javascripts/notes/mock_data.js
@@ -1,1255 +1 @@
-// Copied to ee/spec/frontend/notes/mock_data.js
-
-export const notesDataMock = {
- discussionsPath: '/gitlab-org/gitlab-foss/issues/26/discussions.json',
- lastFetchedAt: 1501862675,
- markdownDocsPath: '/help/user/markdown',
- newSessionPath: '/users/sign_in?redirect_to_referer=yes',
- notesPath: '/gitlab-org/gitlab-foss/noteable/issue/98/notes',
- quickActionsDocsPath: '/help/user/project/quick_actions',
- registerPath: '/users/sign_in?redirect_to_referer=yes#register-pane',
- prerenderedNotesCount: 1,
- closePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=close',
- reopenPath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=reopen',
- canAwardEmoji: true,
-};
-
-export const userDataMock = {
- avatar_url: 'mock_path',
- id: 1,
- name: 'Root',
- path: '/root',
- state: 'active',
- username: 'root',
-};
-
-export const noteableDataMock = {
- assignees: [],
- author_id: 1,
- branch_name: null,
- confidential: false,
- create_note_path: '/gitlab-org/gitlab-foss/notes?target_id=98&target_type=issue',
- created_at: '2017-02-07T10:11:18.395Z',
- current_user: {
- can_create_note: true,
- can_update: true,
- can_award_emoji: true,
- },
- description: '',
- due_date: null,
- human_time_estimate: null,
- human_total_time_spent: null,
- id: 98,
- iid: 26,
- labels: [],
- lock_version: null,
- milestone: null,
- milestone_id: null,
- moved_to_id: null,
- preview_note_path: '/gitlab-org/gitlab-foss/preview_markdown?target_id=98&target_type=Issue',
- project_id: 2,
- state: 'opened',
- time_estimate: 0,
- title: '14',
- total_time_spent: 0,
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- updated_at: '2017-08-04T09:53:01.226Z',
- updated_by_id: 1,
- web_url: '/gitlab-org/gitlab-foss/issues/26',
- noteableType: 'issue',
-};
-
-export const lastFetchedAt = '1501862675';
-
-export const individualNote = {
- expanded: true,
- id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- individual_note: true,
- notes: [
- {
- id: '1390',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: 'test',
- path: '/root',
- },
- created_at: '2017-08-01T17: 09: 33.762Z',
- updated_at: '2017-08-01T17: 09: 33.762Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: null,
- human_access: 'Owner',
- note: 'sdfdsaf',
- note_html: "<p dir='auto'>sdfdsaf</p>",
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- emoji_awardable: true,
- award_emoji: [
- { name: 'baseball', user: { id: 1, name: 'Root', username: 'root' } },
- { name: 'art', user: { id: 1, name: 'Root', username: 'root' } },
- ],
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1390/toggle_award_emoji',
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- note_url: '/group/project/merge_requests/1#note_1',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1390&user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1390',
- },
- ],
- reply_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
-};
-
-export const note = {
- id: '546',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2017-08-10T15:24:03.087Z',
- updated_at: '2017-08-10T15:24:03.087Z',
- system: false,
- noteable_id: 67,
- noteable_type: 'Issue',
- noteable_iid: 7,
- type: null,
- human_access: 'Owner',
- note: 'Vel id placeat reprehenderit sit numquam.',
- note_html: '<p dir="auto">Vel id placeat reprehenderit sit numquam.</p>',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: 'd3842a451b7f3d9a5dfce329515127b2d29a4cd0',
- emoji_awardable: true,
- award_emoji: [
- {
- name: 'baseball',
- user: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- },
- },
- {
- name: 'bath_tone3',
- user: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- },
- },
- ],
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/546/toggle_award_emoji',
- note_url: '/group/project/merge_requests/1#note_1',
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F7%23note_546&user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/546',
-};
-
-export const discussionMock = {
- id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1',
- reply_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1',
- expanded: true,
- notes: [
- {
- id: '1395',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-02T10:51:58.559Z',
- updated_at: '2017-08-02T10:51:58.559Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: 'DiscussionNote',
- human_access: 'Owner',
- note: 'THIS IS A DICUSSSION!',
- note_html: "<p dir='auto'>THIS IS A DICUSSSION!</p>",
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- can_resolve: true,
- },
- discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1',
- emoji_awardable: true,
- award_emoji: [],
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1395/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1395&user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1395',
- },
- {
- id: '1396',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-02T10:56:50.980Z',
- updated_at: '2017-08-03T14:19:35.691Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: 'DiscussionNote',
- human_access: 'Owner',
- note: 'sadfasdsdgdsf',
- note_html: "<p dir='auto'>sadfasdsdgdsf</p>",
- last_edited_at: '2017-08-03T14:19:35.691Z',
- last_edited_by: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- can_resolve: true,
- },
- discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1396/toggle_award_emoji',
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1396&user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1396',
- },
- {
- id: '1437',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-03T18:11:18.780Z',
- updated_at: '2017-08-04T09:52:31.062Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: 'DiscussionNote',
- human_access: 'Owner',
- note: 'adsfasf Should disappear',
- note_html: "<p dir='auto'>adsfasf Should disappear</p>",
- last_edited_at: '2017-08-04T09:52:31.062Z',
- last_edited_by: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- can_resolve: true,
- },
- discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1',
- emoji_awardable: true,
- award_emoji: [],
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1437/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1437&user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1437',
- },
- ],
- individual_note: false,
- resolvable: true,
- active: true,
-};
-
-export const loggedOutnoteableData = {
- id: '98',
- iid: 26,
- author_id: 1,
- description: '',
- lock_version: 1,
- milestone_id: null,
- state: 'opened',
- title: 'asdsa',
- updated_by_id: 1,
- created_at: '2017-02-07T10:11:18.395Z',
- updated_at: '2017-08-08T10:22:51.564Z',
- time_estimate: 0,
- total_time_spent: 0,
- human_time_estimate: null,
- human_total_time_spent: null,
- milestone: null,
- labels: [],
- branch_name: null,
- confidential: false,
- assignees: [
- {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- web_url: 'http://localhost:3000/root',
- },
- ],
- due_date: null,
- moved_to_id: null,
- project_id: 2,
- web_url: '/gitlab-org/gitlab-foss/issues/26',
- current_user: {
- can_create_note: false,
- can_update: false,
- },
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- create_note_path: '/gitlab-org/gitlab-foss/notes?target_id=98&target_type=issue',
- preview_note_path: '/gitlab-org/gitlab-foss/preview_markdown?target_id=98&target_type=Issue',
-};
-
-export const collapseNotesMock = [
- {
- expanded: true,
- id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- individual_note: true,
- notes: [
- {
- id: '1390',
- attachment: null,
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: 'test',
- path: '/root',
- },
- created_at: '2018-02-26T18:07:41.071Z',
- updated_at: '2018-02-26T18:07:41.071Z',
- system: true,
- system_note_icon_name: 'pencil',
- noteable_id: 98,
- noteable_type: 'Issue',
- type: null,
- human_access: 'Owner',
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false },
- discussion_id: 'b97fb7bda470a65b3e009377a9032edec0a4dd05',
- emoji_awardable: false,
- path: '/h5bp/html5-boilerplate/notes/1057',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fh5bp%2Fhtml5-boilerplate%2Fissues%2F10%23note_1057&user_id=1',
- },
- ],
- },
- {
- expanded: true,
- id: 'ffde43f25984ad7f2b4275135e0e2846875336c0',
- individual_note: true,
- notes: [
- {
- id: '1391',
- attachment: null,
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: 'test',
- path: '/root',
- },
- created_at: '2018-02-26T18:13:24.071Z',
- updated_at: '2018-02-26T18:13:24.071Z',
- system: true,
- system_note_icon_name: 'pencil',
- noteable_id: 99,
- noteable_type: 'Issue',
- type: null,
- human_access: 'Owner',
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false },
- discussion_id: '3eb958b4d81dec207ec3537a2f3bd8b9f271bb34',
- emoji_awardable: false,
- path: '/h5bp/html5-boilerplate/notes/1057',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fh5bp%2Fhtml5-boilerplate%2Fissues%2F10%23note_1057&user_id=1',
- },
- ],
- },
-];
-
-export const INDIVIDUAL_NOTE_RESPONSE_MAP = {
- GET: {
- '/gitlab-org/gitlab-foss/issues/26/discussions.json': [
- {
- id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- reply_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- expanded: true,
- notes: [
- {
- id: '1390',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-01T17:09:33.762Z',
- updated_at: '2017-08-01T17:09:33.762Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: null,
- human_access: 'Owner',
- note: 'sdfdsaf',
- note_html: '\u003cp dir="auto"\u003esdfdsaf\u003c/p\u003e',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd',
- emoji_awardable: true,
- award_emoji: [
- {
- name: 'baseball',
- user: {
- id: 1,
- name: 'Root',
- username: 'root',
- },
- },
- {
- name: 'art',
- user: {
- id: 1,
- name: 'Root',
- username: 'root',
- },
- },
- ],
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1390/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1390\u0026user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1390',
- },
- ],
- individual_note: true,
- },
- {
- id: '70d5c92a4039a36c70100c6691c18c27e4b0a790',
- reply_id: '70d5c92a4039a36c70100c6691c18c27e4b0a790',
- expanded: true,
- notes: [
- {
- id: '1391',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-02T10:51:38.685Z',
- updated_at: '2017-08-02T10:51:38.685Z',
- system: false,
- noteable_id: 98,
- noteable_type: 'Issue',
- type: null,
- human_access: 'Owner',
- note: 'New note!',
- note_html: '\u003cp dir="auto"\u003eNew note!\u003c/p\u003e',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: '70d5c92a4039a36c70100c6691c18c27e4b0a790',
- emoji_awardable: true,
- award_emoji: [],
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1391/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F26%23note_1391\u0026user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1391',
- },
- ],
- individual_note: true,
- },
- ],
- '/gitlab-org/gitlab-foss/noteable/issue/98/notes': {
- last_fetched_at: 1512900838,
- notes: [],
- },
- },
- PUT: {
- '/gitlab-org/gitlab-foss/notes/1471': {
- commands_changes: null,
- valid: true,
- id: '1471',
- attachment: null,
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-08T16:53:00.666Z',
- updated_at: '2017-12-10T11:03:21.876Z',
- system: false,
- noteable_id: 124,
- noteable_type: 'Issue',
- noteable_iid: 29,
- type: 'DiscussionNote',
- human_access: 'Owner',
- note: 'Adding a comment',
- note_html: '\u003cp dir="auto"\u003eAdding a comment\u003c/p\u003e',
- last_edited_at: '2017-12-10T11:03:21.876Z',
- last_edited_by: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052',
- emoji_awardable: true,
- award_emoji: [],
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1471/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F29%23note_1471\u0026user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1471',
- },
- },
-};
-
-export const DISCUSSION_NOTE_RESPONSE_MAP = {
- ...INDIVIDUAL_NOTE_RESPONSE_MAP,
- GET: {
- ...INDIVIDUAL_NOTE_RESPONSE_MAP.GET,
- '/gitlab-org/gitlab-foss/issues/26/discussions.json': [
- {
- id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052',
- reply_id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052',
- expanded: true,
- notes: [
- {
- id: '1471',
- attachment: {
- url: null,
- filename: null,
- image: false,
- },
- author: {
- id: 1,
- name: 'Root',
- username: 'root',
- state: 'active',
- avatar_url: null,
- path: '/root',
- },
- created_at: '2017-08-08T16:53:00.666Z',
- updated_at: '2017-08-08T16:53:00.666Z',
- system: false,
- noteable_id: 124,
- noteable_type: 'Issue',
- noteable_iid: 29,
- type: 'DiscussionNote',
- human_access: 'Owner',
- note: 'Adding a comment',
- note_html: '\u003cp dir="auto"\u003eAdding a comment\u003c/p\u003e',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- discussion_id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-foss/notes/1471/toggle_award_emoji',
- noteable_note_url: '/group/project/merge_requests/1#note_1',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F29%23note_1471\u0026user_id=1',
- path: '/gitlab-org/gitlab-foss/notes/1471',
- },
- ],
- individual_note: false,
- },
- ],
- },
-};
-
-export function getIndividualNoteResponse(config) {
- return [200, INDIVIDUAL_NOTE_RESPONSE_MAP[config.method.toUpperCase()][config.url]];
-}
-
-export function getDiscussionNoteResponse(config) {
- return [200, DISCUSSION_NOTE_RESPONSE_MAP[config.method.toUpperCase()][config.url]];
-}
-
-export const notesWithDescriptionChanges = [
- {
- id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- reply_id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- expanded: true,
- notes: [
- {
- id: '901',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:05:36.117Z',
- updated_at: '2018-05-29T12:05:36.117Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
- note_html:
- '<p dir="auto">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_901&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/901/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/901',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- reply_id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- expanded: true,
- notes: [
- {
- id: '902',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:05:58.694Z',
- updated_at: '2018-05-29T12:05:58.694Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note:
- 'Varius vel pharetra vel turpis nunc eget lorem. Ipsum dolor sit amet consectetur adipiscing.',
- note_html:
- '<p dir="auto">Varius vel pharetra vel turpis nunc eget lorem. Ipsum dolor sit amet consectetur adipiscing.</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_902&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/902/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/902',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '7f1feda384083eb31763366e6392399fde6f3f31',
- reply_id: '7f1feda384083eb31763366e6392399fde6f3f31',
- expanded: true,
- notes: [
- {
- id: '903',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:06:05.772Z',
- updated_at: '2018-05-29T12:06:05.772Z',
- system: true,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- system_note_icon_name: 'pencil-square',
- discussion_id: '7f1feda384083eb31763366e6392399fde6f3f31',
- emoji_awardable: false,
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_903&user_id=1',
- human_access: 'Owner',
- path: '/gitlab-org/gitlab-shell/notes/903',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- reply_id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- expanded: true,
- notes: [
- {
- id: '904',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:06:16.112Z',
- updated_at: '2018-05-29T12:06:16.112Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'Ullamcorper eget nulla facilisi etiam',
- note_html: '<p dir="auto">Ullamcorper eget nulla facilisi etiam</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_904&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/904/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/904',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- reply_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- expanded: true,
- notes: [
- {
- id: '905',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:06:28.851Z',
- updated_at: '2018-05-29T12:06:28.851Z',
- system: true,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- system_note_icon_name: 'pencil-square',
- discussion_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- emoji_awardable: false,
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_905&user_id=1',
- human_access: 'Owner',
- path: '/gitlab-org/gitlab-shell/notes/905',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- reply_id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- expanded: true,
- notes: [
- {
- id: '906',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:20:02.925Z',
- updated_at: '2018-05-29T12:20:02.925Z',
- system: true,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- system_note_icon_name: 'pencil-square',
- discussion_id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- emoji_awardable: false,
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_906&user_id=1',
- human_access: 'Owner',
- path: '/gitlab-org/gitlab-shell/notes/906',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
-];
-
-export const collapsedSystemNotes = [
- {
- id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- reply_id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- expanded: true,
- notes: [
- {
- id: '901',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:05:36.117Z',
- updated_at: '2018-05-29T12:05:36.117Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
- note_html:
- '<p dir="auto">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '39b271c2033e9ed43d8edb393702f65f7a830459',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_901&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/901/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/901',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- reply_id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- expanded: true,
- notes: [
- {
- id: '902',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:05:58.694Z',
- updated_at: '2018-05-29T12:05:58.694Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note:
- 'Varius vel pharetra vel turpis nunc eget lorem. Ipsum dolor sit amet consectetur adipiscing.',
- note_html:
- '<p dir="auto">Varius vel pharetra vel turpis nunc eget lorem. Ipsum dolor sit amet consectetur adipiscing.</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '4852335d7dc40b9ceb8fde1a2bb9c1b67e4c7795',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_902&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/902/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/902',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- reply_id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- expanded: true,
- notes: [
- {
- id: '904',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:06:16.112Z',
- updated_at: '2018-05-29T12:06:16.112Z',
- system: false,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'Ullamcorper eget nulla facilisi etiam',
- note_html: '<p dir="auto">Ullamcorper eget nulla facilisi etiam</p>',
- current_user: { can_edit: true, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- discussion_id: '091865fe3ae20f0045234a3d103e3b15e73405b5',
- emoji_awardable: true,
- award_emoji: [],
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_904&user_id=1',
- human_access: 'Owner',
- toggle_award_path: '/gitlab-org/gitlab-shell/notes/904/toggle_award_emoji',
- path: '/gitlab-org/gitlab-shell/notes/904',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- reply_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- expanded: true,
- notes: [
- {
- id: '905',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:06:28.851Z',
- updated_at: '2018-05-29T12:06:28.851Z',
- system: true,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'changed the description',
- note_html: ' <p dir="auto">changed the description 2 times within 1 minute </p>',
- current_user: { can_edit: false, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- system_note_icon_name: 'pencil-square',
- discussion_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044',
- emoji_awardable: false,
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_905&user_id=1',
- human_access: 'Owner',
- path: '/gitlab-org/gitlab-shell/notes/905',
- times_updated: 2,
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
- {
- id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- reply_id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- expanded: true,
- notes: [
- {
- id: '906',
- type: null,
- attachment: null,
- author: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- created_at: '2018-05-29T12:20:02.925Z',
- updated_at: '2018-05-29T12:20:02.925Z',
- system: true,
- noteable_id: 182,
- noteable_type: 'Issue',
- resolvable: false,
- noteable_iid: 12,
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- current_user: { can_edit: false, can_award_emoji: true },
- resolved: false,
- resolved_by: null,
- system_note_icon_name: 'pencil-square',
- discussion_id: '70411b08cdfc01f24187a06d77daa33464cb2620',
- emoji_awardable: false,
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-shell%2Fissues%2F12%23note_906&user_id=1',
- human_access: 'Owner',
- path: '/gitlab-org/gitlab-shell/notes/906',
- },
- ],
- individual_note: true,
- resolvable: false,
- resolved: false,
- diff_discussion: false,
- },
-];
-
-export const discussion1 = {
- id: 'abc1',
- resolvable: true,
- resolved: false,
- active: true,
- diff_file: {
- file_path: 'about.md',
- },
- position: {
- new_line: 50,
- old_line: null,
- },
- notes: [
- {
- created_at: '2018-07-04T16:25:41.749Z',
- },
- ],
-};
-
-export const resolvedDiscussion1 = {
- id: 'abc1',
- resolvable: true,
- resolved: true,
- diff_file: {
- file_path: 'about.md',
- },
- position: {
- new_line: 50,
- old_line: null,
- },
- notes: [
- {
- created_at: '2018-07-04T16:25:41.749Z',
- },
- ],
-};
-
-export const discussion2 = {
- id: 'abc2',
- resolvable: true,
- resolved: false,
- active: true,
- diff_file: {
- file_path: 'README.md',
- },
- position: {
- new_line: null,
- old_line: 20,
- },
- notes: [
- {
- created_at: '2018-07-04T12:05:41.749Z',
- },
- ],
-};
-
-export const discussion3 = {
- id: 'abc3',
- resolvable: true,
- active: true,
- resolved: false,
- diff_file: {
- file_path: 'README.md',
- },
- position: {
- new_line: 21,
- old_line: null,
- },
- notes: [
- {
- created_at: '2018-07-05T17:25:41.749Z',
- },
- ],
-};
-
-export const unresolvableDiscussion = {
- resolvable: false,
-};
-
-export const discussionFiltersMock = [
- {
- title: 'Show all activity',
- value: 0,
- },
- {
- title: 'Show comments only',
- value: 1,
- },
- {
- title: 'Show system notes only',
- value: 2,
- },
-];
+export * from '../../frontend/notes/mock_data.js';
diff --git a/spec/javascripts/notes/stores/collapse_utils_spec.js b/spec/javascripts/notes/stores/collapse_utils_spec.js
index 8ede9319088..d3019f4b9a4 100644
--- a/spec/javascripts/notes/stores/collapse_utils_spec.js
+++ b/spec/javascripts/notes/stores/collapse_utils_spec.js
@@ -1,6 +1,5 @@
import {
isDescriptionSystemNote,
- changeDescriptionNote,
getTimeDifferenceMinutes,
collapseSystemNotes,
} from '~/notes/stores/collapse_utils';
@@ -24,15 +23,6 @@ describe('Collapse utils', () => {
);
});
- it('changes the description to contain the number of changed times', () => {
- const changedNote = changeDescriptionNote(mockSystemNote, 3, 5);
-
- expect(changedNote.times_updated).toEqual(3);
- expect(changedNote.note_html.trim()).toContain(
- '<p dir="auto">changed the description 3 times within 5 minutes </p>',
- );
- });
-
it('gets the time difference between two notes', () => {
const anotherSystemNote = {
created_at: '2018-05-14T21:33:00.000Z',
diff --git a/spec/javascripts/pipelines/graph/action_component_spec.js b/spec/javascripts/pipelines/graph/action_component_spec.js
deleted file mode 100644
index 321497b35b5..00000000000
--- a/spec/javascripts/pipelines/graph/action_component_spec.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import actionComponent from '~/pipelines/components/graph/action_component.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
-describe('pipeline graph action component', () => {
- let component;
- let mock;
-
- beforeEach(done => {
- const ActionComponent = Vue.extend(actionComponent);
- mock = new MockAdapter(axios);
-
- mock.onPost('foo.json').reply(200);
-
- component = mountComponent(ActionComponent, {
- tooltipText: 'bar',
- link: 'foo',
- actionIcon: 'cancel',
- });
-
- Vue.nextTick(done);
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- it('should render the provided title as a bootstrap tooltip', () => {
- expect(component.$el.getAttribute('data-original-title')).toEqual('bar');
- });
-
- it('should update bootstrap tooltip when title changes', done => {
- component.tooltipText = 'changed';
-
- component
- .$nextTick()
- .then(() => {
- expect(component.$el.getAttribute('data-original-title')).toBe('changed');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('should render an svg', () => {
- expect(component.$el.querySelector('.ci-action-icon-wrapper')).toBeDefined();
- expect(component.$el.querySelector('svg')).toBeDefined();
- });
-
- describe('on click', () => {
- it('emits `pipelineActionRequestComplete` after a successful request', done => {
- spyOn(component, '$emit');
-
- component.$el.click();
-
- setTimeout(() => {
- component
- .$nextTick()
- .then(() => {
- expect(component.$emit).toHaveBeenCalledWith('pipelineActionRequestComplete');
- })
- .catch(done.fail);
-
- done();
- }, 0);
- });
-
- it('renders a loading icon while waiting for request', done => {
- component.$el.click();
-
- component.$nextTick(() => {
- expect(component.$el.querySelector('.js-action-icon-loading')).not.toBeNull();
- setTimeout(() => {
- done();
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/pipelines/pipeline_triggerer_spec.js b/spec/javascripts/pipelines/pipeline_triggerer_spec.js
deleted file mode 100644
index 8cf290f2663..00000000000
--- a/spec/javascripts/pipelines/pipeline_triggerer_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { mount } from '@vue/test-utils';
-import pipelineTriggerer from '~/pipelines/components/pipeline_triggerer.vue';
-
-describe('Pipelines Triggerer', () => {
- let wrapper;
-
- const mockData = {
- pipeline: {
- user: {
- name: 'foo',
- avatar_url: '/avatar',
- path: '/path',
- },
- },
- };
-
- const createComponent = () => {
- wrapper = mount(pipelineTriggerer, {
- propsData: mockData,
- });
- };
-
- beforeEach(() => {
- createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should render a table cell', () => {
- expect(wrapper.contains('.table-section')).toBe(true);
- });
-
- it('should render triggerer information when triggerer is provided', () => {
- const link = wrapper.find('.js-pipeline-url-user');
-
- expect(link.attributes('href')).toEqual(mockData.pipeline.user.path);
- expect(link.find('.js-user-avatar-image-toolip').text()).toEqual(mockData.pipeline.user.name);
- expect(link.find('img.avatar').attributes('src')).toEqual(
- `${mockData.pipeline.user.avatar_url}?width=26`,
- );
- });
-
- it('should render "API" when no triggerer is provided', () => {
- wrapper.setProps({
- pipeline: {
- user: null,
- },
- });
-
- expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
- });
-});
diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js
deleted file mode 100644
index d47504d2f54..00000000000
--- a/spec/javascripts/pipelines/pipelines_table_row_spec.js
+++ /dev/null
@@ -1,218 +0,0 @@
-import Vue from 'vue';
-import tableRowComp from '~/pipelines/components/pipelines_table_row.vue';
-import eventHub from '~/pipelines/event_hub';
-
-describe('Pipelines Table Row', () => {
- const jsonFixtureName = 'pipelines/pipelines.json';
- const buildComponent = pipeline => {
- const PipelinesTableRowComponent = Vue.extend(tableRowComp);
- return new PipelinesTableRowComponent({
- el: document.querySelector('.test-dom-element'),
- propsData: {
- pipeline,
- autoDevopsHelpPath: 'foo',
- viewType: 'root',
- },
- }).$mount();
- };
-
- let component;
- let pipeline;
- let pipelineWithoutAuthor;
- let pipelineWithoutCommit;
-
- preloadFixtures(jsonFixtureName);
-
- beforeEach(() => {
- const { pipelines } = getJSONFixture(jsonFixtureName);
-
- pipeline = pipelines.find(p => p.user !== null && p.commit !== null);
- pipelineWithoutAuthor = pipelines.find(p => p.user === null && p.commit !== null);
- pipelineWithoutCommit = pipelines.find(p => p.user === null && p.commit === null);
- });
-
- afterEach(() => {
- component.$destroy();
- });
-
- it('should render a table row', () => {
- component = buildComponent(pipeline);
-
- expect(component.$el.getAttribute('class')).toContain('gl-responsive-table-row');
- });
-
- describe('status column', () => {
- beforeEach(() => {
- component = buildComponent(pipeline);
- });
-
- it('should render a pipeline link', () => {
- expect(
- component.$el.querySelector('.table-section.commit-link a').getAttribute('href'),
- ).toEqual(pipeline.path);
- });
-
- it('should render status text', () => {
- expect(component.$el.querySelector('.table-section.commit-link a').textContent).toContain(
- pipeline.details.status.text,
- );
- });
- });
-
- describe('information column', () => {
- beforeEach(() => {
- component = buildComponent(pipeline);
- });
-
- it('should render a pipeline link', () => {
- expect(
- component.$el.querySelector('.table-section:nth-child(2) a').getAttribute('href'),
- ).toEqual(pipeline.path);
- });
-
- it('should render pipeline ID', () => {
- expect(
- component.$el.querySelector('.table-section:nth-child(2) a > span').textContent,
- ).toEqual(`#${pipeline.id}`);
- });
-
- describe('when a user is provided', () => {
- it('should render user information', () => {
- expect(
- component.$el
- .querySelector('.table-section:nth-child(3) .js-pipeline-url-user')
- .getAttribute('href'),
- ).toEqual(pipeline.user.path);
-
- expect(
- component.$el
- .querySelector('.table-section:nth-child(3) .js-user-avatar-image-toolip')
- .textContent.trim(),
- ).toEqual(pipeline.user.name);
- });
- });
- });
-
- describe('commit column', () => {
- it('should render link to commit', () => {
- component = buildComponent(pipeline);
-
- const commitLink = component.$el.querySelector('.branch-commit .commit-sha');
-
- expect(commitLink.getAttribute('href')).toEqual(pipeline.commit.commit_path);
- });
-
- const findElements = () => {
- const commitTitleElement = component.$el.querySelector('.branch-commit .commit-title');
- const commitAuthorElement = commitTitleElement.querySelector('a.avatar-image-container');
-
- if (!commitAuthorElement) {
- return { commitAuthorElement };
- }
-
- const commitAuthorLink = commitAuthorElement.getAttribute('href');
- const commitAuthorName = commitAuthorElement
- .querySelector('.js-user-avatar-image-toolip')
- .textContent.trim();
-
- return { commitAuthorElement, commitAuthorLink, commitAuthorName };
- };
-
- it('renders nothing without commit', () => {
- expect(pipelineWithoutCommit.commit).toBe(null);
- component = buildComponent(pipelineWithoutCommit);
-
- const { commitAuthorElement } = findElements();
-
- expect(commitAuthorElement).toBe(null);
- });
-
- it('renders commit author', () => {
- component = buildComponent(pipeline);
- const { commitAuthorLink, commitAuthorName } = findElements();
-
- expect(commitAuthorLink).toEqual(pipeline.commit.author.path);
- expect(commitAuthorName).toEqual(pipeline.commit.author.username);
- });
-
- it('renders commit with unregistered author', () => {
- expect(pipelineWithoutAuthor.commit.author).toBe(null);
- component = buildComponent(pipelineWithoutAuthor);
-
- const { commitAuthorLink, commitAuthorName } = findElements();
-
- expect(commitAuthorLink).toEqual(`mailto:${pipelineWithoutAuthor.commit.author_email}`);
- expect(commitAuthorName).toEqual(pipelineWithoutAuthor.commit.author_name);
- });
- });
-
- describe('stages column', () => {
- beforeEach(() => {
- component = buildComponent(pipeline);
- });
-
- it('should render an icon for each stage', () => {
- expect(
- component.$el.querySelectorAll('.table-section:nth-child(4) .js-builds-dropdown-button')
- .length,
- ).toEqual(pipeline.details.stages.length);
- });
- });
-
- describe('actions column', () => {
- const scheduledJobAction = {
- name: 'some scheduled job',
- };
-
- beforeEach(() => {
- const withActions = Object.assign({}, pipeline);
- withActions.details.scheduled_actions = [scheduledJobAction];
- withActions.flags.cancelable = true;
- withActions.flags.retryable = true;
- withActions.cancel_path = '/cancel';
- withActions.retry_path = '/retry';
-
- component = buildComponent(withActions);
- });
-
- it('should render the provided actions', () => {
- expect(component.$el.querySelector('.js-pipelines-retry-button')).not.toBeNull();
- expect(component.$el.querySelector('.js-pipelines-cancel-button')).not.toBeNull();
- const dropdownMenu = component.$el.querySelectorAll('.dropdown-menu');
-
- expect(dropdownMenu).toContainText(scheduledJobAction.name);
- });
-
- it('emits `retryPipeline` event when retry button is clicked and toggles loading', () => {
- eventHub.$on('retryPipeline', endpoint => {
- expect(endpoint).toEqual('/retry');
- });
-
- component.$el.querySelector('.js-pipelines-retry-button').click();
-
- expect(component.isRetrying).toEqual(true);
- });
-
- it('emits `openConfirmationModal` event when cancel button is clicked and toggles loading', () => {
- eventHub.$once('openConfirmationModal', data => {
- const { id, ref, commit } = pipeline;
-
- expect(data.endpoint).toEqual('/cancel');
- expect(data.pipeline).toEqual(jasmine.objectContaining({ id, ref, commit }));
- });
-
- component.$el.querySelector('.js-pipelines-cancel-button').click();
- });
-
- it('renders a loading icon when `cancelingPipeline` matches pipeline id', done => {
- component.cancelingPipeline = pipeline.id;
- component
- .$nextTick()
- .then(() => {
- expect(component.isCancelling).toEqual(true);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/raven/index_spec.js b/spec/javascripts/raven/index_spec.js
deleted file mode 100644
index 6b9fe923624..00000000000
--- a/spec/javascripts/raven/index_spec.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import RavenConfig from '~/raven/raven_config';
-import index from '~/raven/index';
-
-describe('RavenConfig options', () => {
- const sentryDsn = 'sentryDsn';
- const currentUserId = 'currentUserId';
- const gitlabUrl = 'gitlabUrl';
- const environment = 'test';
- const revision = 'revision';
- let indexReturnValue;
-
- beforeEach(() => {
- window.gon = {
- sentry_dsn: sentryDsn,
- sentry_environment: environment,
- current_user_id: currentUserId,
- gitlab_url: gitlabUrl,
- revision,
- };
-
- process.env.HEAD_COMMIT_SHA = revision;
-
- spyOn(RavenConfig, 'init');
-
- indexReturnValue = index();
- });
-
- it('should init with .sentryDsn, .currentUserId, .whitelistUrls and environment', () => {
- expect(RavenConfig.init).toHaveBeenCalledWith({
- sentryDsn,
- currentUserId,
- whitelistUrls: [gitlabUrl, 'webpack-internal://'],
- environment,
- release: revision,
- tags: {
- revision,
- },
- });
- });
-
- it('should return RavenConfig', () => {
- expect(indexReturnValue).toBe(RavenConfig);
- });
-});
diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js
deleted file mode 100644
index af634a0c196..00000000000
--- a/spec/javascripts/raven/raven_config_spec.js
+++ /dev/null
@@ -1,254 +0,0 @@
-import Raven from 'raven-js';
-import RavenConfig from '~/raven/raven_config';
-
-describe('RavenConfig', () => {
- describe('IGNORE_ERRORS', () => {
- it('should be an array of strings', () => {
- const areStrings = RavenConfig.IGNORE_ERRORS.every(error => typeof error === 'string');
-
- expect(areStrings).toBe(true);
- });
- });
-
- describe('IGNORE_URLS', () => {
- it('should be an array of regexps', () => {
- const areRegExps = RavenConfig.IGNORE_URLS.every(url => url instanceof RegExp);
-
- expect(areRegExps).toBe(true);
- });
- });
-
- describe('SAMPLE_RATE', () => {
- it('should be a finite number', () => {
- expect(typeof RavenConfig.SAMPLE_RATE).toEqual('number');
- });
- });
-
- describe('init', () => {
- const options = {
- currentUserId: 1,
- };
-
- beforeEach(() => {
- spyOn(RavenConfig, 'configure');
- spyOn(RavenConfig, 'bindRavenErrors');
- spyOn(RavenConfig, 'setUser');
-
- RavenConfig.init(options);
- });
-
- it('should set the options property', () => {
- expect(RavenConfig.options).toEqual(options);
- });
-
- it('should call the configure method', () => {
- expect(RavenConfig.configure).toHaveBeenCalled();
- });
-
- it('should call the error bindings method', () => {
- expect(RavenConfig.bindRavenErrors).toHaveBeenCalled();
- });
-
- it('should call setUser', () => {
- expect(RavenConfig.setUser).toHaveBeenCalled();
- });
-
- it('should not call setUser if there is no current user ID', () => {
- RavenConfig.setUser.calls.reset();
-
- options.currentUserId = undefined;
-
- RavenConfig.init(options);
-
- expect(RavenConfig.setUser).not.toHaveBeenCalled();
- });
- });
-
- describe('configure', () => {
- let raven;
- let ravenConfig;
- const options = {
- sentryDsn: '//sentryDsn',
- whitelistUrls: ['//gitlabUrl', 'webpack-internal://'],
- environment: 'test',
- release: 'revision',
- tags: {
- revision: 'revision',
- },
- };
-
- beforeEach(() => {
- ravenConfig = jasmine.createSpyObj('ravenConfig', ['shouldSendSample']);
- raven = jasmine.createSpyObj('raven', ['install']);
-
- spyOn(Raven, 'config').and.returnValue(raven);
-
- ravenConfig.options = options;
- ravenConfig.IGNORE_ERRORS = 'ignore_errors';
- ravenConfig.IGNORE_URLS = 'ignore_urls';
-
- RavenConfig.configure.call(ravenConfig);
- });
-
- it('should call Raven.config', () => {
- expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, {
- release: options.release,
- tags: options.tags,
- whitelistUrls: options.whitelistUrls,
- environment: 'test',
- ignoreErrors: ravenConfig.IGNORE_ERRORS,
- ignoreUrls: ravenConfig.IGNORE_URLS,
- shouldSendCallback: jasmine.any(Function),
- });
- });
-
- it('should call Raven.install', () => {
- expect(raven.install).toHaveBeenCalled();
- });
-
- it('should set environment from options', () => {
- ravenConfig.options.environment = 'development';
-
- RavenConfig.configure.call(ravenConfig);
-
- expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, {
- release: options.release,
- tags: options.tags,
- whitelistUrls: options.whitelistUrls,
- environment: 'development',
- ignoreErrors: ravenConfig.IGNORE_ERRORS,
- ignoreUrls: ravenConfig.IGNORE_URLS,
- shouldSendCallback: jasmine.any(Function),
- });
- });
- });
-
- describe('setUser', () => {
- let ravenConfig;
-
- beforeEach(() => {
- ravenConfig = { options: { currentUserId: 1 } };
- spyOn(Raven, 'setUserContext');
-
- RavenConfig.setUser.call(ravenConfig);
- });
-
- it('should call .setUserContext', function() {
- expect(Raven.setUserContext).toHaveBeenCalledWith({
- id: ravenConfig.options.currentUserId,
- });
- });
- });
-
- describe('handleRavenErrors', () => {
- let event;
- let req;
- let config;
- let err;
-
- beforeEach(() => {
- event = {};
- req = { status: 'status', responseText: 'responseText', statusText: 'statusText' };
- config = { type: 'type', url: 'url', data: 'data' };
- err = {};
-
- spyOn(Raven, 'captureMessage');
-
- RavenConfig.handleRavenErrors(event, req, config, err);
- });
-
- it('should call Raven.captureMessage', () => {
- expect(Raven.captureMessage).toHaveBeenCalledWith(err, {
- extra: {
- type: config.type,
- url: config.url,
- data: config.data,
- status: req.status,
- response: req.responseText,
- error: err,
- event,
- },
- });
- });
-
- describe('if no err is provided', () => {
- beforeEach(() => {
- Raven.captureMessage.calls.reset();
-
- RavenConfig.handleRavenErrors(event, req, config);
- });
-
- it('should use req.statusText as the error value', () => {
- expect(Raven.captureMessage).toHaveBeenCalledWith(req.statusText, {
- extra: {
- type: config.type,
- url: config.url,
- data: config.data,
- status: req.status,
- response: req.responseText,
- error: req.statusText,
- event,
- },
- });
- });
- });
-
- describe('if no req.responseText is provided', () => {
- beforeEach(() => {
- req.responseText = undefined;
-
- Raven.captureMessage.calls.reset();
-
- RavenConfig.handleRavenErrors(event, req, config, err);
- });
-
- it('should use `Unknown response text` as the response', () => {
- expect(Raven.captureMessage).toHaveBeenCalledWith(err, {
- extra: {
- type: config.type,
- url: config.url,
- data: config.data,
- status: req.status,
- response: 'Unknown response text',
- error: err,
- event,
- },
- });
- });
- });
- });
-
- describe('shouldSendSample', () => {
- let randomNumber;
-
- beforeEach(() => {
- RavenConfig.SAMPLE_RATE = 50;
-
- spyOn(Math, 'random').and.callFake(() => randomNumber);
- });
-
- it('should call Math.random', () => {
- RavenConfig.shouldSendSample();
-
- expect(Math.random).toHaveBeenCalled();
- });
-
- it('should return true if the sample rate is greater than the random number * 100', () => {
- randomNumber = 0.1;
-
- expect(RavenConfig.shouldSendSample()).toBe(true);
- });
-
- it('should return false if the sample rate is less than the random number * 100', () => {
- randomNumber = 0.9;
-
- expect(RavenConfig.shouldSendSample()).toBe(false);
- });
-
- it('should return true if the sample rate is equal to the random number * 100', () => {
- randomNumber = 0.5;
-
- expect(RavenConfig.shouldSendSample()).toBe(true);
- });
- });
-});
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index 9702cb56d99..1798f9962e2 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -1,4 +1,4 @@
-/* eslint-disable no-var, one-var, no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign, vars-on-top */
+/* eslint-disable no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign */
import $ from 'jquery';
import '~/gl_dropdown';
@@ -6,41 +6,27 @@ import initSearchAutocomplete from '~/search_autocomplete';
import '~/lib/utils/common_utils';
describe('Search autocomplete dropdown', () => {
- var assertLinks,
- dashboardIssuesPath,
- dashboardMRsPath,
- groupIssuesPath,
- groupMRsPath,
- groupName,
- mockDashboardOptions,
- mockGroupOptions,
- mockProjectOptions,
- projectIssuesPath,
- projectMRsPath,
- projectName,
- userId,
- widget;
- var userName = 'root';
+ let widget = null;
- widget = null;
+ const userName = 'root';
- userId = 1;
+ const userId = 1;
- dashboardIssuesPath = '/dashboard/issues';
+ const dashboardIssuesPath = '/dashboard/issues';
- dashboardMRsPath = '/dashboard/merge_requests';
+ const dashboardMRsPath = '/dashboard/merge_requests';
- projectIssuesPath = '/gitlab-org/gitlab-foss/issues';
+ const projectIssuesPath = '/gitlab-org/gitlab-foss/issues';
- projectMRsPath = '/gitlab-org/gitlab-foss/merge_requests';
+ const projectMRsPath = '/gitlab-org/gitlab-foss/merge_requests';
- groupIssuesPath = '/groups/gitlab-org/issues';
+ const groupIssuesPath = '/groups/gitlab-org/issues';
- groupMRsPath = '/groups/gitlab-org/merge_requests';
+ const groupMRsPath = '/groups/gitlab-org/merge_requests';
- projectName = 'GitLab Community Edition';
+ const projectName = 'GitLab Community Edition';
- groupName = 'Gitlab Org';
+ const groupName = 'Gitlab Org';
const removeBodyAttributes = function() {
const $body = $('body');
@@ -76,7 +62,7 @@ describe('Search autocomplete dropdown', () => {
};
// Mock `gl` object in window for dashboard specific page. App code will need it.
- mockDashboardOptions = function() {
+ const mockDashboardOptions = function() {
window.gl || (window.gl = {});
return (window.gl.dashboardOptions = {
issuesPath: dashboardIssuesPath,
@@ -85,7 +71,7 @@ describe('Search autocomplete dropdown', () => {
};
// Mock `gl` object in window for project specific page. App code will need it.
- mockProjectOptions = function() {
+ const mockProjectOptions = function() {
window.gl || (window.gl = {});
return (window.gl.projectOptions = {
'gitlab-ce': {
@@ -96,7 +82,7 @@ describe('Search autocomplete dropdown', () => {
});
};
- mockGroupOptions = function() {
+ const mockGroupOptions = function() {
window.gl || (window.gl = {});
return (window.gl.groupOptions = {
'gitlab-org': {
@@ -107,7 +93,7 @@ describe('Search autocomplete dropdown', () => {
});
};
- assertLinks = function(list, issuesPath, mrsPath) {
+ const assertLinks = function(list, issuesPath, mrsPath) {
if (issuesPath) {
const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_username=${userName}"]`;
const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_username=${userName}"]`;
@@ -144,29 +130,26 @@ describe('Search autocomplete dropdown', () => {
});
it('should show Dashboard specific dropdown menu', function() {
- var list;
addBodyAttributes();
mockDashboardOptions();
widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
});
it('should show Group specific dropdown menu', function() {
- var list;
addBodyAttributes('group');
mockGroupOptions();
widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, groupIssuesPath, groupMRsPath);
});
it('should show Project specific dropdown menu', function() {
- var list;
addBodyAttributes('project');
mockProjectOptions();
widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, projectIssuesPath, projectMRsPath);
});
@@ -180,26 +163,25 @@ describe('Search autocomplete dropdown', () => {
});
it('should not show category related menu if there is text in the input', function() {
- var link, list;
addBodyAttributes('project');
mockProjectOptions();
widget.searchInput.val('help');
widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
- link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`;
+ const list = widget.wrap.find('.dropdown-menu').find('ul');
+ const link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`;
expect(list.find(link).length).toBe(0);
});
it('should not submit the search form when selecting an autocomplete row with the keyboard', function() {
- var ENTER = 13;
- var DOWN = 40;
+ const ENTER = 13;
+ const DOWN = 40;
addBodyAttributes();
mockDashboardOptions(true);
- var submitSpy = spyOnEvent('form', 'submit');
+ const submitSpy = spyOnEvent('form', 'submit');
widget.searchInput.triggerHandler('focus');
widget.wrap.trigger($.Event('keydown', { which: DOWN }));
- var enterKeyEvent = $.Event('keydown', { which: ENTER });
+ const enterKeyEvent = $.Event('keydown', { which: ENTER });
widget.searchInput.trigger(enterKeyEvent);
// This does not currently catch failing behavior. For security reasons,
// browsers will not trigger default behavior (form submit, in this
diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js
index a97608d6b8a..1256852c472 100644
--- a/spec/javascripts/sidebar/subscriptions_spec.js
+++ b/spec/javascripts/sidebar/subscriptions_spec.js
@@ -76,4 +76,25 @@ describe('Subscriptions', function() {
expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar');
});
+
+ describe('given project emails are disabled', () => {
+ const subscribeDisabledDescription = 'Notifications have been disabled';
+
+ beforeEach(() => {
+ vm = mountComponent(Subscriptions, {
+ subscribed: false,
+ projectEmailsDisabled: true,
+ subscribeDisabledDescription,
+ });
+ });
+
+ it('sets the correct display text', () => {
+ expect(vm.$el.textContent).toContain(subscribeDisabledDescription);
+ expect(vm.$refs.tooltip.dataset.originalTitle).toBe(subscribeDisabledDescription);
+ });
+
+ it('does not render the toggle button', () => {
+ expect(vm.$refs.toggleButton).toBeUndefined();
+ });
+ });
});
diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js b/spec/javascripts/signin_tabs_memoizer_spec.js
index ef5c774736b..966ae55ce14 100644
--- a/spec/javascripts/signin_tabs_memoizer_spec.js
+++ b/spec/javascripts/signin_tabs_memoizer_spec.js
@@ -1,5 +1,7 @@
import AccessorUtilities from '~/lib/utils/accessor';
import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
+import trackData from '~/pages/sessions/new/index';
+import Tracking from '~/tracking';
describe('SigninTabsMemoizer', () => {
const fixtureTemplate = 'static/signin_tabs.html';
@@ -93,6 +95,50 @@ describe('SigninTabsMemoizer', () => {
});
});
+ describe('trackData', () => {
+ beforeEach(() => {
+ spyOn(Tracking, 'event');
+ });
+
+ describe('with tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = {
+ category: 'Growth::Acquisition::Experiment::SignUpFlow',
+ action: 'start',
+ label: 'uuid',
+ property: 'control_group',
+ };
+ trackData();
+ });
+
+ it('should track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).toHaveBeenCalledWith(
+ 'Growth::Acquisition::Experiment::SignUpFlow',
+ 'start',
+ {
+ label: 'uuid',
+ property: 'control_group',
+ },
+ );
+ });
+ });
+
+ describe('without tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = undefined;
+ trackData();
+ });
+
+ it('should not track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).not.toHaveBeenCalled();
+ });
+ });
+ });
+
describe('saveData', () => {
beforeEach(() => {
memo = {
diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js
index 5438368ccbe..99c47fa31d4 100644
--- a/spec/javascripts/syntax_highlight_spec.js
+++ b/spec/javascripts/syntax_highlight_spec.js
@@ -1,11 +1,10 @@
-/* eslint-disable no-var, no-return-assign */
+/* eslint-disable no-return-assign */
import $ from 'jquery';
import syntaxHighlight from '~/syntax_highlight';
describe('Syntax Highlighter', function() {
- var stubUserColorScheme;
- stubUserColorScheme = function(value) {
+ const stubUserColorScheme = function(value) {
if (window.gon == null) {
window.gon = {};
}
@@ -40,9 +39,8 @@ describe('Syntax Highlighter', function() {
});
it('prevents an infinite loop when no matches exist', function() {
- var highlight;
setFixtures('<div></div>');
- highlight = function() {
+ const highlight = function() {
return syntaxHighlight($('div'));
};
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
index cb6b158f01c..859745ee9fc 100644
--- a/spec/javascripts/test_bundle.js
+++ b/spec/javascripts/test_bundle.js
@@ -171,38 +171,7 @@ describe('test errors', () => {
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
// exempt these files from the coverage report
- const troubleMakers = [
- './blob_edit/blob_bundle.js',
- './boards/components/modal/empty_state.vue',
- './boards/components/modal/footer.js',
- './boards/components/modal/header.js',
- './cycle_analytics/cycle_analytics_bundle.js',
- './cycle_analytics/components/stage_plan_component.js',
- './cycle_analytics/components/stage_staging_component.js',
- './cycle_analytics/components/stage_test_component.js',
- './commit/pipelines/pipelines_bundle.js',
- './diff_notes/diff_notes_bundle.js',
- './diff_notes/components/jump_to_discussion.js',
- './diff_notes/components/resolve_count.js',
- './dispatcher.js',
- './environments/environments_bundle.js',
- './graphs/graphs_bundle.js',
- './issuable/time_tracking/time_tracking_bundle.js',
- './main.js',
- './merge_conflicts/merge_conflicts_bundle.js',
- './merge_conflicts/components/inline_conflict_lines.js',
- './merge_conflicts/components/parallel_conflict_lines.js',
- './monitoring/monitoring_bundle.js',
- './network/network_bundle.js',
- './network/branch_graph.js',
- './profile/profile_bundle.js',
- './protected_branches/protected_branches_bundle.js',
- './snippet/snippet_bundle.js',
- './terminal/terminal_bundle.js',
- './users/users_bundle.js',
- './issue_show/index.js',
- './pages/admin/application_settings/general/index.js',
- ];
+ const troubleMakers = ['./pages/admin/application_settings/general/index.js'];
describe('Uncovered files', function() {
const sourceFilesContexts = [require.context('~', true, /\.(js|vue)$/)];
diff --git a/spec/javascripts/u2f/mock_u2f_device.js b/spec/javascripts/u2f/mock_u2f_device.js
index 26ddd8ade61..ec8425a4e3e 100644
--- a/spec/javascripts/u2f/mock_u2f_device.js
+++ b/spec/javascripts/u2f/mock_u2f_device.js
@@ -1,20 +1,16 @@
-/* eslint-disable no-unused-expressions, no-return-assign, no-param-reassign */
+/* eslint-disable no-unused-expressions */
export default class MockU2FDevice {
constructor() {
this.respondToAuthenticateRequest = this.respondToAuthenticateRequest.bind(this);
this.respondToRegisterRequest = this.respondToRegisterRequest.bind(this);
window.u2f || (window.u2f = {});
- window.u2f.register = (function(_this) {
- return function(appId, registerRequests, signRequests, callback) {
- return (_this.registerCallback = callback);
- };
- })(this);
- window.u2f.sign = (function(_this) {
- return function(appId, challenges, signRequests, callback) {
- return (_this.authenticateCallback = callback);
- };
- })(this);
+ window.u2f.register = (appId, registerRequests, signRequests, callback) => {
+ this.registerCallback = callback;
+ };
+ window.u2f.sign = (appId, challenges, signRequests, callback) => {
+ this.authenticateCallback = callback;
+ };
}
respondToRegisterRequest(params) {
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js
deleted file mode 100644
index f89627e727b..00000000000
--- a/spec/javascripts/vue_shared/components/commit_spec.js
+++ /dev/null
@@ -1,234 +0,0 @@
-import Vue from 'vue';
-import commitComp from '~/vue_shared/components/commit.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
-describe('Commit component', () => {
- let props;
- let component;
- let CommitComponent;
-
- beforeEach(() => {
- CommitComponent = Vue.extend(commitComp);
- });
-
- afterEach(() => {
- component.$destroy();
- });
-
- it('should render a fork icon if it does not represent a tag', () => {
- component = mountComponent(CommitComponent, {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- shortSha: 'b7836edd',
- title: 'Commit message',
- author: {
- avatar_url: 'https://gitlab.com/uploads/-/system/user/avatar/300478/avatar.png',
- web_url: 'https://gitlab.com/jschatz1',
- path: '/jschatz1',
- username: 'jschatz1',
- },
- });
-
- expect(component.$el.querySelector('.icon-container').children).toContain('svg');
- });
-
- describe('Given all the props', () => {
- beforeEach(() => {
- props = {
- tag: true,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- shortSha: 'b7836edd',
- title: 'Commit message',
- author: {
- avatar_url: 'https://gitlab.com/uploads/-/system/user/avatar/300478/avatar.png',
- web_url: 'https://gitlab.com/jschatz1',
- path: '/jschatz1',
- username: 'jschatz1',
- },
- };
-
- component = mountComponent(CommitComponent, props);
- });
-
- it('should render a tag icon if it represents a tag', () => {
- expect(component.$el.querySelector('.icon-container svg.ic-tag')).not.toBeNull();
- });
-
- it('should render a link to the ref url', () => {
- expect(component.$el.querySelector('.ref-name').getAttribute('href')).toEqual(
- props.commitRef.ref_url,
- );
- });
-
- it('should render the ref name', () => {
- expect(component.$el.querySelector('.ref-name').textContent).toContain(props.commitRef.name);
- });
-
- it('should render the commit short sha with a link to the commit url', () => {
- expect(component.$el.querySelector('.commit-sha').getAttribute('href')).toEqual(
- props.commitUrl,
- );
-
- expect(component.$el.querySelector('.commit-sha').textContent).toContain(props.shortSha);
- });
-
- it('should render icon for commit', () => {
- expect(
- component.$el.querySelector('.js-commit-icon use').getAttribute('xlink:href'),
- ).toContain('commit');
- });
-
- describe('Given commit title and author props', () => {
- it('should render a link to the author profile', () => {
- expect(
- component.$el.querySelector('.commit-title .avatar-image-container').getAttribute('href'),
- ).toEqual(props.author.path);
- });
-
- it('Should render the author avatar with title and alt attributes', () => {
- expect(
- component.$el
- .querySelector('.commit-title .avatar-image-container .js-user-avatar-image-toolip')
- .textContent.trim(),
- ).toContain(props.author.username);
-
- expect(
- component.$el
- .querySelector('.commit-title .avatar-image-container img')
- .getAttribute('alt'),
- ).toContain(`${props.author.username}'s avatar`);
- });
- });
-
- it('should render the commit title', () => {
- expect(component.$el.querySelector('a.commit-row-message').getAttribute('href')).toEqual(
- props.commitUrl,
- );
-
- expect(component.$el.querySelector('a.commit-row-message').textContent).toContain(
- props.title,
- );
- });
- });
-
- describe('When commit title is not provided', () => {
- it('should render default message', () => {
- props = {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- shortSha: 'b7836edd',
- title: null,
- author: {},
- };
-
- component = mountComponent(CommitComponent, props);
-
- expect(component.$el.querySelector('.commit-title span').textContent).toContain(
- "Can't find HEAD commit for this branch",
- );
- });
- });
-
- describe('When commit ref is provided, but merge ref is not', () => {
- it('should render the commit ref', () => {
- props = {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- shortSha: 'b7836edd',
- title: null,
- author: {},
- };
-
- component = mountComponent(CommitComponent, props);
- const refEl = component.$el.querySelector('.ref-name');
-
- expect(refEl.textContent).toContain('master');
-
- expect(refEl.href).toBe(props.commitRef.ref_url);
-
- expect(refEl.getAttribute('data-original-title')).toBe(props.commitRef.name);
-
- expect(component.$el.querySelector('.icon-container .ic-branch')).not.toBeNull();
- });
- });
-
- describe('When both commit and merge ref are provided', () => {
- it('should render the merge ref', () => {
- props = {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- mergeRequestRef: {
- iid: 1234,
- path: 'https://example.com/path/to/mr',
- title: 'Test MR',
- },
- shortSha: 'b7836edd',
- title: null,
- author: {},
- };
-
- component = mountComponent(CommitComponent, props);
- const refEl = component.$el.querySelector('.ref-name');
-
- expect(refEl.textContent).toContain('1234');
-
- expect(refEl.href).toBe(props.mergeRequestRef.path);
-
- expect(refEl.getAttribute('data-original-title')).toBe(props.mergeRequestRef.title);
-
- expect(component.$el.querySelector('.icon-container .ic-git-merge')).not.toBeNull();
- });
- });
-
- describe('When showRefInfo === false', () => {
- it('should not render any ref info', () => {
- props = {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl:
- 'https://gitlab.com/gitlab-org/gitlab-foss/commit/b7836eddf62d663c665769e1b0960197fd215067',
- mergeRequestRef: {
- iid: 1234,
- path: '/path/to/mr',
- title: 'Test MR',
- },
- shortSha: 'b7836edd',
- title: null,
- author: {},
- showRefInfo: false,
- };
-
- component = mountComponent(CommitComponent, props);
-
- expect(component.$el.querySelector('.ref-name')).toBeNull();
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js b/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js
index bdf802052b9..16997e9dc67 100644
--- a/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js
+++ b/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js
@@ -70,4 +70,30 @@ describe('ContentViewer', () => {
done();
});
});
+
+ it('markdown preview receives the file path as a parameter', done => {
+ mock = new MockAdapter(axios);
+ spyOn(axios, 'post').and.callThrough();
+ mock.onPost(`${gon.relative_url_root}/testproject/preview_markdown`).reply(200, {
+ body: '<b>testing</b>',
+ });
+
+ createComponent({
+ path: 'test.md',
+ content: '* Test',
+ projectPath: 'testproject',
+ type: 'markdown',
+ filePath: 'foo/test.md',
+ });
+
+ setTimeout(() => {
+ expect(axios.post).toHaveBeenCalledWith(
+ `${gon.relative_url_root}/testproject/preview_markdown`,
+ { path: 'foo/test.md', text: '* Test' },
+ jasmine.any(Object),
+ );
+
+ done();
+ });
+ });
});
diff --git a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
index 660eaddf01f..1acd6b3ebe7 100644
--- a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
+++ b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
@@ -1,13 +1,23 @@
import Vue from 'vue';
+
import diffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { GREEN_BOX_IMAGE_URL, RED_BOX_IMAGE_URL } from 'spec/test_constants';
describe('DiffViewer', () => {
+ const requiredProps = {
+ diffMode: 'replaced',
+ diffViewerMode: 'image',
+ newPath: GREEN_BOX_IMAGE_URL,
+ newSha: 'ABC',
+ oldPath: RED_BOX_IMAGE_URL,
+ oldSha: 'DEF',
+ };
let vm;
function createComponent(props) {
const DiffViewer = Vue.extend(diffViewer);
+
vm = mountComponent(DiffViewer, props);
}
@@ -20,15 +30,11 @@ describe('DiffViewer', () => {
relative_url_root: '',
};
- createComponent({
- diffMode: 'replaced',
- diffViewerMode: 'image',
- newPath: GREEN_BOX_IMAGE_URL,
- newSha: 'ABC',
- oldPath: RED_BOX_IMAGE_URL,
- oldSha: 'DEF',
- projectPath: '',
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ projectPath: '',
+ }),
+ );
setTimeout(() => {
expect(vm.$el.querySelector('.deleted img').getAttribute('src')).toBe(
@@ -44,14 +50,13 @@ describe('DiffViewer', () => {
});
it('renders fallback download diff display', done => {
- createComponent({
- diffMode: 'replaced',
- diffViewerMode: 'added',
- newPath: 'test.abc',
- newSha: 'ABC',
- oldPath: 'testold.abc',
- oldSha: 'DEF',
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ diffViewerMode: 'added',
+ newPath: 'test.abc',
+ oldPath: 'testold.abc',
+ }),
+ );
setTimeout(() => {
expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain(
@@ -72,29 +77,28 @@ describe('DiffViewer', () => {
});
it('renders renamed component', () => {
- createComponent({
- diffMode: 'renamed',
- diffViewerMode: 'renamed',
- newPath: 'test.abc',
- newSha: 'ABC',
- oldPath: 'testold.abc',
- oldSha: 'DEF',
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ diffMode: 'renamed',
+ diffViewerMode: 'renamed',
+ newPath: 'test.abc',
+ oldPath: 'testold.abc',
+ }),
+ );
expect(vm.$el.textContent).toContain('File moved');
});
it('renders mode changed component', () => {
- createComponent({
- diffMode: 'mode_changed',
- diffViewerMode: 'image',
- newPath: 'test.abc',
- newSha: 'ABC',
- oldPath: 'testold.abc',
- oldSha: 'DEF',
- aMode: '123',
- bMode: '321',
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ diffMode: 'mode_changed',
+ newPath: 'test.abc',
+ oldPath: 'testold.abc',
+ aMode: '123',
+ bMode: '321',
+ }),
+ );
expect(vm.$el.textContent).toContain('File mode changed from 123 to 321');
});
diff --git a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
index 97c870f27d9..0cb26d5000b 100644
--- a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
+++ b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
@@ -4,6 +4,11 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { GREEN_BOX_IMAGE_URL, RED_BOX_IMAGE_URL } from 'spec/test_constants';
describe('ImageDiffViewer', () => {
+ const requiredProps = {
+ diffMode: 'replaced',
+ newPath: GREEN_BOX_IMAGE_URL,
+ oldPath: RED_BOX_IMAGE_URL,
+ };
let vm;
function createComponent(props) {
@@ -45,11 +50,7 @@ describe('ImageDiffViewer', () => {
});
it('renders image diff for replaced', done => {
- createComponent({
- diffMode: 'replaced',
- newPath: GREEN_BOX_IMAGE_URL,
- oldPath: RED_BOX_IMAGE_URL,
- });
+ createComponent(requiredProps);
setTimeout(() => {
expect(vm.$el.querySelector('.added img').getAttribute('src')).toBe(GREEN_BOX_IMAGE_URL);
@@ -70,11 +71,12 @@ describe('ImageDiffViewer', () => {
});
it('renders image diff for new', done => {
- createComponent({
- diffMode: 'new',
- newPath: GREEN_BOX_IMAGE_URL,
- oldPath: '',
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ diffMode: 'new',
+ oldPath: '',
+ }),
+ );
setTimeout(() => {
expect(vm.$el.querySelector('.added img').getAttribute('src')).toBe(GREEN_BOX_IMAGE_URL);
@@ -84,11 +86,12 @@ describe('ImageDiffViewer', () => {
});
it('renders image diff for deleted', done => {
- createComponent({
- diffMode: 'deleted',
- newPath: '',
- oldPath: RED_BOX_IMAGE_URL,
- });
+ createComponent(
+ Object.assign({}, requiredProps, {
+ diffMode: 'deleted',
+ newPath: '',
+ }),
+ );
setTimeout(() => {
expect(vm.$el.querySelector('.deleted img').getAttribute('src')).toBe(RED_BOX_IMAGE_URL);
@@ -119,11 +122,7 @@ describe('ImageDiffViewer', () => {
describe('swipeMode', () => {
beforeEach(done => {
- createComponent({
- diffMode: 'replaced',
- newPath: GREEN_BOX_IMAGE_URL,
- oldPath: RED_BOX_IMAGE_URL,
- });
+ createComponent(requiredProps);
setTimeout(() => {
done();
@@ -142,11 +141,7 @@ describe('ImageDiffViewer', () => {
describe('onionSkin', () => {
beforeEach(done => {
- createComponent({
- diffMode: 'replaced',
- newPath: GREEN_BOX_IMAGE_URL,
- oldPath: RED_BOX_IMAGE_URL,
- });
+ createComponent(requiredProps);
setTimeout(() => {
done();
diff --git a/spec/javascripts/vue_shared/components/icon_spec.js b/spec/javascripts/vue_shared/components/icon_spec.js
index 7390798afa8..ecaef414464 100644
--- a/spec/javascripts/vue_shared/components/icon_spec.js
+++ b/spec/javascripts/vue_shared/components/icon_spec.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import Icon from '~/vue_shared/components/icon.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import { mount } from '@vue/test-utils';
describe('Sprite Icon Component', function() {
describe('Initialization', function() {
@@ -57,4 +58,16 @@ describe('Sprite Icon Component', function() {
expect(Icon.props.name.validator('commit')).toBe(true);
});
});
+
+ it('should call registered listeners when they are triggered', () => {
+ const clickHandler = jasmine.createSpy('clickHandler');
+ const wrapper = mount(Icon, {
+ propsData: { name: 'commit' },
+ listeners: { click: clickHandler },
+ });
+
+ wrapper.find('svg').trigger('click');
+
+ expect(clickHandler).toHaveBeenCalled();
+ });
});
diff --git a/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js b/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js
index 9c2deca585b..323a0f03017 100644
--- a/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js
+++ b/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js
@@ -3,7 +3,7 @@ import _ from 'underscore';
import ProjectSelector from '~/vue_shared/components/project_selector/project_selector.vue';
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
-import { GlSearchBoxByType } from '@gitlab/ui';
+import { GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui';
import { mount, createLocalVue } from '@vue/test-utils';
import { trimText } from 'spec/helpers/text_helper';
@@ -91,6 +91,13 @@ describe('ProjectSelector component', () => {
expect(searchInput.attributes('placeholder')).toBe('Search your projects');
});
+ it(`triggers a "bottomReached" event when user has scrolled to the bottom of the list`, () => {
+ spyOn(vm, '$emit');
+ wrapper.find(GlInfiniteScroll).vm.$emit('bottomReached');
+
+ expect(vm.$emit).toHaveBeenCalledWith('bottomReached');
+ });
+
it(`triggers a "projectClicked" event when a project is clicked`, () => {
spyOn(vm, '$emit');
wrapper.find(ProjectListItem).vm.$emit('click', _.first(searchResults));
diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js
deleted file mode 100644
index 258530f32f7..00000000000
--- a/spec/javascripts/vue_shared/components/table_pagination_spec.js
+++ /dev/null
@@ -1,352 +0,0 @@
-import Vue from 'vue';
-import paginationComp from '~/vue_shared/components/pagination/table_pagination.vue';
-
-describe('Pagination component', () => {
- let component;
- let PaginationComponent;
- let spy;
- let mountComponent;
-
- beforeEach(() => {
- spy = jasmine.createSpy('spy');
- PaginationComponent = Vue.extend(paginationComp);
-
- mountComponent = function(props) {
- return new PaginationComponent({
- propsData: props,
- }).$mount();
- };
- });
-
- describe('render', () => {
- it('should not render anything', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: NaN,
- page: 1,
- perPage: 20,
- previousPage: NaN,
- total: 15,
- totalPages: 1,
- },
- change: spy,
- });
-
- expect(component.$el.childNodes.length).toEqual(0);
- });
-
- describe('prev button', () => {
- it('should be disabled and non clickable', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 2,
- page: 1,
- perPage: 20,
- previousPage: NaN,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- expect(
- component.$el.querySelector('.js-previous-button').classList.contains('disabled'),
- ).toEqual(true);
-
- component.$el.querySelector('.js-previous-button .page-link').click();
-
- expect(spy).not.toHaveBeenCalled();
- });
-
- it('should be disabled and non clickable when total and totalPages are NaN', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 2,
- page: 1,
- perPage: 20,
- previousPage: NaN,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- expect(
- component.$el.querySelector('.js-previous-button').classList.contains('disabled'),
- ).toEqual(true);
-
- component.$el.querySelector('.js-previous-button .page-link').click();
-
- expect(spy).not.toHaveBeenCalled();
- });
-
- it('should be enabled and clickable', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- component.$el.querySelector('.js-previous-button .page-link').click();
-
- expect(spy).toHaveBeenCalledWith(1);
- });
-
- it('should be enabled and clickable when total and totalPages are NaN', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- component.$el.querySelector('.js-previous-button .page-link').click();
-
- expect(spy).toHaveBeenCalledWith(1);
- });
- });
-
- describe('first button', () => {
- it('should call the change callback with the first page', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- const button = component.$el.querySelector('.js-first-button .page-link');
-
- expect(button.textContent.trim()).toEqual('« First');
-
- button.click();
-
- expect(spy).toHaveBeenCalledWith(1);
- });
-
- it('should call the change callback with the first page when total and totalPages are NaN', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- const button = component.$el.querySelector('.js-first-button .page-link');
-
- expect(button.textContent.trim()).toEqual('« First');
-
- button.click();
-
- expect(spy).toHaveBeenCalledWith(1);
- });
- });
-
- describe('last button', () => {
- it('should call the change callback with the last page', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- const button = component.$el.querySelector('.js-last-button .page-link');
-
- expect(button.textContent.trim()).toEqual('Last »');
-
- button.click();
-
- expect(spy).toHaveBeenCalledWith(5);
- });
-
- it('should not render', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 3,
- page: 2,
- perPage: 20,
- previousPage: 1,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- expect(component.$el.querySelector('.js-last-button .page-link')).toBeNull();
- });
- });
-
- describe('next button', () => {
- it('should be disabled and non clickable', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: NaN,
- page: 5,
- perPage: 20,
- previousPage: 4,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- expect(component.$el.querySelector('.js-next-button').textContent.trim()).toEqual('Next ›');
-
- component.$el.querySelector('.js-next-button .page-link').click();
-
- expect(spy).not.toHaveBeenCalled();
- });
-
- it('should be disabled and non clickable when total and totalPages are NaN', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: NaN,
- page: 5,
- perPage: 20,
- previousPage: 4,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- expect(component.$el.querySelector('.js-next-button').textContent.trim()).toEqual('Next ›');
-
- component.$el.querySelector('.js-next-button .page-link').click();
-
- expect(spy).not.toHaveBeenCalled();
- });
-
- it('should be enabled and clickable', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- component.$el.querySelector('.js-next-button .page-link').click();
-
- expect(spy).toHaveBeenCalledWith(4);
- });
-
- it('should be enabled and clickable when total and totalPages are NaN', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- component.$el.querySelector('.js-next-button .page-link').click();
-
- expect(spy).toHaveBeenCalledWith(4);
- });
- });
-
- describe('numbered buttons', () => {
- it('should render 5 pages', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: 84,
- totalPages: 5,
- },
- change: spy,
- });
-
- expect(component.$el.querySelectorAll('.page').length).toEqual(5);
- });
-
- it('should not render any page', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- expect(component.$el.querySelectorAll('.page').length).toEqual(0);
- });
- });
-
- describe('spread operator', () => {
- it('should render', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: 84,
- totalPages: 10,
- },
- change: spy,
- });
-
- expect(component.$el.querySelector('.separator').textContent.trim()).toEqual('...');
- });
-
- it('should not render', () => {
- component = mountComponent({
- pageInfo: {
- nextPage: 4,
- page: 3,
- perPage: 20,
- previousPage: 2,
- total: NaN,
- totalPages: NaN,
- },
- change: spy,
- });
-
- expect(component.$el.querySelector('.separator')).toBeNull();
- });
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js
deleted file mode 100644
index c5045afc5b0..00000000000
--- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ /dev/null
@@ -1,120 +0,0 @@
-import Vue from 'vue';
-import { placeholderImage } from '~/lazy_loader';
-import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
-import mountComponent, { mountComponentWithSlots } from 'spec/helpers/vue_mount_component_helper';
-import defaultAvatarUrl from '~/../images/no_avatar.png';
-
-const DEFAULT_PROPS = {
- size: 99,
- imgSrc: 'myavatarurl.com',
- imgAlt: 'mydisplayname',
- cssClasses: 'myextraavatarclass',
- tooltipText: 'tooltip text',
- tooltipPlacement: 'bottom',
-};
-
-describe('User Avatar Image Component', function() {
- let vm;
- let UserAvatarImage;
-
- beforeEach(() => {
- UserAvatarImage = Vue.extend(userAvatarImage);
- });
-
- describe('Initialization', function() {
- beforeEach(function() {
- vm = mountComponent(UserAvatarImage, {
- ...DEFAULT_PROPS,
- }).$mount();
- });
-
- it('should return a defined Vue component', function() {
- expect(vm).toBeDefined();
- });
-
- it('should have <img> as a child element', function() {
- const imageElement = vm.$el.querySelector('img');
-
- expect(imageElement).not.toBe(null);
- expect(imageElement.getAttribute('src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.getAttribute('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.getAttribute('alt')).toBe(DEFAULT_PROPS.imgAlt);
- });
-
- it('should properly compute avatarSizeClass', function() {
- expect(vm.avatarSizeClass).toBe('s99');
- });
-
- it('should properly render img css', function() {
- const { classList } = vm.$el.querySelector('img');
- const containsAvatar = classList.contains('avatar');
- const containsSizeClass = classList.contains('s99');
- const containsCustomClass = classList.contains(DEFAULT_PROPS.cssClasses);
- const lazyClass = classList.contains('lazy');
-
- expect(containsAvatar).toBe(true);
- expect(containsSizeClass).toBe(true);
- expect(containsCustomClass).toBe(true);
- expect(lazyClass).toBe(false);
- });
- });
-
- describe('Initialization when lazy', function() {
- beforeEach(function() {
- vm = mountComponent(UserAvatarImage, {
- ...DEFAULT_PROPS,
- lazy: true,
- }).$mount();
- });
-
- it('should add lazy attributes', function() {
- const imageElement = vm.$el.querySelector('img');
- const lazyClass = imageElement.classList.contains('lazy');
-
- expect(lazyClass).toBe(true);
- expect(imageElement.getAttribute('src')).toBe(placeholderImage);
- expect(imageElement.getAttribute('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- });
- });
-
- describe('Initialization without src', function() {
- beforeEach(function() {
- vm = mountComponent(UserAvatarImage);
- });
-
- it('should have default avatar image', function() {
- const imageElement = vm.$el.querySelector('img');
-
- expect(imageElement.getAttribute('src')).toBe(defaultAvatarUrl);
- });
- });
-
- describe('dynamic tooltip content', () => {
- const props = DEFAULT_PROPS;
- const slots = {
- default: ['Action!'],
- };
-
- beforeEach(() => {
- vm = mountComponentWithSlots(UserAvatarImage, { props, slots }).$mount();
- });
-
- it('renders the tooltip slot', () => {
- expect(vm.$el.querySelector('.js-user-avatar-image-toolip')).not.toBe(null);
- });
-
- it('renders the tooltip content', () => {
- expect(vm.$el.querySelector('.js-user-avatar-image-toolip').textContent).toContain(
- slots.default[0],
- );
- });
-
- it('does not render tooltip data attributes for on avatar image', () => {
- const avatarImg = vm.$el.querySelector('img');
-
- expect(avatarImg.dataset.originalTitle).not.toBeDefined();
- expect(avatarImg.dataset.placement).not.toBeDefined();
- expect(avatarImg.dataset.container).not.toBeDefined();
- });
- });
-});
diff --git a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js b/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js
deleted file mode 100644
index c7e0d806d80..00000000000
--- a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js
+++ /dev/null
@@ -1,167 +0,0 @@
-import Vue from 'vue';
-import userPopover from '~/vue_shared/components/user_popover/user_popover.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-
-const DEFAULT_PROPS = {
- loaded: true,
- user: {
- username: 'root',
- name: 'Administrator',
- location: 'Vienna',
- bio: null,
- organization: null,
- status: null,
- },
-};
-
-const UserPopover = Vue.extend(userPopover);
-
-describe('User Popover Component', () => {
- const fixtureTemplate = 'merge_requests/diff_comment.html';
- preloadFixtures(fixtureTemplate);
-
- let vm;
-
- beforeEach(() => {
- loadFixtures(fixtureTemplate);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('Empty', () => {
- beforeEach(() => {
- vm = mountComponent(UserPopover, {
- target: document.querySelector('.js-user-link'),
- user: {
- name: null,
- username: null,
- location: null,
- bio: null,
- organization: null,
- status: null,
- },
- });
- });
-
- it('should return skeleton loaders', () => {
- expect(vm.$el.querySelectorAll('.animation-container').length).toBe(4);
- });
- });
-
- describe('basic data', () => {
- it('should show basic fields', () => {
- vm = mountComponent(UserPopover, {
- ...DEFAULT_PROPS,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.textContent).toContain(DEFAULT_PROPS.user.name);
- expect(vm.$el.textContent).toContain(DEFAULT_PROPS.user.username);
- expect(vm.$el.textContent).toContain(DEFAULT_PROPS.user.location);
- });
-
- it('shows icon for location', () => {
- const iconEl = vm.$el.querySelector('.js-location svg');
-
- expect(iconEl.querySelector('use').getAttribute('xlink:href')).toContain('location');
- });
- });
-
- describe('job data', () => {
- it('should show only bio if no organization is available', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.bio = 'Engineer';
-
- vm = mountComponent(UserPopover, {
- ...testProps,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.textContent).toContain('Engineer');
- });
-
- it('should show only organization if no bio is available', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.organization = 'GitLab';
-
- vm = mountComponent(UserPopover, {
- ...testProps,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.textContent).toContain('GitLab');
- });
-
- it('should display bio and organization in separate lines', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.bio = 'Engineer';
- testProps.user.organization = 'GitLab';
-
- vm = mountComponent(UserPopover, {
- ...DEFAULT_PROPS,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.querySelector('.js-bio').textContent).toContain('Engineer');
- expect(vm.$el.querySelector('.js-organization').textContent).toContain('GitLab');
- });
-
- it('should not encode special characters in bio and organization', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.bio = 'Manager & Team Lead';
- testProps.user.organization = 'Me & my <funky> Company';
-
- vm = mountComponent(UserPopover, {
- ...DEFAULT_PROPS,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.querySelector('.js-bio').textContent).toContain('Manager & Team Lead');
- expect(vm.$el.querySelector('.js-organization').textContent).toContain(
- 'Me & my <funky> Company',
- );
- });
-
- it('shows icon for bio', () => {
- const iconEl = vm.$el.querySelector('.js-bio svg');
-
- expect(iconEl.querySelector('use').getAttribute('xlink:href')).toContain('profile');
- });
-
- it('shows icon for organization', () => {
- const iconEl = vm.$el.querySelector('.js-organization svg');
-
- expect(iconEl.querySelector('use').getAttribute('xlink:href')).toContain('work');
- });
- });
-
- describe('status data', () => {
- it('should show only message', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.status = { message_html: 'Hello World' };
-
- vm = mountComponent(UserPopover, {
- ...DEFAULT_PROPS,
- target: document.querySelector('.js-user-link'),
- });
-
- expect(vm.$el.textContent).toContain('Hello World');
- });
-
- it('should show message and emoji', () => {
- const testProps = Object.assign({}, DEFAULT_PROPS);
- testProps.user.status = { emoji: 'basketball_player', message_html: 'Hello World' };
-
- vm = mountComponent(UserPopover, {
- ...DEFAULT_PROPS,
- target: document.querySelector('.js-user-link'),
- status: { emoji: 'basketball_player', message_html: 'Hello World' },
- });
-
- expect(vm.$el.textContent).toContain('Hello World');
- expect(vm.$el.innerHTML).toContain('<gl-emoji data-name="basketball_player"');
- });
- });
-});