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>2022-03-09 09:07:38 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-09 09:07:38 +0300
commit3feda79a555559174b585f8d55a758650737e5c9 (patch)
treea4306c15c52bf9ca6379bfc409b8f35e209c7aab /spec
parent276941b2c436678b956025ae2958e11ccbeac55d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/application_controller_spec.rb17
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb29
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb73
-rw-r--r--spec/frontend/header_search/components/header_search_autocomplete_items_spec.js13
-rw-r--r--spec/frontend/header_search/store/actions_spec.js16
-rw-r--r--spec/frontend/header_search/store/mutations_spec.js4
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js14
-rw-r--r--spec/frontend/sidebar/sidebar_assignees_spec.js31
-rw-r--r--spec/requests/api/users_spec.rb12
-rw-r--r--spec/services/issues/update_service_spec.rb28
10 files changed, 131 insertions, 106 deletions
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index d49d4947cd5..ddd80b67639 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -1059,15 +1059,25 @@ RSpec.describe ApplicationController do
describe 'setting permissions-policy header' do
controller do
skip_before_action :authenticate_user!
+ before_action :redirect_to_example, only: [:redirect]
def index
render html: 'It is a flock of sheep, not a floc of sheep.'
end
+
+ def redirect
+ raise 'Should not be reached'
+ end
+
+ def redirect_to_example
+ redirect_to('https://example.com')
+ end
end
before do
routes.draw do
get 'index' => 'anonymous#index'
+ get 'redirect' => 'anonymous#redirect'
end
end
@@ -1093,6 +1103,13 @@ RSpec.describe ApplicationController do
expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
end
+
+ it 'sets the Permissions-Policy header even when redirected before_action' do
+ get :redirect
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
+ end
end
end
end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 00985dbd77f..73c83ed0ed4 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1065,35 +1065,6 @@ RSpec.describe Projects::IssuesController do
.not_to exceed_query_limit(control_count + 2 * labels.count)
end
- context 'real-time sidebar feature flag' do
- let_it_be(:project) { create(:project, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
-
- context 'when enabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: true)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => true)
- end
- end
-
- context 'when disabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: false)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => false)
- end
- end
- end
-
it 'logs the view with Gitlab::Search::RecentIssues' do
sign_in(user)
recent_issues_double = instance_double(::Gitlab::Search::RecentIssues, log_view: nil)
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index e873ebb21c4..3ba2f7e788d 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -12,14 +12,14 @@ RSpec.describe 'Dropdown assignee', :js do
let(:js_dropdown_assignee) { '#js-dropdown-assignee' }
let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") }
- before do
- project.add_maintainer(user)
- sign_in(user)
+ describe 'behavior' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
- visit project_issues_path(project)
- end
+ visit project_issues_path(project)
+ end
- describe 'behavior' do
it 'loads all the assignees when opened' do
input_filtered_search('assignee:=', submit: false, extra_space: false)
@@ -35,6 +35,11 @@ RSpec.describe 'Dropdown assignee', :js do
describe 'selecting from dropdown without Ajax call' do
before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_issues_path(project)
+
Gitlab::Testing::RequestBlockerMiddleware.block_requests!
input_filtered_search('assignee:=', submit: false, extra_space: false)
end
@@ -51,4 +56,60 @@ RSpec.describe 'Dropdown assignee', :js do
expect_filtered_search_input_empty
end
end
+
+ context 'assignee suggestions' do
+ let!(:group) { create(:group) }
+ let!(:group_project) { create(:project, namespace: group) }
+ let!(:group_user) { create(:user) }
+
+ let!(:subgroup) { create(:group, parent: group) }
+ let!(:subgroup_project) { create(:project, namespace: subgroup) }
+ let!(:subgroup_project_issue) { create(:issue, project: subgroup_project) }
+ let!(:subgroup_user) { create(:user) }
+
+ let!(:subsubgroup) { create(:group, parent: subgroup) }
+ let!(:subsubgroup_project) { create(:project, namespace: subsubgroup) }
+ let!(:subsubgroup_user) { create(:user) }
+
+ let!(:invited_to_group_group) { create(:group) }
+ let!(:invited_to_group_group_user) { create(:user) }
+
+ let!(:invited_to_project_group) { create(:group) }
+ let!(:invited_to_project_group_user) { create(:user) }
+
+ before do
+ group.add_developer(group_user)
+ subgroup.add_developer(subgroup_user)
+ subsubgroup.add_developer(subsubgroup_user)
+ invited_to_group_group.add_developer(invited_to_group_group_user)
+ invited_to_project_group.add_developer(invited_to_project_group_user)
+
+ create(:group_group_link, shared_group: subgroup, shared_with_group: invited_to_group_group)
+ create(:project_group_link, project: subgroup_project, group: invited_to_project_group)
+
+ sign_in(subgroup_user)
+ end
+
+ it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do
+ visit issues_group_path(subgroup)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_group_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_project_group_user.name
+
+ visit project_issues_path(subgroup_project)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_project_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_group_group_user.name
+ end
+ end
end
diff --git a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
index 502f10ff771..f427482be46 100644
--- a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdownItem, GlLoadingIcon, GlAvatar } from '@gitlab/ui';
+import { GlDropdownItem, GlLoadingIcon, GlAvatar, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
@@ -46,6 +46,7 @@ describe('HeaderSearchAutocompleteItems', () => {
const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
const findGlLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findGlAvatar = () => wrapper.findComponent(GlAvatar);
+ const findGlAlert = () => wrapper.findComponent(GlAlert);
describe('template', () => {
describe('when loading is true', () => {
@@ -62,6 +63,15 @@ describe('HeaderSearchAutocompleteItems', () => {
});
});
+ describe('when api returns error', () => {
+ beforeEach(() => {
+ createComponent({ autocompleteError: true });
+ });
+
+ it('renders Alert', () => {
+ expect(findGlAlert().exists()).toBe(true);
+ });
+ });
describe('when loading is false', () => {
beforeEach(() => {
createComponent({ loading: false });
@@ -86,6 +96,7 @@ describe('HeaderSearchAutocompleteItems', () => {
expect(findDropdownItemLinks()).toStrictEqual(expectedLinks);
});
});
+
describe.each`
item | showAvatar | avatarSize
${{ data: [{ category: PROJECTS_CATEGORY, avatar_url: null }] }} | ${true} | ${String(LARGE_AVATAR_PX)}
diff --git a/spec/frontend/header_search/store/actions_spec.js b/spec/frontend/header_search/store/actions_spec.js
index 6599115f017..1748d89a6d3 100644
--- a/spec/frontend/header_search/store/actions_spec.js
+++ b/spec/frontend/header_search/store/actions_spec.js
@@ -1,6 +1,5 @@
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
-import createFlash from '~/flash';
import * as actions from '~/header_search/store/actions';
import * as types from '~/header_search/store/mutation_types';
import createState from '~/header_search/store/state';
@@ -13,11 +12,6 @@ describe('Header Search Store Actions', () => {
let state;
let mock;
- const flashCallback = (callCount) => {
- expect(createFlash).toHaveBeenCalledTimes(callCount);
- createFlash.mockClear();
- };
-
beforeEach(() => {
state = createState({});
mock = new MockAdapter(axios);
@@ -29,10 +23,10 @@ describe('Header Search Store Actions', () => {
});
describe.each`
- axiosMock | type | expectedMutations | flashCallCount
- ${{ method: 'onGet', code: 200, res: MOCK_AUTOCOMPLETE_OPTIONS_RES }} | ${'success'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_SUCCESS, payload: MOCK_AUTOCOMPLETE_OPTIONS_RES }]} | ${0}
- ${{ method: 'onGet', code: 500, res: null }} | ${'error'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_ERROR }]} | ${1}
- `('fetchAutocompleteOptions', ({ axiosMock, type, expectedMutations, flashCallCount }) => {
+ axiosMock | type | expectedMutations
+ ${{ method: 'onGet', code: 200, res: MOCK_AUTOCOMPLETE_OPTIONS_RES }} | ${'success'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_SUCCESS, payload: MOCK_AUTOCOMPLETE_OPTIONS_RES }]}
+ ${{ method: 'onGet', code: 500, res: null }} | ${'error'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_ERROR }]}
+ `('fetchAutocompleteOptions', ({ axiosMock, type, expectedMutations }) => {
describe(`on ${type}`, () => {
beforeEach(() => {
mock[axiosMock.method]().replyOnce(axiosMock.code, axiosMock.res);
@@ -42,7 +36,7 @@ describe('Header Search Store Actions', () => {
action: actions.fetchAutocompleteOptions,
state,
expectedMutations,
- }).then(() => flashCallback(flashCallCount));
+ });
});
});
});
diff --git a/spec/frontend/header_search/store/mutations_spec.js b/spec/frontend/header_search/store/mutations_spec.js
index 7bcf8e49118..e3c15ded948 100644
--- a/spec/frontend/header_search/store/mutations_spec.js
+++ b/spec/frontend/header_search/store/mutations_spec.js
@@ -20,6 +20,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(true);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(false);
});
});
@@ -29,6 +30,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(false);
expect(state.autocompleteOptions).toStrictEqual(MOCK_AUTOCOMPLETE_OPTIONS);
+ expect(state.autocompleteError).toBe(false);
});
});
@@ -38,6 +40,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(false);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(true);
});
});
@@ -46,6 +49,7 @@ describe('Header Search Store Mutations', () => {
mutations[types.CLEAR_AUTOCOMPLETE](state);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(false);
});
});
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
index def46255994..db1cffbd2cb 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
@@ -340,21 +340,9 @@ describe('Sidebar assignees widget', () => {
});
});
- it('when realtime feature flag is disabled', async () => {
+ it('includes the real-time assignees component', async () => {
createComponent();
await waitForPromises();
- expect(findRealtimeAssignees().exists()).toBe(false);
- });
-
- it('when realtime feature flag is enabled', async () => {
- createComponent({
- provide: {
- glFeatures: {
- realTimeIssueSidebar: true,
- },
- },
- });
- await waitForPromises();
expect(findRealtimeAssignees().exists()).toBe(true);
});
diff --git a/spec/frontend/sidebar/sidebar_assignees_spec.js b/spec/frontend/sidebar/sidebar_assignees_spec.js
index 5f77e21c1f8..68d20060c37 100644
--- a/spec/frontend/sidebar/sidebar_assignees_spec.js
+++ b/spec/frontend/sidebar/sidebar_assignees_spec.js
@@ -14,7 +14,7 @@ describe('sidebar assignees', () => {
let wrapper;
let mediator;
let axiosMock;
- const createComponent = (realTimeIssueSidebar = false, props) => {
+ const createComponent = (props) => {
wrapper = shallowMount(SidebarAssignees, {
propsData: {
issuableIid: '1',
@@ -25,11 +25,6 @@ describe('sidebar assignees', () => {
changing: false,
...props,
},
- provide: {
- glFeatures: {
- realTimeIssueSidebar,
- },
- },
// Attaching to document is required because this component emits something from the parent element :/
attachTo: document.body,
});
@@ -86,27 +81,17 @@ describe('sidebar assignees', () => {
expect(wrapper.find(Assigness).exists()).toBe(true);
});
- describe('when realTimeIssueSidebar is turned on', () => {
- describe('when issuableType is issue', () => {
- it('finds AssigneesRealtime componeont', () => {
- createComponent(true);
-
- expect(wrapper.find(AssigneesRealtime).exists()).toBe(true);
- });
- });
-
- describe('when issuableType is MR', () => {
- it('does not find AssigneesRealtime componeont', () => {
- createComponent(true, { issuableType: 'MR' });
+ describe('when issuableType is issue', () => {
+ it('finds AssigneesRealtime component', () => {
+ createComponent();
- expect(wrapper.find(AssigneesRealtime).exists()).toBe(false);
- });
+ expect(wrapper.find(AssigneesRealtime).exists()).toBe(true);
});
});
- describe('when realTimeIssueSidebar is turned off', () => {
- it('does not find AssigneesRealtime', () => {
- createComponent(false, { issuableType: 'issue' });
+ describe('when issuableType is MR', () => {
+ it('does not find AssigneesRealtime component', () => {
+ createComponent({ issuableType: 'MR' });
expect(wrapper.find(AssigneesRealtime).exists()).toBe(false);
});
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 7f5b6661695..2d71674273b 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -3117,6 +3117,18 @@ RSpec.describe API::Users do
expect(response.body).to eq('null')
end
end
+
+ context 'with the API initiating user' do
+ let(:user_id) { admin.id }
+
+ it 'does not block the API initiating user, returns 403' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('403 Forbidden - The API initiating user cannot be blocked by the API')
+ expect(admin.reload.state).to eq('active')
+ end
+ end
end
it 'is not available for non admin users' do
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 92e45194ad1..6d3c3dd4e39 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -1332,32 +1332,14 @@ RSpec.describe Issues::UpdateService, :mailer do
context 'broadcasting issue assignee updates' do
let(:update_params) { { assignee_ids: [user2.id] } }
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(broadcast_issue_updates: true)
- end
-
- it 'triggers the GraphQL subscription' do
- expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue)
-
- update_issue(update_params)
- end
+ it 'triggers the GraphQL subscription' do
+ expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue)
- context 'when assignee is not updated' do
- let(:update_params) { { title: 'Some other title' } }
-
- it 'does not trigger the GraphQL subscription' do
- expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue)
-
- update_issue(update_params)
- end
- end
+ update_issue(update_params)
end
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(broadcast_issue_updates: false)
- end
+ context 'when assignee is not updated' do
+ let(:update_params) { { title: 'Some other title' } }
it 'does not trigger the GraphQL subscription' do
expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue)