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-11-17 18:09:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-17 18:09:28 +0300
commit6535cf9c79362862c31ea7d26c61541b84db18d9 (patch)
tree6d646edcf11d38e8ac23bceed1340ff8907b850d /spec
parent9a8f801d7352b7965fe690a599410fb50005ce67 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/concerns/metrics_dashboard_spec.rb1
-rw-r--r--spec/features/groups/milestone_spec.rb1
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb77
-rw-r--r--spec/finders/merge_requests/by_approvals_finder_spec.rb1
-rw-r--r--spec/fixtures/api/schemas/internal/pages/lookup_path.json6
-rw-r--r--spec/frontend/alerts_settings/alerts_integrations_list_spec.js17
-rw-r--r--spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js2
-rw-r--r--spec/frontend/gfm_auto_complete_spec.js17
-rw-r--r--spec/frontend/notes/components/note_header_spec.js12
-rw-r--r--spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js257
-rw-r--r--spec/frontend/set_status_modal/user_availability_status_spec.js31
-rw-r--r--spec/frontend/vue_shared/components/user_popover/user_popover_spec.js30
-rw-r--r--spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb1
-rw-r--r--spec/helpers/markup_helper_spec.rb1
-rw-r--r--spec/helpers/page_layout_helper_spec.rb38
-rw-r--r--spec/helpers/profiles_helper_spec.rb32
-rw-r--r--spec/helpers/todos_helper_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/design_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/chat/output_spec.rb99
-rw-r--r--spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb1
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb1
-rw-r--r--spec/lib/gitlab/relative_positioning/mover_spec.rb1
-rw-r--r--spec/migrations/reseed_merge_trains_enabled_spec.rb26
-rw-r--r--spec/models/pages/lookup_path_spec.rb56
-rw-r--r--spec/requests/api/admin/instance_clusters_spec.rb1
-rw-r--r--spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb1
-rw-r--r--spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb1
-rw-r--r--spec/requests/api/graphql/project/issue/design_collection/version_spec.rb1
-rw-r--r--spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb3
-rw-r--r--spec/requests/api/graphql/project/jira_import_spec.rb2
-rw-r--r--spec/requests/api/graphql/user/group_member_query_spec.rb1
-rw-r--r--spec/requests/api/graphql/user/project_member_query_spec.rb1
-rw-r--r--spec/requests/api/graphql/user_query_spec.rb5
-rw-r--r--spec/requests/api/internal/pages_spec.rb21
-rw-r--r--spec/requests/api/issues/get_project_issues_spec.rb2
-rw-r--r--spec/requests/api/issues/issues_spec.rb2
-rw-r--r--spec/requests/api/issues/post_projects_issues_spec.rb2
-rw-r--r--spec/requests/projects/metrics/dashboards/builder_spec.rb1
-rw-r--r--spec/rubocop/cop/line_break_around_conditional_block_spec.rb454
-rw-r--r--spec/services/admin/propagate_integration_service_spec.rb1
-rw-r--r--spec/services/alert_management/create_alert_issue_service_spec.rb1
-rw-r--r--spec/services/metrics/dashboard/panel_preview_service_spec.rb1
-rw-r--r--spec/services/notes/destroy_service_spec.rb1
-rw-r--r--spec/services/notification_service_spec.rb1
-rw-r--r--spec/support/shared_contexts/design_management_shared_contexts.rb2
-rw-r--r--spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb3
-rw-r--r--spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb1
-rw-r--r--spec/uploaders/gitlab_uploader_spec.rb18
48 files changed, 706 insertions, 533 deletions
diff --git a/spec/controllers/concerns/metrics_dashboard_spec.rb b/spec/controllers/concerns/metrics_dashboard_spec.rb
index 8a4d8828aaa..83546403ce5 100644
--- a/spec/controllers/concerns/metrics_dashboard_spec.rb
+++ b/spec/controllers/concerns/metrics_dashboard_spec.rb
@@ -155,6 +155,7 @@ RSpec.describe MetricsDashboard do
'.gitlab/dashboards/errors.yml' => dashboard_yml
}
end
+
let_it_be(:project) { create(:project, :custom_repo, files: dashboards) }
before do
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 3ae9a2b7555..8d1008b98a6 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -83,6 +83,7 @@ RSpec.describe 'Group milestones' do
description: 'Lorem Ipsum is simply dummy text'
)
end
+
let_it_be(:active_project_milestone2) { create(:milestone, project: other_project, state: 'active', title: 'v1.1') }
let_it_be(:closed_project_milestone1) { create(:milestone, project: project, state: 'closed', title: 'v2.0') }
let_it_be(:closed_project_milestone2) { create(:milestone, project: other_project, state: 'closed', title: 'v2.0') }
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index 697fccaca34..d0340dfc880 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -20,6 +20,10 @@ RSpec.describe 'User edit profile' do
wait_for_requests
end
+ def toggle_busy_status
+ find('[data-testid="user-availability-checkbox"]').set(true)
+ end
+
it 'changes user profile' do
fill_in 'user_skype', with: 'testskype'
fill_in 'user_linkedin', with: 'testlinkedin'
@@ -180,20 +184,51 @@ RSpec.describe 'User edit profile' do
expect(page).to have_emoji('speech_balloon')
end
end
+
+ it 'sets the users status to busy' do
+ busy_status = find('[data-testid="user-availability-checkbox"]')
+
+ expect(busy_status.checked?).to eq(false)
+
+ toggle_busy_status
+ submit_settings
+ visit profile_path
+
+ expect(busy_status.checked?).to eq(true)
+ end
+
+ context 'with set_user_availability_status feature flag disabled' do
+ before do
+ stub_feature_flags(set_user_availability_status: false)
+ visit root_path(user)
+ end
+
+ it 'does not display the availability checkbox' do
+ expect(page).not_to have_css('[data-testid="user-availability-checkbox"]')
+ end
+ end
end
context 'user menu' do
let(:issue) { create(:issue, project: project)}
let(:project) { create(:project) }
- def open_user_status_modal
+ def open_modal(button_text)
find('.header-user-dropdown-toggle').click
page.within ".header-user" do
- click_button 'Set status'
+ click_button button_text
end
end
+ def open_user_status_modal
+ open_modal 'Set status'
+ end
+
+ def open_edit_status_modal
+ open_modal 'Edit status'
+ end
+
def set_user_status_in_modal
page.within "#set-user-status-modal" do
click_button 'Set status'
@@ -246,6 +281,19 @@ RSpec.describe 'User edit profile' do
end
end
+ it 'sets the users status to busy' do
+ open_user_status_modal
+ busy_status = find('[data-testid="user-availability-checkbox"]')
+
+ expect(busy_status.checked?).to eq(false)
+
+ toggle_busy_status
+ set_user_status_in_modal
+ open_edit_status_modal
+
+ expect(busy_status.checked?).to eq(true)
+ end
+
it 'opens the emoji modal again after closing it' do
open_user_status_modal
select_emoji('biohazard', true)
@@ -307,11 +355,7 @@ RSpec.describe 'User edit profile' do
expect(page).to have_content user_status.message
end
- find('.header-user-dropdown-toggle').click
-
- page.within ".header-user" do
- click_button 'Edit status'
- end
+ open_edit_status_modal
find('.js-clear-user-status-button').click
set_user_status_in_modal
@@ -333,11 +377,7 @@ RSpec.describe 'User edit profile' do
expect(page).to have_content user_status.message
end
- find('.header-user-dropdown-toggle').click
-
- page.within ".header-user" do
- click_button 'Edit status'
- end
+ open_edit_status_modal
page.within "#set-user-status-modal" do
click_button 'Remove status'
@@ -357,6 +397,19 @@ RSpec.describe 'User edit profile' do
expect(page).to have_emoji('speech_balloon')
end
end
+
+ context 'with set_user_availability_status feature flag disabled' do
+ before do
+ stub_feature_flags(set_user_availability_status: false)
+ visit root_path(user)
+ end
+
+ it 'does not display the availability checkbox' do
+ open_user_status_modal
+
+ expect(page).not_to have_css('[data-testid="user-availability-checkbox"]')
+ end
+ end
end
context 'User time preferences', :js do
diff --git a/spec/finders/merge_requests/by_approvals_finder_spec.rb b/spec/finders/merge_requests/by_approvals_finder_spec.rb
index 0e1856879f1..5c56e610c0b 100644
--- a/spec/finders/merge_requests/by_approvals_finder_spec.rb
+++ b/spec/finders/merge_requests/by_approvals_finder_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe MergeRequests::ByApprovalsFinder do
create(:approval, merge_request: mr, user: first_user)
end
end
+
let_it_be(:merge_request_with_both_approvals) do
create(:merge_request).tap do |mr|
create(:approval, merge_request: mr, user: first_user)
diff --git a/spec/fixtures/api/schemas/internal/pages/lookup_path.json b/spec/fixtures/api/schemas/internal/pages/lookup_path.json
index a7793d679be..9d81ea495f1 100644
--- a/spec/fixtures/api/schemas/internal/pages/lookup_path.json
+++ b/spec/fixtures/api/schemas/internal/pages/lookup_path.json
@@ -15,7 +15,11 @@
"required": ["type", "path"],
"properties" : {
"type": { "type": "string", "enum": ["file", "zip"] },
- "path": { "type": "string" }
+ "path": { "type": "string" },
+ "global_id": { "type": "string" },
+ "sha256": { "type": "string" },
+ "file_size": { "type": "integer" },
+ "file_count": { "type": ["integer", "null"] }
},
"additionalProperties": false
},
diff --git a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
index 051caf0e49d..90bb38f0c2b 100644
--- a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
+++ b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
@@ -1,5 +1,6 @@
import { GlTable, GlIcon, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { useMockIntersectionObserver } from 'helpers/mock_dom_observer';
import Tracking from '~/tracking';
import AlertIntegrationsList, {
i18n,
@@ -23,6 +24,7 @@ const mockIntegrations = [
describe('AlertIntegrationsList', () => {
let wrapper;
+ const { trigger: triggerIntersection } = useMockIntersectionObserver();
function mountComponent({ data = {}, props = {} } = {}) {
wrapper = mount(AlertIntegrationsList, {
@@ -100,12 +102,23 @@ describe('AlertIntegrationsList', () => {
describe('Snowplow tracking', () => {
beforeEach(() => {
- jest.spyOn(Tracking, 'event');
mountComponent();
+ jest.spyOn(Tracking, 'event');
+ });
+
+ it('should NOT track alert list page views when list is collapsed', () => {
+ triggerIntersection(wrapper.vm.$el, { entry: { isIntersecting: false } });
+
+ expect(Tracking.event).not.toHaveBeenCalled();
});
- it('should track alert list page views', () => {
+ it('should track alert list page views only once when list is expanded', () => {
+ triggerIntersection(wrapper.vm.$el, { entry: { isIntersecting: true } });
+ triggerIntersection(wrapper.vm.$el, { entry: { isIntersecting: true } });
+ triggerIntersection(wrapper.vm.$el, { entry: { isIntersecting: true } });
+
const { category, action } = trackAlertIntegrationsViewsOptions;
+ expect(Tracking.event).toHaveBeenCalledTimes(1);
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
diff --git a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js
index c24a76f1df0..7384cf9a095 100644
--- a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js
+++ b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js
@@ -3,6 +3,7 @@ import { mount, createLocalVue } from '@vue/test-utils';
import createMockApollo from 'jest/helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
+import { useMockIntersectionObserver } from 'helpers/mock_dom_observer';
import AlertsSettingsWrapper from '~/alerts_settings/components/alerts_settings_wrapper.vue';
import AlertsSettingsFormOld from '~/alerts_settings/components/alerts_settings_form_old.vue';
import AlertsSettingsFormNew from '~/alerts_settings/components/alerts_settings_form_new.vue';
@@ -47,6 +48,7 @@ describe('AlertsSettingsWrapper', () => {
let wrapper;
let fakeApollo;
let destroyIntegrationHandler;
+ useMockIntersectionObserver();
const findLoader = () => wrapper.find(IntegrationsList).find(GlLoadingIcon);
const findIntegrations = () => wrapper.find(IntegrationsList).findAll('table tbody tr');
diff --git a/spec/frontend/gfm_auto_complete_spec.js b/spec/frontend/gfm_auto_complete_spec.js
index 8da4320d993..e7025955e8e 100644
--- a/spec/frontend/gfm_auto_complete_spec.js
+++ b/spec/frontend/gfm_auto_complete_spec.js
@@ -378,6 +378,7 @@ describe('GfmAutoComplete', () => {
username: 'my-group',
title: '',
icon: '',
+ availabilityStatus: '',
}),
).toBe('<li>IMG my-group <small></small> </li>');
});
@@ -389,6 +390,7 @@ describe('GfmAutoComplete', () => {
username: 'my-group',
title: '',
icon: '<i class="icon"/>',
+ availabilityStatus: '',
}),
).toBe('<li>IMG my-group <small></small> <i class="icon"/></li>');
});
@@ -400,9 +402,24 @@ describe('GfmAutoComplete', () => {
username: 'my-group',
title: 'MyGroup+',
icon: '<i class="icon"/>',
+ availabilityStatus: '',
}),
).toBe('<li>IMG my-group <small>MyGroup+</small> <i class="icon"/></li>');
});
+
+ it('should add user availability status if availabilityStatus is set', () => {
+ expect(
+ GfmAutoComplete.Members.templateFunction({
+ avatarTag: 'IMG',
+ username: 'my-group',
+ title: '',
+ icon: '<i class="icon"/>',
+ availabilityStatus: '<span class="gl-text-gray-500"> (Busy)</span>',
+ }),
+ ).toBe(
+ '<li>IMG my-group <small><span class="gl-text-gray-500"> (Busy)</span></small> <i class="icon"/></li>',
+ );
+ });
});
describe('labels', () => {
diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index 1cc4a2fa853..69aab0d051e 100644
--- a/spec/frontend/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -1,7 +1,9 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
import Vuex from 'vuex';
+import { GlSprintf } from '@gitlab/ui';
import NoteHeader from '~/notes/components/note_header.vue';
+import { AVAILABILITY_STATUS } from '~/set_status_modal/utils';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -28,6 +30,9 @@ describe('NoteHeader component', () => {
path: '/root',
state: 'active',
username: 'root',
+ status: {
+ availability: '',
+ },
};
const createComponent = props => {
@@ -37,6 +42,7 @@ describe('NoteHeader component', () => {
actions,
}),
propsData: { ...props },
+ stubs: { GlSprintf },
});
};
@@ -97,6 +103,12 @@ describe('NoteHeader component', () => {
expect(wrapper.find('.js-user-link').exists()).toBe(true);
});
+ it('renders busy status if author availability is set', () => {
+ createComponent({ author: { ...author, status: { availability: AVAILABILITY_STATUS.BUSY } } });
+
+ expect(wrapper.find('.js-user-link').text()).toContain('(Busy)');
+ });
+
it('renders deleted user text if author is not passed as a prop', () => {
createComponent();
diff --git a/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
new file mode 100644
index 00000000000..fad23aa05a4
--- /dev/null
+++ b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
@@ -0,0 +1,257 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal, GlFormCheckbox } from '@gitlab/ui';
+import { initEmojiMock } from 'helpers/emoji';
+import Api from '~/api';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
+import SetStatusModalWrapper, {
+ AVAILABILITY_STATUS,
+} from '~/set_status_modal/set_status_modal_wrapper.vue';
+
+jest.mock('~/api');
+jest.mock('~/flash');
+
+describe('SetStatusModalWrapper', () => {
+ let wrapper;
+ let mockEmoji;
+ const $toast = {
+ show: jest.fn(),
+ };
+
+ const defaultEmoji = 'speech_balloon';
+ const defaultMessage = "They're comin' in too fast!";
+
+ const defaultProps = {
+ currentEmoji: defaultEmoji,
+ currentMessage: defaultMessage,
+ defaultEmoji,
+ canSetUserAvailability: true,
+ };
+
+ const createComponent = (props = {}) => {
+ return shallowMount(SetStatusModalWrapper, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ mocks: {
+ $toast,
+ },
+ });
+ };
+
+ const findModal = () => wrapper.find(GlModal);
+ const findFormField = field => wrapper.find(`[name="user[status][${field}]"]`);
+ const findClearStatusButton = () => wrapper.find('.js-clear-user-status-button');
+ const findNoEmojiPlaceholder = () => wrapper.find('.js-no-emoji-placeholder');
+ const findToggleEmojiButton = () => wrapper.find('.js-toggle-emoji-menu');
+ const findAvailabilityCheckbox = () => wrapper.find(GlFormCheckbox);
+
+ const initModal = ({ mockOnUpdateSuccess = true, mockOnUpdateFailure = true } = {}) => {
+ const modal = findModal();
+ // mock internal emoji methods
+ wrapper.vm.showEmojiMenu = jest.fn();
+ wrapper.vm.hideEmojiMenu = jest.fn();
+ if (mockOnUpdateSuccess) wrapper.vm.onUpdateSuccess = jest.fn();
+ if (mockOnUpdateFailure) wrapper.vm.onUpdateFail = jest.fn();
+
+ modal.vm.$emit('shown');
+ return wrapper.vm.$nextTick();
+ };
+
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent();
+ return initModal();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mockEmoji.restore();
+ });
+
+ describe('with minimum props', () => {
+ it('sets the hidden status emoji field', () => {
+ const field = findFormField('emoji');
+ expect(field.exists()).toBe(true);
+ expect(field.element.value).toBe(defaultEmoji);
+ });
+
+ it('sets the message field', () => {
+ const field = findFormField('message');
+ expect(field.exists()).toBe(true);
+ expect(field.element.value).toBe(defaultMessage);
+ });
+
+ it('sets the availability field to false', () => {
+ const field = findAvailabilityCheckbox();
+ expect(field.exists()).toBe(true);
+ expect(field.element.checked).toBeUndefined();
+ });
+
+ it('has a clear status button', () => {
+ expect(findClearStatusButton().isVisible()).toBe(true);
+ });
+
+ it('clicking the toggle emoji button displays the emoji list', () => {
+ expect(wrapper.vm.showEmojiMenu).not.toHaveBeenCalled();
+ findToggleEmojiButton().trigger('click');
+ expect(wrapper.vm.showEmojiMenu).toHaveBeenCalled();
+ });
+ });
+
+ describe('with no currentMessage set', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ currentMessage: '' });
+ return initModal();
+ });
+
+ it('does not set the message field', () => {
+ expect(findFormField('message').element.value).toBe('');
+ });
+
+ it('hides the clear status button', () => {
+ expect(findClearStatusButton().isVisible()).toBe(false);
+ });
+
+ it('shows the placeholder emoji', () => {
+ expect(findNoEmojiPlaceholder().isVisible()).toBe(true);
+ });
+ });
+
+ describe('with no currentEmoji set', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ currentEmoji: '' });
+ return initModal();
+ });
+
+ it('does not set the hidden status emoji field', () => {
+ expect(findFormField('emoji').element.value).toBe('');
+ });
+
+ it('hides the placeholder emoji', () => {
+ expect(findNoEmojiPlaceholder().isVisible()).toBe(false);
+ });
+
+ describe('with no currentMessage set', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ currentEmoji: '', currentMessage: '' });
+ return initModal();
+ });
+
+ it('shows the placeholder emoji', () => {
+ expect(findNoEmojiPlaceholder().isVisible()).toBe(true);
+ });
+ });
+ });
+
+ describe('update status', () => {
+ describe('succeeds', () => {
+ beforeEach(() => {
+ jest.spyOn(Api, 'postUserStatus').mockResolvedValue();
+ });
+
+ it('clicking "removeStatus" clears the emoji and message fields', async () => {
+ findModal().vm.$emit('cancel');
+ await wrapper.vm.$nextTick();
+
+ expect(findFormField('message').element.value).toBe('');
+ expect(findFormField('emoji').element.value).toBe('');
+ });
+
+ it('clicking "setStatus" submits the user status', async () => {
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ // set the availability status
+ findAvailabilityCheckbox().vm.$emit('input', true);
+
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ const commonParams = { emoji: defaultEmoji, message: defaultMessage };
+
+ expect(Api.postUserStatus).toHaveBeenCalledTimes(2);
+ expect(Api.postUserStatus).toHaveBeenNthCalledWith(1, {
+ availability: AVAILABILITY_STATUS.NOT_SET,
+ ...commonParams,
+ });
+ expect(Api.postUserStatus).toHaveBeenNthCalledWith(2, {
+ availability: AVAILABILITY_STATUS.BUSY,
+ ...commonParams,
+ });
+ });
+
+ it('calls the "onUpdateSuccess" handler', async () => {
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.onUpdateSuccess).toHaveBeenCalled();
+ });
+ });
+
+ describe('success message', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ currentEmoji: '', currentMessage: '' });
+ jest.spyOn(Api, 'postUserStatus').mockResolvedValue();
+ return initModal({ mockOnUpdateSuccess: false });
+ });
+
+ it('displays a toast success message', async () => {
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ expect($toast.show).toHaveBeenCalledWith('Status updated', {
+ position: 'top-center',
+ type: 'success',
+ });
+ });
+ });
+
+ describe('with errors', () => {
+ beforeEach(() => {
+ jest.spyOn(Api, 'postUserStatus').mockRejectedValue();
+ });
+
+ it('calls the "onUpdateFail" handler', async () => {
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.onUpdateFail).toHaveBeenCalled();
+ });
+ });
+
+ describe('error message', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ currentEmoji: '', currentMessage: '' });
+ jest.spyOn(Api, 'postUserStatus').mockRejectedValue();
+ return initModal({ mockOnUpdateFailure: false });
+ });
+
+ it('flashes an error message', async () => {
+ findModal().vm.$emit('ok');
+ await wrapper.vm.$nextTick();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ "Sorry, we weren't able to set your status. Please try again later.",
+ );
+ });
+ });
+ });
+
+ describe('with canSetUserAvailability=false', () => {
+ beforeEach(async () => {
+ mockEmoji = await initEmojiMock();
+ wrapper = createComponent({ canSetUserAvailability: false });
+ return initModal();
+ });
+
+ it('hides the set availability checkbox', () => {
+ expect(findAvailabilityCheckbox().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/set_status_modal/user_availability_status_spec.js b/spec/frontend/set_status_modal/user_availability_status_spec.js
new file mode 100644
index 00000000000..95ca0251ce0
--- /dev/null
+++ b/spec/frontend/set_status_modal/user_availability_status_spec.js
@@ -0,0 +1,31 @@
+import { shallowMount } from '@vue/test-utils';
+import UserAvailabilityStatus from '~/set_status_modal/components/user_availability_status.vue';
+import { AVAILABILITY_STATUS } from '~/set_status_modal/utils';
+
+describe('UserAvailabilityStatus', () => {
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ return shallowMount(UserAvailabilityStatus, {
+ propsData: {
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('with availability status', () => {
+ it(`set to ${AVAILABILITY_STATUS.BUSY}`, () => {
+ wrapper = createComponent({ availability: AVAILABILITY_STATUS.BUSY });
+ expect(wrapper.text()).toContain('(Busy)');
+ });
+
+ it(`set to ${AVAILABILITY_STATUS.NOT_SET}`, () => {
+ wrapper = createComponent({ availability: AVAILABILITY_STATUS.NOT_SET });
+ expect(wrapper.html()).toBe('');
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
index c208d7b0226..7d58a865ba3 100644
--- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
@@ -1,6 +1,8 @@
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading, GlSprintf, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import UserPopover from '~/vue_shared/components/user_popover/user_popover.vue';
+import UserAvailabilityStatus from '~/set_status_modal/components/user_availability_status.vue';
+import { AVAILABILITY_STATUS } from '~/set_status_modal/utils';
const DEFAULT_PROPS = {
user: {
@@ -34,6 +36,7 @@ describe('User Popover Component', () => {
const findByTestId = testid => wrapper.find(`[data-testid="${testid}"]`);
const findUserStatus = () => wrapper.find('.js-user-status');
const findTarget = () => document.querySelector('.js-user-link');
+ const findAvailabilityStatus = () => wrapper.find(UserAvailabilityStatus);
const createWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(UserPopover, {
@@ -43,7 +46,8 @@ describe('User Popover Component', () => {
...props,
},
stubs: {
- 'gl-sprintf': GlSprintf,
+ GlSprintf,
+ UserAvailabilityStatus,
},
...options,
});
@@ -199,6 +203,30 @@ describe('User Popover Component', () => {
expect(findUserStatus().exists()).toBe(false);
});
+
+ it('should show the busy status if user set to busy', () => {
+ const user = {
+ ...DEFAULT_PROPS.user,
+ status: { availability: AVAILABILITY_STATUS.BUSY },
+ };
+
+ createWrapper({ user });
+
+ expect(findAvailabilityStatus().exists()).toBe(true);
+ expect(wrapper.text()).toContain(user.name);
+ expect(wrapper.text()).toContain('(Busy)');
+ });
+
+ it('should hide the busy status for any other status', () => {
+ const user = {
+ ...DEFAULT_PROPS.user,
+ status: { availability: AVAILABILITY_STATUS.NOT_SET },
+ };
+
+ createWrapper({ user });
+
+ expect(wrapper.text()).not.toContain('(Busy)');
+ });
});
describe('security bot', () => {
diff --git a/spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb b/spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb
index ae3097c1d9e..deb5ff584cf 100644
--- a/spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb
@@ -14,6 +14,7 @@ RSpec.describe Resolvers::MergeRequestPipelinesResolver do
sha: merge_request.diff_head_sha
)
end
+
let_it_be(:other_project_pipeline) { create(:ci_pipeline, project: merge_request.source_project, ref: 'other-ref') }
let_it_be(:other_pipeline) { create(:ci_pipeline) }
let(:current_user) { create(:user) }
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 302ab0cc137..6c5855eeb91 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe MarkupHelper do
project.add_maintainer(user)
user
end
+
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let_it_be(:snippet) { create(:project_snippet, project: project) }
diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb
index c213ad7ee59..99cdee6dbb2 100644
--- a/spec/helpers/page_layout_helper_spec.rb
+++ b/spec/helpers/page_layout_helper_spec.rb
@@ -221,4 +221,42 @@ RSpec.describe PageLayoutHelper do
end
end
end
+
+ describe '#user_status_properties' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:user) { build(:user) }
+
+ availability_types = Types::AvailabilityEnum.enum
+
+ where(:message, :emoji, :availability) do
+ "Some message" | UserStatus::DEFAULT_EMOJI | availability_types[:busy]
+ "Some message" | UserStatus::DEFAULT_EMOJI | availability_types[:not_set]
+ "Some message" | "basketball" | availability_types[:busy]
+ "Some message" | "basketball" | availability_types[:not_set]
+ "Some message" | "" | availability_types[:busy]
+ "Some message" | "" | availability_types[:not_set]
+ "" | UserStatus::DEFAULT_EMOJI | availability_types[:busy]
+ "" | UserStatus::DEFAULT_EMOJI | availability_types[:not_set]
+ "" | "basketball" | availability_types[:busy]
+ "" | "basketball" | availability_types[:not_set]
+ "" | "" | availability_types[:busy]
+ "" | "" | availability_types[:not_set]
+ end
+
+ with_them do
+ it "sets the default user status fields" do
+ user.status = UserStatus.new(message: message, emoji: emoji, availability: availability)
+ result = {
+ can_set_user_availability: true,
+ current_availability: availability,
+ current_emoji: emoji,
+ current_message: message,
+ default_emoji: UserStatus::DEFAULT_EMOJI
+ }
+
+ expect(helper.user_status_properties(user)).to eq(result)
+ end
+ end
+ end
end
diff --git a/spec/helpers/profiles_helper_spec.rb b/spec/helpers/profiles_helper_spec.rb
index 61b7ff94edb..9687d038162 100644
--- a/spec/helpers/profiles_helper_spec.rb
+++ b/spec/helpers/profiles_helper_spec.rb
@@ -80,6 +80,38 @@ RSpec.describe ProfilesHelper do
end
end
+ describe "#user_status_set_to_busy?" do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:availability, :result) do
+ "busy" | true
+ "not_set" | false
+ "" | false
+ nil | false
+ end
+
+ with_them do
+ it { expect(helper.user_status_set_to_busy?(OpenStruct.new(availability: availability))).to eq(result) }
+ end
+ end
+
+ describe "#show_status_emoji?" do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:message, :emoji, :result) do
+ "Some message" | UserStatus::DEFAULT_EMOJI | true
+ "Some message" | "" | true
+ "" | "basketball" | true
+ "" | "basketball" | true
+ "" | UserStatus::DEFAULT_EMOJI | false
+ "" | UserStatus::DEFAULT_EMOJI | false
+ end
+
+ with_them do
+ it { expect(helper.show_status_emoji?(OpenStruct.new(message: message, emoji: emoji))).to eq(result) }
+ end
+ end
+
def stub_cas_omniauth_provider
provider = OpenStruct.new(
'name' => 'cas3',
diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb
index 6b658a475b1..9481d756c16 100644
--- a/spec/helpers/todos_helper_spec.rb
+++ b/spec/helpers/todos_helper_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe TodosHelper do
project: issue.project,
note: 'I am note, hear me roar')
end
+
let_it_be(:design_todo) do
create(:todo, :mentioned,
user: user,
@@ -20,6 +21,7 @@ RSpec.describe TodosHelper do
author: author,
note: note)
end
+
let_it_be(:alert_todo) do
alert = create(:alert_management_alert, iid: 1001)
create(:todo, target: alert)
diff --git a/spec/lib/banzai/reference_parser/design_parser_spec.rb b/spec/lib/banzai/reference_parser/design_parser_spec.rb
index 92d3a4aaad2..a9cb2952c26 100644
--- a/spec/lib/banzai/reference_parser/design_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/design_parser_spec.rb
@@ -29,9 +29,11 @@ RSpec.describe Banzai::ReferenceParser::DesignParser do
let_it_be(:other_project_link) do
design_link(create(:design, :with_versions))
end
+
let_it_be(:public_link) do
design_link(create(:design, :with_versions, issue: create(:issue, project: public_project)))
end
+
let_it_be(:public_but_confidential_link) do
design_link(create(:design, :with_versions, issue: create(:issue, :confidential, project: public_project)))
end
diff --git a/spec/lib/gitlab/chat/output_spec.rb b/spec/lib/gitlab/chat/output_spec.rb
index 38e17c39fad..34f6bc0904c 100644
--- a/spec/lib/gitlab/chat/output_spec.rb
+++ b/spec/lib/gitlab/chat/output_spec.rb
@@ -8,62 +8,67 @@ RSpec.describe Gitlab::Chat::Output do
end
let(:output) { described_class.new(build) }
+ let(:trace) { Gitlab::Ci::Trace.new(build) }
+
+ before do
+ trace.set("\e[0KRunning with gitlab-runner 13.4.0~beta.108.g2ed41114 (2ed41114)
+\e[0;m\e[0K on GDK local runner g_XWCUS4
+\e[0;msection_start:1604068171:resolve_secrets\r\e[0K\e[0K\e[36;1mResolving secrets\e[0;m
+\e[0;msection_end:1604068171:resolve_secrets\r\e[0Ksection_start:1604068171:prepare_executor\r\e[0K\e[0K\e[36;1mPreparing the \"docker\" executor\e[0;m
+\e[0;m\e[0KUsing Docker executor with image ubuntu:20.04 ...
+\e[0;m\e[0KUsing locally found image version due to if-not-present pull policy
+\e[0;m\e[0KUsing docker image sha256:d70eaf7277eada08fca944de400e7e4dd97b1262c06ed2b1011500caa4decaf1 for ubuntu:20.04 with digest ubuntu@sha256:fff16eea1a8ae92867721d90c59a75652ea66d29c05294e6e2f898704bdb8cf1 ...
+\e[0;msection_end:1604068172:prepare_executor\r\e[0Ksection_start:1604068172:prepare_script\r\e[0K\e[0K\e[36;1mPreparing environment\e[0;m
+\e[0;mRunning on runner-gxwcus4-project-21-concurrent-0 via MacBook-Pro.local...
+section_end:1604068173:prepare_script\r\e[0Ksection_start:1604068173:get_sources\r\e[0K\e[0K\e[36;1mGetting source from Git repository\e[0;m
+\e[0;m\e[32;1mFetching changes with git depth set to 50...\e[0;m
+Initialized empty Git repository in /builds/267388-group-1/playground/.git/
+\e[32;1mCreated fresh repository.\e[0;m
+\e[32;1mChecking out 6c8eb7f4 as master...\e[0;m
+
+\e[32;1mSkipping Git submodules setup\e[0;m
+section_end:1604068175:get_sources\r\e[0Ksection_start:1604068175:step_script\r\e[0K\e[0K\e[36;1mExecuting \"step_script\" stage of the job script\e[0;m
+\e[0;m\e[32;1m$ echo \"success!\"\e[0;m
+success!
+section_end:1604068175:step_script\r\e[0Ksection_start:1604068175:chat_reply\r\033[0K
+Chat Reply
+section_end:1604068176:chat_reply\r\033[0K\e[32;1mJob succeeded
+\e[0;m")
+ end
describe '#to_s' do
- it 'returns the build output as a String' do
- trace = Gitlab::Ci::Trace.new(build)
-
- trace.set("echo hello\nhello")
-
- allow(build)
- .to receive(:trace)
- .and_return(trace)
-
- allow(output)
- .to receive(:read_offset_and_length)
- .and_return([0, 13])
-
- expect(output.to_s).to eq('he')
+ it 'returns the chat reply as a String' do
+ expect(output.to_s).to eq("Chat Reply")
end
- end
- describe '#read_offset_and_length' do
context 'without the chat_reply trace section' do
- it 'falls back to using the build_script trace section' do
- expect(output)
- .to receive(:find_build_trace_section)
- .with('chat_reply')
- .and_return(nil)
-
- expect(output)
- .to receive(:find_build_trace_section)
- .with('build_script')
- .and_return({ name: 'build_script', byte_start: 1, byte_end: 4 })
-
- expect(output.read_offset_and_length).to eq([1, 3])
+ before do
+ trace.set(trace.raw.gsub('chat_reply', 'not_found'))
end
- end
- context 'without the build_script trace section' do
- it 'raises MissingBuildSectionError' do
- expect { output.read_offset_and_length }
- .to raise_error(described_class::MissingBuildSectionError)
+ it 'falls back to using the step_script trace section' do
+ expect(output.to_s).to eq("\e[0;m\e[32;1m$ echo \"success!\"\e[0;m\nsuccess!")
end
- end
-
- context 'with the chat_reply trace section' do
- it 'returns the read offset and length as an Array' do
- trace = Gitlab::Ci::Trace.new(build)
-
- allow(build)
- .to receive(:trace)
- .and_return(trace)
-
- allow(trace)
- .to receive(:extract_sections)
- .and_return([{ name: 'chat_reply', byte_start: 1, byte_end: 4 }])
- expect(output.read_offset_and_length).to eq([1, 3])
+ context 'without the step_script trace section' do
+ before do
+ trace.set(trace.raw.gsub('step_script', 'build_script'))
+ end
+
+ it 'falls back to using the build_script trace section' do
+ expect(output.to_s).to eq("\e[0;m\e[32;1m$ echo \"success!\"\e[0;m\nsuccess!")
+ end
+
+ context 'without the build_script trace section' do
+ before do
+ trace.set(trace.raw.gsub('build_script', 'not_found'))
+ end
+
+ it 'raises MissingBuildSectionError' do
+ expect { output.to_s }
+ .to raise_error(described_class::MissingBuildSectionError)
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
index 949cfb5a34d..762687beedb 100644
--- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
+++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe Gitlab::ImportExport::JSON::StreamingSerializer do
group: group,
approvals_before_merge: 1)
end
+
let_it_be(:issue) do
create(:issue,
assignees: [user],
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index b6a396afd61..fd3b71deb37 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -973,6 +973,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
create(:project, :builds_disabled, :issues_disabled,
{ name: 'project', path: 'project' })
end
+
let(:shared) { project.import_export_shared }
let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
diff --git a/spec/lib/gitlab/relative_positioning/mover_spec.rb b/spec/lib/gitlab/relative_positioning/mover_spec.rb
index dafd34585a8..cbb15ae876d 100644
--- a/spec/lib/gitlab/relative_positioning/mover_spec.rb
+++ b/spec/lib/gitlab/relative_positioning/mover_spec.rb
@@ -32,6 +32,7 @@ RSpec.describe RelativePositioning::Mover do
let_it_be(:one_free_space_set) do
indices.drop(1).map { |iid| create(:issue, project: one_free_space, iid: iid.succ) }
end
+
let_it_be(:three_sibs_set) do
[1, 2, 3].map { |iid| create(:issue, iid: iid, project: three_sibs) }
end
diff --git a/spec/migrations/reseed_merge_trains_enabled_spec.rb b/spec/migrations/reseed_merge_trains_enabled_spec.rb
new file mode 100644
index 00000000000..71ef0b47da9
--- /dev/null
+++ b/spec/migrations/reseed_merge_trains_enabled_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20201112195322_reseed_merge_trains_enabled.rb')
+
+RSpec.describe ReseedMergeTrainsEnabled do
+ describe 'migrate' do
+ let(:project_ci_cd_settings) { table(:project_ci_cd_settings) }
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+
+ context 'when on Gitlab.com' do
+ before do
+ namespace = namespaces.create!(name: 'hello', path: 'hello/')
+ project1 = projects.create!(namespace_id: namespace.id)
+ project2 = projects.create!(namespace_id: namespace.id)
+ project_ci_cd_settings.create!(project_id: project1.id, merge_pipelines_enabled: true)
+ project_ci_cd_settings.create!(project_id: project2.id, merge_pipelines_enabled: false)
+ end
+
+ it 'updates merge_trains_enabled to true for where merge_pipelines_enabled is true' do
+ expect { migrate! }.to change(project_ci_cd_settings.where(merge_trains_enabled: true), :count).by(1)
+ end
+ end
+ end
+end
diff --git a/spec/models/pages/lookup_path_spec.rb b/spec/models/pages/lookup_path_spec.rb
index bd890a71dfd..f8ebc237577 100644
--- a/spec/models/pages/lookup_path_spec.rb
+++ b/spec/models/pages/lookup_path_spec.rb
@@ -65,11 +65,18 @@ RSpec.describe Pages::LookupPath do
project.pages_metadatum.update!(pages_deployment: deployment)
end
- it 'uses deployment from object storage', :aggregate_failures do
+ it 'uses deployment from object storage' do
Timecop.freeze do
- expect(source[:type]).to eq('zip')
- expect(source[:path]).to eq(deployment.file.url(expire_at: 1.day.from_now))
- expect(source[:path]).to include("Expires=86400")
+ expect(source).to(
+ eq({
+ type: 'zip',
+ path: deployment.file.url(expire_at: 1.day.from_now),
+ global_id: "gid://gitlab/PagesDeployment/#{deployment.id}",
+ sha256: deployment.file_sha256,
+ file_size: deployment.size,
+ file_count: deployment.file_count
+ })
+ )
end
end
@@ -78,10 +85,18 @@ RSpec.describe Pages::LookupPath do
deployment.file.migrate!(::ObjectStorage::Store::LOCAL)
end
- it 'uses file protocol', :aggregate_failures do
+ it 'uses file protocol' do
Timecop.freeze do
- expect(source[:type]).to eq('zip')
- expect(source[:path]).to eq('file://' + deployment.file.path)
+ expect(source).to(
+ eq({
+ type: 'zip',
+ path: 'file://' + deployment.file.path,
+ global_id: "gid://gitlab/PagesDeployment/#{deployment.id}",
+ sha256: deployment.file_sha256,
+ file_size: deployment.size,
+ file_count: deployment.file_count
+ })
+ )
end
end
@@ -110,11 +125,18 @@ RSpec.describe Pages::LookupPath do
project.mark_pages_as_deployed(artifacts_archive: artifacts_archive)
end
- it 'uses artifacts object storage', :aggregate_failures do
+ it 'uses artifacts object storage' do
Timecop.freeze do
- expect(source[:type]).to eq('zip')
- expect(source[:path]).to eq(artifacts_archive.file.url(expire_at: 1.day.from_now))
- expect(source[:path]).to include("Expires=86400")
+ expect(source).to(
+ eq({
+ type: 'zip',
+ path: artifacts_archive.file.url(expire_at: 1.day.from_now),
+ global_id: "gid://gitlab/Ci::JobArtifact/#{artifacts_archive.id}",
+ sha256: artifacts_archive.file_sha256,
+ file_size: artifacts_archive.size,
+ file_count: nil
+ })
+ )
end
end
@@ -123,8 +145,16 @@ RSpec.describe Pages::LookupPath do
it 'uses file protocol', :aggregate_failures do
Timecop.freeze do
- expect(source[:type]).to eq('zip')
- expect(source[:path]).to eq('file://' + artifacts_archive.file.path)
+ expect(source).to(
+ eq({
+ type: 'zip',
+ path: 'file://' + artifacts_archive.file.path,
+ global_id: "gid://gitlab/Ci::JobArtifact/#{artifacts_archive.id}",
+ sha256: artifacts_archive.file_sha256,
+ file_size: artifacts_archive.size,
+ file_count: nil
+ })
+ )
end
end
diff --git a/spec/requests/api/admin/instance_clusters_spec.rb b/spec/requests/api/admin/instance_clusters_spec.rb
index 9d0661089a9..1052080aad4 100644
--- a/spec/requests/api/admin/instance_clusters_spec.rb
+++ b/spec/requests/api/admin/instance_clusters_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe ::API::Admin::InstanceClusters do
user: admin_user,
projects: [project])
end
+
let(:project_cluster_id) { project_cluster.id }
describe "GET /admin/clusters" do
diff --git a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
index ca5a9165760..72ec2b8e070 100644
--- a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
@@ -17,6 +17,7 @@ RSpec.describe 'Getting Metrics Dashboard Annotations' do
let_it_be(:to_old_annotation) do
create(:metrics_dashboard_annotation, environment: environment, starting_at: Time.parse(from).advance(minutes: -5), dashboard_path: path)
end
+
let_it_be(:to_new_annotation) do
create(:metrics_dashboard_annotation, environment: environment, starting_at: to.advance(minutes: 5), dashboard_path: path)
end
diff --git a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
index 634ce58da96..713b26a6a9b 100644
--- a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe 'Updating an image DiffNote' do
position_type: 'image'
)
end
+
let_it_be(:updated_body) { 'Updated body' }
let_it_be(:updated_width) { 50 }
let_it_be(:updated_height) { 100 }
diff --git a/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
index 1b654e660e3..4bce3c7fe0f 100644
--- a/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
+++ b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
@@ -14,6 +14,7 @@ RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)
create(:design_version, issue: issue,
created_designs: create_list(:design, 3, issue: issue))
end
+
let_it_be(:version) do
create(:design_version, issue: issue,
modified_designs: old_version.designs,
diff --git a/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb b/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
index 640ac95cd86..ee0085718b3 100644
--- a/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
+++ b/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
@@ -11,12 +11,15 @@ RSpec.describe 'Getting versions related to an issue' do
let_it_be(:version_a) do
create(:design_version, issue: issue)
end
+
let_it_be(:version_b) do
create(:design_version, issue: issue)
end
+
let_it_be(:version_c) do
create(:design_version, issue: issue)
end
+
let_it_be(:version_d) do
create(:design_version, issue: issue)
end
diff --git a/spec/requests/api/graphql/project/jira_import_spec.rb b/spec/requests/api/graphql/project/jira_import_spec.rb
index 1cc30b95162..98a3f08baa6 100644
--- a/spec/requests/api/graphql/project/jira_import_spec.rb
+++ b/spec/requests/api/graphql/project/jira_import_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe 'query Jira import data' do
total_issue_count: 4
)
end
+
let_it_be(:jira_import2) do
create(
:jira_import_state, :finished,
@@ -31,6 +32,7 @@ RSpec.describe 'query Jira import data' do
total_issue_count: 3
)
end
+
let(:query) do
%(
query {
diff --git a/spec/requests/api/graphql/user/group_member_query_spec.rb b/spec/requests/api/graphql/user/group_member_query_spec.rb
index 3a16d962214..e47cef8cc37 100644
--- a/spec/requests/api/graphql/user/group_member_query_spec.rb
+++ b/spec/requests/api/graphql/user/group_member_query_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe 'GroupMember' do
}
HEREDOC
end
+
let_it_be(:query) do
graphql_query_for('user', { id: member.user.to_global_id.to_s }, query_graphql_field("groupMemberships", {}, fields))
end
diff --git a/spec/requests/api/graphql/user/project_member_query_spec.rb b/spec/requests/api/graphql/user/project_member_query_spec.rb
index 0790e148caf..01827e94d5d 100644
--- a/spec/requests/api/graphql/user/project_member_query_spec.rb
+++ b/spec/requests/api/graphql/user/project_member_query_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe 'ProjectMember' do
}
HEREDOC
end
+
let_it_be(:query) do
graphql_query_for('user', { id: member.user.to_global_id.to_s }, query_graphql_field("projectMemberships", {}, fields))
end
diff --git a/spec/requests/api/graphql/user_query_spec.rb b/spec/requests/api/graphql/user_query_spec.rb
index d64fd3868c2..738e120549e 100644
--- a/spec/requests/api/graphql/user_query_spec.rb
+++ b/spec/requests/api/graphql/user_query_spec.rb
@@ -32,22 +32,27 @@ RSpec.describe 'getting user information' do
create(:merge_request, :unique_branches, :unique_author,
source_project: project_a, assignees: [user])
end
+
let_it_be(:assigned_mr_b) do
create(:merge_request, :unique_branches, :unique_author,
source_project: project_b, assignees: [user])
end
+
let_it_be(:assigned_mr_c) do
create(:merge_request, :unique_branches, :unique_author,
source_project: project_b, assignees: [user])
end
+
let_it_be(:authored_mr) do
create(:merge_request, :unique_branches,
source_project: project_a, author: user)
end
+
let_it_be(:authored_mr_b) do
create(:merge_request, :unique_branches,
source_project: project_b, author: user)
end
+
let_it_be(:authored_mr_c) do
create(:merge_request, :unique_branches,
source_project: project_b, author: user)
diff --git a/spec/requests/api/internal/pages_spec.rb b/spec/requests/api/internal/pages_spec.rb
index 7f17f22b007..9a63e2a8ed5 100644
--- a/spec/requests/api/internal/pages_spec.rb
+++ b/spec/requests/api/internal/pages_spec.rb
@@ -191,6 +191,7 @@ RSpec.describe API::Internal::Pages do
expect(json_response['certificate']).to eq(pages_domain.certificate)
expect(json_response['key']).to eq(pages_domain.key)
+ deployment = project.pages_metadatum.pages_deployment
expect(json_response['lookup_paths']).to eq(
[
{
@@ -200,7 +201,11 @@ RSpec.describe API::Internal::Pages do
'prefix' => '/',
'source' => {
'type' => 'zip',
- 'path' => project.pages_metadatum.pages_deployment.file.url(expire_at: 1.day.from_now)
+ 'path' => deployment.file.url(expire_at: 1.day.from_now),
+ 'global_id' => "gid://gitlab/PagesDeployment/#{deployment.id}",
+ 'sha256' => deployment.file_sha256,
+ 'file_size' => deployment.size,
+ 'file_count' => deployment.file_count
}
}
]
@@ -227,6 +232,7 @@ RSpec.describe API::Internal::Pages do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('internal/pages/virtual_domain')
+ deployment = project.pages_metadatum.pages_deployment
expect(json_response['lookup_paths']).to eq(
[
{
@@ -236,7 +242,11 @@ RSpec.describe API::Internal::Pages do
'prefix' => '/myproject/',
'source' => {
'type' => 'zip',
- 'path' => project.pages_metadatum.pages_deployment.file.url(expire_at: 1.day.from_now)
+ 'path' => deployment.file.url(expire_at: 1.day.from_now),
+ 'global_id' => "gid://gitlab/PagesDeployment/#{deployment.id}",
+ 'sha256' => deployment.file_sha256,
+ 'file_size' => deployment.size,
+ 'file_count' => deployment.file_count
}
}
]
@@ -268,6 +278,7 @@ RSpec.describe API::Internal::Pages do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('internal/pages/virtual_domain')
+ deployment = project.pages_metadatum.pages_deployment
expect(json_response['lookup_paths']).to eq(
[
{
@@ -277,7 +288,11 @@ RSpec.describe API::Internal::Pages do
'prefix' => '/',
'source' => {
'type' => 'zip',
- 'path' => project.pages_metadatum.pages_deployment.file.url(expire_at: 1.day.from_now)
+ 'path' => deployment.file.url(expire_at: 1.day.from_now),
+ 'global_id' => "gid://gitlab/PagesDeployment/#{deployment.id}",
+ 'sha256' => deployment.file_sha256,
+ 'file_size' => deployment.size,
+ 'file_count' => deployment.file_count
}
}
]
diff --git a/spec/requests/api/issues/get_project_issues_spec.rb b/spec/requests/api/issues/get_project_issues_spec.rb
index 4228ca2d5fd..da0bae8d5e7 100644
--- a/spec/requests/api/issues/get_project_issues_spec.rb
+++ b/spec/requests/api/issues/get_project_issues_spec.rb
@@ -54,11 +54,13 @@ RSpec.describe API::Issues do
let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
+
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
+
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { 'None' }
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index b8cbddd9ed4..0fe68be027c 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -54,11 +54,13 @@ RSpec.describe API::Issues do
let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
+
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
+
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { 'None' }
diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb
index a7fe4d4509a..5b3e2363669 100644
--- a/spec/requests/api/issues/post_projects_issues_spec.rb
+++ b/spec/requests/api/issues/post_projects_issues_spec.rb
@@ -53,11 +53,13 @@ RSpec.describe API::Issues do
let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
+
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
+
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { 'None' }
diff --git a/spec/requests/projects/metrics/dashboards/builder_spec.rb b/spec/requests/projects/metrics/dashboards/builder_spec.rb
index e59ed591f63..002acca2135 100644
--- a/spec/requests/projects/metrics/dashboards/builder_spec.rb
+++ b/spec/requests/projects/metrics/dashboards/builder_spec.rb
@@ -32,6 +32,7 @@ RSpec.describe 'Projects::Metrics::Dashboards::BuilderController' do
label: Legend Label
YML
end
+
let_it_be(:invalid_panel_yml) do
<<~YML
---
diff --git a/spec/rubocop/cop/line_break_around_conditional_block_spec.rb b/spec/rubocop/cop/line_break_around_conditional_block_spec.rb
deleted file mode 100644
index 0a26ef49e35..00000000000
--- a/spec/rubocop/cop/line_break_around_conditional_block_spec.rb
+++ /dev/null
@@ -1,454 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require 'rubocop'
-require 'rubocop/rspec/support'
-require_relative '../../../rubocop/cop/line_break_around_conditional_block'
-
-RSpec.describe RuboCop::Cop::LineBreakAroundConditionalBlock, type: :rubocop do
- include CopHelper
-
- subject(:cop) { described_class.new }
-
- shared_examples 'examples with conditional' do |conditional|
- it "flags violation for #{conditional} without line break before" do
- source = <<~RUBY
- do_something
- #{conditional} condition
- do_something_more
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses.size).to eq(1)
- offense = cop.offenses.first
-
- expect(offense.line).to eq(2)
- expect(cop.highlights).to eq(["#{conditional} condition\n do_something_more\nend"])
- expect(offense.message).to eq('Add a line break around conditional blocks')
- end
-
- it "flags violation for #{conditional} without line break after" do
- source = <<~RUBY
- #{conditional} condition
- do_something
- end
- do_something_more
- RUBY
- inspect_source(source)
-
- expect(cop.offenses.size).to eq(1)
- offense = cop.offenses.first
-
- expect(offense.line).to eq(1)
- expect(cop.highlights).to eq(["#{conditional} condition\n do_something\nend"])
- expect(offense.message).to eq('Add a line break around conditional blocks')
- end
-
- it "doesn't flag violation for #{conditional} with line break before and after" do
- source = <<~RUBY
- #{conditional} condition
- do_something
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a method definition" do
- source = <<~RUBY
- def a_method
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a class definition" do
- source = <<~RUBY
- class Foo
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a module definition" do
- source = <<~RUBY
- module Foo
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a begin definition" do
- source = <<~RUBY
- begin
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by an assign/begin definition" do
- source = <<~RUBY
- @project ||= begin
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a block definition" do
- source = <<~RUBY
- on_block(param_a) do |item|
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a block definition with a comment" do
- source = <<~RUBY
- on_block(param_a) do |item| # a short comment
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a block definition using brackets" do
- source = <<~RUBY
- on_block(param_a) { |item|
- #{conditional} condition
- do_something
- end
- }
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a comment" do
- source = <<~RUBY
- # a short comment
- #{conditional} condition
- do_something
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by an assignment" do
- source = <<~RUBY
- foo =
- #{conditional} condition
- do_something
- else
- do_something_more
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a multiline comment" do
- source = <<~RUBY
- =begin
- a multiline comment
- =end
- #{conditional} condition
- do_something
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by another conditional" do
- source = <<~RUBY
- #{conditional} condition_a
- #{conditional} condition_b
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by an else" do
- source = <<~RUBY
- if condition_a
- do_something
- else
- #{conditional} condition_b
- do_something_extra
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by an elsif" do
- source = <<~RUBY
- if condition_a
- do_something
- elsif condition_b
- #{conditional} condition_c
- do_something_extra
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by an ensure" do
- source = <<~RUBY
- def a_method
- ensure
- #{conditional} condition_c
- do_something_extra
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a when" do
- source = <<~RUBY
- case field
- when value
- #{conditional} condition_c
- do_something_extra
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by a comment" do
- source = <<~RUBY
- #{conditional} condition
- do_something
- end
- # a short comment
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by an end" do
- source = <<~RUBY
- class Foo
-
- #{conditional} condition
- do_something
- end
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by an else" do
- source = <<~RUBY
- #{conditional} condition_a
- #{conditional} condition_b
- do_something
- end
- else
- do_something_extra
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by a when" do
- source = <<~RUBY
- case
- when condition_a
- #{conditional} condition_b
- do_something
- end
- when condition_c
- do_something_extra
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by an elsif" do
- source = <<~RUBY
- if condition_a
- #{conditional} condition_b
- do_something
- end
- elsif condition_c
- do_something_extra
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} preceded by a rescue" do
- source = <<~RUBY
- def a_method
- do_something
- rescue
- #{conditional} condition
- do_something
- end
- end
- RUBY
-
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "doesn't flag violation for #{conditional} followed by a rescue" do
- source = <<~RUBY
- def a_method
- #{conditional} condition
- do_something
- end
- rescue
- do_something_extra
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-
- it "autocorrects #{conditional} without line break before" do
- source = <<~RUBY
- do_something
- #{conditional} condition
- do_something_more
- end
- RUBY
- autocorrected = autocorrect_source(source)
-
- expected_source = <<~RUBY
- do_something
-
- #{conditional} condition
- do_something_more
- end
- RUBY
- expect(autocorrected).to eql(expected_source)
- end
-
- it "autocorrects #{conditional} without line break after" do
- source = <<~RUBY
- #{conditional} condition
- do_something
- end
- do_something_more
- RUBY
- autocorrected = autocorrect_source(source)
-
- expected_source = <<~RUBY
- #{conditional} condition
- do_something
- end
-
- do_something_more
- RUBY
- expect(autocorrected).to eql(expected_source)
- end
-
- it "autocorrects #{conditional} without line break before and after" do
- source = <<~RUBY
- do_something
- #{conditional} condition
- do_something_more
- end
- do_something_extra
- RUBY
- autocorrected = autocorrect_source(source)
-
- expected_source = <<~RUBY
- do_something
-
- #{conditional} condition
- do_something_more
- end
-
- do_something_extra
- RUBY
- expect(autocorrected).to eql(expected_source)
- end
- end
-
- %w[if unless].each do |example|
- it_behaves_like 'examples with conditional', example
- end
-
- it "doesn't flag violation for if with elsif" do
- source = <<~RUBY
- if condition
- do_something
- elsif another_condition
- do_something_more
- end
- RUBY
- inspect_source(source)
-
- expect(cop.offenses).to be_empty
- end
-end
diff --git a/spec/services/admin/propagate_integration_service_spec.rb b/spec/services/admin/propagate_integration_service_spec.rb
index 5df6e5e50ff..13320528e4f 100644
--- a/spec/services/admin/propagate_integration_service_spec.rb
+++ b/spec/services/admin/propagate_integration_service_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe Admin::PropagateIntegrationService do
let_it_be(:inherited_integration) do
create(:jira_service, project: create(:project), inherit_from_id: instance_integration.id)
end
+
let_it_be(:different_type_inherited_integration) do
create(:redmine_service, project: project, inherit_from_id: instance_integration.id)
end
diff --git a/spec/services/alert_management/create_alert_issue_service_spec.rb b/spec/services/alert_management/create_alert_issue_service_spec.rb
index f2be317a13d..2834322be7b 100644
--- a/spec/services/alert_management/create_alert_issue_service_spec.rb
+++ b/spec/services/alert_management/create_alert_issue_service_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
'generatorURL' => 'http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1'
}
end
+
let_it_be(:generic_alert, reload: true) { create(:alert_management_alert, :triggered, project: project, payload: payload) }
let_it_be(:prometheus_alert, reload: true) { create(:alert_management_alert, :triggered, :prometheus, project: project, payload: payload) }
let(:alert) { generic_alert }
diff --git a/spec/services/metrics/dashboard/panel_preview_service_spec.rb b/spec/services/metrics/dashboard/panel_preview_service_spec.rb
index d58dee3e7a3..2877d22d1f3 100644
--- a/spec/services/metrics/dashboard/panel_preview_service_spec.rb
+++ b/spec/services/metrics/dashboard/panel_preview_service_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Metrics::Dashboard::PanelPreviewService do
title: test panel
YML
end
+
let_it_be(:dashboard) do
{
panel_groups: [
diff --git a/spec/services/notes/destroy_service_spec.rb b/spec/services/notes/destroy_service_spec.rb
index f0e5b29ac9b..0859c28cbe7 100644
--- a/spec/services/notes/destroy_service_spec.rb
+++ b/spec/services/notes/destroy_service_spec.rb
@@ -41,6 +41,7 @@ RSpec.describe Notes::DestroyService do
create(:merge_request, source_project: repo_project,
target_project: repo_project)
end
+
let_it_be(:note) do
create(:diff_note_on_merge_request, project: repo_project,
noteable: merge_request)
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 546b8fa1443..f9a89c6281e 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -848,6 +848,7 @@ RSpec.describe NotificationService, :mailer do
noteable: design,
note: "Hello #{member_and_mentioned.to_reference}, G'day #{non_member_and_mentioned.to_reference}")
end
+
let_it_be(:note_2) do
create(:diff_note_on_design, noteable: design, author: member_and_author_of_second_note)
end
diff --git a/spec/support/shared_contexts/design_management_shared_contexts.rb b/spec/support/shared_contexts/design_management_shared_contexts.rb
index 3ff6a521338..e6ae7e03664 100644
--- a/spec/support/shared_contexts/design_management_shared_contexts.rb
+++ b/spec/support/shared_contexts/design_management_shared_contexts.rb
@@ -18,12 +18,14 @@ RSpec.shared_context 'four designs in three versions' do
modified_designs: [],
deleted_designs: [])
end
+
let_it_be(:second_version) do
create(:design_version, issue: issue,
created_designs: [design_b, design_c, design_d],
modified_designs: [design_a],
deleted_designs: [])
end
+
let_it_be(:third_version) do
create(:design_version, issue: issue,
created_designs: [],
diff --git a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
index 010c445d8df..88c31bf9cfd 100644
--- a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
+++ b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb
@@ -23,6 +23,7 @@ RSpec.shared_context 'MergeRequestsFinder multiple projects with merge requests
# We cannot use `let_it_be` here otherwise we get:
# Failure/Error: allow(RepositoryForkWorker).to receive(:perform_async).and_return(true)
# The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
+
let!(:project2) do
allow_gitaly_n_plus_1 do
fork_project(project1, user)
@@ -40,9 +41,11 @@ RSpec.shared_context 'MergeRequestsFinder multiple projects with merge requests
let_it_be(:project4, reload: true) do
allow_gitaly_n_plus_1 { create(:project, :repository, group: subgroup) }
end
+
let_it_be(:project5, reload: true) do
allow_gitaly_n_plus_1 { create(:project, group: subgroup) }
end
+
let_it_be(:project6, reload: true) do
allow_gitaly_n_plus_1 { create(:project, group: subgroup) }
end
diff --git a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb
index edc5b313220..de40b926a1c 100644
--- a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb
+++ b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb
@@ -116,6 +116,7 @@ RSpec.shared_context 'Jira projects request context' do
"uuid": "14935009-f8aa-481e-94bc-f7251f320b0e"
}]'
end
+
let_it_be(:empty_jira_projects_json) do
'{
"self": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=0&maxResults=2",
diff --git a/spec/uploaders/gitlab_uploader_spec.rb b/spec/uploaders/gitlab_uploader_spec.rb
index 72845b47a53..4e661e458ad 100644
--- a/spec/uploaders/gitlab_uploader_spec.rb
+++ b/spec/uploaders/gitlab_uploader_spec.rb
@@ -141,5 +141,23 @@ RSpec.describe GitlabUploader do
end
end
end
+
+ describe '#url_or_file_path' do
+ let(:options) { { expire_at: 1.day.from_now } }
+
+ it 'returns url when in remote storage' do
+ expect(subject).to receive(:file_storage?).and_return(false)
+ expect(subject).to receive(:url).with(options).and_return("http://example.com")
+
+ expect(subject.url_or_file_path(options)).to eq("http://example.com")
+ end
+
+ it 'returns url when in remote storage' do
+ expect(subject).to receive(:file_storage?).and_return(true)
+ expect(subject).to receive(:path).and_return("/tmp/file")
+
+ expect(subject.url_or_file_path(options)).to eq("file:///tmp/file")
+ end
+ end
end
end