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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-21 12:09:34 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-21 12:09:34 +0300
commit5bd4297fd759a14ad9ab9232cb985d28bf44ac49 (patch)
tree6c970916f6e8ec494a5631f6defe41a5cd206f93 /spec
parent51da0a2d3976111b19d2996591e08bea5111beb3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/ide/components/activity_bar_spec.js8
-rw-r--r--spec/frontend/ide/components/commit_sidebar/empty_state_spec.js8
-rw-r--r--spec/frontend/ide/components/commit_sidebar/form_spec.js7
-rw-r--r--spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js5
-rw-r--r--spec/frontend/ide/components/commit_sidebar/list_spec.js9
-rw-r--r--spec/frontend/ide/components/commit_sidebar/radio_group_spec.js8
-rw-r--r--spec/frontend/ide/components/commit_sidebar/success_message_spec.js8
-rw-r--r--spec/frontend/ide/components/file_row_extra_spec.js3
-rw-r--r--spec/frontend/ide/components/file_templates/bar_spec.js3
-rw-r--r--spec/frontend/ide/components/ide_review_spec.js4
-rw-r--r--spec/frontend/ide/components/ide_side_bar_spec.js8
-rw-r--r--spec/frontend/ide/components/ide_spec.js6
-rw-r--r--spec/frontend/ide/components/ide_tree_list_spec.js11
-rw-r--r--spec/frontend/ide/components/ide_tree_spec.js9
-rw-r--r--spec/frontend/ide/components/new_dropdown/index_spec.js8
-rw-r--r--spec/frontend/ide/helpers.js20
-rw-r--r--spec/frontend/ide/lib/decorations/controller_spec.js5
-rw-r--r--spec/frontend/ide/lib/diff/controller_spec.js6
-rw-r--r--spec/frontend/ide/lib/editor_spec.js7
-rw-r--r--spec/frontend/ide/stores/actions/merge_request_spec.js7
-rw-r--r--spec/frontend/monitoring/components/dashboard_header_spec.js138
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js174
-rw-r--r--spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb263
-rw-r--r--spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb254
-rw-r--r--spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb159
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb28
-rw-r--r--spec/requests/api/suggestions_spec.rb4
-rw-r--r--spec/services/suggestions/apply_service_spec.rb34
-rw-r--r--spec/support/migrations_helpers/track_untracked_uploads_helpers.rb130
29 files changed, 213 insertions, 1121 deletions
diff --git a/spec/frontend/ide/components/activity_bar_spec.js b/spec/frontend/ide/components/activity_bar_spec.js
index 8b3853d4535..762f3c5dad1 100644
--- a/spec/frontend/ide/components/activity_bar_spec.js
+++ b/spec/frontend/ide/components/activity_bar_spec.js
@@ -1,15 +1,17 @@
import Vue from 'vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import { leftSidebarViews } from '~/ide/constants';
import ActivityBar from '~/ide/components/activity_bar.vue';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore } from '../helpers';
describe('IDE activity bar', () => {
const Component = Vue.extend(ActivityBar);
let vm;
+ let store;
beforeEach(() => {
+ store = createStore();
+
Vue.set(store.state.projects, 'abcproject', {
web_url: 'testing',
});
@@ -20,8 +22,6 @@ describe('IDE activity bar', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
describe('updateActivityBarView', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js b/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js
index 16d0b354a30..dbb43e43c19 100644
--- a/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js
@@ -1,13 +1,15 @@
import Vue from 'vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import emptyState from '~/ide/components/commit_sidebar/empty_state.vue';
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
-import { resetStore } from '../../helpers';
describe('IDE commit panel empty state', () => {
let vm;
+ let store;
beforeEach(() => {
+ store = createStore();
+
const Component = Vue.extend(emptyState);
Vue.set(store.state, 'noChangesStateSvgPath', 'no-changes');
@@ -19,8 +21,6 @@ describe('IDE commit panel empty state', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders no changes text when last commit message is empty', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js
index c62df4a3795..278b7bcf5aa 100644
--- a/spec/frontend/ide/components/commit_sidebar/form_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js
@@ -1,19 +1,20 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { projectData } from 'jest/ide/mock_data';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import CommitForm from '~/ide/components/commit_sidebar/form.vue';
import { leftSidebarViews } from '~/ide/constants';
-import { resetStore } from '../../helpers';
import waitForPromises from 'helpers/wait_for_promises';
describe('IDE commit form', () => {
const Component = Vue.extend(CommitForm);
let vm;
+ let store;
const beginCommitButton = () => vm.$el.querySelector('[data-testid="begin-commit-button"]');
beforeEach(() => {
+ store = createStore();
store.state.changedFiles.push('test');
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'master';
@@ -24,8 +25,6 @@ describe('IDE commit form', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('enables begin commit button when there are changes', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js b/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js
index 45372d18965..42e0a20bc7b 100644
--- a/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js
@@ -1,14 +1,17 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import listCollapsed from '~/ide/components/commit_sidebar/list_collapsed.vue';
import { file } from '../../helpers';
import { removeWhitespace } from '../../../helpers/text_helper';
describe('Multi-file editor commit sidebar list collapsed', () => {
let vm;
+ let store;
beforeEach(() => {
+ store = createStore();
+
const Component = Vue.extend(listCollapsed);
vm = createComponentWithStore(Component, store, {
diff --git a/spec/frontend/ide/components/commit_sidebar/list_spec.js b/spec/frontend/ide/components/commit_sidebar/list_spec.js
index 2b5664ffc4e..2107ff96e95 100644
--- a/spec/frontend/ide/components/commit_sidebar/list_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/list_spec.js
@@ -1,13 +1,16 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import commitSidebarList from '~/ide/components/commit_sidebar/list.vue';
-import { file, resetStore } from '../../helpers';
+import { file } from '../../helpers';
describe('Multi-file editor commit sidebar list', () => {
+ let store;
let vm;
beforeEach(() => {
+ store = createStore();
+
const Component = Vue.extend(commitSidebarList);
vm = createComponentWithStore(Component, store, {
@@ -26,8 +29,6 @@ describe('Multi-file editor commit sidebar list', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
describe('with a list of files', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js b/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js
index ac80ba58056..bf61f4bbe77 100644
--- a/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js
@@ -1,13 +1,15 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import { resetStore } from 'jest/ide/helpers';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import radioGroup from '~/ide/components/commit_sidebar/radio_group.vue';
describe('IDE commit sidebar radio group', () => {
let vm;
+ let store;
beforeEach(done => {
+ store = createStore();
+
const Component = Vue.extend(radioGroup);
store.state.commit.commitAction = '2';
@@ -25,8 +27,6 @@ describe('IDE commit sidebar radio group', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('uses label if present', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/success_message_spec.js b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js
index e1a432b81be..db13c90fbb9 100644
--- a/spec/frontend/ide/components/commit_sidebar/success_message_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js
@@ -1,13 +1,15 @@
import Vue from 'vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import successMessage from '~/ide/components/commit_sidebar/success_message.vue';
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
-import { resetStore } from '../../helpers';
describe('IDE commit panel successful commit state', () => {
let vm;
+ let store;
beforeEach(() => {
+ store = createStore();
+
const Component = Vue.extend(successMessage);
vm = createComponentWithStore(Component, store, {
@@ -19,8 +21,6 @@ describe('IDE commit panel successful commit state', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders last commit message when it exists', done => {
diff --git a/spec/frontend/ide/components/file_row_extra_spec.js b/spec/frontend/ide/components/file_row_extra_spec.js
index e78bacadebb..4bd27d23f76 100644
--- a/spec/frontend/ide/components/file_row_extra_spec.js
+++ b/spec/frontend/ide/components/file_row_extra_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/ide/stores';
import FileRowExtra from '~/ide/components/file_row_extra.vue';
-import { file, resetStore } from '../helpers';
+import { file } from '../helpers';
describe('IDE extra file row component', () => {
let Component;
@@ -32,7 +32,6 @@ describe('IDE extra file row component', () => {
afterEach(() => {
vm.$destroy();
- resetStore(vm.$store);
stagedFilesCount = 0;
unstagedFilesCount = 0;
diff --git a/spec/frontend/ide/components/file_templates/bar_spec.js b/spec/frontend/ide/components/file_templates/bar_spec.js
index 21dbe18a223..5a33837fb14 100644
--- a/spec/frontend/ide/components/file_templates/bar_spec.js
+++ b/spec/frontend/ide/components/file_templates/bar_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/ide/stores';
import Bar from '~/ide/components/file_templates/bar.vue';
-import { resetStore, file } from '../../helpers';
+import { file } from '../../helpers';
describe('IDE file templates bar component', () => {
let Component;
@@ -26,7 +26,6 @@ describe('IDE file templates bar component', () => {
afterEach(() => {
vm.$destroy();
- resetStore(vm.$store);
});
describe('template type dropdown', () => {
diff --git a/spec/frontend/ide/components/ide_review_spec.js b/spec/frontend/ide/components/ide_review_spec.js
index b56957e1f6d..c9ac2ac423d 100644
--- a/spec/frontend/ide/components/ide_review_spec.js
+++ b/spec/frontend/ide/components/ide_review_spec.js
@@ -3,7 +3,7 @@ import IdeReview from '~/ide/components/ide_review.vue';
import { createStore } from '~/ide/stores';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
import { trimText } from '../../helpers/text_helper';
-import { resetStore, file } from '../helpers';
+import { file } from '../helpers';
import { projectData } from '../mock_data';
describe('IDE review mode', () => {
@@ -26,8 +26,6 @@ describe('IDE review mode', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders list of files', () => {
diff --git a/spec/frontend/ide/components/ide_side_bar_spec.js b/spec/frontend/ide/components/ide_side_bar_spec.js
index 65cad2e7eb0..67257b40879 100644
--- a/spec/frontend/ide/components/ide_side_bar_spec.js
+++ b/spec/frontend/ide/components/ide_side_bar_spec.js
@@ -1,15 +1,17 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import ideSidebar from '~/ide/components/ide_side_bar.vue';
import { leftSidebarViews } from '~/ide/constants';
-import { resetStore } from '../helpers';
import { projectData } from '../mock_data';
describe('IdeSidebar', () => {
let vm;
+ let store;
beforeEach(() => {
+ store = createStore();
+
const Component = Vue.extend(ideSidebar);
store.state.currentProjectId = 'abcproject';
@@ -20,8 +22,6 @@ describe('IdeSidebar', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders a sidebar', () => {
diff --git a/spec/frontend/ide/components/ide_spec.js b/spec/frontend/ide/components/ide_spec.js
index efc1d984dec..a7b07a9f0e2 100644
--- a/spec/frontend/ide/components/ide_spec.js
+++ b/spec/frontend/ide/components/ide_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/ide/stores';
import ide from '~/ide/components/ide.vue';
-import { file, resetStore } from '../helpers';
+import { file } from '../helpers';
import { projectData } from '../mock_data';
import extendStore from '~/ide/stores/extend';
@@ -41,8 +41,6 @@ describe('ide component, empty repo', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders "New file" button in empty repo', done => {
@@ -63,8 +61,6 @@ describe('ide component, non-empty repo', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('shows error message when set', done => {
diff --git a/spec/frontend/ide/components/ide_tree_list_spec.js b/spec/frontend/ide/components/ide_tree_list_spec.js
index 30f11db3153..4593ef6049b 100644
--- a/spec/frontend/ide/components/ide_tree_list_spec.js
+++ b/spec/frontend/ide/components/ide_tree_list_spec.js
@@ -1,8 +1,8 @@
import Vue from 'vue';
import IdeTreeList from '~/ide/components/ide_tree_list.vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore, file } from '../helpers';
+import { file } from '../helpers';
import { projectData } from '../mock_data';
describe('IDE tree list', () => {
@@ -10,6 +10,7 @@ describe('IDE tree list', () => {
const normalBranchTree = [file('fileName')];
const emptyBranchTree = [];
let vm;
+ let store;
const bootstrapWithTree = (tree = normalBranchTree) => {
store.state.currentProjectId = 'abcproject';
@@ -25,10 +26,12 @@ describe('IDE tree list', () => {
});
};
+ beforeEach(() => {
+ store = createStore();
+ });
+
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
describe('normal branch', () => {
diff --git a/spec/frontend/ide/components/ide_tree_spec.js b/spec/frontend/ide/components/ide_tree_spec.js
index 01f007f09c3..899daa0bf57 100644
--- a/spec/frontend/ide/components/ide_tree_spec.js
+++ b/spec/frontend/ide/components/ide_tree_spec.js
@@ -1,14 +1,17 @@
import Vue from 'vue';
import IdeTree from '~/ide/components/ide_tree.vue';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore, file } from '../helpers';
+import { file } from '../helpers';
import { projectData } from '../mock_data';
describe('IdeRepoTree', () => {
+ let store;
let vm;
beforeEach(() => {
+ store = createStore();
+
const IdeRepoTree = Vue.extend(IdeTree);
store.state.currentProjectId = 'abcproject';
@@ -24,8 +27,6 @@ describe('IdeRepoTree', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders list of files', () => {
diff --git a/spec/frontend/ide/components/new_dropdown/index_spec.js b/spec/frontend/ide/components/new_dropdown/index_spec.js
index 00781c16609..c6cebf36de3 100644
--- a/spec/frontend/ide/components/new_dropdown/index_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/index_spec.js
@@ -1,13 +1,15 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import newDropdown from '~/ide/components/new_dropdown/index.vue';
-import { resetStore } from '../../helpers';
describe('new dropdown component', () => {
+ let store;
let vm;
beforeEach(() => {
+ store = createStore();
+
const component = Vue.extend(newDropdown);
vm = createComponentWithStore(component, store, {
@@ -30,8 +32,6 @@ describe('new dropdown component', () => {
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
});
it('renders new file, upload and new directory links', () => {
diff --git a/spec/frontend/ide/helpers.js b/spec/frontend/ide/helpers.js
index a9620d26313..8caa9c2b437 100644
--- a/spec/frontend/ide/helpers.js
+++ b/spec/frontend/ide/helpers.js
@@ -1,25 +1,5 @@
import * as pathUtils from 'path';
import { decorateData } from '~/ide/stores/utils';
-import state from '~/ide/stores/state';
-import commitState from '~/ide/stores/modules/commit/state';
-import mergeRequestsState from '~/ide/stores/modules/merge_requests/state';
-import pipelinesState from '~/ide/stores/modules/pipelines/state';
-import branchesState from '~/ide/stores/modules/branches/state';
-import fileTemplatesState from '~/ide/stores/modules/file_templates/state';
-import paneState from '~/ide/stores/modules/pane/state';
-
-export const resetStore = store => {
- const newState = {
- ...state(),
- commit: commitState(),
- mergeRequests: mergeRequestsState(),
- pipelines: pipelinesState(),
- branches: branchesState(),
- fileTemplates: fileTemplatesState(),
- rightPane: paneState(),
- };
- store.replaceState(newState);
-};
export const file = (name = 'name', id = name, type = '', parent = null) =>
decorateData({
diff --git a/spec/frontend/ide/lib/decorations/controller_spec.js b/spec/frontend/ide/lib/decorations/controller_spec.js
index 4556fc9d646..e9b7faaadfe 100644
--- a/spec/frontend/ide/lib/decorations/controller_spec.js
+++ b/spec/frontend/ide/lib/decorations/controller_spec.js
@@ -2,14 +2,17 @@ import Editor from '~/ide/lib/editor';
import DecorationsController from '~/ide/lib/decorations/controller';
import Model from '~/ide/lib/common/model';
import { file } from '../../helpers';
+import { createStore } from '~/ide/stores';
describe('Multi-file editor library decorations controller', () => {
let editorInstance;
let controller;
let model;
+ let store;
beforeEach(() => {
- editorInstance = Editor.create();
+ store = createStore();
+ editorInstance = Editor.create(store);
editorInstance.createInstance(document.createElement('div'));
controller = new DecorationsController(editorInstance);
diff --git a/spec/frontend/ide/lib/diff/controller_spec.js b/spec/frontend/ide/lib/diff/controller_spec.js
index 0b33a4c6ad6..8ee6388a760 100644
--- a/spec/frontend/ide/lib/diff/controller_spec.js
+++ b/spec/frontend/ide/lib/diff/controller_spec.js
@@ -4,6 +4,7 @@ import ModelManager from '~/ide/lib/common/model_manager';
import DecorationsController from '~/ide/lib/decorations/controller';
import DirtyDiffController, { getDiffChangeType, getDecorator } from '~/ide/lib/diff/controller';
import { computeDiff } from '~/ide/lib/diff/diff';
+import { createStore } from '~/ide/stores';
import { file } from '../../helpers';
describe('Multi-file editor library dirty diff controller', () => {
@@ -12,9 +13,12 @@ describe('Multi-file editor library dirty diff controller', () => {
let modelManager;
let decorationsController;
let model;
+ let store;
beforeEach(() => {
- editorInstance = Editor.create();
+ store = createStore();
+
+ editorInstance = Editor.create(store);
editorInstance.createInstance(document.createElement('div'));
modelManager = new ModelManager();
diff --git a/spec/frontend/ide/lib/editor_spec.js b/spec/frontend/ide/lib/editor_spec.js
index 5f28309422d..529f80e6f6f 100644
--- a/spec/frontend/ide/lib/editor_spec.js
+++ b/spec/frontend/ide/lib/editor_spec.js
@@ -5,6 +5,7 @@ import {
Selection,
} from 'monaco-editor';
import Editor from '~/ide/lib/editor';
+import { createStore } from '~/ide/stores';
import { defaultEditorOptions } from '~/ide/lib/editor_options';
import { file } from '../helpers';
@@ -12,6 +13,7 @@ describe('Multi-file editor library', () => {
let instance;
let el;
let holder;
+ let store;
const setNodeOffsetWidth = val => {
Object.defineProperty(instance.instance.getDomNode(), 'offsetWidth', {
@@ -22,13 +24,14 @@ describe('Multi-file editor library', () => {
};
beforeEach(() => {
+ store = createStore();
el = document.createElement('div');
holder = document.createElement('div');
el.appendChild(holder);
document.body.appendChild(el);
- instance = Editor.create();
+ instance = Editor.create(store);
});
afterEach(() => {
@@ -44,7 +47,7 @@ describe('Multi-file editor library', () => {
});
it('creates instance returns cached instance', () => {
- expect(Editor.create()).toEqual(instance);
+ expect(Editor.create(store)).toEqual(instance);
});
describe('createInstance', () => {
diff --git a/spec/frontend/ide/stores/actions/merge_request_spec.js b/spec/frontend/ide/stores/actions/merge_request_spec.js
index e5c4f346459..9ca53a6b382 100644
--- a/spec/frontend/ide/stores/actions/merge_request_spec.js
+++ b/spec/frontend/ide/stores/actions/merge_request_spec.js
@@ -1,6 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
-import store from '~/ide/stores';
+import { createStore } from '~/ide/stores';
import createFlash from '~/flash';
import {
getMergeRequestData,
@@ -10,7 +10,6 @@ import {
} from '~/ide/stores/actions/merge_request';
import service from '~/ide/services';
import { leftSidebarViews, PERMISSION_READ_MR } from '~/ide/constants';
-import { resetStore } from '../../helpers';
const TEST_PROJECT = 'abcproject';
const TEST_PROJECT_ID = 17;
@@ -18,9 +17,12 @@ const TEST_PROJECT_ID = 17;
jest.mock('~/flash');
describe('IDE store merge request actions', () => {
+ let store;
let mock;
beforeEach(() => {
+ store = createStore();
+
mock = new MockAdapter(axios);
store.state.projects[TEST_PROJECT] = {
@@ -34,7 +36,6 @@ describe('IDE store merge request actions', () => {
afterEach(() => {
mock.restore();
- resetStore(store);
});
describe('getMergeRequestsForBranch', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_header_spec.js b/spec/frontend/monitoring/components/dashboard_header_spec.js
index 5a1a615c703..7c841fbbbc5 100644
--- a/spec/frontend/monitoring/components/dashboard_header_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_header_spec.js
@@ -1,16 +1,21 @@
import { shallowMount } from '@vue/test-utils';
import { createStore } from '~/monitoring/stores';
+import * as types from '~/monitoring/stores/mutation_types';
+import { GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import DuplicateDashboardModal from '~/monitoring/components/duplicate_dashboard_modal.vue';
import CreateDashboardModal from '~/monitoring/components/create_dashboard_modal.vue';
-import { setupAllDashboards } from '../store_utils';
+import { setupAllDashboards, setupStoreWithDashboard, setupStoreWithData } from '../store_utils';
import {
+ environmentData,
dashboardGitResponse,
selfMonitoringDashboardGitResponse,
dashboardHeaderProps,
} from '../mock_data';
import { redirectTo } from '~/lib/utils/url_utility';
+const mockProjectPath = 'https://path/to/project';
+
jest.mock('~/lib/utils/url_utility', () => ({
redirectTo: jest.fn(),
queryToObject: jest.fn(),
@@ -21,6 +26,12 @@ describe('Dashboard header', () => {
let store;
let wrapper;
+ const findEnvsDropdown = () => wrapper.find({ ref: 'monitorEnvironmentsDropdown' });
+ const findEnvsDropdownItems = () => findEnvsDropdown().findAll(GlDropdownItem);
+ const findEnvsDropdownSearch = () => findEnvsDropdown().find(GlSearchBoxByType);
+ const findEnvsDropdownSearchMsg = () => wrapper.find({ ref: 'monitorEnvironmentsDropdownMsg' });
+ const findEnvsDropdownLoadingIcon = () => findEnvsDropdown().find(GlLoadingIcon);
+
const findActionsMenu = () => wrapper.find('[data-testid="actions-menu"]');
const findCreateDashboardMenuItem = () =>
findActionsMenu().find('[data-testid="action-create-dashboard"]');
@@ -29,6 +40,10 @@ describe('Dashboard header', () => {
const findDuplicateDashboardModal = () => wrapper.find(DuplicateDashboardModal);
const findCreateDashboardModal = () => wrapper.find('[data-testid="create-dashboard-modal"]');
+ const setSearchTerm = searchTerm => {
+ store.commit(`monitoringDashboard/${types.SET_ENVIRONMENTS_FILTER}`, searchTerm);
+ };
+
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(DashboardHeader, {
propsData: { ...dashboardHeaderProps, ...props },
@@ -45,6 +60,113 @@ describe('Dashboard header', () => {
wrapper.destroy();
});
+ describe('environments dropdown', () => {
+ beforeEach(() => {
+ createShallowWrapper();
+ });
+
+ it('shows the environments dropdown', () => {
+ expect(findEnvsDropdown().exists()).toBe(true);
+ });
+
+ it('renders a search input', () => {
+ expect(findEnvsDropdownSearch().exists()).toBe(true);
+ });
+
+ describe('when environments data is not loaded', () => {
+ beforeEach(() => {
+ setupStoreWithDashboard(store);
+ return wrapper.vm.$nextTick();
+ });
+
+ it('there are no environments listed', () => {
+ expect(findEnvsDropdownItems().length).toBe(0);
+ });
+ });
+
+ describe('when environments data is loaded', () => {
+ const currentDashboard = dashboardGitResponse[0].path;
+
+ beforeEach(() => {
+ setupStoreWithData(store);
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
+ store.state.monitoringDashboard.currentDashboard = currentDashboard;
+
+ return wrapper.vm.$nextTick();
+ });
+
+ it('renders dropdown items with the environment name', () => {
+ const path = `${mockProjectPath}/-/metrics/${encodeURIComponent(currentDashboard)}`;
+
+ findEnvsDropdownItems().wrappers.forEach((itemWrapper, index) => {
+ const { name, id } = environmentData[index];
+ const idParam = encodeURIComponent(id);
+
+ expect(itemWrapper.text()).toBe(name);
+ expect(itemWrapper.attributes('href')).toBe(`${path}?environment=${idParam}`);
+ });
+ });
+
+ // Note: This test is not working, .active does not show the active environment
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/230615
+ // eslint-disable-next-line jest/no-disabled-tests
+ it.skip('renders the environments dropdown with a single active element', () => {
+ const activeItem = findEnvsDropdownItems().wrappers.filter(itemWrapper =>
+ itemWrapper.find('.active').exists(),
+ );
+
+ expect(activeItem.length).toBe(1);
+ });
+
+ it('filters rendered dropdown items', () => {
+ const searchTerm = 'production';
+ const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
+ setSearchTerm(searchTerm);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findEnvsDropdownItems().length).toBe(resultEnvs.length);
+ });
+ });
+
+ it('does not filter dropdown items if search term is empty string', () => {
+ const searchTerm = '';
+ setSearchTerm(searchTerm);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findEnvsDropdownItems().length).toBe(environmentData.length);
+ });
+ });
+
+ it("shows error message if search term doesn't match", () => {
+ const searchTerm = 'does-not-exist';
+ setSearchTerm(searchTerm);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findEnvsDropdownSearchMsg().isVisible()).toBe(true);
+ });
+ });
+
+ it('shows loading element when environments fetch is still loading', () => {
+ store.commit(`monitoringDashboard/${types.REQUEST_ENVIRONMENTS_DATA}`);
+
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(findEnvsDropdownLoadingIcon().exists()).toBe(true);
+ })
+ .then(() => {
+ store.commit(
+ `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
+ environmentData,
+ );
+ })
+ .then(() => {
+ expect(findEnvsDropdownLoadingIcon().exists()).toBe(false);
+ });
+ });
+ });
+ });
+
describe('when a dashboard has been duplicated in the duplicate dashboard modal', () => {
beforeEach(() => {
store.state.monitoringDashboard.projectPath = 'root/sandbox';
@@ -81,7 +203,7 @@ describe('Dashboard header', () => {
});
it('is rendered if projectPath is set in store', () => {
- store.state.monitoringDashboard.projectPath = 'https://path/to/project';
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
return wrapper.vm.$nextTick().then(() => {
expect(findActionsMenu().exists()).toBe(true);
@@ -93,7 +215,7 @@ describe('Dashboard header', () => {
});
it('contains a modal', () => {
- store.state.monitoringDashboard.projectPath = 'https://path/to/project';
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
return wrapper.vm.$nextTick().then(() => {
expect(findActionsMenu().contains(CreateDashboardModal)).toBe(true);
@@ -111,7 +233,7 @@ describe('Dashboard header', () => {
'when the selected dashboard can be duplicated',
dashboardPath => {
it('contains a "Create New" menu item and a "Duplicate Dashboard" menu item', () => {
- store.state.monitoringDashboard.projectPath = 'https://path/to/project';
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store, dashboardPath);
return wrapper.vm.$nextTick().then(() => {
@@ -131,7 +253,7 @@ describe('Dashboard header', () => {
'when the selected dashboard cannot be duplicated',
dashboardPath => {
it('contains a "Create New" menu item and no "Duplicate Dashboard" menu item', () => {
- store.state.monitoringDashboard.projectPath = 'https://path/to/project';
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store, dashboardPath);
return wrapper.vm.$nextTick().then(() => {
@@ -144,10 +266,8 @@ describe('Dashboard header', () => {
});
describe('actions menu modals', () => {
- const url = 'https://path/to/project';
-
beforeEach(() => {
- store.state.monitoringDashboard.projectPath = url;
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store);
createShallowWrapper();
@@ -166,7 +286,7 @@ describe('Dashboard header', () => {
});
it('"Create new dashboard" modal contains correct buttons', () => {
- expect(findCreateDashboardModal().props('projectPath')).toBe(url);
+ expect(findCreateDashboardModal().props('projectPath')).toBe(mockProjectPath);
});
it('"Duplicate Dashboard" opens up a modal', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index 4b7f7a9ddb3..534c4c43d61 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -1,7 +1,7 @@
import { shallowMount, mount } from '@vue/test-utils';
import Tracking from '~/tracking';
import { ESC_KEY, ESC_KEY_IE11 } from '~/lib/utils/keys';
-import { GlModal, GlDropdownItem, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
+import { GlModal, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
import { objectToQuery } from '~/lib/utils/url_utility';
import VueDraggable from 'vuedraggable';
import MockAdapter from 'axios-mock-adapter';
@@ -29,7 +29,7 @@ import {
setupStoreWithDataForPanelCount,
setupStoreWithLinks,
} from '../store_utils';
-import { environmentData, dashboardGitResponse, storeVariables } from '../mock_data';
+import { dashboardGitResponse, storeVariables } from '../mock_data';
import {
metricsDashboardViewModel,
metricsDashboardPanelCount,
@@ -46,12 +46,6 @@ describe('Dashboard', () => {
let mock;
const findDashboardHeader = () => wrapper.find(DashboardHeader);
- const findEnvironmentsDropdown = () =>
- findDashboardHeader().find({ ref: 'monitorEnvironmentsDropdown' });
- const findAllEnvironmentsDropdownItems = () => findEnvironmentsDropdown().findAll(GlDropdownItem);
- const setSearchTerm = searchTerm => {
- store.commit(`monitoringDashboard/${types.SET_ENVIRONMENTS_FILTER}`, searchTerm);
- };
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(Dashboard, {
@@ -90,28 +84,6 @@ describe('Dashboard', () => {
}
});
- describe('no metrics are available yet', () => {
- beforeEach(() => {
- createShallowWrapper();
- });
-
- it('shows the environment selector', () => {
- expect(findEnvironmentsDropdown().exists()).toBe(true);
- });
- });
-
- describe('no data found', () => {
- beforeEach(() => {
- createShallowWrapper();
-
- return wrapper.vm.$nextTick();
- });
-
- it('shows the environment selector dropdown', () => {
- expect(findEnvironmentsDropdown().exists()).toBe(true);
- });
- });
-
describe('request information to the server', () => {
it('calls to set time range and fetch data', () => {
createShallowWrapper({ hasMetrics: true });
@@ -149,17 +121,14 @@ describe('Dashboard', () => {
});
it('fetches the metrics data with proper time window', () => {
- jest.spyOn(store, 'dispatch');
-
createMountedWrapper({ hasMetrics: true });
- store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
-
return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalled();
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ expect.objectContaining({ duration: { seconds: 28800 } }),
+ );
});
});
});
@@ -500,21 +469,6 @@ describe('Dashboard', () => {
return wrapper.vm.$nextTick();
});
- it('renders the environments dropdown with a number of environments', () => {
- expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
-
- findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
- const anchorEl = itemWrapper.find('a');
- if (anchorEl.exists()) {
- const href = anchorEl.attributes('href');
- const currentDashboard = encodeURIComponent(dashboardGitResponse[0].path);
- const environmentId = encodeURIComponent(environmentData[index].id);
- const url = `${TEST_HOST}/-/metrics/${currentDashboard}?environment=${environmentId}`;
- expect(href).toBe(url);
- }
- });
- });
-
it('it does not show loading icons in any group', () => {
setupStoreWithData(store);
@@ -524,16 +478,6 @@ describe('Dashboard', () => {
});
});
});
-
- // Note: This test is not working, .active does not show the active environment
- // eslint-disable-next-line jest/no-disabled-tests
- it.skip('renders the environments dropdown with a single active element', () => {
- const activeItem = findAllEnvironmentsDropdownItems().wrappers.filter(itemWrapper =>
- itemWrapper.find('.active').exists(),
- );
-
- expect(activeItem.length).toBe(1);
- });
});
describe('star dashboards', () => {
@@ -615,16 +559,6 @@ describe('Dashboard', () => {
});
});
- it('hides the environments dropdown list when there is no environments', () => {
- createMountedWrapper({ hasMetrics: true });
-
- setupStoreWithDashboard(store);
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findAllEnvironmentsDropdownItems()).toHaveLength(0);
- });
- });
-
it('renders the datetimepicker dropdown', () => {
createMountedWrapper({ hasMetrics: true });
@@ -811,100 +745,6 @@ describe('Dashboard', () => {
});
});
- describe('searchable environments dropdown', () => {
- beforeEach(() => {
- createMountedWrapper({ hasMetrics: true }, { attachToDocument: true });
-
- setupStoreWithData(store);
-
- return wrapper.vm.$nextTick();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders a search input', () => {
- expect(
- wrapper
- .find(DashboardHeader)
- .find({ ref: 'monitorEnvironmentsDropdownSearch' })
- .exists(),
- ).toBe(true);
- });
-
- it('renders dropdown items', () => {
- findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
- const anchorEl = itemWrapper.find('a');
- if (anchorEl.exists()) {
- expect(anchorEl.text()).toBe(environmentData[index].name);
- }
- });
- });
-
- it('filters rendered dropdown items', () => {
- const searchTerm = 'production';
- const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
- setSearchTerm(searchTerm);
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findAllEnvironmentsDropdownItems().length).toEqual(resultEnvs.length);
- });
- });
-
- it('does not filter dropdown items if search term is empty string', () => {
- const searchTerm = '';
- setSearchTerm(searchTerm);
-
- return wrapper.vm.$nextTick(() => {
- expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
- });
- });
-
- it("shows error message if search term doesn't match", () => {
- const searchTerm = 'does-not-exist';
- setSearchTerm(searchTerm);
-
- return wrapper.vm.$nextTick(() => {
- expect(
- wrapper
- .find(DashboardHeader)
- .find({ ref: 'monitorEnvironmentsDropdownMsg' })
- .isVisible(),
- ).toBe(true);
- });
- });
-
- it('shows loading element when environments fetch is still loading', () => {
- store.commit(`monitoringDashboard/${types.REQUEST_ENVIRONMENTS_DATA}`);
-
- return wrapper.vm
- .$nextTick()
- .then(() => {
- expect(
- wrapper
- .find(DashboardHeader)
- .find({ ref: 'monitorEnvironmentsDropdownLoading' })
- .exists(),
- ).toBe(true);
- })
- .then(() => {
- store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
- })
- .then(() => {
- expect(
- wrapper
- .find(DashboardHeader)
- .find({ ref: 'monitorEnvironmentsDropdownLoading' })
- .exists(),
- ).toBe(false);
- });
- });
- });
-
describe('drag and drop function', () => {
const findDraggables = () => wrapper.findAll(VueDraggable);
const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled'));
diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb
deleted file mode 100644
index 6a25e8e2784..00000000000
--- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb
+++ /dev/null
@@ -1,263 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::PopulateUntrackedUploadsDependencies::UntrackedFile do
- include MigrationsHelpers::TrackUntrackedUploadsHelpers
-
- let!(:appearances) { table(:appearances) }
- let!(:namespaces) { table(:namespaces) }
- let!(:projects) { table(:projects) }
- let!(:routes) { table(:routes) }
- let!(:uploads) { table(:uploads) }
-
- before(:all) do
- ensure_temporary_tracking_table_exists
- end
-
- describe '#upload_path' do
- def assert_upload_path(file_path, expected_upload_path)
- untracked_file = create_untracked_file(file_path)
-
- expect(untracked_file.upload_path).to eq(expected_upload_path)
- end
-
- context 'for an appearance logo file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/appearance/logo/1/some_logo.jpg', 'uploads/-/system/appearance/logo/1/some_logo.jpg')
- end
- end
-
- context 'for an appearance header_logo file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/appearance/header_logo/1/some_logo.jpg', 'uploads/-/system/appearance/header_logo/1/some_logo.jpg')
- end
- end
-
- context 'for a pre-Markdown Note attachment file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/note/attachment/1234/some_attachment.pdf', 'uploads/-/system/note/attachment/1234/some_attachment.pdf')
- end
- end
-
- context 'for a user avatar file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/user/avatar/1234/avatar.jpg', 'uploads/-/system/user/avatar/1234/avatar.jpg')
- end
- end
-
- context 'for a group avatar file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/group/avatar/1234/avatar.jpg', 'uploads/-/system/group/avatar/1234/avatar.jpg')
- end
- end
-
- context 'for a project avatar file path' do
- it 'returns the file path relative to the CarrierWave root' do
- assert_upload_path('/-/system/project/avatar/1234/avatar.jpg', 'uploads/-/system/project/avatar/1234/avatar.jpg')
- end
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- it 'returns the file path relative to the project directory in uploads' do
- project = create_project
- random_hex = SecureRandom.hex
-
- assert_upload_path("/#{get_full_path(project)}/#{random_hex}/Some file.jpg", "#{random_hex}/Some file.jpg")
- end
- end
- end
-
- describe '#uploader' do
- def assert_uploader(file_path, expected_uploader)
- untracked_file = create_untracked_file(file_path)
-
- expect(untracked_file.uploader).to eq(expected_uploader)
- end
-
- context 'for an appearance logo file path' do
- it 'returns AttachmentUploader as a string' do
- assert_uploader('/-/system/appearance/logo/1/some_logo.jpg', 'AttachmentUploader')
- end
- end
-
- context 'for an appearance header_logo file path' do
- it 'returns AttachmentUploader as a string' do
- assert_uploader('/-/system/appearance/header_logo/1/some_logo.jpg', 'AttachmentUploader')
- end
- end
-
- context 'for a pre-Markdown Note attachment file path' do
- it 'returns AttachmentUploader as a string' do
- assert_uploader('/-/system/note/attachment/1234/some_attachment.pdf', 'AttachmentUploader')
- end
- end
-
- context 'for a user avatar file path' do
- it 'returns AvatarUploader as a string' do
- assert_uploader('/-/system/user/avatar/1234/avatar.jpg', 'AvatarUploader')
- end
- end
-
- context 'for a group avatar file path' do
- it 'returns AvatarUploader as a string' do
- assert_uploader('/-/system/group/avatar/1234/avatar.jpg', 'AvatarUploader')
- end
- end
-
- context 'for a project avatar file path' do
- it 'returns AvatarUploader as a string' do
- assert_uploader('/-/system/project/avatar/1234/avatar.jpg', 'AvatarUploader')
- end
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- it 'returns FileUploader as a string' do
- project = create_project
-
- assert_uploader("/#{get_full_path(project)}/#{SecureRandom.hex}/Some file.jpg", 'FileUploader')
- end
- end
- end
-
- describe '#model_type' do
- def assert_model_type(file_path, expected_model_type)
- untracked_file = create_untracked_file(file_path)
-
- expect(untracked_file.model_type).to eq(expected_model_type)
- end
-
- context 'for an appearance logo file path' do
- it 'returns Appearance as a string' do
- assert_model_type('/-/system/appearance/logo/1/some_logo.jpg', 'Appearance')
- end
- end
-
- context 'for an appearance header_logo file path' do
- it 'returns Appearance as a string' do
- assert_model_type('/-/system/appearance/header_logo/1/some_logo.jpg', 'Appearance')
- end
- end
-
- context 'for a pre-Markdown Note attachment file path' do
- it 'returns Note as a string' do
- assert_model_type('/-/system/note/attachment/1234/some_attachment.pdf', 'Note')
- end
- end
-
- context 'for a user avatar file path' do
- it 'returns User as a string' do
- assert_model_type('/-/system/user/avatar/1234/avatar.jpg', 'User')
- end
- end
-
- context 'for a group avatar file path' do
- it 'returns Namespace as a string' do
- assert_model_type('/-/system/group/avatar/1234/avatar.jpg', 'Namespace')
- end
- end
-
- context 'for a project avatar file path' do
- it 'returns Project as a string' do
- assert_model_type('/-/system/project/avatar/1234/avatar.jpg', 'Project')
- end
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- it 'returns Project as a string' do
- project = create_project
-
- assert_model_type("/#{get_full_path(project)}/#{SecureRandom.hex}/Some file.jpg", 'Project')
- end
- end
- end
-
- describe '#model_id' do
- def assert_model_id(file_path, expected_model_id)
- untracked_file = create_untracked_file(file_path)
-
- expect(untracked_file.model_id).to eq(expected_model_id)
- end
-
- context 'for an appearance logo file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/appearance/logo/1/some_logo.jpg', 1)
- end
- end
-
- context 'for an appearance header_logo file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/appearance/header_logo/1/some_logo.jpg', 1)
- end
- end
-
- context 'for a pre-Markdown Note attachment file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/note/attachment/1234/some_attachment.pdf', 1234)
- end
- end
-
- context 'for a user avatar file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/user/avatar/1234/avatar.jpg', 1234)
- end
- end
-
- context 'for a group avatar file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/group/avatar/1234/avatar.jpg', 1234)
- end
- end
-
- context 'for a project avatar file path' do
- it 'returns the ID as a string' do
- assert_model_id('/-/system/project/avatar/1234/avatar.jpg', 1234)
- end
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- it 'returns the ID as a string' do
- project = create_project
-
- assert_model_id("/#{get_full_path(project)}/#{SecureRandom.hex}/Some file.jpg", project.id)
- end
- end
- end
-
- describe '#file_size' do
- context 'for an appearance logo file path' do
- let(:appearance) { create_or_update_appearance(logo: true) }
- let(:untracked_file) { described_class.create!(path: get_uploads(appearance, 'Appearance').first.path) }
-
- it 'returns the file size' do
- expect(untracked_file.file_size).to eq(1062)
- end
- end
-
- context 'for a project avatar file path' do
- let(:project) { create_project(avatar: true) }
- let(:untracked_file) { described_class.create!(path: get_uploads(project, 'Project').first.path) }
-
- it 'returns the file size' do
- expect(untracked_file.file_size).to eq(1062)
- end
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- let(:project) { create_project }
- let(:untracked_file) { create_untracked_file("/#{get_full_path(project)}/#{get_uploads(project, 'Project').first.path}") }
-
- before do
- add_markdown_attachment(project)
- end
-
- it 'returns the file size' do
- expect(untracked_file.file_size).to eq(1062)
- end
- end
- end
-
- def create_untracked_file(path_relative_to_upload_dir)
- described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}#{path_relative_to_upload_dir}")
- end
-end
diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb
deleted file mode 100644
index 787cc54e79a..00000000000
--- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb
+++ /dev/null
@@ -1,254 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::PopulateUntrackedUploads do
- include MigrationsHelpers::TrackUntrackedUploadsHelpers
-
- subject { described_class.new }
-
- let!(:appearances) { table(:appearances) }
- let!(:namespaces) { table(:namespaces) }
- let!(:notes) { table(:notes) }
- let!(:projects) { table(:projects) }
- let!(:routes) { table(:routes) }
- let!(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) }
- let!(:uploads) { table(:uploads) }
- let!(:users) { table(:users) }
-
- before do
- ensure_temporary_tracking_table_exists
- uploads.delete_all
- end
-
- context 'with untracked files and tracked files in untracked_files_for_uploads' do
- let!(:appearance) { create_or_update_appearance(logo: true, header_logo: true) }
- let!(:user1) { create_user(avatar: true) }
- let!(:user2) { create_user(avatar: true) }
- let!(:project1) { create_project(avatar: true) }
- let!(:project2) { create_project(avatar: true) }
-
- before do
- add_markdown_attachment(project1)
- add_markdown_attachment(project2)
-
- # File records created by PrepareUntrackedUploads
- untracked_files_for_uploads.create!(path: get_uploads(appearance, 'Appearance').first.path)
- untracked_files_for_uploads.create!(path: get_uploads(appearance, 'Appearance').last.path)
- untracked_files_for_uploads.create!(path: get_uploads(user1, 'User').first.path)
- untracked_files_for_uploads.create!(path: get_uploads(user2, 'User').first.path)
- untracked_files_for_uploads.create!(path: get_uploads(project1, 'Project').first.path)
- untracked_files_for_uploads.create!(path: get_uploads(project2, 'Project').first.path)
- untracked_files_for_uploads.create!(path: "#{legacy_project_uploads_dir(project1).sub("#{MigrationsHelpers::TrackUntrackedUploadsHelpers::PUBLIC_DIR}/", '')}/#{get_uploads(project1, 'Project').last.path}")
- untracked_files_for_uploads.create!(path: "#{legacy_project_uploads_dir(project2).sub("#{MigrationsHelpers::TrackUntrackedUploadsHelpers::PUBLIC_DIR}/", '')}/#{get_uploads(project2, 'Project').last.path}")
-
- # Untrack 4 files
- get_uploads(user2, 'User').delete_all
- get_uploads(project2, 'Project').delete_all # 2 files: avatar and a Markdown upload
- get_uploads(appearance, 'Appearance').where("path like '%header_logo%'").delete_all
- end
-
- it 'adds untracked files to the uploads table' do
- expect do
- subject.perform(1, untracked_files_for_uploads.reorder(:id).last.id)
- end.to change { uploads.count }.from(4).to(8)
-
- expect(get_uploads(user2, 'User').count).to eq(1)
- expect(get_uploads(project2, 'Project').count).to eq(2)
- expect(get_uploads(appearance, 'Appearance').count).to eq(2)
- end
-
- it 'deletes rows after processing them' do
- expect(subject).to receive(:drop_temp_table_if_finished) # Don't drop the table so we can look at it
-
- expect do
- subject.perform(1, untracked_files_for_uploads.last.id)
- end.to change { untracked_files_for_uploads.count }.from(8).to(0)
- end
-
- it 'does not create duplicate uploads of already tracked files' do
- subject.perform(1, untracked_files_for_uploads.last.id)
-
- expect(get_uploads(user1, 'User').count).to eq(1)
- expect(get_uploads(project1, 'Project').count).to eq(2)
- expect(get_uploads(appearance, 'Appearance').count).to eq(2)
- end
-
- it 'uses the start and end batch ids [only 1st half]' do
- ids = untracked_files_for_uploads.all.order(:id).pluck(:id)
- start_id = ids[0]
- end_id = ids[3]
-
- expect do
- subject.perform(start_id, end_id)
- end.to change { uploads.count }.from(4).to(6)
-
- expect(get_uploads(user1, 'User').count).to eq(1)
- expect(get_uploads(user2, 'User').count).to eq(1)
- expect(get_uploads(appearance, 'Appearance').count).to eq(2)
- expect(get_uploads(project1, 'Project').count).to eq(2)
- expect(get_uploads(project2, 'Project').count).to eq(0)
-
- # Only 4 have been either confirmed or added to uploads
- expect(untracked_files_for_uploads.count).to eq(4)
- end
-
- it 'uses the start and end batch ids [only 2nd half]' do
- ids = untracked_files_for_uploads.all.order(:id).pluck(:id)
- start_id = ids[4]
- end_id = ids[7]
-
- expect do
- subject.perform(start_id, end_id)
- end.to change { uploads.count }.from(4).to(6)
-
- expect(get_uploads(user1, 'User').count).to eq(1)
- expect(get_uploads(user2, 'User').count).to eq(0)
- expect(get_uploads(appearance, 'Appearance').count).to eq(1)
- expect(get_uploads(project1, 'Project').count).to eq(2)
- expect(get_uploads(project2, 'Project').count).to eq(2)
-
- # Only 4 have been either confirmed or added to uploads
- expect(untracked_files_for_uploads.count).to eq(4)
- end
-
- it 'does not drop the temporary tracking table after processing the batch, if there are still untracked rows' do
- subject.perform(1, untracked_files_for_uploads.last.id - 1)
-
- expect(ActiveRecord::Base.connection.table_exists?(:untracked_files_for_uploads)).to be_truthy
- end
-
- it 'drops the temporary tracking table after processing the batch, if there are no untracked rows left' do
- expect(subject).to receive(:drop_temp_table_if_finished)
-
- subject.perform(1, untracked_files_for_uploads.last.id)
- end
-
- it 'does not block a whole batch because of one bad path' do
- untracked_files_for_uploads.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{get_full_path(project2)}/._7d37bf4c747916390e596744117d5d1a")
- expect(untracked_files_for_uploads.count).to eq(9)
- expect(uploads.count).to eq(4)
-
- subject.perform(1, untracked_files_for_uploads.last.id)
-
- expect(untracked_files_for_uploads.count).to eq(1)
- expect(uploads.count).to eq(8)
- end
-
- it 'an unparseable path is shown in error output' do
- bad_path = "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{get_full_path(project2)}/._7d37bf4c747916390e596744117d5d1a"
- untracked_files_for_uploads.create!(path: bad_path)
-
- expect(Rails.logger).to receive(:error).with(/Error parsing path "#{bad_path}":/)
-
- subject.perform(1, untracked_files_for_uploads.last.id)
- end
- end
-
- context 'with no untracked files' do
- it 'does not add to the uploads table (and does not raise error)' do
- expect do
- subject.perform(1, 1000)
- end.not_to change { uploads.count }.from(0)
- end
- end
-
- describe 'upload outcomes for each path pattern' do
- shared_examples_for 'non_markdown_file' do
- let!(:expected_upload_attrs) { model_uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') }
- let!(:untracked_file) { untracked_files_for_uploads.create!(path: expected_upload_attrs['path']) }
-
- before do
- model_uploads.delete_all
- end
-
- it 'creates an Upload record' do
- expect do
- subject.perform(1, untracked_files_for_uploads.last.id)
- end.to change { model_uploads.count }.from(0).to(1)
-
- expect(model_uploads.first.attributes).to include(expected_upload_attrs)
- end
- end
-
- context 'for an appearance logo file path' do
- let(:model) { create_or_update_appearance(logo: true) }
- let(:model_uploads) { get_uploads(model, 'Appearance') }
-
- it_behaves_like 'non_markdown_file'
- end
-
- context 'for an appearance header_logo file path' do
- let(:model) { create_or_update_appearance(header_logo: true) }
- let(:model_uploads) { get_uploads(model, 'Appearance') }
-
- it_behaves_like 'non_markdown_file'
- end
-
- context 'for a pre-Markdown Note attachment file path' do
- let(:model) { create_note(attachment: true) }
- let!(:expected_upload_attrs) { get_uploads(model, 'Note').first.attributes.slice('path', 'uploader', 'size', 'checksum') }
- let!(:untracked_file) { untracked_files_for_uploads.create!(path: expected_upload_attrs['path']) }
-
- before do
- get_uploads(model, 'Note').delete_all
- end
-
- # Can't use the shared example because Note doesn't have an `uploads` association
- it 'creates an Upload record' do
- expect do
- subject.perform(1, untracked_files_for_uploads.last.id)
- end.to change { get_uploads(model, 'Note').count }.from(0).to(1)
-
- expect(get_uploads(model, 'Note').first.attributes).to include(expected_upload_attrs)
- end
- end
-
- context 'for a user avatar file path' do
- let(:model) { create_user(avatar: true) }
- let(:model_uploads) { get_uploads(model, 'User') }
-
- it_behaves_like 'non_markdown_file'
- end
-
- context 'for a group avatar file path' do
- let(:model) { create_group(avatar: true) }
- let(:model_uploads) { get_uploads(model, 'Namespace') }
-
- it_behaves_like 'non_markdown_file'
- end
-
- context 'for a project avatar file path' do
- let(:model) { create_project(avatar: true) }
- let(:model_uploads) { get_uploads(model, 'Project') }
-
- it_behaves_like 'non_markdown_file'
- end
-
- context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
- let(:model) { create_project }
-
- before do
- # Upload the file
- add_markdown_attachment(model)
-
- # Create the untracked_files_for_uploads record
- untracked_files_for_uploads.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{get_full_path(model)}/#{get_uploads(model, 'Project').first.path}")
-
- # Save the expected upload attributes
- @expected_upload_attrs = get_uploads(model, 'Project').first.attributes.slice('path', 'uploader', 'size', 'checksum')
-
- # Untrack the file
- get_uploads(model, 'Project').delete_all
- end
-
- it 'creates an Upload record' do
- expect do
- subject.perform(1, untracked_files_for_uploads.last.id)
- end.to change { get_uploads(model, 'Project').count }.from(0).to(1)
-
- expect(get_uploads(model, 'Project').first.attributes).to include(@expected_upload_attrs)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb
deleted file mode 100644
index 9b01407dc8b..00000000000
--- a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-# Rollback DB to 10.5 (later than this was originally written for) because it still needs to work.
-RSpec.describe Gitlab::BackgroundMigration::PrepareUntrackedUploads do
- include MigrationsHelpers::TrackUntrackedUploadsHelpers
-
- let!(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) }
- let!(:appearances) { table(:appearances) }
- let!(:namespaces) { table(:namespaces) }
- let!(:projects) { table(:projects) }
- let!(:routes) { table(:routes) }
- let!(:uploads) { table(:uploads) }
- let!(:users) { table(:users) }
-
- around do |example|
- # Especially important so the follow-up migration does not get run
- Sidekiq::Testing.fake! do
- example.run
- end
- end
-
- shared_examples 'prepares the untracked_files_for_uploads table' do
- context 'when files were uploaded before and after hashed storage was enabled' do
- let!(:appearance) { create_or_update_appearance(logo: true, header_logo: true) }
- let!(:user) { create_user(avatar: true) }
- let!(:project1) { create_project(avatar: true) }
- let(:project2) { create_project } # instantiate after enabling hashed_storage
-
- before do
- # Markdown upload before enabling hashed_storage
- add_markdown_attachment(project1)
-
- # Markdown upload after enabling hashed_storage
- add_markdown_attachment(project2, hashed_storage: true)
- end
-
- it 'has a path field long enough for really long paths' do
- described_class.new.perform
-
- component = 'a' * 255
-
- long_path = [
- 'uploads',
- component, # project.full_path
- component # filename
- ].flatten.join('/')
-
- record = untracked_files_for_uploads.create!(path: long_path)
- expect(record.reload.path.size).to eq(519)
- end
-
- it 'adds unhashed files to the untracked_files_for_uploads table' do
- described_class.new.perform
-
- expect(untracked_files_for_uploads.count).to eq(5)
- end
-
- it 'adds files with paths relative to CarrierWave.root' do
- described_class.new.perform
- untracked_files_for_uploads.all.each do |file|
- expect(file.path.start_with?('uploads/')).to be_truthy
- end
- end
-
- it 'does not add hashed files to the untracked_files_for_uploads table' do
- described_class.new.perform
-
- hashed_file_path = get_uploads(project2, 'Project').find_by(uploader: 'FileUploader').path
- expect(untracked_files_for_uploads.where("path like '%#{hashed_file_path}%'").exists?).to be_falsey
- end
-
- it 'correctly schedules the follow-up background migration jobs' do
- described_class.new.perform
-
- ids = described_class::UntrackedFile.all.order(:id).pluck(:id)
- expect(described_class::FOLLOW_UP_MIGRATION).to be_scheduled_migration(ids.first, ids.last)
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
- end
-
- # E.g. from a previous failed run of this background migration
- context 'when there is existing data in untracked_files_for_uploads' do
- before do
- described_class.new.perform
- end
-
- it 'does not error or produce duplicates of existing data' do
- expect do
- described_class.new.perform
- end.not_to change { untracked_files_for_uploads.count }.from(5)
- end
- end
-
- # E.g. The installation is in use at the time of migration, and someone has
- # just uploaded a file
- context 'when there are files in /uploads/tmp' do
- let(:tmp_file) { Rails.root.join(described_class::ABSOLUTE_UPLOAD_DIR, 'tmp', 'some_file.jpg') }
-
- before do
- FileUtils.mkdir(File.dirname(tmp_file))
- FileUtils.touch(tmp_file)
- end
-
- after do
- FileUtils.rm(tmp_file)
- end
-
- it 'does not add files from /uploads/tmp' do
- described_class.new.perform
-
- expect(untracked_files_for_uploads.count).to eq(5)
- end
- end
-
- context 'when the last batch size exactly matches the max batch size' do
- it 'does not raise error' do
- stub_const("#{described_class}::FIND_BATCH_SIZE", 5)
-
- expect do
- described_class.new.perform
- end.not_to raise_error
-
- expect(untracked_files_for_uploads.count).to eq(5)
- end
- end
- end
- end
-
- # If running on Postgres 9.2 (like on CI), this whole context is skipped
- # since we're unable to use ON CONFLICT DO NOTHING or IGNORE.
- context "test bulk insert with ON CONFLICT DO NOTHING or IGNORE", if: described_class.new.send(:can_bulk_insert_and_ignore_duplicates?) do
- it_behaves_like 'prepares the untracked_files_for_uploads table'
- end
-
- # If running on Postgres 9.2 (like on CI), the stubbed method has no effect.
- #
- # If running on Postgres 9.5+ or MySQL, then this context effectively tests
- # the bulk insert functionality without ON CONFLICT DO NOTHING or IGNORE.
- context 'test bulk insert without ON CONFLICT DO NOTHING or IGNORE' do
- before do
- allow_any_instance_of(described_class).to receive(:postgresql_pre_9_5?).and_return(true)
- end
-
- it_behaves_like 'prepares the untracked_files_for_uploads table'
- end
-
- # Very new or lightly-used installations that are running this migration
- # may not have an upload directory because they have no uploads.
- context 'when no files were ever uploaded' do
- it 'deletes the `untracked_files_for_uploads` table (and does not raise error)' do
- background_migration = described_class.new
-
- expect(background_migration).to receive(:drop_temp_table)
-
- background_migration.perform
- end
- end
-end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index f733c066127..a340e69df65 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -574,10 +574,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.components_usage_data }
it 'gathers basic components usage data' do
- stub_runtime(:puma)
stub_application_setting(container_registry_vendor: 'gitlab', container_registry_version: 'x.y.z')
- expect(subject[:app_server][:type]).to eq('puma')
expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled)
expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION)
expect(subject[:git][:version]).to eq(Gitlab::Git.version)
@@ -591,32 +589,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:container_registry][:vendor]).to eq('gitlab')
expect(subject[:container_registry][:version]).to eq('x.y.z')
end
-
- def stub_runtime(runtime)
- allow(Gitlab::Runtime).to receive(:identify).and_return(runtime)
- end
- end
-
- describe '.app_server_type' do
- subject { described_class.app_server_type }
-
- it 'successfully identifies runtime and returns the identifier' do
- expect(Gitlab::Runtime).to receive(:identify).and_return(:runtime_identifier)
-
- is_expected.to eq('runtime_identifier')
- end
-
- context 'when runtime is not identified' do
- let(:exception) { Gitlab::Runtime::IdentificationError.new('exception message from runtime identify') }
-
- it 'logs the exception and returns unknown app server type' do
- expect(Gitlab::Runtime).to receive(:identify).and_raise(exception)
-
- expect(Gitlab::AppLogger).to receive(:error).with(exception.message)
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(exception)
- expect(subject).to eq('unknown_app_server_type')
- end
- end
end
describe '.object_store_config' do
diff --git a/spec/requests/api/suggestions_spec.rb b/spec/requests/api/suggestions_spec.rb
index 34d3c54d700..78a2688ac5e 100644
--- a/spec/requests/api/suggestions_spec.rb
+++ b/spec/requests/api/suggestions_spec.rb
@@ -74,7 +74,7 @@ RSpec.describe API::Suggestions do
put api(url, user)
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to eq({ 'message' => 'A suggestion is not applicable.' })
+ expect(json_response).to eq({ 'message' => "Can't apply as this line was changed in a more recent version." })
end
end
@@ -133,7 +133,7 @@ RSpec.describe API::Suggestions do
params: { ids: [suggestion.id, unappliable_suggestion.id] }
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to eq({ 'message' => 'A suggestion is not applicable.' })
+ expect(json_response).to eq({ 'message' => "Can't apply as this line was changed in a more recent version." })
end
end
diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb
index aa9caf35987..d8ade0fbbda 100644
--- a/spec/services/suggestions/apply_service_spec.rb
+++ b/spec/services/suggestions/apply_service_spec.rb
@@ -609,40 +609,16 @@ RSpec.describe Suggestions::ApplyService do
end
end
- context 'suggestion is eligible to be outdated' do
- it 'returns error message' do
- expect(suggestion).to receive(:outdated?) { true }
-
- result = apply_service.new(user, suggestion).execute
-
- expect(result).to eq(message: 'A suggestion is not applicable.',
- status: :error)
- end
- end
-
- context 'note is outdated' do
- before do
- allow(diff_note).to receive(:active?) { false }
- end
+ context 'suggestion is not appliable' do
+ let(:inapplicable_reason) { "Can't apply this suggestion." }
it 'returns error message' do
- result = apply_service.new(user, suggestion).execute
-
- expect(result).to eq(message: 'A suggestion is not applicable.',
- status: :error)
- end
- end
+ expect(suggestion).to receive(:appliable?).and_return(false)
+ expect(suggestion).to receive(:inapplicable_reason).and_return(inapplicable_reason)
- context 'suggestion was already applied' do
- before do
- suggestion.update!(applied: true, commit_id: 'sha')
- end
-
- it 'returns error message' do
result = apply_service.new(user, suggestion).execute
- expect(result).to eq(message: 'A suggestion is not applicable.',
- status: :error)
+ expect(result).to eq(message: inapplicable_reason, status: :error)
end
end
diff --git a/spec/support/migrations_helpers/track_untracked_uploads_helpers.rb b/spec/support/migrations_helpers/track_untracked_uploads_helpers.rb
deleted file mode 100644
index 656be3b6d4d..00000000000
--- a/spec/support/migrations_helpers/track_untracked_uploads_helpers.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-
-module MigrationsHelpers
- module TrackUntrackedUploadsHelpers
- PUBLIC_DIR = File.join(Rails.root, 'tmp', 'tests', 'public')
- UPLOADS_DIR = File.join(PUBLIC_DIR, 'uploads')
- SYSTEM_DIR = File.join(UPLOADS_DIR, '-', 'system')
- UPLOAD_FILENAME = 'image.png'.freeze
- FIXTURE_FILE_PATH = File.join(Rails.root, 'spec', 'fixtures', 'dk.png')
- FIXTURE_CHECKSUM = 'b804383982bb89b00e828e3f44c038cc991d3d1768009fc39ba8e2c081b9fb75'.freeze
-
- def create_or_update_appearance(logo: false, header_logo: false)
- appearance = appearances.first_or_create(title: 'foo', description: 'bar', logo: (UPLOAD_FILENAME if logo), header_logo: (UPLOAD_FILENAME if header_logo))
-
- add_upload(appearance, 'Appearance', 'logo', 'AttachmentUploader') if logo
- add_upload(appearance, 'Appearance', 'header_logo', 'AttachmentUploader') if header_logo
-
- appearance
- end
-
- def create_group(avatar: false)
- index = unique_index(:group)
- group = namespaces.create(name: "group#{index}", path: "group#{index}", avatar: (UPLOAD_FILENAME if avatar))
-
- add_upload(group, 'Group', 'avatar', 'AvatarUploader') if avatar
-
- group
- end
-
- def create_note(attachment: false)
- note = notes.create(attachment: (UPLOAD_FILENAME if attachment))
-
- add_upload(note, 'Note', 'attachment', 'AttachmentUploader') if attachment
-
- note
- end
-
- def create_project(avatar: false)
- group = create_group
- project = projects.create(namespace_id: group.id, path: "project#{unique_index(:project)}", avatar: (UPLOAD_FILENAME if avatar))
- routes.create(path: "#{group.path}/#{project.path}", source_id: project.id, source_type: 'Project') # so Project.find_by_full_path works
-
- add_upload(project, 'Project', 'avatar', 'AvatarUploader') if avatar
-
- project
- end
-
- def create_user(avatar: false)
- user = users.create(email: "foo#{unique_index(:user)}@bar.com", avatar: (UPLOAD_FILENAME if avatar), projects_limit: 100)
-
- add_upload(user, 'User', 'avatar', 'AvatarUploader') if avatar
-
- user
- end
-
- def unique_index(name = :unnamed)
- @unique_index ||= {}
- @unique_index[name] ||= 0
- @unique_index[name] += 1
- end
-
- def add_upload(model, model_type, attachment_type, uploader)
- file_path = upload_file_path(model, model_type, attachment_type)
- path_relative_to_public = file_path.sub("#{PUBLIC_DIR}/", '')
- create_file(file_path)
-
- uploads.create!(
- size: 1062,
- path: path_relative_to_public,
- model_id: model.id,
- model_type: model_type == 'Group' ? 'Namespace' : model_type,
- uploader: uploader,
- checksum: FIXTURE_CHECKSUM
- )
- end
-
- def add_markdown_attachment(project, hashed_storage: false)
- project_dir = hashed_storage ? hashed_project_uploads_dir(project) : legacy_project_uploads_dir(project)
- attachment_dir = File.join(project_dir, SecureRandom.hex)
- attachment_file_path = File.join(attachment_dir, UPLOAD_FILENAME)
- project_attachment_path_relative_to_project = attachment_file_path.sub("#{project_dir}/", '')
- create_file(attachment_file_path)
-
- uploads.create!(
- size: 1062,
- path: project_attachment_path_relative_to_project,
- model_id: project.id,
- model_type: 'Project',
- uploader: 'FileUploader',
- checksum: FIXTURE_CHECKSUM
- )
- end
-
- def legacy_project_uploads_dir(project)
- namespace = namespaces.find_by(id: project.namespace_id)
- File.join(UPLOADS_DIR, namespace.path, project.path)
- end
-
- def hashed_project_uploads_dir(project)
- File.join(UPLOADS_DIR, '@hashed', 'aa', 'aaaaaaaaaaaa')
- end
-
- def upload_file_path(model, model_type, attachment_type)
- dir = File.join(upload_dir(model_type.downcase, attachment_type.to_s), model.id.to_s)
- File.join(dir, UPLOAD_FILENAME)
- end
-
- def upload_dir(model_type, attachment_type)
- File.join(SYSTEM_DIR, model_type, attachment_type)
- end
-
- def create_file(path)
- File.delete(path) if File.exist?(path)
- FileUtils.mkdir_p(File.dirname(path))
- FileUtils.cp(FIXTURE_FILE_PATH, path)
- end
-
- def get_uploads(model, model_type)
- uploads.where(model_type: model_type, model_id: model.id)
- end
-
- def get_full_path(project)
- routes.find_by(source_id: project.id, source_type: 'Project').path
- end
-
- def ensure_temporary_tracking_table_exists
- Gitlab::BackgroundMigration::PrepareUntrackedUploads.new.send(:ensure_temporary_tracking_table_exists)
- end
- end
-end