summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-07 15:09:30 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-07 15:09:30 +0000
commitc6b3ec3f56fa32a0e0ed3de0d0878d25f1adaddf (patch)
tree967afee9a510ff9dd503ebd83706dc760ec2e3ed /spec
parent903ccf7c93eb9490c76857bffe744249cc07de09 (diff)
downloadgitlab-ce-c6b3ec3f56fa32a0e0ed3de0d0878d25f1adaddf.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/alerting/notifications_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/alerts_controller_spec.rb9
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb25
-rw-r--r--spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb352
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/gitlab/repository_url_builder_spec.rb56
-rw-r--r--spec/lib/gitlab/shell_spec.rb8
-rw-r--r--spec/models/member_spec.rb34
-rw-r--r--spec/models/project_wiki_spec.rb25
-rw-r--r--spec/models/snippet_spec.rb16
-rw-r--r--spec/models/user_spec.rb34
-rw-r--r--spec/serializers/merge_request_widget_entity_spec.rb22
-rw-r--r--spec/services/members/update_highest_role_service_spec.rb44
-rw-r--r--spec/services/projects/alerting/notify_service_spec.rb14
-rw-r--r--spec/services/projects/import_export/export_service_spec.rb24
-rw-r--r--spec/services/projects/prometheus/alerts/notify_service_spec.rb31
-rw-r--r--spec/support/shared_examples/models/update_highest_role_shared_examples.rb52
-rw-r--r--spec/support/shared_examples/models/versioned_description_shared_examples.rb52
18 files changed, 220 insertions, 582 deletions
diff --git a/spec/controllers/projects/alerting/notifications_controller_spec.rb b/spec/controllers/projects/alerting/notifications_controller_spec.rb
index a56ac59215f..9d26c2278b1 100644
--- a/spec/controllers/projects/alerting/notifications_controller_spec.rb
+++ b/spec/controllers/projects/alerting/notifications_controller_spec.rb
@@ -48,7 +48,7 @@ describe Projects::Alerting::NotificationsController do
end
context 'when notification service fails' do
- let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: 401) }
+ let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized) }
it 'responds with the service response' do
make_request
diff --git a/spec/controllers/projects/prometheus/alerts_controller_spec.rb b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
index e215f4b68fa..451834e0962 100644
--- a/spec/controllers/projects/prometheus/alerts_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
@@ -158,7 +158,8 @@ describe Projects::Prometheus::AlertsController do
end
describe 'POST #notify' do
- let(:notify_service) { spy }
+ let(:service_response) { ServiceResponse.success }
+ let(:notify_service) { instance_double(Projects::Prometheus::Alerts::NotifyService, execute: service_response) }
before do
sign_out(user)
@@ -170,7 +171,7 @@ describe Projects::Prometheus::AlertsController do
end
it 'returns ok if notification succeeds' do
- expect(notify_service).to receive(:execute).and_return(true)
+ expect(notify_service).to receive(:execute).and_return(ServiceResponse.success)
post :notify, params: project_params, session: { as: :json }
@@ -178,7 +179,9 @@ describe Projects::Prometheus::AlertsController do
end
it 'returns unprocessable entity if notification fails' do
- expect(notify_service).to receive(:execute).and_return(false)
+ expect(notify_service).to receive(:execute).and_return(
+ ServiceResponse.error(message: 'Unprocessable Entity', http_status: :unprocessable_entity)
+ )
post :notify, params: project_params, session: { as: :json }
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 1e13afc6033..7ee8f42e6ef 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -38,7 +38,11 @@ describe 'Import/Export - project export integration test', :js do
sign_in(user)
end
- shared_examples 'export file without sensitive words' do
+ context "with streaming serializer" do
+ before do
+ stub_feature_flags(project_export_as_ndjson: false)
+ end
+
it 'exports a project successfully', :sidekiq_inline do
export_project_and_download_file(page, project)
@@ -59,27 +63,8 @@ describe 'Import/Export - project export integration test', :js do
end
end
- context "with legacy export" do
- before do
- stub_feature_flags(streaming_serializer: false)
- stub_feature_flags(project_export_as_ndjson: false)
- end
-
- it_behaves_like "export file without sensitive words"
- end
-
- context "with streaming serializer" do
- before do
- stub_feature_flags(streaming_serializer: true)
- stub_feature_flags(project_export_as_ndjson: false)
- end
-
- it_behaves_like "export file without sensitive words"
- end
-
context "with ndjson" do
before do
- stub_feature_flags(streaming_serializer: true)
stub_feature_flags(project_export_as_ndjson: true)
end
diff --git a/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb
deleted file mode 100644
index e51f6888bbb..00000000000
--- a/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb
+++ /dev/null
@@ -1,352 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::ImportExport::Project::LegacyTreeSaver do
- describe 'saves the project tree into a json object' do
- let(:shared) { project.import_export_shared }
- let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared) }
- let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:user) { create(:user) }
- let!(:project) { setup_project }
-
- before do
- project.add_maintainer(user)
- allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
- allow_any_instance_of(MergeRequest).to receive(:source_branch_sha).and_return('ABCD')
- allow_any_instance_of(MergeRequest).to receive(:target_branch_sha).and_return('DCBA')
- end
-
- after do
- FileUtils.rm_rf(export_path)
- end
-
- it 'saves project successfully' do
- expect(project_tree_saver.save).to be true
- end
-
- # It is mostly duplicated in
- # `spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb`
- # except:
- # context 'with description override' do
- # context 'group members' do
- # ^ These are specific for the Project::TreeSaver
- context 'JSON' do
- let(:saved_project_json) do
- project_tree_saver.save
- project_json(project_tree_saver.full_path)
- end
-
- # It is not duplicated in
- # `spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb`
- context 'with description override' do
- let(:params) { { description: 'Foo Bar' } }
- let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared, params: params) }
-
- it 'overrides the project description' do
- expect(saved_project_json).to include({ 'description' => params[:description] })
- end
- end
-
- it 'saves the correct json' do
- expect(saved_project_json).to include({ 'description' => 'description', 'visibility_level' => 20 })
- end
-
- it 'has approvals_before_merge set' do
- expect(saved_project_json['approvals_before_merge']).to eq(1)
- end
-
- it 'has milestones' do
- expect(saved_project_json['milestones']).not_to be_empty
- end
-
- it 'has merge requests' do
- expect(saved_project_json['merge_requests']).not_to be_empty
- end
-
- it 'has merge request\'s milestones' do
- expect(saved_project_json['merge_requests'].first['milestone']).not_to be_empty
- end
-
- it 'has merge request\'s source branch SHA' do
- expect(saved_project_json['merge_requests'].first['source_branch_sha']).to eq('ABCD')
- end
-
- it 'has merge request\'s target branch SHA' do
- expect(saved_project_json['merge_requests'].first['target_branch_sha']).to eq('DCBA')
- end
-
- it 'has events' do
- expect(saved_project_json['merge_requests'].first['milestone']['events']).not_to be_empty
- end
-
- it 'has snippets' do
- expect(saved_project_json['snippets']).not_to be_empty
- end
-
- it 'has snippet notes' do
- expect(saved_project_json['snippets'].first['notes']).not_to be_empty
- end
-
- it 'has releases' do
- expect(saved_project_json['releases']).not_to be_empty
- end
-
- it 'has no author on releases' do
- expect(saved_project_json['releases'].first['author']).to be_nil
- end
-
- it 'has the author ID on releases' do
- expect(saved_project_json['releases'].first['author_id']).not_to be_nil
- end
-
- it 'has issues' do
- expect(saved_project_json['issues']).not_to be_empty
- end
-
- it 'has issue comments' do
- notes = saved_project_json['issues'].first['notes']
-
- expect(notes).not_to be_empty
- expect(notes.first['type']).to eq('DiscussionNote')
- end
-
- it 'has issue assignees' do
- expect(saved_project_json['issues'].first['issue_assignees']).not_to be_empty
- end
-
- it 'has author on issue comments' do
- expect(saved_project_json['issues'].first['notes'].first['author']).not_to be_empty
- end
-
- it 'has project members' do
- expect(saved_project_json['project_members']).not_to be_empty
- end
-
- it 'has merge requests diffs' do
- expect(saved_project_json['merge_requests'].first['merge_request_diff']).not_to be_empty
- end
-
- it 'has merge request diff files' do
- expect(saved_project_json['merge_requests'].first['merge_request_diff']['merge_request_diff_files']).not_to be_empty
- end
-
- it 'has merge request diff commits' do
- expect(saved_project_json['merge_requests'].first['merge_request_diff']['merge_request_diff_commits']).not_to be_empty
- end
-
- it 'has merge requests comments' do
- expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty
- end
-
- it 'has author on merge requests comments' do
- expect(saved_project_json['merge_requests'].first['notes'].first['author']).not_to be_empty
- end
-
- it 'has pipeline stages' do
- expect(saved_project_json.dig('ci_pipelines', 0, 'stages')).not_to be_empty
- end
-
- it 'has pipeline statuses' do
- expect(saved_project_json.dig('ci_pipelines', 0, 'stages', 0, 'statuses')).not_to be_empty
- end
-
- it 'has pipeline builds' do
- builds_count = saved_project_json
- .dig('ci_pipelines', 0, 'stages', 0, 'statuses')
- .count { |hash| hash['type'] == 'Ci::Build' }
-
- expect(builds_count).to eq(1)
- end
-
- it 'has no when YML attributes but only the DB column' do
- expect_any_instance_of(Gitlab::Ci::YamlProcessor).not_to receive(:build_attributes)
-
- saved_project_json
- end
-
- it 'has pipeline commits' do
- expect(saved_project_json['ci_pipelines']).not_to be_empty
- end
-
- it 'has ci pipeline notes' do
- expect(saved_project_json['ci_pipelines'].first['notes']).not_to be_empty
- end
-
- it 'has labels with no associations' do
- expect(saved_project_json['labels']).not_to be_empty
- end
-
- it 'has labels associated to records' do
- expect(saved_project_json['issues'].first['label_links'].first['label']).not_to be_empty
- end
-
- it 'has project and group labels' do
- label_types = saved_project_json['issues'].first['label_links'].map { |link| link['label']['type'] }
-
- expect(label_types).to match_array(%w(ProjectLabel GroupLabel))
- end
-
- it 'has priorities associated to labels' do
- priorities = saved_project_json['issues'].first['label_links'].flat_map { |link| link['label']['priorities'] }
-
- expect(priorities).not_to be_empty
- end
-
- it 'has issue resource label events' do
- expect(saved_project_json['issues'].first['resource_label_events']).not_to be_empty
- end
-
- it 'has merge request resource label events' do
- expect(saved_project_json['merge_requests'].first['resource_label_events']).not_to be_empty
- end
-
- it 'saves the correct service type' do
- expect(saved_project_json['services'].first['type']).to eq('CustomIssueTrackerService')
- end
-
- it 'saves the properties for a service' do
- expect(saved_project_json['services'].first['properties']).to eq('one' => 'value')
- end
-
- it 'has project feature' do
- project_feature = saved_project_json['project_feature']
- expect(project_feature).not_to be_empty
- expect(project_feature["issues_access_level"]).to eq(ProjectFeature::DISABLED)
- expect(project_feature["wiki_access_level"]).to eq(ProjectFeature::ENABLED)
- expect(project_feature["builds_access_level"]).to eq(ProjectFeature::PRIVATE)
- end
-
- it 'has custom attributes' do
- expect(saved_project_json['custom_attributes'].count).to eq(2)
- end
-
- it 'has badges' do
- expect(saved_project_json['project_badges'].count).to eq(2)
- end
-
- it 'does not complain about non UTF-8 characters in MR diff files' do
- ActiveRecord::Base.connection.execute("UPDATE merge_request_diff_files SET diff = '---\n- :diff: !binary |-\n LS0tIC9kZXYvbnVsbAorKysgYi9pbWFnZXMvbnVjb3IucGRmCkBAIC0wLDAg\n KzEsMTY3OSBAQAorJVBERi0xLjUNJeLjz9MNCisxIDAgb2JqDTw8L01ldGFk\n YXR'")
-
- expect(project_tree_saver.save).to be true
- end
-
- context 'group members' do
- let(:user2) { create(:user, email: 'group@member.com') }
- let(:member_emails) do
- saved_project_json['project_members'].map do |pm|
- pm['user']['email']
- end
- end
-
- before do
- Group.first.add_developer(user2)
- end
-
- it 'does not export group members if it has no permission' do
- Group.first.add_developer(user)
-
- expect(member_emails).not_to include('group@member.com')
- end
-
- it 'does not export group members as maintainer' do
- Group.first.add_maintainer(user)
-
- expect(member_emails).not_to include('group@member.com')
- end
-
- it 'exports group members as group owner' do
- Group.first.add_owner(user)
-
- expect(member_emails).to include('group@member.com')
- end
-
- context 'as admin' do
- let(:user) { create(:admin) }
-
- it 'exports group members as admin' do
- expect(member_emails).to include('group@member.com')
- end
-
- it 'exports group members as project members' do
- member_types = saved_project_json['project_members'].map { |pm| pm['source_type'] }
-
- expect(member_types).to all(eq('Project'))
- end
- end
- end
-
- context 'project attributes' do
- it 'does not contain the runners token' do
- expect(saved_project_json).not_to include("runners_token" => 'token')
- end
- end
-
- it 'has a board and a list' do
- expect(saved_project_json['boards'].first['lists']).not_to be_empty
- end
- end
- end
-
- def setup_project
- release = create(:release)
- group = create(:group)
-
- project = create(:project,
- :public,
- :repository,
- :issues_disabled,
- :wiki_enabled,
- :builds_private,
- description: 'description',
- releases: [release],
- group: group,
- approvals_before_merge: 1
- )
- allow(project).to receive(:commit).and_return(Commit.new(RepoHelpers.sample_commit, project))
-
- issue = create(:issue, assignees: [user], project: project)
- snippet = create(:project_snippet, project: project)
- project_label = create(:label, project: project)
- group_label = create(:group_label, group: group)
- create(:label_link, label: project_label, target: issue)
- create(:label_link, label: group_label, target: issue)
- create(:label_priority, label: group_label, priority: 1)
- milestone = create(:milestone, project: project)
- merge_request = create(:merge_request, source_project: project, milestone: milestone)
-
- ci_build = create(:ci_build, project: project, when: nil)
- ci_build.pipeline.update(project: project)
- create(:commit_status, project: project, pipeline: ci_build.pipeline)
-
- create(:milestone, project: project)
- create(:discussion_note, noteable: issue, project: project)
- create(:note, noteable: merge_request, project: project)
- create(:note, noteable: snippet, project: project)
- create(:note_on_commit,
- author: user,
- project: project,
- commit_id: ci_build.pipeline.sha)
-
- create(:resource_label_event, label: project_label, issue: issue)
- create(:resource_label_event, label: group_label, merge_request: merge_request)
-
- create(:event, :created, target: milestone, project: project, author: user)
- create(:service, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker', properties: { one: 'value' })
-
- create(:project_custom_attribute, project: project)
- create(:project_custom_attribute, project: project)
-
- create(:project_badge, project: project)
- create(:project_badge, project: project)
-
- board = create(:board, project: project, name: 'TestBoard')
- create(:list, board: board, position: 0, label: project_label)
-
- project
- end
-
- def project_json(filename)
- ::JSON.parse(IO.read(filename))
- end
-end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 653b011084e..55b907fff7c 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -283,6 +283,8 @@ MergeRequest::Metrics:
- commits_count
- first_approved_at
- first_reassigned_at
+- added_lines
+- removed_lines
Ci::Pipeline:
- id
- project_id
diff --git a/spec/lib/gitlab/repository_url_builder_spec.rb b/spec/lib/gitlab/repository_url_builder_spec.rb
new file mode 100644
index 00000000000..3d8870ecb53
--- /dev/null
+++ b/spec/lib/gitlab/repository_url_builder_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::RepositoryUrlBuilder do
+ describe '.build' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:factory, :path_generator) do
+ :project | ->(project) { project.full_path }
+ :project_snippet | ->(snippet) { "#{snippet.project.full_path}/snippets/#{snippet.id}" }
+ :project_wiki | ->(wiki) { "#{wiki.project.full_path}.wiki" }
+
+ :personal_snippet | ->(snippet) { "snippets/#{snippet.id}" }
+ end
+
+ with_them do
+ let(:container) { build_stubbed(factory) }
+ let(:repository) { container.repository }
+ let(:path) { path_generator.call(container) }
+ let(:url) { subject.build(repository.full_path, protocol: protocol) }
+
+ context 'when passing SSH protocol' do
+ let(:protocol) { :ssh }
+
+ it 'returns the SSH URL to the repository' do
+ expect(url).to eq("#{Gitlab.config.gitlab_shell.ssh_path_prefix}#{path}.git")
+ end
+ end
+
+ context 'when passing HTTP protocol' do
+ let(:protocol) { :http }
+
+ it 'returns the HTTP URL to the repo without a username' do
+ expect(url).to eq("#{Gitlab.config.gitlab.url}/#{path}.git")
+ expect(url).not_to include('@')
+ end
+
+ it 'includes the custom HTTP clone root if set' do
+ clone_root = 'https://git.example.com:51234/mygitlab'
+ stub_application_setting(custom_http_clone_url_root: clone_root)
+
+ expect(url).to eq("#{clone_root}/#{path}.git")
+ end
+ end
+
+ context 'when passing an unsupported protocol' do
+ let(:protocol) { :ftp }
+
+ it 'raises an exception' do
+ expect { url }.to raise_error(NotImplementedError)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb
index e4c33863ac2..1f515cffdbf 100644
--- a/spec/lib/gitlab/shell_spec.rb
+++ b/spec/lib/gitlab/shell_spec.rb
@@ -10,14 +10,6 @@ describe Gitlab::Shell do
it { is_expected.to respond_to :remove_repository }
- describe '.url_to_repo' do
- let(:full_path) { 'diaspora/disaspora-rails' }
-
- subject { described_class.url_to_repo(full_path) }
-
- it { is_expected.to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + full_path + '.git') }
- end
-
describe 'memoized secret_token' do
let(:secret_file) { 'tmp/tests/.secret_shell_test' }
let(:link_file) { 'tmp/tests/shell-secret-test/.gitlab_shell_secret' }
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index e922542a984..eeb2350359c 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe Member do
+ include ExclusiveLeaseHelpers
+
using RSpec::Parameterized::TableSyntax
describe "Associations" do
@@ -593,6 +595,9 @@ describe Member do
end
context 'when after_commit :update_highest_role' do
+ let!(:user) { create(:user) }
+ let(:user_id) { user.id }
+
where(:member_type, :source_type) do
:project_member | :project
:group_member | :group
@@ -600,43 +605,34 @@ describe Member do
with_them do
describe 'create member' do
- it 'initializes a new Members::UpdateHighestRoleService object' do
- source = create(source_type) # source owner initializes a new service object too
- user = create(:user)
+ let!(:source) { create(source_type) }
- expect(Members::UpdateHighestRoleService).to receive(:new).with(user.id).and_call_original
+ subject { create(member_type, :guest, user: user, source_type => source) }
- create(member_type, :guest, user: user, source_type => source)
- end
+ include_examples 'update highest role with exclusive lease'
end
context 'when member exists' do
- let!(:member) { create(member_type) }
+ let!(:member) { create(member_type, user: user) }
describe 'update member' do
context 'when access level was changed' do
- it 'initializes a new Members::UpdateHighestRoleService object' do
- expect(Members::UpdateHighestRoleService).to receive(:new).with(member.user_id).and_call_original
+ subject { member.update(access_level: Gitlab::Access::GUEST) }
- member.update(access_level: Gitlab::Access::GUEST)
- end
+ include_examples 'update highest role with exclusive lease'
end
context 'when access level was not changed' do
- it 'does not initialize a new Members::UpdateHighestRoleService object' do
- expect(Members::UpdateHighestRoleService).not_to receive(:new).with(member.user_id)
+ subject { member.update(notification_level: NotificationSetting.levels[:disabled]) }
- member.update(notification_level: NotificationSetting.levels[:disabled])
- end
+ include_examples 'does not update the highest role'
end
end
describe 'destroy member' do
- it 'initializes a new Members::UpdateHighestRoleService object' do
- expect(Members::UpdateHighestRoleService).to receive(:new).with(member.user_id).and_call_original
+ subject { member.destroy }
- member.destroy
- end
+ include_examples 'update highest role with exclusive lease'
end
end
end
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 9f5fd3a9495..1b121b7dee1 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -34,7 +34,7 @@ describe ProjectWiki do
describe "#url_to_repo" do
it "returns the correct ssh url to the repo" do
- expect(subject.url_to_repo).to eq(Gitlab::Shell.url_to_repo(subject.full_path))
+ expect(subject.url_to_repo).to eq(Gitlab::RepositoryUrlBuilder.build(subject.repository.full_path, protocol: :ssh))
end
end
@@ -45,27 +45,8 @@ describe ProjectWiki do
end
describe "#http_url_to_repo" do
- let(:project) { create :project }
-
- context 'when a custom HTTP clone URL root is not set' do
- it 'returns the full http url to the repo' do
- expected_url = "#{Gitlab.config.gitlab.url}/#{subject.full_path}.git"
-
- expect(project_wiki.http_url_to_repo).to eq(expected_url)
- expect(project_wiki.http_url_to_repo).not_to include('@')
- end
- end
-
- context 'when a custom HTTP clone URL root is set' do
- before do
- stub_application_setting(custom_http_clone_url_root: 'https://git.example.com:51234')
- end
-
- it 'returns the full http url to the repo, with the root replaced with the custom one' do
- expected_url = "https://git.example.com:51234/#{subject.full_path}.git"
-
- expect(project_wiki.http_url_to_repo).to eq(expected_url)
- end
+ it "returns the correct http url to the repo" do
+ expect(subject.http_url_to_repo).to eq(Gitlab::RepositoryUrlBuilder.build(subject.repository.full_path, protocol: :http))
end
end
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 9cced1f24ab..8c4d1951697 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -735,22 +735,6 @@ describe Snippet do
end
end
- describe '#url_to_repo' do
- subject { snippet.url_to_repo }
-
- context 'with personal snippet' do
- let(:snippet) { create(:personal_snippet) }
-
- it { is_expected.to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "snippets/#{snippet.id}.git") }
- end
-
- context 'with project snippet' do
- let(:snippet) { create(:project_snippet) }
-
- it { is_expected.to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "#{snippet.project.full_path}/snippets/#{snippet.id}.git") }
- end
- end
-
describe '#versioned_enabled_for?' do
let_it_be(:user) { create(:user) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 679f4a19f5b..5a3e16baa87 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
describe User, :do_not_mock_admin_mode do
include ProjectForksHelper
include TermsHelper
+ include ExclusiveLeaseHelpers
it_behaves_like 'having unique enum values'
@@ -4535,17 +4536,22 @@ describe User, :do_not_mock_admin_mode do
context 'when after_commit :update_highest_role' do
describe 'create user' do
- it 'initializes a new Members::UpdateHighestRoleService object' do
- expect_next_instance_of(Members::UpdateHighestRoleService) do |service|
- expect(service).to receive(:execute)
+ subject { create(:user) }
+
+ it 'schedules a job in the future', :aggregate_failures, :clean_gitlab_redis_shared_state do
+ allow_next_instance_of(Gitlab::ExclusiveLease) do |instance|
+ allow(instance).to receive(:try_obtain).and_return('uuid')
end
- create(:user)
+ expect(UpdateHighestRoleWorker).to receive(:perform_in).and_call_original
+
+ expect { subject }.to change(UpdateHighestRoleWorker.jobs, :size).by(1)
end
end
context 'when user already exists' do
let!(:user) { create(:user) }
+ let(:user_id) { user.id }
describe 'update user' do
using RSpec::Parameterized::TableSyntax
@@ -4560,24 +4566,24 @@ describe User, :do_not_mock_admin_mode do
with_them do
context 'when state was changed' do
- it 'initializes a new Members::UpdateHighestRoleService object' do
- expect_next_instance_of(Members::UpdateHighestRoleService) do |service|
- expect(service).to receive(:execute)
- end
+ subject { user.update(attributes) }
- user.update(attributes)
- end
+ include_examples 'update highest role with exclusive lease'
end
end
context 'when state was not changed' do
- it 'does not initialize a new Members::UpdateHighestRoleService object' do
- expect(Members::UpdateHighestRoleService).not_to receive(:new)
+ subject { user.update(email: 'newmail@example.com') }
- user.update(email: 'newmail@example.com')
- end
+ include_examples 'does not update the highest role'
end
end
+
+ describe 'destroy user' do
+ subject { user.destroy }
+
+ include_examples 'does not update the highest role'
+ end
end
end
diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb
index 31f8bcbfef0..40a0f09d1f3 100644
--- a/spec/serializers/merge_request_widget_entity_spec.rb
+++ b/spec/serializers/merge_request_widget_entity_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe MergeRequestWidgetEntity do
include ProjectForksHelper
- let(:project) { create :project, :repository }
+ let(:project) { create :project, :repository }
let(:resource) { create(:merge_request, source_project: project, target_project: project) }
- let(:user) { create(:user) }
+ let(:user) { create(:user) }
let(:request) { double('request', current_user: user, project: project) }
@@ -54,15 +54,17 @@ describe MergeRequestWidgetEntity do
end
describe 'merge_request_add_ci_config_path' do
+ let!(:project_auto_devops) { create(:project_auto_devops, :disabled, project: project) }
+
before do
project.add_role(user, role)
end
- context 'when there are pipelines' do
+ context 'when there is a standard ci config file in the source project' do
let(:role) { :developer }
before do
- create(:ci_empty_pipeline, project: project, sha: resource.all_commit_shas.first, ref: resource.source_branch)
+ project.repository.create_file(user, Gitlab::FileDetector::PATTERNS[:gitlab_ci], 'CONTENT', message: 'Add .gitlab-ci.yml', branch_name: 'master')
end
it 'no ci config path' do
@@ -70,7 +72,7 @@ describe MergeRequestWidgetEntity do
end
end
- context 'when there are no pipelines' do
+ context 'when there is no standard ci config file in the source project' do
context 'when user has permissions' do
let(:role) { :developer }
@@ -80,6 +82,16 @@ describe MergeRequestWidgetEntity do
expect(subject[:merge_request_add_ci_config_path]).to eq(expected_path)
end
+ context 'when auto devops is enabled' do
+ before do
+ project_auto_devops.enabled = true
+ end
+
+ it 'returns a blank ci config path' do
+ expect(subject[:merge_request_add_ci_config_path]).to be_nil
+ end
+ end
+
context 'when source project is missing' do
before do
resource.source_project = nil
diff --git a/spec/services/members/update_highest_role_service_spec.rb b/spec/services/members/update_highest_role_service_spec.rb
deleted file mode 100644
index 6fcb939203d..00000000000
--- a/spec/services/members/update_highest_role_service_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require 'sidekiq/testing'
-
-describe Members::UpdateHighestRoleService, :clean_gitlab_redis_shared_state do
- include ExclusiveLeaseHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:lease_key) { "update_highest_role:#{user.id}" }
- let(:service) { described_class.new(user.id) }
-
- describe '#perform' do
- subject { service.execute }
-
- context 'when lease is obtained' do
- it 'takes the lease but does not release it', :aggregate_failures do
- expect_to_obtain_exclusive_lease(lease_key, 'uuid', timeout: described_class::LEASE_TIMEOUT)
-
- subject
-
- expect(service.exclusive_lease.exists?).to be_truthy
- end
-
- it 'schedules a job in the future', :aggregate_failures do
- expect(UpdateHighestRoleWorker).to receive(:perform_in).with(described_class::DELAY, user.id).and_call_original
-
- Sidekiq::Testing.fake! do
- expect { subject }.to change(UpdateHighestRoleWorker.jobs, :size).by(1)
- end
- end
- end
-
- context 'when lease cannot be obtained' do
- it 'only schedules one job' do
- Sidekiq::Testing.fake! do
- stub_exclusive_lease_taken(lease_key, timeout: described_class::LEASE_TIMEOUT)
-
- expect { subject }.not_to change(UpdateHighestRoleWorker.jobs, :size)
- end
- end
- end
- end
-end
diff --git a/spec/services/projects/alerting/notify_service_spec.rb b/spec/services/projects/alerting/notify_service_spec.rb
index 289d812f498..f08ecd397ec 100644
--- a/spec/services/projects/alerting/notify_service_spec.rb
+++ b/spec/services/projects/alerting/notify_service_spec.rb
@@ -20,7 +20,7 @@ describe Projects::Alerting::NotifyService do
.exactly(amount).times
Sidekiq::Testing.inline! do
- expect(subject.status).to eq(:success)
+ expect(subject).to be_success
end
end
end
@@ -36,7 +36,7 @@ describe Projects::Alerting::NotifyService do
expect(notification_service)
.to receive_message_chain(:async, :prometheus_alerts_fired)
- expect(subject.status).to eq(:success)
+ expect(subject).to be_success
end
end
@@ -45,7 +45,7 @@ describe Projects::Alerting::NotifyService do
expect(IncidentManagement::ProcessAlertWorker)
.not_to receive(:perform_async)
- expect(subject.status).to eq(:success)
+ expect(subject).to be_success
end
end
@@ -54,7 +54,7 @@ describe Projects::Alerting::NotifyService do
expect(IncidentManagement::ProcessAlertWorker)
.not_to receive(:perform_async)
- expect(subject.status).to eq(:error)
+ expect(subject).to be_error
expect(subject.http_status).to eq(http_status)
end
end
@@ -102,7 +102,7 @@ describe Projects::Alerting::NotifyService do
.and_raise(Gitlab::Alerting::NotificationPayloadParser::BadPayloadError)
end
- it_behaves_like 'does not process incident issues due to error', http_status: 400
+ it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
end
end
@@ -114,13 +114,13 @@ describe Projects::Alerting::NotifyService do
end
context 'with invalid token' do
- it_behaves_like 'does not process incident issues due to error', http_status: 401
+ it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
end
context 'with deactivated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
- it_behaves_like 'does not process incident issues due to error', http_status: 403
+ it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
end
end
end
diff --git a/spec/services/projects/import_export/export_service_spec.rb b/spec/services/projects/import_export/export_service_spec.rb
index 1315ae26322..e00507d1827 100644
--- a/spec/services/projects/import_export/export_service_spec.rb
+++ b/spec/services/projects/import_export/export_service_spec.rb
@@ -26,28 +26,10 @@ describe Projects::ImportExport::ExportService do
service.execute
end
- context 'when :streaming_serializer feature is enabled' do
- before do
- stub_feature_flags(streaming_serializer: true)
- end
-
- it 'saves the models' do
- expect(Gitlab::ImportExport::Project::TreeSaver).to receive(:new).and_call_original
-
- service.execute
- end
- end
+ it 'saves the models' do
+ expect(Gitlab::ImportExport::Project::TreeSaver).to receive(:new).and_call_original
- context 'when :streaming_serializer feature is disabled' do
- before do
- stub_feature_flags(streaming_serializer: false)
- end
-
- it 'saves the models' do
- expect(Gitlab::ImportExport::Project::LegacyTreeSaver).to receive(:new).and_call_original
-
- service.execute
- end
+ service.execute
end
it 'saves the uploads' do
diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
index ce850e65329..dce96dda1e3 100644
--- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
@@ -30,7 +30,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
expect(notification_service)
.to receive_message_chain(:async, :prometheus_alerts_fired)
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
@@ -44,7 +44,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
.exactly(amount).times
Sidekiq::Testing.inline! do
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
end
@@ -54,7 +54,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
expect(IncidentManagement::ProcessPrometheusAlertWorker)
.not_to receive(:perform_async)
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
@@ -69,7 +69,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
expect(create_events_service)
.to receive(:execute)
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
@@ -78,7 +78,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
it_behaves_like 'persists events'
end
- shared_examples 'no notifications' do
+ shared_examples 'no notifications' do |http_status:|
let(:notification_service) { spy }
let(:create_events_service) { spy }
@@ -86,7 +86,8 @@ describe Projects::Prometheus::Alerts::NotifyService do
expect(notification_service).not_to receive(:async)
expect(create_events_service).not_to receive(:execute)
- expect(subject).to eq(false)
+ expect(subject).to be_error
+ expect(subject.http_status).to eq(http_status)
end
end
@@ -130,7 +131,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
when :success
it_behaves_like 'notifies alerts'
when :failure
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unauthorized
else
raise "invalid result: #{result.inspect}"
end
@@ -140,7 +141,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'without project specific cluster' do
let!(:cluster) { create(:cluster, enabled: true) }
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unauthorized
end
context 'with manual prometheus installation' do
@@ -171,7 +172,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
when :success
it_behaves_like 'notifies alerts'
when :failure
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unauthorized
else
raise "invalid result: #{result.inspect}"
end
@@ -193,7 +194,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
expect_any_instance_of(NotificationService)
.not_to receive(:async)
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
@@ -211,7 +212,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
it 'does not send notification' do
expect(NotificationService).not_to receive(:new)
- expect(subject).to eq(true)
+ expect(subject).to be_success
end
end
end
@@ -260,19 +261,19 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'without version' do
let(:payload) { {} }
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unprocessable_entity
end
context 'when version is not "4"' do
let(:payload) { { 'version' => '5' } }
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unprocessable_entity
end
context 'with missing alerts' do
let(:payload) { { 'version' => '4' } }
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :unauthorized
end
context 'when the payload is too big' do
@@ -283,7 +284,7 @@ describe Projects::Prometheus::Alerts::NotifyService do
allow(Gitlab::Utils::DeepSize).to receive(:new).and_return(deep_size_object)
end
- it_behaves_like 'no notifications'
+ it_behaves_like 'no notifications', http_status: :bad_request
it 'does not process issues' do
expect(IncidentManagement::ProcessPrometheusAlertWorker)
diff --git a/spec/support/shared_examples/models/update_highest_role_shared_examples.rb b/spec/support/shared_examples/models/update_highest_role_shared_examples.rb
new file mode 100644
index 00000000000..34c4ada1718
--- /dev/null
+++ b/spec/support/shared_examples/models/update_highest_role_shared_examples.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+# requires a subject and a user_id
+RSpec.shared_examples 'update highest role with exclusive lease' do
+ include ExclusiveLeaseHelpers
+
+ let(:lease_key) { "update_highest_role:#{user_id}" }
+
+ before do
+ allow(Gitlab::ExclusiveLease).to receive(:new).and_call_original
+ end
+
+ context 'when lease is obtained', :clean_gitlab_redis_shared_state do
+ it 'takes the lease but does not release it', :aggregate_failures do
+ expect_to_obtain_exclusive_lease(lease_key, 'uuid', timeout: described_class::HIGHEST_ROLE_LEASE_TIMEOUT)
+ expect(Gitlab::ExclusiveLease).not_to receive(:cancel).with(lease_key, 'uuid')
+
+ subject
+ end
+
+ it 'schedules a job in the future', :aggregate_failures do
+ allow_next_instance_of(Gitlab::ExclusiveLease) do |instance|
+ allow(instance).to receive(:try_obtain).and_return('uuid')
+ end
+
+ expect(UpdateHighestRoleWorker).to receive(:perform_in).with(described_class::HIGHEST_ROLE_JOB_DELAY, user_id).and_call_original
+
+ expect { subject }.to change(UpdateHighestRoleWorker.jobs, :size).by(1)
+ end
+ end
+
+ context 'when lease cannot be obtained', :clean_gitlab_redis_shared_state do
+ it 'only schedules one job' do
+ stub_exclusive_lease_taken(lease_key, timeout: described_class::HIGHEST_ROLE_LEASE_TIMEOUT)
+
+ expect { subject }.not_to change(UpdateHighestRoleWorker.jobs, :size)
+ end
+ end
+end
+
+# requires a subject and a user_id
+RSpec.shared_examples 'does not update the highest role' do
+ it 'does not obtain an exclusive lease' do
+ allow(Gitlab::ExclusiveLease).to receive(:new).and_call_original
+
+ lease = stub_exclusive_lease("update_highest_role:#{user_id}", 'uuid', timeout: described_class::HIGHEST_ROLE_LEASE_TIMEOUT)
+
+ expect(lease).not_to receive(:try_obtain)
+
+ subject
+ end
+end
diff --git a/spec/support/shared_examples/models/versioned_description_shared_examples.rb b/spec/support/shared_examples/models/versioned_description_shared_examples.rb
index 59124af19ec..8fee2494af7 100644
--- a/spec/support/shared_examples/models/versioned_description_shared_examples.rb
+++ b/spec/support/shared_examples/models/versioned_description_shared_examples.rb
@@ -9,54 +9,36 @@ RSpec.shared_examples 'versioned description' do
let(:factory_name) { described_class.name.underscore.to_sym }
let!(:model) { create(factory_name, description: 'Original description') }
- context 'when feature is enabled' do
+ context 'when description was changed' do
before do
- stub_feature_flags(save_description_versions: true)
+ model.update!(description: 'New description')
end
- context 'when description was changed' do
- before do
- model.update!(description: 'New description')
- end
-
- it 'saves the old and new description for the first update' do
- expect(model.description_versions.first.description).to eq('Original description')
- expect(model.description_versions.last.description).to eq('New description')
- end
-
- it 'only saves the new description for subsequent updates' do
- expect { model.update!(description: 'Another description') }.to change { model.description_versions.count }.by(1)
-
- expect(model.description_versions.last.description).to eq('Another description')
- end
+ it 'saves the old and new description for the first update' do
+ expect(model.description_versions.first.description).to eq('Original description')
+ expect(model.description_versions.last.description).to eq('New description')
+ end
- it 'sets the new description version to `saved_description_version`' do
- expect(model.saved_description_version).to eq(model.description_versions.last)
- end
+ it 'only saves the new description for subsequent updates' do
+ expect { model.update!(description: 'Another description') }.to change { model.description_versions.count }.by(1)
- it 'clears `saved_description_version` after another save that does not change description' do
- model.save!
+ expect(model.description_versions.last.description).to eq('Another description')
+ end
- expect(model.saved_description_version).to be_nil
- end
+ it 'sets the new description version to `saved_description_version`' do
+ expect(model.saved_description_version).to eq(model.description_versions.last)
end
- context 'when description was not changed' do
- it 'does not save any description version' do
- expect { model.save! }.not_to change { model.description_versions.count }
+ it 'clears `saved_description_version` after another save that does not change description' do
+ model.save!
- expect(model.saved_description_version).to be_nil
- end
+ expect(model.saved_description_version).to be_nil
end
end
- context 'when feature is disabled' do
- before do
- stub_feature_flags(save_description_versions: false)
- end
-
+ context 'when description was not changed' do
it 'does not save any description version' do
- expect { model.update!(description: 'New description') }.not_to change { model.description_versions.count }
+ expect { model.save! }.not_to change { model.description_versions.count }
expect(model.saved_description_version).to be_nil
end