summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/users_statistics.rb8
-rw-r--r--spec/features/admin/dashboard_spec.rb26
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/frontend/logs/components/environment_logs_spec.js15
-rw-r--r--spec/frontend/logs/stores/actions_spec.js37
-rw-r--r--spec/frontend/logs/stores/mutations_spec.js9
-rw-r--r--spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap22
-rw-r--r--spec/frontend/repository/components/table/row_spec.js9
-rw-r--r--spec/frontend/vue_shared/components/file_icon_spec.js5
-rw-r--r--spec/javascripts/ide/components/external_link_spec.js35
-rw-r--r--spec/javascripts/pipelines/graph/graph_component_spec.js2
-rw-r--r--spec/models/application_setting_spec.rb4
-rw-r--r--spec/models/ci/group_spec.rb2
-rw-r--r--spec/models/ci/runner_spec.rb12
-rw-r--r--spec/models/users_statistics_spec.rb43
-rw-r--r--spec/presenters/ci/pipeline_presenter_spec.rb119
-rw-r--r--spec/requests/api/internal/pages_spec.rb31
-rw-r--r--spec/services/ci/expire_pipeline_cache_service_spec.rb10
-rw-r--r--spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb15
-rw-r--r--spec/services/users/destroy_service_spec.rb2
20 files changed, 235 insertions, 173 deletions
diff --git a/spec/factories/users_statistics.rb b/spec/factories/users_statistics.rb
index 5b0871f2262..07699dc38b2 100644
--- a/spec/factories/users_statistics.rb
+++ b/spec/factories/users_statistics.rb
@@ -2,5 +2,13 @@
FactoryBot.define do
factory :users_statistics do
+ without_groups_and_projects { 23 }
+ with_highest_role_guest { 5 }
+ with_highest_role_reporter { 9 }
+ with_highest_role_developer { 21 }
+ with_highest_role_maintainer { 6 }
+ with_highest_role_owner { 5 }
+ bots { 2 }
+ blocked { 7 }
end
end
diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb
index 6cb345c5066..018ef13cbb6 100644
--- a/spec/features/admin/dashboard_spec.rb
+++ b/spec/features/admin/dashboard_spec.rb
@@ -2,14 +2,14 @@
require 'spec_helper'
-describe 'admin visits dashboard', :js do
+describe 'admin visits dashboard' do
include ProjectForksHelper
before do
sign_in(create(:admin))
end
- context 'counting forks' do
+ context 'counting forks', :js do
it 'correctly counts 2 forks of a project' do
project = create(:project)
project_fork = fork_project(project)
@@ -25,4 +25,26 @@ describe 'admin visits dashboard', :js do
expect(page).to have_content('Forks 2')
end
end
+
+ describe 'Users statistic' do
+ let_it_be(:users_statistics) { create(:users_statistics) }
+
+ it 'shows correct amounts of users', :aggregate_failures do
+ expected_active_users_text = Gitlab.ee? ? 'Active users (Billable users) 71' : 'Active users 71'
+
+ sign_in(create(:admin))
+ visit admin_dashboard_stats_path
+
+ expect(page).to have_content('Users without a Group and Project 23')
+ expect(page).to have_content('Users with highest role Guest 5')
+ expect(page).to have_content('Users with highest role Reporter 9')
+ expect(page).to have_content('Users with highest role Developer 21')
+ expect(page).to have_content('Users with highest role Maintainer 6')
+ expect(page).to have_content('Users with highest role Owner 5')
+ expect(page).to have_content('Bots 2')
+ expect(page).to have_content(expected_active_users_text)
+ expect(page).to have_content('Blocked users 7')
+ expect(page).to have_content('Total users 78')
+ end
+ end
end
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 f8179979018..2eaa2d24c4b 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
@@ -174,7 +174,7 @@ describe 'Set up Mattermost slash commands', :js do
describe 'stable logo url' do
it 'shows a publicly available logo' do
- expect(File.exist?(Rails.root.join('public/slash-command-logo.png')))
+ expect(File.exist?(Rails.root.join('public/slash-command-logo.png'))).to be_truthy
end
end
end
diff --git a/spec/frontend/logs/components/environment_logs_spec.js b/spec/frontend/logs/components/environment_logs_spec.js
index 4da987725a1..befcd462828 100644
--- a/spec/frontend/logs/components/environment_logs_spec.js
+++ b/spec/frontend/logs/components/environment_logs_spec.js
@@ -47,7 +47,7 @@ describe('EnvironmentLogs', () => {
const findLogControlButtons = () => wrapper.find({ name: 'log-control-buttons-stub' });
const findInfiniteScroll = () => wrapper.find({ ref: 'infiniteScroll' });
- const findLogTrace = () => wrapper.find('.js-log-trace');
+ const findLogTrace = () => wrapper.find({ ref: 'logTrace' });
const findLogFooter = () => wrapper.find({ ref: 'logFooter' });
const getInfiniteScrollAttr = attr => parseInt(findInfiniteScroll().attributes(attr), 10);
@@ -169,16 +169,12 @@ describe('EnvironmentLogs', () => {
expect(updateControlBtnsMock).not.toHaveBeenCalled();
});
- it('shows an infinite scroll with height and no content', () => {
- expect(getInfiniteScrollAttr('max-list-height')).toBeGreaterThan(0);
+ it('shows an infinite scroll with no content', () => {
expect(getInfiniteScrollAttr('fetched-items')).toBe(0);
});
- it('shows an infinite scroll container with equal height and max-height ', () => {
- const height = getInfiniteScrollAttr('max-list-height');
-
- expect(height).toEqual(expect.any(Number));
- expect(findInfiniteScroll().attributes('style')).toMatch(`height: ${height}px;`);
+ it('shows an infinite scroll container with no set max-height ', () => {
+ expect(findInfiniteScroll().attributes('max-list-height')).toBeUndefined();
});
it('shows a logs trace', () => {
@@ -270,8 +266,7 @@ describe('EnvironmentLogs', () => {
expect(findAdvancedFilters().exists()).toBe(true);
});
- it('shows infinite scroll with height and no content', () => {
- expect(getInfiniteScrollAttr('max-list-height')).toBeGreaterThan(0);
+ it('shows infinite scroll with content', () => {
expect(getInfiniteScrollAttr('fetched-items')).toBe(mockTrace.length);
});
diff --git a/spec/frontend/logs/stores/actions_spec.js b/spec/frontend/logs/stores/actions_spec.js
index 303737a11cd..882673af984 100644
--- a/spec/frontend/logs/stores/actions_spec.js
+++ b/spec/frontend/logs/stores/actions_spec.js
@@ -38,7 +38,7 @@ jest.mock('~/logs/utils');
const mockDefaultRange = {
start: '2020-01-10T18:00:00.000Z',
- end: '2020-01-10T10:00:00.000Z',
+ end: '2020-01-10T19:00:00.000Z',
};
const mockFixedRange = {
start: '2020-01-09T18:06:20.000Z',
@@ -145,9 +145,6 @@ describe('Logs Store actions', () => {
{ type: types.RECEIVE_ENVIRONMENTS_DATA_ERROR },
],
[],
- () => {
- expect(flash).toHaveBeenCalledTimes(1);
- },
);
});
});
@@ -186,6 +183,7 @@ describe('Logs Store actions', () => {
it('should commit logs and pod data when there is pod name defined', () => {
state.pods.current = mockPodName;
+ state.timeRange.current = mockFixedRange;
return testAction(fetchLogs, null, state, expectedMutations, expectedActions, () => {
expect(latestGetParams()).toMatchObject({
@@ -214,22 +212,26 @@ describe('Logs Store actions', () => {
state.search = mockSearch;
state.timeRange.current = 'INVALID_TIME_RANGE';
+ expectedMutations.splice(1, 0, {
+ type: types.SHOW_TIME_RANGE_INVALID_WARNING,
+ });
+
return testAction(fetchLogs, null, state, expectedMutations, expectedActions, () => {
expect(latestGetParams()).toEqual({
pod_name: mockPodName,
search: mockSearch,
});
- // Warning about time ranges was issued
- expect(flash).toHaveBeenCalledTimes(1);
- expect(flash).toHaveBeenCalledWith(expect.any(String), 'warning');
});
});
it('should commit logs and pod data when no pod name defined', () => {
- state.timeRange.current = mockDefaultRange;
+ state.timeRange.current = defaultTimeRange;
return testAction(fetchLogs, null, state, expectedMutations, expectedActions, () => {
- expect(latestGetParams()).toEqual({});
+ expect(latestGetParams()).toEqual({
+ start_time: expect.any(String),
+ end_time: expect.any(String),
+ });
});
});
});
@@ -249,6 +251,7 @@ describe('Logs Store actions', () => {
it('should commit logs and pod data when there is pod name defined', () => {
state.pods.current = mockPodName;
+ state.timeRange.current = mockFixedRange;
expectedActions = [];
@@ -293,6 +296,10 @@ describe('Logs Store actions', () => {
state.search = mockSearch;
state.timeRange.current = 'INVALID_TIME_RANGE';
+ expectedMutations.splice(1, 0, {
+ type: types.SHOW_TIME_RANGE_INVALID_WARNING,
+ });
+
return testAction(
fetchMoreLogsPrepend,
null,
@@ -304,15 +311,12 @@ describe('Logs Store actions', () => {
pod_name: mockPodName,
search: mockSearch,
});
- // Warning about time ranges was issued
- expect(flash).toHaveBeenCalledTimes(1);
- expect(flash).toHaveBeenCalledWith(expect.any(String), 'warning');
},
);
});
it('should commit logs and pod data when no pod name defined', () => {
- state.timeRange.current = mockDefaultRange;
+ state.timeRange.current = defaultTimeRange;
return testAction(
fetchMoreLogsPrepend,
@@ -321,7 +325,10 @@ describe('Logs Store actions', () => {
expectedMutations,
expectedActions,
() => {
- expect(latestGetParams()).toEqual({});
+ expect(latestGetParams()).toEqual({
+ start_time: expect.any(String),
+ end_time: expect.any(String),
+ });
},
);
});
@@ -357,6 +364,7 @@ describe('Logs Store actions', () => {
it('fetchLogs should commit logs and pod errors', () => {
state.environments.options = mockEnvironments;
state.environments.current = mockEnvName;
+ state.timeRange.current = defaultTimeRange;
return testAction(
fetchLogs,
@@ -377,6 +385,7 @@ describe('Logs Store actions', () => {
it('fetchMoreLogsPrepend should commit logs and pod errors', () => {
state.environments.options = mockEnvironments;
state.environments.current = mockEnvName;
+ state.timeRange.current = defaultTimeRange;
return testAction(
fetchMoreLogsPrepend,
diff --git a/spec/frontend/logs/stores/mutations_spec.js b/spec/frontend/logs/stores/mutations_spec.js
index 37db355af09..46561055a4a 100644
--- a/spec/frontend/logs/stores/mutations_spec.js
+++ b/spec/frontend/logs/stores/mutations_spec.js
@@ -67,6 +67,7 @@ describe('Logs Store Mutations', () => {
options: [],
isLoading: false,
current: null,
+ fetchError: true,
});
});
});
@@ -83,6 +84,7 @@ describe('Logs Store Mutations', () => {
expect(state.logs).toEqual({
lines: [],
cursor: null,
+ fetchError: false,
isLoading: true,
isComplete: false,
});
@@ -101,6 +103,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: mockCursor,
isComplete: false,
+ fetchError: false,
});
});
@@ -115,6 +118,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: null,
isComplete: true,
+ fetchError: false,
});
});
});
@@ -128,6 +132,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: null,
isComplete: false,
+ fetchError: true,
});
});
});
@@ -152,6 +157,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: mockCursor,
isComplete: false,
+ fetchError: false,
});
});
@@ -171,6 +177,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: mockNextCursor,
isComplete: false,
+ fetchError: false,
});
});
@@ -185,6 +192,7 @@ describe('Logs Store Mutations', () => {
isLoading: false,
cursor: null,
isComplete: true,
+ fetchError: false,
});
});
});
@@ -194,6 +202,7 @@ describe('Logs Store Mutations', () => {
mutations[types.RECEIVE_LOGS_DATA_PREPEND_ERROR](state);
expect(state.logs.isLoading).toBe(false);
+ expect(state.logs.fetchError).toBe(true);
});
});
diff --git a/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap b/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
index 5b5c9fd714e..97597ed8063 100644
--- a/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
+++ b/spec/frontend/repository/components/table/__snapshots__/row_spec.js.snap
@@ -7,17 +7,16 @@ exports[`Repository table row component renders table row 1`] = `
<td
class="tree-item-file-name cursor-default position-relative"
>
- <!---->
-
<a
class="tree-item-link str-truncated"
data-qa-selector="file_name_link"
href="https://test.com"
>
- <i
- aria-label="file"
- class="fa fa-fw mr-1 fa-file-text-o"
- role="img"
+ <file-icon-stub
+ class="mr-1 position-relative text-secondary"
+ cssclasses="position-relative file-icon"
+ filename="test"
+ size="16"
/>
<span
class="position-relative"
@@ -60,17 +59,16 @@ exports[`Repository table row component renders table row for path with special
<td
class="tree-item-file-name cursor-default position-relative"
>
- <!---->
-
<a
class="tree-item-link str-truncated"
data-qa-selector="file_name_link"
href="https://test.com"
>
- <i
- aria-label="file"
- class="fa fa-fw mr-1 fa-file-text-o"
- role="img"
+ <file-icon-stub
+ class="mr-1 position-relative text-secondary"
+ cssclasses="position-relative file-icon"
+ filename="test"
+ size="16"
/>
<span
class="position-relative"
diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js
index 7bb7ad6e5dd..cb2193e1d9a 100644
--- a/spec/frontend/repository/components/table/row_spec.js
+++ b/spec/frontend/repository/components/table/row_spec.js
@@ -1,7 +1,7 @@
import { shallowMount, RouterLinkStub } from '@vue/test-utils';
-import { GlBadge, GlLink, GlLoadingIcon } from '@gitlab/ui';
+import { GlBadge, GlLink, GlIcon } from '@gitlab/ui';
import TableRow from '~/repository/components/table/row.vue';
-import Icon from '~/vue_shared/components/icon.vue';
+import FileIcon from '~/vue_shared/components/file_icon.vue';
let vm;
let $router;
@@ -188,7 +188,8 @@ describe('Repository table row component', () => {
vm.setData({ commit: { lockLabel: 'Locked by Root', committedDate: '2019-01-01' } });
return vm.vm.$nextTick().then(() => {
- expect(vm.find(Icon).exists()).toBe(true);
+ expect(vm.find(GlIcon).exists()).toBe(true);
+ expect(vm.find(GlIcon).props('name')).toBe('lock');
});
});
@@ -202,6 +203,6 @@ describe('Repository table row component', () => {
loadingPath: 'test',
});
- expect(vm.find(GlLoadingIcon).exists()).toBe(true);
+ expect(vm.find(FileIcon).props('loading')).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/file_icon_spec.js b/spec/frontend/vue_shared/components/file_icon_spec.js
index 7b7633a06d6..5a385eee60c 100644
--- a/spec/frontend/vue_shared/components/file_icon_spec.js
+++ b/spec/frontend/vue_shared/components/file_icon_spec.js
@@ -1,7 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import { GlLoadingIcon } from '@gitlab/ui';
+import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import FileIcon from '~/vue_shared/components/file_icon.vue';
-import Icon from '~/vue_shared/components/icon.vue';
describe('File Icon component', () => {
let wrapper;
@@ -48,7 +47,7 @@ describe('File Icon component', () => {
});
expect(findIcon().exists()).toBe(false);
- expect(wrapper.find(Icon).classes()).toContain('folder-icon');
+ expect(wrapper.find(GlIcon).classes()).toContain('folder-icon');
});
it('should render a loading icon', () => {
diff --git a/spec/javascripts/ide/components/external_link_spec.js b/spec/javascripts/ide/components/external_link_spec.js
deleted file mode 100644
index b3d94c041fa..00000000000
--- a/spec/javascripts/ide/components/external_link_spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Vue from 'vue';
-import externalLink from '~/ide/components/external_link.vue';
-import createVueComponent from '../../helpers/vue_mount_component_helper';
-import { file } from '../helpers';
-
-describe('ExternalLink', () => {
- const activeFile = file();
- let vm;
-
- function createComponent() {
- const ExternalLink = Vue.extend(externalLink);
-
- activeFile.permalink = 'test';
-
- return createVueComponent(ExternalLink, {
- file: activeFile,
- });
- }
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders the external link with the correct href', done => {
- activeFile.binary = true;
- vm = createComponent();
-
- vm.$nextTick(() => {
- const openLink = vm.$el.querySelector('a');
-
- expect(openLink.href).toMatch(`/${activeFile.permalink}`);
- done();
- });
- });
-});
diff --git a/spec/javascripts/pipelines/graph/graph_component_spec.js b/spec/javascripts/pipelines/graph/graph_component_spec.js
index fa6a5f57410..d2c10362ba3 100644
--- a/spec/javascripts/pipelines/graph/graph_component_spec.js
+++ b/spec/javascripts/pipelines/graph/graph_component_spec.js
@@ -159,7 +159,6 @@ describe('graph component', () => {
expect(component.$emit).toHaveBeenCalledWith(
'onClickTriggeredBy',
- component.pipeline,
component.pipeline.triggered_by[0],
);
});
@@ -196,7 +195,6 @@ describe('graph component', () => {
expect(component.$emit).toHaveBeenCalledWith(
'onClickTriggered',
- component.pipeline,
component.pipeline.triggered[0],
);
});
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 3ec6110d789..523e17f82c1 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -34,6 +34,10 @@ describe ApplicationSetting do
it { is_expected.to allow_value("dev.gitlab.com").for(:commit_email_hostname) }
it { is_expected.not_to allow_value("@dev.gitlab").for(:commit_email_hostname) }
+ it { is_expected.to allow_value(true).for(:container_expiration_policies_enable_historic_entries) }
+ it { is_expected.to allow_value(false).for(:container_expiration_policies_enable_historic_entries) }
+ it { is_expected.not_to allow_value(nil).for(:container_expiration_policies_enable_historic_entries) }
+
it { is_expected.to allow_value("myemail@gitlab.com").for(:lets_encrypt_notification_email) }
it { is_expected.to allow_value(nil).for(:lets_encrypt_notification_email) }
it { is_expected.not_to allow_value("notanemail").for(:lets_encrypt_notification_email) }
diff --git a/spec/models/ci/group_spec.rb b/spec/models/ci/group_spec.rb
index b3b158a111e..5516a1a9c61 100644
--- a/spec/models/ci/group_spec.rb
+++ b/spec/models/ci/group_spec.rb
@@ -53,7 +53,7 @@ describe Ci::Group do
it 'calls the status from the object itself' do
expect(jobs.first).to receive(:detailed_status)
- expect(subject.detailed_status(double(:user)))
+ subject.detailed_status(double(:user))
end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 55af292e8f3..b8034ba5bf2 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -526,14 +526,14 @@ describe Ci::Runner do
it 'sets a new last_update value when it is called the first time' do
last_update = runner.ensure_runner_queue_value
- expect_value_in_queues.to eq(last_update)
+ expect(value_in_queues).to eq(last_update)
end
it 'does not change if it is not expired and called again' do
last_update = runner.ensure_runner_queue_value
expect(runner.ensure_runner_queue_value).to eq(last_update)
- expect_value_in_queues.to eq(last_update)
+ expect(value_in_queues).to eq(last_update)
end
context 'updates runner queue after changing editable value' do
@@ -544,7 +544,7 @@ describe Ci::Runner do
end
it 'sets a new last_update value' do
- expect_value_in_queues.not_to eq(last_update)
+ expect(value_in_queues).not_to eq(last_update)
end
end
@@ -556,14 +556,14 @@ describe Ci::Runner do
end
it 'has an old last_update value' do
- expect_value_in_queues.to eq(last_update)
+ expect(value_in_queues).to eq(last_update)
end
end
- def expect_value_in_queues
+ def value_in_queues
Gitlab::Redis::SharedState.with do |redis|
runner_queue_key = runner.send(:runner_queue_key)
- expect(redis.get(runner_queue_key))
+ redis.get(runner_queue_key)
end
end
end
diff --git a/spec/models/users_statistics_spec.rb b/spec/models/users_statistics_spec.rb
index fc23bed711f..4437a5469c6 100644
--- a/spec/models/users_statistics_spec.rb
+++ b/spec/models/users_statistics_spec.rb
@@ -2,7 +2,36 @@
require 'spec_helper'
-RSpec.describe UsersStatistics do
+describe UsersStatistics do
+ let(:users_statistics) { build(:users_statistics) }
+
+ describe 'scopes' do
+ describe '.order_created_at_desc' do
+ it 'returns the entries ordered by created at descending' do
+ users_statistics1 = create(:users_statistics, created_at: Time.current)
+ users_statistics2 = create(:users_statistics, created_at: Time.current - 2.days)
+ users_statistics3 = create(:users_statistics, created_at: Time.current - 5.hours)
+
+ expect(described_class.order_created_at_desc).to eq(
+ [
+ users_statistics1,
+ users_statistics3,
+ users_statistics2
+ ]
+ )
+ end
+ end
+ end
+
+ describe '.latest' do
+ it 'returns the latest entry' do
+ create(:users_statistics, created_at: Time.current - 1.day)
+ users_statistics = create(:users_statistics, created_at: Time.current)
+
+ expect(described_class.latest).to eq(users_statistics)
+ end
+ end
+
describe '.create_current_stats!' do
before do
create_list(:user_highest_role, 4)
@@ -40,4 +69,16 @@ RSpec.describe UsersStatistics do
end
end
end
+
+ describe '#active' do
+ it 'sums users statistics values without the value for blocked' do
+ expect(users_statistics.active).to eq(71)
+ end
+ end
+
+ describe '#total' do
+ it 'sums all users statistics values' do
+ expect(users_statistics.total).to eq(78)
+ end
+ end
end
diff --git a/spec/presenters/ci/pipeline_presenter_spec.rb b/spec/presenters/ci/pipeline_presenter_spec.rb
index c9c4f567549..28eb6804703 100644
--- a/spec/presenters/ci/pipeline_presenter_spec.rb
+++ b/spec/presenters/ci/pipeline_presenter_spec.rb
@@ -7,7 +7,7 @@ describe Ci::PipelinePresenter do
let(:user) { create(:user) }
let(:current_user) { user }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :test_repo) }
let(:pipeline) { create(:ci_pipeline, project: project) }
subject(:presenter) do
@@ -87,34 +87,32 @@ describe Ci::PipelinePresenter do
end
describe '#name' do
+ before do
+ allow(pipeline).to receive(:merge_request_event_type) { event_type }
+ end
+
subject { presenter.name }
- context 'when pipeline is detached merge request pipeline' do
- let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.all_pipelines.last }
+ context 'for a detached merge request pipeline' do
+ let(:event_type) { :detached }
it { is_expected.to eq('Detached merge request pipeline') }
end
- context 'when pipeline is merge request pipeline' do
- let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) }
- let(:pipeline) { merge_request.all_pipelines.last }
+ context 'for a merged result pipeline' do
+ let(:event_type) { :merged_result }
it { is_expected.to eq('Merged result pipeline') }
end
- context 'when pipeline is merge train pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
-
- before do
- allow(pipeline).to receive(:merge_request_event_type) { :merge_train }
- end
+ context 'for a merge train pipeline' do
+ let(:event_type) { :merge_train }
it { is_expected.to eq('Merge train pipeline') }
end
context 'when pipeline is branch pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:event_type) { nil }
it { is_expected.to eq('Pipeline') }
end
@@ -145,8 +143,6 @@ describe Ci::PipelinePresenter do
end
context 'when pipeline is branch pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
-
context 'when ref exists in the repository' do
before do
allow(pipeline).to receive(:ref_exists?) { true }
@@ -165,7 +161,7 @@ describe Ci::PipelinePresenter do
end
end
- context 'when ref exists in the repository' do
+ context 'when ref does not exist in the repository' do
before do
allow(pipeline).to receive(:ref_exists?) { false }
end
@@ -188,12 +184,17 @@ describe Ci::PipelinePresenter do
describe '#all_related_merge_request_text' do
subject { presenter.all_related_merge_request_text }
+ let(:mr_1) { create(:merge_request) }
+ let(:mr_2) { create(:merge_request) }
+
context 'with zero related merge requests (branch pipeline)' do
it { is_expected.to eq('No related merge requests found.') }
end
context 'with one related merge request' do
- let!(:mr_1) { create(:merge_request, project: project, source_project: project) }
+ before do
+ allow(pipeline).to receive(:all_merge_requests).and_return(MergeRequest.where(id: mr_1.id))
+ end
it {
is_expected.to eq("1 related merge request: " \
@@ -202,8 +203,9 @@ describe Ci::PipelinePresenter do
end
context 'with two related merge requests' do
- let!(:mr_1) { create(:merge_request, project: project, source_project: project, target_branch: 'staging') }
- let!(:mr_2) { create(:merge_request, project: project, source_project: project, target_branch: 'feature') }
+ before do
+ allow(pipeline).to receive(:all_merge_requests).and_return(MergeRequest.where(id: [mr_1.id, mr_2.id]))
+ end
it {
is_expected.to eq("2 related merge requests: " \
@@ -223,22 +225,25 @@ describe Ci::PipelinePresenter do
end
describe '#all_related_merge_requests' do
+ subject(:all_related_merge_requests) do
+ presenter.send(:all_related_merge_requests)
+ end
+
it 'memoizes the returned relation' do
- query_count = ActiveRecord::QueryRecorder.new do
- 3.times { presenter.send(:all_related_merge_requests).count }
- end.count
+ expect(pipeline).to receive(:all_merge_requests_by_recency).exactly(1).time.and_call_original
+ 2.times { presenter.send(:all_related_merge_requests).count }
+ end
+
+ context 'for a branch pipeline with two open MRs' do
+ let!(:one) { create(:merge_request, source_project: project, source_branch: pipeline.ref) }
+ let!(:two) { create(:merge_request, source_project: project, source_branch: pipeline.ref, target_branch: 'wip') }
- expect(query_count).to eq(2)
+ it { is_expected.to contain_exactly(one, two) }
end
context 'permissions' do
- let!(:merge_request) do
- create(:merge_request, project: project, source_project: project)
- end
-
- subject(:all_related_merge_requests) do
- presenter.send(:all_related_merge_requests)
- end
+ let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) }
+ let(:pipeline) { merge_request.all_pipelines.take }
shared_examples 'private merge requests' do
context 'when not logged in' do
@@ -315,61 +320,51 @@ describe Ci::PipelinePresenter do
describe '#link_to_merge_request' do
subject { presenter.link_to_merge_request }
- let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.all_pipelines.last }
+ context 'with a related merge request' do
+ let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) }
+ let(:pipeline) { merge_request.all_pipelines.take }
- it 'returns a correct link' do
- is_expected
- .to include(project_merge_request_path(merge_request.project, merge_request))
+ it 'returns a correct link' do
+ is_expected.to include(project_merge_request_path(project, merge_request))
+ end
end
context 'when pipeline is branch pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
+ it { is_expected.to be_nil }
end
end
describe '#link_to_merge_request_source_branch' do
subject { presenter.link_to_merge_request_source_branch }
- let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
- let(:pipeline) { merge_request.all_pipelines.last }
+ context 'with a related merge request' do
+ let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) }
+ let(:pipeline) { merge_request.all_pipelines.take }
- it 'returns a correct link' do
- is_expected
- .to include(project_commits_path(merge_request.source_project,
- merge_request.source_branch))
+ it 'returns a correct link' do
+ is_expected.to include(project_commits_path(project, merge_request.source_branch))
+ end
end
context 'when pipeline is branch pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
+ it { is_expected.to be_nil }
end
end
describe '#link_to_merge_request_target_branch' do
subject { presenter.link_to_merge_request_target_branch }
- let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) }
- let(:pipeline) { merge_request.all_pipelines.last }
+ context 'with a related merge request' do
+ let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_project: project) }
+ let(:pipeline) { merge_request.all_pipelines.take }
- it 'returns a correct link' do
- is_expected
- .to include(project_commits_path(merge_request.target_project, merge_request.target_branch))
+ it 'returns a correct link' do
+ is_expected.to include(project_commits_path(project, merge_request.target_branch))
+ end
end
context 'when pipeline is branch pipeline' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
+ it { is_expected.to be_nil }
end
end
end
diff --git a/spec/requests/api/internal/pages_spec.rb b/spec/requests/api/internal/pages_spec.rb
index 0c3c2fa22d6..fecf15c29c2 100644
--- a/spec/requests/api/internal/pages_spec.rb
+++ b/spec/requests/api/internal/pages_spec.rb
@@ -3,13 +3,36 @@
require 'spec_helper'
describe API::Internal::Pages do
- describe "GET /internal/pages" do
- let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) }
+ let(:auth_headers) do
+ jwt_token = JWT.encode({ 'iss' => 'gitlab-pages' }, Gitlab::Pages.secret, 'HS256')
+ { Gitlab::Pages::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ end
+ let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) }
+
+ before do
+ allow(Gitlab::Pages).to receive(:secret).and_return(pages_secret)
+ end
+
+ describe "GET /internal/pages/status" do
+ def query_enabled(headers = {})
+ get api("/internal/pages/status"), headers: headers
+ end
- before do
- allow(Gitlab::Pages).to receive(:secret).and_return(pages_secret)
+ it 'responds with 401 Unauthorized' do
+ query_enabled
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+
+ it 'responds with 204 no content' do
+ query_enabled(auth_headers)
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ expect(response.body).to be_empty
end
+ end
+ describe "GET /internal/pages" do
def query_host(host, headers = {})
get api("/internal/pages"), headers: headers, params: { host: host }
end
diff --git a/spec/services/ci/expire_pipeline_cache_service_spec.rb b/spec/services/ci/expire_pipeline_cache_service_spec.rb
index 7b9d6ed4f41..78e1ba0109a 100644
--- a/spec/services/ci/expire_pipeline_cache_service_spec.rb
+++ b/spec/services/ci/expire_pipeline_cache_service_spec.rb
@@ -22,19 +22,19 @@ describe Ci::ExpirePipelineCacheService do
end
it 'invalidates Etag caching for merge request pipelines if pipeline runs on any commit of that source branch' do
- pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master')
- merge_request = create(:merge_request, source_project: project, source_branch: pipeline.ref)
+ merge_request = create(:merge_request, :with_detached_merge_request_pipeline)
+ project = merge_request.target_project
+
merge_request_pipelines_path = "/#{project.full_path}/-/merge_requests/#{merge_request.iid}/pipelines.json"
allow_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch)
expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(merge_request_pipelines_path)
- subject.execute(pipeline)
+ subject.execute(merge_request.all_pipelines.last)
end
it 'updates the cached status for a project' do
- expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline)
- .with(pipeline)
+ expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline).with(pipeline)
subject.execute(pipeline)
end
diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
index 4d87fa3e832..0cec1e7be22 100644
--- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
+++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
@@ -8,10 +8,6 @@ describe MergeRequests::AddTodoWhenBuildFailsService do
let(:sha) { '1234567890abcdef1234567890abcdef12345678' }
let(:ref) { merge_request.source_branch }
- let(:pipeline) do
- create(:ci_pipeline, ref: ref, project: project, sha: sha)
- end
-
let(:service) do
described_class.new(project, user, commit_message: 'Awesome message')
end
@@ -19,12 +15,11 @@ describe MergeRequests::AddTodoWhenBuildFailsService do
let(:todo_service) { spy('todo service') }
let(:merge_request) do
- create(:merge_request, merge_user: user,
- source_branch: 'master',
- target_branch: 'feature',
- source_project: project,
- target_project: project,
- state: 'opened')
+ create(:merge_request, :with_detached_merge_request_pipeline, :opened, merge_user: user)
+ end
+
+ let(:pipeline) do
+ merge_request.all_pipelines.take
end
before do
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index a664719783a..216d9170274 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -15,7 +15,7 @@ describe Users::DestroyService do
it 'deletes the user' do
user_data = service.execute(user)
- expect { user_data['email'].to eq(user.email) }
+ expect(user_data['email']).to eq(user.email)
expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound)
expect { Namespace.find(namespace.id) }.to raise_error(ActiveRecord::RecordNotFound)
end