diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-03 21:09:56 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-03 21:09:56 +0000 |
commit | c1a50b8195f4e36fda9b233acbde57a449bcf6c3 (patch) | |
tree | b24a10a7951e9a799397753d1badf6894fe03089 /spec | |
parent | b6847c621ff246e6abceb90545d5a608318762d6 (diff) | |
download | gitlab-ce-c1a50b8195f4e36fda9b233acbde57a449bcf6c3.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/projects/import/jira_controller_spec.rb | 22 | ||||
-rw-r--r-- | spec/frontend/notes/components/sort_discussion_spec.js | 8 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 265 | ||||
-rw-r--r-- | spec/requests/api/runners_spec.rb | 68 | ||||
-rw-r--r-- | spec/views/profiles/show.html.haml_spec.rb | 44 |
5 files changed, 338 insertions, 69 deletions
diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb index 3a29c3d4093..33b51320391 100644 --- a/spec/controllers/projects/import/jira_controller_spec.rb +++ b/spec/controllers/projects/import/jira_controller_spec.rb @@ -66,13 +66,29 @@ describe Projects::Import::JiraController do context 'when running jira import first time' do context 'get show' do - it 'renders show template' do - allow(JIRA::Resource::Project).to receive(:all).and_return([]) + before do + allow(JIRA::Resource::Project).to receive(:all).and_return(jira_projects) + expect(project.import_state).to be_nil get :show, params: { namespace_id: project.namespace.to_param, project_id: project } + end + + context 'when no projects have been retrieved from Jira' do + let(:jira_projects) { [] } + + it 'render an error message' do + expect(flash[:alert]).to eq('No projects have been returned from Jira. Please check your Jira configuration.') + expect(response).to render_template(:show) + end + end + + context 'when everything is ok' do + let(:jira_projects) { [double(name: 'FOO project', key: 'FOO')] } - expect(response).to render_template :show + it 'renders show template' do + expect(response).to render_template(:show) + end end end diff --git a/spec/frontend/notes/components/sort_discussion_spec.js b/spec/frontend/notes/components/sort_discussion_spec.js index 785e8c75233..724c77eee3d 100644 --- a/spec/frontend/notes/components/sort_discussion_spec.js +++ b/spec/frontend/notes/components/sort_discussion_spec.js @@ -3,6 +3,7 @@ import Vuex from 'vuex'; import SortDiscussion from '~/notes/components/sort_discussion.vue'; import createStore from '~/notes/stores'; import { ASC, DESC } from '~/notes/constants'; +import Tracking from '~/tracking'; const localVue = createLocalVue(); localVue.use(Vuex); @@ -22,6 +23,7 @@ describe('Sort Discussion component', () => { beforeEach(() => { store = createStore(); + jest.spyOn(Tracking, 'event'); }); afterEach(() => { @@ -37,6 +39,9 @@ describe('Sort Discussion component', () => { wrapper.find('.js-newest-first').trigger('click'); expect(store.dispatch).toHaveBeenCalledWith('setDiscussionSortDirection', DESC); + expect(Tracking.event).toHaveBeenCalledWith(undefined, 'change_discussion_sort_direction', { + property: DESC, + }); }); }); @@ -58,6 +63,9 @@ describe('Sort Discussion component', () => { wrapper.find('.js-oldest-first').trigger('click'); expect(store.dispatch).toHaveBeenCalledWith('setDiscussionSortDirection', ASC); + expect(Tracking.event).toHaveBeenCalledWith(undefined, 'change_discussion_sort_direction', { + property: ASC, + }); }); it('applies the active class to the correct button in the dropdown', () => { diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 12f83e6d8c6..e69d4e18c1e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2835,61 +2835,88 @@ describe User, :do_not_mock_admin_mode do describe '#ci_owned_runners' do let(:user) { create(:user) } - let!(:project) { create(:project) } - let(:runner) { create(:ci_runner, :project, projects: [project]) } - context 'without any projects nor groups' do - it 'does not load' do - expect(user.ci_owned_runners).to be_empty + shared_examples :nested_groups_owner do + context 'when the user is the owner of a multi-level group' do + before do + set_permissions_for_users + end + + it 'loads all the runners in the tree of groups' do + expect(user.ci_owned_runners).to contain_exactly(runner, group_runner) + end end end - context 'with personal projects runners' do - let(:namespace) { create(:namespace, owner: user) } - let!(:project) { create(:project, namespace: namespace) } + shared_examples :group_owner do + context 'when the user is the owner of a one level group' do + before do + group.add_owner(user) + end - it 'loads' do - expect(user.ci_owned_runners).to contain_exactly(runner) + it 'loads the runners in the group' do + expect(user.ci_owned_runners).to contain_exactly(group_runner) + end end end - context 'with personal group runner' do - let!(:project) { create(:project) } - let(:group_runner) { create(:ci_runner, :group, groups: [group]) } - let!(:group) do - create(:group).tap do |group| - group.add_owner(user) + shared_examples :project_owner do + context 'when the user is the owner of a project' do + it 'loads the runner belonging to the project' do + expect(user.ci_owned_runners).to contain_exactly(runner) + end + end + end + + shared_examples :project_member do + context 'when the user is a maintainer' do + before do + add_user(:maintainer) + end + + it 'loads the runners of the project' do + expect(user.ci_owned_runners).to contain_exactly(project_runner) end end - it 'loads' do - expect(user.ci_owned_runners).to contain_exactly(group_runner) + context 'when the user is a developer' do + before do + add_user(:developer) + end + + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty + end end - end - context 'with personal project and group runner' do - let(:namespace) { create(:namespace, owner: user) } - let!(:project) { create(:project, namespace: namespace) } - let!(:group_runner) { create(:ci_runner, :group, groups: [group]) } + context 'when the user is a reporter' do + before do + add_user(:reporter) + end - let!(:group) do - create(:group).tap do |group| - group.add_owner(user) + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty end end - it 'loads' do - expect(user.ci_owned_runners).to contain_exactly(runner, group_runner) + context 'when the user is a guest' do + before do + add_user(:guest) + end + + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty + end end end - shared_examples :member do + shared_examples :group_member do context 'when the user is a maintainer' do before do add_user(:maintainer) end - it 'does not load' do + it 'does not load the runners of the group' do expect(user.ci_owned_runners).to be_empty end end @@ -2899,29 +2926,49 @@ describe User, :do_not_mock_admin_mode do add_user(:developer) end - it 'does not load' do + it 'does not load any runner' do expect(user.ci_owned_runners).to be_empty end end - end - shared_examples :group_member do - context 'when the user is owner' do + context 'when the user is a reporter' do before do - add_user(:owner) + add_user(:reporter) end - it 'loads' do - expect(user.ci_owned_runners).to contain_exactly(runner) + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty end end - it_behaves_like :member + context 'when the user is a guest' do + before do + add_user(:guest) + end + + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty + end + end end - context 'with groups projects runners' do - let(:group) { create(:group) } - let!(:project) { create(:project, group: group) } + context 'without any projects nor groups' do + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty + end + end + + context 'with runner in a personal project' do + let!(:namespace) { create(:namespace, owner: user) } + let!(:project) { create(:project, namespace: namespace) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } + + it_behaves_like :project_owner + end + + context 'with group runner in a non owned group' do + let!(:group) { create(:group) } + let!(:runner) { create(:ci_runner, :group, groups: [group]) } def add_user(access) group.add_user(user, access) @@ -2930,37 +2977,114 @@ describe User, :do_not_mock_admin_mode do it_behaves_like :group_member end - context 'with groups runners' do + context 'with group runner in an owned group' do + let!(:group) { create(:group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [group]) } + + it_behaves_like :group_owner + end + + context 'with group runner in an owned group and group runner in a different owner subgroup' do + let!(:group) { create(:group) } let!(:runner) { create(:ci_runner, :group, groups: [group]) } + let!(:subgroup) { create(:group, parent: group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) } + let!(:another_user) { create(:user) } + + def set_permissions_for_users + group.add_owner(user) + subgroup.add_owner(another_user) + end + + it_behaves_like :nested_groups_owner + end + + context 'with personal project runner in an an owned group and a group runner in that same group' do let!(:group) { create(:group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [group]) } + let!(:project) { create(:project, group: group) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } - def add_user(access) - group.add_user(user, access) + def set_permissions_for_users + group.add_owner(user) end - it_behaves_like :group_member + it_behaves_like :nested_groups_owner end - context 'with other projects runners' do - let!(:project) { create(:project) } + context 'with personal project runner in an owned group and a group runner in a subgroup' do + let!(:group) { create(:group) } + let!(:subgroup) { create(:group, parent: group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) } + let!(:project) { create(:project, group: group) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } + + def set_permissions_for_users + group.add_owner(user) + end + + it_behaves_like :nested_groups_owner + end + + context 'with personal project runner in an owned group in an owned namespace and a group runner in that group' do + let!(:namespace) { create(:namespace, owner: user) } + let!(:group) { create(:group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [group]) } + let!(:project) { create(:project, namespace: namespace, group: group) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } + + def set_permissions_for_users + group.add_owner(user) + end + + it_behaves_like :nested_groups_owner + end + + context 'with personal project runner in an owned namespace, an owned group, a subgroup and a group runner in that subgroup' do + let!(:namespace) { create(:namespace, owner: user) } + let!(:group) { create(:group) } + let!(:subgroup) { create(:group, parent: group) } + let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) } + let!(:project) { create(:project, namespace: namespace, group: group) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } + + def set_permissions_for_users + group.add_owner(user) + end + + it_behaves_like :nested_groups_owner + end + + context 'with a project runner that belong to projects that belong to a not owned group' do + let!(:group) { create(:group) } + let!(:project) { create(:project, group: group) } + let!(:project_runner) { create(:ci_runner, :project, projects: [project]) } def add_user(access) project.add_user(user, access) end - it_behaves_like :member + it_behaves_like :project_member end - context 'with subgroup with different owner for project runner' do - let(:group) { create(:group) } - let(:another_user) { create(:user) } - let(:subgroup) { create(:group, parent: group) } - let!(:project) { create(:project, group: subgroup) } + context 'with project runners that belong to projects that do not belong to any group' do + let!(:project) { create(:project) } + let!(:runner) { create(:ci_runner, :project, projects: [project]) } + + it 'does not load any runner' do + expect(user.ci_owned_runners).to be_empty + end + end + + context 'with a group runner that belongs to a subgroup of a group owned by another user' do + let!(:group) { create(:group) } + let!(:subgroup) { create(:group, parent: group) } + let!(:runner) { create(:ci_runner, :group, groups: [subgroup]) } + let!(:another_user) { create(:user) } def add_user(access) - group.add_user(user, access) + subgroup.add_user(user, access) group.add_user(another_user, :owner) - subgroup.add_user(another_user, :owner) end it_behaves_like :group_member @@ -4406,6 +4530,16 @@ describe User, :do_not_mock_admin_mode do it { is_expected.to be false } end + + context 'when `:gitlab_employee_badge` feature flag is disabled' do + let(:user) { build(:user, email: 'test@gitlab.com') } + + before do + stub_feature_flags(gitlab_employee_badge: false) + end + + it { is_expected.to be false } + end end describe '#current_highest_access_level' do @@ -4428,6 +4562,27 @@ describe User, :do_not_mock_admin_mode do end end + describe '#organization' do + using RSpec::Parameterized::TableSyntax + + let(:user) { build(:user, organization: 'ACME') } + + subject { user.organization } + + where(:gitlab_employee?, :expected_result) do + true | 'GitLab' + false | 'ACME' + end + + with_them do + before do + allow(user).to receive(:gitlab_employee?).and_return(gitlab_employee?) + end + + it { is_expected.to eql(expected_result) } + end + end + context 'when after_commit :update_highest_role' do describe 'create user' do it 'initializes a new Members::UpdateHighestRoleService object' do diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index f6b257e6288..164be8f0da6 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -6,20 +6,28 @@ describe API::Runners do let(:admin) { create(:user, :admin) } let(:user) { create(:user) } let(:user2) { create(:user) } + let(:group_guest) { create(:user) } + let(:group_reporter) { create(:user) } + let(:group_developer) { create(:user) } let(:group_maintainer) { create(:user) } let(:project) { create(:project, creator_id: user.id) } let(:project2) { create(:project, creator_id: user.id) } let(:group) { create(:group).tap { |group| group.add_owner(user) } } + let(:subgroup) { create(:group, parent: group) } let!(:shared_runner) { create(:ci_runner, :instance, description: 'Shared runner') } let!(:project_runner) { create(:ci_runner, :project, description: 'Project runner', projects: [project]) } let!(:two_projects_runner) { create(:ci_runner, :project, description: 'Two projects runner', projects: [project, project2]) } - let!(:group_runner) { create(:ci_runner, :group, description: 'Group runner', groups: [group]) } + let!(:group_runner_a) { create(:ci_runner, :group, description: 'Group runner A', groups: [group]) } + let!(:group_runner_b) { create(:ci_runner, :group, description: 'Group runner B', groups: [subgroup]) } before do # Set project access for users + create(:group_member, :guest, user: group_guest, group: group) + create(:group_member, :reporter, user: group_reporter, group: group) + create(:group_member, :developer, user: group_developer, group: group) create(:group_member, :maintainer, user: group_maintainer, group: group) create(:project_member, :maintainer, user: user, project: project) create(:project_member, :maintainer, user: user, project: project2) @@ -41,7 +49,8 @@ describe API::Runners do expect(json_response).to match_array [ a_hash_including('description' => 'Project runner'), a_hash_including('description' => 'Two projects runner'), - a_hash_including('description' => 'Group runner') + a_hash_including('description' => 'Group runner A'), + a_hash_including('description' => 'Group runner B') ] end @@ -131,7 +140,8 @@ describe API::Runners do expect(json_response).to match_array [ a_hash_including('description' => 'Project runner'), a_hash_including('description' => 'Two projects runner'), - a_hash_including('description' => 'Group runner'), + a_hash_including('description' => 'Group runner A'), + a_hash_including('description' => 'Group runner B'), a_hash_including('description' => 'Shared runner') ] end @@ -156,7 +166,8 @@ describe API::Runners do expect(json_response).to match_array [ a_hash_including('description' => 'Project runner'), a_hash_including('description' => 'Two projects runner'), - a_hash_including('description' => 'Group runner') + a_hash_including('description' => 'Group runner A'), + a_hash_including('description' => 'Group runner B') ] end @@ -165,7 +176,7 @@ describe API::Runners do expect(response).to have_gitlab_http_status(:bad_request) end - it 'filters runners by type' do + it 'filters runners by project type' do get api('/runners/all?type=project_type', admin) expect(json_response).to match_array [ @@ -174,6 +185,15 @@ describe API::Runners do ] end + it 'filters runners by group type' do + get api('/runners/all?type=group_type', admin) + + expect(json_response).to match_array [ + a_hash_including('description' => 'Group runner A'), + a_hash_including('description' => 'Group runner B') + ] + end + it 'does not filter by invalid type' do get api('/runners/all?type=bogus', admin) @@ -526,15 +546,41 @@ describe API::Runners do end.to change { Ci::Runner.project_type.count }.by(-1) end + it 'does not delete group runner with guest access' do + delete api("/runners/#{group_runner_a.id}", group_guest) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'does not delete group runner with reporter access' do + delete api("/runners/#{group_runner_a.id}", group_reporter) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'does not delete group runner with developer access' do + delete api("/runners/#{group_runner_a.id}", group_developer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + it 'does not delete group runner with maintainer access' do - delete api("/runners/#{group_runner.id}", group_maintainer) + delete api("/runners/#{group_runner_a.id}", group_maintainer) expect(response).to have_gitlab_http_status(:forbidden) end - it 'deletes group runner with owner access' do + it 'deletes owned group runner with owner access' do + expect do + delete api("/runners/#{group_runner_a.id}", user) + + expect(response).to have_gitlab_http_status(:no_content) + end.to change { Ci::Runner.group_type.count }.by(-1) + end + + it 'deletes inherited group runner with owner access' do expect do - delete api("/runners/#{group_runner.id}", user) + delete api("/runners/#{group_runner_b.id}", user) expect(response).to have_gitlab_http_status(:no_content) end.to change { Ci::Runner.group_type.count }.by(-1) @@ -842,7 +888,7 @@ describe API::Runners do get api("/groups/#{group.id}/runners", user) expect(json_response).to match_array([ - a_hash_including('description' => 'Group runner') + a_hash_including('description' => 'Group runner A') ]) end @@ -851,7 +897,7 @@ describe API::Runners do get api("/groups/#{group.id}/runners?type=group_type", user) expect(json_response).to match_array([ - a_hash_including('description' => 'Group runner') + a_hash_including('description' => 'Group runner A') ]) end @@ -939,7 +985,7 @@ describe API::Runners do end it 'does not enable group runner' do - post api("/projects/#{project.id}/runners", user), params: { runner_id: group_runner.id } + post api("/projects/#{project.id}/runners", user), params: { runner_id: group_runner_a.id } expect(response).to have_gitlab_http_status(:forbidden) end diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb index 14e6feed3ab..e1c21f87780 100644 --- a/spec/views/profiles/show.html.haml_spec.rb +++ b/spec/views/profiles/show.html.haml_spec.rb @@ -19,4 +19,48 @@ describe 'profiles/show' do expect(rendered).to have_field('user_id', with: user.id) end end + + context 'gitlab.com organization field' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + context 'when `:gitlab_employee_badge` feature flag is enabled' do + context 'and when user has an `@gitlab.com` email address' do + let(:user) { create(:user, email: 'test@gitlab.com') } + + it 'displays the organization field as `readonly` with a `value` of `GitLab`' do + render + + expect(rendered).to have_selector('#user_organization[readonly][value="GitLab"]') + end + end + + context 'and when a user does not have an `@gitlab.com` email' do + let(:user) { create(:user, email: 'test@example.com') } + + it 'displays an editable organization field' do + render + + expect(rendered).to have_selector('#user_organization:not([readonly]):not([value="GitLab"])') + end + end + end + + context 'when `:gitlab_employee_badge` feature flag is disabled' do + before do + stub_feature_flags(gitlab_employee_badge: false) + end + + context 'and when a user has an `@gitlab.com` email' do + let(:user) { create(:user, email: 'test@gitlab.com') } + + it 'displays an editable organization field' do + render + + expect(rendered).to have_selector('#user_organization:not([readonly]):not([value="GitLab"])') + end + end + end + end end |