summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-20 15:09:17 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-20 15:09:17 +0000
commit194b499aa8e26df26ff70a1e1ce0396587bd5243 (patch)
treec873ac9c3096faf4a5da43d6670107461da2a7d7
parent43b4b3e2d2ddebc0a89b94a8251c162ec5719780 (diff)
downloadgitlab-ce-194b499aa8e26df26ff70a1e1ce0396587bd5243.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/services/projects/prometheus/alerts/alert_params.rb17
-rw-r--r--app/services/projects/prometheus/alerts/create_service.rb15
-rw-r--r--app/services/projects/prometheus/alerts/destroy_service.rb13
-rw-r--r--app/services/projects/prometheus/alerts/update_service.rb15
-rw-r--r--changelogs/unreleased/fix-openapi-file-detector.yml5
-rw-r--r--doc/api/merge_requests.md14
-rw-r--r--doc/development/chatops_on_gitlabcom.md2
-rw-r--r--lib/gitlab/file_detector.rb2
-rw-r--r--lib/gitlab/import_export/relation_tree_restorer.rb20
-rw-r--r--spec/frontend/diffs/components/commit_widget_spec.js19
-rw-r--r--spec/frontend/diffs/components/diff_discussions_spec.js (renamed from spec/javascripts/diffs/components/diff_discussions_spec.js)4
-rw-r--r--spec/frontend/diffs/components/diff_expansion_cell_spec.js (renamed from spec/javascripts/diffs/components/diff_expansion_cell_spec.js)4
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js (renamed from spec/javascripts/diffs/components/diff_file_spec.js)12
-rw-r--r--spec/frontend/diffs/components/diff_line_note_form_spec.js (renamed from spec/javascripts/diffs/components/diff_line_note_form_spec.js)78
-rw-r--r--spec/frontend/diffs/components/file_row_stats_spec.js (renamed from spec/javascripts/diffs/components/file_row_stats_spec.js)2
-rw-r--r--spec/frontend/diffs/components/image_diff_overlay_spec.js140
-rw-r--r--spec/frontend/diffs/components/inline_diff_expansion_row_spec.js (renamed from spec/javascripts/diffs/components/inline_diff_expansion_row_spec.js)2
-rw-r--r--spec/frontend/diffs/components/inline_diff_table_row_spec.js (renamed from spec/javascripts/diffs/components/inline_diff_table_row_spec.js)2
-rw-r--r--spec/frontend/diffs/components/inline_diff_view_spec.js (renamed from spec/javascripts/diffs/components/inline_diff_view_spec.js)2
-rw-r--r--spec/frontend/diffs/components/parallel_diff_expansion_row_spec.js (renamed from spec/javascripts/diffs/components/parallel_diff_expansion_row_spec.js)2
-rw-r--r--spec/frontend/diffs/components/parallel_diff_table_row_spec.js (renamed from spec/javascripts/diffs/components/parallel_diff_table_row_spec.js)2
-rw-r--r--spec/frontend/diffs/components/parallel_diff_view_spec.js (renamed from spec/javascripts/diffs/components/parallel_diff_view_spec.js)2
-rw-r--r--spec/frontend/diffs/mock_data/diff_file_unreadable.js244
-rw-r--r--spec/frontend/diffs/store/actions_spec.js (renamed from spec/javascripts/diffs/store/actions_spec.js)162
-rw-r--r--spec/frontend/diffs/store/getters_spec.js (renamed from spec/javascripts/diffs/store/getters_spec.js)0
-rw-r--r--spec/frontend/diffs/store/mutations_spec.js (renamed from spec/javascripts/diffs/store/mutations_spec.js)17
-rw-r--r--spec/frontend/diffs/store/utils_spec.js (renamed from spec/javascripts/diffs/store/utils_spec.js)2
-rw-r--r--spec/javascripts/diffs/components/commit_widget_spec.js24
-rw-r--r--spec/javascripts/diffs/components/image_diff_overlay_spec.js146
-rw-r--r--spec/javascripts/diffs/create_diffs_store.js4
-rw-r--r--spec/javascripts/diffs/mock_data/diff_discussions.js537
-rw-r--r--spec/javascripts/diffs/mock_data/diff_file_unreadable.js249
-rw-r--r--spec/lib/gitlab/file_detector_spec.rb15
-rw-r--r--spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb56
-rw-r--r--spec/services/groups/import_export/import_service_spec.rb16
-rw-r--r--spec/services/projects/prometheus/alerts/create_service_spec.rb52
-rw-r--r--spec/services/projects/prometheus/alerts/destroy_service_spec.rb21
-rw-r--r--spec/services/projects/prometheus/alerts/update_service_spec.rb53
38 files changed, 849 insertions, 1123 deletions
diff --git a/app/services/projects/prometheus/alerts/alert_params.rb b/app/services/projects/prometheus/alerts/alert_params.rb
new file mode 100644
index 00000000000..1c39ed36b12
--- /dev/null
+++ b/app/services/projects/prometheus/alerts/alert_params.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Projects
+ module Prometheus
+ module Alerts
+ module AlertParams
+ def alert_params
+ return params if params[:operator].blank?
+
+ params.merge(
+ operator: PrometheusAlert.operator_to_enum(params[:operator])
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/projects/prometheus/alerts/create_service.rb b/app/services/projects/prometheus/alerts/create_service.rb
new file mode 100644
index 00000000000..dc0cacf49f3
--- /dev/null
+++ b/app/services/projects/prometheus/alerts/create_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ module Prometheus
+ module Alerts
+ class CreateService < BaseService
+ include AlertParams
+
+ def execute
+ project.prometheus_alerts.create(alert_params)
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/projects/prometheus/alerts/destroy_service.rb b/app/services/projects/prometheus/alerts/destroy_service.rb
new file mode 100644
index 00000000000..14e88a2e356
--- /dev/null
+++ b/app/services/projects/prometheus/alerts/destroy_service.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Projects
+ module Prometheus
+ module Alerts
+ class DestroyService < BaseService
+ def execute(alert)
+ alert.destroy
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/projects/prometheus/alerts/update_service.rb b/app/services/projects/prometheus/alerts/update_service.rb
new file mode 100644
index 00000000000..a0c8a5ccc2d
--- /dev/null
+++ b/app/services/projects/prometheus/alerts/update_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ module Prometheus
+ module Alerts
+ class UpdateService < BaseService
+ include AlertParams
+
+ def execute(alert)
+ alert.update(alert_params)
+ end
+ end
+ end
+ end
+end
diff --git a/changelogs/unreleased/fix-openapi-file-detector.yml b/changelogs/unreleased/fix-openapi-file-detector.yml
new file mode 100644
index 00000000000..7793df62e77
--- /dev/null
+++ b/changelogs/unreleased/fix-openapi-file-detector.yml
@@ -0,0 +1,5 @@
+---
+title: Fix OpenAPI file detector
+merge_request: 27321
+author: Roger Meier
+type: fixed
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 3c31ebf067b..0b90b277d6f 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -64,9 +64,12 @@ Parameters:
NOTE: **Note:**
[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/29984),
-the mergeability (`merge_status`) of each merge request will be checked
+when `async_merge_request_check_mergeability` feature flag is enabled, the
+mergeability (`merge_status`) of each merge request will be checked
asynchronously when a request is made to this endpoint. Poll this API endpoint
-to get updated status.
+to get updated status. This affects the `has_conflicts` property as it is
+dependent on the `merge_status`. It'll return `false` unless `merge_status` is
+`cannot_be_merged`.
```json
[
@@ -538,9 +541,12 @@ Parameters:
NOTE: **Note:**
[Starting in GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/issues/29984),
-the mergeability (`merge_status`) of a merge request will be checked
+when `async_merge_request_check_mergeability` feature flag is enabled, the
+mergeability (`merge_status`) of a merge request will be checked
asynchronously when a request is made to this endpoint. Poll this API endpoint
-to get updated status.
+to get updated status. This affects the `has_conflicts` property as it is
+dependent on the `merge_status`. It'll return `false` unless `merge_status` is
+`cannot_be_merged`.
```json
{
diff --git a/doc/development/chatops_on_gitlabcom.md b/doc/development/chatops_on_gitlabcom.md
index 90b9cca54ac..a8151471b87 100644
--- a/doc/development/chatops_on_gitlabcom.md
+++ b/doc/development/chatops_on_gitlabcom.md
@@ -16,6 +16,8 @@ To request access to Chatops on GitLab.com:
1. Log into <https://ops.gitlab.net/users/sign_in> **using the same username** as for GitLab.com (you may have to rename it).
1. Ask in the [#production](https://gitlab.slack.com/messages/production) channel to add you by running `/chatops run member add <username> gitlab-com/chatops --ops`.
+NOTE: **Note:** If you had to change your username for GitLab.com on the first step, make sure [to reflect this information](https://gitlab.com/gitlab-com/www-gitlab-com#adding-yourself-to-the-team-page) on [the team page](https://about.gitlab.com/team).
+
## See also
- [Chatops Usage](../ci/chatops/README.md)
diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb
index 305fbeecce1..351d5096132 100644
--- a/lib/gitlab/file_detector.rb
+++ b/lib/gitlab/file_detector.rb
@@ -40,7 +40,7 @@ module Gitlab
yarn_lock: 'yarn.lock',
# OpenAPI Specification files
- openapi: %r{.*(openapi|swagger).*\.(yaml|yml|json)\z}i
+ openapi: %r{([^\/]+)*(openapi|swagger)([^\/]+)*\.(yaml|yml|json)\z}i
}.freeze
# Returns an Array of file types based on the given paths.
diff --git a/lib/gitlab/import_export/relation_tree_restorer.rb b/lib/gitlab/import_export/relation_tree_restorer.rb
index 88cf346d8ec..1157e18c7f9 100644
--- a/lib/gitlab/import_export/relation_tree_restorer.rb
+++ b/lib/gitlab/import_export/relation_tree_restorer.rb
@@ -71,6 +71,7 @@ module Gitlab
import_failure_service.with_retry(action: 'relation_object.save!', relation_key: relation_key, relation_index: relation_index) do
relation_object.save!
+ log_relation_creation(@importable, relation_key, relation_object)
end
rescue => e
import_failure_service.log_import_failure(
@@ -218,6 +219,25 @@ module Gitlab
relation_reader.sort_ci_pipelines_by_id
end
+
+ # Enable logging of each top-level relation creation when Importing
+ # into a Group if feature flag is enabled
+ def log_relation_creation(importable, relation_key, relation_object)
+ root_ancestor_group = importable.try(:root_ancestor)
+
+ return unless root_ancestor_group
+ return unless root_ancestor_group.instance_of?(::Group)
+ return unless Feature.enabled?(:log_import_export_relation_creation, root_ancestor_group)
+
+ @shared.logger.info(
+ importable_type: importable.class.to_s,
+ importable_id: importable.id,
+ relation_key: relation_key,
+ relation_id: relation_object.id,
+ author_id: relation_object.try(:author_id),
+ message: '[Project/Group Import] Created new object relation'
+ )
+ end
end
end
end
diff --git a/spec/frontend/diffs/components/commit_widget_spec.js b/spec/frontend/diffs/components/commit_widget_spec.js
new file mode 100644
index 00000000000..54e7596b726
--- /dev/null
+++ b/spec/frontend/diffs/components/commit_widget_spec.js
@@ -0,0 +1,19 @@
+import { shallowMount } from '@vue/test-utils';
+import CommitWidget from '~/diffs/components/commit_widget.vue';
+import CommitItem from '~/diffs/components/commit_item.vue';
+
+describe('diffs/components/commit_widget', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = shallowMount(CommitWidget, {
+ propsData: { commit: {} },
+ });
+ });
+
+ it('renders commit item', () => {
+ const commitElement = wrapper.find(CommitItem);
+
+ expect(commitElement.exists()).toBe(true);
+ });
+});
diff --git a/spec/javascripts/diffs/components/diff_discussions_spec.js b/spec/frontend/diffs/components/diff_discussions_spec.js
index 1b924bb947d..ba5a4f96204 100644
--- a/spec/javascripts/diffs/components/diff_discussions_spec.js
+++ b/spec/frontend/diffs/components/diff_discussions_spec.js
@@ -57,7 +57,7 @@ describe('DiffDiscussions', () => {
it('dispatches toggleDiscussion when clicking collapse button', () => {
createComponent({ shouldCollapseDiscussions: true });
- spyOn(wrapper.vm.$store, 'dispatch').and.stub();
+ jest.spyOn(wrapper.vm.$store, 'dispatch').mockImplementation();
const diffNotesToggle = findDiffNotesToggle();
diffNotesToggle.trigger('click');
@@ -74,7 +74,7 @@ describe('DiffDiscussions', () => {
expect(diffNotesToggle.text().trim()).toBe('1');
expect(diffNotesToggle.classes()).toEqual(
- jasmine.arrayContaining(['btn-transparent', 'badge', 'badge-pill']),
+ expect.arrayContaining(['btn-transparent', 'badge', 'badge-pill']),
);
});
diff --git a/spec/javascripts/diffs/components/diff_expansion_cell_spec.js b/spec/frontend/diffs/components/diff_expansion_cell_spec.js
index 9a5048d9332..31c6a4d5b60 100644
--- a/spec/javascripts/diffs/components/diff_expansion_cell_spec.js
+++ b/spec/frontend/diffs/components/diff_expansion_cell_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import { cloneDeep } from 'lodash';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores';
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
import { getPreviousLineIndex } from '~/diffs/store/utils';
@@ -69,7 +69,7 @@ describe('DiffExpansionCell', () => {
mockLine = getLine(mockFile, INLINE_DIFF_VIEW_TYPE, LINE_TO_USE);
store = createStore();
store.state.diffs.diffFiles = [mockFile];
- spyOn(store, 'dispatch').and.returnValue(Promise.resolve());
+ jest.spyOn(store, 'dispatch').mockReturnValue(Promise.resolve());
});
const createComponent = (options = {}) => {
diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index e2b64a5418e..d0ba71fce47 100644
--- a/spec/javascripts/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import { createStore } from 'ee_else_ce/mr_notes/stores';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import DiffFileComponent from '~/diffs/components/diff_file.vue';
import { diffViewerModes, diffViewerErrors } from '~/ide/constants';
import diffFileMockDataReadable from '../mock_data/diff_file';
@@ -16,7 +16,7 @@ describe('DiffFile', () => {
file: JSON.parse(JSON.stringify(diffFileMockDataReadable)),
canCurrentUserFork: false,
}).$mount();
- trackingSpy = mockTracking('_category_', vm.$el, spyOn);
+ trackingSpy = mockTracking('_category_', vm.$el, jest.spyOn);
});
afterEach(() => {
@@ -164,7 +164,7 @@ describe('DiffFile', () => {
});
it('should update store state', done => {
- spyOn(vm.$store, 'dispatch');
+ jest.spyOn(vm.$store, 'dispatch').mockImplementation(() => {});
vm.isCollapsed = true;
@@ -211,7 +211,7 @@ describe('DiffFile', () => {
describe('watch collapsed', () => {
it('calls handleLoadCollapsedDiff if collapsed changed & file has no lines', done => {
- spyOn(vm, 'handleLoadCollapsedDiff');
+ jest.spyOn(vm, 'handleLoadCollapsedDiff').mockImplementation(() => {});
vm.file.highlighted_diff_lines = undefined;
vm.file.parallel_diff_lines = [];
@@ -237,7 +237,7 @@ describe('DiffFile', () => {
canCurrentUserFork: false,
}).$mount();
- spyOn(vm, 'handleLoadCollapsedDiff');
+ jest.spyOn(vm, 'handleLoadCollapsedDiff').mockImplementation(() => {});
vm.file.highlighted_diff_lines = undefined;
vm.file.parallel_diff_lines = [];
diff --git a/spec/javascripts/diffs/components/diff_line_note_form_spec.js b/spec/frontend/diffs/components/diff_line_note_form_spec.js
index 09263e5ce83..9b032d10fdc 100644
--- a/spec/javascripts/diffs/components/diff_line_note_form_spec.js
+++ b/spec/frontend/diffs/components/diff_line_note_form_spec.js
@@ -1,12 +1,12 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { shallowMount } from '@vue/test-utils';
import DiffLineNoteForm from '~/diffs/components/diff_line_note_form.vue';
+import NoteForm from '~/notes/components/note_form.vue';
import { createStore } from '~/mr_notes/stores';
import diffFileMockData from '../mock_data/diff_file';
import { noteableDataMock } from '../../notes/mock_data';
describe('DiffLineNoteForm', () => {
- let component;
+ let wrapper;
let diffFile;
let diffLines;
const getDiffFileMock = () => Object.assign({}, diffFileMockData);
@@ -14,58 +14,57 @@ describe('DiffLineNoteForm', () => {
beforeEach(() => {
diffFile = getDiffFileMock();
diffLines = diffFile.highlighted_diff_lines;
-
- component = createComponentWithStore(Vue.extend(DiffLineNoteForm), createStore(), {
- diffFileHash: diffFile.file_hash,
- diffLines,
- line: diffLines[0],
- noteTargetLine: diffLines[0],
- });
-
- Object.defineProperties(component, {
- noteableData: { value: noteableDataMock },
- isLoggedIn: { value: true },
+ const store = createStore();
+ store.state.notes.userData.id = 1;
+ store.state.notes.noteableData = noteableDataMock;
+
+ wrapper = shallowMount(DiffLineNoteForm, {
+ store,
+ propsData: {
+ diffFileHash: diffFile.file_hash,
+ diffLines,
+ line: diffLines[0],
+ noteTargetLine: diffLines[0],
+ },
});
-
- component.$mount();
});
describe('methods', () => {
describe('handleCancelCommentForm', () => {
it('should ask for confirmation when shouldConfirm and isDirty passed as truthy', () => {
- spyOn(window, 'confirm').and.returnValue(false);
+ jest.spyOn(window, 'confirm').mockReturnValue(false);
- component.handleCancelCommentForm(true, true);
+ wrapper.vm.handleCancelCommentForm(true, true);
expect(window.confirm).toHaveBeenCalled();
});
it('should ask for confirmation when one of the params false', () => {
- spyOn(window, 'confirm').and.returnValue(false);
+ jest.spyOn(window, 'confirm').mockReturnValue(false);
- component.handleCancelCommentForm(true, false);
+ wrapper.vm.handleCancelCommentForm(true, false);
expect(window.confirm).not.toHaveBeenCalled();
- component.handleCancelCommentForm(false, true);
+ wrapper.vm.handleCancelCommentForm(false, true);
expect(window.confirm).not.toHaveBeenCalled();
});
it('should call cancelCommentForm with lineCode', done => {
- spyOn(window, 'confirm');
- spyOn(component, 'cancelCommentForm');
- spyOn(component, 'resetAutoSave');
- component.handleCancelCommentForm();
+ jest.spyOn(window, 'confirm').mockImplementation(() => {});
+ jest.spyOn(wrapper.vm, 'cancelCommentForm').mockImplementation(() => {});
+ jest.spyOn(wrapper.vm, 'resetAutoSave').mockImplementation(() => {});
+ wrapper.vm.handleCancelCommentForm();
expect(window.confirm).not.toHaveBeenCalled();
- component.$nextTick(() => {
- expect(component.cancelCommentForm).toHaveBeenCalledWith({
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.cancelCommentForm).toHaveBeenCalledWith({
lineCode: diffLines[0].line_code,
- fileHash: component.diffFileHash,
+ fileHash: wrapper.vm.diffFileHash,
});
- expect(component.resetAutoSave).toHaveBeenCalled();
+ expect(wrapper.vm.resetAutoSave).toHaveBeenCalled();
done();
});
@@ -74,17 +73,16 @@ describe('DiffLineNoteForm', () => {
describe('saveNoteForm', () => {
it('should call saveNote action with proper params', done => {
- const saveDiffDiscussionSpy = spyOn(component, 'saveDiffDiscussion').and.returnValue(
- Promise.resolve(),
- );
- spyOnProperty(component, 'formData').and.returnValue('formData');
+ const saveDiffDiscussionSpy = jest
+ .spyOn(wrapper.vm, 'saveDiffDiscussion')
+ .mockReturnValue(Promise.resolve());
- component
+ wrapper.vm
.handleSaveNote('note body')
.then(() => {
expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
note: 'note body',
- formData: 'formData',
+ formData: wrapper.vm.formData,
});
})
.then(done)
@@ -97,18 +95,14 @@ describe('DiffLineNoteForm', () => {
it('should init autosave', () => {
const key = 'autosave/Note/Issue/98//DiffNote//1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1';
- expect(component.autosave).toBeDefined();
- expect(component.autosave.key).toEqual(key);
+ expect(wrapper.vm.autosave).toBeDefined();
+ expect(wrapper.vm.autosave.key).toEqual(key);
});
});
describe('template', () => {
it('should have note form', () => {
- const { $el } = component;
-
- expect($el.querySelector('.js-vue-textarea')).toBeDefined();
- expect($el.querySelector('.js-vue-issue-save')).toBeDefined();
- expect($el.querySelector('.js-vue-markdown-field')).toBeDefined();
+ expect(wrapper.find(NoteForm).exists()).toBe(true);
});
});
});
diff --git a/spec/javascripts/diffs/components/file_row_stats_spec.js b/spec/frontend/diffs/components/file_row_stats_spec.js
index 59c5e592a59..34d85ba10b0 100644
--- a/spec/javascripts/diffs/components/file_row_stats_spec.js
+++ b/spec/frontend/diffs/components/file_row_stats_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import mountComponent from 'helpers/vue_mount_component_helper';
import FileRowStats from '~/diffs/components/file_row_stats.vue';
describe('Diff file row stats', () => {
diff --git a/spec/frontend/diffs/components/image_diff_overlay_spec.js b/spec/frontend/diffs/components/image_diff_overlay_spec.js
new file mode 100644
index 00000000000..accf0a972d0
--- /dev/null
+++ b/spec/frontend/diffs/components/image_diff_overlay_spec.js
@@ -0,0 +1,140 @@
+import { shallowMount } from '@vue/test-utils';
+import ImageDiffOverlay from '~/diffs/components/image_diff_overlay.vue';
+import { createStore } from '~/mr_notes/stores';
+import { imageDiffDiscussions } from '../mock_data/diff_discussions';
+import Icon from '~/vue_shared/components/icon.vue';
+
+describe('Diffs image diff overlay component', () => {
+ const dimensions = {
+ width: 100,
+ height: 200,
+ };
+ let wrapper;
+ let dispatch;
+ const getAllImageBadges = () => wrapper.findAll('.js-image-badge');
+
+ function createComponent(props = {}, extendStore = () => {}) {
+ const store = createStore();
+
+ extendStore(store);
+ dispatch = jest.spyOn(store, 'dispatch').mockImplementation();
+
+ wrapper = shallowMount(ImageDiffOverlay, {
+ store,
+ propsData: {
+ discussions: [...imageDiffDiscussions],
+ fileHash: 'ABC',
+ ...props,
+ },
+ methods: {
+ getImageDimensions: jest.fn().mockReturnValue(dimensions),
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders comment badges', () => {
+ createComponent();
+
+ expect(getAllImageBadges()).toHaveLength(2);
+ });
+
+ it('renders index of discussion in badge', () => {
+ createComponent();
+ const imageBadges = getAllImageBadges();
+
+ expect(
+ imageBadges
+ .at(0)
+ .text()
+ .trim(),
+ ).toBe('1');
+ expect(
+ imageBadges
+ .at(1)
+ .text()
+ .trim(),
+ ).toBe('2');
+ });
+
+ it('renders icon when showCommentIcon is true', () => {
+ createComponent({ showCommentIcon: true });
+
+ expect(wrapper.find(Icon).exists()).toBe(true);
+ });
+
+ it('sets badge comment positions', () => {
+ createComponent();
+ const imageBadges = getAllImageBadges();
+
+ expect(imageBadges.at(0).attributes('style')).toBe('left: 10px; top: 10px;');
+ expect(imageBadges.at(1).attributes('style')).toBe('left: 5px; top: 5px;');
+ });
+
+ it('renders single badge for discussion object', () => {
+ createComponent({
+ discussions: {
+ ...imageDiffDiscussions[0],
+ },
+ });
+
+ expect(getAllImageBadges()).toHaveLength(1);
+ });
+
+ it('dispatches openDiffFileCommentForm when clicking overlay', () => {
+ createComponent({ canComment: true });
+ wrapper.find('.js-add-image-diff-note-button').trigger('click', { offsetX: 0, offsetY: 0 });
+
+ expect(dispatch).toHaveBeenCalledWith('diffs/openDiffFileCommentForm', {
+ fileHash: 'ABC',
+ x: 0,
+ y: 0,
+ width: 100,
+ height: 200,
+ });
+ });
+
+ describe('toggle discussion', () => {
+ const getImageBadge = () => wrapper.find('.js-image-badge');
+
+ it('disables buttons when shouldToggleDiscussion is false', () => {
+ createComponent({ shouldToggleDiscussion: false });
+
+ expect(getImageBadge().attributes('disabled')).toEqual('disabled');
+ });
+
+ it('dispatches toggleDiscussion when clicking image badge', () => {
+ createComponent();
+ getImageBadge().trigger('click');
+
+ expect(dispatch).toHaveBeenCalledWith('toggleDiscussion', {
+ discussionId: '1',
+ });
+ });
+ });
+
+ describe('comment form', () => {
+ const getCommentIndicator = () => wrapper.find('.comment-indicator');
+ beforeEach(() => {
+ createComponent({}, store => {
+ store.state.diffs.commentForms.push({
+ fileHash: 'ABC',
+ x: 20,
+ y: 10,
+ });
+ });
+ });
+
+ it('renders comment form badge', () => {
+ expect(getCommentIndicator().exists()).toBe(true);
+ });
+
+ it('sets comment form badge position', () => {
+ expect(getCommentIndicator().attributes('style')).toBe('left: 20px; top: 10px;');
+ });
+ });
+});
diff --git a/spec/javascripts/diffs/components/inline_diff_expansion_row_spec.js b/spec/frontend/diffs/components/inline_diff_expansion_row_spec.js
index 852b8c4fbfc..f423c3b111e 100644
--- a/spec/javascripts/diffs/components/inline_diff_expansion_row_spec.js
+++ b/spec/frontend/diffs/components/inline_diff_expansion_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores';
import InlineDiffExpansionRow from '~/diffs/components/inline_diff_expansion_row.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/javascripts/diffs/components/inline_diff_table_row_spec.js b/spec/frontend/diffs/components/inline_diff_table_row_spec.js
index 392893eb695..66349727b11 100644
--- a/spec/javascripts/diffs/components/inline_diff_table_row_spec.js
+++ b/spec/frontend/diffs/components/inline_diff_table_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores';
import InlineDiffTableRow from '~/diffs/components/inline_diff_table_row.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/javascripts/diffs/components/inline_diff_view_spec.js b/spec/frontend/diffs/components/inline_diff_view_spec.js
index 76d88d4d9f0..a63c13fb271 100644
--- a/spec/javascripts/diffs/components/inline_diff_view_spec.js
+++ b/spec/frontend/diffs/components/inline_diff_view_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import '~/behaviors/markdown/render_gfm';
import { createStore } from 'ee_else_ce/mr_notes/stores';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
import diffFileMockData from '../mock_data/diff_file';
import discussionsMockData from '../mock_data/diff_discussions';
diff --git a/spec/javascripts/diffs/components/parallel_diff_expansion_row_spec.js b/spec/frontend/diffs/components/parallel_diff_expansion_row_spec.js
index f6a5a1096f3..15b2a824697 100644
--- a/spec/javascripts/diffs/components/parallel_diff_expansion_row_spec.js
+++ b/spec/frontend/diffs/components/parallel_diff_expansion_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores';
import ParallelDiffExpansionRow from '~/diffs/components/parallel_diff_expansion_row.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/javascripts/diffs/components/parallel_diff_table_row_spec.js b/spec/frontend/diffs/components/parallel_diff_table_row_spec.js
index 4e69382ba03..6b92d448cf5 100644
--- a/spec/javascripts/diffs/components/parallel_diff_table_row_spec.js
+++ b/spec/frontend/diffs/components/parallel_diff_table_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores';
import ParallelDiffTableRow from '~/diffs/components/parallel_diff_table_row.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/javascripts/diffs/components/parallel_diff_view_spec.js b/spec/frontend/diffs/components/parallel_diff_view_spec.js
index 7daca25719b..0eefbc7ec08 100644
--- a/spec/javascripts/diffs/components/parallel_diff_view_spec.js
+++ b/spec/frontend/diffs/components/parallel_diff_view_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import { createStore } from 'ee_else_ce/mr_notes/stores';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
import * as constants from '~/diffs/constants';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/frontend/diffs/mock_data/diff_file_unreadable.js b/spec/frontend/diffs/mock_data/diff_file_unreadable.js
new file mode 100644
index 00000000000..8c2df45988e
--- /dev/null
+++ b/spec/frontend/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/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 7363a213847..8a1c3e56e5a 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -1,13 +1,13 @@
import MockAdapter from 'axios-mock-adapter';
import Cookies from 'js-cookie';
-import mockDiffFile from 'spec/diffs/mock_data/diff_file';
+import mockDiffFile from 'jest/diffs/mock_data/diff_file';
import {
DIFF_VIEW_COOKIE_NAME,
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
DIFFS_PER_PAGE,
} from '~/diffs/constants';
-import actions, {
+import {
setBaseConfig,
fetchDiffFiles,
fetchDiffFilesBatch,
@@ -48,14 +48,28 @@ import eventHub from '~/notes/event_hub';
import * as types from '~/diffs/store/mutation_types';
import axios from '~/lib/utils/axios_utils';
import testAction from '../../helpers/vuex_action_helper';
+import * as utils from '~/diffs/store/utils';
+import * as commonUtils from '~/lib/utils/common_utils';
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+import createFlash from '~/flash';
+
+jest.mock('~/flash', () => jest.fn());
describe('DiffsStoreActions', () => {
+ useLocalStorageSpy();
+
const originalMethods = {
requestAnimationFrame: global.requestAnimationFrame,
requestIdleCallback: global.requestIdleCallback,
};
beforeEach(() => {
+ jest.spyOn(window.history, 'pushState');
+ jest.spyOn(commonUtils, 'historyPushState');
+ jest.spyOn(commonUtils, 'handleLocationHash').mockImplementation(() => null);
+ jest.spyOn(commonUtils, 'scrollToElement').mockImplementation(() => null);
+ jest.spyOn(utils, 'convertExpandLines').mockImplementation(() => null);
+ jest.spyOn(utils, 'idleCallback').mockImplementation(() => null);
['requestAnimationFrame', 'requestIdleCallback'].forEach(method => {
global[method] = cb => {
cb();
@@ -67,6 +81,7 @@ describe('DiffsStoreActions', () => {
['requestAnimationFrame', 'requestIdleCallback'].forEach(method => {
global[method] = originalMethods[method];
});
+ createFlash.mockClear();
});
describe('setBaseConfig', () => {
@@ -349,13 +364,11 @@ describe('DiffsStoreActions', () => {
});
it('should show flash on API error', done => {
- const flashSpy = spyOnDependency(actions, 'createFlash');
-
mock.onGet(endpointCoverage).reply(400);
testAction(fetchCoverageFiles, {}, { endpointCoverage }, [], [], () => {
- expect(flashSpy).toHaveBeenCalledTimes(1);
- expect(flashSpy).toHaveBeenCalledWith(jasmine.stringMatching('Something went wrong'));
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith(expect.stringMatching('Something went wrong'));
done();
});
});
@@ -566,10 +579,10 @@ describe('DiffsStoreActions', () => {
[{ type: types.SET_DIFF_VIEW_TYPE, payload: INLINE_DIFF_VIEW_TYPE }],
[],
() => {
- setTimeout(() => {
+ setImmediate(() => {
expect(Cookies.get('diff_view')).toEqual(INLINE_DIFF_VIEW_TYPE);
done();
- }, 0);
+ });
},
);
});
@@ -584,10 +597,10 @@ describe('DiffsStoreActions', () => {
[{ type: types.SET_DIFF_VIEW_TYPE, payload: PARALLEL_DIFF_VIEW_TYPE }],
[],
() => {
- setTimeout(() => {
+ setImmediate(() => {
expect(Cookies.get(DIFF_VIEW_COOKIE_NAME)).toEqual(PARALLEL_DIFF_VIEW_TYPE);
done();
- }, 0);
+ });
},
);
});
@@ -661,7 +674,7 @@ describe('DiffsStoreActions', () => {
const file = { hash: 123, load_collapsed_diff_url: '/load/collapsed/diff/url' };
const data = { hash: 123, parallelDiffLines: [{ lineCode: 1 }] };
const mock = new MockAdapter(axios);
- const commit = jasmine.createSpy('commit');
+ const commit = jest.fn();
mock.onGet(file.loadCollapsedDiffUrl).reply(200, data);
loadCollapsedDiff({ commit, getters: { commitId: null }, state }, file)
@@ -680,7 +693,7 @@ describe('DiffsStoreActions', () => {
commitId: null,
};
- spyOn(axios, 'get').and.returnValue(Promise.resolve({ data: {} }));
+ jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} }));
loadCollapsedDiff({ commit() {}, getters, state }, file);
@@ -695,7 +708,7 @@ describe('DiffsStoreActions', () => {
commitId: '123',
};
- spyOn(axios, 'get').and.returnValue(Promise.resolve({ data: {} }));
+ jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} }));
loadCollapsedDiff({ commit() {}, getters, state }, file);
@@ -725,12 +738,12 @@ describe('DiffsStoreActions', () => {
describe('toggleFileDiscussions', () => {
it('should dispatch collapseDiscussion when all discussions are expanded', () => {
const getters = {
- getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ id: 1 }]),
- diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(true),
- diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(false),
+ getDiffFileDiscussions: jest.fn(() => [{ id: 1 }]),
+ diffHasAllExpandedDiscussions: jest.fn(() => true),
+ diffHasAllCollapsedDiscussions: jest.fn(() => false),
};
- const dispatch = jasmine.createSpy('dispatch');
+ const dispatch = jest.fn();
toggleFileDiscussions({ getters, dispatch });
@@ -743,12 +756,12 @@ describe('DiffsStoreActions', () => {
it('should dispatch expandDiscussion when all discussions are collapsed', () => {
const getters = {
- getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ id: 1 }]),
- diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(false),
- diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(true),
+ getDiffFileDiscussions: jest.fn(() => [{ id: 1 }]),
+ diffHasAllExpandedDiscussions: jest.fn(() => false),
+ diffHasAllCollapsedDiscussions: jest.fn(() => true),
};
- const dispatch = jasmine.createSpy();
+ const dispatch = jest.fn();
toggleFileDiscussions({ getters, dispatch });
@@ -761,12 +774,12 @@ describe('DiffsStoreActions', () => {
it('should dispatch expandDiscussion when some discussions are collapsed and others are expanded for the collapsed discussion', () => {
const getters = {
- getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ expanded: false, id: 1 }]),
- diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(false),
- diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(false),
+ getDiffFileDiscussions: jest.fn(() => [{ expanded: false, id: 1 }]),
+ diffHasAllExpandedDiscussions: jest.fn(() => false),
+ diffHasAllCollapsedDiscussions: jest.fn(() => false),
};
- const dispatch = jasmine.createSpy();
+ const dispatch = jest.fn();
toggleFileDiscussions({ getters, dispatch });
@@ -786,28 +799,22 @@ describe('DiffsStoreActions', () => {
it('should not call handleLocationHash when there is not hash', () => {
window.location.hash = '';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededInline({}, lineMock);
- expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
});
it('should not call handleLocationHash when the hash does not match any line', () => {
window.location.hash = 'XYZ_456';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededInline({}, lineMock);
- expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
});
it('should call handleLocationHash only when the hash matches a line', () => {
window.location.hash = 'ABC_123';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededInline(
{},
{
@@ -822,8 +829,8 @@ describe('DiffsStoreActions', () => {
},
);
- expect(handleLocationHashSpy).toHaveBeenCalled();
- expect(handleLocationHashSpy).toHaveBeenCalledTimes(1);
+ expect(commonUtils.handleLocationHash).toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).toHaveBeenCalledTimes(1);
});
});
@@ -838,28 +845,22 @@ describe('DiffsStoreActions', () => {
it('should not call handleLocationHash when there is not hash', () => {
window.location.hash = '';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededParallel({}, lineMock);
- expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
});
it('should not call handleLocationHash when the hash does not match any line', () => {
window.location.hash = 'XYZ_456';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededParallel({}, lineMock);
- expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
});
it('should call handleLocationHash only when the hash matches a line', () => {
window.location.hash = 'ABC_123';
- const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
-
scrollToLineIfNeededParallel(
{},
{
@@ -880,8 +881,8 @@ describe('DiffsStoreActions', () => {
},
);
- expect(handleLocationHashSpy).toHaveBeenCalled();
- expect(handleLocationHashSpy).toHaveBeenCalledTimes(1);
+ expect(commonUtils.handleLocationHash).toHaveBeenCalled();
+ expect(commonUtils.handleLocationHash).toHaveBeenCalledTimes(1);
});
});
@@ -898,7 +899,7 @@ describe('DiffsStoreActions', () => {
id: commitId,
},
};
- const dispatch = jasmine.createSpy('dispatch').and.callFake(name => {
+ const dispatch = jest.fn(name => {
switch (name) {
case 'saveNote':
return Promise.resolve({
@@ -913,17 +914,16 @@ describe('DiffsStoreActions', () => {
saveDiffDiscussion({ state, dispatch }, { note, formData })
.then(() => {
- const { calls } = dispatch;
-
- expect(calls.count()).toBe(5);
- expect(calls.argsFor(0)).toEqual(['saveNote', jasmine.any(Object), { root: true }]);
-
- const postData = calls.argsFor(0)[1];
+ expect(dispatch).toHaveBeenCalledTimes(5);
+ expect(dispatch).toHaveBeenNthCalledWith(1, 'saveNote', expect.any(Object), {
+ root: true,
+ });
+ const postData = dispatch.mock.calls[0][1];
expect(postData.data.note.commit_id).toBe(commitId);
- expect(calls.argsFor(1)).toEqual(['updateDiscussion', 'test', { root: true }]);
- expect(calls.argsFor(2)).toEqual(['assignDiscussionsToDiff', ['discussion']]);
+ expect(dispatch).toHaveBeenNthCalledWith(2, 'updateDiscussion', 'test', { root: true });
+ expect(dispatch).toHaveBeenNthCalledWith(3, 'assignDiscussionsToDiff', ['discussion']);
})
.then(done)
.catch(done.fail);
@@ -947,12 +947,7 @@ describe('DiffsStoreActions', () => {
let commit;
beforeEach(() => {
- commit = jasmine.createSpy();
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
+ commit = jest.fn();
});
it('updates location hash', () => {
@@ -990,7 +985,7 @@ describe('DiffsStoreActions', () => {
});
it('updates localStorage', () => {
- spyOn(localStorage, 'setItem');
+ jest.spyOn(localStorage, 'setItem').mockImplementation(() => {});
toggleShowTreeList({ commit() {}, state: { showTreeList: true } });
@@ -998,7 +993,7 @@ describe('DiffsStoreActions', () => {
});
it('does not update localStorage', () => {
- spyOn(localStorage, 'setItem');
+ jest.spyOn(localStorage, 'setItem').mockImplementation(() => {});
toggleShowTreeList({ commit() {}, state: { showTreeList: true } }, false);
@@ -1027,7 +1022,6 @@ describe('DiffsStoreActions', () => {
};
let commit;
let $emit;
- let scrollToElement;
const state = ({ collapsed, renderIt }) => ({
diffFiles: [
{
@@ -1041,9 +1035,8 @@ describe('DiffsStoreActions', () => {
});
beforeEach(() => {
- commit = jasmine.createSpy('commit');
- scrollToElement = spyOnDependency(actions, 'scrollToElement').and.stub();
- $emit = spyOn(eventHub, '$emit');
+ commit = jest.fn();
+ $emit = jest.spyOn(eventHub, '$emit');
});
it('renders and expands file for the given discussion id', () => {
@@ -1053,7 +1046,7 @@ describe('DiffsStoreActions', () => {
expect(commit).toHaveBeenCalledWith('RENDER_FILE', localState.diffFiles[0]);
expect($emit).toHaveBeenCalledTimes(1);
- expect(scrollToElement).toHaveBeenCalledTimes(1);
+ expect(commonUtils.scrollToElement).toHaveBeenCalledTimes(1);
});
it('jumps to discussion on already rendered and expanded file', () => {
@@ -1063,7 +1056,7 @@ describe('DiffsStoreActions', () => {
expect(commit).not.toHaveBeenCalled();
expect($emit).toHaveBeenCalledTimes(1);
- expect(scrollToElement).not.toHaveBeenCalled();
+ expect(commonUtils.scrollToElement).not.toHaveBeenCalled();
});
});
@@ -1080,8 +1073,6 @@ describe('DiffsStoreActions', () => {
});
it('sets localStorage', () => {
- spyOn(localStorage, 'setItem').and.stub();
-
setRenderTreeList({ commit() {} }, true);
expect(localStorage.setItem).toHaveBeenCalledWith('mr_diff_tree_list', true);
@@ -1090,7 +1081,7 @@ describe('DiffsStoreActions', () => {
describe('setShowWhitespace', () => {
beforeEach(() => {
- spyOn(eventHub, '$emit').and.stub();
+ jest.spyOn(eventHub, '$emit').mockImplementation();
});
it('commits SET_SHOW_WHITESPACE', done => {
@@ -1105,41 +1096,30 @@ describe('DiffsStoreActions', () => {
});
it('sets localStorage', () => {
- spyOn(localStorage, 'setItem').and.stub();
-
setShowWhitespace({ commit() {} }, { showWhitespace: true });
expect(localStorage.setItem).toHaveBeenCalledWith('mr_show_whitespace', true);
});
it('calls history pushState', () => {
- spyOn(localStorage, 'setItem').and.stub();
- spyOn(window.history, 'pushState').and.stub();
-
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
expect(window.history.pushState).toHaveBeenCalled();
});
it('calls history pushState with merged params', () => {
- const originalPushState = window.history;
-
- originalPushState.pushState({}, '', '?test=1');
-
- spyOn(localStorage, 'setItem').and.stub();
- spyOn(window.history, 'pushState').and.stub();
+ window.history.pushState({}, '', '?test=1');
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
- expect(window.history.pushState.calls.mostRecent().args[2]).toMatch(/(.*)\?test=1&w=0/);
+ expect(
+ window.history.pushState.mock.calls[window.history.pushState.mock.calls.length - 1][2],
+ ).toMatch(/(.*)\?test=1&w=0/);
- originalPushState.pushState({}, '', '?');
+ window.history.pushState({}, '', '?');
});
it('emits eventHub event', () => {
- spyOn(localStorage, 'setItem').and.stub();
- spyOn(window.history, 'pushState').and.stub();
-
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
expect(eventHub.$emit).toHaveBeenCalledWith('refetchDiffData');
@@ -1284,13 +1264,13 @@ describe('DiffsStoreActions', () => {
describe('setExpandedDiffLines', () => {
beforeEach(() => {
- spyOnDependency(actions, 'idleCallback').and.callFake(cb => {
+ utils.idleCallback.mockImplementation(cb => {
cb({ timeRemaining: () => 50 });
});
});
it('commits SET_CURRENT_VIEW_DIFF_FILE_LINES when lines less than MAX_RENDERING_DIFF_LINES', done => {
- spyOnDependency(actions, 'convertExpandLines').and.callFake(() => ['test']);
+ utils.convertExpandLines.mockImplementation(() => ['test']);
testAction(
setExpandedDiffLines,
@@ -1313,7 +1293,7 @@ describe('DiffsStoreActions', () => {
it('commits ADD_CURRENT_VIEW_DIFF_FILE_LINES when lines more than MAX_RENDERING_DIFF_LINES', done => {
const lines = new Array(501).fill().map((_, i) => `line-${i}`);
- spyOnDependency(actions, 'convertExpandLines').and.callFake(() => lines);
+ utils.convertExpandLines.mockReturnValue(lines);
testAction(
setExpandedDiffLines,
@@ -1347,7 +1327,7 @@ describe('DiffsStoreActions', () => {
const mock = new MockAdapter(axios);
mock.onPost(state.dismissEndpoint).reply(200, {});
- spyOn(axios, 'post').and.callThrough();
+ jest.spyOn(axios, 'post');
testAction(
setSuggestPopoverDismissed,
diff --git a/spec/javascripts/diffs/store/getters_spec.js b/spec/frontend/diffs/store/getters_spec.js
index ca47f51cb15..ca47f51cb15 100644
--- a/spec/javascripts/diffs/store/getters_spec.js
+++ b/spec/frontend/diffs/store/getters_spec.js
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js
index c36aff39aa9..f486a53fc4d 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/frontend/diffs/store/mutations_spec.js
@@ -3,6 +3,7 @@ import mutations from '~/diffs/store/mutations';
import * as types from '~/diffs/store/mutation_types';
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
import diffFileMockData from '../mock_data/diff_file';
+import * as utils from '~/diffs/store/utils';
describe('DiffsStoreMutations', () => {
describe('SET_BASE_CONFIG', () => {
@@ -181,21 +182,21 @@ describe('DiffsStoreMutations', () => {
const state = { diffFiles: [diffFile], diffViewType: 'viewType' };
const lines = [{ old_line: 1, new_line: 1 }];
- const findDiffFileSpy = spyOnDependency(mutations, 'findDiffFile').and.returnValue(diffFile);
- const removeMatchLineSpy = spyOnDependency(mutations, 'removeMatchLine');
- const lineRefSpy = spyOnDependency(mutations, 'addLineReferences').and.returnValue(lines);
- const addContextLinesSpy = spyOnDependency(mutations, 'addContextLines');
+ jest.spyOn(utils, 'findDiffFile').mockImplementation(() => diffFile);
+ jest.spyOn(utils, 'removeMatchLine').mockImplementation(() => null);
+ jest.spyOn(utils, 'addLineReferences').mockImplementation(() => lines);
+ jest.spyOn(utils, 'addContextLines').mockImplementation(() => null);
mutations[types.ADD_CONTEXT_LINES](state, options);
- expect(findDiffFileSpy).toHaveBeenCalledWith(state.diffFiles, options.fileHash);
- expect(removeMatchLineSpy).toHaveBeenCalledWith(
+ expect(utils.findDiffFile).toHaveBeenCalledWith(state.diffFiles, options.fileHash);
+ expect(utils.removeMatchLine).toHaveBeenCalledWith(
diffFile,
options.lineNumbers,
options.params.bottom,
);
- expect(lineRefSpy).toHaveBeenCalledWith(
+ expect(utils.addLineReferences).toHaveBeenCalledWith(
options.contextLines,
options.lineNumbers,
options.params.bottom,
@@ -203,7 +204,7 @@ describe('DiffsStoreMutations', () => {
options.nextLineNumbers,
);
- expect(addContextLinesSpy).toHaveBeenCalledWith({
+ expect(utils.addContextLines).toHaveBeenCalledWith({
inlineLines: diffFile.highlighted_diff_lines,
parallelLines: diffFile.parallel_diff_lines,
diffViewType: 'viewType',
diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/frontend/diffs/store/utils_spec.js
index 223c4d7e40b..1adcdab272a 100644
--- a/spec/javascripts/diffs/store/utils_spec.js
+++ b/spec/frontend/diffs/store/utils_spec.js
@@ -463,7 +463,7 @@ describe('DiffsStoreUtils', () => {
expect(updatedFilesList).toEqual([
mock,
- jasmine.objectContaining({
+ expect.objectContaining({
content_sha: 'ABC',
file_hash: 'DEF',
}),
diff --git a/spec/javascripts/diffs/components/commit_widget_spec.js b/spec/javascripts/diffs/components/commit_widget_spec.js
deleted file mode 100644
index 2b60bd232ed..00000000000
--- a/spec/javascripts/diffs/components/commit_widget_spec.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import CommitWidget from '~/diffs/components/commit_widget.vue';
-import getDiffWithCommit from '../mock_data/diff_with_commit';
-
-describe('diffs/components/commit_widget', () => {
- const Component = Vue.extend(CommitWidget);
- const { commit } = getDiffWithCommit();
-
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- commit: getDiffWithCommit().commit,
- });
- });
-
- it('renders commit item', () => {
- const commitElement = vm.$el.querySelector('li.commit');
-
- expect(commitElement).not.toBeNull();
- expect(commitElement).toContainText(commit.short_id);
- });
-});
diff --git a/spec/javascripts/diffs/components/image_diff_overlay_spec.js b/spec/javascripts/diffs/components/image_diff_overlay_spec.js
deleted file mode 100644
index c2e5c6c34aa..00000000000
--- a/spec/javascripts/diffs/components/image_diff_overlay_spec.js
+++ /dev/null
@@ -1,146 +0,0 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import ImageDiffOverlay from '~/diffs/components/image_diff_overlay.vue';
-import { createStore } from '~/mr_notes/stores';
-import { imageDiffDiscussions } from '../mock_data/diff_discussions';
-
-describe('Diffs image diff overlay component', () => {
- const dimensions = {
- width: 100,
- height: 200,
- };
- let Component;
- let vm;
-
- function createComponent(props = {}, extendStore = () => {}) {
- const store = createStore();
-
- extendStore(store);
-
- vm = createComponentWithStore(Component, store, {
- discussions: [...imageDiffDiscussions],
- fileHash: 'ABC',
- ...props,
- });
- }
-
- beforeAll(() => {
- Component = Vue.extend(ImageDiffOverlay);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders comment badges', () => {
- createComponent();
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelectorAll('.js-image-badge').length).toBe(2);
- });
-
- it('renders index of discussion in badge', () => {
- createComponent();
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelectorAll('.js-image-badge')[0].textContent.trim()).toBe('1');
- expect(vm.$el.querySelectorAll('.js-image-badge')[1].textContent.trim()).toBe('2');
- });
-
- it('renders icon when showCommentIcon is true', () => {
- createComponent({ showCommentIcon: true });
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelector('.js-image-badge svg')).not.toBe(null);
- });
-
- it('sets badge comment positions', () => {
- createComponent();
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelectorAll('.js-image-badge')[0].style.left).toBe('10px');
- expect(vm.$el.querySelectorAll('.js-image-badge')[0].style.top).toBe('10px');
-
- expect(vm.$el.querySelectorAll('.js-image-badge')[1].style.left).toBe('5px');
- expect(vm.$el.querySelectorAll('.js-image-badge')[1].style.top).toBe('5px');
- });
-
- it('renders single badge for discussion object', () => {
- createComponent({
- discussions: {
- ...imageDiffDiscussions[0],
- },
- });
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelectorAll('.js-image-badge').length).toBe(1);
- });
-
- it('dispatches openDiffFileCommentForm when clicking overlay', () => {
- createComponent({ canComment: true });
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- spyOn(vm.$store, 'dispatch').and.stub();
-
- vm.$el.querySelector('.js-add-image-diff-note-button').click();
-
- expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/openDiffFileCommentForm', {
- fileHash: 'ABC',
- x: 0,
- y: 0,
- width: 100,
- height: 200,
- });
- });
-
- describe('toggle discussion', () => {
- it('disables buttons when shouldToggleDiscussion is false', () => {
- createComponent({ shouldToggleDiscussion: false });
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- expect(vm.$el.querySelector('.js-image-badge').hasAttribute('disabled')).toBe(true);
- });
-
- it('dispatches toggleDiscussion when clicking image badge', () => {
- createComponent();
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
-
- spyOn(vm.$store, 'dispatch').and.stub();
-
- vm.$el.querySelector('.js-image-badge').click();
-
- expect(vm.$store.dispatch).toHaveBeenCalledWith('toggleDiscussion', { discussionId: '1' });
- });
- });
-
- describe('comment form', () => {
- beforeEach(() => {
- createComponent({}, store => {
- store.state.diffs.commentForms.push({
- fileHash: 'ABC',
- x: 20,
- y: 10,
- });
- });
- spyOn(vm, 'getImageDimensions').and.returnValue(dimensions);
- vm.$mount();
- });
-
- it('renders comment form badge', () => {
- expect(vm.$el.querySelector('.comment-indicator')).not.toBe(null);
- });
-
- it('sets comment form badge position', () => {
- expect(vm.$el.querySelector('.comment-indicator').style.left).toBe('20px');
- expect(vm.$el.querySelector('.comment-indicator').style.top).toBe('10px');
- });
- });
-});
diff --git a/spec/javascripts/diffs/create_diffs_store.js b/spec/javascripts/diffs/create_diffs_store.js
index cfefd4238b8..9df057dd8b2 100644
--- a/spec/javascripts/diffs/create_diffs_store.js
+++ b/spec/javascripts/diffs/create_diffs_store.js
@@ -1 +1,5 @@
+// No new code should be added to this file. Instead, modify the
+// file this one re-exports from. For more detail about why, see:
+// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/31349
+
export { default } from '../../frontend/diffs/create_diffs_store';
diff --git a/spec/javascripts/diffs/mock_data/diff_discussions.js b/spec/javascripts/diffs/mock_data/diff_discussions.js
index dc25dd1647a..17586fddd0f 100644
--- a/spec/javascripts/diffs/mock_data/diff_discussions.js
+++ b/spec/javascripts/diffs/mock_data/diff_discussions.js
@@ -1,534 +1,5 @@
-export default {
- id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- reply_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- position: {
- old_line: null,
- new_line: 2,
- old_path: 'CHANGELOG',
- new_path: 'CHANGELOG',
- base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a',
- start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962',
- head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
- },
- line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
- expanded: true,
- notes: [
- {
- id: '1749',
- type: 'DiffNote',
- 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-04-03T21:06:21.521Z',
- updated_at: '2018-04-08T08:50:41.762Z',
- system: false,
- noteable_id: 51,
- noteable_type: 'MergeRequest',
- noteable_iid: 20,
- human_access: 'Owner',
- note: 'comment 1',
- note_html: '<p dir="auto">comment 1</p>',
- last_edited_at: '2018-04-08T08:50:41.762Z',
- last_edited_by: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- resolved: false,
- resolvable: true,
- resolved_by: null,
- discussion_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-test/notes/1749/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-test%2Fmerge_requests%2F20%23note_1749&user_id=1',
- path: '/gitlab-org/gitlab-test/notes/1749',
- noteable_note_url:
- 'http://localhost:3000/gitlab-org/gitlab-test/-/merge_requests/20#note_1749',
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- },
- {
- id: '1753',
- type: 'DiffNote',
- attachment: null,
- author: {
- id: 1,
- name: 'Fatih Acet',
- username: 'fatihacet',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/fatihacevt',
- },
- created_at: '2018-04-08T08:49:35.804Z',
- updated_at: '2018-04-08T08:50:45.915Z',
- system: false,
- noteable_id: 51,
- noteable_type: 'MergeRequest',
- noteable_iid: 20,
- human_access: 'Owner',
- note: 'comment 2 is really long one',
- note_html: '<p dir="auto">comment 2 is really long one</p>',
- last_edited_at: '2018-04-08T08:50:45.915Z',
- last_edited_by: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- state: 'active',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- path: '/root',
- },
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- resolved: false,
- resolvable: true,
- resolved_by: null,
- discussion_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-test/notes/1753/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-test%2Fmerge_requests%2F20%23note_1753&user_id=1',
- path: '/gitlab-org/gitlab-test/notes/1753',
- noteable_note_url:
- 'http://localhost:3000/gitlab-org/gitlab-test/-/merge_requests/20#note_1753',
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- },
- {
- id: '1754',
- type: 'DiffNote',
- 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-04-08T08:50:48.294Z',
- updated_at: '2018-04-08T08:50:48.294Z',
- system: false,
- noteable_id: 51,
- noteable_type: 'MergeRequest',
- noteable_iid: 20,
- human_access: 'Owner',
- note: 'comment 3',
- note_html: '<p dir="auto">comment 3</p>',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- resolved: false,
- resolvable: true,
- resolved_by: null,
- discussion_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-test/notes/1754/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-test%2Fmerge_requests%2F20%23note_1754&user_id=1',
- path: '/gitlab-org/gitlab-test/notes/1754',
- noteable_note_url:
- 'http://localhost:3000/gitlab-org/gitlab-test/-/merge_requests/20#note_1754',
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- },
- {
- id: '1755',
- type: 'DiffNote',
- 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-04-08T08:50:50.911Z',
- updated_at: '2018-04-08T08:50:50.911Z',
- system: false,
- noteable_id: 51,
- noteable_type: 'MergeRequest',
- noteable_iid: 20,
- human_access: 'Owner',
- note: 'comment 4',
- note_html: '<p dir="auto">comment 4</p>',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- resolved: false,
- resolvable: true,
- resolved_by: null,
- discussion_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-test/notes/1755/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-test%2Fmerge_requests%2F20%23note_1755&user_id=1',
- path: '/gitlab-org/gitlab-test/notes/1755',
- noteable_note_url:
- 'http://localhost:3000/gitlab-org/gitlab-test/-/merge_requests/20#note_1755',
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- },
- {
- id: '1756',
- type: 'DiffNote',
- 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-04-08T08:50:53.895Z',
- updated_at: '2018-04-08T08:50:53.895Z',
- system: false,
- noteable_id: 51,
- noteable_type: 'MergeRequest',
- noteable_iid: 20,
- human_access: 'Owner',
- note: 'comment 5',
- note_html: '<p dir="auto">comment 5</p>',
- current_user: {
- can_edit: true,
- can_award_emoji: true,
- },
- resolved: false,
- resolvable: true,
- resolved_by: null,
- discussion_id: '6b232e05bea388c6b043ccc243ba505faac04ea8',
- emoji_awardable: true,
- award_emoji: [],
- toggle_award_path: '/gitlab-org/gitlab-test/notes/1756/toggle_award_emoji',
- report_abuse_path:
- '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-test%2Fmerge_requests%2F20%23note_1756&user_id=1',
- path: '/gitlab-org/gitlab-test/notes/1756',
- noteable_note_url:
- 'http://localhost:3000/gitlab-org/gitlab-test/-/merge_requests/20#note_1756',
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- },
- ],
- individual_note: false,
- resolvable: true,
- resolved: false,
- resolve_path:
- '/gitlab-org/gitlab-test/-/merge_requests/20/discussions/6b232e05bea388c6b043ccc243ba505faac04ea8/resolve',
- resolve_with_issue_path:
- '/gitlab-org/gitlab-test/-/issues/new?discussion_to_resolve=6b232e05bea388c6b043ccc243ba505faac04ea8&merge_request_to_resolve_discussions_of=20',
- diff_file: {
- submodule: false,
- submodule_link: null,
- blob: {
- id: '9e10516ca50788acf18c518a231914a21e5f16f7',
- path: 'CHANGELOG',
- name: 'CHANGELOG',
- mode: '100644',
- readable_text: true,
- 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.rb',
- 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,
- added_lines: 2,
- 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_OLD',
- new_path_html: 'CHANGELOG',
- is_fully_expanded: true,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- text: '',
- rich_text: '',
- meta_data: {
- old_pos: 3,
- new_pos: 5,
- },
- },
- {
- line_code: null,
- type: 'match',
- old_line: null,
- new_line: null,
- text: '',
- rich_text: '',
- meta_data: {
- old_pos: 3,
- new_pos: 5,
- },
- },
- {
- line_code: null,
- type: 'match',
- old_line: null,
- new_line: null,
- text: '',
- rich_text: '',
- meta_data: {
- old_pos: 3,
- new_pos: 5,
- },
- },
- ],
- parallel_diff_lines: [
- {
- left: null,
- right: {
- line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1',
- type: 'new',
- old_line: null,
- new_line: 1,
- 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: null,
- right: {
- line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
- type: 'new',
- old_line: null,
- new_line: 2,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- text: '',
- rich_text: '',
- meta_data: {
- old_pos: 3,
- new_pos: 5,
- },
- },
- right: {
- line_code: null,
- type: 'match',
- old_line: null,
- new_line: null,
- text: '',
- rich_text: '',
- meta_data: {
- old_pos: 3,
- new_pos: 5,
- },
- },
- },
- ],
- viewer: {
- name: 'text',
- error: null,
- },
- },
- diff_discussion: true,
- truncated_diff_lines: [
- {
- text: 'line',
- rich_text:
- '<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="1">\n1\n</td>\n<td class="line_content new"><span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n</td>\n</tr>\n<tr class="line_holder new" id="">\n<td class="diff-line-num new old_line" data-linenumber="1">\n \n</td>\n<td class="diff-line-num new new_line" data-linenumber="2">\n2\n</td>\n<td class="line_content new"><span id="LC2" class="line" lang="plaintext"></span>\n</td>\n</tr>\n',
- can_receive_suggestion: true,
- line_code: '6f209374f7e565f771b95720abf46024c41d1885_1_1',
- type: 'new',
- old_line: null,
- new_line: 1,
- meta_data: null,
- },
- ],
-};
+// No new code should be added to this file. Instead, modify the
+// file this one re-exports from. For more detail about why, see:
+// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/31349
-export const imageDiffDiscussions = [
- {
- id: '1',
- position: {
- x: 10,
- y: 10,
- width: 100,
- height: 200,
- },
- },
- {
- id: '2',
- position: {
- x: 5,
- y: 5,
- width: 100,
- height: 200,
- },
- },
-];
+export { default } from '../../../frontend/diffs/mock_data/diff_discussions';
diff --git a/spec/javascripts/diffs/mock_data/diff_file_unreadable.js b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
index 8c2df45988e..09a0dc61847 100644
--- a/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
+++ b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
@@ -1,244 +1,5 @@
-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,
-};
+// No new code should be added to this file. Instead, modify the
+// file this one re-exports from. For more detail about why, see:
+// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/31349
+
+export { default } from '../../../frontend/diffs/mock_data/diff_file_unreadable';
diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb
index 3972bd24e80..5bf70ef898a 100644
--- a/spec/lib/gitlab/file_detector_spec.rb
+++ b/spec/lib/gitlab/file_detector_spec.rb
@@ -96,14 +96,25 @@ describe Gitlab::FileDetector do
'swagger.yml', 'swagger.yaml', 'swagger.json',
'gitlab_swagger.yml', 'openapi_gitlab.yml',
'OpenAPI.YML', 'openapi.Yaml', 'openapi.JSON',
- 'openapi.gitlab.yml', 'gitlab.openapi.yml'
+ 'openapi.gitlab.yml', 'gitlab.openapi.yml',
+ 'attention/openapi.yml', 'attention/swagger.yml',
+ 'attention/gitlab_swagger.yml', 'attention/openapi_gitlab.yml',
+ 'openapi/openapi.yml', 'openapi/swagger.yml',
+ 'openapi/my_openapi.yml', 'openapi/swagger_one.yml'
]
openapi_types.each do |type_name|
expect(described_class.type_of(type_name)).to eq(:openapi)
end
- expect(described_class.type_of('openapiyml')).to be_nil
+ openapi_bad_types = [
+ 'openapiyml',
+ 'openapi/attention.yaml', 'swagger/attention.yaml'
+ ]
+
+ openapi_bad_types.each do |type_name|
+ expect(described_class.type_of(type_name)).to be_nil
+ end
end
end
end
diff --git a/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb
index 578418998c0..e36144b1a30 100644
--- a/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb
@@ -60,6 +60,38 @@ describe Gitlab::ImportExport::RelationTreeRestorer do
end
end
+ shared_examples 'logging of relations creation' do
+ context 'when log_import_export_relation_creation feature flag is enabled' do
+ before do
+ stub_feature_flags(log_import_export_relation_creation: { enabled: true, thing: group })
+ end
+
+ it 'logs top-level relation creation' do
+ expect(relation_tree_restorer.shared.logger)
+ .to receive(:info)
+ .with(hash_including(message: '[Project/Group Import] Created new object relation'))
+ .at_least(:once)
+
+ subject
+ end
+ end
+
+ context 'when log_import_export_relation_creation feature flag is disabled' do
+ before do
+ stub_feature_flags(log_import_export_relation_creation: { enabled: false, thing: group })
+ end
+
+ it 'does not log top-level relation creation' do
+ expect(relation_tree_restorer.shared.logger)
+ .to receive(:info)
+ .with(hash_including(message: '[Project/Group Import] Created new object relation'))
+ .never
+
+ subject
+ end
+ end
+ end
+
context 'when restoring a project' do
let(:path) { 'spec/fixtures/lib/gitlab/import_export/complex/project.json' }
let(:importable) { create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project') }
@@ -71,6 +103,30 @@ describe Gitlab::ImportExport::RelationTreeRestorer do
let(:relation_reader) { Gitlab::ImportExport::JSON::LegacyReader::File.new(path, reader.project_relation_names) }
it_behaves_like 'import project successfully'
+
+ context 'logging of relations creation' do
+ let(:group) { create(:group) }
+ let(:importable) { create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project', group: group) }
+
+ include_examples 'logging of relations creation'
+ end
+ end
+ end
+
+ context 'when restoring a group' do
+ let(:path) { 'spec/fixtures/lib/gitlab/import_export/group_exports/no_children/group.json' }
+ let(:group) { create(:group) }
+ let(:importable) { create(:group, parent: group) }
+ let(:object_builder) { Gitlab::ImportExport::Group::ObjectBuilder }
+ let(:relation_factory) { Gitlab::ImportExport::Group::RelationFactory }
+ let(:relation_reader) { Gitlab::ImportExport::JSON::LegacyReader::File.new(path, reader.group_relation_names) }
+ let(:reader) do
+ Gitlab::ImportExport::Reader.new(
+ shared: shared,
+ config: Gitlab::ImportExport::Config.new(config: Gitlab::ImportExport.group_config_file).to_h
+ )
end
+
+ include_examples 'logging of relations creation'
end
end
diff --git a/spec/services/groups/import_export/import_service_spec.rb b/spec/services/groups/import_export/import_service_spec.rb
index 49c786ef67f..d95bba38b3e 100644
--- a/spec/services/groups/import_export/import_service_spec.rb
+++ b/spec/services/groups/import_export/import_service_spec.rb
@@ -15,6 +15,10 @@ describe Groups::ImportExport::ImportService do
before do
ImportExportUpload.create(group: group, import_file: import_file)
+
+ allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
+ allow(import_logger).to receive(:error)
+ allow(import_logger).to receive(:info)
end
context 'when user has correct permissions' do
@@ -29,13 +33,11 @@ describe Groups::ImportExport::ImportService do
end
it 'logs the import success' do
- allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
-
expect(import_logger).to receive(:info).with(
group_id: group.id,
group_name: group.name,
message: 'Group Import/Export: Import succeeded'
- )
+ ).once
subject
end
@@ -45,8 +47,6 @@ describe Groups::ImportExport::ImportService do
let(:user) { create(:user) }
it 'logs the error and raises an exception' do
- allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
-
expect(import_logger).to receive(:error).with(
group_id: group.id,
group_name: group.name,
@@ -71,16 +71,12 @@ describe Groups::ImportExport::ImportService do
context 'when there are errors with the import file' do
let(:import_file) { fixture_file_upload('spec/fixtures/symlink_export.tar.gz') }
- before do
- allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger)
- end
-
it 'logs the error and raises an exception' do
expect(import_logger).to receive(:error).with(
group_id: group.id,
group_name: group.name,
message: a_string_including('Errors occurred')
- )
+ ).once
expect { subject }.to raise_error(Gitlab::ImportExport::Error)
end
diff --git a/spec/services/projects/prometheus/alerts/create_service_spec.rb b/spec/services/projects/prometheus/alerts/create_service_spec.rb
new file mode 100644
index 00000000000..50c776df734
--- /dev/null
+++ b/spec/services/projects/prometheus/alerts/create_service_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::Prometheus::Alerts::CreateService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ let(:service) { described_class.new(project, user, params) }
+
+ subject { service.execute }
+
+ describe '#execute' do
+ context 'with params' do
+ let_it_be(:environment) { create(:environment, project: project) }
+
+ let_it_be(:metric) do
+ create(:prometheus_metric, project: project)
+ end
+
+ let(:params) do
+ {
+ environment_id: environment.id,
+ prometheus_metric_id: metric.id,
+ operator: '<',
+ threshold: 1.0
+ }
+ end
+
+ it 'creates an alert' do
+ expect(subject).to be_persisted
+
+ expect(subject).to have_attributes(
+ project: project,
+ environment: environment,
+ prometheus_metric: metric,
+ operator: 'lt',
+ threshold: 1.0
+ )
+ end
+ end
+
+ context 'without params' do
+ let(:params) { {} }
+
+ it 'fails to create' do
+ expect(subject).to be_new_record
+ expect(subject).to be_invalid
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb
new file mode 100644
index 00000000000..7205ace8308
--- /dev/null
+++ b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::Prometheus::Alerts::DestroyService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:alert) { create(:prometheus_alert, project: project) }
+
+ let(:service) { described_class.new(project, user, nil) }
+
+ describe '#execute' do
+ subject { service.execute(alert) }
+
+ it 'deletes the alert' do
+ expect(subject).to be_truthy
+
+ expect(alert).to be_destroyed
+ end
+ end
+end
diff --git a/spec/services/projects/prometheus/alerts/update_service_spec.rb b/spec/services/projects/prometheus/alerts/update_service_spec.rb
new file mode 100644
index 00000000000..8a99c2679f7
--- /dev/null
+++ b/spec/services/projects/prometheus/alerts/update_service_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::Prometheus::Alerts::UpdateService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:environment) { create(:environment, project: project) }
+
+ let_it_be(:alert) do
+ create(:prometheus_alert, project: project, environment: environment)
+ end
+
+ let(:service) { described_class.new(project, user, params) }
+
+ let(:params) do
+ {
+ environment_id: alert.environment_id,
+ prometheus_metric_id: alert.prometheus_metric_id,
+ operator: '==',
+ threshold: 2.0
+ }
+ end
+
+ describe '#execute' do
+ subject { service.execute(alert) }
+
+ context 'with valid params' do
+ it 'updates the alert' do
+ expect(subject).to be_truthy
+
+ expect(alert.reload).to have_attributes(
+ operator: 'eq',
+ threshold: 2.0
+ )
+ end
+ end
+
+ context 'with invalid params' do
+ let(:other_environment) { create(:environment) }
+
+ before do
+ params[:environment_id] = other_environment.id
+ end
+
+ it 'fails to update' do
+ expect(subject).to be_falsey
+
+ expect(alert).to be_invalid
+ end
+ end
+ end
+end