summaryrefslogtreecommitdiff
path: root/spec/models
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models')
-rw-r--r--spec/models/application_setting_spec.rb36
-rw-r--r--spec/models/ci/build_spec.rb6
-rw-r--r--spec/models/ci/build_trace_chunk_spec.rb12
-rw-r--r--spec/models/clusters/applications/ingress_spec.rb1
-rw-r--r--spec/models/clusters/applications/jupyter_spec.rb1
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb1
-rw-r--r--spec/models/clusters/applications/runner_spec.rb1
-rw-r--r--spec/models/commit_spec.rb31
-rw-r--r--spec/models/concerns/reactive_caching_spec.rb11
-rw-r--r--spec/models/concerns/resolvable_discussion_spec.rb13
-rw-r--r--spec/models/concerns/sortable_spec.rb18
-rw-r--r--spec/models/hooks/web_hook_log_spec.rb18
-rw-r--r--spec/models/merge_request_diff_spec.rb46
-rw-r--r--spec/models/merge_request_spec.rb105
-rw-r--r--spec/models/namespace_spec.rb13
-rw-r--r--spec/models/note_spec.rb10
-rw-r--r--spec/models/project_services/bamboo_service_spec.rb22
-rw-r--r--spec/models/project_spec.rb20
-rw-r--r--spec/models/repository_spec.rb288
19 files changed, 381 insertions, 272 deletions
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 3e6656e0f12..02f74e2ea54 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -25,15 +25,6 @@ describe ApplicationSetting do
it { is_expected.to allow_value(https).for(:after_sign_out_path) }
it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
- describe 'disabled_oauth_sign_in_sources validations' do
- before do
- allow(Devise).to receive(:omniauth_providers).and_return([:github])
- end
-
- it { is_expected.to allow_value(['github']).for(:disabled_oauth_sign_in_sources) }
- it { is_expected.not_to allow_value(['test']).for(:disabled_oauth_sign_in_sources) }
- end
-
describe 'default_artifacts_expire_in' do
it 'sets an error if it cannot parse' do
setting.update(default_artifacts_expire_in: 'a')
@@ -314,6 +305,33 @@ describe ApplicationSetting do
end
end
+ describe '#disabled_oauth_sign_in_sources=' do
+ before do
+ allow(Devise).to receive(:omniauth_providers).and_return([:github])
+ end
+
+ it 'removes unknown sources (as strings) from the array' do
+ subject.disabled_oauth_sign_in_sources = %w[github test]
+
+ expect(subject).to be_valid
+ expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
+ end
+
+ it 'removes unknown sources (as symbols) from the array' do
+ subject.disabled_oauth_sign_in_sources = %i[github test]
+
+ expect(subject).to be_valid
+ expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
+ end
+
+ it 'ignores nil' do
+ subject.disabled_oauth_sign_in_sources = nil
+
+ expect(subject).to be_valid
+ expect(subject.disabled_oauth_sign_in_sources).to be_empty
+ end
+ end
+
context 'restricted signup domains' do
it 'sets single domain' do
setting.domain_whitelist_raw = 'example.com'
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 51b9b518117..6758adc59eb 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1871,7 +1871,11 @@ describe Ci::Build do
end
context 'when yaml_variables are undefined' do
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:pipeline) do
+ create(:ci_pipeline, project: project,
+ sha: project.commit.id,
+ ref: project.default_branch)
+ end
before do
build.yaml_variables = nil
diff --git a/spec/models/ci/build_trace_chunk_spec.rb b/spec/models/ci/build_trace_chunk_spec.rb
index b5a6d959ccb..464897de306 100644
--- a/spec/models/ci/build_trace_chunk_spec.rb
+++ b/spec/models/ci/build_trace_chunk_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
+ include ExclusiveLeaseHelpers
+
set(:build) { create(:ci_build, :running) }
let(:chunk_index) { 0 }
let(:data_store) { :redis }
@@ -125,14 +127,6 @@ describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
end
end
end
-
- context 'when data_store is others' do
- before do
- build_trace_chunk.send(:write_attribute, :data_store, -1)
- end
-
- it { expect { subject }.to raise_error('Unsupported data store') }
- end
end
describe '#truncate' do
@@ -330,7 +324,7 @@ describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state do
describe 'ExclusiveLock' do
before do
- allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) { nil }
+ stub_exclusive_lease_taken
stub_const('Ci::BuildTraceChunk::WRITE_LOCK_RETRY', 1)
end
diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb
index a47a07d908d..bb5b2ef3a47 100644
--- a/spec/models/clusters/applications/ingress_spec.rb
+++ b/spec/models/clusters/applications/ingress_spec.rb
@@ -73,6 +73,7 @@ describe Clusters::Applications::Ingress do
it 'should be initialized with ingress arguments' do
expect(subject.name).to eq('ingress')
expect(subject.chart).to eq('stable/nginx-ingress')
+ expect(subject.version).to be_nil
expect(subject.values).to eq(ingress.values)
end
end
diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb
index ca48a1d8072..65750141e65 100644
--- a/spec/models/clusters/applications/jupyter_spec.rb
+++ b/spec/models/clusters/applications/jupyter_spec.rb
@@ -36,6 +36,7 @@ describe Clusters::Applications::Jupyter do
it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('jupyter')
expect(subject.chart).to eq('jupyter/jupyterhub')
+ expect(subject.version).to be_nil
expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/')
expect(subject.values).to eq(jupyter.values)
end
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index d2302583ac8..efd57040005 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -109,6 +109,7 @@ describe Clusters::Applications::Prometheus do
it 'should be initialized with 3 arguments' do
expect(subject.name).to eq('prometheus')
expect(subject.chart).to eq('stable/prometheus')
+ expect(subject.version).to eq('6.7.3')
expect(subject.values).to eq(prometheus.values)
end
end
diff --git a/spec/models/clusters/applications/runner_spec.rb b/spec/models/clusters/applications/runner_spec.rb
index 3ef59457c5f..b12500d0acd 100644
--- a/spec/models/clusters/applications/runner_spec.rb
+++ b/spec/models/clusters/applications/runner_spec.rb
@@ -31,6 +31,7 @@ describe Clusters::Applications::Runner do
it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner')
+ expect(subject.version).to be_nil
expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.values).to eq(gitlab_runner.values)
end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 090f91168ad..5157d8fc645 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -514,30 +514,21 @@ eos
end
describe '#uri_type' do
- shared_examples 'URI type' do
- it 'returns the URI type at the given path' do
- expect(commit.uri_type('files/html')).to be(:tree)
- expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
- expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw)
- expect(commit.uri_type('files/js/application.js')).to be(:blob)
- end
-
- it "returns nil if the path doesn't exists" do
- expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
- end
-
- it 'is nil if the path is nil or empty' do
- expect(commit.uri_type(nil)).to be_nil
- expect(commit.uri_type("")).to be_nil
- end
+ it 'returns the URI type at the given path' do
+ expect(commit.uri_type('files/html')).to be(:tree)
+ expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
+ expect(project.commit('video').uri_type('files/videos/intro.mp4')).to be(:raw)
+ expect(commit.uri_type('files/js/application.js')).to be(:blob)
end
- context 'when Gitaly commit_tree_entry feature is enabled' do
- it_behaves_like 'URI type'
+ it "returns nil if the path doesn't exists" do
+ expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
+ expect(commit.uri_type('../path/doesnt/exist')).to be_nil
end
- context 'when Gitaly commit_tree_entry feature is disabled', :disable_gitaly do
- it_behaves_like 'URI type'
+ it 'is nil if the path is nil or empty' do
+ expect(commit.uri_type(nil)).to be_nil
+ expect(commit.uri_type("")).to be_nil
end
end
diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb
index f2a3df50c1a..0f156619e9e 100644
--- a/spec/models/concerns/reactive_caching_spec.rb
+++ b/spec/models/concerns/reactive_caching_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe ReactiveCaching, :use_clean_rails_memory_store_caching do
+ include ExclusiveLeaseHelpers
include ReactiveCachingHelpers
class CacheTest
@@ -106,8 +107,8 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
end
it 'takes and releases the lease' do
- expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return("000000")
- expect(Gitlab::ExclusiveLease).to receive(:cancel).with(cache_key, "000000")
+ expect_to_obtain_exclusive_lease(cache_key, 'uuid')
+ expect_to_cancel_exclusive_lease(cache_key, 'uuid')
go!
end
@@ -153,11 +154,9 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
end
context 'when the lease is already taken' do
- before do
- expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return(nil)
- end
-
it 'skips the calculation' do
+ stub_exclusive_lease_taken(cache_key)
+
expect(instance).to receive(:calculate_reactive_cache).never
go!
diff --git a/spec/models/concerns/resolvable_discussion_spec.rb b/spec/models/concerns/resolvable_discussion_spec.rb
index 2a2ef5a304d..2f9f63ce7e0 100644
--- a/spec/models/concerns/resolvable_discussion_spec.rb
+++ b/spec/models/concerns/resolvable_discussion_spec.rb
@@ -534,11 +534,18 @@ describe Discussion, ResolvableDiscussion do
describe "#last_resolved_note" do
let(:current_user) { create(:user) }
+ let(:time) { Time.now.utc }
before do
- first_note.resolve!(current_user)
- third_note.resolve!(current_user)
- second_note.resolve!(current_user)
+ Timecop.freeze(time - 1.second) do
+ first_note.resolve!(current_user)
+ end
+ Timecop.freeze(time) do
+ third_note.resolve!(current_user)
+ end
+ Timecop.freeze(time + 1.second) do
+ second_note.resolve!(current_user)
+ end
end
it "returns the last note that was resolved" do
diff --git a/spec/models/concerns/sortable_spec.rb b/spec/models/concerns/sortable_spec.rb
index b821a84d5e0..39c16ae60af 100644
--- a/spec/models/concerns/sortable_spec.rb
+++ b/spec/models/concerns/sortable_spec.rb
@@ -40,15 +40,25 @@ describe Sortable do
describe 'ordering by name' do
it 'ascending' do
- expect(relation).to receive(:reorder).with("lower(name) asc")
+ expect(relation).to receive(:reorder).once.and_call_original
- relation.order_by('name_asc')
+ table = Regexp.escape(ActiveRecord::Base.connection.quote_table_name(:namespaces))
+ column = Regexp.escape(ActiveRecord::Base.connection.quote_column_name(:name))
+
+ sql = relation.order_by('name_asc').to_sql
+
+ expect(sql).to match /.+ORDER BY LOWER\(#{table}.#{column}\) ASC\z/
end
it 'descending' do
- expect(relation).to receive(:reorder).with("lower(name) desc")
+ expect(relation).to receive(:reorder).once.and_call_original
+
+ table = Regexp.escape(ActiveRecord::Base.connection.quote_table_name(:namespaces))
+ column = Regexp.escape(ActiveRecord::Base.connection.quote_column_name(:name))
+
+ sql = relation.order_by('name_desc').to_sql
- relation.order_by('name_desc')
+ expect(sql).to match /.+ORDER BY LOWER\(#{table}.#{column}\) DESC\z/
end
end
diff --git a/spec/models/hooks/web_hook_log_spec.rb b/spec/models/hooks/web_hook_log_spec.rb
index 19bc88b1333..744a6ccae8b 100644
--- a/spec/models/hooks/web_hook_log_spec.rb
+++ b/spec/models/hooks/web_hook_log_spec.rb
@@ -9,6 +9,24 @@ describe WebHookLog do
it { is_expected.to validate_presence_of(:web_hook) }
+ describe '.recent' do
+ let(:hook) { create(:project_hook) }
+
+ it 'does not return web hook logs that are too old' do
+ create(:web_hook_log, web_hook: hook, created_at: 91.days.ago)
+
+ expect(described_class.recent.size).to be_zero
+ end
+
+ it 'returns the web hook logs in descending order' do
+ hook1 = create(:web_hook_log, web_hook: hook, created_at: 2.hours.ago)
+ hook2 = create(:web_hook_log, web_hook: hook, created_at: 1.hour.ago)
+ hooks = described_class.recent.to_a
+
+ expect(hooks).to eq([hook2, hook1])
+ end
+ end
+
describe '#success?' do
let(:web_hook_log) { build(:web_hook_log, response_status: status) }
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index b4249d72fc8..ccc3ff861c5 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -47,6 +47,45 @@ describe MergeRequestDiff do
end
describe '#diffs' do
+ let(:merge_request) { create(:merge_request, :with_diffs) }
+ let!(:diff) { merge_request.merge_request_diff.reload }
+
+ context 'when it was not cleaned by the system' do
+ it 'returns persisted diffs' do
+ expect(diff).to receive(:load_diffs)
+
+ diff.diffs
+ end
+ end
+
+ context 'when diff was cleaned by the system' do
+ before do
+ diff.clean!
+ end
+
+ it 'returns diffs from repository if can compare with current diff refs' do
+ expect(diff).not_to receive(:load_diffs)
+
+ expect(Compare)
+ .to receive(:new)
+ .with(instance_of(Gitlab::Git::Compare), merge_request.target_project,
+ base_sha: diff.base_commit_sha, straight: false)
+ .and_call_original
+
+ diff.diffs
+ end
+
+ it 'returns persisted diffs if cannot compare with diff refs' do
+ expect(diff).to receive(:load_diffs)
+
+ diff.update!(head_commit_sha: 'invalid-sha')
+
+ diff.diffs
+ end
+ end
+ end
+
+ describe '#raw_diffs' do
context 'when the :ignore_whitespace_change option is set' do
it 'creates a new compare object instead of loading from the DB' do
expect(diff_with_commits).not_to receive(:load_diffs)
@@ -114,6 +153,13 @@ describe MergeRequestDiff do
expect(mr_diff.empty?).to be_truthy
end
+ it 'expands collapsed diffs before saving' do
+ mr_diff = create(:merge_request, source_branch: 'expand-collapse-lines', target_branch: 'master').merge_request_diff
+ diff_file = mr_diff.merge_request_diff_files.find_by(new_path: 'expand-collapse/file-5.txt')
+
+ expect(diff_file.diff).not_to be_empty
+ end
+
it 'saves binary diffs correctly' do
path = 'files/images/icn-time-tracking.pdf'
mr_diff = create(:merge_request, source_branch: 'add-pdf-text-binary', target_branch: 'master').merge_request_diff
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 3f028b3bd5c..8c6b411ec9a 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1324,6 +1324,7 @@ describe MergeRequest do
context 'when broken' do
before do
allow(subject).to receive(:broken?) { true }
+ allow(project.repository).to receive(:can_be_merged?).and_return(false)
end
it 'becomes unmergeable' do
@@ -1629,28 +1630,17 @@ describe MergeRequest do
end
describe "#reload_diff" do
- let(:discussion) { create(:diff_note_on_merge_request, project: subject.project, noteable: subject).to_discussion }
- let(:commit) { subject.project.commit(sample_commit.id) }
-
- it "does not change existing merge request diff" do
- expect(subject.merge_request_diff).not_to receive(:save_git_content)
- subject.reload_diff
- end
-
- it "creates new merge request diff" do
- expect { subject.reload_diff }.to change { subject.merge_request_diffs.count }.by(1)
- end
-
- it "executes diff cache service" do
- expect_any_instance_of(MergeRequests::MergeRequestDiffCacheService).to receive(:execute).with(subject, an_instance_of(MergeRequestDiff))
+ it 'calls MergeRequests::ReloadDiffsService#execute with correct params' do
+ user = create(:user)
+ service = instance_double(MergeRequests::ReloadDiffsService, execute: nil)
- subject.reload_diff
- end
+ expect(MergeRequests::ReloadDiffsService)
+ .to receive(:new).with(subject, user)
+ .and_return(service)
- it "calls update_diff_discussion_positions" do
- expect(subject).to receive(:update_diff_discussion_positions)
+ subject.reload_diff(user)
- subject.reload_diff
+ expect(service).to have_received(:execute)
end
context 'when using the after_update hook to update' do
@@ -2144,32 +2134,77 @@ describe MergeRequest do
describe 'transition to cannot_be_merged' do
let(:notification_service) { double(:notification_service) }
let(:todo_service) { double(:todo_service) }
-
- subject { create(:merge_request, merge_status: :unchecked) }
+ subject { create(:merge_request, state, merge_status: :unchecked) }
before do
allow(NotificationService).to receive(:new).and_return(notification_service)
allow(TodoService).to receive(:new).and_return(todo_service)
+
+ allow(subject.project.repository).to receive(:can_be_merged?).and_return(false)
+ end
+
+ [:opened, :locked].each do |state|
+ context state do
+ let(:state) { state }
+
+ it 'notifies conflict, but does not notify again if rechecking still results in cannot_be_merged' do
+ expect(notification_service).to receive(:merge_request_unmergeable).with(subject).once
+ expect(todo_service).to receive(:merge_request_became_unmergeable).with(subject).once
+
+ subject.mark_as_unmergeable
+ subject.mark_as_unchecked
+ subject.mark_as_unmergeable
+ end
+
+ it 'notifies conflict, whenever newly unmergeable' do
+ expect(notification_service).to receive(:merge_request_unmergeable).with(subject).twice
+ expect(todo_service).to receive(:merge_request_became_unmergeable).with(subject).twice
+
+ subject.mark_as_unmergeable
+ subject.mark_as_unchecked
+ subject.mark_as_mergeable
+ subject.mark_as_unchecked
+ subject.mark_as_unmergeable
+ end
+
+ it 'does not notify whenever merge request is newly unmergeable due to other reasons' do
+ allow(subject.project.repository).to receive(:can_be_merged?).and_return(true)
+
+ expect(notification_service).not_to receive(:merge_request_unmergeable)
+ expect(todo_service).not_to receive(:merge_request_became_unmergeable)
+
+ subject.mark_as_unmergeable
+ end
+ end
end
- it 'notifies, but does not notify again if rechecking still results in cannot_be_merged' do
- expect(notification_service).to receive(:merge_request_unmergeable).with(subject).once
- expect(todo_service).to receive(:merge_request_became_unmergeable).with(subject).once
+ [:closed, :merged].each do |state|
+ let(:state) { state }
- subject.mark_as_unmergeable
- subject.mark_as_unchecked
- subject.mark_as_unmergeable
+ context state do
+ it 'does not notify' do
+ expect(notification_service).not_to receive(:merge_request_unmergeable)
+ expect(todo_service).not_to receive(:merge_request_became_unmergeable)
+
+ subject.mark_as_unmergeable
+ end
+ end
end
- it 'notifies whenever merge request is newly unmergeable' do
- expect(notification_service).to receive(:merge_request_unmergeable).with(subject).twice
- expect(todo_service).to receive(:merge_request_became_unmergeable).with(subject).twice
+ context 'source branch is missing' do
+ subject { create(:merge_request, :invalid, :opened, merge_status: :unchecked, target_branch: 'master') }
+
+ before do
+ allow(subject.project.repository).to receive(:can_be_merged?).and_call_original
+ end
- subject.mark_as_unmergeable
- subject.mark_as_unchecked
- subject.mark_as_mergeable
- subject.mark_as_unchecked
- subject.mark_as_unmergeable
+ it 'does not raise error' do
+ expect(notification_service).not_to receive(:merge_request_unmergeable)
+ expect(todo_service).not_to receive(:merge_request_became_unmergeable)
+
+ expect { subject.mark_as_unmergeable }.not_to raise_error
+ expect(subject.cannot_be_merged?).to eq(true)
+ end
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 18b01c3e6b7..70f1a1c8b38 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -655,6 +655,19 @@ describe Namespace do
end
end
+ describe '#root_ancestor' do
+ it 'returns the top most ancestor', :nested_groups do
+ root_group = create(:group)
+ nested_group = create(:group, parent: root_group)
+ deep_nested_group = create(:group, parent: nested_group)
+ very_deep_nested_group = create(:group, parent: deep_nested_group)
+
+ expect(nested_group.root_ancestor).to eq(root_group)
+ expect(deep_nested_group.root_ancestor).to eq(root_group)
+ expect(very_deep_nested_group.root_ancestor).to eq(root_group)
+ end
+ end
+
describe '#remove_exports' do
let(:legacy_project) { create(:project, :with_export, :legacy_storage, namespace: namespace) }
let(:hashed_project) { create(:project, :with_export, namespace: namespace) }
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 6a6c71e6c82..a2cb716cb93 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -828,5 +828,15 @@ describe Note do
note.destroy!
end
+
+ context 'when issuable etag caching is disabled' do
+ it 'does not store cache key' do
+ allow(note.noteable).to receive(:etag_caching_enabled?).and_return(false)
+
+ expect_any_instance_of(Gitlab::EtagCaching::Store).not_to receive(:touch)
+
+ note.save!
+ end
+ end
end
end
diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb
index 85baaccf035..f4f7afb1b92 100644
--- a/spec/models/project_services/bamboo_service_spec.rb
+++ b/spec/models/project_services/bamboo_service_spec.rb
@@ -120,6 +120,14 @@ describe BambooService, :use_clean_rails_memory_store_caching do
end
end
+ describe '#execute' do
+ it 'runs update and build action' do
+ stub_update_and_build_request
+
+ subject.execute(Gitlab::DataBuilder::Push::SAMPLE_DATA)
+ end
+ end
+
describe '#build_page' do
it 'returns the contents of the reactive cache' do
stub_reactive_cache(service, { build_page: 'foo' }, 'sha', 'ref')
@@ -216,10 +224,20 @@ describe BambooService, :use_clean_rails_memory_store_caching do
end
end
+ def stub_update_and_build_request(status: 200, body: nil)
+ bamboo_full_url = 'http://gitlab.com/bamboo/updateAndBuild.action?buildKey=foo&os_authType=basic'
+
+ stub_bamboo_request(bamboo_full_url, status, body)
+ end
+
def stub_request(status: 200, body: nil)
- bamboo_full_url = 'http://gitlab.com/bamboo/rest/api/latest/result?label=123&os_authType=basic'
+ bamboo_full_url = 'http://gitlab.com/bamboo/rest/api/latest/result/byChangeset/123?os_authType=basic'
+
+ stub_bamboo_request(bamboo_full_url, status, body)
+ end
- WebMock.stub_request(:get, bamboo_full_url).to_return(
+ def stub_bamboo_request(url, status, body)
+ WebMock.stub_request(:get, url).to_return(
status: status,
headers: { 'Content-Type' => 'application/json' },
body: body
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index bc9cce6b0c3..abdc65336ca 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -571,13 +571,13 @@ describe Project do
last_activity_at: timestamp,
last_repository_updated_at: timestamp - 1.hour)
- expect(project.last_activity_date).to eq(timestamp)
+ expect(project.last_activity_date).to be_like_time(timestamp)
project.update_attributes(updated_at: timestamp,
last_activity_at: timestamp - 1.hour,
last_repository_updated_at: nil)
- expect(project.last_activity_date).to eq(timestamp)
+ expect(project.last_activity_date).to be_like_time(timestamp)
end
end
end
@@ -2339,6 +2339,22 @@ describe Project do
end
end
+ describe '#any_lfs_file_locks?', :request_store do
+ set(:project) { create(:project) }
+
+ it 'returns false when there are no LFS file locks' do
+ expect(project.any_lfs_file_locks?).to be_falsey
+ end
+
+ it 'returns a cached true when there are LFS file locks' do
+ create(:lfs_file_lock, project: project)
+
+ expect(project.lfs_file_locks).to receive(:any?).once.and_call_original
+
+ 2.times { expect(project.any_lfs_file_locks?).to be_truthy }
+ end
+ end
+
describe '#protected_for?' do
let(:project) { create(:project) }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index b6df048d4ca..d060ab923d1 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -46,7 +46,7 @@ describe Repository do
it { is_expected.not_to include('feature') }
it { is_expected.not_to include('fix') }
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error do
broken_repository.branch_names_contains(sample_commit.id)
@@ -192,7 +192,7 @@ describe Repository do
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error do
broken_repository.last_commit_id_for_path(sample_commit.id, '.gitignore')
@@ -226,7 +226,7 @@ describe Repository do
is_expected.to eq('c1acaa5')
end
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error do
broken_repository.last_commit_for_path(sample_commit.id, '.gitignore').id
@@ -391,7 +391,7 @@ describe Repository do
it_behaves_like 'finding commits by message'
end
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error { broken_repository.find_commits_by_message('s') }
end
@@ -434,44 +434,34 @@ describe Repository do
end
describe '#can_be_merged?' do
- shared_examples 'can be merged' do
- context 'mergeable branches' do
- subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') }
+ context 'mergeable branches' do
+ subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') }
- it { is_expected.to be_truthy }
- end
-
- context 'non-mergeable branches without conflict sides missing' do
- subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') }
-
- it { is_expected.to be_falsey }
- end
+ it { is_expected.to be_truthy }
+ end
- context 'non-mergeable branches with conflict sides missing' do
- subject { repository.can_be_merged?('conflict-missing-side', 'conflict-start') }
+ context 'non-mergeable branches without conflict sides missing' do
+ subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') }
- it { is_expected.to be_falsey }
- end
+ it { is_expected.to be_falsey }
+ end
- context 'non merged branch' do
- subject { repository.merged_to_root_ref?('fix') }
+ context 'non-mergeable branches with conflict sides missing' do
+ subject { repository.can_be_merged?('conflict-missing-side', 'conflict-start') }
- it { is_expected.to be_falsey }
- end
+ it { is_expected.to be_falsey }
+ end
- context 'non existent branch' do
- subject { repository.merged_to_root_ref?('non_existent_branch') }
+ context 'non merged branch' do
+ subject { repository.merged_to_root_ref?('fix') }
- it { is_expected.to be_nil }
- end
+ it { is_expected.to be_falsey }
end
- context 'when Gitaly can_be_merged feature is enabled' do
- it_behaves_like 'can be merged'
- end
+ context 'non existent branch' do
+ subject { repository.merged_to_root_ref?('non_existent_branch') }
- context 'when Gitaly can_be_merged feature is disabled', :disable_gitaly do
- it_behaves_like 'can be merged'
+ it { is_expected.to be_nil }
end
end
@@ -489,6 +479,14 @@ describe Repository do
end
end
+ context 'when ref is not specified' do
+ it 'is using a root ref' do
+ expect(repository).to receive(:find_commit).with('master')
+
+ repository.commit
+ end
+ end
+
context 'when ref is not valid' do
context 'when preceding tree element exists' do
it 'returns nil' do
@@ -674,7 +672,7 @@ describe Repository do
end
end
- shared_examples "search_files_by_content" do
+ describe "search_files_by_content" do
let(:results) { repository.search_files_by_content('feature', 'master') }
subject { results }
@@ -705,7 +703,7 @@ describe Repository do
expect(results).to match_array([])
end
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error do
broken_repository.search_files_by_content('feature', 'master')
@@ -721,7 +719,7 @@ describe Repository do
end
end
- shared_examples "search_files_by_name" do
+ describe "search_files_by_name" do
let(:results) { repository.search_files_by_name('files', 'master') }
it 'returns result' do
@@ -754,23 +752,13 @@ describe Repository do
expect(results).to match_array([])
end
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error { broken_repository.search_files_by_name('files', 'master') }
end
end
end
- describe 'with gitaly enabled' do
- it_behaves_like 'search_files_by_content'
- it_behaves_like 'search_files_by_name'
- end
-
- describe 'with gitaly disabled', :disable_gitaly do
- it_behaves_like 'search_files_by_content'
- it_behaves_like 'search_files_by_name'
- end
-
describe '#async_remove_remote' do
before do
masterrev = repository.find_branch('master').dereferenced_target
@@ -806,7 +794,7 @@ describe Repository do
describe '#fetch_ref' do
let(:broken_repository) { create(:project, :broken_storage).repository }
- describe 'when storage is broken', :broken_storage do
+ describe 'when storage is broken', :broken_storage do
it 'should raise a storage error' do
expect_to_raise_storage_error do
broken_repository.fetch_ref(broken_repository, source_ref: '1', target_ref: '2')
@@ -1709,19 +1697,29 @@ describe Repository do
end
describe '#after_change_head' do
- it 'flushes the readme cache' do
+ it 'flushes the method caches' do
expect(repository).to receive(:expire_method_caches).with([
- :readme,
+ :size,
+ :commit_count,
+ :rendered_readme,
+ :contribution_guide,
:changelog,
- :license,
- :contributing,
+ :license_blob,
+ :license_key,
:gitignore,
- :koding,
- :gitlab_ci,
+ :koding_yml,
+ :gitlab_ci_yml,
+ :branch_names,
+ :tag_names,
+ :branch_count,
+ :tag_count,
:avatar,
- :issue_template,
- :merge_request_template,
- :xcode_config
+ :exists?,
+ :root_ref,
+ :has_visible_content?,
+ :issue_template_names,
+ :merge_request_template_names,
+ :xcode_project?
])
repository.after_change_head
@@ -1863,155 +1861,61 @@ describe Repository do
describe '#add_tag' do
let(:user) { build_stubbed(:user) }
- shared_examples 'adding tag' do
- context 'with a valid target' do
- it 'creates the tag' do
- repository.add_tag(user, '8.5', 'master', 'foo')
-
- tag = repository.find_tag('8.5')
- expect(tag).to be_present
- expect(tag.message).to eq('foo')
- expect(tag.dereferenced_target.id).to eq(repository.commit('master').id)
- end
-
- it 'returns a Gitlab::Git::Tag object' do
- tag = repository.add_tag(user, '8.5', 'master', 'foo')
+ context 'with a valid target' do
+ it 'creates the tag' do
+ repository.add_tag(user, '8.5', 'master', 'foo')
- expect(tag).to be_a(Gitlab::Git::Tag)
- end
+ tag = repository.find_tag('8.5')
+ expect(tag).to be_present
+ expect(tag.message).to eq('foo')
+ expect(tag.dereferenced_target.id).to eq(repository.commit('master').id)
end
- context 'with an invalid target' do
- it 'returns false' do
- expect(repository.add_tag(user, '8.5', 'bar', 'foo')).to be false
- end
- end
- end
-
- context 'when Gitaly operation_user_add_tag feature is enabled' do
- it_behaves_like 'adding tag'
- end
-
- context 'when Gitaly operation_user_add_tag feature is disabled', :disable_gitaly do
- it_behaves_like 'adding tag'
-
- it 'passes commit SHA to pre-receive and update hooks and tag SHA to post-receive hook' do
- pre_receive_hook = Gitlab::Git::Hook.new('pre-receive', project)
- update_hook = Gitlab::Git::Hook.new('update', project)
- post_receive_hook = Gitlab::Git::Hook.new('post-receive', project)
-
- allow(Gitlab::Git::Hook).to receive(:new)
- .and_return(pre_receive_hook, update_hook, post_receive_hook)
-
- allow(pre_receive_hook).to receive(:trigger).and_call_original
- allow(update_hook).to receive(:trigger).and_call_original
- allow(post_receive_hook).to receive(:trigger).and_call_original
-
+ it 'returns a Gitlab::Git::Tag object' do
tag = repository.add_tag(user, '8.5', 'master', 'foo')
- commit_sha = repository.commit('master').id
- tag_sha = tag.target
-
- expect(pre_receive_hook).to have_received(:trigger)
- .with(anything, anything, anything, commit_sha, anything)
- expect(update_hook).to have_received(:trigger)
- .with(anything, anything, anything, commit_sha, anything)
- expect(post_receive_hook).to have_received(:trigger)
- .with(anything, anything, anything, tag_sha, anything)
+ expect(tag).to be_a(Gitlab::Git::Tag)
end
end
- end
-
- describe '#rm_branch' do
- shared_examples "user deleting a branch" do
- it 'removes a branch' do
- expect(repository).to receive(:before_remove_branch)
- expect(repository).to receive(:after_remove_branch)
- repository.rm_branch(user, 'feature')
+ context 'with an invalid target' do
+ it 'returns false' do
+ expect(repository.add_tag(user, '8.5', 'bar', 'foo')).to be false
end
end
+ end
- context 'with gitaly enabled' do
- it_behaves_like "user deleting a branch"
-
- context 'when pre hooks failed' do
- before do
- allow_any_instance_of(Gitlab::GitalyClient::OperationService)
- .to receive(:user_delete_branch).and_raise(Gitlab::Git::PreReceiveError)
- end
-
- it 'gets an error and does not delete the branch' do
- expect do
- repository.rm_branch(user, 'feature')
- end.to raise_error(Gitlab::Git::PreReceiveError)
+ describe '#rm_branch' do
+ it 'removes a branch' do
+ expect(repository).to receive(:before_remove_branch)
+ expect(repository).to receive(:after_remove_branch)
- expect(repository.find_branch('feature')).not_to be_nil
- end
- end
+ repository.rm_branch(user, 'feature')
end
- context 'with gitaly disabled', :disable_gitaly do
- it_behaves_like "user deleting a branch"
-
- let(:old_rev) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } # git rev-parse feature
- let(:blank_sha) { '0000000000000000000000000000000000000000' }
-
- context 'when pre hooks were successful' do
- it 'runs without errors' do
- expect_any_instance_of(Gitlab::Git::HooksService).to receive(:execute)
- .with(git_user, repository.raw_repository, old_rev, blank_sha, 'refs/heads/feature')
-
- expect { repository.rm_branch(user, 'feature') }.not_to raise_error
- end
-
- it 'deletes the branch' do
- allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, nil])
-
- expect { repository.rm_branch(user, 'feature') }.not_to raise_error
-
- expect(repository.find_branch('feature')).to be_nil
- end
+ context 'when pre hooks failed' do
+ before do
+ allow_any_instance_of(Gitlab::GitalyClient::OperationService)
+ .to receive(:user_delete_branch).and_raise(Gitlab::Git::PreReceiveError)
end
- context 'when pre hooks failed' do
- it 'gets an error' do
- allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, ''])
-
- expect do
- repository.rm_branch(user, 'feature')
- end.to raise_error(Gitlab::Git::PreReceiveError)
- end
-
- it 'does not delete the branch' do
- allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, ''])
+ it 'gets an error and does not delete the branch' do
+ expect do
+ repository.rm_branch(user, 'feature')
+ end.to raise_error(Gitlab::Git::PreReceiveError)
- expect do
- repository.rm_branch(user, 'feature')
- end.to raise_error(Gitlab::Git::PreReceiveError)
- expect(repository.find_branch('feature')).not_to be_nil
- end
+ expect(repository.find_branch('feature')).not_to be_nil
end
end
end
describe '#rm_tag' do
- shared_examples 'removing tag' do
- it 'removes a tag' do
- expect(repository).to receive(:before_remove_tag)
+ it 'removes a tag' do
+ expect(repository).to receive(:before_remove_tag)
- repository.rm_tag(build_stubbed(:user), 'v1.1.0')
+ repository.rm_tag(build_stubbed(:user), 'v1.1.0')
- expect(repository.find_tag('v1.1.0')).to be_nil
- end
- end
-
- context 'when Gitaly operation_user_delete_tag feature is enabled' do
- it_behaves_like 'removing tag'
- end
-
- context 'when Gitaly operation_user_delete_tag feature is disabled', :skip_gitaly_mock do
- it_behaves_like 'removing tag'
+ expect(repository.find_tag('v1.1.0')).to be_nil
end
end
@@ -2304,6 +2208,28 @@ describe Repository do
end
end
+ describe '#local_branches' do
+ it 'returns the local branches' do
+ masterrev = repository.find_branch('master').dereferenced_target
+ create_remote_branch('joe', 'remote_branch', masterrev)
+ repository.add_branch(user, 'local_branch', masterrev.id)
+
+ expect(repository.local_branches.any? { |branch| branch.name == 'remote_branch' }).to eq(false)
+ expect(repository.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true)
+ end
+ end
+
+ describe '#remote_branches' do
+ it 'returns the remote branches' do
+ masterrev = repository.find_branch('master').dereferenced_target
+ create_remote_branch('joe', 'remote_branch', masterrev)
+ repository.add_branch(user, 'local_branch', masterrev.id)
+
+ expect(repository.remote_branches('joe').any? { |branch| branch.name == 'local_branch' }).to eq(false)
+ expect(repository.remote_branches('joe').any? { |branch| branch.name == 'remote_branch' }).to eq(true)
+ end
+ end
+
describe '#commit_count' do
context 'with a non-existing repository' do
it 'returns 0' do