summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-05 18:08:43 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-05 18:08:43 +0000
commite129eff88309eca18f3902afd710e2e07393fe45 (patch)
tree2dd9399fdcfdee719d51e63cd821adc58165ccb3 /spec
parent205b6baf2677879c35968d2b659225b58e8a1227 (diff)
downloadgitlab-ce-e129eff88309eca18f3902afd710e2e07393fe45.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups/variables_controller_spec.rb2
-rw-r--r--spec/controllers/import/available_namespaces_controller_spec.rb6
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb2
-rw-r--r--spec/controllers/projects/mirrors_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb2
-rw-r--r--spec/features/admin/admin_groups_spec.rb8
-rw-r--r--spec/features/admin/admin_projects_spec.rb4
-rw-r--r--spec/features/file_uploads/multipart_invalid_uploads_spec.rb2
-rw-r--r--spec/features/issuables/issuable_list_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb4
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_deployment_widget_spec.rb2
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb4
-rw-r--r--spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_collaboration_links_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb4
-rw-r--r--spec/finders/autocomplete/users_finder_spec.rb2
-rw-r--r--spec/finders/joined_groups_finder_spec.rb2
-rw-r--r--spec/finders/packages/conan/package_finder_spec.rb2
-rw-r--r--spec/finders/packages/group_packages_finder_spec.rb4
-rw-r--r--spec/frontend/ide/components/new_dropdown/modal_spec.js424
-rw-r--r--spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/container_repositories_resolver_spec.rb2
-rw-r--r--spec/graphql/types/ci/job_token_scope_type_spec.rb4
-rw-r--r--spec/helpers/diff_helper_spec.rb51
-rw-r--r--spec/helpers/namespace_storage_limit_alert_helper_spec.rb11
-rw-r--r--spec/helpers/projects_helper_spec.rb2
-rw-r--r--spec/helpers/todos_helper_spec.rb10
-rw-r--r--spec/lib/banzai/reference_parser/snippet_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/variables/builder_spec.rb10
-rw-r--r--spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb23
-rw-r--r--spec/lib/gitlab/import_export/members_mapper_spec.rb6
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/users_extractor_spec.rb93
-rw-r--r--spec/lib/gitlab/user_access_spec.rb34
-rw-r--r--spec/mailers/notify_spec.rb8
-rw-r--r--spec/models/ci/build_spec.rb25
-rw-r--r--spec/models/group_spec.rb94
-rw-r--r--spec/models/members/group_member_spec.rb6
-rw-r--r--spec/models/members/project_member_spec.rb10
-rw-r--r--spec/models/merge_request_diff_file_spec.rb144
-rw-r--r--spec/models/merge_request_diff_spec.rb97
-rw-r--r--spec/models/merge_request_spec.rb2
-rw-r--r--spec/models/project_spec.rb4
-rw-r--r--spec/models/project_team_spec.rb10
-rw-r--r--spec/models/ssh_host_key_spec.rb41
-rw-r--r--spec/models/user_spec.rb30
-rw-r--r--spec/policies/environment_policy_spec.rb8
-rw-r--r--spec/policies/namespace/root_storage_statistics_policy_spec.rb2
-rw-r--r--spec/policies/project_policy_spec.rb6
-rw-r--r--spec/policies/project_statistics_policy_spec.rb2
-rw-r--r--spec/requests/api/ci/runner/jobs_request_post_spec.rb8
-rw-r--r--spec/requests/api/events_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb2
-rw-r--r--spec/requests/api/graphql/container_repository/container_repository_details_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/container_repositories_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/container_repositories_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb2
-rw-r--r--spec/requests/api/group_variables_spec.rb2
-rw-r--r--spec/requests/api/invitations_spec.rb26
-rw-r--r--spec/requests/jira_connect/oauth_application_ids_controller_spec.rb53
-rw-r--r--spec/requests/jira_connect/subscriptions_controller_spec.rb29
-rw-r--r--spec/requests/openid_connect_spec.rb14
-rw-r--r--spec/requests/projects/environments_controller_spec.rb2
-rw-r--r--spec/serializers/member_user_entity_spec.rb4
-rw-r--r--spec/services/groups/destroy_service_spec.rb10
-rw-r--r--spec/services/groups/update_service_spec.rb12
-rw-r--r--spec/services/issues/related_branches_service_spec.rb2
-rw-r--r--spec/services/members/creator_service_spec.rb4
-rw-r--r--spec/services/members/groups/creator_service_spec.rb6
-rw-r--r--spec/services/members/projects/creator_service_spec.rb6
-rw-r--r--spec/services/notification_service_spec.rb6
-rw-r--r--spec/services/projects/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/fork_service_spec.rb12
-rw-r--r--spec/services/projects/update_service_spec.rb2
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb57
-rw-r--r--spec/services/todo_service_spec.rb4
-rw-r--r--spec/support/helpers/project_helpers.rb2
-rw-r--r--spec/support/shared_examples/finders/issues_finder_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/member_shared_examples.rb78
-rw-r--r--spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb2
-rw-r--r--spec/views/shared/deploy_tokens/_form.html.haml_spec.rb2
-rw-r--r--spec/workers/disallow_two_factor_for_group_worker_spec.rb2
-rw-r--r--spec/workers/remove_expired_members_worker_spec.rb4
90 files changed, 1147 insertions, 461 deletions
diff --git a/spec/controllers/groups/variables_controller_spec.rb b/spec/controllers/groups/variables_controller_spec.rb
index 8c0aa83b9c4..6dbe75bb1df 100644
--- a/spec/controllers/groups/variables_controller_spec.rb
+++ b/spec/controllers/groups/variables_controller_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Groups::VariablesController do
before do
sign_in(user)
- group.add_user(user, access_level)
+ group.add_member(user, access_level)
end
describe 'GET #show' do
diff --git a/spec/controllers/import/available_namespaces_controller_spec.rb b/spec/controllers/import/available_namespaces_controller_spec.rb
index 0f98d649338..26ea1d92189 100644
--- a/spec/controllers/import/available_namespaces_controller_spec.rb
+++ b/spec/controllers/import/available_namespaces_controller_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Import::AvailableNamespacesController do
it "does not include group with access level #{params[:role]} in list" do
group = create(:group, project_creation_level: group_project_creation_level)
- group.add_user(user, role)
+ group.add_member(user, role)
get :index
expect(response).to have_gitlab_http_status(:ok)
@@ -52,7 +52,7 @@ RSpec.describe Import::AvailableNamespacesController do
it "does not include group with access level #{params[:role]} in list" do
group = create(:group, project_creation_level: group_project_creation_level)
- group.add_user(user, role)
+ group.add_member(user, role)
get :index
expect(response).to have_gitlab_http_status(:ok)
@@ -81,7 +81,7 @@ RSpec.describe Import::AvailableNamespacesController do
it "#{params[:is_visible] ? 'includes' : 'does not include'} group with access level #{params[:role]} in list" do
group = create(:group, project_creation_level: project_creation_level)
- group.add_user(user, :developer)
+ group.add_member(user, :developer)
get :index
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 1305693372c..badac688229 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1818,7 +1818,7 @@ RSpec.describe Projects::IssuesController do
context 'user is allowed access' do
before do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
end
it 'displays all available notes' do
diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb
index 686effd799e..d33bc215cfc 100644
--- a/spec/controllers/projects/mirrors_controller_spec.rb
+++ b/spec/controllers/projects/mirrors_controller_spec.rb
@@ -211,7 +211,7 @@ RSpec.describe Projects::MirrorsController do
context 'data in the cache' do
let(:ssh_key) { 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf' }
- let(:ssh_fp) { { type: 'ed25519', bits: 256, fingerprint: '2e:65:6a:c8:cf:bf:b2:8b:9a:bd:6d:9f:11:5c:12:16', index: 0 } }
+ let(:ssh_fp) { { type: 'ed25519', bits: 256, fingerprint: '2e:65:6a:c8:cf:bf:b2:8b:9a:bd:6d:9f:11:5c:12:16', fingerprint_sha256: 'SHA256:eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8', index: 0 } }
it 'returns the data with a 200 response' do
stub_reactive_cache(cache, known_hosts: ssh_key)
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index d9d26a68785..34477a7bb68 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -409,7 +409,7 @@ RSpec.describe ProjectsController do
before do
project.update!(visibility: project_visibility.to_s)
- project.team.add_user(user, :guest) if user_type == :member
+ project.team.add_member(user, :guest) if user_type == :member
sign_in(user) unless user_type == :anonymous
end
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index f903d7c2db2..040c6a65b7c 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -236,7 +236,7 @@ RSpec.describe 'Admin Groups' do
it 'renders relative time' do
expire_time = Time.current + 2.days
current_user.update!(time_display_relative: true)
- group.add_user(user, Gitlab::Access::REPORTER, expires_at: expire_time)
+ group.add_member(user, Gitlab::Access::REPORTER, expires_at: expire_time)
visit admin_group_path(group)
@@ -246,7 +246,7 @@ RSpec.describe 'Admin Groups' do
it 'renders absolute time' do
expire_time = Time.current.tomorrow.middle_of_day
current_user.update!(time_display_relative: false)
- group.add_user(user, Gitlab::Access::REPORTER, expires_at: expire_time)
+ group.add_member(user, Gitlab::Access::REPORTER, expires_at: expire_time)
visit admin_group_path(group)
@@ -257,7 +257,7 @@ RSpec.describe 'Admin Groups' do
describe 'add admin himself to a group' do
before do
- group.add_user(:user, Gitlab::Access::OWNER)
+ group.add_member(:user, Gitlab::Access::OWNER)
end
it 'adds admin a to a group as developer', :js do
@@ -274,7 +274,7 @@ RSpec.describe 'Admin Groups' do
describe 'admin removes themself from a group', :js do
it 'removes admin from the group' do
- group.add_user(current_user, Gitlab::Access::DEVELOPER)
+ group.add_member(current_user, Gitlab::Access::DEVELOPER)
visit group_group_members_path(group)
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 866368af40a..6b147b01991 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe "Admin::Projects" do
it 'renders relative time' do
expire_time = Time.current + 2.days
current_user.update!(time_display_relative: true)
- project.add_user(user, Gitlab::Access::REPORTER, expires_at: expire_time)
+ project.add_member(user, Gitlab::Access::REPORTER, expires_at: expire_time)
visit admin_project_path(project)
@@ -30,7 +30,7 @@ RSpec.describe "Admin::Projects" do
it 'renders absolute time' do
expire_time = Time.current.tomorrow.middle_of_day
current_user.update!(time_display_relative: false)
- project.add_user(user, Gitlab::Access::REPORTER, expires_at: expire_time)
+ project.add_member(user, Gitlab::Access::REPORTER, expires_at: expire_time)
visit admin_project_path(project)
diff --git a/spec/features/file_uploads/multipart_invalid_uploads_spec.rb b/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
index 91c8e100e6a..cff8b4e61a5 100644
--- a/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
+++ b/spec/features/file_uploads/multipart_invalid_uploads_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe 'Invalid uploads that must be rejected', :api, :js do
# These keys are rejected directly by rack itself.
# The request will not be received by multipart.rb (can't use the 'handling file uploads' shared example)
- it_behaves_like 'rejecting invalid keys', key_name: 'x' * 11000, message: 'Puma caught this error: exceeded available parameter key space (RangeError)'
+ it_behaves_like 'rejecting invalid keys', key_name: 'x' * 11000, message: 'Puma caught this error: exceeded available parameter key space (Rack::QueryParser::ParamsTooDeepError)'
it_behaves_like 'rejecting invalid keys', key_name: 'package[]test', status: 400, message: 'Bad Request'
it_behaves_like 'handling file uploads', 'by rejecting uploads with an invalid key'
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
index 0fa2d238b0a..a1e80586c05 100644
--- a/spec/features/issuables/issuable_list_spec.rb
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'issuable list', :js do
issuable_types = [:issue, :merge_request]
before do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
sign_in(user)
issuable_types.each { |type| create_issuables(type) }
end
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index 7a367723609..c44181a60e4 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -15,8 +15,8 @@ RSpec.describe 'Visual tokens', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- project.add_user(user, :maintainer)
- project.add_user(user_rock, :maintainer)
+ project.add_member(user, :maintainer)
+ project.add_member(user_rock, :maintainer)
sign_in(user)
visit project_issues_path(project)
diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
index ae1bce7ea4c..5ba09703852 100644
--- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
+++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
context 'when signed in' do
before do
- project.add_user(user, membership_level)
+ project.add_member(user, membership_level)
sign_in(user)
end
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 81034caaee2..e045f11c0d8 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
before do
merge_request.update!(merge_commit_sha: sha)
- project.add_user(user, role)
+ project.add_member(user, role)
sign_in(user)
end
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index bd0874316ac..c92e8bc2954 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date
end
it 'changes expiration date' do
- project.team.add_users([new_member.id], :developer, expires_at: three_days_from_now)
+ project.team.add_members([new_member.id], :developer, expires_at: three_days_from_now)
visit project_project_members_path(project)
page.within find_member_row(new_member) do
@@ -46,7 +46,7 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date
end
it 'clears expiration date' do
- project.team.add_users([new_member.id], :developer, expires_at: five_days_from_now)
+ project.team.add_members([new_member.id], :developer, expires_at: five_days_from_now)
visit project_project_members_path(project)
page.within find_member_row(new_member) do
diff --git a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
index 59f1bc94226..262885e09b3 100644
--- a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Project > Show > User interacts with auto devops implicitly enab
let(:user) { create(:user) }
before do
- project.add_user(user, role)
+ project.add_member(user, role)
sign_in(user)
end
diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
index 552f068ecc7..fb2f0539558 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
with_them do
before do
project.project_feature.update!({ merge_requests_access_level: merge_requests_access_level })
- project.add_user(user, user_level)
+ project.add_member(user, user_level)
visit project_path(project)
end
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index efb7c98d63a..3ba3650b608 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -579,9 +579,9 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
context 'group setting' do
before do
group1 = create :group, name: 'Group 1', require_two_factor_authentication: true
- group1.add_user(user, GroupMember::DEVELOPER)
+ group1.add_member(user, GroupMember::DEVELOPER)
group2 = create :group, name: 'Group 2', require_two_factor_authentication: true
- group2.add_user(user, GroupMember::DEVELOPER)
+ group2.add_member(user, GroupMember::DEVELOPER)
end
context 'with grace period defined' do
diff --git a/spec/finders/autocomplete/users_finder_spec.rb b/spec/finders/autocomplete/users_finder_spec.rb
index 9b3421d1b4f..de031041e18 100644
--- a/spec/finders/autocomplete/users_finder_spec.rb
+++ b/spec/finders/autocomplete/users_finder_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe Autocomplete::UsersFinder do
let_it_be(:group) { create(:group, :public) }
before_all do
- group.add_users([user1], GroupMember::DEVELOPER)
+ group.add_members([user1], GroupMember::DEVELOPER)
end
it { is_expected.to match_array([user1]) }
diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb
index 058db735708..feb1b11d159 100644
--- a/spec/finders/joined_groups_finder_spec.rb
+++ b/spec/finders/joined_groups_finder_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe JoinedGroupsFinder do
context 'if profile visitor is in one of the private group projects' do
before do
project = create(:project, :private, group: private_group, name: 'B', path: 'B')
- project.add_user(profile_visitor, Gitlab::Access::DEVELOPER)
+ project.add_member(profile_visitor, Gitlab::Access::DEVELOPER)
end
it 'shows group' do
diff --git a/spec/finders/packages/conan/package_finder_spec.rb b/spec/finders/packages/conan/package_finder_spec.rb
index 6848786818b..f25a62225a8 100644
--- a/spec/finders/packages/conan/package_finder_spec.rb
+++ b/spec/finders/packages/conan/package_finder_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe ::Packages::Conan::PackageFinder do
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.string_options[visibility.to_s])
- project.add_user(user, role) unless role == :anonymous
+ project.add_member(user, role) unless role == :anonymous
end
it { is_expected.to eq(expected_packages) }
diff --git a/spec/finders/packages/group_packages_finder_spec.rb b/spec/finders/packages/group_packages_finder_spec.rb
index 954db6481cd..90a8cd3c57f 100644
--- a/spec/finders/packages/group_packages_finder_spec.rb
+++ b/spec/finders/packages/group_packages_finder_spec.rb
@@ -98,8 +98,8 @@ RSpec.describe Packages::GroupPackagesFinder do
)
unless role == :anonymous
- project.add_user(user, role)
- subproject.add_user(user, role)
+ project.add_member(user, role)
+ subproject.add_member(user, role)
end
end
diff --git a/spec/frontend/ide/components/new_dropdown/modal_spec.js b/spec/frontend/ide/components/new_dropdown/modal_spec.js
index e8635444801..8c72a37ec84 100644
--- a/spec/frontend/ide/components/new_dropdown/modal_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/modal_spec.js
@@ -1,209 +1,373 @@
-import Vue, { nextTick } from 'vue';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { GlButton, GlModal } from '@gitlab/ui';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
-import modal from '~/ide/components/new_dropdown/modal.vue';
+import Modal from '~/ide/components/new_dropdown/modal.vue';
import { createStore } from '~/ide/stores';
+import { stubComponent } from 'helpers/stub_component';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { createEntriesFromPaths } from '../../helpers';
jest.mock('~/flash');
+const NEW_NAME = 'babar';
+
describe('new file modal component', () => {
- const Component = Vue.extend(modal);
- let vm;
+ const showModal = jest.fn();
+ const toggleModal = jest.fn();
+
+ let store;
+ let wrapper;
+
+ const findGlModal = () => wrapper.findComponent(GlModal);
+ const findInput = () => wrapper.findByTestId('file-name-field');
+ const findTemplateButtons = () => wrapper.findAllComponents(GlButton);
+ const findTemplateButtonsModel = () =>
+ findTemplateButtons().wrappers.map((x) => ({
+ text: x.text(),
+ variant: x.props('variant'),
+ category: x.props('category'),
+ }));
+
+ const open = (type, path) => {
+ // TODO: This component can not be passed props
+ // We have to interact with the open() method?
+ wrapper.vm.open(type, path);
+ };
+ const triggerSubmit = () => {
+ findGlModal().vm.$emit('primary');
+ };
+ const triggerCancel = () => {
+ findGlModal().vm.$emit('cancel');
+ };
+
+ const mountComponent = () => {
+ const GlModalStub = stubComponent(GlModal);
+ jest.spyOn(GlModalStub.methods, 'show').mockImplementation(showModal);
+ jest.spyOn(GlModalStub.methods, 'toggle').mockImplementation(toggleModal);
+
+ wrapper = shallowMountExtended(Modal, {
+ store,
+ stubs: {
+ GlModal: GlModalStub,
+ },
+ // We need to attach to document for "focus" to work
+ attachTo: document.body,
+ });
+ };
+
+ beforeEach(() => {
+ store = createStore();
+
+ Object.assign(
+ store.state.entries,
+ createEntriesFromPaths([
+ 'README.md',
+ 'src',
+ 'src/deleted.js',
+ 'src/parent_dir',
+ 'src/parent_dir/foo.js',
+ ]),
+ );
+ Object.assign(store.state.entries['src/deleted.js'], { deleted: true });
+
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ });
afterEach(() => {
- vm.$destroy();
+ store = null;
+ wrapper.destroy();
+ document.body.innerHTML = '';
});
- describe.each`
- entryType | modalTitle | btnTitle | showsFileTemplates
- ${'tree'} | ${'Create new directory'} | ${'Create directory'} | ${false}
- ${'blob'} | ${'Create new file'} | ${'Create file'} | ${true}
- `('$entryType', ({ entryType, modalTitle, btnTitle, showsFileTemplates }) => {
+ describe('default', () => {
beforeEach(async () => {
- const store = createStore();
-
- vm = createComponentWithStore(Component, store).$mount();
- vm.open(entryType);
- vm.name = 'testing';
+ mountComponent();
+ // Not necessarily needed, but used to ensure that nothing extra is happening after the tick
await nextTick();
});
- afterEach(() => {
- vm.close();
+ it('renders modal', () => {
+ expect(findGlModal().props()).toMatchObject({
+ actionCancel: {
+ attributes: [{ variant: 'default' }],
+ text: 'Cancel',
+ },
+ actionPrimary: {
+ attributes: [{ variant: 'confirm' }],
+ text: 'Create file',
+ },
+ actionSecondary: null,
+ size: 'lg',
+ modalId: 'ide-new-entry',
+ title: 'Create new file',
+ });
});
- it(`sets modal title as ${entryType}`, () => {
- expect(document.querySelector('.modal-title').textContent.trim()).toBe(modalTitle);
+ it('renders name label', () => {
+ expect(wrapper.find('label').text()).toBe('Name');
});
- it(`sets button label as ${entryType}`, () => {
- expect(document.querySelector('.btn-confirm').textContent.trim()).toBe(btnTitle);
+ it('renders template buttons', () => {
+ const actual = findTemplateButtonsModel();
+
+ expect(actual.length).toBeGreaterThan(0);
+ expect(actual).toEqual(
+ store.getters['fileTemplates/templateTypes'].map((template) => ({
+ category: 'secondary',
+ text: template.name,
+ variant: 'dashed',
+ })),
+ );
});
- it(`sets form label as ${entryType}`, () => {
- expect(document.querySelector('.label-bold').textContent.trim()).toBe('Name');
+ // These negative ".not.toHaveBeenCalled" assertions complement the positive "toHaveBeenCalled"
+ // assertions that show up later in this spec. Without these, we're not guaranteed the "act"
+ // actually caused the change in behavior.
+ it('does not dispatch actions by default', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
});
- it(`shows file templates: ${showsFileTemplates}`, () => {
- const templateFilesEl = document.querySelector('.file-templates');
- expect(Boolean(templateFilesEl)).toBe(showsFileTemplates);
+ it('does not trigger modal by default', () => {
+ expect(showModal).not.toHaveBeenCalled();
+ expect(toggleModal).not.toHaveBeenCalled();
});
- });
- describe('rename entry', () => {
- beforeEach(() => {
- const store = createStore();
- store.state.entries = {
- 'test-path': {
- name: 'test',
- type: 'blob',
- path: 'test-path',
- },
- };
-
- vm = createComponentWithStore(Component, store).$mount();
+ it('does not focus input by default', () => {
+ expect(document.activeElement).toBe(document.body);
});
+ });
- it.each`
- entryType | modalTitle | btnTitle
- ${'tree'} | ${'Rename folder'} | ${'Rename folder'}
- ${'blob'} | ${'Rename file'} | ${'Rename file'}
- `(
- 'renders title and button for renaming $entryType',
- async ({ entryType, modalTitle, btnTitle }) => {
- vm.$store.state.entries['test-path'].type = entryType;
- vm.open('rename', 'test-path');
+ describe.each`
+ entryType | path | modalTitle | btnTitle | showsFileTemplates | inputValue | inputPlaceholder
+ ${'tree'} | ${''} | ${'Create new directory'} | ${'Create directory'} | ${false} | ${''} | ${'dir/'}
+ ${'blob'} | ${''} | ${'Create new file'} | ${'Create file'} | ${true} | ${''} | ${'dir/file_name'}
+ ${'blob'} | ${'foo/bar'} | ${'Create new file'} | ${'Create file'} | ${true} | ${'foo/bar/'} | ${'dir/file_name'}
+ `(
+ 'when opened as $entryType with path "$path"',
+ ({
+ entryType,
+ path,
+ modalTitle,
+ btnTitle,
+ showsFileTemplates,
+ inputValue,
+ inputPlaceholder,
+ }) => {
+ beforeEach(async () => {
+ mountComponent();
+
+ open(entryType, path);
await nextTick();
- expect(document.querySelector('.modal-title').textContent.trim()).toBe(modalTitle);
- expect(document.querySelector('.btn-confirm').textContent.trim()).toBe(btnTitle);
- },
- );
+ });
- describe('entryName', () => {
- it('returns entries name', () => {
- vm.open('rename', 'test-path');
+ it('sets modal props', () => {
+ expect(findGlModal().props()).toMatchObject({
+ title: modalTitle,
+ actionPrimary: {
+ attributes: [{ variant: 'confirm' }],
+ text: btnTitle,
+ },
+ });
+ });
- expect(vm.entryName).toBe('test-path');
+ it('sets input attributes', () => {
+ expect(findInput().element.value).toBe(inputValue);
+ expect(findInput().attributes('placeholder')).toBe(inputPlaceholder);
});
- it('does not reset entryName to its old value if empty', () => {
- vm.entryName = 'hello';
- vm.entryName = '';
+ it(`shows file templates: ${showsFileTemplates}`, () => {
+ const actual = findTemplateButtonsModel().length > 0;
- expect(vm.entryName).toBe('');
+ expect(actual).toBe(showsFileTemplates);
});
- });
- describe('open', () => {
- it('sets entryName to path provided if modalType is rename', () => {
- vm.open('rename', 'test-path');
+ it('shows modal', () => {
+ expect(showModal).toHaveBeenCalled();
+ });
- expect(vm.entryName).toBe('test-path');
+ it('focus on input', () => {
+ expect(document.activeElement).toBe(findInput().element);
});
- it("appends '/' to the path if modalType isn't rename", () => {
- vm.open('blob', 'test-path');
+ it('resets when canceled', async () => {
+ triggerCancel();
+
+ await nextTick();
- expect(vm.entryName).toBe('test-path/');
+ // Resets input value
+ expect(findInput().element.value).toBe('');
+ // Resets to blob mode
+ expect(findGlModal().props('title')).toBe('Create new file');
});
+ },
+ );
+
+ describe.each`
+ modalType | name | expectedName
+ ${'blob'} | ${'foo/bar.js'} | ${'foo/bar.js'}
+ ${'blob'} | ${'foo /bar.js'} | ${'foo/bar.js'}
+ ${'tree'} | ${'foo/dir'} | ${'foo/dir'}
+ ${'tree'} | ${'foo /dir'} | ${'foo/dir'}
+ `('when submitting as $modalType with "$name"', ({ modalType, name, expectedName }) => {
+ beforeEach(async () => {
+ mountComponent();
+
+ open(modalType, '');
+ await nextTick();
- it('leaves entryName blank if no path is provided', () => {
- vm.open('blob');
+ findInput().setValue(name);
+ triggerSubmit();
+ });
- expect(vm.entryName).toBe('');
+ it('triggers createTempEntry action', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('createTempEntry', {
+ name: expectedName,
+ type: modalType,
});
});
});
- describe('createFromTemplate', () => {
- let store;
+ describe('when creating from template type', () => {
+ beforeEach(async () => {
+ mountComponent();
- beforeEach(() => {
- store = createStore();
- store.state.entries = {
- 'test-path/test': {
- name: 'test',
- deleted: false,
- },
- };
+ open('blob', 'some_dir');
- vm = createComponentWithStore(Component, store).$mount();
- vm.open('blob');
+ await nextTick();
- jest.spyOn(vm, 'createTempEntry').mockImplementation();
+ // Set input, then trigger button
+ findInput().setValue('some_dir/foo.js');
+ findTemplateButtons().at(1).vm.$emit('click');
});
- it.each`
- entryName | newFilePath
- ${''} | ${'.gitignore'}
- ${'README.md'} | ${'.gitignore'}
- ${'test-path/test/'} | ${'test-path/test/.gitignore'}
- ${'test-path/test'} | ${'test-path/.gitignore'}
- ${'test-path/test/abc.md'} | ${'test-path/test/.gitignore'}
- `(
- 'creates a new file with the given template name in appropriate directory for path: $path',
- ({ entryName, newFilePath }) => {
- vm.entryName = entryName;
+ it('triggers createTempEntry action', () => {
+ const { name: expectedName } = store.getters['fileTemplates/templateTypes'][1];
- vm.createFromTemplate({ name: '.gitignore' });
+ expect(store.dispatch).toHaveBeenCalledWith('createTempEntry', {
+ name: `some_dir/${expectedName}`,
+ type: 'blob',
+ });
+ });
- expect(vm.createTempEntry).toHaveBeenCalledWith({
- name: newFilePath,
- type: 'blob',
- });
- },
- );
+ it('toggles modal', () => {
+ expect(toggleModal).toHaveBeenCalled();
+ });
});
- describe('submitForm', () => {
- let store;
+ describe.each`
+ origPath | title | inputValue | inputSelectionStart
+ ${'src/parent_dir'} | ${'Rename folder'} | ${'src/parent_dir'} | ${'src/'.length}
+ ${'README.md'} | ${'Rename file'} | ${'README.md'} | ${0}
+ `('when renaming for $origPath', ({ origPath, title, inputValue, inputSelectionStart }) => {
+ beforeEach(async () => {
+ mountComponent();
+
+ open('rename', origPath);
+
+ await nextTick();
+ });
- beforeEach(() => {
- store = createStore();
- store.state.entries = {
- 'test-path/test': {
- name: 'test',
- deleted: false,
+ it('sets modal props for renaming', () => {
+ expect(findGlModal().props()).toMatchObject({
+ title,
+ actionPrimary: {
+ attributes: [{ variant: 'confirm' }],
+ text: title,
},
- };
+ });
+ });
- vm = createComponentWithStore(Component, store).$mount();
+ it('sets input value', () => {
+ expect(findInput().element.value).toBe(inputValue);
});
- it('throws an error when target entry exists', () => {
- vm.open('rename', 'test-path/test');
+ it(`does not show file templates`, () => {
+ expect(findTemplateButtonsModel()).toHaveLength(0);
+ });
- expect(createFlash).not.toHaveBeenCalled();
+ it('shows modal when renaming', () => {
+ expect(showModal).toHaveBeenCalled();
+ });
+
+ it('focus on input when renaming', () => {
+ expect(document.activeElement).toBe(findInput().element);
+ });
+
+ it('selects name part of the input', () => {
+ expect(findInput().element.selectionStart).toBe(inputSelectionStart);
+ expect(findInput().element.selectionEnd).toBe(origPath.length);
+ });
+
+ describe('when renames is submitted successfully', () => {
+ beforeEach(() => {
+ findInput().setValue(NEW_NAME);
+ triggerSubmit();
+ });
+
+ it('dispatches renameEntry event', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('renameEntry', {
+ path: origPath,
+ parentPath: '',
+ name: NEW_NAME,
+ });
+ });
- vm.submitForm();
+ it('does not trigger flash', () => {
+ expect(createFlash).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when renaming and file already exists', () => {
+ beforeEach(async () => {
+ mountComponent();
+
+ open('rename', 'src/parent_dir');
+
+ await nextTick();
+
+ // Set to something that already exists!
+ findInput().setValue('src');
+ triggerSubmit();
+ });
+ it('creates flash', () => {
expect(createFlash).toHaveBeenCalledWith({
- message: 'The name "test-path/test" is already taken in this directory.',
+ message: 'The name "src" is already taken in this directory.',
fadeTransition: false,
addBodyClass: true,
});
});
- it('does not throw error when target entry does not exist', () => {
- jest.spyOn(vm, 'renameEntry').mockImplementation();
+ it('does not dispatch event', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
- vm.open('rename', 'test-path/test');
- vm.entryName = 'test-path/test2';
- vm.submitForm();
+ describe('when renaming and file has been deleted', () => {
+ beforeEach(async () => {
+ mountComponent();
- expect(createFlash).not.toHaveBeenCalled();
- });
+ open('rename', 'src/parent_dir/foo.js');
- it('removes leading/trailing found in the new name', () => {
- vm.open('rename', 'test-path/test');
+ await nextTick();
- vm.entryName = 'test-path /test';
+ findInput().setValue('src/deleted.js');
+ triggerSubmit();
+ });
- vm.submitForm();
+ it('does not create flash', () => {
+ expect(createFlash).not.toHaveBeenCalled();
+ });
- expect(vm.entryName).toBe('test-path/test');
+ it('dispatches event', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('renameEntry', {
+ path: 'src/parent_dir/foo.js',
+ name: 'deleted.js',
+ parentPath: 'src',
+ });
});
});
});
diff --git a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
index 59616815de0..ac7cef20df4 100644
--- a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
describe '#resolve' do
context 'with access to scope' do
before do
- project.add_user(current_user, :maintainer)
+ project.add_member(current_user, :maintainer)
end
it 'returns nil when scope is not enabled' do
@@ -51,7 +51,7 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
context 'without access to scope' do
before do
- project.add_user(current_user, :developer)
+ project.add_member(current_user, :developer)
end
it 'generates an error' do
diff --git a/spec/graphql/resolvers/container_repositories_resolver_spec.rb b/spec/graphql/resolvers/container_repositories_resolver_spec.rb
index d7aa761320f..ed922259903 100644
--- a/spec/graphql/resolvers/container_repositories_resolver_spec.rb
+++ b/spec/graphql/resolvers/container_repositories_resolver_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do
context 'with authorized user' do
before do
- group.add_user(user, :maintainer)
+ group.add_member(user, :maintainer)
end
context 'when the object is a project' do
diff --git a/spec/graphql/types/ci/job_token_scope_type_spec.rb b/spec/graphql/types/ci/job_token_scope_type_spec.rb
index 43225b2089b..c1a3c4dd54d 100644
--- a/spec/graphql/types/ci/job_token_scope_type_spec.rb
+++ b/spec/graphql/types/ci/job_token_scope_type_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe GitlabSchema.types['CiJobTokenScopeType'] do
context 'with access to scope' do
before do
- project.add_user(current_user, :maintainer)
+ project.add_member(current_user, :maintainer)
end
context 'when multiple projects in the allow list' do
@@ -46,7 +46,7 @@ RSpec.describe GitlabSchema.types['CiJobTokenScopeType'] do
context 'when linked projects are readable' do
before do
- link.target_project.add_user(current_user, :developer)
+ link.target_project.add_member(current_user, :developer)
end
it 'returns readable projects in scope' do
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index cf16807723b..b6efced698d 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -471,21 +471,60 @@ RSpec.describe DiffHelper do
describe '#conflicts' do
let(:merge_request) { instance_double(MergeRequest) }
+ let(:merge_ref_head_diff) { true }
+ let(:can_be_resolved_in_ui?) { true }
+ let(:allow_tree_conflicts) { false }
+ let(:files) { [instance_double(Gitlab::Conflict::File, path: 'a')] }
+ let(:exception) { nil }
before do
allow(helper).to receive(:merge_request).and_return(merge_request)
- allow(helper).to receive(:options).and_return(merge_ref_head_diff: true)
+ allow(helper).to receive(:options).and_return(merge_ref_head_diff: merge_ref_head_diff)
+
+ allow_next_instance_of(MergeRequests::Conflicts::ListService, merge_request, allow_tree_conflicts: allow_tree_conflicts) do |svc|
+ allow(svc).to receive(:can_be_resolved_in_ui?).and_return(can_be_resolved_in_ui?)
+
+ if exception.present?
+ allow(svc).to receive_message_chain(:conflicts, :files).and_raise(exception)
+ else
+ allow(svc).to receive_message_chain(:conflicts, :files).and_return(files)
+ end
+ end
end
- context 'when Gitlab::Git::Conflict::Resolver::ConflictSideMissing exception is raised' do
- before do
- allow_next_instance_of(MergeRequests::Conflicts::ListService, merge_request, allow_tree_conflicts: true) do |svc|
- allow(svc).to receive_message_chain(:conflicts, :files).and_raise(Gitlab::Git::Conflict::Resolver::ConflictSideMissing)
+ it 'returns list of conflicts indexed by path' do
+ expect(helper.conflicts).to eq('a' => files.first)
+ end
+
+ context 'when merge_ref_head_diff option is false' do
+ let(:merge_ref_head_diff) { false }
+
+ it 'returns nil' do
+ expect(helper.conflicts).to be_nil
+ end
+ end
+
+ context 'when conflicts cannot be resolved in UI' do
+ let(:can_be_resolved_in_ui?) { false }
+
+ it 'returns nil' do
+ expect(helper.conflicts).to be_nil
+ end
+
+ context 'when allow_tree_conflicts is true' do
+ let(:allow_tree_conflicts) { true }
+
+ it 'returns list of conflicts' do
+ expect(helper.conflicts(allow_tree_conflicts: allow_tree_conflicts)).to eq('a' => files.first)
end
end
+ end
+
+ context 'when Gitlab::Git::Conflict::Resolver::ConflictSideMissing exception is raised' do
+ let(:exception) { Gitlab::Git::Conflict::Resolver::ConflictSideMissing }
it 'returns an empty hash' do
- expect(helper.conflicts(allow_tree_conflicts: true)).to eq({})
+ expect(helper.conflicts).to eq({})
end
end
end
diff --git a/spec/helpers/namespace_storage_limit_alert_helper_spec.rb b/spec/helpers/namespace_storage_limit_alert_helper_spec.rb
deleted file mode 100644
index ab3cf96edef..00000000000
--- a/spec/helpers/namespace_storage_limit_alert_helper_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe NamespaceStorageLimitAlertHelper do
- describe '#display_namespace_storage_limit_alert!' do
- it 'is defined in CE' do
- expect { helper.display_namespace_storage_limit_alert! }.not_to raise_error
- end
- end
-end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 4502729866c..42c97b61d19 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -698,7 +698,7 @@ RSpec.describe ProjectsHelper do
def grant_user_access(project, user, access)
case access
when :developer, :maintainer
- project.add_user(user, access)
+ project.add_member(user, access)
when :owner
project.namespace.update!(owner: user)
end
diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb
index 73a454fd9f7..bbabfedc3ee 100644
--- a/spec/helpers/todos_helper_spec.rb
+++ b/spec/helpers/todos_helper_spec.rb
@@ -133,6 +133,16 @@ RSpec.describe TodosHelper do
expect(path).to eq("/#{todo.project.full_path}/-/work_items/#{todo.target.id}")
end
end
+
+ context 'when given an issue with a note anchor' do
+ let(:todo) { create(:todo, project: issue.project, target: issue, note: note) }
+
+ it 'responds with an appropriate path' do
+ path = helper.todo_target_path(todo)
+
+ expect(path).to eq("/#{issue.project.full_path}/-/issues/#{issue.iid}##{dom_id(note)}")
+ end
+ end
end
describe '#todo_target_type_name' do
diff --git a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
index 3459784708f..e8ef4e7f6e3 100644
--- a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Banzai::ReferenceParser::SnippetParser do
end
before do
- project.add_user(project_member, :developer)
+ project.add_member(project_member, :developer)
end
describe '#nodes_visible_to_user' do
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
index ec394bb9f05..34d5158a5ab 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
describe '#serialized_records' do
shared_context 'when records are loaded by maintainer' do
before do
- project.add_user(user, Gitlab::Access::DEVELOPER)
+ project.add_member(user, Gitlab::Access::DEVELOPER)
end
it 'returns all records' do
@@ -72,7 +72,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
context 'when records are loaded by guest' do
before do
- project.add_user(user, Gitlab::Access::GUEST)
+ project.add_member(user, Gitlab::Access::GUEST)
end
it 'filters out confidential issues' do
@@ -124,7 +124,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
end
before do
- project.add_user(user, Gitlab::Access::DEVELOPER)
+ project.add_member(user, Gitlab::Access::DEVELOPER)
stub_const('Gitlab::Analytics::CycleAnalytics::RecordsFetcher::MAX_RECORDS', 2)
end
diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb
index b0704ad7f50..8ec0846bdca 100644
--- a/spec/lib/gitlab/ci/variables/builder_spec.rb
+++ b/spec/lib/gitlab/ci/variables/builder_spec.rb
@@ -166,9 +166,8 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
allow(builder).to receive(:secret_instance_variables) { [var('J', 10), var('K', 10)] }
allow(builder).to receive(:secret_group_variables) { [var('K', 11), var('L', 11)] }
allow(builder).to receive(:secret_project_variables) { [var('L', 12), var('M', 12)] }
- allow(job).to receive(:trigger_request) { double(user_variables: [var('M', 13), var('N', 13)]) }
- allow(pipeline).to receive(:variables) { [var('N', 14), var('O', 14)] }
- allow(pipeline).to receive(:pipeline_schedule) { double(job_variables: [var('O', 15), var('P', 15)]) }
+ allow(pipeline).to receive(:variables) { [var('M', 13), var('N', 13)] }
+ allow(pipeline).to receive(:pipeline_schedule) { double(job_variables: [var('N', 14), var('O', 14)]) }
end
it 'returns variables in order depending on resource hierarchy' do
@@ -185,8 +184,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
var('K', 11), var('L', 11),
var('L', 12), var('M', 12),
var('M', 13), var('N', 13),
- var('N', 14), var('O', 14),
- var('O', 15), var('P', 15)])
+ var('N', 14), var('O', 14)])
end
it 'overrides duplicate keys depending on resource hierarchy' do
@@ -198,7 +196,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
'I' => '9', 'J' => '10',
'K' => '11', 'L' => '12',
'M' => '13', 'N' => '14',
- 'O' => '15', 'P' => '15')
+ 'O' => '14')
end
end
diff --git a/spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb b/spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb
index e676e5fe034..2878d72210e 100644
--- a/spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb
+++ b/spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb
@@ -109,7 +109,7 @@ RSpec.describe Gitlab::DatabaseImporters::InstanceAdministrators::CreateGroup do
admin2 = create(:user, :admin)
existing_group.add_owner(user)
- existing_group.add_users([admin1, admin2], Gitlab::Access::MAINTAINER)
+ existing_group.add_members([admin1, admin2], Gitlab::Access::MAINTAINER)
application_setting.instance_administrators_group_id = existing_group.id
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 03f522ae490..3f73a730744 100644
--- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
+++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
@@ -171,4 +171,27 @@ RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do
expect(described_class.batch_size(exportable)).to eq(described_class::BATCH_SIZE)
end
end
+
+ describe '#serialize_relation' do
+ context 'when record is a merge request' do
+ let(:json_writer) do
+ Class.new do
+ def write_relation_array(_, _, enumerator)
+ enumerator.each { _1 }
+ end
+ end.new
+ end
+
+ it 'removes cached external diff' do
+ merge_request = create(:merge_request, source_project: exportable, target_project: exportable)
+ cache_dir = merge_request.merge_request_diff.send(:external_diff_cache_dir)
+
+ expect(subject).to receive(:remove_cached_external_diff).with(merge_request).twice
+
+ subject.serialize_relation({ merge_requests: { include: [] } })
+
+ expect(Dir.exist?(cache_dir)).to eq(false)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb
index 87ca899a87d..d7ad34255c1 100644
--- a/spec/lib/gitlab/import_export/members_mapper_spec.rb
+++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb
@@ -258,7 +258,7 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
end
before do
- group.add_users([user, user2], GroupMember::DEVELOPER)
+ group.add_members([user, user2], GroupMember::DEVELOPER)
end
it 'maps the project member' do
@@ -281,7 +281,7 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
end
before do
- group.add_users([user, user2], GroupMember::DEVELOPER)
+ group.add_members([user, user2], GroupMember::DEVELOPER)
end
it 'maps the importer' do
@@ -315,7 +315,7 @@ RSpec.describe Gitlab::ImportExport::MembersMapper do
shared_examples_for 'it fetches the access level from parent group' do
before do
- group.add_users([user], group_access_level)
+ group.add_members([user], group_access_level)
end
it "and resolves it correctly" do
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 95a995b1d5e..fac960d8df2 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -875,7 +875,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
context 'with group visibility' do
before do
group = create(:group, visibility_level: group_visibility)
- group.add_users([user], GroupMember::MAINTAINER)
+ group.add_members([user], GroupMember::MAINTAINER)
project.update!(group: group)
end
diff --git a/spec/lib/gitlab/quick_actions/users_extractor_spec.rb b/spec/lib/gitlab/quick_actions/users_extractor_spec.rb
new file mode 100644
index 00000000000..d00f52bb056
--- /dev/null
+++ b/spec/lib/gitlab/quick_actions/users_extractor_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::QuickActions::UsersExtractor do
+ subject(:extractor) { described_class.new(current_user, project: project, group: group, target: target, text: text) }
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:target) { create(:issue, project: project) }
+
+ let_it_be(:pancakes) { create(:user, username: 'pancakes') }
+ let_it_be(:waffles) { create(:user, username: 'waffles') }
+ let_it_be(:syrup) { create(:user, username: 'syrup') }
+
+ before do
+ allow(target).to receive(:allows_multiple_assignees?).and_return(false)
+ end
+
+ context 'when the text is nil' do
+ let(:text) { nil }
+
+ it 'returns an empty array' do
+ expect(extractor.execute).to be_empty
+ end
+ end
+
+ context 'when the text is blank' do
+ let(:text) { ' ' }
+
+ it 'returns an empty array' do
+ expect(extractor.execute).to be_empty
+ end
+ end
+
+ context 'when there are users to be found' do
+ context 'when using usernames' do
+ let(:text) { 'me, pancakes waffles and syrup' }
+
+ it 'finds the users' do
+ expect(extractor.execute).to contain_exactly(current_user, pancakes, waffles, syrup)
+ end
+ end
+
+ context 'when there are too many users' do
+ let(:text) { 'me, pancakes waffles and syrup' }
+
+ before do
+ stub_const("#{described_class}::MAX_QUICK_ACTION_USERS", 2)
+ end
+
+ it 'complains' do
+ expect { extractor.execute }.to raise_error(described_class::TooManyError)
+ end
+ end
+
+ context 'when using references' do
+ let(:text) { 'me, @pancakes @waffles and @syrup' }
+
+ it 'finds the users' do
+ expect(extractor.execute).to contain_exactly(current_user, pancakes, waffles, syrup)
+ end
+ end
+
+ context 'when using a mixture of usernames and references' do
+ let(:text) { 'me, @pancakes waffles and @syrup' }
+
+ it 'finds the users' do
+ expect(extractor.execute).to contain_exactly(current_user, pancakes, waffles, syrup)
+ end
+ end
+
+ context 'when one or more users cannot be found' do
+ let(:text) { 'me, @bacon @pancakes, chicken waffles and @syrup' }
+
+ it 'reports an error' do
+ expect { extractor.execute }.to raise_error(described_class::MissingError, include('bacon', 'chicken'))
+ end
+ end
+
+ context 'when trying to find group members' do
+ let(:group) { create(:group, path: 'breakfast-foods') }
+ let(:text) { group.to_reference }
+
+ it 'reports an error' do
+ [pancakes, waffles].each { group.add_developer(_1) }
+
+ expect { extractor.execute }.to raise_error(described_class::MissingError, include('breakfast-foods'))
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb
index b1de3e21b77..1ae45d41f2d 100644
--- a/spec/lib/gitlab/user_access_spec.rb
+++ b/spec/lib/gitlab/user_access_spec.rb
@@ -219,19 +219,19 @@ RSpec.describe Gitlab::UserAccess do
describe '#can_create_tag?' do
describe 'push to none protected tag' do
it 'returns true if user is a maintainer' do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
expect(access.can_create_tag?('random_tag')).to be_truthy
end
it 'returns true if user is a developer' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_create_tag?('random_tag')).to be_truthy
end
it 'returns false if user is a reporter' do
- project.add_user(user, :reporter)
+ project.add_member(user, :reporter)
expect(access.can_create_tag?('random_tag')).to be_falsey
end
@@ -242,19 +242,19 @@ RSpec.describe Gitlab::UserAccess do
let(:not_existing_tag) { create :protected_tag, project: project }
it 'returns true if user is a maintainer' do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
expect(access.can_create_tag?(tag.name)).to be_truthy
end
it 'returns false if user is a developer' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_create_tag?(tag.name)).to be_falsey
end
it 'returns false if user is a reporter' do
- project.add_user(user, :reporter)
+ project.add_member(user, :reporter)
expect(access.can_create_tag?(tag.name)).to be_falsey
end
@@ -266,19 +266,19 @@ RSpec.describe Gitlab::UserAccess do
end
it 'returns true if user is a maintainer' do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
expect(access.can_create_tag?(@tag.name)).to be_truthy
end
it 'returns true if user is a developer' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_create_tag?(@tag.name)).to be_truthy
end
it 'returns false if user is a reporter' do
- project.add_user(user, :reporter)
+ project.add_member(user, :reporter)
expect(access.can_create_tag?(@tag.name)).to be_falsey
end
@@ -288,19 +288,19 @@ RSpec.describe Gitlab::UserAccess do
describe '#can_delete_branch?' do
describe 'delete unprotected branch' do
it 'returns true if user is a maintainer' do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
expect(access.can_delete_branch?('random_branch')).to be_truthy
end
it 'returns true if user is a developer' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_delete_branch?('random_branch')).to be_truthy
end
it 'returns false if user is a reporter' do
- project.add_user(user, :reporter)
+ project.add_member(user, :reporter)
expect(access.can_delete_branch?('random_branch')).to be_falsey
end
@@ -310,19 +310,19 @@ RSpec.describe Gitlab::UserAccess do
let(:branch) { create(:protected_branch, project: project, name: "test") }
it 'returns true if user is a maintainer' do
- project.add_user(user, :maintainer)
+ project.add_member(user, :maintainer)
expect(access.can_delete_branch?(branch.name)).to be_truthy
end
it 'returns false if user is a developer' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_delete_branch?(branch.name)).to be_falsey
end
it 'returns false if user is a reporter' do
- project.add_user(user, :reporter)
+ project.add_member(user, :reporter)
expect(access.can_delete_branch?(branch.name)).to be_falsey
end
@@ -334,7 +334,7 @@ RSpec.describe Gitlab::UserAccess do
context 'when user cannot push_code to a project repository (eg. as a guest)' do
it 'is false' do
- project.add_user(user, :guest)
+ project.add_member(user, :guest)
expect(access.can_push_for_ref?(ref)).to be_falsey
end
@@ -342,7 +342,7 @@ RSpec.describe Gitlab::UserAccess do
context 'when user can push_code to a project repository (eg. as a developer)' do
it 'is true' do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
expect(access.can_push_for_ref?(ref)).to be_truthy
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index a9796c28870..f501488bb8c 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -1550,7 +1550,7 @@ RSpec.describe Notify do
end
describe 'invitations' do
- let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
+ let(:owner) { create(:user).tap { |u| group.add_member(u, Gitlab::Access::OWNER) } }
let(:group_member) { invite_to_group(group, inviter: inviter) }
let(:inviter) { owner }
@@ -1605,7 +1605,7 @@ RSpec.describe Notify do
end
describe 'group invitation reminders' do
- let_it_be(:inviter) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
+ let_it_be(:inviter) { create(:user).tap { |u| group.add_member(u, Gitlab::Access::OWNER) } }
let(:group_member) { invite_to_group(group, inviter: inviter) }
@@ -1688,7 +1688,7 @@ RSpec.describe Notify do
describe 'group invitation accepted' do
let(:invited_user) { create(:user, name: 'invited user') }
- let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
+ let(:owner) { create(:user).tap { |u| group.add_member(u, Gitlab::Access::OWNER) } }
let(:group_member) do
invitee = invite_to_group(group, inviter: owner)
invitee.accept_invite!(invited_user)
@@ -1714,7 +1714,7 @@ RSpec.describe Notify do
end
describe 'group invitation declined' do
- let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
+ let(:owner) { create(:user).tap { |u| group.add_member(u, Gitlab::Access::OWNER) } }
let(:group_member) do
invitee = invite_to_group(group, inviter: owner)
invitee.decline_invite!
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index d3501d9bb1b..fef28e7c550 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -3251,10 +3251,6 @@ RSpec.describe Ci::Build do
let(:trigger) { create(:ci_trigger, project: project) }
let(:trigger_request) { create(:ci_trigger_request, pipeline: pipeline, trigger: trigger) }
- let(:user_trigger_variable) do
- { key: 'TRIGGER_KEY_1', value: 'TRIGGER_VALUE_1', public: false, masked: false }
- end
-
let(:predefined_trigger_variable) do
{ key: 'CI_PIPELINE_TRIGGERED', value: 'true', public: true, masked: false }
end
@@ -3263,26 +3259,7 @@ RSpec.describe Ci::Build do
build.trigger_request = trigger_request
end
- shared_examples 'returns variables for triggers' do
- it { is_expected.to include(user_trigger_variable) }
- it { is_expected.to include(predefined_trigger_variable) }
- end
-
- context 'when variables are stored in trigger_request' do
- before do
- trigger_request.update_attribute(:variables, { 'TRIGGER_KEY_1' => 'TRIGGER_VALUE_1' } )
- end
-
- it_behaves_like 'returns variables for triggers'
- end
-
- context 'when variables are stored in pipeline_variables' do
- before do
- create(:ci_pipeline_variable, pipeline: pipeline, key: 'TRIGGER_KEY_1', value: 'TRIGGER_VALUE_1')
- end
-
- it_behaves_like 'returns variables for triggers'
- end
+ it { is_expected.to include(predefined_trigger_variable) }
end
context 'when pipeline has a variable' do
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index d47f43a630d..91ba12a16d5 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -726,7 +726,7 @@ RSpec.describe Group do
context 'when user is a member of private group' do
before do
- private_group.add_user(user, Gitlab::Access::DEVELOPER)
+ private_group.add_member(user, Gitlab::Access::DEVELOPER)
end
it { is_expected.to match_array([private_group, internal_group, group]) }
@@ -736,7 +736,7 @@ RSpec.describe Group do
let!(:private_subgroup) { create(:group, :private, parent: private_group) }
before do
- private_subgroup.add_user(user, Gitlab::Access::DEVELOPER)
+ private_subgroup.add_member(user, Gitlab::Access::DEVELOPER)
end
it { is_expected.to match_array([private_subgroup, internal_group, group]) }
@@ -848,7 +848,7 @@ RSpec.describe Group do
expect(member).to receive(:refresh_member_authorized_projects).with(blocking: true)
end
- group.add_user(user, GroupMember::MAINTAINER)
+ group.add_member(user, GroupMember::MAINTAINER)
expect(group.group_members.maintainers.map(&:user)).to include(user)
end
@@ -858,7 +858,7 @@ RSpec.describe Group do
expect(member).to receive(:refresh_member_authorized_projects).with(blocking: false)
end
- group.add_user(user, GroupMember::MAINTAINER, blocking_refresh: false)
+ group.add_member(user, GroupMember::MAINTAINER, blocking_refresh: false)
end
end
@@ -866,12 +866,12 @@ RSpec.describe Group do
let(:user) { create(:user) }
before do
- group.add_users([user.id], GroupMember::GUEST)
+ group.add_members([user.id], GroupMember::GUEST)
end
it "updates the group permission" do
expect(group.group_members.guests.map(&:user)).to include(user)
- group.add_users([user.id], GroupMember::DEVELOPER)
+ group.add_members([user.id], GroupMember::DEVELOPER)
expect(group.group_members.developers.map(&:user)).to include(user)
expect(group.group_members.guests.map(&:user)).not_to include(user)
end
@@ -880,7 +880,7 @@ RSpec.describe Group do
let!(:project) { create(:project, group: group) }
before do
- group.add_users([create(:user)], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
+ group.add_members([create(:user)], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
end
it 'creates a member_task with the correct attributes', :aggregate_failures do
@@ -896,7 +896,7 @@ RSpec.describe Group do
let(:user) { create(:user) }
before do
- group.add_user(user, GroupMember::MAINTAINER)
+ group.add_member(user, GroupMember::MAINTAINER)
end
it "is true if avatar is image" do
@@ -993,7 +993,7 @@ RSpec.describe Group do
context 'there is also a project_bot owner' do
before do
- group.add_user(create(:user, :project_bot), GroupMember::OWNER)
+ group.add_member(create(:user, :project_bot), GroupMember::OWNER)
end
it { expect(group.last_owner?(@members[:owner])).to be_truthy }
@@ -1024,7 +1024,7 @@ RSpec.describe Group do
let(:member) { blocked_user.group_members.last }
before do
- group.add_user(blocked_user, GroupMember::OWNER)
+ group.add_member(blocked_user, GroupMember::OWNER)
end
context 'when last_blocked_owner is set' do
@@ -1050,7 +1050,7 @@ RSpec.describe Group do
context 'with another active owner' do
before do
- group.add_user(create(:user), GroupMember::OWNER)
+ group.add_member(create(:user), GroupMember::OWNER)
end
it { expect(group.member_last_blocked_owner?(member)).to be(false) }
@@ -1058,7 +1058,7 @@ RSpec.describe Group do
context 'with 2 blocked owners' do
before do
- group.add_user(create(:user, :blocked), GroupMember::OWNER)
+ group.add_member(create(:user, :blocked), GroupMember::OWNER)
end
it { expect(group.member_last_blocked_owner?(member)).to be(false) }
@@ -1082,7 +1082,7 @@ RSpec.describe Group do
describe '#single_blocked_owner?' do
context 'when there is only one blocked owner' do
before do
- group.add_user(blocked_user, GroupMember::OWNER)
+ group.add_member(blocked_user, GroupMember::OWNER)
end
it 'returns true' do
@@ -1094,8 +1094,8 @@ RSpec.describe Group do
let_it_be(:blocked_user_2) { create(:user, :blocked) }
before do
- group.add_user(blocked_user, GroupMember::OWNER)
- group.add_user(blocked_user_2, GroupMember::OWNER)
+ group.add_member(blocked_user, GroupMember::OWNER)
+ group.add_member(blocked_user_2, GroupMember::OWNER)
end
it 'returns true' do
@@ -1114,8 +1114,8 @@ RSpec.describe Group do
let_it_be(:user) { create(:user) }
before do
- group.add_user(blocked_user, GroupMember::OWNER)
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(blocked_user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
end
it 'has only blocked owners' do
@@ -1129,7 +1129,7 @@ RSpec.describe Group do
context 'when there is only one owner' do
let!(:owner) do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
end
it 'returns the owner' do
@@ -1138,7 +1138,7 @@ RSpec.describe Group do
context 'and there is also a project_bot owner' do
before do
- group.add_user(create(:user, :project_bot), GroupMember::OWNER)
+ group.add_member(create(:user, :project_bot), GroupMember::OWNER)
end
it 'returns only the human owner' do
@@ -1151,11 +1151,11 @@ RSpec.describe Group do
let_it_be(:user_2) { create(:user) }
let!(:owner) do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
end
let!(:owner2) do
- group.add_user(user_2, GroupMember::OWNER)
+ group.add_member(user_2, GroupMember::OWNER)
end
it 'returns both owners' do
@@ -1164,7 +1164,7 @@ RSpec.describe Group do
context 'and there is also a project_bot owner' do
before do
- group.add_user(create(:user, :project_bot), GroupMember::OWNER)
+ group.add_member(create(:user, :project_bot), GroupMember::OWNER)
end
it 'returns only the human owners' do
@@ -1186,7 +1186,7 @@ RSpec.describe Group do
let(:member) { group.members.last }
before do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
end
context 'when last_owner is set' do
@@ -1284,11 +1284,11 @@ RSpec.describe Group do
requester: create(:user)
}
- group.add_user(members[:owner], GroupMember::OWNER)
- group.add_user(members[:maintainer], GroupMember::MAINTAINER)
- group.add_user(members[:developer], GroupMember::DEVELOPER)
- group.add_user(members[:reporter], GroupMember::REPORTER)
- group.add_user(members[:guest], GroupMember::GUEST)
+ group.add_member(members[:owner], GroupMember::OWNER)
+ group.add_member(members[:maintainer], GroupMember::MAINTAINER)
+ group.add_member(members[:developer], GroupMember::DEVELOPER)
+ group.add_member(members[:reporter], GroupMember::REPORTER)
+ group.add_member(members[:guest], GroupMember::GUEST)
group.request_access(members[:requester])
members
@@ -1464,8 +1464,8 @@ RSpec.describe Group do
describe '#direct_members' do
let_it_be(:group) { create(:group, :nested) }
- let_it_be(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
- let_it_be(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
+ let_it_be(:maintainer) { group.parent.add_member(create(:user), GroupMember::MAINTAINER) }
+ let_it_be(:developer) { group.add_member(create(:user), GroupMember::DEVELOPER) }
it 'does not return members of the parent' do
expect(group.direct_members).not_to include(maintainer)
@@ -1491,8 +1491,8 @@ RSpec.describe Group do
shared_examples_for 'members_with_parents' do
let!(:group) { create(:group, :nested) }
- let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
- let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
+ let!(:maintainer) { group.parent.add_member(create(:user), GroupMember::MAINTAINER) }
+ let!(:developer) { group.add_member(create(:user), GroupMember::DEVELOPER) }
let!(:pending_maintainer) { create(:group_member, :awaiting, :maintainer, group: group.parent) }
let!(:pending_developer) { create(:group_member, :awaiting, :developer, group: group) }
@@ -1603,9 +1603,9 @@ RSpec.describe Group do
context 'members-related methods' do
let!(:group) { create(:group, :nested) }
let!(:sub_group) { create(:group, parent: group) }
- let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
- let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
- let!(:other_developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
+ let!(:maintainer) { group.parent.add_member(create(:user), GroupMember::MAINTAINER) }
+ let!(:developer) { group.add_member(create(:user), GroupMember::DEVELOPER) }
+ let!(:other_developer) { group.add_member(create(:user), GroupMember::DEVELOPER) }
describe '#direct_and_indirect_members' do
it 'returns parents members' do
@@ -1619,7 +1619,7 @@ RSpec.describe Group do
end
describe '#direct_and_indirect_members_with_inactive' do
- let!(:maintainer_blocked) { group.parent.add_user(create(:user, :blocked), GroupMember::MAINTAINER) }
+ let!(:maintainer_blocked) { group.parent.add_member(create(:user, :blocked), GroupMember::MAINTAINER) }
it 'returns parents members' do
expect(group.direct_and_indirect_members_with_inactive).to include(developer)
@@ -1795,8 +1795,8 @@ RSpec.describe Group do
maintainer = create(:user)
developer = create(:user)
- group.add_user(maintainer, GroupMember::MAINTAINER)
- group.add_user(developer, GroupMember::DEVELOPER)
+ group.add_member(maintainer, GroupMember::MAINTAINER)
+ group.add_member(developer, GroupMember::DEVELOPER)
expect(group.user_ids_for_project_authorizations)
.to include(maintainer.id, developer.id)
@@ -1847,7 +1847,7 @@ RSpec.describe Group do
context 'group membership' do
before do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
end
it 'is called when require_two_factor_authentication is changed' do
@@ -1870,7 +1870,7 @@ RSpec.describe Group do
it 'calls #update_two_factor_requirement on each group member' do
other_user = create(:user)
- group.add_user(other_user, GroupMember::OWNER)
+ group.add_member(other_user, GroupMember::OWNER)
calls = 0
allow_any_instance_of(User).to receive(:update_two_factor_requirement) do
@@ -1885,7 +1885,7 @@ RSpec.describe Group do
context 'sub groups and projects' do
it 'enables two_factor_requirement for group member' do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: true)
@@ -1899,7 +1899,7 @@ RSpec.describe Group do
context 'two_factor_requirement is also enabled for ancestor group' do
it 'enables two_factor_requirement for subgroup member' do
subgroup = create(:group, :nested, parent: group)
- subgroup.add_user(indirect_user, GroupMember::OWNER)
+ subgroup.add_member(indirect_user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: true)
@@ -1910,7 +1910,7 @@ RSpec.describe Group do
context 'two_factor_requirement is disabled for ancestor group' do
it 'enables two_factor_requirement for subgroup member' do
subgroup = create(:group, :nested, parent: group, require_two_factor_authentication: true)
- subgroup.add_user(indirect_user, GroupMember::OWNER)
+ subgroup.add_member(indirect_user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: false)
@@ -1919,7 +1919,7 @@ RSpec.describe Group do
it 'enable two_factor_requirement for ancestor group member' do
ancestor_group = create(:group)
- ancestor_group.add_user(indirect_user, GroupMember::OWNER)
+ ancestor_group.add_member(indirect_user, GroupMember::OWNER)
group.update!(parent: ancestor_group)
group.update!(require_two_factor_authentication: true)
@@ -1933,7 +1933,7 @@ RSpec.describe Group do
context 'two_factor_requirement is enabled for ancestor group' do
it 'enables two_factor_requirement for subgroup member' do
subgroup = create(:group, :nested, parent: group)
- subgroup.add_user(indirect_user, GroupMember::OWNER)
+ subgroup.add_member(indirect_user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: true)
@@ -1944,7 +1944,7 @@ RSpec.describe Group do
context 'two_factor_requirement is also disabled for ancestor group' do
it 'disables two_factor_requirement for subgroup member' do
subgroup = create(:group, :nested, parent: group)
- subgroup.add_user(indirect_user, GroupMember::OWNER)
+ subgroup.add_member(indirect_user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: false)
@@ -1954,7 +1954,7 @@ RSpec.describe Group do
it 'disables two_factor_requirement for ancestor group member' do
ancestor_group = create(:group, require_two_factor_authentication: false)
indirect_user.update!(require_two_factor_authentication_from_group: true)
- ancestor_group.add_user(indirect_user, GroupMember::OWNER)
+ ancestor_group.add_member(indirect_user, GroupMember::OWNER)
group.update!(require_two_factor_authentication: false)
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index f93c2d36966..94032146f51 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -219,7 +219,7 @@ RSpec.describe GroupMember do
end
context 'on create' do
- let(:action) { group.add_user(user, Gitlab::Access::GUEST) }
+ let(:action) { group.add_member(user, Gitlab::Access::GUEST) }
let(:blocking) { true }
it 'changes access level', :sidekiq_inline do
@@ -241,7 +241,7 @@ RSpec.describe GroupMember do
context 'on update' do
before do
- group.add_user(user, Gitlab::Access::GUEST)
+ group.add_member(user, Gitlab::Access::GUEST)
end
let(:action) { group.members.find_by(user: user).update!(access_level: Gitlab::Access::DEVELOPER) }
@@ -266,7 +266,7 @@ RSpec.describe GroupMember do
context 'on destroy' do
before do
- group.add_user(user, Gitlab::Access::GUEST)
+ group.add_member(user, Gitlab::Access::GUEST)
end
let(:action) { group.members.find_by(user: user).destroy! }
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 8c989f5aaca..48798d419e8 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -111,12 +111,12 @@ RSpec.describe ProjectMember do
end
end
- describe '.add_users_to_projects' do
+ describe '.add_members_to_projects' do
it 'adds the given users to the given projects' do
projects = create_list(:project, 2)
users = create_list(:user, 2)
- described_class.add_users_to_projects(
+ described_class.add_members_to_projects(
[projects.first.id, projects.second.id],
[users.first.id, users.second],
described_class::MAINTAINER)
@@ -236,7 +236,7 @@ RSpec.describe ProjectMember do
end
context 'on create' do
- let(:action) { project.add_user(user, Gitlab::Access::GUEST) }
+ let(:action) { project.add_member(user, Gitlab::Access::GUEST) }
it 'changes access level' do
expect { action }.to change { user.can?(:guest_access, project) }.from(false).to(true)
@@ -250,7 +250,7 @@ RSpec.describe ProjectMember do
let(:action) { project.members.find_by(user: user).update!(access_level: Gitlab::Access::DEVELOPER) }
before do
- project.add_user(user, Gitlab::Access::GUEST)
+ project.add_member(user, Gitlab::Access::GUEST)
end
it 'changes access level' do
@@ -265,7 +265,7 @@ RSpec.describe ProjectMember do
let(:action) { project.members.find_by(user: user).destroy! }
before do
- project.add_user(user, Gitlab::Access::GUEST)
+ project.add_member(user, Gitlab::Access::GUEST)
end
it 'changes access level', :sidekiq_inline do
diff --git a/spec/models/merge_request_diff_file_spec.rb b/spec/models/merge_request_diff_file_spec.rb
index c9bcb900eca..64203c50759 100644
--- a/spec/models/merge_request_diff_file_spec.rb
+++ b/spec/models/merge_request_diff_file_spec.rb
@@ -13,50 +13,53 @@ RSpec.describe MergeRequestDiffFile do
let(:invalid_items_for_bulk_insertion) { [] } # class does not have any validations defined
end
+ let(:unpacked) { 'unpacked' }
+ let(:packed) { [unpacked].pack('m0') }
+ let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
+
describe '#diff' do
+ let(:file) { build(:merge_request_diff_file) }
+
context 'when diff is not stored' do
let(:unpacked) { 'unpacked' }
let(:packed) { [unpacked].pack('m0') }
before do
- subject.diff = packed
+ file.diff = packed
end
context 'when the diff is marked as binary' do
before do
- subject.binary = true
+ file.binary = true
end
it 'unpacks from base 64' do
- expect(subject.diff).to eq(unpacked)
+ expect(file.diff).to eq(unpacked)
end
context 'invalid base64' do
let(:packed) { '---/dev/null' }
it 'returns the raw diff' do
- expect(subject.diff).to eq(packed)
+ expect(file.diff).to eq(packed)
end
end
end
context 'when the diff is not marked as binary' do
it 'returns the raw diff' do
- expect(subject.diff).to eq(packed)
+ expect(file.diff).to eq(packed)
end
end
end
context 'when diff is stored in DB' do
- let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
-
it 'returns UTF-8 string' do
expect(file.diff.encoding).to eq Encoding::UTF_8
end
end
context 'when diff is stored in external storage' do
- let(:file) { create(:merge_request).merge_request_diff.merge_request_diff_files.first }
let(:test_dir) { 'tmp/tests/external-diffs' }
around do |example|
@@ -81,17 +84,132 @@ RSpec.describe MergeRequestDiffFile do
describe '#utf8_diff' do
it 'does not raise error when the diff is binary' do
- subject.diff = "\x05\x00\x68\x65\x6c\x6c\x6f"
+ file = build(:merge_request_diff_file)
+ file.diff = "\x05\x00\x68\x65\x6c\x6c\x6f"
- expect { subject.utf8_diff }.not_to raise_error
+ expect { file.utf8_diff }.not_to raise_error
end
it 'calls #diff once' do
- allow(subject).to receive(:diff).and_return('test')
+ allow(file).to receive(:diff).and_return('test')
+
+ expect(file).to receive(:diff).once
+
+ file.utf8_diff
+ end
+ end
+
+ describe '#diff_export' do
+ context 'when diff is externally stored' do
+ let(:test_dir) { 'tmp/tests/external-diffs' }
+
+ around do |example|
+ FileUtils.mkdir_p(test_dir)
+
+ begin
+ example.run
+ ensure
+ FileUtils.rm_rf(test_dir)
+ end
+ end
+
+ before do
+ stub_external_diffs_setting(enabled: true, storage_path: test_dir)
+ end
+
+ context 'when external diff is not cached' do
+ it 'caches external diffs' do
+ expect(file.merge_request_diff).to receive(:cache_external_diff).and_call_original
+
+ expect(file.diff_export).to eq(file.utf8_diff)
+ end
+ end
+
+ context 'when external diff is already cached' do
+ it 'reads diff from cached external diff' do
+ file_stub = double
+
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_yield(file_stub)
+ expect(file_stub).to receive(:seek).with(file.external_diff_offset)
+ expect(file_stub).to receive(:read).with(file.external_diff_size)
+
+ file.diff_export
+ end
+ end
+
+ context 'when the diff is marked as binary' do
+ let(:file) { build(:merge_request_diff_file) }
- expect(subject).to receive(:diff).once
+ before do
+ allow(file.merge_request_diff).to receive(:stored_externally?).and_return(true)
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_return(packed)
+ end
+
+ context 'when the diff is marked as binary' do
+ before do
+ file.binary = true
+ end
+
+ it 'unpacks from base 64' do
+ expect(file.diff_export).to eq(unpacked)
+ end
+
+ context 'invalid base64' do
+ let(:packed) { '---/dev/null' }
+
+ it 'returns the raw diff' do
+ expect(file.diff_export).to eq(packed)
+ end
+ end
+ end
+
+ context 'when the diff is not marked as binary' do
+ it 'returns the raw diff' do
+ expect(file.diff_export).to eq(packed)
+ end
+ end
+ end
+
+ context 'when content responds to #encoding' do
+ it 'encodes content to utf8 encoding' do
+ expect(file.diff_export.encoding).to eq(Encoding::UTF_8)
+ end
+ end
+
+ context 'when content is blank' do
+ it 'returns an empty string' do
+ allow(file.merge_request_diff).to receive(:cached_external_diff).and_return(nil)
+
+ expect(file.diff_export).to eq('')
+ end
+ end
- subject.utf8_diff
+ context 'when exception is raised' do
+ it 'falls back to #utf8_diff' do
+ allow(file).to receive(:binary?).and_raise(StandardError)
+ expect(file).to receive(:utf8_diff)
+
+ file.diff_export
+ end
+ end
+ end
+
+ context 'when externally_stored_diffs_caching_export feature flag is disabled' do
+ it 'calls #utf8_diff' do
+ stub_feature_flags(externally_stored_diffs_caching_export: false)
+
+ expect(file).to receive(:utf8_diff)
+
+ file.diff_export
+ end
+ end
+
+ context 'when diff is not stored externally' do
+ it 'calls #utf8_diff' do
+ expect(file).to receive(:utf8_diff)
+
+ file.diff_export
+ end
end
end
end
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index afe7251f59a..007e84164a8 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -1120,4 +1120,101 @@ RSpec.describe MergeRequestDiff do
expect(described_class.latest_diff_for_merge_requests(nil)).to be_empty
end
end
+
+ context 'external diff caching' do
+ let(:test_dir) { 'tmp/tests/external-diffs' }
+ let(:cache_dir) { File.join(Dir.tmpdir, "project-#{diff.project.id}-external-mr-#{diff.merge_request_id}-diff-#{diff.id}-cache") }
+ let(:cache_filepath) { File.join(cache_dir, "diff-#{diff.id}") }
+ let(:external_diff_content) { diff.opening_external_diff { |diff| diff.read } }
+
+ around do |example|
+ FileUtils.mkdir_p(test_dir)
+
+ begin
+ example.run
+ ensure
+ FileUtils.rm_rf(test_dir)
+ end
+ end
+
+ before do
+ stub_external_diffs_setting(enabled: true, storage_path: test_dir)
+ end
+
+ subject(:diff) { diff_with_commits }
+
+ describe '#cached_external_diff' do
+ context 'when diff is externally stored' do
+ context 'when diff is already cached' do
+ it 'yields cached file' do
+ Dir.mkdir(cache_dir)
+ File.open(cache_filepath, 'wb') { |f| f.write(external_diff_content) }
+
+ expect(diff).not_to receive(:cache_external_diff)
+
+ expect { |b| diff.cached_external_diff(&b) }.to yield_with_args(File)
+ end
+ end
+
+ context 'when diff is not cached' do
+ it 'caches external diff in tmp storage' do
+ expect(diff).to receive(:cache_external_diff).and_call_original
+ expect(File.exist?(cache_filepath)).to eq(false)
+ expect { |b| diff.cached_external_diff(&b) }.to yield_with_args(File)
+ expect(File.exist?(cache_filepath)).to eq(true)
+ expect(File.read(cache_filepath)).to eq(external_diff_content)
+ end
+ end
+ end
+
+ context 'when diff is not externally stored' do
+ it 'yields nil' do
+ stub_external_diffs_setting(enabled: false)
+
+ expect { |b| diff.cached_external_diff(&b) }.to yield_with_args(nil)
+ end
+ end
+ end
+
+ describe '#remove_cached_external_diff' do
+ before do
+ diff.cached_external_diff { |diff| diff }
+ end
+
+ it 'removes external diff cache diff' do
+ expect(Dir.exist?(cache_dir)).to eq(true)
+
+ diff.remove_cached_external_diff
+
+ expect(Dir.exist?(cache_dir)).to eq(false)
+ end
+
+ context 'when path is traversed' do
+ it 'raises' do
+ allow(diff).to receive(:external_diff_cache_dir).and_return(File.join(cache_dir, '..'))
+
+ expect { diff.remove_cached_external_diff }.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path')
+ end
+ end
+
+ context 'when path is not allowed' do
+ it 'raises' do
+ allow(diff).to receive(:external_diff_cache_dir).and_return('/')
+
+ expect { diff.remove_cached_external_diff }.to raise_error(StandardError, 'path / is not allowed')
+ end
+ end
+
+ context 'when dir does not exist' do
+ it 'returns' do
+ FileUtils.rm_rf(cache_dir)
+
+ expect(Dir.exist?(cache_dir)).to eq(false)
+ expect(FileUtils).not_to receive(:rm_rf).with(cache_dir)
+
+ diff.remove_cached_external_diff
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 77b81b2c310..c2f3deb6c06 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -658,7 +658,7 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
before do
- project.add_user(user, :developer)
+ project.add_member(user, :developer)
end
describe '.total_time_to_merge' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index b7ed7b20833..74a4a023a20 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -821,7 +821,7 @@ RSpec.describe Project, factory_default: :keep do
end
describe 'delegation' do
- [:add_guest, :add_reporter, :add_developer, :add_maintainer, :add_user, :add_users].each do |method|
+ [:add_guest, :add_reporter, :add_developer, :add_maintainer, :add_member, :add_members].each do |method|
it { is_expected.to delegate_method(method).to(:team) }
end
@@ -1862,7 +1862,7 @@ RSpec.describe Project, factory_default: :keep do
describe 'when a user has access to a project' do
before do
- project.add_user(user, Gitlab::Access::MAINTAINER)
+ project.add_member(user, Gitlab::Access::MAINTAINER)
end
it { is_expected.to eq([project]) }
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 2ddbab7779e..1fab07c1452 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -251,13 +251,13 @@ RSpec.describe ProjectTeam do
end
end
- describe '#add_users' do
+ describe '#add_members' do
let(:user1) { create(:user) }
let(:user2) { create(:user) }
let(:project) { create(:project) }
it 'add the given users to the team' do
- project.team.add_users([user1, user2], :reporter)
+ project.team.add_members([user1, user2], :reporter)
expect(project.team.reporter?(user1)).to be(true)
expect(project.team.reporter?(user2)).to be(true)
@@ -265,7 +265,7 @@ RSpec.describe ProjectTeam do
context 'when `tasks_to_be_done` and `tasks_project_id` are passed' do
before do
- project.team.add_users([user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
+ project.team.add_members([user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
end
it 'creates a member_task with the correct attributes', :aggregate_failures do
@@ -277,12 +277,12 @@ RSpec.describe ProjectTeam do
end
end
- describe '#add_user' do
+ describe '#add_member' do
let(:user) { create(:user) }
let(:project) { create(:project) }
it 'add the given user to the team' do
- project.team.add_user(user, :reporter)
+ project.team.add_member(user, :reporter)
expect(project.team.reporter?(user)).to be(true)
end
diff --git a/spec/models/ssh_host_key_spec.rb b/spec/models/ssh_host_key_spec.rb
index 4b756846598..0348aab9f97 100644
--- a/spec/models/ssh_host_key_spec.rb
+++ b/spec/models/ssh_host_key_spec.rb
@@ -26,6 +26,9 @@ RSpec.describe SshHostKey do
'Ebi86VjJRi2sOuYoXQU1'
end
+ let(:ssh_key1) { Gitlab::SSHPublicKey.new(key1) }
+ let(:ssh_key2) { Gitlab::SSHPublicKey.new(key2) }
+
# Purposefully ordered so that `sort` will make changes
let(:known_hosts) do
<<~EOF
@@ -88,10 +91,17 @@ RSpec.describe SshHostKey do
it 'returns an array of indexed fingerprints when the cache is filled' do
stub_reactive_cache(ssh_host_key, known_hosts: known_hosts)
- expected = [key1, key2]
- .map { |data| Gitlab::SSHPublicKey.new(data) }
+ expected = [ssh_key1, ssh_key2]
.each_with_index
- .map { |key, i| { bits: key.bits, fingerprint: key.fingerprint, type: key.type, index: i } }
+ .map do |key, i|
+ {
+ bits: key.bits,
+ fingerprint: key.fingerprint,
+ fingerprint_sha256: key.fingerprint_sha256,
+ type: key.type,
+ index: i
+ }
+ end
expect(ssh_host_key.fingerprints.as_json).to eq(expected)
end
@@ -107,8 +117,16 @@ RSpec.describe SshHostKey do
expect(ssh_host_key.fingerprints.as_json).to eq(
[
- { bits: 2048, fingerprint: Gitlab::SSHPublicKey.new(key1).fingerprint, type: :rsa, index: 0 },
- { bits: 2048, fingerprint: Gitlab::SSHPublicKey.new(key2).fingerprint, type: :rsa, index: 1 }
+ { bits: 2048,
+ fingerprint: ssh_key1.fingerprint,
+ fingerprint_sha256: ssh_key1.fingerprint_sha256,
+ type: :rsa,
+ index: 0 },
+ { bits: 2048,
+ fingerprint: ssh_key2.fingerprint,
+ fingerprint_sha256: ssh_key2.fingerprint_sha256,
+ type: :rsa,
+ index: 1 }
]
)
end
@@ -116,6 +134,19 @@ RSpec.describe SshHostKey do
it 'returns an empty array when the cache is empty' do
expect(ssh_host_key.fingerprints).to eq([])
end
+
+ context 'when FIPS is enabled', :fips_mode do
+ it 'only includes SHA256 fingerprint' do
+ stub_reactive_cache(ssh_host_key, known_hosts: known_hosts)
+
+ expect(ssh_host_key.fingerprints.as_json).to eq(
+ [
+ { bits: 2048, fingerprint_sha256: ssh_key1.fingerprint_sha256, type: :rsa, index: 0 },
+ { bits: 2048, fingerprint_sha256: ssh_key2.fingerprint_sha256, type: :rsa, index: 1 }
+ ]
+ )
+ end
+ end
end
describe '#host_keys_changed?' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 7a5908fb586..626d8c8d337 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2292,7 +2292,7 @@ RSpec.describe User do
@group = create :group
@group.add_owner(@user)
- @group.add_user(@user2, GroupMember::OWNER)
+ @group.add_member(@user2, GroupMember::OWNER)
end
it { expect(@user2.several_namespaces?).to be_truthy }
@@ -3834,7 +3834,7 @@ RSpec.describe User do
let!(:project) { create(:project, group: project_group) }
before do
- private_group.add_user(user, Gitlab::Access::MAINTAINER)
+ private_group.add_member(user, Gitlab::Access::MAINTAINER)
project.add_maintainer(user)
end
@@ -3861,7 +3861,7 @@ RSpec.describe User do
let_it_be(:parent_group) do
create(:group).tap do |g|
- g.add_user(user, Gitlab::Access::MAINTAINER)
+ g.add_member(user, Gitlab::Access::MAINTAINER)
end
end
@@ -4289,7 +4289,7 @@ RSpec.describe User do
let!(:runner) { create(:ci_runner, :group, groups: [group]) }
def add_user(access)
- group.add_user(user, access)
+ group.add_member(user, access)
end
it_behaves_like :group_member
@@ -4379,7 +4379,7 @@ RSpec.describe User do
let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
def add_user(access)
- project.add_user(user, access)
+ project.add_member(user, access)
end
it_behaves_like :project_member
@@ -4401,8 +4401,8 @@ RSpec.describe User do
let!(:another_user) { create(:user) }
def add_user(access)
- subgroup.add_user(user, access)
- group.add_user(another_user, :owner)
+ subgroup.add_member(user, access)
+ group.add_member(another_user, :owner)
end
it_behaves_like :group_member
@@ -4759,8 +4759,8 @@ RSpec.describe User do
let(:group2) { create :group, require_two_factor_authentication: true, two_factor_grace_period: 32 }
before do
- group1.add_user(user, GroupMember::OWNER)
- group2.add_user(user, GroupMember::OWNER)
+ group1.add_member(user, GroupMember::OWNER)
+ group2.add_member(user, GroupMember::OWNER)
user.update_two_factor_requirement
end
@@ -4779,7 +4779,7 @@ RSpec.describe User do
let!(:group1a) { create :group, parent: group1 }
before do
- group1a.add_user(user, GroupMember::OWNER)
+ group1a.add_member(user, GroupMember::OWNER)
user.update_two_factor_requirement
end
@@ -4794,7 +4794,7 @@ RSpec.describe User do
let!(:group1a) { create :group, require_two_factor_authentication: true, parent: group1 }
before do
- group1.add_user(user, GroupMember::OWNER)
+ group1.add_member(user, GroupMember::OWNER)
user.update_two_factor_requirement
end
@@ -4815,7 +4815,7 @@ RSpec.describe User do
group_access: ProjectGroupLink.default_access
)
- group2.add_user(user, GroupMember::OWNER)
+ group2.add_member(user, GroupMember::OWNER)
end
it 'does not require 2FA' do
@@ -4829,7 +4829,7 @@ RSpec.describe User do
let(:group) { create :group }
before do
- group.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
user.update_two_factor_requirement
end
@@ -4858,8 +4858,8 @@ RSpec.describe User do
let(:user) { create :user }
before do
- group.add_user(user, GroupMember::OWNER)
- group_not_requiring_2FA.add_user(user, GroupMember::OWNER)
+ group.add_member(user, GroupMember::OWNER)
+ group_not_requiring_2FA.add_member(user, GroupMember::OWNER)
end
context 'when user is direct member of group requiring 2FA' do
diff --git a/spec/policies/environment_policy_spec.rb b/spec/policies/environment_policy_spec.rb
index 649b1a770c0..701fc7ac9ae 100644
--- a/spec/policies/environment_policy_spec.rb
+++ b/spec/policies/environment_policy_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe EnvironmentPolicy do
with_them do
before do
- project.add_user(user, access_level) unless access_level.nil?
+ project.add_member(user, access_level) unless access_level.nil?
end
it { expect(policy.allowed?(:stop_environment)).to be allowed? }
@@ -49,7 +49,7 @@ RSpec.describe EnvironmentPolicy do
context 'with protected branch' do
with_them do
before do
- project.add_user(user, access_level) unless access_level.nil?
+ project.add_member(user, access_level) unless access_level.nil?
create(:protected_branch, :no_one_can_push,
name: 'master', project: project)
end
@@ -86,7 +86,7 @@ RSpec.describe EnvironmentPolicy do
with_them do
before do
- project.add_user(user, access_level) unless access_level.nil?
+ project.add_member(user, access_level) unless access_level.nil?
end
it { expect(policy.allowed?(:stop_environment)).to be allowed? }
@@ -120,7 +120,7 @@ RSpec.describe EnvironmentPolicy do
with_them do
before do
- project.add_user(user, access_level) unless access_level.nil?
+ project.add_member(user, access_level) unless access_level.nil?
end
it { expect(policy).to be_disallowed :destroy_environment }
diff --git a/spec/policies/namespace/root_storage_statistics_policy_spec.rb b/spec/policies/namespace/root_storage_statistics_policy_spec.rb
index e6b58bca4a8..89875f83c9b 100644
--- a/spec/policies/namespace/root_storage_statistics_policy_spec.rb
+++ b/spec/policies/namespace/root_storage_statistics_policy_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe Namespace::RootStorageStatisticsPolicy do
with_them do
before do
- group.add_user(user, user_type) unless user_type == :non_member
+ group.add_member(user, user_type) unless user_type == :non_member
end
it { is_expected.to eq(outcome) }
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 5884dc3f23f..de36b755e88 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1736,7 +1736,7 @@ RSpec.describe ProjectPolicy do
%w(guest reporter developer maintainer).each do |role|
context role do
before do
- project.add_user(current_user, role.to_sym)
+ project.add_member(current_user, role.to_sym)
end
if role == 'guest'
@@ -1770,7 +1770,7 @@ RSpec.describe ProjectPolicy do
%w(guest reporter developer maintainer).each do |role|
context role do
before do
- project.add_user(current_user, role.to_sym)
+ project.add_member(current_user, role.to_sym)
end
it { is_expected.to be_allowed(:read_ci_cd_analytics) }
@@ -1800,7 +1800,7 @@ RSpec.describe ProjectPolicy do
%w(guest reporter developer maintainer).each do |role|
context role do
before do
- project.add_user(current_user, role.to_sym)
+ project.add_member(current_user, role.to_sym)
end
if role == 'guest'
diff --git a/spec/policies/project_statistics_policy_spec.rb b/spec/policies/project_statistics_policy_spec.rb
index 74630dc38ad..56e6161a264 100644
--- a/spec/policies/project_statistics_policy_spec.rb
+++ b/spec/policies/project_statistics_policy_spec.rb
@@ -72,7 +72,7 @@ RSpec.describe ProjectStatisticsPolicy do
before do
unless [:unauthenticated, :non_member].include?(user_type)
- project.add_user(external, user_type)
+ project.add_member(external, user_type)
end
end
diff --git a/spec/requests/api/ci/runner/jobs_request_post_spec.rb b/spec/requests/api/ci/runner/jobs_request_post_spec.rb
index 3f3a61949d4..746be1ccc44 100644
--- a/spec/requests/api/ci/runner/jobs_request_post_spec.rb
+++ b/spec/requests/api/ci/runner/jobs_request_post_spec.rb
@@ -675,14 +675,6 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
end
end
- context 'when variables are stored in trigger_request' do
- before do
- trigger_request.update_attribute(:variables, { TRIGGER_KEY_1: 'TRIGGER_VALUE_1' } )
- end
-
- it_behaves_like 'expected variables behavior'
- end
-
context 'when variables are stored in pipeline_variables' do
before do
create(:ci_pipeline_variable, pipeline: pipeline, key: :TRIGGER_KEY_1, value: 'TRIGGER_VALUE_1')
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index 110d6e2f99e..d6c3999f22f 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -173,7 +173,7 @@ RSpec.describe API::Events do
let(:second_note) { create(:note_on_issue, project: create(:project)) }
before do
- second_note.project.add_user(user, :developer)
+ second_note.project.add_member(user, :developer)
[second_note].each do |note|
EventCreateService.new.leave_note(note, user)
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index 446d1fb1bdb..e17a83d8e47 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -424,7 +424,7 @@ RSpec.describe 'Query.runner(id)' do
let(:user) { create(:user) }
before do
- group.add_user(user, Gitlab::Access::OWNER)
+ group.add_member(user, Gitlab::Access::OWNER)
end
it_behaves_like 'retrieval with no admin url' do
diff --git a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
index 847fa72522e..14c55e61a65 100644
--- a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
+++ b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe 'container repository details' do
with_them do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility.to_s.upcase, false))
- project.add_user(user, role) unless role == :anonymous
+ project.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/group/container_repositories_spec.rb b/spec/requests/api/graphql/group/container_repositories_spec.rb
index be0b866af4a..8ec321c8d7c 100644
--- a/spec/requests/api/graphql/group/container_repositories_spec.rb
+++ b/spec/requests/api/graphql/group/container_repositories_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe 'getting container repositories in a group' do
group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
- group.add_user(user, role) unless role == :anonymous
+ group.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
index cdb21512894..daa1483e956 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
@@ -75,7 +75,7 @@ RSpec.describe 'getting dependency proxy blobs in a group' do
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
- group.add_user(user, role) unless role == :anonymous
+ group.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
index d21c3046c1a..cc706c3051f 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe 'getting dependency proxy settings for a group' do
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
- group.add_user(user, role) unless role == :anonymous
+ group.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
index 40f4b082072..3b2b04b1322 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
@@ -60,7 +60,7 @@ RSpec.describe 'getting dependency proxy image ttl policy for a group' do
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
- group.add_user(user, role) unless role == :anonymous
+ group.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
index c7149c100b2..9bb661a734e 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -73,7 +73,7 @@ RSpec.describe 'getting dependency proxy manifests in a group' do
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
- group.add_user(user, role) unless role == :anonymous
+ group.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/project/container_repositories_spec.rb b/spec/requests/api/graphql/project/container_repositories_spec.rb
index bbab6012f3f..01b117a89d8 100644
--- a/spec/requests/api/graphql/project/container_repositories_spec.rb
+++ b/spec/requests/api/graphql/project/container_repositories_spec.rb
@@ -81,7 +81,7 @@ RSpec.describe 'getting container repositories in a project' do
with_them do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility.to_s.upcase, false))
- project.add_user(user, role) unless role == :anonymous
+ project.add_member(user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb b/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
index a025c57d4b8..33e1dbcba27 100644
--- a/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
+++ b/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe 'getting the packages cleanup policy linked to a project' do
with_them do
before do
project.update!(visibility: visibility.to_s)
- project.add_user(current_user, role) unless role == :anonymous
+ project.add_member(current_user, role) unless role == :anonymous
end
it 'return the proper response' do
diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb
index 6d5676bbe35..a7b4bea362f 100644
--- a/spec/requests/api/group_variables_spec.rb
+++ b/spec/requests/api/group_variables_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe API::GroupVariables do
let(:access_level) {}
before do
- group.add_user(user, access_level) if access_level
+ group.add_member(user, access_level) if access_level
end
describe 'GET /groups/:id/variables' do
diff --git a/spec/requests/api/invitations_spec.rb b/spec/requests/api/invitations_spec.rb
index 64ad5733c1b..58068bf01a3 100644
--- a/spec/requests/api/invitations_spec.rb
+++ b/spec/requests/api/invitations_spec.rb
@@ -320,7 +320,7 @@ RSpec.describe API::Invitations do
let(:source) { project }
end
- it 'records queries', :request_store, :use_sql_query_cache do
+ it 'does not exceed expected queries count for emails', :request_store, :use_sql_query_cache do
post invitations_url(project, maintainer), params: { email: email, access_level: Member::DEVELOPER }
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
@@ -336,7 +336,25 @@ RSpec.describe API::Invitations do
end.not_to exceed_all_query_limit(control.count).with_threshold(unresolved_n_plus_ones)
end
- it 'records queries with secondary emails', :request_store, :use_sql_query_cache do
+ it 'does not exceed expected queries count for user_ids', :request_store, :use_sql_query_cache do
+ stranger2 = create(:user)
+
+ post invitations_url(project, maintainer), params: { user_id: stranger.id, access_level: Member::DEVELOPER }
+
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ post invitations_url(project, maintainer), params: { user_id: stranger2.id, access_level: Member::DEVELOPER }
+ end
+
+ users = create_list(:user, 5)
+
+ unresolved_n_plus_ones = 116 # 51 for 1 vs 167 for 5 - currently there are 29 queries added per user
+
+ expect do
+ post invitations_url(project, maintainer), params: { user_id: users.map(&:id).join(','), access_level: Member::DEVELOPER }
+ end.not_to exceed_all_query_limit(control.count).with_threshold(unresolved_n_plus_ones)
+ end
+
+ it 'does not exceed expected queries count with secondary emails', :request_store, :use_sql_query_cache do
create(:email, email: email, user: create(:user))
post invitations_url(project, maintainer), params: { email: email, access_level: Member::DEVELOPER }
@@ -365,7 +383,7 @@ RSpec.describe API::Invitations do
let(:source) { group }
end
- it 'records queries', :request_store, :use_sql_query_cache do
+ it 'does not exceed expected queries count for emails', :request_store, :use_sql_query_cache do
post invitations_url(group, maintainer), params: { email: email, access_level: Member::DEVELOPER }
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
@@ -381,7 +399,7 @@ RSpec.describe API::Invitations do
end.not_to exceed_all_query_limit(control.count).with_threshold(unresolved_n_plus_ones)
end
- it 'records queries with secondary emails', :request_store, :use_sql_query_cache do
+ it 'does not exceed expected queries count for secondary emails', :request_store, :use_sql_query_cache do
create(:email, email: email, user: create(:user))
post invitations_url(group, maintainer), params: { email: email, access_level: Member::DEVELOPER }
diff --git a/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb b/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
index ffeaf1075f3..b0c2eaec4e2 100644
--- a/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
+++ b/spec/requests/jira_connect/oauth_application_ids_controller_spec.rb
@@ -3,7 +3,40 @@
require 'spec_helper'
RSpec.describe JiraConnect::OauthApplicationIdsController do
+ describe 'OPTIONS /-/jira_connect/oauth_application_id' do
+ before do
+ stub_application_setting(jira_connect_application_key: '123456')
+
+ options '/-/jira_connect/oauth_application_id', headers: { 'Origin' => 'http://notgitlab.com' }
+ end
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ it 'allows cross-origin requests', :aggregate_failures do
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
+ expect(response.headers['Access-Control-Allow-Methods']).to eq 'GET, OPTIONS'
+ expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
+ end
+
+ context 'on GitLab.com' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'renders not found' do
+ options '/-/jira_connect/oauth_application_id'
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response.headers['Access-Control-Allow-Origin']).not_to eq '*'
+ end
+ end
+ end
+
describe 'GET /-/jira_connect/oauth_application_id' do
+ let(:cors_request_headers) { { 'Origin' => 'http://notgitlab.com' } }
+
before do
stub_application_setting(jira_connect_application_key: '123456')
end
@@ -15,6 +48,14 @@ RSpec.describe JiraConnect::OauthApplicationIdsController do
expect(json_response).to eq({ "application_id" => "123456" })
end
+ it 'allows cross-origin requests', :aggregate_failures do
+ get '/-/jira_connect/oauth_application_id', headers: cors_request_headers
+
+ expect(response.headers['Access-Control-Allow-Origin']).to eq '*'
+ expect(response.headers['Access-Control-Allow-Methods']).to eq 'GET, OPTIONS'
+ expect(response.headers['Access-Control-Allow-Credentials']).to be_nil
+ end
+
context 'application ID is empty' do
before do
stub_application_setting(jira_connect_application_key: '')
@@ -38,5 +79,17 @@ RSpec.describe JiraConnect::OauthApplicationIdsController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'on GitLab.com' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'renders not found' do
+ get '/-/jira_connect/oauth_application_id'
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
end
diff --git a/spec/requests/jira_connect/subscriptions_controller_spec.rb b/spec/requests/jira_connect/subscriptions_controller_spec.rb
new file mode 100644
index 00000000000..b10d07b3771
--- /dev/null
+++ b/spec/requests/jira_connect/subscriptions_controller_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe JiraConnect::SubscriptionsController do
+ describe 'GET /-/jira_connect/subscriptions' do
+ let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'http://self-managed-gitlab.com') }
+
+ let(:qsh) do
+ Atlassian::Jwt.create_query_string_hash('https://gitlab.test/subscriptions', 'GET', 'https://gitlab.test')
+ end
+
+ let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
+
+ before do
+ get '/-/jira_connect/subscriptions', params: { jwt: jwt }
+ end
+
+ subject(:content_security_policy) { response.headers['Content-Security-Policy'] }
+
+ it { is_expected.to include('http://self-managed-gitlab.com/-/jira_connect/oauth_application_ids')}
+
+ context 'with no self-managed instance configured' do
+ let_it_be(:installation) { create(:jira_connect_installation, instance_url: '') }
+
+ it { is_expected.not_to include('http://self-managed-gitlab.com')}
+ end
+ end
+end
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index c647fee1564..afaa6168bfd 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -120,9 +120,9 @@ RSpec.describe 'OpenID Connect requests' do
let!(:group4) { create :group, parent: group3 }
before do
- group1.add_user(user, GroupMember::OWNER)
- group3.add_user(user, Gitlab::Access::DEVELOPER)
- group4.add_user(user, Gitlab::Access::MAINTAINER)
+ group1.add_member(user, GroupMember::OWNER)
+ group3.add_member(user, Gitlab::Access::DEVELOPER)
+ group4.add_member(user, Gitlab::Access::MAINTAINER)
request_user_info!
end
@@ -163,8 +163,8 @@ RSpec.describe 'OpenID Connect requests' do
let!(:group4) { create :group, parent: group3 }
before do
- group1.add_user(user, Gitlab::Access::OWNER)
- group3.add_user(user, Gitlab::Access::DEVELOPER)
+ group1.add_member(user, Gitlab::Access::OWNER)
+ group3.add_member(user, Gitlab::Access::DEVELOPER)
request_access_token!
@payload = JSON::JWT.decode(json_response['id_token'], :skip_verification)
@@ -358,8 +358,8 @@ RSpec.describe 'OpenID Connect requests' do
let!(:group4) { create :group, parent: group3 }
before do
- group1.add_user(user, Gitlab::Access::OWNER)
- group3.add_user(user, Gitlab::Access::DEVELOPER)
+ group1.add_member(user, Gitlab::Access::OWNER)
+ group3.add_member(user, Gitlab::Access::DEVELOPER)
request_access_token!
@payload = JSON::JWT.decode(json_response['id_token'], :skip_verification)
diff --git a/spec/requests/projects/environments_controller_spec.rb b/spec/requests/projects/environments_controller_spec.rb
index 5cdf507abef..0890b0c45da 100644
--- a/spec/requests/projects/environments_controller_spec.rb
+++ b/spec/requests/projects/environments_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Projects::EnvironmentsController do
- let_it_be(:project) { create(:project, :repository) }
+ let_it_be_with_refind(:project) { create(:project, :repository) }
let(:environment) { create(:environment, name: 'production', project: project) }
diff --git a/spec/serializers/member_user_entity_spec.rb b/spec/serializers/member_user_entity_spec.rb
index 85f29845d65..4dd6848c47b 100644
--- a/spec/serializers/member_user_entity_spec.rb
+++ b/spec/serializers/member_user_entity_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe MemberUserEntity do
shared_examples 'correctly exposes user two_factor_enabled' do
context 'when the current_user has a role lower than minimum manage member role' do
before do
- source.add_user(current_user, Gitlab::Access::DEVELOPER)
+ source.add_member(current_user, Gitlab::Access::DEVELOPER)
end
it 'does not expose user two_factor_enabled' do
@@ -65,7 +65,7 @@ RSpec.describe MemberUserEntity do
context 'when the current user has a minimum manage member role or higher' do
before do
- source.add_user(current_user, minimum_manage_member_role)
+ source.add_member(current_user, minimum_manage_member_role)
end
it 'matches json schema' do
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index 628943e40ff..57a151efda6 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Groups::DestroyService do
let(:remove_path) { group.path + "+#{group.id}+deleted" }
before do
- group.add_user(user, Gitlab::Access::OWNER)
+ group.add_member(user, Gitlab::Access::OWNER)
end
def destroy_group(group, user, async)
@@ -168,8 +168,8 @@ RSpec.describe Groups::DestroyService do
let(:group2_user) { create(:user) }
before do
- group1.add_user(group1_user, Gitlab::Access::OWNER)
- group2.add_user(group2_user, Gitlab::Access::OWNER)
+ group1.add_member(group1_user, Gitlab::Access::OWNER)
+ group2.add_member(group2_user, Gitlab::Access::OWNER)
end
context 'when a project is shared with a group' do
@@ -203,7 +203,7 @@ RSpec.describe Groups::DestroyService do
let(:group3_user) { create(:user) }
before do
- group3.add_user(group3_user, Gitlab::Access::OWNER)
+ group3.add_member(group3_user, Gitlab::Access::OWNER)
create(:group_group_link, shared_group: group2, shared_with_group: group3)
group3.refresh_members_authorized_projects
@@ -290,7 +290,7 @@ RSpec.describe Groups::DestroyService do
let!(:shared_with_group_user) { create(:user) }
before do
- shared_with_group.add_user(shared_with_group_user, Gitlab::Access::MAINTAINER)
+ shared_with_group.add_member(shared_with_group_user, Gitlab::Access::MAINTAINER)
create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group)
shared_with_group.refresh_members_authorized_projects
diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb
index 46c5e2a9818..c0e1691fe26 100644
--- a/spec/services/groups/update_service_spec.rb
+++ b/spec/services/groups/update_service_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe Groups::UpdateService do
let!(:service) { described_class.new(public_group, user, visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
before do
- public_group.add_user(user, Gitlab::Access::OWNER)
+ public_group.add_member(user, Gitlab::Access::OWNER)
create(:project, :public, group: public_group)
expect(TodosDestroyer::GroupPrivateWorker).not_to receive(:perform_in)
@@ -119,7 +119,7 @@ RSpec.describe Groups::UpdateService do
let!(:service) { described_class.new(internal_group, user, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
before do
- internal_group.add_user(user, Gitlab::Access::OWNER)
+ internal_group.add_member(user, Gitlab::Access::OWNER)
create(:project, :internal, group: internal_group)
expect(TodosDestroyer::GroupPrivateWorker).not_to receive(:perform_in)
@@ -135,7 +135,7 @@ RSpec.describe Groups::UpdateService do
let!(:service) { described_class.new(internal_group, user, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
before do
- internal_group.add_user(user, Gitlab::Access::OWNER)
+ internal_group.add_member(user, Gitlab::Access::OWNER)
create(:project, :private, group: internal_group)
expect(TodosDestroyer::GroupPrivateWorker).to receive(:perform_in)
@@ -233,7 +233,7 @@ RSpec.describe Groups::UpdateService do
let!(:service) { described_class.new(internal_group, user, visibility_level: 99) }
before do
- internal_group.add_user(user, Gitlab::Access::MAINTAINER)
+ internal_group.add_member(user, Gitlab::Access::MAINTAINER)
end
it "does not change permission level" do
@@ -246,7 +246,7 @@ RSpec.describe Groups::UpdateService do
let(:service) { described_class.new(internal_group, user, emails_disabled: true) }
it 'updates the attribute' do
- internal_group.add_user(user, Gitlab::Access::OWNER)
+ internal_group.add_member(user, Gitlab::Access::OWNER)
expect { service.execute }.to change { internal_group.emails_disabled }.to(true)
end
@@ -280,7 +280,7 @@ RSpec.describe Groups::UpdateService do
let!(:service) { described_class.new(internal_group, user, path: SecureRandom.hex) }
before do
- internal_group.add_user(user, Gitlab::Access::MAINTAINER)
+ internal_group.add_member(user, Gitlab::Access::MAINTAINER)
create(:project, :internal, group: internal_group)
end
diff --git a/spec/services/issues/related_branches_service_spec.rb b/spec/services/issues/related_branches_service_spec.rb
index 53474c61907..7a4bae7f852 100644
--- a/spec/services/issues/related_branches_service_spec.rb
+++ b/spec/services/issues/related_branches_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Issues::RelatedBranchesService, :clean_gitlab_redis_cache do
+RSpec.describe Issues::RelatedBranchesService do
let_it_be(:developer) { create(:user) }
let_it_be(:issue) { create(:issue) }
diff --git a/spec/services/members/creator_service_spec.rb b/spec/services/members/creator_service_spec.rb
index 8b1df2ab86d..ad4c649086b 100644
--- a/spec/services/members/creator_service_spec.rb
+++ b/spec/services/members/creator_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Members::CreatorService do
describe '#execute' do
it 'raises error for new member on authorization check implementation' do
expect do
- described_class.add_user(source, user, :maintainer, current_user: current_user)
+ described_class.add_member(source, user, :maintainer, current_user: current_user)
end.to raise_error(NotImplementedError)
end
@@ -19,7 +19,7 @@ RSpec.describe Members::CreatorService do
source.add_developer(user)
expect do
- described_class.add_user(source, user, :maintainer, current_user: current_user)
+ described_class.add_member(source, user, :maintainer, current_user: current_user)
end.to raise_error(NotImplementedError)
end
end
diff --git a/spec/services/members/groups/creator_service_spec.rb b/spec/services/members/groups/creator_service_spec.rb
index b80b7998eac..4130fbd44fa 100644
--- a/spec/services/members/groups/creator_service_spec.rb
+++ b/spec/services/members/groups/creator_service_spec.rb
@@ -14,13 +14,13 @@ RSpec.describe Members::Groups::CreatorService do
it_behaves_like 'owner management'
- describe '.add_users' do
+ describe '.add_members' do
it_behaves_like 'bulk member creation' do
let_it_be(:member_type) { GroupMember }
end
end
- describe '.add_user' do
+ describe '.add_member' do
it_behaves_like 'member creation' do
let_it_be(:member_type) { GroupMember }
end
@@ -30,7 +30,7 @@ RSpec.describe Members::Groups::CreatorService do
expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait).once
1.upto(3) do
- described_class.add_user(source, user, :maintainer)
+ described_class.add_member(source, user, :maintainer)
end
end
end
diff --git a/spec/services/members/projects/creator_service_spec.rb b/spec/services/members/projects/creator_service_spec.rb
index 38955122ab0..8304bee2ffc 100644
--- a/spec/services/members/projects/creator_service_spec.rb
+++ b/spec/services/members/projects/creator_service_spec.rb
@@ -14,13 +14,13 @@ RSpec.describe Members::Projects::CreatorService do
it_behaves_like 'owner management'
- describe '.add_users' do
+ describe '.add_members' do
it_behaves_like 'bulk member creation' do
let_it_be(:member_type) { ProjectMember }
end
end
- describe '.add_user' do
+ describe '.add_member' do
it_behaves_like 'member creation' do
let_it_be(:member_type) { ProjectMember }
end
@@ -30,7 +30,7 @@ RSpec.describe Members::Projects::CreatorService do
expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to receive(:bulk_perform_in).once
1.upto(3) do
- described_class.add_user(source, user, :maintainer)
+ described_class.add_member(source, user, :maintainer)
end
end
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 8e0f964d965..98fe8a40c61 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -582,8 +582,8 @@ RSpec.describe NotificationService, :mailer do
before do
note.project.namespace_id = group.id
- group.add_user(@u_watcher, GroupMember::MAINTAINER)
- group.add_user(@u_custom_global, GroupMember::MAINTAINER)
+ group.add_member(@u_watcher, GroupMember::MAINTAINER)
+ group.add_member(@u_custom_global, GroupMember::MAINTAINER)
note.project.save!
@u_watcher.notification_settings_for(note.project).participating!
@@ -3850,7 +3850,7 @@ RSpec.describe NotificationService, :mailer do
# Group member: global=watch, group=global
@g_global_watcher ||= create_global_setting_for(create(:user), :watch)
- group.add_users([@g_watcher, @g_global_watcher], :maintainer)
+ group.add_members([@g_watcher, @g_global_watcher], :maintainer)
group
end
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 278ca148b74..7361b9b8e35 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -224,7 +224,7 @@ RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publi
context 'when flushing caches fail due to Redis' do
before do
new_user = create(:user)
- project.team.add_user(new_user, Gitlab::Access::DEVELOPER)
+ project.team.add_member(new_user, Gitlab::Access::DEVELOPER)
allow_any_instance_of(described_class).to receive(:flush_caches).and_raise(::Redis::CannotConnectError)
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index e292c13c46e..b1b45e89c1b 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -32,14 +32,14 @@ RSpec.describe Projects::ForkService do
external_authorization_classification_label: 'classification-label')
@to_user = create(:user)
@to_namespace = @to_user.namespace
- @from_project.add_user(@to_user, :developer)
+ @from_project.add_member(@to_user, :developer)
end
context 'fork project' do
context 'when forker is a guest' do
before do
@guest = create(:user)
- @from_project.add_user(@guest, :guest)
+ @from_project.add_member(@guest, :guest)
end
subject { fork_project(@from_project, @guest, using_service: true) }
@@ -261,10 +261,10 @@ RSpec.describe Projects::ForkService do
description: 'Wow, such a cool project!',
ci_config_path: 'debian/salsa-ci.yml')
@group = create(:group)
- @group.add_user(@group_owner, GroupMember::OWNER)
- @group.add_user(@developer, GroupMember::DEVELOPER)
- @project.add_user(@developer, :developer)
- @project.add_user(@group_owner, :developer)
+ @group.add_member(@group_owner, GroupMember::OWNER)
+ @group.add_member(@developer, GroupMember::DEVELOPER)
+ @project.add_member(@developer, :developer)
+ @project.add_member(@group_owner, :developer)
@opts = { namespace: @group, using_service: true }
end
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 1241491d914..f019434a4fe 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -424,7 +424,7 @@ RSpec.describe Projects::UpdateService do
it 'does not update when not project owner' do
maintainer = create(:user)
- project.add_user(maintainer, :maintainer)
+ project.add_member(maintainer, :maintainer)
expect { update_project(project, maintainer, emails_disabled: true) }
.not_to change { project.emails_disabled }
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index f7ed6006099..3f11eaa7e93 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe QuickActions::InterpretService do
+ include AfterNextHelpers
+
let_it_be(:group) { create(:group, :crm_enabled) }
let_it_be(:public_project) { create(:project, :public, group: group) }
let_it_be(:repository_project) { create(:project, :repository) }
@@ -17,8 +19,9 @@ RSpec.describe QuickActions::InterpretService do
let(:milestone) { create(:milestone, project: project, title: '9.10') }
let(:commit) { create(:commit, project: project) }
+ let(:current_user) { developer }
- subject(:service) { described_class.new(project, developer) }
+ subject(:service) { described_class.new(project, current_user) }
before_all do
public_project.add_developer(developer)
@@ -682,6 +685,58 @@ RSpec.describe QuickActions::InterpretService do
end
shared_examples 'assign command' do
+ it 'assigns to me' do
+ cmd = '/assign me'
+
+ _, updates, _ = service.execute(cmd, issuable)
+
+ expect(updates).to eq(assignee_ids: [current_user.id])
+ end
+
+ it 'does not assign to group members' do
+ grp = create(:group)
+ grp.add_developer(developer)
+ grp.add_developer(developer2)
+
+ cmd = "/assign #{grp.to_reference}"
+
+ _, updates, message = service.execute(cmd, issuable)
+
+ expect(updates).to be_blank
+ expect(message).to include('Failed to find users')
+ end
+
+ context 'when there are too many references' do
+ before do
+ stub_const('Gitlab::QuickActions::UsersExtractor::MAX_QUICK_ACTION_USERS', 2)
+ end
+
+ it 'says what went wrong' do
+ cmd = '/assign her and you, me and them'
+
+ _, updates, message = service.execute(cmd, issuable)
+
+ expect(updates).to be_blank
+ expect(message).to include('Too many references. Quick actions are limited to at most 2 user references')
+ end
+ end
+
+ context 'when the user extractor raises an uninticipated error' do
+ before do
+ allow_next(Gitlab::QuickActions::UsersExtractor)
+ .to receive(:execute).and_raise(Gitlab::QuickActions::UsersExtractor::Error)
+ end
+
+ it 'tracks the exception in dev, and reports a generic message in production' do
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).twice
+
+ _, updates, message = service.execute('/assign some text', issuable)
+
+ expect(updates).to be_blank
+ expect(message).to include('Something went wrong')
+ end
+ end
+
it 'assigns to users with escaped underscores' do
user = create(:user)
base = user.username
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index e4582e19416..1cb44366457 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -186,8 +186,8 @@ RSpec.describe TodoService do
before do
group.add_owner(author)
- group.add_user(member, Gitlab::Access::DEVELOPER)
- group.add_user(john_doe, Gitlab::Access::DEVELOPER)
+ group.add_member(member, Gitlab::Access::DEVELOPER)
+ group.add_member(john_doe, Gitlab::Access::DEVELOPER)
service.new_issue(issue, author)
end
diff --git a/spec/support/helpers/project_helpers.rb b/spec/support/helpers/project_helpers.rb
index ef8947ab340..2427ed2bcc9 100644
--- a/spec/support/helpers/project_helpers.rb
+++ b/spec/support/helpers/project_helpers.rb
@@ -13,7 +13,7 @@ module ProjectHelpers
when :admin
create(:user, :admin, name: 'admin')
else
- create(:user, name: membership).tap { |u| target.add_user(u, membership) }
+ create(:user, name: membership).tap { |u| target.add_member(u, membership) }
end
end
diff --git a/spec/support/shared_examples/finders/issues_finder_shared_examples.rb b/spec/support/shared_examples/finders/issues_finder_shared_examples.rb
index 622a88e8323..f3c616c7d9b 100644
--- a/spec/support/shared_examples/finders/issues_finder_shared_examples.rb
+++ b/spec/support/shared_examples/finders/issues_finder_shared_examples.rb
@@ -962,7 +962,7 @@ RSpec.shared_examples 'issues or work items finder' do |factory, execute_context
group = create(:group)
project = create(:project, group: group)
item = create(factory, project: project)
- group.add_user(user, :owner)
+ group.add_member(user, :owner)
expect(items).to include(item)
end
diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb
index 75fff11cecd..9ac173341d7 100644
--- a/spec/support/shared_examples/models/member_shared_examples.rb
+++ b/spec/support/shared_examples/models/member_shared_examples.rb
@@ -80,7 +80,7 @@ RSpec.shared_examples_for "member creation" do
let_it_be(:admin) { create(:admin) }
it 'returns a Member object', :aggregate_failures do
- member = described_class.add_user(source, user, :maintainer)
+ member = described_class.add_member(source, user, :maintainer)
expect(member).to be_a member_type
expect(member).to be_persisted
@@ -99,7 +99,7 @@ RSpec.shared_examples_for "member creation" do
end
it 'does not update the member' do
- member = described_class.add_user(source, project_bot, :maintainer, current_user: user)
+ member = described_class.add_member(source, project_bot, :maintainer, current_user: user)
expect(source.users.reload).to include(project_bot)
expect(member).to be_persisted
@@ -110,7 +110,7 @@ RSpec.shared_examples_for "member creation" do
context 'when project_bot is not already a member' do
it 'adds the member' do
- member = described_class.add_user(source, project_bot, :maintainer, current_user: user)
+ member = described_class.add_member(source, project_bot, :maintainer, current_user: user)
expect(source.users.reload).to include(project_bot)
expect(member).to be_persisted
@@ -120,7 +120,7 @@ RSpec.shared_examples_for "member creation" do
context 'when admin mode is enabled', :enable_admin_mode, :aggregate_failures do
it 'sets members.created_by to the given admin current_user' do
- member = described_class.add_user(source, user, :maintainer, current_user: admin)
+ member = described_class.add_member(source, user, :maintainer, current_user: admin)
expect(member).to be_persisted
expect(source.users.reload).to include(user)
@@ -130,7 +130,7 @@ RSpec.shared_examples_for "member creation" do
context 'when admin mode is disabled' do
it 'rejects setting members.created_by to the given admin current_user', :aggregate_failures do
- member = described_class.add_user(source, user, :maintainer, current_user: admin)
+ member = described_class.add_member(source, user, :maintainer, current_user: admin)
expect(member).not_to be_persisted
expect(source.users.reload).not_to include(user)
@@ -139,7 +139,7 @@ RSpec.shared_examples_for "member creation" do
end
it 'sets members.expires_at to the given expires_at' do
- member = described_class.add_user(source, user, :maintainer, expires_at: Date.new(2016, 9, 22))
+ member = described_class.add_member(source, user, :maintainer, expires_at: Date.new(2016, 9, 22))
expect(member.expires_at).to eq(Date.new(2016, 9, 22))
end
@@ -148,7 +148,7 @@ RSpec.shared_examples_for "member creation" do
it "accepts the :#{sym_key} symbol as access level", :aggregate_failures do
expect(source.users).not_to include(user)
- member = described_class.add_user(source, user.id, sym_key)
+ member = described_class.add_member(source, user.id, sym_key)
expect(member.access_level).to eq(int_access_level)
expect(source.users.reload).to include(user)
@@ -157,7 +157,7 @@ RSpec.shared_examples_for "member creation" do
it "accepts the #{int_access_level} integer as access level", :aggregate_failures do
expect(source.users).not_to include(user)
- member = described_class.add_user(source, user.id, int_access_level)
+ member = described_class.add_member(source, user.id, int_access_level)
expect(member.access_level).to eq(int_access_level)
expect(source.users.reload).to include(user)
@@ -169,7 +169,7 @@ RSpec.shared_examples_for "member creation" do
it 'adds the user as a member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, user.id, :maintainer)
+ described_class.add_member(source, user.id, :maintainer)
expect(source.users.reload).to include(user)
end
@@ -179,7 +179,7 @@ RSpec.shared_examples_for "member creation" do
it 'does not add the user as a member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, non_existing_record_id, :maintainer)
+ described_class.add_member(source, non_existing_record_id, :maintainer)
expect(source.users.reload).not_to include(user)
end
@@ -189,7 +189,7 @@ RSpec.shared_examples_for "member creation" do
it 'adds the user as a member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, user, :maintainer)
+ described_class.add_member(source, user, :maintainer)
expect(source.users.reload).to include(user)
end
@@ -205,7 +205,7 @@ RSpec.shared_examples_for "member creation" do
expect(source.requesters.exists?(user_id: user)).to be_truthy
expect do
- described_class.add_user(source, user, :maintainer)
+ described_class.add_member(source, user, :maintainer)
end.to raise_error(Gitlab::Access::AccessDeniedError)
expect(source.users.reload).not_to include(user)
@@ -217,7 +217,7 @@ RSpec.shared_examples_for "member creation" do
it 'adds the user as a member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, user.email, :maintainer)
+ described_class.add_member(source, user.email, :maintainer)
expect(source.users.reload).to include(user)
end
@@ -227,7 +227,7 @@ RSpec.shared_examples_for "member creation" do
it 'creates an invited member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, 'user@example.com', :maintainer)
+ described_class.add_member(source, 'user@example.com', :maintainer)
expect(source.members.invite.pluck(:invite_email)).to include('user@example.com')
end
@@ -237,7 +237,7 @@ RSpec.shared_examples_for "member creation" do
it 'creates an invited member', :aggregate_failures do
email_starting_with_number = "#{user.id}_email@example.com"
- described_class.add_user(source, email_starting_with_number, :maintainer)
+ described_class.add_member(source, email_starting_with_number, :maintainer)
expect(source.members.invite.pluck(:invite_email)).to include(email_starting_with_number)
expect(source.users.reload).not_to include(user)
@@ -249,7 +249,7 @@ RSpec.shared_examples_for "member creation" do
it 'creates the member' do
expect(source.users).not_to include(user)
- described_class.add_user(source, user, :maintainer, current_user: admin)
+ described_class.add_member(source, user, :maintainer, current_user: admin)
expect(source.users.reload).to include(user)
end
@@ -263,7 +263,7 @@ RSpec.shared_examples_for "member creation" do
expect(source.users).not_to include(user)
expect(source.requesters.exists?(user_id: user)).to be_truthy
- described_class.add_user(source, user, :maintainer, current_user: admin)
+ described_class.add_member(source, user, :maintainer, current_user: admin)
expect(source.users.reload).to include(user)
expect(source.requesters.reload.exists?(user_id: user)).to be_falsy
@@ -275,7 +275,7 @@ RSpec.shared_examples_for "member creation" do
it 'does not create the member', :aggregate_failures do
expect(source.users).not_to include(user)
- member = described_class.add_user(source, user, :maintainer, current_user: user)
+ member = described_class.add_member(source, user, :maintainer, current_user: user)
expect(source.users.reload).not_to include(user)
expect(member).not_to be_persisted
@@ -290,7 +290,7 @@ RSpec.shared_examples_for "member creation" do
expect(source.users).not_to include(user)
expect(source.requesters.exists?(user_id: user)).to be_truthy
- described_class.add_user(source, user, :maintainer, current_user: user)
+ described_class.add_member(source, user, :maintainer, current_user: user)
expect(source.users.reload).not_to include(user)
expect(source.requesters.exists?(user_id: user)).to be_truthy
@@ -300,14 +300,14 @@ RSpec.shared_examples_for "member creation" do
context 'when member already exists' do
before do
- source.add_user(user, :developer)
+ source.add_member(user, :developer)
end
context 'with no current_user' do
it 'updates the member' do
expect(source.users).to include(user)
- described_class.add_user(source, user, :maintainer)
+ described_class.add_member(source, user, :maintainer)
expect(source.members.find_by(user_id: user).access_level).to eq(Gitlab::Access::MAINTAINER)
end
@@ -317,7 +317,7 @@ RSpec.shared_examples_for "member creation" do
it 'updates the member' do
expect(source.users).to include(user)
- described_class.add_user(source, user, :maintainer, current_user: admin)
+ described_class.add_member(source, user, :maintainer, current_user: admin)
expect(source.members.find_by(user_id: user).access_level).to eq(Gitlab::Access::MAINTAINER)
end
@@ -327,7 +327,7 @@ RSpec.shared_examples_for "member creation" do
it 'does not update the member' do
expect(source.users).to include(user)
- described_class.add_user(source, user, :maintainer, current_user: user)
+ described_class.add_member(source, user, :maintainer, current_user: user)
expect(source.members.find_by(user_id: user).access_level).to eq(Gitlab::Access::DEVELOPER)
end
@@ -345,12 +345,12 @@ RSpec.shared_examples_for "bulk member creation" do
# maintainers cannot add owners
source.add_maintainer(user)
- expect(described_class.add_users(source, [user1, user2], :owner, current_user: user)).to be_empty
+ expect(described_class.add_members(source, [user1, user2], :owner, current_user: user)).to be_empty
end
end
it 'returns Member objects' do
- members = described_class.add_users(source, [user1, user2], :maintainer)
+ members = described_class.add_members(source, [user1, user2], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
@@ -358,7 +358,7 @@ RSpec.shared_examples_for "bulk member creation" do
end
it 'returns an empty array' do
- members = described_class.add_users(source, [], :maintainer)
+ members = described_class.add_members(source, [], :maintainer)
expect(members).to be_a Array
expect(members).to be_empty
@@ -367,7 +367,7 @@ RSpec.shared_examples_for "bulk member creation" do
it 'supports different formats' do
list = ['joe@local.test', admin, user1.id, user2.id.to_s]
- members = described_class.add_users(source, list, :maintainer)
+ members = described_class.add_members(source, list, :maintainer)
expect(members.size).to eq(4)
expect(members.first).to be_invite
@@ -375,7 +375,7 @@ RSpec.shared_examples_for "bulk member creation" do
context 'with de-duplication' do
it 'has the same user by id and user' do
- members = described_class.add_users(source, [user1.id, user1, user1.id, user2, user2.id, user2], :maintainer)
+ members = described_class.add_members(source, [user1.id, user1, user1.id, user2, user2.id, user2], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
@@ -383,7 +383,7 @@ RSpec.shared_examples_for "bulk member creation" do
end
it 'has the same user sent more than once' do
- members = described_class.add_users(source, [user1, user1], :maintainer)
+ members = described_class.add_members(source, [user1, user1], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1)
expect(members).to all(be_a(member_type))
@@ -392,7 +392,7 @@ RSpec.shared_examples_for "bulk member creation" do
end
it 'with the same user sent more than once by user and by email' do
- members = described_class.add_users(source, [user1, user1.email], :maintainer)
+ members = described_class.add_members(source, [user1, user1.email], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1)
expect(members).to all(be_a(member_type))
@@ -400,7 +400,7 @@ RSpec.shared_examples_for "bulk member creation" do
end
it 'with the same user sent more than once by user id and by email' do
- members = described_class.add_users(source, [user1.id, user1.email], :maintainer)
+ members = described_class.add_members(source, [user1.id, user1.email], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1)
expect(members).to all(be_a(member_type))
@@ -409,12 +409,12 @@ RSpec.shared_examples_for "bulk member creation" do
context 'when a member already exists' do
before do
- source.add_user(user1, :developer)
+ source.add_member(user1, :developer)
end
it 'has the same user sent more than once with the member already existing' do
expect do
- members = described_class.add_users(source, [user1, user1, user2], :maintainer)
+ members = described_class.add_members(source, [user1, user1, user2], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
@@ -425,7 +425,7 @@ RSpec.shared_examples_for "bulk member creation" do
user3 = create(:user)
expect do
- members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+ members = described_class.add_members(source, [user1.id, user2, user3.id], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
@@ -436,7 +436,7 @@ RSpec.shared_examples_for "bulk member creation" do
user3 = create(:user)
expect do
- members = described_class.add_users(source, [user1, user2, user3], :maintainer)
+ members = described_class.add_members(source, [user1, user2, user3], :maintainer)
expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
@@ -448,7 +448,7 @@ RSpec.shared_examples_for "bulk member creation" do
let(:task_project) { source.is_a?(Group) ? create(:project, group: source) : source }
it 'creates a member_task with the correct attributes', :aggregate_failures do
- members = described_class.add_users(source, [user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: task_project.id)
+ members = described_class.add_members(source, [user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: task_project.id)
member = members.last
expect(member.tasks_to_be_done).to match_array([:ci, :code])
@@ -457,7 +457,7 @@ RSpec.shared_examples_for "bulk member creation" do
context 'with an already existing member' do
before do
- source.add_user(user1, :developer)
+ source.add_member(user1, :developer)
end
it 'does not update tasks to be done if tasks already exist', :aggregate_failures do
@@ -465,7 +465,7 @@ RSpec.shared_examples_for "bulk member creation" do
create(:member_task, member: member, project: task_project, tasks_to_be_done: %w(code ci))
expect do
- described_class.add_users(source,
+ described_class.add_members(source,
[user1.id],
:developer,
tasks_to_be_done: %w(issues),
@@ -479,7 +479,7 @@ RSpec.shared_examples_for "bulk member creation" do
it 'adds tasks to be done if they do not exist', :aggregate_failures do
expect do
- described_class.add_users(source,
+ described_class.add_members(source,
[user1.id],
:developer,
tasks_to_be_done: %w(issues),
diff --git a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
index d7c2b645de9..bb2f8965294 100644
--- a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
@@ -72,7 +72,7 @@ RSpec.shared_examples 'conan search endpoint' do
project.update!(visibility: 'private')
project.team.truncate
user.project_authorizations.delete_all
- project.add_user(user, role) unless role == :anonymous
+ project.add_member(user, role) unless role == :anonymous
get api(url), params: params, headers: headers
end
diff --git a/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb b/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb
index 5ac42952f78..74ad0ccb77a 100644
--- a/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb
+++ b/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'shared/deploy_tokens/_form.html.haml' do
RSpec.shared_examples "display deploy token settings" do |role, shows_package_registry_permissions|
before do
- subject.add_user(user, role)
+ subject.add_member(user, role)
allow(view).to receive(:current_user).and_return(user)
stub_config(packages: { enabled: packages_enabled })
end
diff --git a/spec/workers/disallow_two_factor_for_group_worker_spec.rb b/spec/workers/disallow_two_factor_for_group_worker_spec.rb
index a69dd893f81..f30b12dd7f4 100644
--- a/spec/workers/disallow_two_factor_for_group_worker_spec.rb
+++ b/spec/workers/disallow_two_factor_for_group_worker_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe DisallowTwoFactorForGroupWorker do
end
it "updates group members" do
- group.add_user(user, GroupMember::DEVELOPER)
+ group.add_member(user, GroupMember::DEVELOPER)
described_class.new.perform(group.id)
diff --git a/spec/workers/remove_expired_members_worker_spec.rb b/spec/workers/remove_expired_members_worker_spec.rb
index 6d0d4aeef89..8d7d488094f 100644
--- a/spec/workers/remove_expired_members_worker_spec.rb
+++ b/spec/workers/remove_expired_members_worker_spec.rb
@@ -47,7 +47,7 @@ RSpec.describe RemoveExpiredMembersWorker do
let_it_be(:expired_project_bot) { create(:user, :project_bot) }
before do
- project.add_user(expired_project_bot, :maintainer, expires_at: 1.day.from_now)
+ project.add_member(expired_project_bot, :maintainer, expires_at: 1.day.from_now)
travel_to(3.days.from_now)
end
@@ -67,7 +67,7 @@ RSpec.describe RemoveExpiredMembersWorker do
let_it_be(:other_project_bot) { create(:user, :project_bot) }
before do
- project.add_user(other_project_bot, :maintainer, expires_at: 10.days.from_now)
+ project.add_member(other_project_bot, :maintainer, expires_at: 10.days.from_now)
travel_to(3.days.from_now)
end