summaryrefslogtreecommitdiff
path: root/spec/models
diff options
context:
space:
mode:
authorTimothy Andrew <mail@timothyandrew.net>2016-09-20 14:48:13 +0530
committerTimothy Andrew <mail@timothyandrew.net>2016-09-20 14:48:13 +0530
commitfa890604aaf15b9e4f0199e6a4cff24c29955a37 (patch)
tree1606c5585a93d3c0449effbe7b5cc901900833dd /spec/models
parent0b97b42d60a662c0d138c44f6dbd05a3048ac349 (diff)
parent95b9421ad3b2678da6e0af0131eafd52cdd0b2a5 (diff)
downloadgitlab-ce-fa890604aaf15b9e4f0199e6a4cff24c29955a37.tar.gz
Merge remote-tracking branch 'origin/master' into 21170-cycle-analytics
Diffstat (limited to 'spec/models')
-rw-r--r--spec/models/blob_spec.rb20
-rw-r--r--spec/models/build_spec.rb106
-rw-r--r--spec/models/ci/build_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb63
-rw-r--r--spec/models/commit_status_spec.rb43
-rw-r--r--spec/models/diff_note_spec.rb37
-rw-r--r--spec/models/discussion_spec.rb96
-rw-r--r--spec/models/environment_spec.rb16
-rw-r--r--spec/models/event_spec.rb43
-rw-r--r--spec/models/group_spec.rb46
-rw-r--r--spec/models/hooks/project_hook_spec.rb18
-rw-r--r--spec/models/hooks/service_hook_spec.rb18
-rw-r--r--spec/models/hooks/system_hook_spec.rb20
-rw-r--r--spec/models/hooks/web_hook_spec.rb18
-rw-r--r--spec/models/member_spec.rb42
-rw-r--r--spec/models/members/group_member_spec.rb19
-rw-r--r--spec/models/members/project_member_spec.rb19
-rw-r--r--spec/models/merge_request_spec.rb97
-rw-r--r--spec/models/project_services/asana_service_spec.rb20
-rw-r--r--spec/models/project_services/assembla_service_spec.rb20
-rw-r--r--spec/models/project_services/bamboo_service_spec.rb20
-rw-r--r--spec/models/project_services/bugzilla_service_spec.rb20
-rw-r--r--spec/models/project_services/buildkite_service_spec.rb20
-rw-r--r--spec/models/project_services/campfire_service_spec.rb20
-rw-r--r--spec/models/project_services/custom_issue_tracker_service_spec.rb20
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb20
-rw-r--r--spec/models/project_services/external_wiki_service_spec.rb21
-rw-r--r--spec/models/project_services/flowdock_service_spec.rb20
-rw-r--r--spec/models/project_services/gemnasium_service_spec.rb20
-rw-r--r--spec/models/project_services/gitlab_issue_tracker_service_spec.rb20
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb20
-rw-r--r--spec/models/project_services/irker_service_spec.rb20
-rw-r--r--spec/models/project_services/jira_service_spec.rb20
-rw-r--r--spec/models/project_services/pivotaltracker_service_spec.rb20
-rw-r--r--spec/models/project_services/pushover_service_spec.rb20
-rw-r--r--spec/models/project_services/redmine_service_spec.rb20
-rw-r--r--spec/models/project_services/slack_service/build_message_spec.rb32
-rw-r--r--spec/models/project_services/slack_service/pipeline_message_spec.rb55
-rw-r--r--spec/models/project_services/slack_service_spec.rb91
-rw-r--r--spec/models/project_services/teamcity_service_spec.rb20
-rw-r--r--spec/models/project_spec.rb165
-rw-r--r--spec/models/repository_spec.rb71
42 files changed, 838 insertions, 680 deletions
diff --git a/spec/models/blob_spec.rb b/spec/models/blob_spec.rb
index cee20234e1f..03d02b4d382 100644
--- a/spec/models/blob_spec.rb
+++ b/spec/models/blob_spec.rb
@@ -1,3 +1,4 @@
+# encoding: utf-8
require 'rails_helper'
describe Blob do
@@ -7,6 +8,25 @@ describe Blob do
end
end
+ describe '#data' do
+ context 'using a binary blob' do
+ it 'returns the data as-is' do
+ data = "\n\xFF\xB9\xC3"
+ blob = described_class.new(double(binary?: true, data: data))
+
+ expect(blob.data).to eq(data)
+ end
+ end
+
+ context 'using a text blob' do
+ it 'converts the data to UTF-8' do
+ blob = described_class.new(double(binary?: false, data: "\n\xFF\xB9\xC3"))
+
+ expect(blob.data).to eq("\n���")
+ end
+ end
+ end
+
describe '#svg?' do
it 'is falsey when not text' do
git_blob = double(text?: false)
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index c45c2635cf4..e7864b7ad33 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -88,9 +88,7 @@ describe Ci::Build, models: true do
end
describe '#trace' do
- subject { build.trace_html }
-
- it { is_expected.to be_empty }
+ it { expect(build.trace).to be_nil }
context 'when build.trace contains text' do
let(:text) { 'example output' }
@@ -98,16 +96,80 @@ describe Ci::Build, models: true do
build.trace = text
end
- it { is_expected.to include(text) }
- it { expect(subject.length).to be >= text.length }
+ it { expect(build.trace).to eq(text) }
+ end
+
+ context 'when build.trace hides runners token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.update(trace: token)
+ build.project.update(runners_token: token)
+ end
+
+ it { expect(build.trace).not_to include(token) }
+ it { expect(build.raw_trace).to include(token) }
+ end
+
+ context 'when build.trace hides build token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.update(trace: token)
+ build.update(token: token)
+ end
+
+ it { expect(build.trace).not_to include(token) }
+ it { expect(build.raw_trace).to include(token) }
+ end
+ end
+
+ describe '#raw_trace' do
+ subject { build.raw_trace }
+
+ context 'when build.trace hides runners token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.project.update(runners_token: token)
+ build.update(trace: token)
+ end
+
+ it { is_expected.not_to include(token) }
+ end
+
+ context 'when build.trace hides build token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.update(token: token)
+ build.update(trace: token)
+ end
+
+ it { is_expected.not_to include(token) }
+ end
+ end
+
+ context '#append_trace' do
+ subject { build.trace_html }
+
+ context 'when build.trace hides runners token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.project.update(runners_token: token)
+ build.append_trace(token, 0)
+ end
+
+ it { is_expected.not_to include(token) }
end
- context 'when build.trace hides token' do
+ context 'when build.trace hides build token' do
let(:token) { 'my_secret_token' }
before do
- build.project.update_attributes(runners_token: token)
- build.update_attributes(trace: token)
+ build.update(token: token)
+ build.append_trace(token, 0)
end
it { is_expected.not_to include(token) }
@@ -231,6 +293,34 @@ describe Ci::Build, models: true do
it { is_expected.to eq(predefined_variables) }
end
+ context 'when build has user' do
+ let(:user) { create(:user, username: 'starter') }
+ let(:user_variables) do
+ [
+ { key: 'GITLAB_USER_ID', value: user.id.to_s, public: true },
+ { key: 'GITLAB_USER_EMAIL', value: user.email, public: true }
+ ]
+ end
+
+ before do
+ build.update_attributes(user: user)
+ end
+
+ it { user_variables.each { |v| is_expected.to include(v) } }
+ end
+
+ context 'when build started manually' do
+ before do
+ build.update_attributes(when: :manual)
+ end
+
+ let(:manual_variable) do
+ { key: 'CI_BUILD_MANUAL', value: 'true', public: true }
+ end
+
+ it { is_expected.to include(manual_variable) }
+ end
+
context 'when build is for tag' do
let(:tag_variable) do
{ key: 'CI_BUILD_TAG', value: 'master', public: true }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index bce18b4e99e..a37a00f461a 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -8,7 +8,7 @@ describe Ci::Build, models: true do
it 'obfuscates project runners token' do
allow(build).to receive(:raw_trace).and_return("Test: #{build.project.runners_token}")
- expect(build.trace).to eq("Test: xxxxxx")
+ expect(build.trace).to eq("Test: xxxxxxxxxxxxxxxxxxxx")
end
it 'empty project runners token' do
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 5bafcc13f61..0b989b98b61 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -124,21 +124,38 @@ describe Ci::Pipeline, models: true do
describe 'state machine' do
let(:current) { Time.now.change(usec: 0) }
- let(:build) { create :ci_build, name: 'build1', pipeline: pipeline }
+ let(:build) { create_build('build1', current, 10) }
+ let(:build_b) { create_build('build2', current, 20) }
+ let(:build_c) { create_build('build3', current + 50, 10) }
describe '#duration' do
before do
- travel_to(current - 120) do
+ pipeline.update(created_at: current)
+
+ travel_to(current + 5) do
pipeline.run
+ pipeline.save
+ end
+
+ travel_to(current + 30) do
+ build.success
+ end
+
+ travel_to(current + 40) do
+ build_b.drop
end
- travel_to(current) do
- pipeline.succeed
+ travel_to(current + 70) do
+ build_c.success
end
+
+ pipeline.drop
end
it 'matches sum of builds duration' do
- expect(pipeline.reload.duration).to eq(120)
+ pipeline.reload
+
+ expect(pipeline.duration).to eq(40)
end
end
@@ -200,6 +217,14 @@ describe Ci::Pipeline, models: true do
end
end
end
+
+ def create_build(name, queued_at = current, started_from = 0)
+ create(:ci_build,
+ name: name,
+ pipeline: pipeline,
+ queued_at: queued_at,
+ started_at: queued_at + started_from)
+ end
end
describe '#branch?' do
@@ -379,8 +404,8 @@ describe Ci::Pipeline, models: true do
end
describe '#execute_hooks' do
- let!(:build_a) { create_build('a') }
- let!(:build_b) { create_build('b') }
+ let!(:build_a) { create_build('a', 0) }
+ let!(:build_b) { create_build('b', 1) }
let!(:hook) do
create(:project_hook, project: project, pipeline_events: enabled)
@@ -404,7 +429,7 @@ describe Ci::Pipeline, models: true do
build_b.enqueue
end
- it 'receive a pending event once' do
+ it 'receives a pending event once' do
expect(WebMock).to have_requested_pipeline_hook('pending').once
end
end
@@ -417,7 +442,7 @@ describe Ci::Pipeline, models: true do
build_b.run
end
- it 'receive a running event once' do
+ it 'receives a running event once' do
expect(WebMock).to have_requested_pipeline_hook('running').once
end
end
@@ -428,11 +453,21 @@ describe Ci::Pipeline, models: true do
build_b.success
end
- it 'receive a success event once' do
+ it 'receives a success event once' do
expect(WebMock).to have_requested_pipeline_hook('success').once
end
end
+ context 'when stage one failed' do
+ before do
+ build_a.drop
+ end
+
+ it 'receives a failed event once' do
+ expect(WebMock).to have_requested_pipeline_hook('failed').once
+ end
+ end
+
def have_requested_pipeline_hook(status)
have_requested(:post, hook.url).with do |req|
json_body = JSON.parse(req.body)
@@ -456,8 +491,12 @@ describe Ci::Pipeline, models: true do
end
end
- def create_build(name)
- create(:ci_build, :created, pipeline: pipeline, name: name)
+ def create_build(name, stage_idx)
+ create(:ci_build,
+ :created,
+ pipeline: pipeline,
+ name: name,
+ stage_idx: stage_idx)
end
end
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index fcfa3138ce5..2f1baff5d66 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -40,7 +40,7 @@ describe CommitStatus, models: true do
it { is_expected.to be_falsey }
end
- %w(running success failed).each do |status|
+ %w[running success failed].each do |status|
context "if commit status is #{status}" do
before { commit_status.status = status }
@@ -48,7 +48,7 @@ describe CommitStatus, models: true do
end
end
- %w(pending canceled).each do |status|
+ %w[pending canceled].each do |status|
context "if commit status is #{status}" do
before { commit_status.status = status }
@@ -60,7 +60,7 @@ describe CommitStatus, models: true do
describe '#active?' do
subject { commit_status.active? }
- %w(pending running).each do |state|
+ %w[pending running].each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
@@ -68,7 +68,7 @@ describe CommitStatus, models: true do
end
end
- %w(success failed canceled).each do |state|
+ %w[success failed canceled].each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
@@ -80,7 +80,7 @@ describe CommitStatus, models: true do
describe '#complete?' do
subject { commit_status.complete? }
- %w(success failed canceled).each do |state|
+ %w[success failed canceled].each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
@@ -88,7 +88,7 @@ describe CommitStatus, models: true do
end
end
- %w(pending running).each do |state|
+ %w[pending running].each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
@@ -187,7 +187,7 @@ describe CommitStatus, models: true do
subject { CommitStatus.where(pipeline: pipeline).stages }
it 'returns ordered list of stages' do
- is_expected.to eq(%w(build test deploy))
+ is_expected.to eq(%w[build test deploy])
end
end
@@ -223,4 +223,33 @@ describe CommitStatus, models: true do
expect(commit_status.commit).to eq project.commit
end
end
+
+ describe '#group_name' do
+ subject { commit_status.group_name }
+
+ tests = {
+ 'rspec:windows' => 'rspec:windows',
+ 'rspec:windows 0' => 'rspec:windows 0',
+ 'rspec:windows 0 test' => 'rspec:windows 0 test',
+ 'rspec:windows 0 1' => 'rspec:windows',
+ 'rspec:windows 0 1 name' => 'rspec:windows name',
+ 'rspec:windows 0/1' => 'rspec:windows',
+ 'rspec:windows 0/1 name' => 'rspec:windows name',
+ 'rspec:windows 0:1' => 'rspec:windows',
+ 'rspec:windows 0:1 name' => 'rspec:windows name',
+ 'rspec:windows 10000 20000' => 'rspec:windows',
+ 'rspec:windows 0 : / 1' => 'rspec:windows',
+ 'rspec:windows 0 : / 1 name' => 'rspec:windows name',
+ '0 1 name ruby' => 'name ruby',
+ '0 :/ 1 name ruby' => 'name ruby'
+ }
+
+ tests.each do |name, group_name|
+ it "'#{name}' puts in '#{group_name}'" do
+ commit_status.name = name
+
+ is_expected.to eq(group_name)
+ end
+ end
+ end
end
diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb
index 6a640474cfe..3db5937a4f3 100644
--- a/spec/models/diff_note_spec.rb
+++ b/spec/models/diff_note_spec.rb
@@ -31,6 +31,43 @@ describe DiffNote, models: true do
subject { create(:diff_note_on_merge_request, project: project, position: position, noteable: merge_request) }
+ describe ".resolve!" do
+ let(:current_user) { create(:user) }
+ let!(:commit_note) { create(:diff_note_on_commit) }
+ let!(:resolved_note) { create(:diff_note_on_merge_request, :resolved) }
+ let!(:unresolved_note) { create(:diff_note_on_merge_request) }
+
+ before do
+ described_class.resolve!(current_user)
+
+ commit_note.reload
+ resolved_note.reload
+ unresolved_note.reload
+ end
+
+ it 'resolves only the resolvable, not yet resolved notes' do
+ expect(commit_note.resolved_at).to be_nil
+ expect(resolved_note.resolved_by).not_to eq(current_user)
+ expect(unresolved_note.resolved_at).not_to be_nil
+ expect(unresolved_note.resolved_by).to eq(current_user)
+ end
+ end
+
+ describe ".unresolve!" do
+ let!(:resolved_note) { create(:diff_note_on_merge_request, :resolved) }
+
+ before do
+ described_class.unresolve!
+
+ resolved_note.reload
+ end
+
+ it 'unresolves the resolved notes' do
+ expect(resolved_note.resolved_by).to be_nil
+ expect(resolved_note.resolved_at).to be_nil
+ end
+ end
+
describe "#position=" do
context "when provided a string" do
it "sets the position" do
diff --git a/spec/models/discussion_spec.rb b/spec/models/discussion_spec.rb
index 179f2e73662..0142706d140 100644
--- a/spec/models/discussion_spec.rb
+++ b/spec/models/discussion_spec.rb
@@ -238,27 +238,19 @@ describe Discussion, model: true do
context "when resolvable" do
let(:user) { create(:user) }
+ let(:second_note) { create(:diff_note_on_commit) } # unresolvable
before do
allow(subject).to receive(:resolvable?).and_return(true)
-
- allow(first_note).to receive(:resolvable?).and_return(true)
- allow(second_note).to receive(:resolvable?).and_return(false)
- allow(third_note).to receive(:resolvable?).and_return(true)
end
context "when all resolvable notes are resolved" do
before do
first_note.resolve!(user)
third_note.resolve!(user)
- end
- it "calls resolve! on every resolvable note" do
- expect(first_note).to receive(:resolve!).with(current_user)
- expect(second_note).not_to receive(:resolve!)
- expect(third_note).to receive(:resolve!).with(current_user)
-
- subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
end
it "doesn't change resolved_at on the resolved notes" do
@@ -309,46 +301,44 @@ describe Discussion, model: true do
first_note.resolve!(user)
end
- it "calls resolve! on every resolvable note" do
- expect(first_note).to receive(:resolve!).with(current_user)
- expect(second_note).not_to receive(:resolve!)
- expect(third_note).to receive(:resolve!).with(current_user)
-
- subject.resolve!(current_user)
- end
-
it "doesn't change resolved_at on the resolved note" do
expect(first_note.resolved_at).not_to be_nil
- expect { subject.resolve!(current_user) }.not_to change { first_note.resolved_at }
+ expect { subject.resolve!(current_user) }.
+ not_to change { first_note.reload.resolved_at }
end
it "doesn't change resolved_by on the resolved note" do
expect(first_note.resolved_by).to eq(user)
- expect { subject.resolve!(current_user) }.not_to change { first_note.resolved_by }
+ expect { subject.resolve!(current_user) }.
+ not_to change { first_note.reload && first_note.resolved_by }
end
it "doesn't change the resolved state on the resolved note" do
expect(first_note.resolved?).to be true
- expect { subject.resolve!(current_user) }.not_to change { first_note.resolved? }
+ expect { subject.resolve!(current_user) }.
+ not_to change { first_note.reload && first_note.resolved? }
end
it "sets resolved_at on the unresolved note" do
subject.resolve!(current_user)
+ third_note.reload
expect(third_note.resolved_at).not_to be_nil
end
it "sets resolved_by on the unresolved note" do
subject.resolve!(current_user)
+ third_note.reload
expect(third_note.resolved_by).to eq(current_user)
end
it "marks the unresolved note as resolved" do
subject.resolve!(current_user)
+ third_note.reload
expect(third_note.resolved?).to be true
end
@@ -373,16 +363,10 @@ describe Discussion, model: true do
end
context "when no resolvable notes are resolved" do
- it "calls resolve! on every resolvable note" do
- expect(first_note).to receive(:resolve!).with(current_user)
- expect(second_note).not_to receive(:resolve!)
- expect(third_note).to receive(:resolve!).with(current_user)
-
- subject.resolve!(current_user)
- end
-
it "sets resolved_at on the unresolved notes" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(first_note.resolved_at).not_to be_nil
expect(third_note.resolved_at).not_to be_nil
@@ -390,6 +374,8 @@ describe Discussion, model: true do
it "sets resolved_by on the unresolved notes" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(first_note.resolved_by).to eq(current_user)
expect(third_note.resolved_by).to eq(current_user)
@@ -397,6 +383,8 @@ describe Discussion, model: true do
it "marks the unresolved notes as resolved" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(first_note.resolved?).to be true
expect(third_note.resolved?).to be true
@@ -404,18 +392,24 @@ describe Discussion, model: true do
it "sets resolved_at" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(subject.resolved_at).not_to be_nil
end
it "sets resolved_by" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(subject.resolved_by).to eq(current_user)
end
it "marks as resolved" do
subject.resolve!(current_user)
+ first_note.reload
+ third_note.reload
expect(subject.resolved?).to be true
end
@@ -451,16 +445,10 @@ describe Discussion, model: true do
third_note.resolve!(user)
end
- it "calls unresolve! on every resolvable note" do
- expect(first_note).to receive(:unresolve!)
- expect(second_note).not_to receive(:unresolve!)
- expect(third_note).to receive(:unresolve!)
-
- subject.unresolve!
- end
-
it "unsets resolved_at on the resolved notes" do
subject.unresolve!
+ first_note.reload
+ third_note.reload
expect(first_note.resolved_at).to be_nil
expect(third_note.resolved_at).to be_nil
@@ -468,6 +456,8 @@ describe Discussion, model: true do
it "unsets resolved_by on the resolved notes" do
subject.unresolve!
+ first_note.reload
+ third_note.reload
expect(first_note.resolved_by).to be_nil
expect(third_note.resolved_by).to be_nil
@@ -475,6 +465,8 @@ describe Discussion, model: true do
it "unmarks the resolved notes as resolved" do
subject.unresolve!
+ first_note.reload
+ third_note.reload
expect(first_note.resolved?).to be false
expect(third_note.resolved?).to be false
@@ -482,12 +474,16 @@ describe Discussion, model: true do
it "unsets resolved_at" do
subject.unresolve!
+ first_note.reload
+ third_note.reload
expect(subject.resolved_at).to be_nil
end
it "unsets resolved_by" do
subject.unresolve!
+ first_note.reload
+ third_note.reload
expect(subject.resolved_by).to be_nil
end
@@ -504,40 +500,22 @@ describe Discussion, model: true do
first_note.resolve!(user)
end
- it "calls unresolve! on every resolvable note" do
- expect(first_note).to receive(:unresolve!)
- expect(second_note).not_to receive(:unresolve!)
- expect(third_note).to receive(:unresolve!)
-
- subject.unresolve!
- end
-
it "unsets resolved_at on the resolved note" do
subject.unresolve!
- expect(first_note.resolved_at).to be_nil
+ expect(subject.first_note.resolved_at).to be_nil
end
it "unsets resolved_by on the resolved note" do
subject.unresolve!
- expect(first_note.resolved_by).to be_nil
+ expect(subject.first_note.resolved_by).to be_nil
end
it "unmarks the resolved note as resolved" do
subject.unresolve!
- expect(first_note.resolved?).to be false
- end
- end
-
- context "when no resolvable notes are resolved" do
- it "calls unresolve! on every resolvable note" do
- expect(first_note).to receive(:unresolve!)
- expect(second_note).not_to receive(:unresolve!)
- expect(third_note).to receive(:unresolve!)
-
- subject.unresolve!
+ expect(subject.first_note.resolved?).to be false
end
end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index c881897926e..6b1867a44e1 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -63,4 +63,20 @@ describe Environment, models: true do
end
end
end
+
+ describe '#environment_type' do
+ subject { environment.environment_type }
+
+ it 'sets a environment type if name has multiple segments' do
+ environment.update!(name: 'production/worker.gitlab.com')
+
+ is_expected.to eq('production')
+ end
+
+ it 'nullifies a type if it\'s a simple name' do
+ environment.update!(name: 'production')
+
+ is_expected.to be_nil
+ end
+ end
end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index b5d0d79e14e..8600eb4d2c4 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -16,18 +16,12 @@ describe Event, models: true do
describe 'Callbacks' do
describe 'after_create :reset_project_activity' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
- context "project's last activity was less than 5 minutes ago" do
- it 'does not update project.last_activity_at if it has been touched less than 5 minutes ago' do
- create_event(project, project.owner)
- project.update_column(:last_activity_at, 5.minutes.ago)
- project_last_activity_at = project.last_activity_at
+ it 'calls the reset_project_activity method' do
+ expect_any_instance_of(Event).to receive(:reset_project_activity)
- create_event(project, project.owner)
-
- expect(project.last_activity_at).to eq(project_last_activity_at)
- end
+ create_event(project, project.owner)
end
end
end
@@ -161,6 +155,35 @@ describe Event, models: true do
end
end
+ describe '#reset_project_activity' do
+ let(:project) { create(:empty_project) }
+
+ context 'when a project was updated less than 1 hour ago' do
+ it 'does not update the project' do
+ project.update(last_activity_at: Time.now)
+
+ expect(project).not_to receive(:update_column).
+ with(:last_activity_at, a_kind_of(Time))
+
+ create_event(project, project.owner)
+ end
+ end
+
+ context 'when a project was updated more than 1 hour ago' do
+ it 'updates the project' do
+ project.update(last_activity_at: 1.year.ago)
+
+ expect_any_instance_of(Gitlab::ExclusiveLease).
+ to receive(:try_obtain).and_return(true)
+
+ expect(project).to receive(:update_column).
+ with(:last_activity_at, a_kind_of(Time))
+
+ create_event(project, project.owner)
+ end
+ end
+ end
+
def create_event(project, user, attrs = {})
data = {
before: Gitlab::Git::BLANK_SHA,
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index ea4b59c26b1..0b3ef9b98fd 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -187,6 +187,52 @@ describe Group, models: true do
it { expect(group.has_master?(@members[:requester])).to be_falsey }
end
+ describe '#lfs_enabled?' do
+ context 'LFS enabled globally' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ end
+
+ it 'returns true when nothing is set' do
+ expect(group.lfs_enabled?).to be_truthy
+ end
+
+ it 'returns false when set to false' do
+ group.update_attribute(:lfs_enabled, false)
+
+ expect(group.lfs_enabled?).to be_falsey
+ end
+
+ it 'returns true when set to true' do
+ group.update_attribute(:lfs_enabled, true)
+
+ expect(group.lfs_enabled?).to be_truthy
+ end
+ end
+
+ context 'LFS disabled globally' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(false)
+ end
+
+ it 'returns false when nothing is set' do
+ expect(group.lfs_enabled?).to be_falsey
+ end
+
+ it 'returns false when set to false' do
+ group.update_attribute(:lfs_enabled, false)
+
+ expect(group.lfs_enabled?).to be_falsey
+ end
+
+ it 'returns false when set to true' do
+ group.update_attribute(:lfs_enabled, true)
+
+ expect(group.lfs_enabled?).to be_falsey
+ end
+ end
+ end
+
describe '#owners' do
let(:owner) { create(:user) }
let(:developer) { create(:user) }
diff --git a/spec/models/hooks/project_hook_spec.rb b/spec/models/hooks/project_hook_spec.rb
index 4a457997a4f..474ae62ccec 100644
--- a/spec/models/hooks/project_hook_spec.rb
+++ b/spec/models/hooks/project_hook_spec.rb
@@ -1,21 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string(255) default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-#
-
require 'spec_helper'
describe ProjectHook, models: true do
diff --git a/spec/models/hooks/service_hook_spec.rb b/spec/models/hooks/service_hook_spec.rb
index 534e1b4f128..1a83c836652 100644
--- a/spec/models/hooks/service_hook_spec.rb
+++ b/spec/models/hooks/service_hook_spec.rb
@@ -1,21 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string(255) default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-#
-
require "spec_helper"
describe ServiceHook, models: true do
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index cbdf7eec082..ad2b710041a 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -1,21 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string(255) default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-#
-
require "spec_helper"
describe SystemHook, models: true do
@@ -48,7 +30,7 @@ describe SystemHook, models: true do
it "user_create hook" do
create(:user)
-
+
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_create/,
headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index f9bab487b96..e52b9d75cef 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -1,21 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string(255) default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-#
-
require 'spec_helper'
describe WebHook, models: true do
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index fef90d9b5cb..0b1634f654a 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -57,7 +57,7 @@ describe Member, models: true do
describe 'Scopes & finders' do
before do
- project = create(:project)
+ project = create(:empty_project)
group = create(:group)
@owner_user = create(:user).tap { |u| group.add_owner(u) }
@owner = group.members.find_by(user_id: @owner_user.id)
@@ -65,6 +65,15 @@ describe Member, models: true do
@master_user = create(:user).tap { |u| project.team << [u, :master] }
@master = project.members.find_by(user_id: @master_user.id)
+ @blocked_user = create(:user).tap do |u|
+ project.team << [u, :master]
+ project.team << [u, :developer]
+
+ u.block!
+ end
+ @blocked_master = project.members.find_by(user_id: @blocked_user.id, access_level: Gitlab::Access::MASTER)
+ @blocked_developer = project.members.find_by(user_id: @blocked_user.id, access_level: Gitlab::Access::DEVELOPER)
+
Member.add_user(
project.members,
'toto1@example.com',
@@ -73,7 +82,7 @@ describe Member, models: true do
)
@invited_member = project.members.invite.find_by_invite_email('toto1@example.com')
- accepted_invite_user = build(:user)
+ accepted_invite_user = build(:user, state: :active)
Member.add_user(
project.members,
'toto2@example.com',
@@ -91,7 +100,7 @@ describe Member, models: true do
describe '.access_for_user_ids' do
it 'returns the right access levels' do
- users = [@owner_user.id, @master_user.id]
+ users = [@owner_user.id, @master_user.id, @blocked_user.id]
expected = {
@owner_user.id => Gitlab::Access::OWNER,
@master_user.id => Gitlab::Access::MASTER
@@ -125,6 +134,19 @@ describe Member, models: true do
it { expect(described_class.request).not_to include @accepted_request_member }
end
+ describe '.developers' do
+ subject { described_class.developers.to_a }
+
+ it { is_expected.not_to include @owner }
+ it { is_expected.not_to include @master }
+ it { is_expected.to include @invited_member }
+ it { is_expected.to include @accepted_invite_member }
+ it { is_expected.not_to include @requested_member }
+ it { is_expected.to include @accepted_request_member }
+ it { is_expected.not_to include @blocked_master }
+ it { is_expected.not_to include @blocked_developer }
+ end
+
describe '.owners_and_masters' do
it { expect(described_class.owners_and_masters).to include @owner }
it { expect(described_class.owners_and_masters).to include @master }
@@ -132,6 +154,20 @@ describe Member, models: true do
it { expect(described_class.owners_and_masters).not_to include @accepted_invite_member }
it { expect(described_class.owners_and_masters).not_to include @requested_member }
it { expect(described_class.owners_and_masters).not_to include @accepted_request_member }
+ it { expect(described_class.owners_and_masters).not_to include @blocked_master }
+ end
+
+ describe '.has_access' do
+ subject { described_class.has_access.to_a }
+
+ it { is_expected.to include @owner }
+ it { is_expected.to include @master }
+ it { is_expected.to include @invited_member }
+ it { is_expected.to include @accepted_invite_member }
+ it { is_expected.not_to include @requested_member }
+ it { is_expected.to include @accepted_request_member }
+ it { is_expected.not_to include @blocked_master }
+ it { is_expected.not_to include @blocked_developer }
end
end
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index 4f875fd257a..56fa7fa6134 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: members
-#
-# id :integer not null, primary key
-# access_level :integer not null
-# source_id :integer not null
-# source_type :string(255) not null
-# user_id :integer
-# notification_level :integer not null
-# type :string(255)
-# created_at :datetime
-# updated_at :datetime
-# created_by_id :integer
-# invite_email :string(255)
-# invite_token :string(255)
-# invite_accepted_at :datetime
-#
-
require 'spec_helper'
describe GroupMember, models: true do
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index be57957b569..805c15a4e5e 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: members
-#
-# id :integer not null, primary key
-# access_level :integer not null
-# source_id :integer not null
-# source_type :string(255) not null
-# user_id :integer
-# notification_level :integer not null
-# type :string(255)
-# created_at :datetime
-# updated_at :datetime
-# created_by_id :integer
-# invite_email :string(255)
-# invite_token :string(255)
-# invite_accepted_at :datetime
-#
-
require 'spec_helper'
describe ProjectMember, models: true do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 5bf3b8e609e..06feeb1bbba 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -703,16 +703,24 @@ describe MergeRequest, models: true do
describe "#environments" do
let(:project) { create(:project) }
- let!(:environment) { create(:environment, project: project) }
- let!(:environment1) { create(:environment, project: project) }
- let!(:environment2) { create(:environment, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
it 'selects deployed environments' do
- create(:deployment, environment: environment, sha: project.commit('master').id)
- create(:deployment, environment: environment1, sha: project.commit('feature').id)
+ environments = create_list(:environment, 3, project: project)
+ create(:deployment, environment: environments.first, sha: project.commit('master').id)
+ create(:deployment, environment: environments.second, sha: project.commit('feature').id)
- expect(merge_request.environments).to eq [environment]
+ expect(merge_request.environments).to eq [environments.first]
+ end
+
+ context 'without a diff_head_commit' do
+ before do
+ expect(merge_request).to receive(:diff_head_commit).and_return(nil)
+ end
+
+ it 'returns an empty array' do
+ expect(merge_request.environments).to be_empty
+ end
end
end
@@ -1038,4 +1046,81 @@ describe MergeRequest, models: true do
end
end
end
+
+ describe '#closed_without_source_project?' do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:fork_project) { create(:project, forked_from_project: project, namespace: user.namespace) }
+ let(:destroy_service) { Projects::DestroyService.new(fork_project, user) }
+
+ context 'when the merge request is closed' do
+ let(:closed_merge_request) do
+ create(:closed_merge_request,
+ source_project: fork_project,
+ target_project: project)
+ end
+
+ it 'returns false if the source project exists' do
+ expect(closed_merge_request.closed_without_source_project?).to be_falsey
+ end
+
+ it 'returns true if the source project does not exist' do
+ destroy_service.execute
+ closed_merge_request.reload
+
+ expect(closed_merge_request.closed_without_source_project?).to be_truthy
+ end
+ end
+
+ context 'when the merge request is open' do
+ it 'returns false' do
+ expect(subject.closed_without_source_project?).to be_falsey
+ end
+ end
+ end
+
+ describe '#reopenable?' do
+ context 'when the merge request is closed' do
+ it 'returns true' do
+ subject.close
+
+ expect(subject.reopenable?).to be_truthy
+ end
+
+ context 'forked project' do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:fork_project) { create(:project, forked_from_project: project, namespace: user.namespace) }
+ let(:merge_request) do
+ create(:closed_merge_request,
+ source_project: fork_project,
+ target_project: project)
+ end
+
+ it 'returns false if unforked' do
+ Projects::UnlinkForkService.new(fork_project, user).execute
+
+ expect(merge_request.reload.reopenable?).to be_falsey
+ end
+
+ it 'returns false if the source project is deleted' do
+ Projects::DestroyService.new(fork_project, user).execute
+
+ expect(merge_request.reload.reopenable?).to be_falsey
+ end
+
+ it 'returns false if the merge request is merged' do
+ merge_request.update_attributes(state: 'merged')
+
+ expect(merge_request.reload.reopenable?).to be_falsey
+ end
+ end
+ end
+
+ context 'when the merge request is opened' do
+ it 'returns false' do
+ expect(subject.reopenable?).to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/models/project_services/asana_service_spec.rb b/spec/models/project_services/asana_service_spec.rb
index dc702cfc42c..8e5145e824b 100644
--- a/spec/models/project_services/asana_service_spec.rb
+++ b/spec/models/project_services/asana_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe AsanaService, models: true do
diff --git a/spec/models/project_services/assembla_service_spec.rb b/spec/models/project_services/assembla_service_spec.rb
index d672d80156c..4c5acb7990b 100644
--- a/spec/models/project_services/assembla_service_spec.rb
+++ b/spec/models/project_services/assembla_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe AssemblaService, models: true do
diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb
index 9ae461f8c2d..d7e1a4e3b6c 100644
--- a/spec/models/project_services/bamboo_service_spec.rb
+++ b/spec/models/project_services/bamboo_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe BambooService, models: true do
diff --git a/spec/models/project_services/bugzilla_service_spec.rb b/spec/models/project_services/bugzilla_service_spec.rb
index a6d9717ccb5..739cc72b2ff 100644
--- a/spec/models/project_services/bugzilla_service_spec.rb
+++ b/spec/models/project_services/bugzilla_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe BugzillaService, models: true do
diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb
index 0866e1532dd..6f65beb79d0 100644
--- a/spec/models/project_services/buildkite_service_spec.rb
+++ b/spec/models/project_services/buildkite_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe BuildkiteService, models: true do
diff --git a/spec/models/project_services/campfire_service_spec.rb b/spec/models/project_services/campfire_service_spec.rb
index c76ae21421b..a3b9d084a75 100644
--- a/spec/models/project_services/campfire_service_spec.rb
+++ b/spec/models/project_services/campfire_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe CampfireService, models: true do
diff --git a/spec/models/project_services/custom_issue_tracker_service_spec.rb b/spec/models/project_services/custom_issue_tracker_service_spec.rb
index ff976f8ec59..7020667ea58 100644
--- a/spec/models/project_services/custom_issue_tracker_service_spec.rb
+++ b/spec/models/project_services/custom_issue_tracker_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe CustomIssueTrackerService, models: true do
diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb
index 8ef892259f2..f13bb1e8adf 100644
--- a/spec/models/project_services/drone_ci_service_spec.rb
+++ b/spec/models/project_services/drone_ci_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe DroneCiService, models: true do
diff --git a/spec/models/project_services/external_wiki_service_spec.rb b/spec/models/project_services/external_wiki_service_spec.rb
index d7c5ea95d71..342d86aeca9 100644
--- a/spec/models/project_services/external_wiki_service_spec.rb
+++ b/spec/models/project_services/external_wiki_service_spec.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require 'spec_helper'
describe ExternalWikiService, models: true do
diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb
index d2557019756..d6db02d6e76 100644
--- a/spec/models/project_services/flowdock_service_spec.rb
+++ b/spec/models/project_services/flowdock_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe FlowdockService, models: true do
diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb
index 3d0b6c9816b..529044d1d8b 100644
--- a/spec/models/project_services/gemnasium_service_spec.rb
+++ b/spec/models/project_services/gemnasium_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe GemnasiumService, models: true do
diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
index 8ef79a17d50..652804fb444 100644
--- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
+++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe GitlabIssueTrackerService, models: true do
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index 34eafbe555d..cf713684463 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe HipchatService, models: true do
diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb
index ffb17fd3259..f8c45b37561 100644
--- a/spec/models/project_services/irker_service_spec.rb
+++ b/spec/models/project_services/irker_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
require 'socket'
require 'json'
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 9037ca5cc20..b48a3176007 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe JiraService, models: true do
diff --git a/spec/models/project_services/pivotaltracker_service_spec.rb b/spec/models/project_services/pivotaltracker_service_spec.rb
index d098d988521..45b2f1068bf 100644
--- a/spec/models/project_services/pivotaltracker_service_spec.rb
+++ b/spec/models/project_services/pivotaltracker_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe PivotaltrackerService, models: true do
diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb
index 5959c81577d..8fc92a9ab51 100644
--- a/spec/models/project_services/pushover_service_spec.rb
+++ b/spec/models/project_services/pushover_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe PushoverService, models: true do
diff --git a/spec/models/project_services/redmine_service_spec.rb b/spec/models/project_services/redmine_service_spec.rb
index 7d14f6e8280..b8679cd2563 100644
--- a/spec/models/project_services/redmine_service_spec.rb
+++ b/spec/models/project_services/redmine_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe RedmineService, models: true do
diff --git a/spec/models/project_services/slack_service/build_message_spec.rb b/spec/models/project_services/slack_service/build_message_spec.rb
index 7fcfdf0eacd..452f4e2782c 100644
--- a/spec/models/project_services/slack_service/build_message_spec.rb
+++ b/spec/models/project_services/slack_service/build_message_spec.rb
@@ -10,7 +10,7 @@ describe SlackService::BuildMessage do
tag: false,
project_name: 'project_name',
- project_url: 'somewhere.com',
+ project_url: 'example.gitlab.com',
commit: {
status: status,
@@ -20,42 +20,38 @@ describe SlackService::BuildMessage do
}
end
- context 'succeeded' do
+ let(:message) { build_message }
+
+ context 'build succeeded' do
let(:status) { 'success' }
let(:color) { 'good' }
let(:duration) { 10 }
-
+ let(:message) { build_message('passed') }
+
it 'returns a message with information about succeeded build' do
- message = '<somewhere.com|project_name>: Commit <somewhere.com/commit/97de212e80737a608d939f648d959671fb0a0142/builds|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker passed in 10 seconds'
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
- context 'failed' do
+ context 'build failed' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 10 }
it 'returns a message with information about failed build' do
- message = '<somewhere.com|project_name>: Commit <somewhere.com/commit/97de212e80737a608d939f648d959671fb0a0142/builds|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker failed in 10 seconds'
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
- end
-
- describe '#seconds_name' do
- let(:status) { 'failed' }
- let(:color) { 'danger' }
- let(:duration) { 1 }
+ end
- it 'returns seconds as singular when there is only one' do
- message = '<somewhere.com|project_name>: Commit <somewhere.com/commit/97de212e80737a608d939f648d959671fb0a0142/builds|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker failed in 1 second'
- expect(subject.pretext).to be_empty
- expect(subject.fallback).to eq(message)
- expect(subject.attachments).to eq([text: message, color: color])
- end
+ def build_message(status_text = status)
+ "<example.gitlab.com|project_name>:" \
+ " Commit <example.gitlab.com/commit/" \
+ "97de212e80737a608d939f648d959671fb0a0142/builds|97de212e>" \
+ " of <example.gitlab.com/commits/develop|develop> branch" \
+ " by hacker #{status_text} in #{duration} #{'second'.pluralize(duration)}"
end
end
diff --git a/spec/models/project_services/slack_service/pipeline_message_spec.rb b/spec/models/project_services/slack_service/pipeline_message_spec.rb
new file mode 100644
index 00000000000..babb3909f56
--- /dev/null
+++ b/spec/models/project_services/slack_service/pipeline_message_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+describe SlackService::PipelineMessage do
+ subject { SlackService::PipelineMessage.new(args) }
+
+ let(:args) do
+ {
+ object_attributes: {
+ id: 123,
+ sha: '97de212e80737a608d939f648d959671fb0a0142',
+ tag: false,
+ ref: 'develop',
+ status: status,
+ duration: duration
+ },
+ project: { path_with_namespace: 'project_name',
+ web_url: 'example.gitlab.com' },
+ commit: { author_name: 'hacker' }
+ }
+ end
+
+ let(:message) { build_message }
+
+ context 'pipeline succeeded' do
+ let(:status) { 'success' }
+ let(:color) { 'good' }
+ let(:duration) { 10 }
+ let(:message) { build_message('passed') }
+
+ it 'returns a message with information about succeeded build' do
+ expect(subject.pretext).to be_empty
+ expect(subject.fallback).to eq(message)
+ expect(subject.attachments).to eq([text: message, color: color])
+ end
+ end
+
+ context 'pipeline failed' do
+ let(:status) { 'failed' }
+ let(:color) { 'danger' }
+ let(:duration) { 10 }
+
+ it 'returns a message with information about failed build' do
+ expect(subject.pretext).to be_empty
+ expect(subject.fallback).to eq(message)
+ expect(subject.attachments).to eq([text: message, color: color])
+ end
+ end
+
+ def build_message(status_text = status)
+ "<example.gitlab.com|project_name>:" \
+ " Pipeline <example.gitlab.com/pipelines/123|97de212e>" \
+ " of <example.gitlab.com/commits/develop|develop> branch" \
+ " by hacker #{status_text} in #{duration} #{'second'.pluralize(duration)}"
+ end
+end
diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb
index 28af68d13b4..c07a70a8069 100644
--- a/spec/models/project_services/slack_service_spec.rb
+++ b/spec/models/project_services/slack_service_spec.rb
@@ -1,26 +1,9 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe SlackService, models: true do
+ let(:slack) { SlackService.new }
+ let(:webhook_url) { 'https://example.gitlab.com/' }
+
describe "Associations" do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
@@ -42,15 +25,14 @@ describe SlackService, models: true do
end
describe "Execute" do
- let(:slack) { SlackService.new }
let(:user) { create(:user) }
let(:project) { create(:project) }
+ let(:username) { 'slack_username' }
+ let(:channel) { 'slack_channel' }
+
let(:push_sample_data) do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
- let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' }
- let(:username) { 'slack_username' }
- let(:channel) { 'slack_channel' }
before do
allow(slack).to receive_messages(
@@ -212,10 +194,8 @@ describe SlackService, models: true do
end
describe "Note events" do
- let(:slack) { SlackService.new }
let(:user) { create(:user) }
let(:project) { create(:project, creator_id: user.id) }
- let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' }
before do
allow(slack).to receive_messages(
@@ -285,4 +265,63 @@ describe SlackService, models: true do
end
end
end
+
+ describe 'Pipeline events' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ let(:pipeline) do
+ create(:ci_pipeline,
+ project: project, status: status,
+ sha: project.commit.sha, ref: project.default_branch)
+ end
+
+ before do
+ allow(slack).to receive_messages(
+ project: project,
+ service_hook: true,
+ webhook: webhook_url
+ )
+ end
+
+ shared_examples 'call Slack API' do
+ before do
+ WebMock.stub_request(:post, webhook_url)
+ end
+
+ it 'calls Slack API for pipeline events' do
+ data = Gitlab::DataBuilder::Pipeline.build(pipeline)
+ slack.execute(data)
+
+ expect(WebMock).to have_requested(:post, webhook_url).once
+ end
+ end
+
+ context 'with failed pipeline' do
+ let(:status) { 'failed' }
+
+ it_behaves_like 'call Slack API'
+ end
+
+ context 'with succeeded pipeline' do
+ let(:status) { 'success' }
+
+ context 'with default to notify_only_broken_pipelines' do
+ it 'does not call Slack API for pipeline events' do
+ data = Gitlab::DataBuilder::Pipeline.build(pipeline)
+ result = slack.execute(data)
+
+ expect(result).to be_falsy
+ end
+ end
+
+ context 'with setting notify_only_broken_pipelines to false' do
+ before do
+ slack.notify_only_broken_pipelines = false
+ end
+
+ it_behaves_like 'call Slack API'
+ end
+ end
+ end
end
diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb
index 474715d24c3..f7e878844dc 100644
--- a/spec/models/project_services/teamcity_service_spec.rb
+++ b/spec/models/project_services/teamcity_service_spec.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# id :integer not null, primary key
-# type :string(255)
-# title :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# active :boolean default(FALSE), not null
-# properties :text
-# template :boolean default(FALSE)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-#
-
require 'spec_helper'
describe TeamcityService, models: true do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 4a41fafb84d..a388ff703a6 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -6,6 +6,7 @@ describe Project, models: true do
it { is_expected.to belong_to(:namespace) }
it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to have_many(:users) }
+ it { is_expected.to have_many(:services) }
it { is_expected.to have_many(:events).dependent(:destroy) }
it { is_expected.to have_many(:merge_requests).dependent(:destroy) }
it { is_expected.to have_many(:issues).dependent(:destroy) }
@@ -24,6 +25,30 @@ describe Project, models: true do
it { is_expected.to have_one(:pushover_service).dependent(:destroy) }
it { is_expected.to have_one(:asana_service).dependent(:destroy) }
it { is_expected.to have_one(:board).dependent(:destroy) }
+ it { is_expected.to have_one(:campfire_service).dependent(:destroy) }
+ it { is_expected.to have_one(:drone_ci_service).dependent(:destroy) }
+ it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) }
+ it { is_expected.to have_one(:builds_email_service).dependent(:destroy) }
+ it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) }
+ it { is_expected.to have_one(:irker_service).dependent(:destroy) }
+ it { is_expected.to have_one(:pivotaltracker_service).dependent(:destroy) }
+ it { is_expected.to have_one(:hipchat_service).dependent(:destroy) }
+ it { is_expected.to have_one(:flowdock_service).dependent(:destroy) }
+ it { is_expected.to have_one(:assembla_service).dependent(:destroy) }
+ it { is_expected.to have_one(:gemnasium_service).dependent(:destroy) }
+ it { is_expected.to have_one(:buildkite_service).dependent(:destroy) }
+ it { is_expected.to have_one(:bamboo_service).dependent(:destroy) }
+ it { is_expected.to have_one(:teamcity_service).dependent(:destroy) }
+ it { is_expected.to have_one(:jira_service).dependent(:destroy) }
+ it { is_expected.to have_one(:redmine_service).dependent(:destroy) }
+ it { is_expected.to have_one(:custom_issue_tracker_service).dependent(:destroy) }
+ it { is_expected.to have_one(:bugzilla_service).dependent(:destroy) }
+ it { is_expected.to have_one(:gitlab_issue_tracker_service).dependent(:destroy) }
+ it { is_expected.to have_one(:external_wiki_service).dependent(:destroy) }
+ it { is_expected.to have_one(:project_feature).dependent(:destroy) }
+ it { is_expected.to have_one(:import_data).class_name('ProjectImportData').dependent(:destroy) }
+ it { is_expected.to have_one(:last_event).class_name('Event') }
+ it { is_expected.to have_one(:forked_from_project).through(:forked_project_link) }
it { is_expected.to have_many(:commit_statuses) }
it { is_expected.to have_many(:pipelines) }
it { is_expected.to have_many(:builds) }
@@ -31,9 +56,16 @@ describe Project, models: true do
it { is_expected.to have_many(:runners) }
it { is_expected.to have_many(:variables) }
it { is_expected.to have_many(:triggers) }
+ it { is_expected.to have_many(:labels).dependent(:destroy) }
+ it { is_expected.to have_many(:users_star_projects).dependent(:destroy) }
it { is_expected.to have_many(:environments).dependent(:destroy) }
it { is_expected.to have_many(:deployments).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
+ it { is_expected.to have_many(:releases).dependent(:destroy) }
+ it { is_expected.to have_many(:lfs_objects_projects).dependent(:destroy) }
+ it { is_expected.to have_many(:project_group_links).dependent(:destroy) }
+ it { is_expected.to have_many(:notification_settings).dependent(:destroy) }
+ it { is_expected.to have_many(:forks).through(:forked_project_links) }
describe '#members & #requesters' do
let(:project) { create(:project) }
@@ -178,7 +210,7 @@ describe Project, models: true do
expect(project.runners_token).not_to eq('')
end
- it 'does not set an random toke if one provided' do
+ it 'does not set an random token if one provided' do
project = FactoryGirl.create :empty_project, runners_token: 'my-token'
expect(project.runners_token).to eq('my-token')
end
@@ -276,20 +308,23 @@ describe Project, models: true do
end
describe 'last_activity methods' do
- let(:project) { create(:project) }
- let(:last_event) { double(created_at: Time.now) }
+ let(:timestamp) { Time.now - 2.hours }
+ let(:project) { create(:project, created_at: timestamp, updated_at: timestamp) }
describe 'last_activity' do
it 'alias last_activity to last_event' do
- allow(project).to receive(:last_event).and_return(last_event)
+ last_event = create(:event, project: project)
+
expect(project.last_activity).to eq(last_event)
end
end
describe 'last_activity_date' do
it 'returns the creation date of the project\'s last event if present' do
- create(:event, project: project)
- expect(project.last_activity_at.to_i).to eq(last_event.created_at.to_i)
+ expect_any_instance_of(Event).to receive(:try_obtain_lease).and_return(true)
+ new_event = create(:event, project: project, created_at: Time.now)
+
+ expect(project.last_activity_at.to_i).to eq(new_event.created_at.to_i)
end
it 'returns the project\'s last update date if it has no events' do
@@ -1385,6 +1420,68 @@ describe Project, models: true do
end
end
+ describe '#lfs_enabled?' do
+ let(:project) { create(:project) }
+
+ shared_examples 'project overrides group' do
+ it 'returns true when enabled in project' do
+ project.update_attribute(:lfs_enabled, true)
+
+ expect(project.lfs_enabled?).to be_truthy
+ end
+
+ it 'returns false when disabled in project' do
+ project.update_attribute(:lfs_enabled, false)
+
+ expect(project.lfs_enabled?).to be_falsey
+ end
+
+ it 'returns the value from the namespace, when no value is set in project' do
+ expect(project.lfs_enabled?).to eq(project.namespace.lfs_enabled?)
+ end
+ end
+
+ context 'LFS disabled in group' do
+ before do
+ project.namespace.update_attribute(:lfs_enabled, false)
+ enable_lfs
+ end
+
+ it_behaves_like 'project overrides group'
+ end
+
+ context 'LFS enabled in group' do
+ before do
+ project.namespace.update_attribute(:lfs_enabled, true)
+ enable_lfs
+ end
+
+ it_behaves_like 'project overrides group'
+ end
+
+ describe 'LFS disabled globally' do
+ shared_examples 'it always returns false' do
+ it do
+ expect(project.lfs_enabled?).to be_falsey
+ expect(project.namespace.lfs_enabled?).to be_falsey
+ end
+ end
+
+ context 'when no values are set' do
+ it_behaves_like 'it always returns false'
+ end
+
+ context 'when all values are set to true' do
+ before do
+ project.namespace.update_attribute(:lfs_enabled, true)
+ project.update_attribute(:lfs_enabled, true)
+ end
+
+ it_behaves_like 'it always returns false'
+ end
+ end
+ end
+
describe '.where_paths_in' do
context 'without any paths' do
it 'returns an empty relation' do
@@ -1497,4 +1594,60 @@ describe Project, models: true do
project.change_head(project.default_branch)
end
end
+
+ describe '#pushes_since_gc' do
+ let(:project) { create(:project) }
+
+ after do
+ project.reset_pushes_since_gc
+ end
+
+ context 'without any pushes' do
+ it 'returns 0' do
+ expect(project.pushes_since_gc).to eq(0)
+ end
+ end
+
+ context 'with a number of pushes' do
+ it 'returns the number of pushes' do
+ 3.times { project.increment_pushes_since_gc }
+
+ expect(project.pushes_since_gc).to eq(3)
+ end
+ end
+ end
+
+ describe '#increment_pushes_since_gc' do
+ let(:project) { create(:project) }
+
+ after do
+ project.reset_pushes_since_gc
+ end
+
+ it 'increments the number of pushes since the last GC' do
+ 3.times { project.increment_pushes_since_gc }
+
+ expect(project.pushes_since_gc).to eq(3)
+ end
+ end
+
+ describe '#reset_pushes_since_gc' do
+ let(:project) { create(:project) }
+
+ after do
+ project.reset_pushes_since_gc
+ end
+
+ it 'resets the number of pushes since the last GC' do
+ 3.times { project.increment_pushes_since_gc }
+
+ project.reset_pushes_since_gc
+
+ expect(project.pushes_since_gc).to eq(0)
+ end
+ end
+
+ def enable_lfs
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index afc7dc5db81..94681004c96 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -186,32 +186,6 @@ describe Repository, models: true do
it { is_expected.to be_an String }
it { expect(subject.lines[2]).to eq("master:CHANGELOG:188: - Feature: Replace teams with group membership\n") }
end
-
- describe 'parsing result' do
- subject { repository.parse_search_result(search_result) }
- let(:search_result) { results.first }
-
- it { is_expected.to be_an OpenStruct }
- it { expect(subject.filename).to eq('CHANGELOG') }
- it { expect(subject.basename).to eq('CHANGELOG') }
- it { expect(subject.ref).to eq('master') }
- it { expect(subject.startline).to eq(186) }
- it { expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n") }
-
- context "when filename has extension" do
- let(:search_result) { "master:CONTRIBUTE.md:5:- [Contribute to GitLab](#contribute-to-gitlab)\n" }
-
- it { expect(subject.filename).to eq('CONTRIBUTE.md') }
- it { expect(subject.basename).to eq('CONTRIBUTE') }
- end
-
- context "when file under directory" do
- let(:search_result) { "master:a/b/c.md:5:a b c\n" }
-
- it { expect(subject.filename).to eq('a/b/c.md') }
- it { expect(subject.basename).to eq('a/b/c') }
- end
- end
end
describe "#changelog" do
@@ -441,7 +415,7 @@ describe Repository, models: true do
end
end
- describe '#commit_with_hooks' do
+ describe '#update_branch_with_hooks' do
let(:old_rev) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } # git rev-parse feature
let(:new_rev) { 'a74ae73c1ccde9b974a70e82b901588071dc142a' } # commit whose parent is old_rev
@@ -454,31 +428,64 @@ describe Repository, models: true do
it 'runs without errors' do
expect do
- repository.commit_with_hooks(user, 'feature') { new_rev }
+ repository.update_branch_with_hooks(user, 'feature') { new_rev }
end.not_to raise_error
end
it 'ensures the autocrlf Git option is set to :input' do
expect(repository).to receive(:update_autocrlf_option)
- repository.commit_with_hooks(user, 'feature') { new_rev }
+ repository.update_branch_with_hooks(user, 'feature') { new_rev }
end
context "when the branch wasn't empty" do
it 'updates the head' do
expect(repository.find_branch('feature').target.id).to eq(old_rev)
- repository.commit_with_hooks(user, 'feature') { new_rev }
+ repository.update_branch_with_hooks(user, 'feature') { new_rev }
expect(repository.find_branch('feature').target.id).to eq(new_rev)
end
end
end
+ context 'when the update adds more than one commit' do
+ it 'runs without errors' do
+ old_rev = '33f3729a45c02fc67d00adb1b8bca394b0e761d9'
+
+ # old_rev is an ancestor of new_rev
+ expect(repository.rugged.merge_base(old_rev, new_rev)).to eq(old_rev)
+
+ # old_rev is not a direct ancestor (parent) of new_rev
+ expect(repository.rugged.lookup(new_rev).parent_ids).not_to include(old_rev)
+
+ branch = 'feature-ff-target'
+ repository.add_branch(user, branch, old_rev)
+
+ expect { repository.update_branch_with_hooks(user, branch) { new_rev } }.not_to raise_error
+ end
+ end
+
+ context 'when the update would remove commits from the target branch' do
+ it 'raises an exception' do
+ branch = 'master'
+ old_rev = repository.find_branch(branch).target.sha
+
+ # The 'master' branch is NOT an ancestor of new_rev.
+ expect(repository.rugged.merge_base(old_rev, new_rev)).not_to eq(old_rev)
+
+ # Updating 'master' to new_rev would lose the commits on 'master' that
+ # are not contained in new_rev. This should not be allowed.
+ expect do
+ repository.update_branch_with_hooks(user, branch) { new_rev }
+ end.to raise_error(Repository::CommitError)
+ end
+ 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.commit_with_hooks(user, 'feature') { new_rev }
+ repository.update_branch_with_hooks(user, 'feature') { new_rev }
end.to raise_error(GitHooksService::PreReceiveError)
end
end
@@ -497,7 +504,7 @@ describe Repository, models: true do
expect(repository).to receive(:expire_has_visible_content_cache)
expect(repository).to receive(:expire_branch_count_cache)
- repository.commit_with_hooks(user, 'new-feature') { new_rev }
+ repository.update_branch_with_hooks(user, 'new-feature') { new_rev }
end
end