summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-24 12:10:17 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-24 12:10:17 +0000
commit4b9bde7848d9538c1635ffe7a5385ba013487b4a (patch)
tree5aad1d5d94ea233a36c8ac2850e099236e1c2cdc /spec
parent2f752481c2e727834216a93dee82df9f8e2acb2e (diff)
downloadgitlab-ce-4b9bde7848d9538c1635ffe7a5385ba013487b4a.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb28
-rw-r--r--spec/factories/project_statistics.rb1
-rw-r--r--spec/features/admin/admin_settings_spec.rb1
-rw-r--r--spec/features/boards/new_issue_spec.rb43
-rw-r--r--spec/features/labels_hierarchy_spec.rb1
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb8
-rw-r--r--spec/features/projects/services/user_activates_issue_tracker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb2
-rw-r--r--spec/features/projects/user_sees_sidebar_spec.rb5
-rw-r--r--spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js19
-rw-r--r--spec/frontend/boards/stores/actions_spec.js96
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js24
-rw-r--r--spec/frontend/helpers/fake_date.js49
-rw-r--r--spec/frontend/helpers/fake_date_spec.js33
-rw-r--r--spec/frontend/import_projects/components/import_projects_table_spec.js4
-rw-r--r--spec/frontend/integrations/edit/components/active_checkbox_spec.js76
-rw-r--r--spec/frontend/integrations/edit/components/active_toggle_spec.js81
-rw-r--r--spec/frontend/integrations/edit/components/integration_form_spec.js14
-rw-r--r--spec/frontend/integrations/edit/mock_data.js4
-rw-r--r--spec/frontend/issuable_suggestions/components/app_spec.js2
-rw-r--r--spec/frontend/logs/components/environment_logs_spec.js1
-rw-r--r--spec/frontend/logs/components/log_advanced_filters_spec.js1
-rw-r--r--spec/frontend/logs/components/log_control_buttons_spec.js1
-rw-r--r--spec/frontend/logs/components/log_simple_filters_spec.js1
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js6
-rw-r--r--spec/frontend/packages/details/components/package_history_spec.js6
-rw-r--r--spec/frontend/performance_bar/services/performance_bar_service_spec.js37
-rw-r--r--spec/frontend/pipelines/components/pipelines_filtered_search_spec.js1
-rw-r--r--spec/frontend/pipelines/pipelines_actions_spec.js6
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_status_token_spec.js17
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js32
-rw-r--r--spec/frontend/vue_shared/components/table_pagination_spec.js4
-rw-r--r--spec/helpers/user_callouts_helper_spec.rb20
-rw-r--r--spec/lib/gitlab/badge/pipeline/status_spec.rb28
-rw-r--r--spec/models/ci/pipeline_artifact_spec.rb4
-rw-r--r--spec/models/project_statistics_spec.rb19
-rw-r--r--spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb10
-rw-r--r--spec/support/helpers/test_env.rb18
-rw-r--r--spec/support/shared_contexts/project_service_jira_context.rb2
-rw-r--r--spec/support/shared_contexts/project_service_shared_context.rb4
-rw-r--r--spec/views/admin/services/index.html.haml_spec.rb30
-rw-r--r--spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb26
-rw-r--r--spec/workers/deployments/finished_worker_spec.rb12
44 files changed, 549 insertions, 232 deletions
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 7e7a630921f..242b2fd3ec6 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
RSpec.describe Projects::BadgesController do
- let(:project) { pipeline.project }
- let!(:pipeline) { create(:ci_empty_pipeline) }
- let(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :repository) }
+ let_it_be(:pipeline, reload: true) { create(:ci_empty_pipeline, project: project) }
+ let_it_be(:user) { create(:user) }
shared_examples 'a badge resource' do |badge_type|
context 'when pipelines are public' do
@@ -137,6 +137,26 @@ RSpec.describe Projects::BadgesController do
describe '#pipeline' do
it_behaves_like 'a badge resource', :pipeline
+
+ context 'with ignore_skipped param' do
+ render_views
+
+ before do
+ pipeline.update!(status: :skipped)
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ it 'returns skipped badge if set to false' do
+ get_badge(:pipeline, ignore_skipped: false)
+ expect(response.body).to include('skipped')
+ end
+
+ it 'does not return skipped badge if set to true' do
+ get_badge(:pipeline, ignore_skipped: true)
+ expect(response.body).to include('unknown')
+ end
+ end
end
describe '#coverage' do
@@ -148,7 +168,7 @@ RSpec.describe Projects::BadgesController do
namespace_id: project.namespace.to_param,
project_id: project,
ref: pipeline.ref
- }.merge(args.slice(:style, :key_text, :key_width))
+ }.merge(args.slice(:style, :key_text, :key_width, :ignore_skipped))
get badge, params: params, format: :svg
end
diff --git a/spec/factories/project_statistics.rb b/spec/factories/project_statistics.rb
index 78e80a92b3a..ea003b67db0 100644
--- a/spec/factories/project_statistics.rb
+++ b/spec/factories/project_statistics.rb
@@ -22,6 +22,7 @@ FactoryBot.define do
project_statistics.build_artifacts_size = evaluator.size_multiplier * 4
project_statistics.packages_size = evaluator.size_multiplier * 5
project_statistics.snippets_size = evaluator.size_multiplier * 6
+ project_statistics.pipeline_artifacts_size = evaluator.size_multiplier * 7
end
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index f5b05c76e90..c281ba3aab9 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -525,6 +525,7 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
end
def check_all_events
+ page.check('Active')
page.check('Push')
page.check('Issue')
page.check('Confidential Issue')
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index efa1f8cfc0d..f434ea0c66f 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -130,24 +130,43 @@ RSpec.describe 'Issue Boards new issue', :js do
context 'group boards' do
let_it_be(:group) { create(:group, :public) }
- let_it_be(:project) { create(:project, namespace: group) }
+ let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:group_board) { create(:board, group: group) }
- let_it_be(:list) { create(:list, board: group_board, position: 0) }
+ let_it_be(:project_label) { create(:label, project: project, name: 'label') }
+ let_it_be(:list) { create(:list, board: group_board, label: project_label, position: 0) }
context 'for unauthorized users' do
- before do
- sign_in(user)
- visit group_board_path(group, group_board)
- wait_for_requests
- end
+ context 'when backlog does not exist' do
+ before do
+ sign_in(user)
+ visit group_board_path(group, group_board)
+ wait_for_requests
+ end
- it 'displays new issue button in open list' do
- expect(first('.board')).to have_selector('.issue-count-badge-add-button', count: 1)
+ it 'does not display new issue button in label list' do
+ page.within('.board.is-draggable') do
+ expect(page).not_to have_selector('.issue-count-badge-add-button')
+ end
+ end
end
- it 'does not display new issue button in label list' do
- page.within('.board.is-draggable') do
- expect(page).not_to have_selector('.issue-count-badge-add-button')
+ context 'when backlog list already exists' do
+ let!(:backlog_list) { create(:backlog_list, board: group_board) }
+
+ before do
+ sign_in(user)
+ visit group_board_path(group, group_board)
+ wait_for_requests
+ end
+
+ it 'displays new issue button in open list' do
+ expect(first('.board')).to have_selector('.issue-count-badge-add-button', count: 1)
+ end
+
+ it 'does not display new issue button in label list' do
+ page.within('.board.is-draggable') do
+ expect(page).not_to have_selector('.issue-count-badge-add-button')
+ end
end
end
end
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 1545cb36e9b..51dcf57eb94 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -296,6 +296,7 @@ RSpec.describe 'Labels Hierarchy', :js do
let(:board) { create(:board, group: parent) }
before do
+ stub_feature_flags(graphql_board_lists: false)
parent.add_developer(user)
visit group_board_path(parent, board)
find('.js-new-board-list').click
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 8747b3ab54c..a9c196bb84b 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -311,7 +311,7 @@ RSpec.describe 'Pipelines', :js do
let!(:delayed_job) do
create(:ci_build, :scheduled,
pipeline: pipeline,
- name: 'delayed job',
+ name: 'delayed job 1',
stage: 'test')
end
@@ -327,7 +327,7 @@ RSpec.describe 'Pipelines', :js do
find('.js-pipeline-dropdown-manual-actions').click
time_diff = [0, delayed_job.scheduled_at - Time.now].max
- expect(page).to have_button('delayed job')
+ expect(page).to have_button('delayed job 1')
expect(page).to have_content(Time.at(time_diff).utc.strftime("%H:%M:%S"))
end
@@ -335,7 +335,7 @@ RSpec.describe 'Pipelines', :js do
let!(:delayed_job) do
create(:ci_build, :expired_scheduled,
pipeline: pipeline,
- name: 'delayed job',
+ name: 'delayed job 1',
stage: 'test')
end
@@ -349,7 +349,7 @@ RSpec.describe 'Pipelines', :js do
context 'when user played a delayed job immediately' do
before do
find('.js-pipeline-dropdown-manual-actions').click
- page.accept_confirm { click_button('delayed job') }
+ page.accept_confirm { click_button('delayed job 1') }
wait_for_requests
end
diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
index 4f25794d058..c7389460a07 100644
--- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'User activates issue tracker', :js do
let(:url) { 'http://tracker.example.com' }
def fill_form(disable: false, skip_new_issue_url: false)
- click_active_toggle if disable
+ click_active_checkbox if disable
fill_in 'service_project_url', with: url
fill_in 'service_issues_url', with: "#{url}/:id"
diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
index 6ddffb710a8..1b94856d640 100644
--- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
token = ('a'..'z').to_a.join
fill_in 'service_token', with: token
- click_active_toggle
+ click_active_checkbox
click_on 'Save changes'
expect(current_path).to eq(edit_project_service_path(project, :mattermost_slash_commands))
diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
index afe6855d6ad..7a0b56027fe 100644
--- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Slack slash commands', :js do
it 'redirects to the integrations page after saving but not activating' do
fill_in 'Token', with: 'token'
- click_active_toggle
+ click_active_checkbox
click_on 'Save'
expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands))
diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb
index 1d443e0b339..50d7b353c46 100644
--- a/spec/features/projects/user_sees_sidebar_spec.rb
+++ b/spec/features/projects/user_sees_sidebar_spec.rb
@@ -6,10 +6,6 @@ RSpec.describe 'Projects > User sees sidebar' do
let(:user) { create(:user) }
let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) }
- before do
- stub_feature_flags(vue_issuables_list: false)
- end
-
# NOTE: See documented behaviour https://design.gitlab.com/regions/navigation#contextual-navigation
context 'on different viewports', :js do
include MobileHelpers
@@ -134,6 +130,7 @@ RSpec.describe 'Projects > User sees sidebar' do
context 'as guest' do
let(:guest) { create(:user) }
+ let!(:issue) { create(:issue, :opened, project: project, author: guest) }
before do
project.add_guest(guest)
diff --git a/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js b/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js
index 2814b5ce357..ea7b4584a63 100644
--- a/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js
@@ -1,6 +1,7 @@
import { mount } from '@vue/test-utils';
import SidebarTodo from '~/alert_management/components/sidebar/sidebar_todo.vue';
-import AlertMarkTodo from '~/alert_management/graphql/mutations/alert_todo_create.mutation.graphql';
+import createAlertTodoMutation from '~/alert_management/graphql/mutations/alert_todo_create.mutation.graphql';
+import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
import mockAlerts from '../mocks/alerts.json';
const mockAlert = mockAlerts[0];
@@ -61,14 +62,14 @@ describe('Alert Details Sidebar To Do', () => {
expect(findToDoButton().text()).toBe('Add a To-Do');
});
- it('calls `$apollo.mutate` with `AlertMarkTodo` mutation and variables containing `iid`, `todoEvent`, & `projectPath`', async () => {
+ it('calls `$apollo.mutate` with `createAlertTodoMutation` mutation and variables containing `iid`, `todoEvent`, & `projectPath`', async () => {
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
findToDoButton().trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
- mutation: AlertMarkTodo,
+ mutation: createAlertTodoMutation,
variables: {
iid: '1527542',
projectPath: 'projectPath',
@@ -76,6 +77,7 @@ describe('Alert Details Sidebar To Do', () => {
});
});
});
+
describe('removing a todo', () => {
beforeEach(() => {
mountComponent({
@@ -91,12 +93,19 @@ describe('Alert Details Sidebar To Do', () => {
expect(findToDoButton().text()).toBe('Mark as done');
});
- it('calls `$apollo.mutate` with `AlertMarkTodoDone` mutation and variables containing `id`', async () => {
+ it('calls `$apollo.mutate` with `todoMarkDoneMutation` mutation and variables containing `id`', async () => {
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
findToDoButton().trigger('click');
await wrapper.vm.$nextTick();
- expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledTimes(1);
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+ mutation: todoMarkDoneMutation,
+ update: expect.anything(),
+ variables: {
+ id: '1234',
+ },
+ });
});
});
});
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 71e62a4ac5d..54b8d499324 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -1,7 +1,7 @@
import testAction from 'helpers/vuex_action_helper';
-import actions from '~/boards/stores/actions';
+import actions, { gqlClient } from '~/boards/stores/actions';
import * as types from '~/boards/stores/mutation_types';
-import { inactiveId } from '~/boards/constants';
+import { inactiveId, ListType } from '~/boards/constants';
const expectNotImplemented = action => {
it('is not implemented', () => {
@@ -62,8 +62,31 @@ describe('setActiveId', () => {
});
});
-describe('fetchLists', () => {
- expectNotImplemented(actions.fetchLists);
+describe('showWelcomeList', () => {
+ it('should dispatch addList action', done => {
+ const state = {
+ endpoints: { fullPath: 'gitlab-org', boardId: '1' },
+ boardType: 'group',
+ disabled: false,
+ boardLists: [{ type: 'backlog' }, { type: 'closed' }],
+ };
+
+ const blankList = {
+ id: 'blank',
+ listType: ListType.blank,
+ title: 'Welcome to your issue board!',
+ position: 0,
+ };
+
+ testAction(
+ actions.showWelcomeList,
+ {},
+ state,
+ [],
+ [{ type: 'addList', payload: blankList }],
+ done,
+ );
+ });
});
describe('generateDefaultLists', () => {
@@ -71,7 +94,70 @@ describe('generateDefaultLists', () => {
});
describe('createList', () => {
- expectNotImplemented(actions.createList);
+ it('should dispatch addList action when creating backlog list', done => {
+ const backlogList = {
+ id: 'gid://gitlab/List/1',
+ listType: 'backlog',
+ title: 'Open',
+ position: 0,
+ };
+
+ jest.spyOn(gqlClient, 'mutate').mockReturnValue(
+ Promise.resolve({
+ data: {
+ boardListCreate: {
+ list: backlogList,
+ errors: [],
+ },
+ },
+ }),
+ );
+
+ const state = {
+ endpoints: { fullPath: 'gitlab-org', boardId: '1' },
+ boardType: 'group',
+ disabled: false,
+ boardLists: [{ type: 'closed' }],
+ };
+
+ testAction(
+ actions.createList,
+ { backlog: true },
+ state,
+ [],
+ [{ type: 'addList', payload: { ...backlogList, id: 1 } }],
+ done,
+ );
+ });
+
+ it('should commit CREATE_LIST_FAILURE mutation when API returns an error', done => {
+ jest.spyOn(gqlClient, 'mutate').mockReturnValue(
+ Promise.resolve({
+ data: {
+ boardListCreate: {
+ list: {},
+ errors: [{ foo: 'bar' }],
+ },
+ },
+ }),
+ );
+
+ const state = {
+ endpoints: { fullPath: 'gitlab-org', boardId: '1' },
+ boardType: 'group',
+ disabled: false,
+ boardLists: [{ type: 'closed' }],
+ };
+
+ testAction(
+ actions.createList,
+ { backlog: true },
+ state,
+ [{ type: types.CREATE_LIST_FAILURE }],
+ [],
+ done,
+ );
+ });
});
describe('updateList', () => {
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index e5b26e9994e..51833241b37 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -1,6 +1,7 @@
import mutations from '~/boards/stores/mutations';
+import * as types from '~/boards/stores/mutation_types';
import defaultState from '~/boards/stores/state';
-import { mockIssue } from '../mock_data';
+import { listObj, listObjDuplicate, mockIssue } from '../mock_data';
const expectNotImplemented = action => {
it('is not implemented', () => {
@@ -26,11 +27,30 @@ describe('Board Store Mutations', () => {
fullPath: 'gitlab-org',
};
const boardType = 'group';
+ const disabled = false;
+ const showPromotion = false;
- mutations.SET_INITIAL_BOARD_DATA(state, { ...endpoints, boardType });
+ mutations[types.SET_INITIAL_BOARD_DATA](state, {
+ ...endpoints,
+ boardType,
+ disabled,
+ showPromotion,
+ });
expect(state.endpoints).toEqual(endpoints);
expect(state.boardType).toEqual(boardType);
+ expect(state.disabled).toEqual(disabled);
+ expect(state.showPromotion).toEqual(showPromotion);
+ });
+ });
+
+ describe('RECEIVE_LISTS', () => {
+ it('Should set boardLists to state', () => {
+ const lists = [listObj, listObjDuplicate];
+
+ mutations[types.RECEIVE_LISTS](state, lists);
+
+ expect(state.boardLists).toEqual(lists);
});
});
diff --git a/spec/frontend/helpers/fake_date.js b/spec/frontend/helpers/fake_date.js
new file mode 100644
index 00000000000..8417b1c520a
--- /dev/null
+++ b/spec/frontend/helpers/fake_date.js
@@ -0,0 +1,49 @@
+// Frida Kahlo's birthday (6 = July)
+export const DEFAULT_ARGS = [2020, 6, 6];
+
+const RealDate = Date;
+
+const isMocked = val => Boolean(val.mock);
+
+export const createFakeDateClass = ctorDefault => {
+ const FakeDate = new Proxy(RealDate, {
+ construct: (target, argArray) => {
+ const ctorArgs = argArray.length ? argArray : ctorDefault;
+
+ return new RealDate(...ctorArgs);
+ },
+ apply: (target, thisArg, argArray) => {
+ const ctorArgs = argArray.length ? argArray : ctorDefault;
+
+ return RealDate(...ctorArgs);
+ },
+ // We want to overwrite the default 'now', but only if it's not already mocked
+ get: (target, prop) => {
+ if (prop === 'now' && !isMocked(target[prop])) {
+ return () => new RealDate(...ctorDefault).getTime();
+ }
+
+ return target[prop];
+ },
+ getPrototypeOf: target => {
+ return target.prototype;
+ },
+ // We need to be able to set props so that `jest.spyOn` will work.
+ set: (target, prop, value) => {
+ // eslint-disable-next-line no-param-reassign
+ target[prop] = value;
+ return true;
+ },
+ });
+
+ return FakeDate;
+};
+
+export const useFakeDate = (...args) => {
+ const FakeDate = createFakeDateClass(args.length ? args : DEFAULT_ARGS);
+ global.Date = FakeDate;
+};
+
+export const useRealDate = () => {
+ global.Date = RealDate;
+};
diff --git a/spec/frontend/helpers/fake_date_spec.js b/spec/frontend/helpers/fake_date_spec.js
new file mode 100644
index 00000000000..8afc8225f9b
--- /dev/null
+++ b/spec/frontend/helpers/fake_date_spec.js
@@ -0,0 +1,33 @@
+import { createFakeDateClass, DEFAULT_ARGS, useRealDate } from './fake_date';
+
+describe('spec/helpers/fake_date', () => {
+ describe('createFakeDateClass', () => {
+ let FakeDate;
+
+ beforeAll(() => {
+ useRealDate();
+ });
+
+ beforeEach(() => {
+ FakeDate = createFakeDateClass(DEFAULT_ARGS);
+ });
+
+ it('should use default args', () => {
+ expect(new FakeDate()).toEqual(new Date(...DEFAULT_ARGS));
+ expect(FakeDate()).toEqual(Date(...DEFAULT_ARGS));
+ });
+
+ it('should have deterministic now()', () => {
+ expect(FakeDate.now()).not.toBe(Date.now());
+ expect(FakeDate.now()).toBe(new Date(...DEFAULT_ARGS).getTime());
+ });
+
+ it('should be instanceof Date', () => {
+ expect(new FakeDate()).toBeInstanceOf(Date);
+ });
+
+ it('should be instanceof self', () => {
+ expect(new FakeDate()).toBeInstanceOf(FakeDate);
+ });
+ });
+});
diff --git a/spec/frontend/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_projects/components/import_projects_table_spec.js
index b217242968a..7ae4d650e36 100644
--- a/spec/frontend/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_projects/components/import_projects_table_spec.js
@@ -110,8 +110,8 @@ describe('ImportProjectsTable', () => {
wrapper
.findAll('th')
.filter(w => w.text() === `From ${providerTitle}`)
- .isEmpty(),
- ).toBe(false);
+ .exists(),
+ ).toBe(true);
expect(wrapper.contains(ProviderRepoTableRow)).toBe(true);
expect(wrapper.contains(ImportedProjectTableRow)).toBe(true);
diff --git a/spec/frontend/integrations/edit/components/active_checkbox_spec.js b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
new file mode 100644
index 00000000000..38bcb1e0aab
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
@@ -0,0 +1,76 @@
+import { mount } from '@vue/test-utils';
+import { GlFormCheckbox } from '@gitlab/ui';
+import { createStore } from '~/integrations/edit/store';
+
+import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
+
+describe('ActiveCheckbox', () => {
+ let wrapper;
+
+ const createComponent = (customStateProps = {}, isInheriting = false) => {
+ wrapper = mount(ActiveCheckbox, {
+ store: createStore({
+ customState: { ...customStateProps },
+ }),
+ computed: {
+ isInheriting: () => isInheriting,
+ },
+ });
+ };
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ const findGlFormCheckbox = () => wrapper.find(GlFormCheckbox);
+ const findInputInCheckbox = () => findGlFormCheckbox().find('input');
+
+ describe('template', () => {
+ describe('is inheriting adminSettings', () => {
+ it('renders GlFormCheckbox as disabled', () => {
+ createComponent({}, true);
+
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ expect(findInputInCheckbox().attributes('disabled')).toBe('disabled');
+ });
+ });
+
+ describe('initialActivated is false', () => {
+ it('renders GlFormCheckbox as unchecked', () => {
+ createComponent({
+ initialActivated: false,
+ });
+
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ expect(findGlFormCheckbox().vm.$attrs.checked).toBe(false);
+ expect(findInputInCheckbox().attributes('disabled')).toBeUndefined();
+ });
+ });
+
+ describe('initialActivated is true', () => {
+ beforeEach(() => {
+ createComponent({
+ initialActivated: true,
+ });
+ });
+
+ it('renders GlFormCheckbox as checked', () => {
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ expect(findGlFormCheckbox().vm.$attrs.checked).toBe(true);
+ });
+
+ describe('on checkbox click', () => {
+ it('switches the form value', async () => {
+ findInputInCheckbox().trigger('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(findGlFormCheckbox().vm.$attrs.checked).toBe(false);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/active_toggle_spec.js b/spec/frontend/integrations/edit/components/active_toggle_spec.js
deleted file mode 100644
index 228d8f5fc30..00000000000
--- a/spec/frontend/integrations/edit/components/active_toggle_spec.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { mount } from '@vue/test-utils';
-import { GlToggle } from '@gitlab/ui';
-
-import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
-
-const GL_TOGGLE_ACTIVE_CLASS = 'is-checked';
-const GL_TOGGLE_DISABLED_CLASS = 'is-disabled';
-
-describe('ActiveToggle', () => {
- let wrapper;
-
- const defaultProps = {
- initialActivated: true,
- };
-
- const createComponent = (props = {}, isInheriting = false) => {
- wrapper = mount(ActiveToggle, {
- propsData: { ...defaultProps, ...props },
- computed: {
- isInheriting: () => isInheriting,
- },
- });
- };
-
- afterEach(() => {
- if (wrapper) {
- wrapper.destroy();
- wrapper = null;
- }
- });
-
- const findGlToggle = () => wrapper.find(GlToggle);
- const findButtonInToggle = () => findGlToggle().find('button');
- const findInputInToggle = () => findGlToggle().find('input');
-
- describe('template', () => {
- describe('is inheriting adminSettings', () => {
- it('renders GlToggle as disabled', () => {
- createComponent({}, true);
-
- expect(findGlToggle().exists()).toBe(true);
- expect(findButtonInToggle().classes()).toContain(GL_TOGGLE_DISABLED_CLASS);
- });
- });
-
- describe('initialActivated is false', () => {
- it('renders GlToggle as inactive', () => {
- createComponent({
- initialActivated: false,
- });
-
- expect(findGlToggle().exists()).toBe(true);
- expect(findButtonInToggle().classes()).not.toContain(GL_TOGGLE_ACTIVE_CLASS);
- expect(findInputInToggle().attributes('value')).toBe('false');
- });
- });
-
- describe('initialActivated is true', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders GlToggle as active', () => {
- expect(findGlToggle().exists()).toBe(true);
- expect(findButtonInToggle().classes()).toContain(GL_TOGGLE_ACTIVE_CLASS);
- expect(findInputInToggle().attributes('value')).toBe('true');
- });
-
- describe('on toggle click', () => {
- it('switches the form value', () => {
- findButtonInToggle().trigger('click');
-
- wrapper.vm.$nextTick(() => {
- expect(findButtonInToggle().classes()).not.toContain(GL_TOGGLE_ACTIVE_CLASS);
- expect(findInputInToggle().attributes('value')).toBe('false');
- });
- });
- });
- });
- });
-});
diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js
index f8e2eb5e7f4..fccb56f4597 100644
--- a/spec/frontend/integrations/edit/components/integration_form_spec.js
+++ b/spec/frontend/integrations/edit/components/integration_form_spec.js
@@ -3,7 +3,7 @@ import { mockIntegrationProps } from 'jest/integrations/edit/mock_data';
import { createStore } from '~/integrations/edit/store';
import IntegrationForm from '~/integrations/edit/components/integration_form.vue';
import OverrideDropdown from '~/integrations/edit/components/override_dropdown.vue';
-import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
+import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
@@ -21,7 +21,7 @@ describe('IntegrationForm', () => {
}),
stubs: {
OverrideDropdown,
- ActiveToggle,
+ ActiveCheckbox,
JiraTriggerFields,
TriggerFields,
},
@@ -39,27 +39,27 @@ describe('IntegrationForm', () => {
});
const findOverrideDropdown = () => wrapper.find(OverrideDropdown);
- const findActiveToggle = () => wrapper.find(ActiveToggle);
+ const findActiveCheckbox = () => wrapper.find(ActiveCheckbox);
const findJiraTriggerFields = () => wrapper.find(JiraTriggerFields);
const findJiraIssuesFields = () => wrapper.find(JiraIssuesFields);
const findTriggerFields = () => wrapper.find(TriggerFields);
describe('template', () => {
describe('showActive is true', () => {
- it('renders ActiveToggle', () => {
+ it('renders ActiveCheckbox', () => {
createComponent();
- expect(findActiveToggle().exists()).toBe(true);
+ expect(findActiveCheckbox().exists()).toBe(true);
});
});
describe('showActive is false', () => {
- it('does not render ActiveToggle', () => {
+ it('does not render ActiveCheckbox', () => {
createComponent({
showActive: false,
});
- expect(findActiveToggle().exists()).toBe(false);
+ expect(findActiveCheckbox().exists()).toBe(false);
});
});
diff --git a/spec/frontend/integrations/edit/mock_data.js b/spec/frontend/integrations/edit/mock_data.js
index 0886290c908..821972b7698 100644
--- a/spec/frontend/integrations/edit/mock_data.js
+++ b/spec/frontend/integrations/edit/mock_data.js
@@ -1,8 +1,6 @@
export const mockIntegrationProps = {
id: 25,
- activeToggleProps: {
- initialActivated: true,
- },
+ initialActivated: true,
showActive: true,
triggerFieldsProps: {
initialTriggerCommit: false,
diff --git a/spec/frontend/issuable_suggestions/components/app_spec.js b/spec/frontend/issuable_suggestions/components/app_spec.js
index d51c89807be..015bd1b1efb 100644
--- a/spec/frontend/issuable_suggestions/components/app_spec.js
+++ b/spec/frontend/issuable_suggestions/components/app_spec.js
@@ -41,7 +41,7 @@ describe('Issuable suggestions app component', () => {
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
- expect(wrapper.isEmpty()).toBe(false);
+ expect(wrapper.findAll('li').length).toBe(data.issues.length);
});
});
diff --git a/spec/frontend/logs/components/environment_logs_spec.js b/spec/frontend/logs/components/environment_logs_spec.js
index 6421aca684f..c998fbfaf41 100644
--- a/spec/frontend/logs/components/environment_logs_spec.js
+++ b/spec/frontend/logs/components/environment_logs_spec.js
@@ -122,7 +122,6 @@ describe('EnvironmentLogs', () => {
initWrapper();
expect(wrapper.isVueInstance()).toBe(true);
- expect(wrapper.isEmpty()).toBe(false);
expect(findEnvironmentsDropdown().is(GlDeprecatedDropdown)).toBe(true);
expect(findSimpleFilters().exists()).toBe(true);
diff --git a/spec/frontend/logs/components/log_advanced_filters_spec.js b/spec/frontend/logs/components/log_advanced_filters_spec.js
index 007c5000e16..af472790a18 100644
--- a/spec/frontend/logs/components/log_advanced_filters_spec.js
+++ b/spec/frontend/logs/components/log_advanced_filters_spec.js
@@ -69,7 +69,6 @@ describe('LogAdvancedFilters', () => {
initWrapper();
expect(wrapper.isVueInstance()).toBe(true);
- expect(wrapper.isEmpty()).toBe(false);
expect(findFilteredSearch().exists()).toBe(true);
expect(findTimeRangePicker().exists()).toBe(true);
diff --git a/spec/frontend/logs/components/log_control_buttons_spec.js b/spec/frontend/logs/components/log_control_buttons_spec.js
index 38e568f569f..9b3e2ebbafa 100644
--- a/spec/frontend/logs/components/log_control_buttons_spec.js
+++ b/spec/frontend/logs/components/log_control_buttons_spec.js
@@ -29,7 +29,6 @@ describe('LogControlButtons', () => {
initWrapper();
expect(wrapper.isVueInstance()).toBe(true);
- expect(wrapper.isEmpty()).toBe(false);
expect(findScrollToTop().is(GlButton)).toBe(true);
expect(findScrollToBottom().is(GlButton)).toBe(true);
diff --git a/spec/frontend/logs/components/log_simple_filters_spec.js b/spec/frontend/logs/components/log_simple_filters_spec.js
index e739621431e..c7908dc2cc5 100644
--- a/spec/frontend/logs/components/log_simple_filters_spec.js
+++ b/spec/frontend/logs/components/log_simple_filters_spec.js
@@ -60,7 +60,6 @@ describe('LogSimpleFilters', () => {
initWrapper();
expect(wrapper.isVueInstance()).toBe(true);
- expect(wrapper.isEmpty()).toBe(false);
expect(findPodsDropdown().exists()).toBe(true);
});
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index f37d95317ab..ca01f821da3 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -668,7 +668,11 @@ describe('Dashboard', () => {
});
it('shows a remove button, which removes a panel', () => {
- expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
+ expect(
+ findFirstDraggableRemoveButton()
+ .find('a')
+ .exists(),
+ ).toBe(true);
expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
findFirstDraggableRemoveButton().trigger('click');
diff --git a/spec/frontend/packages/details/components/package_history_spec.js b/spec/frontend/packages/details/components/package_history_spec.js
index e293e119585..28bcbbb2b1b 100644
--- a/spec/frontend/packages/details/components/package_history_spec.js
+++ b/spec/frontend/packages/details/components/package_history_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { GlLink, GlSprintf } from '@gitlab/ui';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import HistoryElement from '~/packages/details/components/history_element.vue';
import component from '~/packages/details/components/package_history.vue';
import { mavenPackage, mockPipelineInfo } from '../../mock_data';
@@ -16,7 +17,10 @@ describe('Package History', () => {
wrapper = shallowMount(component, {
propsData: { ...defaultProps, ...props },
stubs: {
- HistoryElement: '<div data-testid="history-element"><slot></slot></div>',
+ HistoryElement: {
+ props: HistoryElement.props,
+ template: '<div data-testid="history-element"><slot></slot></div>',
+ },
GlSprintf,
},
});
diff --git a/spec/frontend/performance_bar/services/performance_bar_service_spec.js b/spec/frontend/performance_bar/services/performance_bar_service_spec.js
index 5e7a52ba734..36bfd575c12 100644
--- a/spec/frontend/performance_bar/services/performance_bar_service_spec.js
+++ b/spec/frontend/performance_bar/services/performance_bar_service_spec.js
@@ -8,13 +8,13 @@ describe('PerformanceBarService', () => {
}
it('returns false when the request URL is the peek URL', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/peek' }, '/peek')).toBe(
- false,
- );
+ expect(
+ fireCallback({ headers: { 'x-request-id': '123' }, config: { url: '/peek' } }, '/peek'),
+ ).toBe(false);
});
it('returns false when there is no request ID', () => {
- expect(fireCallback({ headers: {}, url: '/request' }, '/peek')).toBe(false);
+ expect(fireCallback({ headers: {}, config: { url: '/request' } }, '/peek')).toBe(false);
});
it('returns false when the response is from the cache', () => {
@@ -27,15 +27,18 @@ describe('PerformanceBarService', () => {
});
it('returns true when the request is an API request', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/api/' }, '/peek')).toBe(
- true,
- );
+ expect(
+ fireCallback({ headers: { 'x-request-id': '123' }, config: { url: '/api/' } }, '/peek'),
+ ).toBe(true);
});
it('returns true for all other requests', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/request' }, '/peek')).toBe(
- true,
- );
+ expect(
+ fireCallback(
+ { headers: { 'x-request-id': '123' }, config: { url: '/request' } },
+ '/peek',
+ ),
+ ).toBe(true);
});
});
@@ -45,7 +48,7 @@ describe('PerformanceBarService', () => {
}
it('gets the request ID from the headers', () => {
- expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek')).toEqual('123');
+ expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek')).toBe('123');
});
});
@@ -54,14 +57,10 @@ describe('PerformanceBarService', () => {
return PerformanceBarService.callbackParams(response, peekUrl)[2];
}
- it('gets the request URL from the response object', () => {
- expect(requestUrl({ headers: {}, url: '/request' }, '/peek')).toEqual('/request');
- });
-
- it('gets the request URL from response.config if present', () => {
- expect(
- requestUrl({ headers: {}, config: { url: '/config-url' }, url: '/request' }, '/peek'),
- ).toEqual('/config-url');
+ it('gets the request URL from response.config', () => {
+ expect(requestUrl({ headers: {}, config: { url: '/config-url' } }, '/peek')).toBe(
+ '/config-url',
+ );
});
});
});
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
index c5b7318d3af..3c9982ecee3 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
@@ -48,7 +48,6 @@ describe('Pipelines filtered search', () => {
it('displays UI elements', () => {
expect(wrapper.isVueInstance()).toBe(true);
- expect(wrapper.isEmpty()).toBe(false);
expect(findFilteredSearch().exists()).toBe(true);
});
diff --git a/spec/frontend/pipelines/pipelines_actions_spec.js b/spec/frontend/pipelines/pipelines_actions_spec.js
index cce4c2dfa7b..071a2b24889 100644
--- a/spec/frontend/pipelines/pipelines_actions_spec.js
+++ b/spec/frontend/pipelines/pipelines_actions_spec.js
@@ -1,7 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { TEST_HOST } from 'spec/test_constants';
-import { GlDeprecatedButton } from '@gitlab/ui';
+import { GlButton } from '@gitlab/ui';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import PipelinesActions from '~/pipelines/components/pipelines_list/pipelines_actions.vue';
@@ -19,7 +19,7 @@ describe('Pipelines Actions dropdown', () => {
});
};
- const findAllDropdownItems = () => wrapper.findAll(GlDeprecatedButton);
+ const findAllDropdownItems = () => wrapper.findAll(GlButton);
const findAllCountdowns = () => wrapper.findAll(GlCountdown);
beforeEach(() => {
@@ -66,7 +66,7 @@ describe('Pipelines Actions dropdown', () => {
it('makes a request and toggles the loading state', () => {
mock.onPost(mockActions.path).reply(200);
- wrapper.find(GlDeprecatedButton).vm.$emit('click');
+ wrapper.find(GlButton).vm.$emit('click');
expect(wrapper.vm.isLoading).toBe(true);
diff --git a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
index 096e4cd97f6..b53955ab743 100644
--- a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
@@ -5,16 +5,17 @@ import PipelineStatusToken from '~/pipelines/components/pipelines_list/tokens/pi
describe('Pipeline Status Token', () => {
let wrapper;
- const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
- const findAllGlIcons = () => wrapper.findAll(GlIcon);
-
const stubs = {
GlFilteredSearchToken: {
+ props: GlFilteredSearchToken.props,
template: `<div><slot name="suggestions"></slot></div>`,
},
};
+ const findFilteredSearchToken = () => wrapper.find(stubs.GlFilteredSearchToken);
+ const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findAllGlIcons = () => wrapper.findAll(GlIcon);
+
const defaultProps = {
config: {
type: 'status',
@@ -27,12 +28,12 @@ describe('Pipeline Status Token', () => {
},
};
- const createComponent = options => {
+ const createComponent = () => {
wrapper = shallowMount(PipelineStatusToken, {
propsData: {
...defaultProps,
},
- ...options,
+ stubs,
});
};
@@ -50,10 +51,6 @@ describe('Pipeline Status Token', () => {
});
describe('shows statuses correctly', () => {
- beforeEach(() => {
- createComponent({ stubs });
- });
-
it('renders all pipeline statuses available', () => {
expect(findAllFilteredSearchSuggestions()).toHaveLength(wrapper.vm.statuses.length);
expect(findAllGlIcons()).toHaveLength(wrapper.vm.statuses.length);
diff --git a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
index c95d2ea1b7b..9363944a719 100644
--- a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
@@ -7,16 +7,17 @@ import { users } from '../mock_data';
describe('Pipeline Trigger Author Token', () => {
let wrapper;
- const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
- const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
-
const stubs = {
GlFilteredSearchToken: {
+ props: GlFilteredSearchToken.props,
template: `<div><slot name="suggestions"></slot></div>`,
},
};
+ const findFilteredSearchToken = () => wrapper.find(stubs.GlFilteredSearchToken);
+ const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+
const defaultProps = {
config: {
type: 'username',
@@ -31,7 +32,7 @@ describe('Pipeline Trigger Author Token', () => {
},
};
- const createComponent = (options, data) => {
+ const createComponent = data => {
wrapper = shallowMount(PipelineTriggerAuthorToken, {
propsData: {
...defaultProps,
@@ -41,7 +42,7 @@ describe('Pipeline Trigger Author Token', () => {
...data,
};
},
- ...options,
+ stubs,
});
};
@@ -69,13 +70,13 @@ describe('Pipeline Trigger Author Token', () => {
describe('displays loading icon correctly', () => {
it('shows loading icon', () => {
- createComponent({ stubs }, { loading: true });
+ createComponent({ loading: true });
expect(findLoadingIcon().exists()).toBe(true);
});
it('does not show loading icon', () => {
- createComponent({ stubs }, { loading: false });
+ createComponent({ loading: false });
expect(findLoadingIcon().exists()).toBe(false);
});
@@ -85,22 +86,17 @@ describe('Pipeline Trigger Author Token', () => {
beforeEach(() => {});
it('renders all trigger authors', () => {
- createComponent({ stubs }, { users, loading: false });
+ createComponent({ users, loading: false });
// should have length of all users plus the static 'Any' option
expect(findAllFilteredSearchSuggestions()).toHaveLength(users.length + 1);
});
it('renders only the trigger author searched for', () => {
- createComponent(
- { stubs },
- {
- users: [
- { name: 'Arnold', username: 'admin', state: 'active', avatar_url: 'avatar-link' },
- ],
- loading: false,
- },
- );
+ createComponent({
+ users: [{ name: 'Arnold', username: 'admin', state: 'active', avatar_url: 'avatar-link' }],
+ loading: false,
+ });
expect(findAllFilteredSearchSuggestions()).toHaveLength(2);
});
diff --git a/spec/frontend/vue_shared/components/table_pagination_spec.js b/spec/frontend/vue_shared/components/table_pagination_spec.js
index ef3ae088eec..2a4672c2647 100644
--- a/spec/frontend/vue_shared/components/table_pagination_spec.js
+++ b/spec/frontend/vue_shared/components/table_pagination_spec.js
@@ -50,7 +50,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.isEmpty()).toBe(false);
+ expect(wrapper.find(GlPagination).exists()).toBe(true);
});
it('renders if there is a prev page', () => {
@@ -66,7 +66,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.isEmpty()).toBe(false);
+ expect(wrapper.find(GlPagination).exists()).toBe(true);
});
});
diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb
index 6f1f358af83..a42be3c87fb 100644
--- a/spec/helpers/user_callouts_helper_spec.rb
+++ b/spec/helpers/user_callouts_helper_spec.rb
@@ -81,6 +81,26 @@ RSpec.describe UserCalloutsHelper do
end
end
+ describe '.show_service_templates_deprecated?' do
+ subject { helper.show_service_templates_deprecated? }
+
+ context 'when user has not dismissed' do
+ before do
+ allow(helper).to receive(:user_dismissed?).with(described_class::SERVICE_TEMPLATES_DEPRECATED) { false }
+ end
+
+ it { is_expected.to be true }
+ end
+
+ context 'when user dismissed' do
+ before do
+ allow(helper).to receive(:user_dismissed?).with(described_class::SERVICE_TEMPLATES_DEPRECATED) { true }
+ end
+
+ it { is_expected.to be false }
+ end
+ end
+
describe '.show_customize_homepage_banner?' do
let(:customize_homepage) { true }
diff --git a/spec/lib/gitlab/badge/pipeline/status_spec.rb b/spec/lib/gitlab/badge/pipeline/status_spec.rb
index fcc0d4030fd..b5dabca0477 100644
--- a/spec/lib/gitlab/badge/pipeline/status_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/status_spec.rb
@@ -78,6 +78,34 @@ RSpec.describe Gitlab::Badge::Pipeline::Status do
expect(badge.status).to eq 'success'
end
end
+
+ context 'when ignored_skipped is set to true' do
+ let(:new_badge) { described_class.new(project, branch, opts: { ignore_skipped: true }) }
+
+ before do
+ pipeline.skip!
+ end
+
+ describe '#status' do
+ it 'uses latest non-skipped status' do
+ expect(new_badge.status).not_to eq 'skipped'
+ end
+ end
+ end
+
+ context 'when ignored_skipped is set to false' do
+ let(:new_badge) { described_class.new(project, branch, opts: { ignore_skipped: false }) }
+
+ before do
+ pipeline.skip!
+ end
+
+ describe '#status' do
+ it 'uses latest status' do
+ expect(new_badge.status).to eq 'skipped'
+ end
+ end
+ end
end
context 'build does not exist' do
diff --git a/spec/models/ci/pipeline_artifact_spec.rb b/spec/models/ci/pipeline_artifact_spec.rb
index 9d2172d7572..3a7aa9d33b7 100644
--- a/spec/models/ci/pipeline_artifact_spec.rb
+++ b/spec/models/ci/pipeline_artifact_spec.rb
@@ -12,6 +12,10 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
it_behaves_like 'having unique enum values'
+ it_behaves_like 'UpdateProjectStatistics' do
+ subject { build(:ci_pipeline_artifact) }
+ end
+
describe 'validations' do
it { is_expected.to validate_presence_of(:pipeline) }
it { is_expected.to validate_presence_of(:project) }
diff --git a/spec/models/project_statistics_spec.rb b/spec/models/project_statistics_spec.rb
index 5f66de3a63c..383fabcfffb 100644
--- a/spec/models/project_statistics_spec.rb
+++ b/spec/models/project_statistics_spec.rb
@@ -32,8 +32,9 @@ RSpec.describe ProjectStatistics do
repository_size: 2.exabytes,
wiki_size: 1.exabytes,
lfs_objects_size: 2.exabytes,
- build_artifacts_size: 2.exabytes - 1,
- snippets_size: 1.exabyte
+ build_artifacts_size: 1.exabyte,
+ snippets_size: 1.exabyte,
+ pipeline_artifacts_size: 1.exabyte - 1
)
statistics.reload
@@ -42,9 +43,10 @@ RSpec.describe ProjectStatistics do
expect(statistics.repository_size).to eq(2.exabytes)
expect(statistics.wiki_size).to eq(1.exabytes)
expect(statistics.lfs_objects_size).to eq(2.exabytes)
- expect(statistics.build_artifacts_size).to eq(2.exabytes - 1)
+ expect(statistics.build_artifacts_size).to eq(1.exabyte)
expect(statistics.storage_size).to eq(8.exabytes - 1)
expect(statistics.snippets_size).to eq(1.exabyte)
+ expect(statistics.pipeline_artifacts_size).to eq(1.exabyte - 1)
end
end
@@ -282,12 +284,13 @@ RSpec.describe ProjectStatistics do
repository_size: 2,
wiki_size: 4,
lfs_objects_size: 3,
- snippets_size: 2
+ snippets_size: 2,
+ pipeline_artifacts_size: 3
)
statistics.reload
- expect(statistics.storage_size).to eq 11
+ expect(statistics.storage_size).to eq 14
end
it 'works during wiki_size backfill' do
@@ -339,6 +342,12 @@ RSpec.describe ProjectStatistics do
it_behaves_like 'a statistic that increases storage_size'
end
+ context 'when adjusting :pipeline_artifacts_size' do
+ let(:stat) { :pipeline_artifacts_size }
+
+ it_behaves_like 'a statistic that increases storage_size'
+ end
+
context 'when adjusting :packages_size' do
let(:stat) { :packages_size }
diff --git a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
index db931c50bdf..df8130b9c5d 100644
--- a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
+++ b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
@@ -10,7 +10,7 @@ require_relative '../../../../rubocop/cop/usage_data/distinct_count_by_large_for
RSpec.describe RuboCop::Cop::UsageData::DistinctCountByLargeForeignKey, type: :rubocop do
include CopHelper
- let(:allowed_foreign_keys) { %i[author_id user_id] }
+ let(:allowed_foreign_keys) { [:author_id, :user_id, :'merge_requests.target_project_id'] }
let(:config) do
RuboCop::Config.new('UsageData/DistinctCountByLargeForeignKey' => {
@@ -29,10 +29,16 @@ RSpec.describe RuboCop::Cop::UsageData::DistinctCountByLargeForeignKey, type: :r
end
context 'when calling by allowed key' do
- it 'does not register an offence' do
+ it 'does not register an offence with symbol' do
inspect_source('distinct_count(Issue, :author_id)')
expect(cop.offenses).to be_empty
end
+
+ it 'does not register an offence with string' do
+ inspect_source("distinct_count(Issue, 'merge_requests.target_project_id')")
+
+ expect(cop.offenses).to be_empty
+ end
end
end
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index 641ed24207e..a64871ca75b 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -247,9 +247,8 @@ module TestEnv
'GitLab Workhorse',
install_dir: workhorse_dir,
version: Gitlab::Workhorse.version,
- task: "gitlab:workhorse:install[#{install_workhorse_args}]") do
- Gitlab::SetupHelper::Workhorse.create_configuration(workhorse_dir, nil)
- end
+ task: "gitlab:workhorse:install[#{install_workhorse_args}]"
+ )
end
def workhorse_dir
@@ -260,14 +259,6 @@ module TestEnv
host = "[#{host}]" if host.include?(':')
listen_addr = [host, port].join(':')
- config_path = Gitlab::SetupHelper::Workhorse.get_config_path(workhorse_dir)
-
- # This should be set up in setup_workhorse, but since
- # component_needs_update? only checks that versions are consistent,
- # we need to ensure the config file exists. This line can be removed
- # later after a new Workhorse version is updated.
- Gitlab::SetupHelper::Workhorse.create_configuration(workhorse_dir, nil) unless File.exist?(config_path)
-
workhorse_pid = spawn(
{ 'PATH' => "#{ENV['PATH']}:#{workhorse_dir}" },
File.join(workhorse_dir, 'gitlab-workhorse'),
@@ -275,7 +266,10 @@ module TestEnv
'-documentRoot', Rails.root.join('public').to_s,
'-listenAddr', listen_addr,
'-secretPath', Gitlab::Workhorse.secret_path.to_s,
- '-config', config_path,
+ # TODO: Needed for workhorse + redis features.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/209245
+ #
+ # '-config', '',
'-logFile', 'log/workhorse-test.log',
'-logFormat', 'structured',
'-developmentMode' # to serve assets and rich error messages
diff --git a/spec/support/shared_contexts/project_service_jira_context.rb b/spec/support/shared_contexts/project_service_jira_context.rb
index 4ca5c99323a..8e01de70846 100644
--- a/spec/support/shared_contexts/project_service_jira_context.rb
+++ b/spec/support/shared_contexts/project_service_jira_context.rb
@@ -5,7 +5,7 @@ RSpec.shared_context 'project service Jira context' do
let(:test_url) { 'http://jira.example.com/rest/api/2/serverInfo' }
def fill_form(disable: false)
- click_active_toggle if disable
+ click_active_checkbox if disable
fill_in 'service_url', with: url
fill_in 'service_username', with: 'username'
diff --git a/spec/support/shared_contexts/project_service_shared_context.rb b/spec/support/shared_contexts/project_service_shared_context.rb
index a72d4901b72..36cc81f6689 100644
--- a/spec/support/shared_contexts/project_service_shared_context.rb
+++ b/spec/support/shared_contexts/project_service_shared_context.rb
@@ -18,8 +18,8 @@ RSpec.shared_context 'project service activation' do
click_link(name)
end
- def click_active_toggle
- find('input[name="service[active]"] + button').click
+ def click_active_checkbox
+ find('input[name="service[active]"]').click
end
def click_test_integration
diff --git a/spec/views/admin/services/index.html.haml_spec.rb b/spec/views/admin/services/index.html.haml_spec.rb
new file mode 100644
index 00000000000..e8cd2dde67e
--- /dev/null
+++ b/spec/views/admin/services/index.html.haml_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'admin/services/index.html.haml' do
+ before do
+ assign(:services, build_stubbed_list(:service, 1))
+ assign(:existing_instance_types, [])
+ end
+
+ context 'user has not dismissed Service Templates deprecation message' do
+ it 'shows the message' do
+ allow(view).to receive(:show_service_templates_deprecated?).and_return(true)
+
+ render
+
+ expect(rendered).to have_content('Service Templates will soon be deprecated.')
+ end
+ end
+
+ context 'user has dismissed Service Templates deprecation message' do
+ it 'does not show the message' do
+ allow(view).to receive(:show_service_templates_deprecated?).and_return(false)
+
+ render
+
+ expect(rendered).not_to have_content('Service Templates will soon be deprecated.')
+ end
+ end
+end
diff --git a/spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb b/spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb
index d9f2dd326dd..f510852e753 100644
--- a/spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb
+++ b/spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb
@@ -29,10 +29,8 @@ RSpec.describe Ci::RefDeleteUnlockArtifactsWorker do
context 'when user exists' do
let(:user_id) { project.creator.id }
- context 'when ci ref exists' do
- before do
- create(:ci_ref, ref_path: ref)
- end
+ context 'when ci ref exists for project' do
+ let!(:ci_ref) { create(:ci_ref, ref_path: ref, project: project) }
it 'calls the service' do
service = spy(Ci::UnlockArtifactsService)
@@ -40,17 +38,33 @@ RSpec.describe Ci::RefDeleteUnlockArtifactsWorker do
perform
- expect(service).to have_received(:execute)
+ expect(service).to have_received(:execute).with(ci_ref)
end
end
- context 'when ci ref does not exist' do
+ context 'when ci ref does not exist for the given project' do
+ let!(:another_ci_ref) { create(:ci_ref, ref_path: ref) }
+
it 'does not call the service' do
expect(Ci::UnlockArtifactsService).not_to receive(:new)
perform
end
end
+
+ context 'when same ref path exists for a different project' do
+ let!(:another_ci_ref) { create(:ci_ref, ref_path: ref) }
+ let!(:ci_ref) { create(:ci_ref, ref_path: ref, project: project) }
+
+ it 'calls the service with the correct ref_id' do
+ service = spy(Ci::UnlockArtifactsService)
+ expect(Ci::UnlockArtifactsService).to receive(:new).and_return(service)
+
+ perform
+
+ expect(service).to have_received(:execute).with(ci_ref)
+ end
+ end
end
context 'when user does not exist' do
diff --git a/spec/workers/deployments/finished_worker_spec.rb b/spec/workers/deployments/finished_worker_spec.rb
index e1ec2d89e0a..d0a26ae1547 100644
--- a/spec/workers/deployments/finished_worker_spec.rb
+++ b/spec/workers/deployments/finished_worker_spec.rb
@@ -61,17 +61,5 @@ RSpec.describe Deployments::FinishedWorker do
worker.perform(deployment.id)
end
-
- it 'does not execute webhooks if feature flag is disabled' do
- stub_feature_flags(deployment_webhooks: false)
-
- deployment = create(:deployment)
- project = deployment.project
- create(:project_hook, deployment_events: true, project: project)
-
- expect(WebHookService).not_to receive(:new)
-
- worker.perform(deployment.id)
- end
end
end