diff options
Diffstat (limited to 'spec/models')
72 files changed, 767 insertions, 1080 deletions
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index dfbac7b4004..5f64453a35f 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -36,6 +36,22 @@ describe ApplicationSetting, models: true do it { expect(setting).to be_valid } + describe 'validations' do + let(:http) { 'http://example.com' } + let(:https) { 'https://example.com' } + let(:ftp) { 'ftp://example.com' } + + it { is_expected.to allow_value(nil).for(:home_page_url) } + it { is_expected.to allow_value(http).for(:home_page_url) } + it { is_expected.to allow_value(https).for(:home_page_url) } + it { is_expected.not_to allow_value(ftp).for(:home_page_url) } + + it { is_expected.to allow_value(nil).for(:after_sign_out_path) } + it { is_expected.to allow_value(http).for(:after_sign_out_path) } + 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) } + end + context 'restricted signup domains' do it 'set single domain' do setting.restricted_signup_domains_raw = 'example.com' @@ -57,26 +73,4 @@ describe ApplicationSetting, models: true do expect(setting.restricted_signup_domains).to eq(['example.com', '*.example.com']) end end - - context 'shared runners' do - let(:gl_project) { create(:empty_project) } - - before do - allow_any_instance_of(Project).to receive(:current_application_settings).and_return(setting) - end - - subject { gl_project.ensure_gitlab_ci_project.shared_runners_enabled } - - context 'enabled' do - before { setting.update_attributes(shared_runners_enabled: true) } - - it { is_expected.to be_truthy } - end - - context 'disabled' do - before { setting.update_attributes(shared_runners_enabled: false) } - - it { is_expected.to be_falsey } - end - end end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index d80748f23a4..e4cac105110 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -15,11 +15,26 @@ require 'spec_helper' -describe BroadcastMessage do +describe BroadcastMessage, models: true do subject { create(:broadcast_message) } it { is_expected.to be_valid } + describe 'validations' do + let(:triplet) { '#000' } + let(:hex) { '#AABBCC' } + + it { is_expected.to allow_value(nil).for(:color) } + it { is_expected.to allow_value(triplet).for(:color) } + it { is_expected.to allow_value(hex).for(:color) } + it { is_expected.not_to allow_value('000').for(:color) } + + it { is_expected.to allow_value(nil).for(:font) } + it { is_expected.to allow_value(triplet).for(:font) } + it { is_expected.to allow_value(hex).for(:font) } + it { is_expected.not_to allow_value('000').for(:font) } + end + describe :current do it "should return last message if time match" do broadcast_message = create(:broadcast_message, starts_at: Time.now.yesterday, ends_at: Time.now.tomorrow) diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 839b4c6b16e..96b6f1dbca6 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -25,10 +25,9 @@ require 'spec_helper' -describe Ci::Build do - let(:project) { FactoryGirl.create :ci_project } - let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } - let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } +describe Ci::Build, models: true do + let(:project) { FactoryGirl.create :empty_project } + let(:commit) { FactoryGirl.create :ci_commit, project: project } let(:build) { FactoryGirl.create :ci_build, commit: commit } it { is_expected.to validate_presence_of :ref } @@ -112,7 +111,7 @@ describe Ci::Build do let(:token) { 'my_secret_token' } before do - build.project.update_attributes(token: token) + build.project.update_attributes(runners_token: token) build.update_attributes(trace: token) end @@ -120,11 +119,12 @@ describe Ci::Build do end end - describe :timeout do - subject { build.timeout } - - it { is_expected.to eq(commit.project.timeout) } - end + # TODO: build timeout + # describe :timeout do + # subject { build.timeout } + # + # it { is_expected.to eq(commit.project.timeout) } + # end describe :options do let(:options) do @@ -140,11 +140,12 @@ describe Ci::Build do it { is_expected.to eq(options) } end - describe :allow_git_fetch do - subject { build.allow_git_fetch } - - it { is_expected.to eq(project.allow_git_fetch) } - end + # TODO: allow_git_fetch + # describe :allow_git_fetch do + # subject { build.allow_git_fetch } + # + # it { is_expected.to eq(project.allow_git_fetch) } + # end describe :project do subject { build.project } @@ -164,12 +165,6 @@ describe Ci::Build do it { is_expected.to eq(project.name) } end - describe :repo_url do - subject { build.repo_url } - - it { is_expected.to eq(project.repo_url_with_auth) } - end - describe :extract_coverage do context 'valid content & regex' do subject { build.extract_coverage('Coverage 1033 / 1051 LOC (98.29%) covered', '\(\d+.\d+\%\) covered') } @@ -266,40 +261,6 @@ describe Ci::Build do end end - describe :project_recipients do - let(:pusher_email) { 'pusher@gitlab.test' } - let(:user) { User.new(notification_email: pusher_email) } - subject { build.project_recipients } - - before do - build.update_attributes(user: user) - end - - it 'should return pusher_email as only recipient when no additional recipients are given' do - project.update_attributes(email_add_pusher: true, - email_recipients: '') - is_expected.to eq([pusher_email]) - end - - it 'should return pusher_email and additional recipients' do - project.update_attributes(email_add_pusher: true, - email_recipients: 'rec1 rec2') - is_expected.to eq(['rec1', 'rec2', pusher_email]) - end - - it 'should return recipients' do - project.update_attributes(email_add_pusher: false, - email_recipients: 'rec1 rec2') - is_expected.to eq(['rec1', 'rec2']) - end - - it 'should return unique recipients only' do - project.update_attributes(email_add_pusher: true, - email_recipients: "rec1 rec1 #{pusher_email}") - is_expected.to eq(['rec1', pusher_email]) - end - end - describe :can_be_served? do let(:runner) { FactoryGirl.create :ci_specific_runner } @@ -415,4 +376,18 @@ describe Ci::Build do is_expected.to_not be_nil end end + + describe :repo_url do + let(:build) { FactoryGirl.create :ci_build } + let(:project) { build.project } + + subject { build.repo_url } + + it { is_expected.to be_a(String) } + it { is_expected.to end_with(".git") } + it { is_expected.to start_with(project.web_url[0..6]) } + it { is_expected.to include(build.token) } + it { is_expected.to include('gitlab-ci-token') } + it { is_expected.to include(project.web_url[7..-1]) } + end end diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index a13f6458cac..b193e16e7f8 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -13,17 +13,16 @@ # tag :boolean default(FALSE) # yaml_errors :text # committed_at :datetime -# gl_project_id :integer +# project_id :integer # require 'spec_helper' -describe Ci::Commit do - let(:project) { FactoryGirl.create :ci_project } - let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } - let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } +describe Ci::Commit, models: true do + let(:project) { FactoryGirl.create :empty_project } + let(:commit) { FactoryGirl.create :ci_commit, project: project } - it { is_expected.to belong_to(:gl_project) } + it { is_expected.to belong_to(:project) } it { is_expected.to have_many(:statuses) } it { is_expected.to have_many(:trigger_requests) } it { is_expected.to have_many(:builds) } @@ -37,16 +36,16 @@ describe Ci::Commit do let(:project) { FactoryGirl.create :empty_project } it 'returns ordered list of commits' do - commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project - commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project + commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: project + commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hours.ago, project: project expect(project.ci_commits.ordered).to eq([commit2, commit1]) end it 'returns commits ordered by committed_at and id, with nulls last' do - commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project - commit2 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project - commit3 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project - commit4 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project + commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: project + commit2 = FactoryGirl.create :ci_commit, committed_at: nil, project: project + commit3 = FactoryGirl.create :ci_commit, committed_at: 2.hours.ago, project: project + commit4 = FactoryGirl.create :ci_commit, committed_at: nil, project: project expect(project.ci_commits.ordered).to eq([commit2, commit4, commit3, commit1]) end end @@ -162,7 +161,7 @@ describe Ci::Commit do end describe :create_builds do - let!(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } + let!(:commit) { FactoryGirl.create :ci_commit, project: project } def create_builds(trigger_request = nil) commit.create_builds('master', false, nil, trigger_request) @@ -390,9 +389,8 @@ describe Ci::Commit do end describe "coverage" do - let(:project) { FactoryGirl.create :ci_project, coverage_regex: "/.*/" } - let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } - let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } + let(:project) { FactoryGirl.create :empty_project, build_coverage_regex: "/.*/" } + let(:commit) { FactoryGirl.create :ci_commit, project: project } it "calculates average when there are two builds with coverage" do FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit diff --git a/spec/models/ci/project_services/hip_chat_message_spec.rb b/spec/models/ci/project_services/hip_chat_message_spec.rb deleted file mode 100644 index e23d6ae2c28..00000000000 --- a/spec/models/ci/project_services/hip_chat_message_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'spec_helper' - -describe Ci::HipChatMessage do - subject { Ci::HipChatMessage.new(build) } - - let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - - let(:build) do - commit.builds.first - end - - context 'when all matrix builds succeed' do - it 'returns a successful message' do - commit.create_builds('master', false, nil) - commit.builds.update_all(status: "success") - commit.reload - - expect(subject.status_color).to eq 'green' - expect(subject.notify?).to be_falsey - expect(subject.to_s).to match(/Commit #\d+/) - expect(subject.to_s).to match(/Successful in \d+ second\(s\)\./) - end - end - - context 'when at least one matrix build fails' do - it 'returns a failure message' do - commit.create_builds('master', false, nil) - first_build = commit.builds.first - second_build = commit.builds.last - first_build.update(status: "success") - second_build.update(status: "failed") - - expect(subject.status_color).to eq 'red' - expect(subject.notify?).to be_truthy - expect(subject.to_s).to match(/Commit #\d+/) - expect(subject.to_s).to match(/Failed in \d+ second\(s\)\./) - end - end -end diff --git a/spec/models/ci/project_services/hip_chat_service_spec.rb b/spec/models/ci/project_services/hip_chat_service_spec.rb deleted file mode 100644 index d9ccc855edf..00000000000 --- a/spec/models/ci/project_services/hip_chat_service_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - - -require 'spec_helper' - -describe Ci::HipChatService do - - describe "Validations" do - - context "active" do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :hipchat_room } - it { is_expected.to validate_presence_of :hipchat_token } - - end - end - - describe "Execute" do - - let(:service) { Ci::HipChatService.new } - let(:commit) { FactoryGirl.create :ci_commit } - let(:build) { FactoryGirl.create :ci_build, commit: commit, status: 'failed' } - let(:api_url) { 'https://api.hipchat.com/v2/room/123/notification?auth_token=a1b2c3d4e5f6' } - - before do - allow(service).to receive_messages( - project: commit.project, - project_id: commit.project_id, - notify_only_broken_builds: false, - hipchat_room: 123, - hipchat_token: 'a1b2c3d4e5f6' - ) - - WebMock.stub_request(:post, api_url) - end - - - it "should call the HipChat API" do - service.execute(build) - Ci::HipChatNotifierWorker.drain - - expect( WebMock ).to have_requested(:post, api_url).once - end - - it "calls the worker with expected arguments" do - expect( Ci::HipChatNotifierWorker ).to receive(:perform_async) \ - .with(an_instance_of(String), hash_including( - token: 'a1b2c3d4e5f6', - room: 123, - server: 'https://api.hipchat.com', - color: 'red', - notify: true - )) - - service.execute(build) - end - end -end diff --git a/spec/models/ci/project_services/mail_service_spec.rb b/spec/models/ci/project_services/mail_service_spec.rb deleted file mode 100644 index d9b3d34ff15..00000000000 --- a/spec/models/ci/project_services/mail_service_spec.rb +++ /dev/null @@ -1,191 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - -require 'spec_helper' - -describe Ci::MailService do - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - end - end - - describe 'Sends email for' do - let(:mail) { Ci::MailService.new } - let(:user) { User.new(notification_email: 'git@example.com')} - - describe 'failed build' do - let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true) } - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'failed', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_fail_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - end - end - - describe 'successfull build' do - let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true, email_only_broken_builds: false) } - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'success', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successfull build and project has email_recipients' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: false, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'success', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - should_email("jeroen@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successful build and notify only broken builds' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: true, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'success', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email(commit.git_author_email) - should_email("jeroen@example.com") - mail.execute(build) if mail.can_execute?(build) - end - - def should_email(email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successful build and can test service' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: false, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'success', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - build - end - - it do - expect(mail.can_test?).to eq(true) - end - end - - describe 'retried build should not receive email' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: true, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: 'failed', commit: commit, user: user) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - Ci::Build.retry(build) - should_email(commit.git_author_email) - should_email("jeroen@example.com") - mail.execute(build) if mail.can_execute?(build) - end - - def should_email(email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - end -end diff --git a/spec/models/ci/project_services/slack_message_spec.rb b/spec/models/ci/project_services/slack_message_spec.rb deleted file mode 100644 index 8adda6c86cc..00000000000 --- a/spec/models/ci/project_services/slack_message_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -describe Ci::SlackMessage do - subject { Ci::SlackMessage.new(commit) } - - let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - - context 'when all matrix builds succeeded' do - let(:color) { 'good' } - - it 'returns a message with success' do - commit.create_builds('master', false, nil) - commit.builds.update_all(status: "success") - commit.reload - - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Commit') - expect(subject.fallback).to include("\##{commit.id}") - expect(subject.fallback).to include('succeeded') - expect(subject.attachments.first[:fields]).to be_empty - end - end - - context 'when one of matrix builds failed' do - let(:color) { 'danger' } - - it 'returns a message with information about failed build' do - commit.create_builds('master', false, nil) - first_build = commit.builds.first - second_build = commit.builds.last - first_build.update(status: "success") - second_build.update(status: "failed") - - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Commit') - expect(subject.fallback).to include("\##{commit.id}") - expect(subject.fallback).to include('failed') - expect(subject.attachments.first[:fields].size).to eq(1) - expect(subject.attachments.first[:fields].first[:title]).to eq(second_build.name) - expect(subject.attachments.first[:fields].first[:value]).to include("\##{second_build.id}") - end - end -end diff --git a/spec/models/ci/project_services/slack_service_spec.rb b/spec/models/ci/project_services/slack_service_spec.rb deleted file mode 100644 index 1ac7dfe568d..00000000000 --- a/spec/models/ci/project_services/slack_service_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - -require 'spec_helper' - -describe Ci::SlackService do - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :webhook } - end - end - - describe "Execute" do - let(:slack) { Ci::SlackService.new } - let(:commit) { FactoryGirl.create :ci_commit } - let(:build) { FactoryGirl.create :ci_build, commit: commit, status: 'failed' } - let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' } - let(:notify_only_broken_builds) { false } - - before do - allow(slack).to receive_messages( - project: commit.project, - project_id: commit.project_id, - webhook: webhook_url, - notify_only_broken_builds: notify_only_broken_builds - ) - - WebMock.stub_request(:post, webhook_url) - end - - it "should call Slack API" do - slack.execute(build) - Ci::SlackNotifierWorker.drain - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end -end diff --git a/spec/models/ci/project_spec.rb b/spec/models/ci/project_spec.rb deleted file mode 100644 index ac7e38bbcb0..00000000000 --- a/spec/models/ci/project_spec.rb +++ /dev/null @@ -1,246 +0,0 @@ -# == Schema Information -# -# Table name: ci_projects -# -# id :integer not null, primary key -# name :string(255) -# timeout :integer default(3600), not null -# created_at :datetime -# updated_at :datetime -# token :string(255) -# default_ref :string(255) -# path :string(255) -# always_build :boolean default(FALSE), not null -# polling_interval :integer -# public :boolean default(FALSE), not null -# ssh_url_to_repo :string(255) -# gitlab_id :integer -# allow_git_fetch :boolean default(TRUE), not null -# email_recipients :string(255) default(""), not null -# email_add_pusher :boolean default(TRUE), not null -# email_only_broken_builds :boolean default(TRUE), not null -# skip_refs :string(255) -# coverage_regex :string(255) -# shared_runners_enabled :boolean default(FALSE) -# generated_yaml_config :text -# - -require 'spec_helper' - -describe Ci::Project do - let(:project) { FactoryGirl.create :ci_project } - let(:gl_project) { project.gl_project } - subject { project } - - it { is_expected.to have_many(:runner_projects) } - it { is_expected.to have_many(:runners) } - it { is_expected.to have_many(:web_hooks) } - it { is_expected.to have_many(:events) } - it { is_expected.to have_many(:variables) } - it { is_expected.to have_many(:triggers) } - it { is_expected.to have_many(:services) } - - it { is_expected.to validate_presence_of :timeout } - it { is_expected.to validate_presence_of :gitlab_id } - - describe 'before_validation' do - it 'should set an random token if none provided' do - project = FactoryGirl.create :ci_project_without_token - expect(project.token).not_to eq("") - end - - it 'should not set an random toke if one provided' do - project = FactoryGirl.create :ci_project - expect(project.token).to eq("iPWx6WM4lhHNedGfBpPJNP") - end - end - - describe :name_with_namespace do - subject { project.name_with_namespace } - - it { is_expected.to eq(project.name) } - it { is_expected.to eq(gl_project.name_with_namespace) } - end - - describe :path_with_namespace do - subject { project.path_with_namespace } - - it { is_expected.to eq(project.path) } - it { is_expected.to eq(gl_project.path_with_namespace) } - end - - describe :path_with_namespace do - subject { project.web_url } - - it { is_expected.to eq(gl_project.web_url) } - end - - describe :web_url do - subject { project.web_url } - - it { is_expected.to eq(project.gitlab_url) } - it { is_expected.to eq(gl_project.web_url) } - end - - describe :http_url_to_repo do - subject { project.http_url_to_repo } - - it { is_expected.to eq(gl_project.http_url_to_repo) } - end - - describe :ssh_url_to_repo do - subject { project.ssh_url_to_repo } - - it { is_expected.to eq(gl_project.ssh_url_to_repo) } - end - - describe :commits do - subject { project.commits } - - before do - FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: gl_project - end - - it { is_expected.to eq(gl_project.ci_commits) } - end - - describe :builds do - subject { project.builds } - - before do - commit = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: gl_project - FactoryGirl.create :ci_build, commit: commit - end - - it { is_expected.to eq(gl_project.ci_builds) } - end - - describe "ordered_by_last_commit_date" do - it "returns ordered projects" do - newest_project = FactoryGirl.create :empty_project - newest_ci_project = newest_project.ensure_gitlab_ci_project - oldest_project = FactoryGirl.create :empty_project - oldest_ci_project = oldest_project.ensure_gitlab_ci_project - project_without_commits = FactoryGirl.create :empty_project - ci_project_without_commits = project_without_commits.ensure_gitlab_ci_project - - FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: newest_project - FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: oldest_project - - expect(Ci::Project.ordered_by_last_commit_date).to eq([newest_ci_project, oldest_ci_project, ci_project_without_commits]) - end - end - - context :valid_project do - let(:commit) { FactoryGirl.create(:ci_commit) } - - context :project_with_commit_and_builds do - let(:project) { commit.project } - - before do - FactoryGirl.create(:ci_build, commit: commit) - end - - it { expect(project.status).to eq('pending') } - it { expect(project.last_commit).to be_kind_of(Ci::Commit) } - it { expect(project.human_status).to eq('pending') } - end - end - - describe '#email_notification?' do - it do - project = FactoryGirl.create :ci_project, email_add_pusher: true - expect(project.email_notification?).to eq(true) - end - - it do - project = FactoryGirl.create :ci_project, email_add_pusher: false, email_recipients: 'test tesft' - expect(project.email_notification?).to eq(true) - end - - it do - project = FactoryGirl.create :ci_project, email_add_pusher: false, email_recipients: '' - expect(project.email_notification?).to eq(false) - end - end - - describe '#broken_or_success?' do - it do - project = FactoryGirl.create :ci_project, email_add_pusher: true - allow(project).to receive(:broken?).and_return(true) - allow(project).to receive(:success?).and_return(true) - expect(project.broken_or_success?).to eq(true) - end - - it do - project = FactoryGirl.create :ci_project, email_add_pusher: true - allow(project).to receive(:broken?).and_return(true) - allow(project).to receive(:success?).and_return(false) - expect(project.broken_or_success?).to eq(true) - end - - it do - project = FactoryGirl.create :ci_project, email_add_pusher: true - allow(project).to receive(:broken?).and_return(false) - allow(project).to receive(:success?).and_return(true) - expect(project.broken_or_success?).to eq(true) - end - - it do - project = FactoryGirl.create :ci_project, email_add_pusher: true - allow(project).to receive(:broken?).and_return(false) - allow(project).to receive(:success?).and_return(false) - expect(project.broken_or_success?).to eq(false) - end - end - - describe :repo_url_with_auth do - let(:project) { FactoryGirl.create :ci_project } - subject { project.repo_url_with_auth } - - it { is_expected.to be_a(String) } - it { is_expected.to end_with(".git") } - it { is_expected.to start_with(project.gitlab_url[0..6]) } - it { is_expected.to include(project.token) } - it { is_expected.to include('gitlab-ci-token') } - it { is_expected.to include(project.gitlab_url[7..-1]) } - end - - describe :any_runners do - it "there are no runners available" do - project = FactoryGirl.create(:ci_project) - expect(project.any_runners?).to be_falsey - end - - it "there is a specific runner" do - project = FactoryGirl.create(:ci_project) - project.runners << FactoryGirl.create(:ci_specific_runner) - expect(project.any_runners?).to be_truthy - end - - it "there is a shared runner" do - project = FactoryGirl.create(:ci_project, shared_runners_enabled: true) - FactoryGirl.create(:ci_shared_runner) - expect(project.any_runners?).to be_truthy - end - - it "there is a shared runner, but they are prohibited to use" do - project = FactoryGirl.create(:ci_project) - FactoryGirl.create(:ci_shared_runner) - expect(project.any_runners?).to be_falsey - end - - it "checks the presence of specific runner" do - project = FactoryGirl.create(:ci_project) - specific_runner = FactoryGirl.create(:ci_specific_runner) - project.runners << specific_runner - expect(project.any_runners? { |runner| runner == specific_runner }).to be_truthy - end - - it "checks the presence of shared runner" do - project = FactoryGirl.create(:ci_project, shared_runners_enabled: true) - shared_runner = FactoryGirl.create(:ci_shared_runner) - expect(project.any_runners? { |runner| runner == shared_runner }).to be_truthy - end - end -end diff --git a/spec/models/ci/runner_project_spec.rb b/spec/models/ci/runner_project_spec.rb index 37682c6ea0c..da8491357a5 100644 --- a/spec/models/ci/runner_project_spec.rb +++ b/spec/models/ci/runner_project_spec.rb @@ -11,6 +11,6 @@ require 'spec_helper' -describe Ci::RunnerProject do +describe Ci::RunnerProject, models: true do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 9a1233b9095..232760dfeba 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -19,7 +19,7 @@ require 'spec_helper' -describe Ci::Runner do +describe Ci::Runner, models: true do describe '#display_name' do it 'should return the description if it has a value' do runner = FactoryGirl.build(:ci_runner, description: 'Linux/Ruby-1.9.3-p448') @@ -38,7 +38,7 @@ describe Ci::Runner do end describe :assign_to do - let!(:project) { FactoryGirl.create :ci_project } + let!(:project) { FactoryGirl.create :empty_project } let!(:shared_runner) { FactoryGirl.create(:ci_shared_runner) } before { shared_runner.assign_to(project) } @@ -116,8 +116,8 @@ describe Ci::Runner do describe "belongs_to_one_project?" do it "returns false if there are two projects runner assigned to" do runner = FactoryGirl.create(:ci_specific_runner) - project = FactoryGirl.create(:ci_project) - project1 = FactoryGirl.create(:ci_project) + project = FactoryGirl.create(:empty_project) + project1 = FactoryGirl.create(:empty_project) project.runners << runner project1.runners << runner @@ -126,7 +126,7 @@ describe Ci::Runner do it "returns true" do runner = FactoryGirl.create(:ci_specific_runner) - project = FactoryGirl.create(:ci_project) + project = FactoryGirl.create(:empty_project) project.runners << runner expect(runner.belongs_to_one_project?).to be_truthy diff --git a/spec/models/ci/service_spec.rb b/spec/models/ci/service_spec.rb deleted file mode 100644 index 36cda988eb4..00000000000 --- a/spec/models/ci/service_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# == Schema Information -# -# Table name: ci_services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - -require 'spec_helper' - -describe Ci::Service do - - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Mass assignment" do - end - - describe "Test Button" do - before do - @service = Ci::Service.new - end - - describe "Testable" do - let(:commit) { FactoryGirl.create :ci_commit } - let(:build) { FactoryGirl.create :ci_build, commit: commit } - - before do - allow(@service).to receive_messages( - project: commit.project - ) - build - @testable = @service.can_test? - end - - describe :can_test do - it { expect(@testable).to eq(true) } - end - end - end -end diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb index b8aa3c1e777..cb2f51e2011 100644 --- a/spec/models/ci/trigger_spec.rb +++ b/spec/models/ci/trigger_spec.rb @@ -12,8 +12,8 @@ require 'spec_helper' -describe Ci::Trigger do - let(:project) { FactoryGirl.create :ci_project } +describe Ci::Trigger, models: true do + let(:project) { FactoryGirl.create :empty_project } describe 'before_validation' do it 'should set an random token if none provided' do diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index a515f5881ff..31b56953a13 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -13,7 +13,7 @@ require 'spec_helper' -describe Ci::Variable do +describe Ci::Variable, models: true do subject { Ci::Variable.new } let(:secret_value) { 'secret' } diff --git a/spec/models/ci/web_hook_spec.rb b/spec/models/ci/web_hook_spec.rb deleted file mode 100644 index 2865482a212..00000000000 --- a/spec/models/ci/web_hook_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# == Schema Information -# -# Table name: ci_web_hooks -# -# id :integer not null, primary key -# url :string(255) not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe Ci::WebHook do - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Validations" do - it { is_expected.to validate_presence_of(:url) } - - context "url format" do - it { is_expected.to allow_value("http://example.com").for(:url) } - it { is_expected.to allow_value("https://excample.com").for(:url) } - it { is_expected.to allow_value("http://test.com/api").for(:url) } - it { is_expected.to allow_value("http://test.com/api?key=abc").for(:url) } - it { is_expected.to allow_value("http://test.com/api?key=abc&type=def").for(:url) } - - it { is_expected.not_to allow_value("example.com").for(:url) } - it { is_expected.not_to allow_value("ftp://example.com").for(:url) } - it { is_expected.not_to allow_value("herp-and-derp").for(:url) } - end - end - - describe "execute" do - before(:each) do - @web_hook = FactoryGirl.create(:ci_web_hook) - @project = @web_hook.project - @data = { before: 'oldrev', after: 'newrev', ref: 'ref' } - - WebMock.stub_request(:post, @web_hook.url) - end - - it "POSTs to the web hook URL" do - @web_hook.execute(@data) - expect(WebMock).to have_requested(:post, @web_hook.url).once - end - - it "POSTs the data as JSON" do - json = @data.to_json - - @web_hook.execute(@data) - expect(WebMock).to have_requested(:post, @web_hook.url).with(body: json).once - end - - it "catches exceptions" do - expect(Ci::WebHook).to receive(:post).and_raise("Some HTTP Post error") - - expect{ @web_hook.execute(@data) }. - to raise_error(RuntimeError, 'Some HTTP Post error') - end - end -end diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb index 1031af097bd..9307d97e214 100644 --- a/spec/models/commit_range_spec.rb +++ b/spec/models/commit_range_spec.rb @@ -1,56 +1,78 @@ require 'spec_helper' -describe CommitRange do +describe CommitRange, models: true do describe 'modules' do subject { described_class } it { is_expected.to include_module(Referable) } end - let(:sha_from) { 'f3f85602' } - let(:sha_to) { 'e86e1013' } + let!(:project) { create(:project, :public) } + let!(:commit1) { project.commit("HEAD~2") } + let!(:commit2) { project.commit } - let(:range) { described_class.new("#{sha_from}...#{sha_to}") } - let(:range2) { described_class.new("#{sha_from}..#{sha_to}") } + let(:sha_from) { commit1.short_id } + let(:sha_to) { commit2.short_id } + + let(:full_sha_from) { commit1.id } + let(:full_sha_to) { commit2.id } + + let(:range) { described_class.new("#{sha_from}...#{sha_to}", project) } + let(:range2) { described_class.new("#{sha_from}..#{sha_to}", project) } it 'raises ArgumentError when given an invalid range string' do - expect { described_class.new("Foo") }.to raise_error(ArgumentError) + expect { described_class.new("Foo", project) }.to raise_error(ArgumentError) end describe '#to_s' do it 'is correct for three-dot syntax' do - expect(range.to_s).to eq "#{sha_from[0..7]}...#{sha_to[0..7]}" + expect(range.to_s).to eq "#{full_sha_from}...#{full_sha_to}" end it 'is correct for two-dot syntax' do - expect(range2.to_s).to eq "#{sha_from[0..7]}..#{sha_to[0..7]}" + expect(range2.to_s).to eq "#{full_sha_from}..#{full_sha_to}" end end describe '#to_reference' do - let(:project) { double('project', to_reference: 'namespace1/project') } + let(:cross) { create(:project) } + + it 'returns a String reference to the object' do + expect(range.to_reference).to eq "#{full_sha_from}...#{full_sha_to}" + end + + it 'returns a String reference to the object' do + expect(range2.to_reference).to eq "#{full_sha_from}..#{full_sha_to}" + end + + it 'supports a cross-project reference' do + expect(range.to_reference(cross)).to eq "#{project.to_reference}@#{full_sha_from}...#{full_sha_to}" + end + end - before do - range.project = project + describe '#reference_link_text' do + let(:cross) { create(:project) } + + it 'returns a String reference to the object' do + expect(range.reference_link_text).to eq "#{sha_from}...#{sha_to}" end it 'returns a String reference to the object' do - expect(range.to_reference).to eq range.to_s + expect(range2.reference_link_text).to eq "#{sha_from}..#{sha_to}" end it 'supports a cross-project reference' do - cross = double('project') - expect(range.to_reference(cross)).to eq "#{project.to_reference}@#{range.to_s}" + expect(range.reference_link_text(cross)).to eq "#{project.to_reference}@#{sha_from}...#{sha_to}" end end describe '#reference_title' do it 'returns the correct String for three-dot ranges' do - expect(range.reference_title).to eq "Commits #{sha_from} through #{sha_to}" + expect(range.reference_title).to eq "Commits #{full_sha_from} through #{full_sha_to}" end it 'returns the correct String for two-dot ranges' do - expect(range2.reference_title).to eq "Commits #{sha_from}^ through #{sha_to}" + expect(range2.reference_title).to eq "Commits #{full_sha_from}^ through #{full_sha_to}" end end @@ -60,11 +82,11 @@ describe CommitRange do end it 'includes the correct values for a three-dot range' do - expect(range.to_param).to eq({ from: sha_from, to: sha_to }) + expect(range.to_param).to eq({ from: full_sha_from, to: full_sha_to }) end it 'includes the correct values for a two-dot range' do - expect(range2.to_param).to eq({ from: sha_from + '^', to: sha_to }) + expect(range2.to_param).to eq({ from: full_sha_from + '^', to: full_sha_to }) end end @@ -79,64 +101,37 @@ describe CommitRange do end describe '#valid_commits?' do - context 'without a project' do - it 'returns nil' do - expect(range.valid_commits?).to be_nil + context 'with a valid repo' do + before do + expect(project).to receive(:valid_repo?).and_return(true) end - end - - it 'accepts an optional project argument' do - project1 = double('project1').as_null_object - project2 = double('project2').as_null_object - - # project1 gets assigned through the accessor, but ignored when not given - # as an argument to `valid_commits?` - expect(project1).not_to receive(:present?) - range.project = project1 - - # project2 gets passed to `valid_commits?` - expect(project2).to receive(:present?).and_return(false) - range.valid_commits?(project2) - end - - context 'with a project' do - let(:project) { double('project', repository: double('repository')) } + it 'is false when `sha_from` is invalid' do + expect(project).to receive(:commit).with(sha_from).and_return(nil) + expect(project).to receive(:commit).with(sha_to).and_call_original - context 'with a valid repo' do - before do - expect(project).to receive(:valid_repo?).and_return(true) - range.project = project - end + expect(range).not_to be_valid_commits + end - it 'is false when `sha_from` is invalid' do - expect(project.repository).to receive(:commit).with(sha_from).and_return(false) - expect(project.repository).not_to receive(:commit).with(sha_to) - expect(range).not_to be_valid_commits - end + it 'is false when `sha_to` is invalid' do + expect(project).to receive(:commit).with(sha_from).and_call_original + expect(project).to receive(:commit).with(sha_to).and_return(nil) - it 'is false when `sha_to` is invalid' do - expect(project.repository).to receive(:commit).with(sha_from).and_return(true) - expect(project.repository).to receive(:commit).with(sha_to).and_return(false) - expect(range).not_to be_valid_commits - end + expect(range).not_to be_valid_commits + end - it 'is true when both `sha_from` and `sha_to` are valid' do - expect(project.repository).to receive(:commit).with(sha_from).and_return(true) - expect(project.repository).to receive(:commit).with(sha_to).and_return(true) - expect(range).to be_valid_commits - end + it 'is true when both `sha_from` and `sha_to` are valid' do + expect(range).to be_valid_commits end + end - context 'without a valid repo' do - before do - expect(project).to receive(:valid_repo?).and_return(false) - range.project = project - end + context 'without a valid repo' do + before do + expect(project).to receive(:valid_repo?).and_return(false) + end - it 'returns false' do - expect(range).not_to be_valid_commits - end + it 'returns false' do + expect(range).not_to be_valid_commits end end end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 90be9324951..ecf37b40c58 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Commit do +describe Commit, models: true do let(:project) { create(:project) } let(:commit) { project.commit } @@ -24,6 +24,17 @@ describe Commit do end end + describe '#reference_link_text' do + it 'returns a String reference to the object' do + expect(commit.reference_link_text).to eq commit.short_id + end + + it 'supports a cross-project reference' do + cross = double('project') + expect(commit.reference_link_text(cross)).to eq "#{project.to_reference}@#{commit.short_id}" + end + end + describe '#title' do it "returns no_commit_message when safe_message is blank" do allow(commit).to receive(:safe_message).and_return('') @@ -77,14 +88,10 @@ eos let(:other_issue) { create :issue, project: other_project } it 'detects issues that this commit is marked as closing' do - allow(commit).to receive(:safe_message).and_return("Fixes ##{issue.iid}") - expect(commit.closes_issues).to eq([issue]) - end - - it 'does not detect issues from other projects' do ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}" - allow(commit).to receive(:safe_message).and_return("Fixes #{ext_ref}") - expect(commit.closes_issues).to be_empty + allow(commit).to receive(:safe_message).and_return("Fixes ##{issue.iid} and #{ext_ref}") + expect(commit.closes_issues).to include(issue) + expect(commit.closes_issues).to include(other_issue) end end @@ -100,4 +107,15 @@ eos # Include the subject in the repository stub. let(:extra_commits) { [subject] } end + + describe '#hook_attrs' do + let(:data) { commit.hook_attrs(with_changed_files: true) } + + it { expect(data).to be_a(Hash) } + it { expect(data[:message]).to include('Add submodule from gitlab.com') } + it { expect(data[:timestamp]).to eq('2014-02-27T11:01:38+02:00') } + it { expect(data[:added]).to eq(["gitlab-grack"]) } + it { expect(data[:modified]).to eq([".gitmodules"]) } + it { expect(data[:removed]).to eq([]) } + end end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index dca0715eed8..b8f901b3433 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -33,18 +33,19 @@ require 'spec_helper' -describe CommitStatus do +describe CommitStatus, models: true do let(:commit) { FactoryGirl.create :ci_commit } let(:commit_status) { FactoryGirl.create :commit_status, commit: commit } it { is_expected.to belong_to(:commit) } it { is_expected.to belong_to(:user) } + it { is_expected.to belong_to(:project) } + it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_inclusion_of(:status).in_array(%w(pending running failed success canceled)) } it { is_expected.to delegate_method(:sha).to(:commit) } it { is_expected.to delegate_method(:short_sha).to(:commit) } - it { is_expected.to delegate_method(:gl_project).to(:commit) } it { is_expected.to respond_to :success? } it { is_expected.to respond_to :failed? } diff --git a/spec/models/concerns/case_sensitivity_spec.rb b/spec/models/concerns/case_sensitivity_spec.rb index f7ed30f8198..25b3f4e50da 100644 --- a/spec/models/concerns/case_sensitivity_spec.rb +++ b/spec/models/concerns/case_sensitivity_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe CaseSensitivity do +describe CaseSensitivity, models: true do describe '.iwhere' do let(:connection) { ActiveRecord::Base.connection } let(:model) { Class.new { include CaseSensitivity } } diff --git a/spec/models/concerns/strip_attribute_spec.rb b/spec/models/concerns/strip_attribute_spec.rb new file mode 100644 index 00000000000..6445e29c3ef --- /dev/null +++ b/spec/models/concerns/strip_attribute_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Milestone, "StripAttribute" do + let(:milestone) { create(:milestone) } + + describe ".strip_attributes" do + it { expect(Milestone).to respond_to(:strip_attributes) } + it { expect(Milestone.strip_attrs).to include(:title) } + end + + describe "#strip_attributes" do + before do + milestone.title = ' 8.3 ' + milestone.valid? + end + + it { expect(milestone.title).to eq('8.3') } + end + +end diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb new file mode 100644 index 00000000000..a9b0b64e5de --- /dev/null +++ b/spec/models/concerns/token_authenticatable_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +shared_examples 'TokenAuthenticatable' do + describe 'dynamically defined methods' do + it { expect(described_class).to be_private_method_defined(:generate_token_for) } + it { expect(described_class).to respond_to("find_by_#{token_field}") } + it { is_expected.to respond_to("ensure_#{token_field}") } + it { is_expected.to respond_to("reset_#{token_field}!") } + end +end + +describe User, 'TokenAuthenticatable' do + let(:token_field) { :authentication_token } + it_behaves_like 'TokenAuthenticatable' + + describe 'ensures authentication token' do + subject { create(:user).send(token_field) } + it { is_expected.to be_a String } + end +end + +describe ApplicationSetting, 'TokenAuthenticatable' do + let(:token_field) { :runners_registration_token } + it_behaves_like 'TokenAuthenticatable' + + describe 'generating new token' do + subject { described_class.new } + let(:token) { subject.send(token_field) } + + context 'token is not generated yet' do + it { expect(token).to be nil } + + describe 'ensured token' do + subject { described_class.new.send("ensure_#{token_field}") } + + it { is_expected.to be_a String } + it { is_expected.to_not be_blank } + end + end + + context 'token is generated' do + before { subject.send("reset_#{token_field}!") } + it { expect(token).to be_a String } + end + end + + describe 'multiple token fields' do + before do + described_class.send(:add_authentication_token_field, :yet_another_token) + end + + describe '.token_fields' do + subject { described_class.authentication_token_fields } + it { is_expected.to include(:runners_registration_token, :yet_another_token) } + end + end +end diff --git a/spec/models/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb index 95729932459..64ba778afea 100644 --- a/spec/models/deploy_key_spec.rb +++ b/spec/models/deploy_key_spec.rb @@ -15,7 +15,7 @@ require 'spec_helper' -describe DeployKey do +describe DeployKey, models: true do let(:project) { create(:project) } let(:deploy_key) { create(:deploy_key, projects: [project]) } diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb index 0eb22599d18..8aedbfb8636 100644 --- a/spec/models/deploy_keys_project_spec.rb +++ b/spec/models/deploy_keys_project_spec.rb @@ -11,7 +11,7 @@ require 'spec_helper' -describe DeployKeysProject do +describe DeployKeysProject, models: true do describe "Associations" do it { is_expected.to belong_to(:deploy_key) } it { is_expected.to belong_to(:project) } diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index ae53f7a536b..071582b0282 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -16,7 +16,7 @@ require 'spec_helper' -describe Event do +describe Event, models: true do describe "Associations" do it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:target) } diff --git a/spec/models/external_issue_spec.rb b/spec/models/external_issue_spec.rb index 7744610db78..6ec6b9037a4 100644 --- a/spec/models/external_issue_spec.rb +++ b/spec/models/external_issue_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe ExternalIssue do +describe ExternalIssue, models: true do let(:project) { double('project', to_reference: 'namespace1/project1') } let(:issue) { described_class.new('EXT-1234', project) } diff --git a/spec/models/external_wiki_service_spec.rb b/spec/models/external_wiki_service_spec.rb index 4bd5b0be61c..b198aa77526 100644 --- a/spec/models/external_wiki_service_spec.rb +++ b/spec/models/external_wiki_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe ExternalWikiService do +describe ExternalWikiService, models: true do include ExternalWikiHelper describe "Associations" do it { should belong_to :project } diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb index c86314c454c..d61c1c96bde 100644 --- a/spec/models/generic_commit_status_spec.rb +++ b/spec/models/generic_commit_status_spec.rb @@ -33,7 +33,7 @@ require 'spec_helper' -describe GenericCommitStatus do +describe GenericCommitStatus, models: true do let(:commit) { FactoryGirl.create :ci_commit } let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, commit: commit } diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb index 6eeff30b20e..ba03e6aabd0 100644 --- a/spec/models/global_milestone_spec.rb +++ b/spec/models/global_milestone_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe GlobalMilestone do +describe GlobalMilestone, models: true do let(:user) { create(:user) } let(:user2) { create(:user) } let(:group) { create(:group) } diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 6f166b5ab75..646f767e6fe 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -16,7 +16,7 @@ require 'spec_helper' -describe Group do +describe Group, models: true do let!(:group) { create(:group) } describe 'associations' do diff --git a/spec/models/hooks/project_hook_spec.rb b/spec/models/hooks/project_hook_spec.rb index a2dc66fce3e..645ee0b929a 100644 --- a/spec/models/hooks/project_hook_spec.rb +++ b/spec/models/hooks/project_hook_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' -describe ProjectHook do +describe ProjectHook, models: true do describe '.push_hooks' do it 'should return hooks for push events only' do hook = create(:project_hook, push_events: true) diff --git a/spec/models/hooks/service_hook_spec.rb b/spec/models/hooks/service_hook_spec.rb index 16641c12124..1455661485b 100644 --- a/spec/models/hooks/service_hook_spec.rb +++ b/spec/models/hooks/service_hook_spec.rb @@ -18,7 +18,7 @@ require "spec_helper" -describe ServiceHook do +describe ServiceHook, models: true do describe "Associations" do it { is_expected.to belong_to :service } end diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb index 02d2cc2c77a..138b87a9a06 100644 --- a/spec/models/hooks/system_hook_spec.rb +++ b/spec/models/hooks/system_hook_spec.rb @@ -18,7 +18,7 @@ require "spec_helper" -describe SystemHook do +describe SystemHook, models: true do describe "execute" do before(:each) do @system_hook = create(:system_hook) diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb index 2fdc49f02ee..2d90b0793cc 100644 --- a/spec/models/hooks/web_hook_spec.rb +++ b/spec/models/hooks/web_hook_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' -describe ProjectHook do +describe ProjectHook, models: true do describe "Associations" do it { is_expected.to belong_to :project } end @@ -71,5 +71,11 @@ describe ProjectHook do expect { @project_hook.execute(@data, 'push_hooks') }.to raise_error(RuntimeError) end + + it "handles SSL exceptions" do + expect(WebHook).to receive(:post).and_raise(OpenSSL::SSL::SSLError.new('SSL error')) + + expect(@project_hook.execute(@data, 'push_hooks')).to eq([false, 'SSL error']) + end end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index c9aa1b063c6..52271c7c8c6 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe Issue do +describe Issue, models: true do describe "Associations" do it { is_expected.to belong_to(:milestone) } end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 2f819f60cbb..c962b83644a 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -15,7 +15,7 @@ require 'spec_helper' -describe Key do +describe Key, models: true do describe "Associations" do it { is_expected.to belong_to(:user) } end @@ -81,7 +81,7 @@ describe Key do it 'rejects the multiple line key' do key = build(:key) - key.key.gsub!(' ', "\n") + key.key.tr!(' ', "\n") expect(key).not_to be_valid end end diff --git a/spec/models/label_link_spec.rb b/spec/models/label_link_spec.rb index 8c240826582..dc7510b1de3 100644 --- a/spec/models/label_link_spec.rb +++ b/spec/models/label_link_spec.rb @@ -12,7 +12,7 @@ require 'spec_helper' -describe LabelLink do +describe LabelLink, models: true do let(:label) { create(:label_link) } it { expect(label).to be_valid } diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb index 511ee8cbd96..696fbf7e0aa 100644 --- a/spec/models/label_spec.rb +++ b/spec/models/label_spec.rb @@ -13,7 +13,7 @@ require 'spec_helper' -describe Label do +describe Label, models: true do let(:label) { create(:label) } describe 'associations' do diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 57f840c1e91..2aedca20df2 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -19,7 +19,7 @@ require 'spec_helper' -describe Member do +describe Member, models: true do describe "Associations" do it { is_expected.to belong_to(:user) } end diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index 652026729bb..5424c9b9cba 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -19,7 +19,7 @@ require 'spec_helper' -describe GroupMember do +describe GroupMember, models: true do context 'notification' do describe "#after_create" do it "should send email to user" do diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index ee912bf12a2..9f26d9eb5ce 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -19,7 +19,7 @@ require 'spec_helper' -describe ProjectMember do +describe ProjectMember, models: true do describe :import_team do before do @abilities = Six.new diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 90af75ff0e3..1aeba9b2b3b 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -25,13 +25,13 @@ require 'spec_helper' -describe MergeRequest do +describe MergeRequest, models: true do subject { create(:merge_request) } describe 'associations' do it { is_expected.to belong_to(:target_project).with_foreign_key(:target_project_id).class_name('Project') } it { is_expected.to belong_to(:source_project).with_foreign_key(:source_project_id).class_name('Project') } - + it { is_expected.to belong_to(:merge_user).class_name("User") } it { is_expected.to have_one(:merge_request_diff).dependent(:destroy) } end @@ -48,12 +48,32 @@ describe MergeRequest do describe 'validation' do it { is_expected.to validate_presence_of(:target_branch) } it { is_expected.to validate_presence_of(:source_branch) } + + context "Validation of merge user with Merge When Build succeeds" do + it "allows user to be nil when the feature is disabled" do + expect(subject).to be_valid + end + + it "is invalid without merge user" do + subject.merge_when_build_succeeds = true + expect(subject).not_to be_valid + end + + it "is valid with merge user" do + subject.merge_when_build_succeeds = true + subject.merge_user = build(:user) + + expect(subject).to be_valid + end + end end describe 'respond to' do it { is_expected.to respond_to(:unchecked?) } it { is_expected.to respond_to(:can_be_merged?) } it { is_expected.to respond_to(:cannot_be_merged?) } + it { is_expected.to respond_to(:merge_params) } + it { is_expected.to respond_to(:merge_when_build_succeeds) } end describe '#to_reference' do @@ -172,6 +192,50 @@ describe MergeRequest do end end + describe '#can_remove_source_branch?' do + let(:user) { create(:user) } + let(:user2) { create(:user) } + + before do + subject.source_project.team << [user, :master] + + subject.source_branch = "feature" + subject.target_branch = "master" + subject.save! + end + + it "can't be removed when its a protected branch" do + allow(subject.source_project).to receive(:protected_branch?).and_return(true) + expect(subject.can_remove_source_branch?(user)).to be_falsey + end + + it "cant remove a root ref" do + subject.source_branch = "master" + subject.target_branch = "feature" + + expect(subject.can_remove_source_branch?(user)).to be_falsey + end + + it "is unable to remove the source branch for a project the user cannot push to" do + expect(subject.can_remove_source_branch?(user2)).to be_falsey + end + + it "is can be removed in all other cases" do + expect(subject.can_remove_source_branch?(user)).to be_truthy + end + end + + describe "#reset_merge_when_build_succeeds" do + let(:merge_if_green) { create :merge_request, merge_when_build_succeeds: true, merge_user: create(:user) } + + it "sets the item to false" do + merge_if_green.reset_merge_when_build_succeeds + merge_if_green.reload + + expect(merge_if_green.merge_when_build_succeeds).to be_falsey + end + end + describe "#hook_attrs" do it "has all the required keys" do attrs = subject.hook_attrs @@ -193,4 +257,29 @@ describe MergeRequest do it_behaves_like 'a Taskable' do subject { create :merge_request, :simple } end + + describe '#ci_commit' do + describe 'when the source project exists' do + it 'returns the latest commit' do + commit = double(:commit, id: '123abc') + ci_commit = double(:ci_commit) + + allow(subject).to receive(:last_commit).and_return(commit) + + expect(subject.source_project).to receive(:ci_commit). + with('123abc'). + and_return(ci_commit) + + expect(subject.ci_commit).to eq(ci_commit) + end + end + + describe 'when the source project does not exist' do + it 'returns nil' do + allow(subject).to receive(:source_project).and_return(nil) + + expect(subject.ci_commit).to be_nil + end + end + end end diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 77c58627322..30a71987d86 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -15,7 +15,7 @@ require 'spec_helper' -describe Milestone do +describe Milestone, models: true do describe "Associations" do it { is_expected.to belong_to(:project) } it { is_expected.to have_many(:issues) } diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index a98b9cb7321..4fa2d2bc4d2 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -16,7 +16,7 @@ require 'spec_helper' -describe Namespace do +describe Namespace, models: true do let!(:namespace) { create(:namespace) } it { is_expected.to have_many :projects } diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index f347f537550..216c7dabae0 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -16,11 +16,12 @@ # system :boolean default(FALSE), not null # st_diff :text # updated_by_id :integer +# is_award :boolean default(FALSE), not null # require 'spec_helper' -describe Note do +describe Note, models: true do describe 'associations' do it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:noteable) } @@ -141,4 +142,30 @@ describe Note do expect(Note.grouped_awards.first.last).to match_array(Note.all) end end + + describe "editable?" do + it "returns true" do + note = build(:note) + expect(note.editable?).to be_truthy + end + + it "returns false" do + note = build(:note, system: true) + expect(note.editable?).to be_falsy + end + + it "returns false" do + note = build(:note, is_award: true, note: "smiley") + expect(note.editable?).to be_falsy + end + end + + describe "set_award!" do + let(:issue) { create :issue } + + it "converts aliases to actual name" do + note = create :note, note: ":thumbsup:", noteable: issue + expect(note.reload.note).to eq("+1") + end + end end diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb index f600a240c46..3643ad1b052 100644 --- a/spec/models/project_security_spec.rb +++ b/spec/models/project_security_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Project do +describe Project, models: true do describe :authorization do before do @p1 = create(:project) diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb index 230807ea672..88cd624877a 100644 --- a/spec/models/project_services/buildkite_service_spec.rb +++ b/spec/models/project_services/buildkite_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe BuildkiteService do +describe BuildkiteService, models: true do describe 'Associations' do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index e9967f5fe0b..a2cf68a9e38 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe DroneCiService do +describe DroneCiService, models: true do describe 'associations' do it { is_expected.to belong_to(:project) } it { is_expected.to have_one(:service_hook) } diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb index 16296607a94..ff7fbcaa004 100644 --- a/spec/models/project_services/flowdock_service_spec.rb +++ b/spec/models/project_services/flowdock_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe FlowdockService do +describe FlowdockService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb index 9e156472316..ecb3ccb1673 100644 --- a/spec/models/project_services/gemnasium_service_spec.rb +++ b/spec/models/project_services/gemnasium_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe GemnasiumService do +describe GemnasiumService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb deleted file mode 100644 index b9006b693b2..00000000000 --- a/spec/models/project_services/gitlab_ci_service_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# == 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 GitlabCiService do - describe 'associations' do - it { is_expected.to belong_to(:project) } - it { is_expected.to have_one(:service_hook) } - end - - describe 'commits methods' do - before do - @ci_project = create(:ci_project) - @service = GitlabCiService.new - allow(@service).to receive_messages( - service_hook: true, - project_url: 'http://ci.gitlab.org/projects/2', - token: 'verySecret', - project: @ci_project.gl_project - ) - end - - describe :build_page do - it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://localhost/#{@ci_project.gl_project.path_with_namespace}/commit/2ab7834c/builds")} - end - - describe "execute" do - let(:user) { create(:user, username: 'username') } - let(:project) { create(:project, name: 'project') } - let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - - it "calls CreateCommitService" do - expect_any_instance_of(Ci::CreateCommitService).to receive(:execute).with(@ci_project, user, push_sample_data) - - @service.execute(push_sample_data) - end - end - end -end 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 e34ca09bffc..3518dbd1728 100644 --- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb +++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe GitlabIssueTrackerService do +describe GitlabIssueTrackerService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index f67d7b30980..91dd92b7c67 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe HipchatService do +describe HipchatService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } @@ -57,23 +57,21 @@ describe HipchatService do it 'should use v1 if version is provided' do allow(hipchat).to receive(:api_version).and_return('v1') - expect(HipChat::Client).to receive(:new). - with(token, - api_version: 'v1', - server_url: server_url). - and_return( - double(:hipchat_service).as_null_object) + expect(HipChat::Client).to receive(:new).with( + token, + api_version: 'v1', + server_url: server_url + ).and_return(double(:hipchat_service).as_null_object) hipchat.execute(push_sample_data) end it 'should use v2 as the version when nothing is provided' do allow(hipchat).to receive(:api_version).and_return('') - expect(HipChat::Client).to receive(:new). - with(token, - api_version: 'v2', - server_url: server_url). - and_return( - double(:hipchat_service).as_null_object) + expect(HipChat::Client).to receive(:new).with( + token, + api_version: 'v2', + server_url: server_url + ).and_return(double(:hipchat_service).as_null_object) hipchat.execute(push_sample_data) end @@ -247,6 +245,55 @@ describe HipchatService do end end + context 'build events' do + let(:build) { create(:ci_build) } + let(:data) { Gitlab::BuildDataBuilder.build(build) } + + context 'for failed' do + before { build.drop } + + it "should call Hipchat API" do + hipchat.execute(data) + + expect(WebMock).to have_requested(:post, api_url).once + end + + it "should create a build message" do + message = hipchat.send(:create_build_message, data) + + project_url = project.web_url + project_name = project.name_with_namespace.gsub(/\s/, '') + sha = data[:sha] + ref = data[:ref] + ref_type = data[:tag] ? 'tag' : 'branch' + duration = data[:commit][:duration] + + expect(message).to eq("<a href=\"#{project_url}\">#{project_name}</a>: " \ + "Commit <a href=\"#{project_url}/commit/#{sha}/builds\">#{Commit.truncate_sha(sha)}</a> " \ + "of <a href=\"#{project_url}/commits/#{ref}\">#{ref}</a> #{ref_type} " \ + "by #{data[:commit][:author_name]} failed in #{duration} second(s)") + end + end + + context 'for succeeded' do + before do + build.success + end + + it "should call Hipchat API" do + hipchat.notify_only_broken_builds = false + hipchat.execute(data) + expect(WebMock).to have_requested(:post, api_url).once + end + + it "should notify only broken" do + hipchat.notify_only_broken_builds = true + hipchat.execute(data) + expect(WebMock).to_not have_requested(:post, api_url).once + end + end + end + context "#message_options" do it "should be set to the defaults" do expect(hipchat.send(:message_options)).to eq({ notify: false, color: 'yellow' }) diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb index 7d483a44c53..b783b1a576e 100644 --- a/spec/models/project_services/irker_service_spec.rb +++ b/spec/models/project_services/irker_service_spec.rb @@ -22,7 +22,7 @@ require 'spec_helper' require 'socket' require 'json' -describe IrkerService do +describe IrkerService, models: true do describe 'Associations' do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb index ddd2cce212c..7d91ebe9ce6 100644 --- a/spec/models/project_services/jira_service_spec.rb +++ b/spec/models/project_services/jira_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe JiraService do +describe JiraService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } @@ -94,9 +94,9 @@ describe JiraService do end it 'should be prepopulated with the settings' do - expect(@service.properties[:project_url]).to eq('http://jira.sample/projects/project_a') - expect(@service.properties[:issues_url]).to eq("http://jira.sample/issues/:id") - expect(@service.properties[:new_issue_url]).to eq("http://jira.sample/projects/project_a/issues/new") + expect(@service.properties["project_url"]).to eq('http://jira.sample/projects/project_a') + expect(@service.properties["issues_url"]).to eq("http://jira.sample/issues/:id") + expect(@service.properties["new_issue_url"]).to eq("http://jira.sample/projects/project_a/issues/new") end end end diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb index ac10ffbd39b..96039f9491b 100644 --- a/spec/models/project_services/pushover_service_spec.rb +++ b/spec/models/project_services/pushover_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe PushoverService do +describe PushoverService, models: true do describe 'Associations' do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_services/slack_service/build_message_spec.rb b/spec/models/project_services/slack_service/build_message_spec.rb new file mode 100644 index 00000000000..621c83c0cda --- /dev/null +++ b/spec/models/project_services/slack_service/build_message_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe SlackService::BuildMessage do + subject { SlackService::BuildMessage.new(args) } + + let(:args) do + { + sha: '97de212e80737a608d939f648d959671fb0a0142', + ref: 'develop', + tag: false, + + project_name: 'project_name', + project_url: 'somewhere.com', + + commit: { + status: status, + author_name: 'hacker', + duration: 10, + }, + } + end + + context 'succeeded' do + let(:status) { 'success' } + let(:color) { 'good' } + + 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 second(s)' + 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 + let(:status) { 'failed' } + let(:color) { 'danger' } + + 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 second(s)' + expect(subject.pretext).to be_empty + expect(subject.fallback).to eq(message) + expect(subject.attachments).to eq([text: message, color: color]) + end + end +end diff --git a/spec/models/project_services/slack_service/issue_message_spec.rb b/spec/models/project_services/slack_service/issue_message_spec.rb index b78d92f23a1..97e6f03e308 100644 --- a/spec/models/project_services/slack_service/issue_message_spec.rb +++ b/spec/models/project_services/slack_service/issue_message_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SlackService::IssueMessage do +describe SlackService::IssueMessage, models: true do subject { SlackService::IssueMessage.new(args) } let(:args) do diff --git a/spec/models/project_services/slack_service/merge_message_spec.rb b/spec/models/project_services/slack_service/merge_message_spec.rb index 581c50d6c88..dae8bd90922 100644 --- a/spec/models/project_services/slack_service/merge_message_spec.rb +++ b/spec/models/project_services/slack_service/merge_message_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SlackService::MergeMessage do +describe SlackService::MergeMessage, models: true do subject { SlackService::MergeMessage.new(args) } let(:args) do diff --git a/spec/models/project_services/slack_service/note_message_spec.rb b/spec/models/project_services/slack_service/note_message_spec.rb index 21fb575480b..06006b9a4f5 100644 --- a/spec/models/project_services/slack_service/note_message_spec.rb +++ b/spec/models/project_services/slack_service/note_message_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SlackService::NoteMessage do +describe SlackService::NoteMessage, models: true do let(:color) { '#345' } before do @@ -89,10 +89,10 @@ describe SlackService::NoteMessage do it 'returns a message regarding notes on an issue' do message = SlackService::NoteMessage.new(@args) expect(message.pretext).to eq( - "Test User commented on " \ - "<url|issue #20> in <somewhere.com|project_name>: " \ - "*issue title*") - expected_attachments = [ + "Test User commented on " \ + "<url|issue #20> in <somewhere.com|project_name>: " \ + "*issue title*") + expected_attachments = [ { text: "comment on an issue", color: color, diff --git a/spec/models/project_services/slack_service/push_message_spec.rb b/spec/models/project_services/slack_service/push_message_spec.rb index ddc290820d1..cda9ee670b0 100644 --- a/spec/models/project_services/slack_service/push_message_spec.rb +++ b/spec/models/project_services/slack_service/push_message_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SlackService::PushMessage do +describe SlackService::PushMessage, models: true do subject { SlackService::PushMessage.new(args) } let(:args) do diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb index 97b60e19e40..a9e0afad90f 100644 --- a/spec/models/project_services/slack_service_spec.rb +++ b/spec/models/project_services/slack_service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe SlackService do +describe SlackService, models: true do describe "Associations" do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } diff --git a/spec/models/project_snippet_spec.rb b/spec/models/project_snippet_spec.rb index 3e8f106d27f..cc92eb0bd9f 100644 --- a/spec/models/project_snippet_spec.rb +++ b/spec/models/project_snippet_spec.rb @@ -17,7 +17,7 @@ require 'spec_helper' -describe ProjectSnippet do +describe ProjectSnippet, models: true do describe "Associations" do it { is_expected.to belong_to(:project) } end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index f80fada45e9..c4d3813e9c9 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -28,11 +28,12 @@ # import_type :string(255) # import_source :string(255) # commit_count :integer default(0) +# import_error :text # require 'spec_helper' -describe Project do +describe Project, models: true do describe 'associations' do it { is_expected.to belong_to(:group) } it { is_expected.to belong_to(:namespace) } @@ -53,6 +54,13 @@ describe Project do it { is_expected.to have_one(:slack_service).dependent(:destroy) } 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_many(:commit_statuses) } + it { is_expected.to have_many(:ci_commits) } + it { is_expected.to have_many(:builds) } + it { is_expected.to have_many(:runner_projects) } + it { is_expected.to have_many(:runners) } + it { is_expected.to have_many(:variables) } + it { is_expected.to have_many(:triggers) } end describe 'modules' do @@ -87,6 +95,18 @@ describe Project do expect(project2.errors[:limit_reached].first).to match(/Your project limit is 0/) end end + + describe 'project token' do + it 'should set an random token if none provided' do + project = FactoryGirl.create :empty_project, runners_token: '' + expect(project.runners_token).not_to eq('') + end + + it 'should not set an random toke if one provided' do + project = FactoryGirl.create :empty_project, runners_token: 'my-token' + expect(project.runners_token).to eq('my-token') + end + end describe 'Respond to' do it { is_expected.to respond_to(:url_to_repo) } @@ -152,13 +172,17 @@ describe Project do describe '#get_issue' do let(:project) { create(:empty_project) } - let(:issue) { create(:issue, project: project) } + let!(:issue) { create(:issue, project: project) } context 'with default issues tracker' do it 'returns an issue' do expect(project.get_issue(issue.iid)).to eq issue end + it 'returns count of open issues' do + expect(project.open_issues_count).to eq(1) + end + it 'returns nil when no issue found' do expect(project.get_issue(999)).to be_nil end @@ -394,12 +418,7 @@ describe Project do describe :ci_commit do let(:project) { create :project } - let(:commit) { create :ci_commit, gl_project: project } - - before do - project.ensure_gitlab_ci_project - project.create_gitlab_ci_service(active: true) - end + let(:commit) { create :ci_commit, project: project } it { expect(project.ci_commit(commit.sha)).to eq(commit) } end @@ -411,9 +430,7 @@ describe Project do subject { project.builds_enabled } - it { is_expected.to eq(project.gitlab_ci_service.active) } it { expect(project.builds_enabled?).to be_truthy } - it { expect(project.gitlab_ci_project).to be_a(Ci::Project) } end describe '.trending' do @@ -444,7 +461,9 @@ describe Project do before do 2.times do - create(:note_on_commit, project: project2, created_at: date) + # Little fix for special issue related to Fractional Seconds support for MySQL. + # See: https://github.com/rails/rails/pull/14359/files + create(:note_on_commit, project: project2, created_at: date + 1) end end @@ -472,4 +491,65 @@ describe Project do it { is_expected.to eq([]) } end end + + context 'shared runners by default' do + let(:project) { create(:empty_project) } + + subject { project.shared_runners_enabled } + + context 'are enabled' do + before { stub_application_setting(shared_runners_enabled: true) } + + it { is_expected.to be_truthy } + end + + context 'are disabled' do + before { stub_application_setting(shared_runners_enabled: false) } + + it { is_expected.to be_falsey } + end + end + + describe :any_runners do + let(:project) { create(:empty_project, shared_runners_enabled: shared_runners_enabled) } + let(:specific_runner) { create(:ci_specific_runner) } + let(:shared_runner) { create(:ci_shared_runner) } + + context 'for shared runners disabled' do + let(:shared_runners_enabled) { false } + + it 'there are no runners available' do + expect(project.any_runners?).to be_falsey + end + + it 'there is a specific runner' do + project.runners << specific_runner + expect(project.any_runners?).to be_truthy + end + + it 'there is a shared runner, but they are prohibited to use' do + shared_runner + expect(project.any_runners?).to be_falsey + end + + it 'checks the presence of specific runner' do + project.runners << specific_runner + expect(project.any_runners? { |runner| runner == specific_runner }).to be_truthy + end + end + + context 'for shared runners enabled' do + let(:shared_runners_enabled) { true } + + it 'there is a shared runner' do + shared_runner + expect(project.any_runners?).to be_truthy + end + + it 'checks the presence of shared runner' do + shared_runner + expect(project.any_runners? { |runner| runner == shared_runner }).to be_truthy + end + end + end end diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb index 26e8fdae472..5cd5ae327bf 100644 --- a/spec/models/project_team_spec.rb +++ b/spec/models/project_team_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe ProjectTeam do +describe ProjectTeam, models: true do let(:master) { create(:user) } let(:reporter) { create(:user) } let(:guest) { create(:user) } diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index 3b889144447..876b927eaea 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe ProjectWiki do +describe ProjectWiki, models: true do let(:project) { create(:empty_project) } let(:repository) { project.repository } let(:user) { project.owner } diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb index 1e6937b536c..7e956cf6779 100644 --- a/spec/models/protected_branch_spec.rb +++ b/spec/models/protected_branch_spec.rb @@ -12,7 +12,7 @@ require 'spec_helper' -describe ProtectedBranch do +describe ProtectedBranch, models: true do describe 'Associations' do it { is_expected.to belong_to(:project) } end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 319fa0a7c8d..afbf62035ac 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1,9 +1,10 @@ require 'spec_helper' -describe Repository do +describe Repository, models: true do include RepoHelpers let(:repository) { create(:project).repository } + let(:user) { create(:user) } describe :branch_names_contains do subject { repository.branch_names_contains(sample_commit.id) } @@ -99,5 +100,123 @@ describe Repository do it { expect(subject.startline).to eq(186) } it { expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n") } end + + end + + describe "#license" do + before do + repository.send(:cache).expire(:license) + TestBlob = Struct.new(:name) + end + + it 'test selection preference' do + files = [TestBlob.new('file'), TestBlob.new('license'), TestBlob.new('copying')] + expect(repository.tree).to receive(:blobs).and_return(files) + + expect(repository.license.name).to eq('license') + end + + it 'also accepts licence instead of license' do + expect(repository.tree).to receive(:blobs).and_return([TestBlob.new('licence')]) + + expect(repository.license.name).to eq('licence') + end + end + + describe :add_branch do + context 'when pre hooks were successful' do + it 'should run without errors' do + hook = double(trigger: true) + expect(Gitlab::Git::Hook).to receive(:new).exactly(3).times.and_return(hook) + + expect { repository.add_branch(user, 'new_feature', 'master') }.not_to raise_error + end + + it 'should create the branch' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(true) + + branch = repository.add_branch(user, 'new_feature', 'master') + + expect(branch.name).to eq('new_feature') + end + end + + context 'when pre hooks failed' do + it 'should get an error' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(false) + + expect do + repository.add_branch(user, 'new_feature', 'master') + end.to raise_error(GitHooksService::PreReceiveError) + end + + it 'should not create the branch' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(false) + + expect do + repository.add_branch(user, 'new_feature', 'master') + end.to raise_error(GitHooksService::PreReceiveError) + expect(repository.find_branch('new_feature')).to be_nil + end + end + end + + describe :rm_branch do + context 'when pre hooks were successful' do + it 'should run without errors' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(true) + + expect { repository.rm_branch(user, 'feature') }.not_to raise_error + end + + it 'should delete the branch' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(true) + + expect { repository.rm_branch(user, 'feature') }.not_to raise_error + + expect(repository.find_branch('feature')).to be_nil + end + end + + context 'when pre hooks failed' do + it 'should get an error' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(false) + + expect do + repository.rm_branch(user, 'new_feature') + end.to raise_error(GitHooksService::PreReceiveError) + end + + it 'should not delete the branch' 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(GitHooksService::PreReceiveError) + expect(repository.find_branch('feature')).not_to be_nil + end + end + end + + describe :commit_with_hooks do + context 'when pre hooks were successful' do + it 'should run without errors' do + expect_any_instance_of(GitHooksService).to receive(:execute).and_return(true) + + expect do + repository.commit_with_hooks(user, 'feature') { sample_commit.id } + end.not_to raise_error + end + end + + context 'when pre hooks failed' do + it 'should get an error' do + allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(false) + + expect do + repository.commit_with_hooks(user, 'feature') { sample_commit.id } + end.to raise_error(GitHooksService::PreReceiveError) + end + end end end diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 692e5fda3ba..0ca82365b98 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -20,7 +20,7 @@ require 'spec_helper' -describe Service do +describe Service, models: true do describe "Associations" do it { is_expected.to belong_to :project } diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 81581838675..eb2dbbdc5a4 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -17,7 +17,7 @@ require 'spec_helper' -describe Snippet do +describe Snippet, models: true do describe 'modules' do subject { described_class } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4631b12faf1..376266c0955 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -56,11 +56,12 @@ # project_view :integer default(0) # consumed_timestep :integer # layout :integer default(0) +# hide_project_limit :boolean default(FALSE) # require 'spec_helper' -describe User do +describe User, models: true do include Gitlab::CurrentSettings describe 'modules' do @@ -91,7 +92,23 @@ describe User do end describe 'validations' do - it { is_expected.to validate_presence_of(:username) } + describe 'username' do + it 'validates presence' do + expect(subject).to validate_presence_of(:username) + end + + it 'rejects blacklisted names' do + user = build(:user, username: 'dashboard') + + expect(user).not_to be_valid + expect(user.errors.values).to eq [['dashboard is a reserved name']] + end + + it 'validates uniqueness' do + expect(subject).to validate_uniqueness_of(:username) + end + end + it { is_expected.to validate_presence_of(:projects_limit) } it { is_expected.to validate_numericality_of(:projects_limit) } it { is_expected.to allow_value(0).for(:projects_limit) } @@ -445,8 +462,8 @@ describe User do expect(User.search(user1.username.downcase).to_a).to eq([user1]) expect(User.search(user2.username.upcase).to_a).to eq([user2]) expect(User.search(user2.username.downcase).to_a).to eq([user2]) - expect(User.search(user1.username.downcase).to_a.count).to eq(2) - expect(User.search(user2.username.downcase).to_a.count).to eq(1) + expect(User.search(user1.username.downcase).to_a.size).to eq(2) + expect(User.search(user2.username.downcase).to_a.size).to eq(1) end end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index d7802d1734f..c1b03838aa9 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe WikiPage do +describe WikiPage, models: true do let(:project) { create(:empty_project) } let(:user) { project.owner } let(:wiki) { ProjectWiki.new(project, user) } |