Fix merge error

This commit is contained in:
Jan-Gerd Tenberge
2015-10-22 21:43:17 +02:00
778 changed files with 11727 additions and 7486 deletions
@@ -0,0 +1,14 @@
require 'spec_helper'
describe TrendingProjectsFinder, benchmark: true do
describe '#execute' do
let(:finder) { described_class.new }
let(:user) { create(:user) }
# to_a is used to force actually running the query (instead of just building
# it).
benchmark_subject { finder.execute(user).non_archived.to_a }
it { is_expected.to iterate_per_second(500) }
end
end
@@ -0,0 +1,41 @@
require 'spec_helper'
describe Gitlab::Markdown::ReferenceFilter, benchmark: true do
let(:input) do
html = <<-EOF
<p>Hello @alice and @bob, how are you doing today?</p>
<p>This is simple @dummy text to see how the @ReferenceFilter class performs
when @processing HTML.</p>
EOF
Nokogiri::HTML.fragment(html)
end
let(:project) { create(:empty_project) }
let(:filter) { described_class.new(input, project: project) }
describe '#replace_text_nodes_matching' do
let(:iterations) { 6000 }
describe 'with identical input and output HTML' do
benchmark_subject do
filter.replace_text_nodes_matching(User.reference_pattern) do |content|
content
end
end
it { is_expected.to iterate_per_second(iterations) }
end
describe 'with different input and output HTML' do
benchmark_subject do
filter.replace_text_nodes_matching(User.reference_pattern) do |content|
'@eve'
end
end
it { is_expected.to iterate_per_second(iterations) }
end
end
end
+17
View File
@@ -0,0 +1,17 @@
require 'spec_helper'
describe Milestone, benchmark: true do
describe '#sort_issues' do
let(:milestone) { create(:milestone) }
let(:issue1) { create(:issue, milestone: milestone) }
let(:issue2) { create(:issue, milestone: milestone) }
let(:issue3) { create(:issue, milestone: milestone) }
let(:issue_ids) { [issue3.id, issue2.id, issue1.id] }
benchmark_subject { milestone.sort_issues(issue_ids) }
it { is_expected.to iterate_per_second(500) }
end
end
+50
View File
@@ -0,0 +1,50 @@
require 'spec_helper'
describe Project, benchmark: true do
describe '.trending' do
let(:group) { create(:group) }
let(:project1) { create(:empty_project, :public, group: group) }
let(:project2) { create(:empty_project, :public, group: group) }
let(:iterations) { 500 }
before do
2.times do
create(:note_on_commit, project: project1)
end
create(:note_on_commit, project: project2)
end
describe 'without an explicit start date' do
benchmark_subject { described_class.trending.to_a }
it { is_expected.to iterate_per_second(iterations) }
end
describe 'with an explicit start date' do
let(:date) { 1.month.ago }
benchmark_subject { described_class.trending(date).to_a }
it { is_expected.to iterate_per_second(iterations) }
end
end
describe '.find_with_namespace' do
let(:group) { create(:group, name: 'sisinmaru') }
let(:project) { create(:project, name: 'maru', namespace: group) }
describe 'using a capitalized namespace' do
benchmark_subject { described_class.find_with_namespace('sisinmaru/MARU') }
it { is_expected.to iterate_per_second(600) }
end
describe 'using a lowercased namespace' do
benchmark_subject { described_class.find_with_namespace('sisinmaru/maru') }
it { is_expected.to iterate_per_second(600) }
end
end
end
@@ -0,0 +1,23 @@
require 'spec_helper'
describe ProjectTeam, benchmark: true do
describe '#max_member_access' do
let(:group) { create(:group) }
let(:project) { create(:empty_project, group: group) }
let(:user) { create(:user) }
before do
project.team << [user, :master]
5.times do
project.team << [create(:user), :reporter]
project.group.add_user(create(:user), :reporter)
end
end
benchmark_subject { project.team.max_member_access(user.id) }
it { is_expected.to iterate_per_second(35000) }
end
end
+42
View File
@@ -0,0 +1,42 @@
require 'spec_helper'
describe User, benchmark: true do
describe '.by_login' do
before do
%w{Alice Bob Eve}.each do |name|
create(:user,
email: "#{name}@gitlab.com",
username: name,
name: name)
end
end
# The iteration count is based on the query taking little over 1 ms when
# using PostgreSQL.
let(:iterations) { 900 }
describe 'using a capitalized username' do
benchmark_subject { User.by_login('Alice') }
it { is_expected.to iterate_per_second(iterations) }
end
describe 'using a lowercase username' do
benchmark_subject { User.by_login('alice') }
it { is_expected.to iterate_per_second(iterations) }
end
describe 'using a capitalized Email address' do
benchmark_subject { User.by_login('Alice@gitlab.com') }
it { is_expected.to iterate_per_second(iterations) }
end
describe 'using a lowercase Email address' do
benchmark_subject { User.by_login('alice@gitlab.com') }
it { is_expected.to iterate_per_second(iterations) }
end
end
end
@@ -0,0 +1,72 @@
require 'spec_helper'
describe AbuseReportsController do
let(:reporter) { create(:user) }
let(:user) { create(:user) }
let(:message) { "This user is a spammer" }
before do
sign_in(reporter)
end
describe "POST create" do
context "with admin notification email set" do
let(:admin_email) { "admin@example.com"}
before(:each) do
stub_application_setting(admin_notification_email: admin_email)
end
it "sends a notification email" do
post :create,
abuse_report: {
user_id: user.id,
message: message
}
email = ActionMailer::Base.deliveries.last
expect(email.to).to eq([admin_email])
expect(email.subject).to include(user.username)
expect(email.text_part.body).to include(message)
end
it "saves the abuse report" do
expect do
post :create,
abuse_report: {
user_id: user.id,
message: message
}
end.to change { AbuseReport.count }.by(1)
end
end
context "without admin notification email set" do
before(:each) do
stub_application_setting(admin_notification_email: nil)
end
it "does not send a notification email" do
expect do
post :create,
abuse_report: {
user_id: user.id,
message: message
}
end.not_to change { ActionMailer::Base.deliveries.count }
end
it "saves the abuse report" do
expect do
post :create,
abuse_report: {
user_id: user.id,
message: message
}
end.to change { AbuseReport.count }.by(1)
end
end
end
end
@@ -7,6 +7,21 @@ describe Admin::UsersController do
sign_in(admin)
end
describe 'POST login_as' do
let(:user) { create(:user) }
it 'logs admin as another user' do
expect(warden.authenticate(scope: :user)).not_to eq(user)
post :login_as, id: user.username
expect(warden.authenticate(scope: :user)).to eq(user)
end
it 'redirects user to homepage' do
post :login_as, id: user.username
expect(response).to redirect_to(root_path)
end
end
describe 'DELETE #user with projects' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
@@ -22,6 +37,32 @@ describe Admin::UsersController do
end
end
describe 'PUT block/:id' do
let(:user) { create(:user) }
it 'blocks user' do
put :block, id: user.username
user.reload
expect(user.blocked?).to be_truthy
expect(flash[:notice]).to eq 'Successfully blocked'
end
end
describe 'PUT unblock/:id' do
let(:user) { create(:user) }
before do
user.block
end
it 'unblocks user' do
put :unblock, id: user.username
user.reload
expect(user.blocked?).to be_falsey
expect(flash[:notice]).to eq 'Successfully unblocked'
end
end
describe 'PUT unlock/:id' do
let(:user) { create(:user) }
@@ -1,27 +0,0 @@
require "spec_helper"
describe Ci::CommitsController do
before do
@project = FactoryGirl.create :ci_project
end
describe "GET /status" do
it "returns status of commit" do
commit = FactoryGirl.create :ci_commit, project: @project
get :status, id: commit.sha, ref_id: commit.ref, project_id: @project.id
expect(response).to be_success
expect(response.code).to eq('200')
JSON.parse(response.body)["status"] == "pending"
end
it "returns not_found status" do
commit = FactoryGirl.create :ci_commit, project: @project
get :status, id: commit.sha, ref_id: "deploy", project_id: @project.id
expect(response).to be_success
expect(response.code).to eq('200')
JSON.parse(response.body)["status"] == "not_found"
end
end
end
@@ -41,7 +41,7 @@ describe Import::GithubController do
it "assigns variables" do
@project = create(:project, import_type: 'github', creator_id: user.id)
stub_client(repos: [@repo], orgs: [@org], org_repos: [@org_repo])
stub_client(repos: [@repo, @org_repo], orgs: [@org], org_repos: [@org_repo])
get :status
@@ -0,0 +1,33 @@
require 'spec_helper'
describe InvitesController do
let(:token) { '123456' }
let(:user) { create(:user) }
let(:member) { create(:project_member, invite_token: token, invite_email: 'test@abc.com', user: user) }
before do
controller.instance_variable_set(:@member, member)
sign_in(user)
end
describe 'GET #accept' do
it 'accepts user' do
get :accept, id: token
member.reload
expect(response.status).to eq(302)
expect(member.user).to eq(user)
expect(flash[:notice]).to include 'You have been granted'
end
end
describe 'GET #decline' do
it 'declines user' do
get :decline, id: token
expect{member.reload}.to raise_error ActiveRecord::RecordNotFound
expect(response.status).to eq(302)
expect(flash[:notice]).to include 'You have declined the invitation to join'
end
end
end
@@ -8,28 +8,34 @@ describe Projects::IssuesController do
before do
sign_in(user)
project.team << [user, :developer]
controller.instance_variable_set(:@project, project)
end
describe "GET #index" do
it "returns index" do
get :index, namespace_id: project.namespace.id, project_id: project.id
get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(200)
end
it "return 301 if request path doesn't match project path" do
get :index, namespace_id: project.namespace.path, project_id: project.path.upcase
expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project))
end
it "returns 404 when issues are disabled" do
project.issues_enabled = false
project.save
get :index, namespace_id: project.namespace.id, project_id: project.id
get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(404)
end
it "returns 404 when external issue tracker is enabled" do
controller.instance_variable_set(:@project, project)
allow(project).to receive(:default_issues_tracker?).and_return(false)
get :index, namespace_id: project.namespace.id, project_id: project.id
get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(404)
end
@@ -33,33 +33,5 @@ describe Projects::RepositoriesController do
expect(response.status).to eq(404)
end
end
context "when the service doesn't return a path" do
before do
allow(service).to receive(:execute).and_return(nil)
end
it "reloads the page" do
get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip"
expect(response).to redirect_to(archive_namespace_project_repository_path(project.namespace, project, ref: "master", format: "zip"))
end
end
context "when the service returns a path" do
let(:path) { Rails.root.join("spec/fixtures/dk.png").to_s }
before do
allow(service).to receive(:execute).and_return(path)
end
it "sends the file" do
get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip"
expect(response.body).to eq(File.binread(path))
end
end
end
end
@@ -10,26 +10,43 @@ describe Projects::ServicesController do
project.team << [user, :master]
controller.instance_variable_set(:@project, project)
controller.instance_variable_set(:@service, service)
request.env["HTTP_REFERER"] = "/"
end
describe "#test" do
context 'success' do
it "should redirect and show success message" do
expect(service).to receive(:test).and_return({ success: true, result: 'done' })
get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html
expect(response.status).to redirect_to('/')
expect(flash[:notice]).to eq('We sent a request to the provided URL')
end
shared_examples_for 'services controller' do |referrer|
before do
request.env["HTTP_REFERER"] = referrer
end
context 'failure' do
it "should redirect and show failure message" do
expect(service).to receive(:test).and_return({ success: false, result: 'Bad test' })
get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html
expect(response.status).to redirect_to('/')
expect(flash[:alert]).to eq('We tried to send a request to the provided URL but an error occurred: Bad test')
describe "#test" do
context 'success' do
it "should redirect and show success message" do
expect(service).to receive(:test).and_return({ success: true, result: 'done' })
get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html
expect(response.status).to redirect_to('/')
expect(flash[:notice]).to eq('We sent a request to the provided URL')
end
end
context 'failure' do
it "should redirect and show failure message" do
expect(service).to receive(:test).and_return({ success: false, result: 'Bad test' })
get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html
expect(response.status).to redirect_to('/')
expect(flash[:alert]).to eq('We tried to send a request to the provided URL but an error occurred: Bad test')
end
end
end
end
describe 'referrer defined' do
it_should_behave_like 'services controller' do
let!(:referrer) { "/" }
end
end
describe 'referrer undefined' do
it_should_behave_like 'services controller' do
let!(:referrer) { nil }
end
end
end
@@ -88,4 +88,40 @@ describe Projects::TreeController do
end
end
end
describe '#create_dir' do
render_views
before do
post(:create_dir,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
id: 'master',
dir_name: path,
new_branch: target_branch,
commit_message: 'Test commit message')
end
context 'successful creation' do
let(:path) { 'files/new_dir'}
let(:target_branch) { 'master-test'}
it 'redirects to the new directory' do
expect(subject).
to redirect_to("/#{project.path_with_namespace}/blob/#{target_branch}/#{path}")
expect(flash[:notice]).to eq('The directory has been successfully created')
end
end
context 'unsuccessful creation' do
let(:path) { 'README.md' }
let(:target_branch) { 'master'}
it 'does not allow overwriting of existing files' do
expect(subject).
to redirect_to("/#{project.path_with_namespace}/blob/master")
expect(flash[:alert]).to eq('Directory already exists as a file')
end
end
end
end
@@ -33,7 +33,7 @@ describe Projects::UploadsController do
it 'returns a content with original filename, new link, and correct type.' do
expect(response.body).to match '\"alt\":\"rails_sample\"'
expect(response.body).to match "\"url\":\"http://localhost/#{project.path_with_namespace}/uploads"
expect(response.body).to match "\"url\":\"/uploads"
expect(response.body).to match '\"is_image\":true'
end
end
@@ -49,7 +49,7 @@ describe Projects::UploadsController do
it 'returns a content with original filename, new link, and correct type.' do
expect(response.body).to match '\"alt\":\"doc_sample.txt\"'
expect(response.body).to match "\"url\":\"http://localhost/#{project.path_with_namespace}/uploads"
expect(response.body).to match "\"url\":\"/uploads"
expect(response.body).to match '\"is_image\":false'
end
end
@@ -21,6 +21,71 @@ describe ProjectsController do
expect(response.body).to include("content='#{content}'")
end
end
context "rendering default project view" do
render_views
it "renders the activity view" do
allow(controller).to receive(:current_user).and_return(user)
allow(user).to receive(:project_view).and_return('activity')
get :show, namespace_id: public_project.namespace.path, id: public_project.path
expect(response).to render_template('_activity')
end
it "renders the readme view" do
allow(controller).to receive(:current_user).and_return(user)
allow(user).to receive(:project_view).and_return('readme')
get :show, namespace_id: public_project.namespace.path, id: public_project.path
expect(response).to render_template('_readme')
end
it "renders the files view" do
allow(controller).to receive(:current_user).and_return(user)
allow(user).to receive(:project_view).and_return('files')
get :show, namespace_id: public_project.namespace.path, id: public_project.path
expect(response).to render_template('_files')
end
end
context "when requested with case sensitive namespace and project path" do
context "when there is a match with the same casing" do
it "loads the project" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path
expect(assigns(:project)).to eq(public_project)
expect(response.status).to eq(200)
end
end
context "when there is a match with different casing" do
it "redirects to the normalized path" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase
expect(assigns(:project)).to eq(public_project)
expect(response).to redirect_to("/#{public_project.path_with_namespace}")
end
# MySQL queries are case insensitive by default, so this spec would fail.
if Gitlab::Database.postgresql?
context "when there is also a match with the same casing" do
let!(:other_project) { create(:project, :public, namespace: public_project.namespace, path: public_project.path.upcase) }
it "loads the exactly matched project" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase
expect(assigns(:project)).to eq(other_project)
expect(response.status).to eq(200)
end
end
end
end
end
end
describe "POST #toggle_star" do
@@ -48,4 +113,50 @@ describe ProjectsController do
expect(user.starred?(public_project)).to be_falsey
end
end
describe "DELETE remove_fork" do
context 'when signed in' do
before do
sign_in(user)
end
context 'with forked project' do
let(:project_fork) { create(:project, namespace: user.namespace) }
before do
create(:forked_project_link, forked_to_project: project_fork)
end
it 'should remove fork from project' do
delete(:remove_fork,
namespace_id: project_fork.namespace.to_param,
id: project_fork.to_param, format: :js)
expect(project_fork.forked?).to be_falsey
expect(flash[:notice]).to eq('The fork relationship has been removed.')
expect(response).to render_template(:remove_fork)
end
end
context 'when project not forked' do
let(:unforked_project) { create(:project, namespace: user.namespace) }
it 'should do nothing if project was not forked' do
delete(:remove_fork,
namespace_id: unforked_project.namespace.to_param,
id: unforked_project.to_param, format: :js)
expect(flash[:notice]).to be_nil
expect(response).to render_template(:remove_fork)
end
end
end
it "does nothing if user is not signed in" do
delete(:remove_fork,
namespace_id: project.namespace.to_param,
id: project.to_param, format: :js)
expect(response.status).to eq(401)
end
end
end
+23 -1
View File
@@ -10,7 +10,7 @@ describe RootController do
allow(subject).to receive(:current_user).and_return(user)
end
context 'who has customized their dashboard setting' do
context 'who has customized their dashboard setting for starred projects' do
before do
user.update_attribute(:dashboard, 'stars')
end
@@ -21,6 +21,28 @@ describe RootController do
end
end
context 'who has customized their dashboard setting for project activities' do
before do
user.update_attribute(:dashboard, 'project_activity')
end
it 'redirects to the activity list' do
get :index
expect(response).to redirect_to activity_dashboard_path
end
end
context 'who has customized their dashboard setting for starred project activities' do
before do
user.update_attribute(:dashboard, 'starred_project_activity')
end
it 'redirects to the activity list' do
get :index
expect(response).to redirect_to activity_dashboard_path(filter: 'starred')
end
end
context 'who uses the default dashboard setting' do
it 'renders the default dashboard' do
get :index
+7
View File
@@ -27,6 +27,9 @@
FactoryGirl.define do
factory :ci_build, class: Ci::Build do
name 'test'
ref 'master'
tag false
started_at 'Di 29. Okt 09:51:28 CET 2013'
finished_at 'Di 29. Okt 09:53:28 CET 2013'
commands 'ls -a'
@@ -43,5 +46,9 @@ FactoryGirl.define do
started_at nil
finished_at nil
end
factory :ci_build_tag do
tag true
end
end
end
+15 -41
View File
@@ -17,58 +17,32 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :ci_commit, class: Ci::Commit do
ref 'master'
before_sha '76de212e80737a608d939f648d959671fb0a0142'
factory :ci_empty_commit, class: Ci::Commit do
sha '97de212e80737a608d939f648d959671fb0a0142'
push_data do
{
ref: 'refs/heads/master',
before: '76de212e80737a608d939f648d959671fb0a0142',
after: '97de212e80737a608d939f648d959671fb0a0142',
user_name: 'Git User',
user_email: 'git@example.com',
repository: {
name: 'test-data',
url: 'ssh://git@gitlab.com/test/test-data.git',
description: '',
homepage: 'http://gitlab.com/test/test-data'
},
commits: [
{
id: '97de212e80737a608d939f648d959671fb0a0142',
message: 'Test commit message',
timestamp: '2014-09-23T13:12:25+02:00',
url: 'https://gitlab.com/test/test-data/commit/97de212e80737a608d939f648d959671fb0a0142',
author: {
name: 'Git User',
email: 'git@user.com'
}
}
],
total_commits_count: 1,
ci_yaml_file: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
}
end
gl_project factory: :empty_project
factory :ci_commit_without_jobs do
after(:create) do |commit, evaluator|
commit.push_data[:ci_yaml_file] = YAML.dump({})
commit.save
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) }
end
end
factory :ci_commit_with_one_job do
after(:create) do |commit, evaluator|
commit.push_data[:ci_yaml_file] = YAML.dump({ rspec: { script: "ls" } })
commit.save
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) }
end
end
factory :ci_commit_with_two_jobs do
after(:create) do |commit, evaluator|
commit.push_data[:ci_yaml_file] = YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } })
commit.save
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) }
end
end
factory :ci_commit do
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) }
end
end
end
+1 -13
View File
@@ -29,21 +29,9 @@
FactoryGirl.define do
factory :ci_project_without_token, class: Ci::Project do
sequence :name do |n|
"GitLab / gitlab-shell#{n}"
end
default_ref 'master'
sequence :path do |n|
"gitlab/gitlab-shell#{n}"
end
sequence :ssh_url_to_repo do |n|
"git@demo.gitlab.com:gitlab/gitlab-shell#{n}.git"
end
gl_project factory: :project
gl_project factory: :empty_project
factory :ci_project do
token 'iPWx6WM4lhHNedGfBpPJNP'
+15
View File
@@ -0,0 +1,15 @@
FactoryGirl.define do
factory :commit_status, class: CommitStatus do
started_at 'Di 29. Okt 09:51:28 CET 2013'
finished_at 'Di 29. Okt 09:53:28 CET 2013'
name 'default'
status 'success'
description 'commit status'
commit factory: :ci_commit
factory :generic_commit_status, class: GenericCommitStatus do
name 'generic'
description 'external commit status'
end
end
end
+21
View File
@@ -111,6 +111,27 @@ describe "Admin::Users", feature: true do
expect(page).to have_content(@user.name)
end
describe 'Login as another user' do
it 'should show login button for other users and check that it works' do
another_user = create(:user)
visit admin_user_path(another_user)
click_link 'Log in as this user'
expect(page).to have_content("Logged in as #{another_user.username}")
page.within '.sidebar-user .username' do
expect(page).to have_content(another_user.username)
end
end
it 'should not show login button for admin itself' do
visit admin_user_path(@user)
expect(page).not_to have_content('Log in as this user')
end
end
describe 'Two-factor Authentication status' do
it 'shows when enabled' do
@user.update_attribute(:two_factor_enabled, true)
+89
View File
@@ -0,0 +1,89 @@
require 'spec_helper'
describe "Builds" do
before do
login_as(:user)
@commit = FactoryGirl.create :ci_commit
@build = FactoryGirl.create :ci_build, commit: @commit
@gl_project = @commit.project.gl_project
@gl_project.team << [@user, :master]
end
describe "GET /:project/builds" do
context "Running scope" do
before do
@build.run!
visit namespace_project_builds_path(@gl_project.namespace, @gl_project)
end
it { expect(page).to have_content 'Running' }
it { expect(page).to have_content 'Cancel all' }
it { expect(page).to have_content @build.short_sha }
it { expect(page).to have_content @build.ref }
it { expect(page).to have_content @build.name }
end
context "Finished scope" do
before do
@build.run!
visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :finished)
end
it { expect(page).to have_content 'No builds to show' }
it { expect(page).to have_content 'Cancel all' }
end
context "All builds" do
before do
@gl_project.ci_builds.running_or_pending.each(&:success)
visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :all)
end
it { expect(page).to have_content 'All' }
it { expect(page).to have_content @build.short_sha }
it { expect(page).to have_content @build.ref }
it { expect(page).to have_content @build.name }
it { expect(page).to_not have_content 'Cancel all' }
end
end
describe "GET /:project/builds/:id/cancel_all" do
before do
@build.run!
visit cancel_all_namespace_project_builds_path(@gl_project.namespace, @gl_project)
end
it { expect(page).to have_content 'No builds to show' }
it { expect(page).to_not have_content 'Cancel all' }
end
describe "GET /:project/builds/:id" do
before do
visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
end
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
end
describe "GET /:project/builds/:id/cancel" do
before do
@build.run!
visit cancel_namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
end
it { expect(page).to have_content 'canceled' }
it { expect(page).to have_content 'Retry' }
end
describe "POST /:project/builds/:id/retry" do
before do
visit cancel_namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
click_link 'Retry'
end
it { expect(page).to have_content 'pending' }
it { expect(page).to have_content 'Cancel' }
end
end
+5 -6
View File
@@ -1,8 +1,7 @@
require 'spec_helper'
describe "Admin Builds" do
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:commit) { FactoryGirl.create :ci_commit }
let(:build) { FactoryGirl.create :ci_build, commit: commit }
before do
@@ -22,10 +21,10 @@ describe "Admin Builds" do
describe "Tabs" do
it "shows all builds" do
build = FactoryGirl.create :ci_build, commit: commit, status: "pending"
build1 = FactoryGirl.create :ci_build, commit: commit, status: "running"
build2 = FactoryGirl.create :ci_build, commit: commit, status: "success"
build3 = FactoryGirl.create :ci_build, commit: commit, status: "failed"
FactoryGirl.create :ci_build, commit: commit, status: "pending"
FactoryGirl.create :ci_build, commit: commit, status: "running"
FactoryGirl.create :ci_build, commit: commit, status: "success"
FactoryGirl.create :ci_build, commit: commit, status: "failed"
visit ci_admin_builds_path
+13 -14
View File
@@ -2,8 +2,7 @@ require 'spec_helper'
describe "Admin Runners" do
before do
skip_ci_admin_auth
login_as :user
login_as :admin
end
describe "Runners page" do
@@ -20,16 +19,16 @@ describe "Admin Runners" do
describe 'search' do
before do
FactoryGirl.create :ci_runner, description: 'foo'
FactoryGirl.create :ci_runner, description: 'bar'
FactoryGirl.create :ci_runner, description: 'runner-foo'
FactoryGirl.create :ci_runner, description: 'runner-bar'
search_form = find('#runners-search')
search_form.fill_in 'search', with: 'foo'
search_form.fill_in 'search', with: 'runner-foo'
search_form.click_button 'Search'
end
it { expect(page).to have_content("foo") }
it { expect(page).not_to have_content("bar") }
it { expect(page).to have_content("runner-foo") }
it { expect(page).not_to have_content("runner-bar") }
end
end
@@ -37,8 +36,8 @@ describe "Admin Runners" do
let(:runner) { FactoryGirl.create :ci_runner }
before do
FactoryGirl.create(:ci_project, name: "foo")
FactoryGirl.create(:ci_project, name: "bar")
@project1 = FactoryGirl.create(:ci_project)
@project2 = FactoryGirl.create(:ci_project)
visit ci_admin_runner_path(runner)
end
@@ -47,19 +46,19 @@ describe "Admin Runners" do
end
describe 'projects' do
it { expect(page).to have_content("foo") }
it { expect(page).to have_content("bar") }
it { expect(page).to have_content(@project1.name_with_namespace) }
it { expect(page).to have_content(@project2.name_with_namespace) }
end
describe 'search' do
before do
search_form = find('#runner-projects-search')
search_form.fill_in 'search', with: 'foo'
search_form.fill_in 'search', with: @project1.gl_project.name
search_form.click_button 'Search'
end
it { expect(page).to have_content("foo") }
it { expect(page).not_to have_content("bar") }
it { expect(page).to have_content(@project1.name_with_namespace) }
it { expect(page).not_to have_content(@project2.name_with_namespace) }
end
end
end
-60
View File
@@ -1,60 +0,0 @@
require 'spec_helper'
describe "Builds" do
context :private_project do
before do
@project = FactoryGirl.create :ci_project
@commit = FactoryGirl.create :ci_commit, project: @project
@build = FactoryGirl.create :ci_build, commit: @commit
login_as :user
@project.gl_project.team << [@user, :master]
end
describe "GET /:project/builds/:id" do
before do
visit ci_project_build_path(@project, @build)
end
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
end
describe "GET /:project/builds/:id/cancel" do
before do
@build.run!
visit cancel_ci_project_build_path(@project, @build)
end
it { expect(page).to have_content 'canceled' }
it { expect(page).to have_content 'Retry' }
end
describe "POST /:project/builds/:id/retry" do
before do
@build.cancel!
visit ci_project_build_path(@project, @build)
click_link 'Retry'
end
it { expect(page).to have_content 'pending' }
it { expect(page).to have_content 'Cancel' }
end
end
context :public_project do
describe "Show page public accessible" do
before do
@project = FactoryGirl.create :ci_public_project
@commit = FactoryGirl.create :ci_commit, project: @project
@runner = FactoryGirl.create :ci_specific_runner
@build = FactoryGirl.create :ci_build, commit: @commit, runner: @runner
stub_gitlab_calls
visit ci_project_build_path(@project, @build)
end
it { expect(page).to have_content @commit.sha[0..7] }
end
end
end
-69
View File
@@ -1,69 +0,0 @@
require 'spec_helper'
describe "Commits" do
include Ci::CommitsHelper
context "Authenticated user" do
before do
@project = FactoryGirl.create :ci_project
@commit = FactoryGirl.create :ci_commit, project: @project
@build = FactoryGirl.create :ci_build, commit: @commit
login_as :user
@project.gl_project.team << [@user, :master]
end
describe "GET /:project/commits/:sha" do
before do
visit ci_commit_path(@commit)
end
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
end
describe "Cancel commit" do
it "cancels commit" do
visit ci_commit_path(@commit)
click_on "Cancel"
expect(page).to have_content "canceled"
end
end
describe ".gitlab-ci.yml not found warning" do
it "does not show warning" do
visit ci_commit_path(@commit)
expect(page).not_to have_content ".gitlab-ci.yml not found in this commit"
end
it "shows warning" do
@commit.push_data[:ci_yaml_file] = nil
@commit.save
visit ci_commit_path(@commit)
expect(page).to have_content ".gitlab-ci.yml not found in this commit"
end
end
end
context "Public pages" do
before do
@project = FactoryGirl.create :ci_public_project
@commit = FactoryGirl.create :ci_commit, project: @project
@build = FactoryGirl.create :ci_build, commit: @commit
end
describe "GET /:project/commits/:sha" do
before do
visit ci_commit_path(@commit)
end
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
end
end
end
-38
View File
@@ -1,38 +0,0 @@
require 'spec_helper'
describe "Projects" do
let(:user) { create(:user) }
before do
login_as(user)
@project = FactoryGirl.create :ci_project, name: "GitLab / gitlab-shell"
@project.gl_project.team << [user, :master]
end
describe "GET /ci/projects/:id" do
before do
visit ci_project_path(@project)
end
it { expect(page).to have_content @project.name }
it { expect(page).to have_content 'All commits' }
end
describe "GET /ci/projects/:id/edit" do
before do
visit edit_ci_project_path(@project)
end
it { expect(page).to have_content @project.name }
it { expect(page).to have_content 'Build Schedule' }
it "updates configuration" do
fill_in 'Timeout', with: '70'
click_button 'Save changes'
expect(page).to have_content 'was successfully updated'
expect(find_field('Timeout').value).to eq '70'
end
end
end
+22
View File
@@ -0,0 +1,22 @@
require 'spec_helper'
describe "CI settings" do
let(:user) { create(:user) }
before { login_as(user) }
before do
@project = FactoryGirl.create :ci_project
@gl_project = @project.gl_project
@gl_project.team << [user, :master]
visit edit_namespace_project_ci_settings_path(@gl_project.namespace, @gl_project)
end
it { expect(page).to have_content 'Build Schedule' }
it "updates configuration" do
fill_in 'Timeout', with: '70'
click_button 'Save changes'
expect(page).to have_content 'was successfully updated'
expect(find_field('Timeout').value).to eq '70'
end
end
+27
View File
@@ -0,0 +1,27 @@
require 'spec_helper'
describe 'CI web hooks' do
let(:user) { create(:user) }
before { login_as(user) }
before do
@project = FactoryGirl.create :ci_project
@gl_project = @project.gl_project
@gl_project.team << [user, :master]
visit namespace_project_ci_web_hooks_path(@gl_project.namespace, @gl_project)
end
context 'create a trigger' do
before do
fill_in 'web_hook_url', with: 'http://example.com'
click_on 'Add Web Hook'
end
it { expect(@project.web_hooks.count).to eq(1) }
it 'revokes the trigger' do
click_on 'Remove'
expect(@project.web_hooks.count).to eq(0)
end
end
end
+61
View File
@@ -0,0 +1,61 @@
require 'spec_helper'
describe "Commits" do
include CiStatusHelper
let(:project) { create(:project) }
describe "CI" do
before do
login_as :user
project.team << [@user, :master]
@ci_project = project.ensure_gitlab_ci_project
@commit = FactoryGirl.create :ci_commit, gl_project: project, sha: project.commit.sha
@build = FactoryGirl.create :ci_build, commit: @commit
@generic_status = FactoryGirl.create :generic_commit_status, commit: @commit
end
before do
stub_ci_commit_to_return_yaml_file
end
describe "GET /:project/commits/:sha" do
before do
visit ci_status_path(@commit)
end
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
end
describe "Cancel all builds" do
it "cancels commit" do
visit ci_status_path(@commit)
click_on "Cancel all"
expect(page).to have_content "canceled"
end
end
describe "Cancel build" do
it "cancels build" do
visit ci_status_path(@commit)
click_on "Cancel"
expect(page).to have_content "canceled"
end
end
describe ".gitlab-ci.yml not found warning" do
it "does not show warning" do
visit ci_status_path(@commit)
expect(page).not_to have_content ".gitlab-ci.yml not found in this commit"
end
it "shows warning" do
stub_ci_commit_yaml_file(nil)
visit ci_status_path(@commit)
expect(page).to have_content ".gitlab-ci.yml not found in this commit"
end
end
end
end
+1 -1
View File
@@ -95,7 +95,7 @@ feature 'Login', feature: true do
user = create(:user, password: 'not-the-default')
login_with(user)
expect(page).to have_content('Invalid email or password.')
expect(page).to have_content('Invalid login or password.')
end
end
end
+1 -1
View File
@@ -220,7 +220,7 @@ describe 'GitLab Markdown', feature: true do
end
end
# `markdown` calls these two methods
# Fake a `current_user` helper
def current_user
@feat.user
end
+34 -44
View File
@@ -1,53 +1,43 @@
require 'spec_helper'
feature 'Password reset', feature: true do
def forgot_password
describe 'throttling' do
it 'sends reset instructions when not previously sent' do
visit root_path
forgot_password(create(:user))
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
expect(current_path).to eq new_user_session_path
end
it 'sends reset instructions when previously sent more than a minute ago' do
user = create(:user)
user.send_reset_password_instructions
user.update_attribute(:reset_password_sent_at, 5.minutes.ago)
visit root_path
forgot_password(user)
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
expect(current_path).to eq new_user_session_path
end
it "throttles multiple resets in a short timespan" do
user = create(:user)
user.send_reset_password_instructions
visit root_path
forgot_password(user)
expect(page).to have_content(I18n.t('devise.passwords.recently_reset'))
expect(current_path).to eq new_user_password_path
end
end
def forgot_password(user)
click_on 'Forgot your password?'
fill_in 'Email', with: user.email
click_button 'Reset password'
user.reload
end
def get_reset_token
mail = ActionMailer::Base.deliveries.last
body = mail.body.encoded
body.scan(/reset_password_token=(.+)\"/).flatten.first
end
def reset_password(password = 'password')
visit edit_user_password_path(reset_password_token: get_reset_token)
fill_in 'New password', with: password
fill_in 'Confirm new password', with: password
click_button 'Change your password'
end
describe 'with two-factor authentication' do
let(:user) { create(:user, :two_factor) }
it 'requires login after password reset' do
visit root_path
forgot_password
reset_password
expect(page).to have_content("Your password was changed successfully.")
expect(page).not_to have_content("You are now signed in.")
expect(current_path).to eq new_user_session_path
end
end
describe 'without two-factor authentication' do
let(:user) { create(:user) }
it 'automatically logs in after password reset' do
visit root_path
forgot_password
reset_password
expect(current_path).to eq root_path
expect(page).to have_content("Your password was changed successfully. You are now signed in.")
end
end
end
+25 -4
View File
@@ -34,6 +34,27 @@ feature 'Project', feature: true do
end
end
describe 'remove forked relationship', js: true do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
before do
login_with user
create(:forked_project_link, forked_to_project: project)
visit edit_namespace_project_path(project.namespace, project)
end
it 'should remove fork' do
expect(page).to have_content 'Remove fork relationship'
remove_with_confirm('Remove fork relationship', project.path)
expect(page).to have_content 'The fork relationship has been removed.'
expect(project.forked?).to be_falsey
expect(page).not_to have_content 'Remove fork relationship'
end
end
describe 'removal', js: true do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
@@ -45,13 +66,13 @@ feature 'Project', feature: true do
end
it 'should remove project' do
expect { remove_project }.to change {Project.count}.by(-1)
expect { remove_with_confirm('Remove project', project.path) }.to change {Project.count}.by(-1)
end
end
def remove_project
click_link "Remove project"
fill_in 'confirm_name_input', with: project.path
def remove_with_confirm(button_text, confirm_with)
click_button button_text
fill_in 'confirm_name_input', with: confirm_with
click_button 'Confirm'
end
end
@@ -1,11 +1,10 @@
require 'spec_helper'
describe "Runners" do
let(:user) { create(:user) }
include GitlabRoutingHelper
before do
login_as(user)
end
let(:user) { create(:user) }
before { login_as(user) }
describe "specific runners" do
before do
@@ -20,18 +19,17 @@ describe "Runners" do
@specific_runner2 = FactoryGirl.create :ci_specific_runner
@project.runners << @specific_runner
@project2.runners << @specific_runner2
visit runners_path(@project.gl_project)
end
it "places runners in right places" do
visit ci_project_runners_path(@project)
expect(page.find(".available-specific-runners")).to have_content(@specific_runner2.display_name)
expect(page.find(".activated-specific-runners")).to have_content(@specific_runner.display_name)
expect(page.find(".available-shared-runners")).to have_content(@shared_runner.display_name)
end
it "enables specific runner for project" do
visit ci_project_runners_path(@project)
within ".available-specific-runners" do
click_on "Enable for this project"
end
@@ -41,8 +39,7 @@ describe "Runners" do
it "disables specific runner for project" do
@project2.runners << @specific_runner
visit ci_project_runners_path(@project)
visit runners_path(@project.gl_project)
within ".activated-specific-runners" do
click_on "Disable for this project"
@@ -52,8 +49,6 @@ describe "Runners" do
end
it "removes specific runner for project if this is last project for that runners" do
visit ci_project_runners_path(@project)
within ".activated-specific-runners" do
click_on "Remove runner"
end
@@ -66,13 +61,11 @@ describe "Runners" do
before do
@project = FactoryGirl.create :ci_project
@project.gl_project.team << [user, :master]
visit runners_path(@project.gl_project)
end
it "enables shared runners" do
visit ci_project_runners_path(@project)
click_on "Enable shared runners"
expect(@project.reload.shared_runners_enabled).to be_truthy
end
end
@@ -83,13 +76,11 @@ describe "Runners" do
@project.gl_project.team << [user, :master]
@specific_runner = FactoryGirl.create :ci_specific_runner
@project.runners << @specific_runner
visit runners_path(@project.gl_project)
end
it "shows runner information" do
visit ci_project_runners_path(@project)
click_on @specific_runner.short_sha
expect(page).to have_content(@specific_runner.platform)
end
end
@@ -1,13 +1,14 @@
require 'spec_helper'
describe 'Triggers' do
let(:user) { create(:user) }
let(:user) { create(:user) }
before { login_as(user) }
before do
login_as(user)
@project = FactoryGirl.create :ci_project
@project.gl_project.team << [user, :master]
visit ci_project_triggers_path(@project)
@gl_project = @project.gl_project
@gl_project.team << [user, :master]
visit namespace_project_triggers_path(@gl_project.namespace, @gl_project)
end
context 'create a trigger' do
+2 -2
View File
@@ -1,6 +1,8 @@
require 'spec_helper'
feature 'Users', feature: true do
let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
scenario 'GET /users/sign_in creates a new user account' do
visit new_user_session_path
fill_in 'user_name', with: 'Name Surname'
@@ -11,7 +13,6 @@ feature 'Users', feature: true do
end
scenario 'Successful user signin invalidates password reset token' do
user = create(:user)
expect(user.reset_password_token).to be_nil
visit new_user_password_path
@@ -28,7 +29,6 @@ feature 'Users', feature: true do
expect(user.reset_password_token).to be_nil
end
let!(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
scenario 'Should show one error if email is already taken' do
visit new_user_session_path
fill_in 'user_name', with: 'Another user name'
@@ -1,28 +1,25 @@
require 'spec_helper'
describe "Variables" do
let(:user) { create(:user) }
before do
login_as(user)
end
let(:user) { create(:user) }
before { login_as(user) }
describe "specific runners" do
before do
@project = FactoryGirl.create :ci_project
@project.gl_project.team << [user, :master]
@gl_project = @project.gl_project
@gl_project.team << [user, :master]
end
it "creates variable", js: true do
visit ci_project_variables_path(@project)
visit namespace_project_variables_path(@gl_project.namespace, @gl_project)
click_on "Add a variable"
fill_in "Key", with: "SECRET_KEY"
fill_in "Value", with: "SECRET_VALUE"
click_on "Save changes"
expect(page).to have_content("Variables were successfully updated.")
expect(@project.variables.count).to eq(1)
end
end
end
+20
View File
@@ -6,9 +6,11 @@ describe IssuesFinder do
let(:project1) { create(:project) }
let(:project2) { create(:project) }
let(:milestone) { create(:milestone, project: project1) }
let(:label) { create(:label, project: project2) }
let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) }
let(:issue2) { create(:issue, author: user, assignee: user, project: project2) }
let(:issue3) { create(:issue, author: user2, assignee: user2, project: project2) }
let!(:label_link) { create(:label_link, label: label, target: issue2) }
before do
project1.team << [user, :master]
@@ -48,6 +50,24 @@ describe IssuesFinder do
expect(issues).to eq([issue1])
end
it 'should filter by no milestone id' do
params = { scope: "all", milestone_title: Milestone::None.title, state: 'opened' }
issues = IssuesFinder.new(user, params).execute
expect(issues).to match_array([issue2, issue3])
end
it 'should filter by label name' do
params = { scope: "all", label_name: label.title, state: 'opened' }
issues = IssuesFinder.new(user, params).execute
expect(issues).to eq([issue2])
end
it 'should filter by no label name' do
params = { scope: "all", label_name: Label::None.title, state: 'opened' }
issues = IssuesFinder.new(user, params).execute
expect(issues).to match_array([issue1, issue3])
end
it 'should be empty for unauthorized user' do
params = { scope: "all", state: 'opened' }
issues = IssuesFinder.new(nil, params).execute
@@ -0,0 +1,39 @@
require 'spec_helper'
describe TrendingProjectsFinder do
let(:user) { build(:user) }
describe '#execute' do
describe 'without an explicit start date' do
subject { described_class.new }
it 'returns the trending projects' do
relation = double(:ar_relation)
allow(subject).to receive(:projects_for)
.with(user)
.and_return(relation)
allow(relation).to receive(:trending)
.with(an_instance_of(ActiveSupport::TimeWithZone))
end
end
describe 'with an explicit start date' do
let(:date) { 2.months.ago }
subject { described_class.new }
it 'returns the trending projects' do
relation = double(:ar_relation)
allow(subject).to receive(:projects_for)
.with(user)
.and_return(relation)
allow(relation).to receive(:trending)
.with(date)
end
end
end
end
+9
View File
@@ -99,6 +99,15 @@ describe ApplicationHelper do
helper.avatar_icon('foo@example.com', 20, 2)
end
describe 'using a User' do
it 'should return an URL for the avatar' do
user = create(:user, avatar: File.open(avatar_file_path))
expect(helper.avatar_icon(user).to_s).
to match("/uploads/user/avatar/#{user.id}/banana_sample.gif")
end
end
end
describe 'gravatar_icon' do
+21 -12
View File
@@ -11,12 +11,15 @@ describe GitlabMarkdownHelper do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:snippet) { create(:project_snippet, project: project) }
# Helper expects a current_user method.
let(:current_user) { user }
before do
# Ensure the generated reference links aren't redacted
project.team << [user, :master]
# Helper expects a @project instance variable
@project = project
helper.instance_variable_set(:@project, project)
# Stub the `current_user` helper
allow(helper).to receive(:current_user).and_return(user)
end
describe "#markdown" do
@@ -25,23 +28,23 @@ describe GitlabMarkdownHelper do
it "should link to the merge request" do
expected = namespace_project_merge_request_path(project.namespace, project, merge_request)
expect(markdown(actual)).to match(expected)
expect(helper.markdown(actual)).to match(expected)
end
it "should link to the commit" do
expected = namespace_project_commit_path(project.namespace, project, commit)
expect(markdown(actual)).to match(expected)
expect(helper.markdown(actual)).to match(expected)
end
it "should link to the issue" do
expected = namespace_project_issue_path(project.namespace, project, issue)
expect(markdown(actual)).to match(expected)
expect(helper.markdown(actual)).to match(expected)
end
end
describe "override default project" do
let(:actual) { issue.to_reference }
let(:second_project) { create(:project) }
let(:second_project) { create(:project, :public) }
let(:second_issue) { create(:issue, project: second_project) }
it 'should link to the issue' do
@@ -56,7 +59,7 @@ describe GitlabMarkdownHelper do
let(:issues) { create_list(:issue, 2, project: project) }
it 'should handle references nested in links with all the text' do
actual = link_to_gfm("This should finally fix #{issues[0].to_reference} and #{issues[1].to_reference} for real", commit_path)
actual = helper.link_to_gfm("This should finally fix #{issues[0].to_reference} and #{issues[1].to_reference} for real", commit_path)
doc = Nokogiri::HTML.parse(actual)
# Make sure we didn't create invalid markup
@@ -86,7 +89,7 @@ describe GitlabMarkdownHelper do
end
it 'should forward HTML options' do
actual = link_to_gfm("Fixed in #{commit.id}", commit_path, class: 'foo')
actual = helper.link_to_gfm("Fixed in #{commit.id}", commit_path, class: 'foo')
doc = Nokogiri::HTML.parse(actual)
expect(doc.css('a')).to satisfy do |v|
@@ -97,15 +100,21 @@ describe GitlabMarkdownHelper do
it "escapes HTML passed in as the body" do
actual = "This is a <h1>test</h1> - see #{issues[0].to_reference}"
expect(link_to_gfm(actual, commit_path)).
expect(helper.link_to_gfm(actual, commit_path)).
to match('&lt;h1&gt;test&lt;/h1&gt;')
end
it 'ignores reference links when they are the entire body' do
text = issues[0].to_reference
act = link_to_gfm(text, '/foo')
act = helper.link_to_gfm(text, '/foo')
expect(act).to eq %Q(<a href="/foo">#{issues[0].to_reference}</a>)
end
it 'should replace commit message with emoji to link' do
actual = link_to_gfm(':book:Book', '/foo')
expect(actual).
to eq %Q(<img class="emoji" title=":book:" alt=":book:" src="http://localhost/assets/emoji/1F4D6.png" height="20" width="20" align="absmiddle"><a href="/foo">Book</a>)
end
end
describe '#render_wiki_content' do
+10
View File
@@ -117,4 +117,14 @@ describe IssuesHelper do
end
end
describe "#merge_requests_sentence" do
subject { merge_requests_sentence(merge_requests)}
let(:merge_requests) do
[ build(:merge_request, iid: 1), build(:merge_request, iid: 2),
build(:merge_request, iid: 3)]
end
it { is_expected.to eq("!1, !2, or !3") }
end
end
-12
View File
@@ -1,12 +0,0 @@
require 'spec_helper'
describe MergeRequestsHelper do
describe :issues_sentence do
subject { issues_sentence(issues) }
let(:issues) do
[build(:issue, iid: 1), build(:issue, iid: 2), build(:issue, iid: 3)]
end
it { is_expected.to eq('#1, #2, and #3') }
end
end
@@ -0,0 +1,32 @@
require 'spec_helper'
describe MergeRequestsHelper do
describe "#issues_sentence" do
subject { issues_sentence(issues) }
let(:issues) do
[build(:issue, iid: 1), build(:issue, iid: 2), build(:issue, iid: 3)]
end
it { is_expected.to eq('#1, #2, and #3') }
end
describe "#format_mr_branch_names" do
describe "within the same project" do
let(:merge_request) { create(:merge_request) }
subject { format_mr_branch_names(merge_request) }
it { is_expected.to eq([merge_request.source_branch, merge_request.target_branch]) }
end
describe "within different projects" do
let(:project) { create(:project) }
let(:fork_project) { create(:project, forked_from_project: project) }
let(:merge_request) { create(:merge_request, source_project: fork_project, target_project: project) }
subject { format_mr_branch_names(merge_request) }
let(:source_title) { "#{fork_project.path_with_namespace}:#{merge_request.source_branch}" }
let(:target_title) { "#{project.path_with_namespace}:#{merge_request.target_branch}" }
it { is_expected.to eq([source_title, target_title]) }
end
end
end
+6 -2
View File
@@ -8,14 +8,18 @@ describe PreferencesHelper do
end
it 'raises an exception when defined choices may be using the wrong key' do
expect(User).to receive(:dashboards).and_return(foo: 'foo', bar: 'bar')
dashboards = User.dashboards.dup
dashboards[:projects_changed] = dashboards.delete :projects
expect(User).to receive(:dashboards).and_return(dashboards)
expect { helper.dashboard_choices }.to raise_error(KeyError)
end
it 'provides better option descriptions' do
expect(helper.dashboard_choices).to match_array [
['Your Projects (default)', 'projects'],
['Starred Projects', 'stars']
['Starred Projects', 'stars'],
["Your Projects' Activity", 'project_activity'],
["Starred Projects' Activity", 'starred_project_activity']
]
end
end
+16 -2
View File
@@ -61,13 +61,27 @@ describe ProjectsHelper do
end
it "returns a valid cach key" do
expect(helper.send(:readme_cache_key)).to eq("#{project.id}-#{project.commit.id}-readme")
expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-#{project.commit.id}-readme")
end
it "returns a valid cache key if HEAD does not exist" do
allow(project).to receive(:commit) { nil }
expect(helper.send(:readme_cache_key)).to eq("#{project.id}-nil-readme")
expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-nil-readme")
end
end
describe 'link_to_member' do
let(:group) { create(:group) }
let(:project) { create(:empty_project, group: group) }
let(:user) { create(:user) }
describe 'using the default options' do
it 'returns an HTML link to the user' do
link = helper.link_to_member(project, user)
expect(link).to match(%r{/u/#{user.username}})
end
end
end
end
@@ -1,6 +1,6 @@
require 'spec_helper'
describe Ci::RunnersHelper do
describe RunnersHelper do
it "returns - not contacted yet" do
runner = FactoryGirl.build :ci_runner
expect(runner_status_icon(runner)).to include("not connected yet")
@@ -12,7 +12,7 @@ describe Ci::RunnersHelper do
end
it "returns online text" do
runner = FactoryGirl.build(:ci_runner, contacted_at: 1.hour.ago, active: true)
runner = FactoryGirl.build(:ci_runner, contacted_at: 1.second.ago, active: true)
expect(runner_status_icon(runner)).to include("Runner is online")
end
end
@@ -1,6 +1,6 @@
require 'spec_helper'
describe Ci::ApplicationHelper do
describe TimeHelper do
describe "#duration_in_words" do
it "returns minutes and seconds" do
intervals_in_words = {
@@ -0,0 +1,70 @@
#= require behaviors/quick_submit
describe 'Quick Submit behavior', ->
fixture.preload('behaviors/quick_submit.html')
beforeEach ->
fixture.load('behaviors/quick_submit.html')
# Prevent a form submit from moving us off the testing page
$('form').submit (e) -> e.preventDefault()
@spies = {
submit: spyOnEvent('form', 'submit')
}
it 'does not respond to other keyCodes', ->
$('input').trigger(keydownEvent(keyCode: 32))
expect(@spies.submit).not.toHaveBeenTriggered()
it 'does not respond to Enter alone', ->
$('input').trigger(keydownEvent(ctrlKey: false, metaKey: false))
expect(@spies.submit).not.toHaveBeenTriggered()
it 'does not respond to repeated events', ->
$('input').trigger(keydownEvent(repeat: true))
expect(@spies.submit).not.toHaveBeenTriggered()
it 'disables submit buttons', ->
$('textarea').trigger(keydownEvent())
expect($('input[type=submit]')).toBeDisabled()
expect($('button[type=submit]')).toBeDisabled()
# We cannot stub `navigator.userAgent` for CI's `rake teaspoon` task, so we'll
# only run the tests that apply to the current platform
if navigator.userAgent.match(/Macintosh/)
it 'responds to Meta+Enter', ->
$('input').trigger(keydownEvent())
expect(@spies.submit).toHaveBeenTriggered()
it 'excludes other modifier keys', ->
$('input').trigger(keydownEvent(altKey: true))
$('input').trigger(keydownEvent(ctrlKey: true))
$('input').trigger(keydownEvent(shiftKey: true))
expect(@spies.submit).not.toHaveBeenTriggered()
else
it 'responds to Ctrl+Enter', ->
$('input').trigger(keydownEvent())
expect(@spies.submit).toHaveBeenTriggered()
it 'excludes other modifier keys', ->
$('input').trigger(keydownEvent(altKey: true))
$('input').trigger(keydownEvent(metaKey: true))
$('input').trigger(keydownEvent(shiftKey: true))
expect(@spies.submit).not.toHaveBeenTriggered()
keydownEvent = (options) ->
if navigator.userAgent.match(/Macintosh/)
defaults = { keyCode: 13, metaKey: true }
else
defaults = { keyCode: 13, ctrlKey: true }
$.Event('keydown', $.extend({}, defaults, options))
@@ -0,0 +1,6 @@
%form{ action: '/foo' }
%input.js-quick-submit{ type: 'text' }
%textarea.js-quick-submit
%input{ type: 'submit'} Submit
%button.btn{ type: 'submit' } Submit
@@ -1,4 +1,4 @@
#tree-content-holder
#blob-content-holder
.file-content
.line-numbers
- 1.upto(25) do |i|
@@ -39,7 +39,7 @@ describe 'LineHighlighter', ->
expect(spy).toHaveBeenPrevented()
it 'handles garbage input from the hash', ->
func = -> new LineHighlighter('#tree-content-holder')
func = -> new LineHighlighter('#blob-content-holder')
expect(func).not.toThrow()
describe '#clickHandler', ->
+1
View File
@@ -9,6 +9,7 @@
# require the specific files that are being used in the spec that tests them.
#= require jquery
#= require jquery.turbolinks
#= require bootstrap
#= require underscore
+2 -3
View File
@@ -4,13 +4,12 @@ describe "Charts" do
context "build_times" do
before do
@project = FactoryGirl.create(:ci_project)
@commit = FactoryGirl.create(:ci_commit, project: @project)
@commit = FactoryGirl.create(:ci_commit)
FactoryGirl.create(:ci_build, commit: @commit)
end
it 'should return build times in minutes' do
chart = Ci::Charts::BuildTime.new(@project)
chart = Ci::Charts::BuildTime.new(@commit.project)
expect(chart.build_times).to eq([2])
end
end
+51 -9
View File
@@ -17,13 +17,15 @@ module Ci
expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1)
expect(config_processor.builds_for_stage_and_ref(type, "master").first).to eq({
stage: "test",
stage_idx: 1,
except: nil,
name: :rspec,
only: nil,
script: "pwd\nrspec",
tags: [],
commands: "pwd\nrspec",
tag_list: [],
options: {},
allow_failure: false
allow_failure: false,
when: "on_success"
})
end
@@ -115,15 +117,17 @@ module Ci
expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({
except: nil,
stage: "test",
stage_idx: 1,
name: :rspec,
only: nil,
script: "pwd\nrspec",
tags: [],
commands: "pwd\nrspec",
tag_list: [],
options: {
image: "ruby:2.1",
services: ["mysql"]
},
allow_failure: false
allow_failure: false,
when: "on_success"
})
end
@@ -141,15 +145,17 @@ module Ci
expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({
except: nil,
stage: "test",
stage_idx: 1,
name: :rspec,
only: nil,
script: "pwd\nrspec",
tags: [],
commands: "pwd\nrspec",
tag_list: [],
options: {
image: "ruby:2.5",
services: ["postgresql"]
},
allow_failure: false
allow_failure: false,
when: "on_success"
})
end
end
@@ -171,6 +177,21 @@ module Ci
end
end
describe "When" do
%w(on_success on_failure always).each do |when_state|
it "returns #{when_state} when defined" do
config = YAML.dump({
rspec: { script: "rspec", when: when_state }
})
config_processor = GitlabCiYamlProcessor.new(config)
builds = config_processor.builds_for_stage_and_ref("test", "master")
expect(builds.size).to eq(1)
expect(builds.first[:when]).to eq(when_state)
end
end
end
describe "Error handling" do
it "indicates that object is invalid" do
expect{GitlabCiYamlProcessor.new("invalid_yaml\n!ccdvlf%612334@@@@")}.to raise_error(GitlabCiYamlProcessor::ValidationError)
@@ -197,6 +218,20 @@ module Ci
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "image should be a string")
end
it "returns errors if job name is blank" do
config = YAML.dump({ '' => { script: "test" } })
expect do
GitlabCiYamlProcessor.new(config)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "job name should be non-empty string")
end
it "returns errors if job name is non-string" do
config = YAML.dump({ 10 => { script: "test" } })
expect do
GitlabCiYamlProcessor.new(config)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "job name should be non-empty string")
end
it "returns errors if job image parameter is invalid" do
config = YAML.dump({ rspec: { script: "test", image: ["test"] } })
expect do
@@ -308,6 +343,13 @@ module Ci
GitlabCiYamlProcessor.new(config)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "variables should be a map of key-valued strings")
end
it "returns errors if job when is not on_success, on_failure or always" do
config = YAML.dump({ rspec: { script: "test", when: 1 } })
expect do
GitlabCiYamlProcessor.new(config)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure or always")
end
end
end
end
+2 -2
View File
@@ -151,14 +151,14 @@ describe Grack::Auth do
end
it "repeated attempts followed by successful attempt" do
for n in 0..maxretry do
maxretry.times.each do
expect(attempt_login(false)).to eq(401)
end
expect(attempt_login(true)).to eq(200)
expect(Rack::Attack::Allow2Ban.banned?(ip)).to be_falsey
for n in 0..maxretry do
maxretry.times.each do
expect(attempt_login(false)).to eq(401)
end
end
+13
View File
@@ -15,4 +15,17 @@ describe Gitlab::Shell do
it { is_expected.to respond_to :fork_repository }
it { expect(gitlab_shell.url_to_repo('diaspora')).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "diaspora.git") }
describe Gitlab::Shell::KeyAdder do
describe '#add_key' do
it 'normalizes space characters in the key' do
io = spy
adder = described_class.new(io)
adder.add_key('key-42', "sha-rsa foo\tbar\tbaz")
expect(io).to have_received(:puts).with("key-42\tsha-rsa foo bar baz")
end
end
end
end
@@ -140,28 +140,28 @@ describe Gitlab::ClosingIssueExtractor do
message = "Closes #{reference} and fix #{reference2}"
expect(subject.closed_by_message(message)).
to eq([issue, other_issue])
to match_array([issue, other_issue])
end
it 'fetches comma-separated issues references in single line message' do
message = "Closes #{reference}, closes #{reference2}"
expect(subject.closed_by_message(message)).
to eq([issue, other_issue])
to match_array([issue, other_issue])
end
it 'fetches comma-separated issues numbers in single line message' do
message = "Closes #{reference}, #{reference2} and #{reference3}"
expect(subject.closed_by_message(message)).
to eq([issue, other_issue, third_issue])
to match_array([issue, other_issue, third_issue])
end
it 'fetches issues in multi-line message' do
message = "Awesome commit (closes #{reference})\nAlso fixes #{reference2}"
expect(subject.closed_by_message(message)).
to eq([issue, other_issue])
to match_array([issue, other_issue])
end
it 'fetches issues in hybrid message' do
@@ -169,7 +169,7 @@ describe Gitlab::ClosingIssueExtractor do
"Also fixing issues #{reference2}, #{reference3} and #4"
expect(subject.closed_by_message(message)).
to eq([issue, other_issue, third_issue])
to match_array([issue, other_issue, third_issue])
end
end
end
+17
View File
@@ -0,0 +1,17 @@
require 'spec_helper'
describe Gitlab::Database do
# These are just simple smoke tests to check if the methods work (regardless
# of what they may return).
describe '.mysql?' do
subject { described_class.mysql? }
it { is_expected.to satisfy { |val| val == true || val == false } }
end
describe '.postgresql?' do
subject { described_class.postgresql? }
it { is_expected.to satisfy { |val| val == true || val == false } }
end
end
@@ -13,7 +13,6 @@ describe Gitlab::Email::AttachmentUploader do
expect(link).not_to be_nil
expect(link[:is_image]).to be_truthy
expect(link[:alt]).to eq("bricks")
expect(link[:url]).to include("/#{project.path_with_namespace}")
expect(link[:url]).to include("bricks.png")
end
end
+21
View File
@@ -13,6 +13,17 @@ describe Gitlab::LDAP::User do
let(:auth_hash) do
OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info)
end
let(:ldap_user_upper_case) { Gitlab::LDAP::User.new(auth_hash_upper_case) }
let(:info_upper_case) do
{
name: 'John',
email: 'John@Example.com', # Email address has upper case chars
nickname: 'john'
}
end
let(:auth_hash_upper_case) do
OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info_upper_case)
end
describe :changed? do
it "marks existing ldap user as changed" do
@@ -57,6 +68,16 @@ describe Gitlab::LDAP::User do
expect(existing_user.id).to eql ldap_user.gl_user.id
end
it 'connects to existing ldap user if the extern_uid changes and email address has upper case characters' do
existing_user = create(:omniauth_user, email: 'john@example.com', extern_uid: 'old-uid', provider: 'ldapmain')
expect{ ldap_user_upper_case.save }.not_to change{ User.count }
existing_user.reload
expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
expect(existing_user.ldap_identity.provider).to eql 'ldapmain'
expect(existing_user.id).to eql ldap_user.gl_user.id
end
it 'maintains an identity per provider' do
existing_user = create(:omniauth_user, email: 'john@example.com', provider: 'twitter')
expect(existing_user.identities.count).to eql(1)
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe CommitRangeReferenceFilter do
include FilterSpecHelper
let(:project) { create(:project) }
let(:project) { create(:project, :public) }
let(:commit1) { project.commit }
let(:commit2) { project.commit("HEAD~2") }
@@ -75,12 +75,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit_range'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-commit-range attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-commit-range')
expect(link.attr('data-commit-range')).to eq range.to_reference
end
it 'supports an :only_path option' do
@@ -92,59 +100,45 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("See #{reference}")
result = reference_pipeline_result("See #{reference}")
expect(result[:references][:commit_range]).not_to be_empty
end
end
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:reference) { range.to_reference(project) }
before do
range.project = project2
end
context 'when user can access reference' do
before { allow_cross_reference! }
it 'links to a valid reference' do
doc = filter("See #{reference}")
it 'links to a valid reference' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
exp = Regexp.escape("#{project2.to_reference}@#{range.to_s}")
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Fixed #{project2.to_reference}@#{commit1.id.reverse}...#{commit2.id}"
expect(filter(act).to_html).to eq exp
exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = pipeline_result("See #{reference}")
expect(result[:references][:commit_range]).not_to be_empty
end
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
context 'when user cannot access reference' do
before { disallow_cross_reference! }
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
it 'ignores valid references' do
exp = act = "See #{reference}"
exp = Regexp.escape("#{project2.to_reference}@#{range.to_s}")
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
end
expect(filter(act).to_html).to eq exp
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Fixed #{project2.to_reference}@#{commit1.id.reverse}...#{commit2.id}"
expect(filter(act).to_html).to eq exp
exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = reference_pipeline_result("See #{reference}")
expect(result[:references][:commit_range]).not_to be_empty
end
end
end
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe CommitReferenceFilter do
include FilterSpecHelper
let(:project) { create(:project) }
let(:project) { create(:project, :public) }
let(:commit) { project.commit }
it 'requires project context' do
@@ -71,12 +71,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-commit attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-commit')
expect(link.attr('data-commit')).to eq commit.id
end
it 'supports an :only_path context' do
@@ -88,53 +96,39 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("See #{reference}")
result = reference_pipeline_result("See #{reference}")
expect(result[:references][:commit]).not_to be_empty
end
end
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:commit) { project2.commit }
let(:reference) { commit.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
it 'links to a valid reference' do
doc = filter("See #{reference}")
it 'links to a valid reference' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id)
end
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
exp = Regexp.escape(project2.to_reference)
expect(doc.to_html).to match(/\(<a.+>#{exp}@#{commit.short_id}<\/a>\.\)/)
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Committed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = pipeline_result("See #{reference}")
expect(result[:references][:commit]).not_to be_empty
end
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id)
end
context 'when user cannot access reference' do
before { disallow_cross_reference! }
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
it 'ignores valid references' do
exp = act = "See #{reference}"
exp = Regexp.escape(project2.to_reference)
expect(doc.to_html).to match(/\(<a.+>#{exp}@#{commit.short_id}<\/a>\.\)/)
end
expect(filter(act).to_html).to eq exp
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Committed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = reference_pipeline_result("See #{reference}")
expect(result[:references][:commit]).not_to be_empty
end
end
end
@@ -2,20 +2,16 @@ require 'spec_helper'
module Gitlab::Markdown
describe CrossProjectReference do
# context in the html-pipeline sense, not in the rspec sense
let(:context) do
{
current_user: double('user'),
project: double('project')
}
end
include described_class
describe '#project_from_ref' do
context 'when no project was referenced' do
it 'returns the project from context' do
expect(project_from_ref(nil)).to eq context[:project]
project = double
allow(self).to receive(:context).and_return({ project: project })
expect(project_from_ref(nil)).to eq project
end
end
@@ -26,29 +22,13 @@ module Gitlab::Markdown
end
context 'when referenced project exists' do
let(:project2) { double('referenced project') }
it 'returns the referenced project' do
project2 = double('referenced project')
before do
expect(Project).to receive(:find_with_namespace).
with('cross/reference').and_return(project2)
end
context 'and the user has permission to read it' do
it 'returns the referenced project' do
expect(self).to receive(:user_can_reference_project?).
with(project2).and_return(true)
expect(project_from_ref('cross/reference')).to eq project2
end
end
context 'and the user does not have permission to read it' do
it 'returns nil' do
expect(self).to receive(:user_can_reference_project?).
with(project2).and_return(false)
expect(project_from_ref('cross/reference')).to be_nil
end
expect(project_from_ref('cross/reference')).to eq project2
end
end
end
@@ -8,7 +8,7 @@ module Gitlab::Markdown
IssuesHelper
end
let(:project) { create(:empty_project) }
let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, project: project) }
it 'requires project context' do
@@ -68,12 +68,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-issue'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("Issue #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-issue attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-issue')
expect(link.attr('data-issue')).to eq issue.id.to_s
end
it 'supports an :only_path context' do
@@ -85,60 +93,46 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("Fixed #{reference}")
result = reference_pipeline_result("Fixed #{reference}")
expect(result[:references][:issue]).to eq [issue]
end
end
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:empty_project, namespace: namespace) }
let(:project2) { create(:empty_project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { issue.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
it 'ignores valid references when cross-reference project uses external tracker' do
expect_any_instance_of(Project).to receive(:get_issue).
with(issue.iid).and_return(nil)
it 'ignores valid references when cross-reference project uses external tracker' do
expect_any_instance_of(Project).to receive(:get_issue).
with(issue.iid).and_return(nil)
exp = act = "Issue #{reference}"
expect(filter(act).to_html).to eq exp
end
it 'links to a valid reference' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq helper.url_for_issue(issue.iid, project2)
end
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores invalid issue IDs on the referenced project' do
exp = act = "Fixed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = pipeline_result("Fixed #{reference}")
expect(result[:references][:issue]).to eq [issue]
end
exp = act = "Issue #{reference}"
expect(filter(act).to_html).to eq exp
end
context 'when user cannot access reference' do
before { disallow_cross_reference! }
it 'links to a valid reference' do
doc = filter("See #{reference}")
it 'ignores valid references' do
exp = act = "See #{reference}"
expect(doc.css('a').first.attr('href')).
to eq helper.url_for_issue(issue.iid, project2)
end
expect(filter(act).to_html).to eq exp
end
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores invalid issue IDs on the referenced project' do
exp = act = "Fixed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = reference_pipeline_result("Fixed #{reference}")
expect(result[:references][:issue]).to eq [issue]
end
end
end
@@ -5,7 +5,7 @@ module Gitlab::Markdown
describe LabelReferenceFilter do
include FilterSpecHelper
let(:project) { create(:empty_project) }
let(:project) { create(:empty_project, :public) }
let(:label) { create(:label, project: project) }
let(:reference) { label.to_reference }
@@ -25,12 +25,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-label'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("Label #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-label attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-label')
expect(link.attr('data-label')).to eq label.id.to_s
end
it 'supports an :only_path context' do
@@ -42,7 +50,7 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("Label #{reference}")
result = reference_pipeline_result("Label #{reference}")
expect(result[:references][:label]).to eq [label]
end
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe MergeRequestReferenceFilter do
include FilterSpecHelper
let(:project) { create(:project) }
let(:project) { create(:project, :public) }
let(:merge) { create(:merge_request, source_project: project) }
it 'requires project context' do
@@ -56,12 +56,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-merge_request'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("Merge #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-merge-request attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-merge-request')
expect(link.attr('data-merge-request')).to eq merge.id.to_s
end
it 'supports an :only_path context' do
@@ -73,53 +81,39 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("Merge #{reference}")
result = reference_pipeline_result("Merge #{reference}")
expect(result[:references][:merge_request]).to eq [merge]
end
end
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:merge) { create(:merge_request, source_project: project2) }
let(:reference) { merge.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
it 'links to a valid reference' do
doc = filter("See #{reference}")
it 'links to a valid reference' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_merge_request_url(project2.namespace,
project, merge)
end
it 'links with adjacent text' do
doc = filter("Merge (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores invalid merge IDs on the referenced project' do
exp = act = "Merge #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = pipeline_result("Merge #{reference}")
expect(result[:references][:merge_request]).to eq [merge]
end
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_merge_request_url(project2.namespace,
project, merge)
end
context 'when user cannot access reference' do
before { disallow_cross_reference! }
it 'links with adjacent text' do
doc = filter("Merge (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores valid references' do
exp = act = "See #{reference}"
it 'ignores invalid merge IDs on the referenced project' do
exp = act = "Merge #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = reference_pipeline_result("Merge #{reference}")
expect(result[:references][:merge_request]).to eq [merge]
end
end
end
@@ -0,0 +1,91 @@
require 'spec_helper'
module Gitlab::Markdown
describe RedactorFilter do
include ActionView::Helpers::UrlHelper
include FilterSpecHelper
it 'ignores non-GFM links' do
html = %(See <a href="https://google.com/">Google</a>)
doc = filter(html, current_user: double)
expect(doc.css('a').length).to eq 1
end
def reference_link(data)
link_to('text', '', class: 'gfm', data: data)
end
context 'with data-project' do
it 'removes unpermitted Project references' do
user = create(:user)
project = create(:empty_project)
link = reference_link(project: project.id, reference_filter: Gitlab::Markdown::ReferenceFilter.name)
doc = filter(link, current_user: user)
expect(doc.css('a').length).to eq 0
end
it 'allows permitted Project references' do
user = create(:user)
project = create(:empty_project)
project.team << [user, :master]
link = reference_link(project: project.id, reference_filter: Gitlab::Markdown::ReferenceFilter.name)
doc = filter(link, current_user: user)
expect(doc.css('a').length).to eq 1
end
it 'handles invalid Project references' do
link = reference_link(project: 12345, reference_filter: Gitlab::Markdown::ReferenceFilter.name)
expect { filter(link) }.not_to raise_error
end
end
context "for user references" do
context 'with data-group' do
it 'removes unpermitted Group references' do
user = create(:user)
group = create(:group)
link = reference_link(group: group.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
doc = filter(link, current_user: user)
expect(doc.css('a').length).to eq 0
end
it 'allows permitted Group references' do
user = create(:user)
group = create(:group)
group.add_developer(user)
link = reference_link(group: group.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
doc = filter(link, current_user: user)
expect(doc.css('a').length).to eq 1
end
it 'handles invalid Group references' do
link = reference_link(group: 12345, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
expect { filter(link) }.not_to raise_error
end
end
context 'with data-user' do
it 'allows any User reference' do
user = create(:user)
link = reference_link(user: user.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
doc = filter(link)
expect(doc.css('a').length).to eq 1
end
end
end
end
end
@@ -0,0 +1,89 @@
require 'spec_helper'
module Gitlab::Markdown
describe ReferenceGathererFilter do
include ActionView::Helpers::UrlHelper
include FilterSpecHelper
def reference_link(data)
link_to('text', '', class: 'gfm', data: data)
end
context "for issue references" do
context 'with data-project' do
it 'removes unpermitted Project references' do
user = create(:user)
project = create(:empty_project)
issue = create(:issue, project: project)
link = reference_link(project: project.id, issue: issue.id, reference_filter: Gitlab::Markdown::IssueReferenceFilter.name)
result = pipeline_result(link, current_user: user)
expect(result[:references][:issue]).to be_empty
end
it 'allows permitted Project references' do
user = create(:user)
project = create(:empty_project)
issue = create(:issue, project: project)
project.team << [user, :master]
link = reference_link(project: project.id, issue: issue.id, reference_filter: Gitlab::Markdown::IssueReferenceFilter.name)
result = pipeline_result(link, current_user: user)
expect(result[:references][:issue]).to eq([issue])
end
it 'handles invalid Project references' do
link = reference_link(project: 12345, issue: 12345, reference_filter: Gitlab::Markdown::IssueReferenceFilter.name)
expect { pipeline_result(link) }.not_to raise_error
end
end
end
context "for user references" do
context 'with data-group' do
it 'removes unpermitted Group references' do
user = create(:user)
group = create(:group)
link = reference_link(group: group.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
result = pipeline_result(link, current_user: user)
expect(result[:references][:user]).to be_empty
end
it 'allows permitted Group references' do
user = create(:user)
group = create(:group)
group.add_developer(user)
link = reference_link(group: group.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
result = pipeline_result(link, current_user: user)
expect(result[:references][:user]).to eq([user])
end
it 'handles invalid Group references' do
link = reference_link(group: 12345, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
expect { pipeline_result(link) }.not_to raise_error
end
end
context 'with data-user' do
it 'allows any User reference' do
user = create(:user)
link = reference_link(user: user.id, reference_filter: Gitlab::Markdown::UserReferenceFilter.name)
result = pipeline_result(link)
expect(result[:references][:user]).to eq([user])
end
end
end
end
end
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe SnippetReferenceFilter do
include FilterSpecHelper
let(:project) { create(:empty_project) }
let(:project) { create(:empty_project, :public) }
let(:snippet) { create(:project_snippet, project: project) }
let(:reference) { snippet.to_reference }
@@ -55,12 +55,20 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-snippet'
end
it 'includes a data-project-id attribute' do
it 'includes a data-project attribute' do
doc = filter("Snippet #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
expect(link).to have_attribute('data-project')
expect(link.attr('data-project')).to eq project.id.to_s
end
it 'includes a data-snippet attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-snippet')
expect(link.attr('data-snippet')).to eq snippet.id.to_s
end
it 'supports an :only_path context' do
@@ -72,52 +80,38 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("Snippet #{reference}")
result = reference_pipeline_result("Snippet #{reference}")
expect(result[:references][:snippet]).to eq [snippet]
end
end
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:empty_project, namespace: namespace) }
let(:project2) { create(:empty_project, :public, namespace: namespace) }
let(:snippet) { create(:project_snippet, project: project2) }
let(:reference) { snippet.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
it 'links to a valid reference' do
doc = filter("See #{reference}")
it 'links to a valid reference' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
it 'links with adjacent text' do
doc = filter("See (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores invalid snippet IDs on the referenced project' do
exp = act = "See #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = pipeline_result("Snippet #{reference}")
expect(result[:references][:snippet]).to eq [snippet]
end
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
context 'when user cannot access reference' do
before { disallow_cross_reference! }
it 'links with adjacent text' do
doc = filter("See (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
end
it 'ignores valid references' do
exp = act = "See #{reference}"
it 'ignores invalid snippet IDs on the referenced project' do
exp = act = "See #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
expect(filter(act).to_html).to eq exp
end
it 'adds to the results hash' do
result = reference_pipeline_result("Snippet #{reference}")
expect(result[:references][:snippet]).to eq [snippet]
end
end
end
@@ -0,0 +1,75 @@
# encoding: UTF-8
require 'spec_helper'
module Gitlab::Markdown
describe UploadLinkFilter do
def filter(doc, contexts = {})
contexts.reverse_merge!({
project: project
})
described_class.call(doc, contexts)
end
def image(path)
%(<img src="#{path}" />)
end
def link(path)
%(<a href="#{path}">#{path}</a>)
end
let(:project) { create(:project) }
shared_examples :preserve_unchanged do
it 'does not modify any relative URL in anchor' do
doc = filter(link('README.md'))
expect(doc.at_css('a')['href']).to eq 'README.md'
end
it 'does not modify any relative URL in image' do
doc = filter(image('files/images/logo-black.png'))
expect(doc.at_css('img')['src']).to eq 'files/images/logo-black.png'
end
end
it 'does not raise an exception on invalid URIs' do
act = link("://foo")
expect { filter(act) }.not_to raise_error
end
context 'with a valid repository' do
it 'rebuilds relative URL for a link' do
doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('a')['href']).
to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'rebuilds relative URL for an image' do
doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('a')['href']).
to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'does not modify absolute URL' do
doc = filter(link('http://example.com'))
expect(doc.at_css('a')['href']).to eq 'http://example.com'
end
it 'supports Unicode filenames' do
path = '/uploads/한글.png'
escaped = Addressable::URI.escape(path)
# Stub these methods so the file doesn't actually need to be in the repo
allow_any_instance_of(described_class).
to receive(:file_exists?).and_return(true)
allow_any_instance_of(described_class).
to receive(:image?).with(path).and_return(true)
doc = filter(image(escaped))
expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png"
end
end
end
end
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe UserReferenceFilter do
include FilterSpecHelper
let(:project) { create(:empty_project) }
let(:project) { create(:empty_project, :public) }
let(:user) { create(:user) }
let(:reference) { user.to_reference }
@@ -39,7 +39,7 @@ module Gitlab::Markdown
end
it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}")
result = reference_pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq [project.creator]
end
end
@@ -64,59 +64,40 @@ module Gitlab::Markdown
expect(doc.css('a').length).to eq 1
end
it 'includes a data-user-id attribute' do
it 'includes a data-user attribute' do
doc = filter("Hey #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-user-id')
expect(link.attr('data-user-id')).to eq user.namespace.owner_id.to_s
expect(link).to have_attribute('data-user')
expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s
end
it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}")
result = reference_pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq [user]
end
end
context 'mentioning a group' do
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:reference) { group.to_reference }
context 'that the current user can read' do
before do
group.add_developer(user)
end
it 'links to the Group' do
doc = filter("Hey #{reference}", current_user: user)
expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
end
it 'includes a data-group-id attribute' do
doc = filter("Hey #{reference}", current_user: user)
link = doc.css('a').first
expect(link).to have_attribute('data-group-id')
expect(link.attr('data-group-id')).to eq group.id.to_s
end
it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}", current_user: user)
expect(result[:references][:user]).to eq group.users
end
it 'links to the Group' do
doc = filter("Hey #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
end
context 'that the current user cannot read' do
it 'ignores references to the Group' do
doc = filter("Hey #{reference}", current_user: user)
expect(doc.to_html).to eq "Hey #{reference}"
end
it 'includes a data-group attribute' do
doc = filter("Hey #{reference}")
link = doc.css('a').first
it 'does not add to the results hash' do
result = pipeline_result("Hey #{reference}", current_user: user)
expect(result[:references][:user]).to eq []
end
expect(link).to have_attribute('data-group')
expect(link.attr('data-group')).to eq group.id.to_s
end
it 'adds to the results hash' do
result = reference_pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq group.users
end
end
-4
View File
@@ -19,10 +19,6 @@ describe Gitlab::OAuth::User do
let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') }
it "finds an existing user based on uid and provider (facebook)" do
# FIXME (rspeicher): It's unlikely that this test is actually doing anything
# `auth` is never used and removing it entirely doesn't break the test, so
# what's it doing?
auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider')
expect( oauth_user.persisted? ).to be_truthy
end
+7 -7
View File
@@ -13,7 +13,7 @@ describe Gitlab::ReferenceExtractor do
project.team << [@u_bar, :guest]
subject.analyze('@foo, @baduser, @bar, and @offteam')
expect(subject.users).to eq([@u_foo, @u_bar, @u_offteam])
expect(subject.users).to match_array([@u_foo, @u_bar, @u_offteam])
end
it 'ignores user mentions inside specific elements' do
@@ -37,7 +37,7 @@ describe Gitlab::ReferenceExtractor do
> @offteam
})
expect(subject.users).to eq([])
expect(subject.users).to match_array([])
end
it 'accesses valid issue objects' do
@@ -45,7 +45,7 @@ describe Gitlab::ReferenceExtractor do
@i1 = create(:issue, project: project)
subject.analyze("#{@i0.to_reference}, #{@i1.to_reference}, and #{Issue.reference_prefix}999.")
expect(subject.issues).to eq([@i0, @i1])
expect(subject.issues).to match_array([@i0, @i1])
end
it 'accesses valid merge requests' do
@@ -53,7 +53,7 @@ describe Gitlab::ReferenceExtractor do
@m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'feature_conflict')
subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.")
expect(subject.merge_requests).to eq([@m1, @m0])
expect(subject.merge_requests).to match_array([@m1, @m0])
end
it 'accesses valid labels' do
@@ -62,7 +62,7 @@ describe Gitlab::ReferenceExtractor do
@l2 = create(:label)
subject.analyze("~#{@l0.id}, ~999, ~#{@l2.id}, ~#{@l1.id}")
expect(subject.labels).to eq([@l0, @l1])
expect(subject.labels).to match_array([@l0, @l1])
end
it 'accesses valid snippets' do
@@ -71,7 +71,7 @@ describe Gitlab::ReferenceExtractor do
@s2 = create(:project_snippet)
subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}")
expect(subject.snippets).to eq([@s0, @s1])
expect(subject.snippets).to match_array([@s0, @s1])
end
it 'accesses valid commits' do
@@ -109,7 +109,7 @@ describe Gitlab::ReferenceExtractor do
subject.analyze("this refers issue #{issue.to_reference(project)}")
extracted = subject.issues
expect(extracted.size).to eq(1)
expect(extracted).to eq([issue])
expect(extracted).to match_array([issue])
end
end
end
+50
View File
@@ -0,0 +1,50 @@
require 'spec_helper'
describe Gitlab::UploadsTransfer do
before do
@root_dir = File.join(Rails.root, "public", "uploads")
@upload_transfer = Gitlab::UploadsTransfer.new
@project_path_was = "test_project_was"
@project_path = "test_project"
@namespace_path_was = "test_namespace_was"
@namespace_path = "test_namespace"
end
after do
FileUtils.rm_rf([
File.join(@root_dir, @namespace_path),
File.join(@root_dir, @namespace_path_was)
])
end
describe '#move_project' do
it "moves project upload to another namespace" do
FileUtils.mkdir_p(File.join(@root_dir, @namespace_path_was, @project_path))
@upload_transfer.move_project(@project_path, @namespace_path_was, @namespace_path)
expected_path = File.join(@root_dir, @namespace_path, @project_path)
expect(Dir.exist?(expected_path)).to be_truthy
end
end
describe '#rename_project' do
it "renames project" do
FileUtils.mkdir_p(File.join(@root_dir, @namespace_path, @project_path_was))
@upload_transfer.rename_project(@project_path_was, @project_path, @namespace_path)
expected_path = File.join(@root_dir, @namespace_path, @project_path)
expect(Dir.exist?(expected_path)).to be_truthy
end
end
describe '#rename_namespace' do
it "renames namespace" do
FileUtils.mkdir_p(File.join(@root_dir, @namespace_path_was, @project_path))
@upload_transfer.rename_namespace(@namespace_path_was, @namespace_path)
expected_path = File.join(@root_dir, @namespace_path, @project_path)
expect(Dir.exist?(expected_path)).to be_truthy
end
end
end
+1 -2
View File
@@ -5,8 +5,7 @@ describe Ci::Notify do
include EmailSpec::Matchers
before do
@project = FactoryGirl.create :ci_project
@commit = FactoryGirl.create :ci_commit, project: @project
@commit = FactoryGirl.create :ci_commit
@build = FactoryGirl.create :ci_build, commit: @commit
end
+2 -1
View File
@@ -52,6 +52,7 @@ describe Notify do
end
it 'has headers that reference an existing thread' do
is_expected.to have_header 'Message-ID', /<(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'References', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'In-Reply-To', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
@@ -399,7 +400,7 @@ describe Notify do
describe 'project was moved' do
let(:project) { create(:project) }
let(:user) { create(:user) }
subject { Notify.project_was_moved_email(project.id, user.id) }
subject { Notify.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
it_behaves_like 'an email sent from GitLab'
+12
View File
@@ -16,4 +16,16 @@ RSpec.describe AbuseReport, type: :model do
subject { create(:abuse_report) }
it { expect(subject).to be_valid }
describe 'associations' do
it { is_expected.to belong_to(:reporter).class_name('User') }
it { is_expected.to belong_to(:user) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:reporter) }
it { is_expected.to validate_presence_of(:user) }
it { is_expected.to validate_presence_of(:message) }
it { is_expected.to validate_uniqueness_of(:user_id) }
end
end
+2 -2
View File
@@ -27,12 +27,12 @@ describe BroadcastMessage do
end
it "should return nil if time not come" do
broadcast_message = create(:broadcast_message, starts_at: Time.now.tomorrow, ends_at: Time.now + 2.days)
create(:broadcast_message, starts_at: Time.now.tomorrow, ends_at: Time.now + 2.days)
expect(BroadcastMessage.current).to be_nil
end
it "should return nil if time has passed" do
broadcast_message = create(:broadcast_message, starts_at: Time.now - 2.days, ends_at: Time.now.yesterday)
create(:broadcast_message, starts_at: Time.now - 2.days, ends_at: Time.now.yesterday)
expect(BroadcastMessage.current).to be_nil
end
end
@@ -27,16 +27,12 @@ require 'spec_helper'
describe Ci::Build do
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
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, commit: commit }
it { is_expected.to belong_to(:commit) }
it { is_expected.to validate_presence_of :status }
it { is_expected.to validate_presence_of :ref }
it { is_expected.to respond_to :success? }
it { is_expected.to respond_to :failed? }
it { is_expected.to respond_to :running? }
it { is_expected.to respond_to :pending? }
it { is_expected.to respond_to :trace_html }
describe :first_pending do
@@ -63,72 +59,6 @@ describe Ci::Build do
end
end
describe :started? do
subject { build.started? }
context 'without started_at' do
before { build.started_at = nil }
it { is_expected.to be_falsey }
end
%w(running success failed).each do |status|
context "if build status is #{status}" do
before { build.status = status }
it { is_expected.to be_truthy }
end
end
%w(pending canceled).each do |status|
context "if build status is #{status}" do
before { build.status = status }
it { is_expected.to be_falsey }
end
end
end
describe :active? do
subject { build.active? }
%w(pending running).each do |state|
context "if build.status is #{state}" do
before { build.status = state }
it { is_expected.to be_truthy }
end
end
%w(success failed canceled).each do |state|
context "if build.status is #{state}" do
before { build.status = state }
it { is_expected.to be_falsey }
end
end
end
describe :complete? do
subject { build.complete? }
%w(success failed canceled).each do |state|
context "if build.status is #{state}" do
before { build.status = state }
it { is_expected.to be_truthy }
end
end
%w(pending running).each do |state|
context "if build.status is #{state}" do
before { build.status = state }
it { is_expected.to be_falsey }
end
end
end
describe :ignored? do
subject { build.ignored? }
@@ -177,6 +107,17 @@ describe Ci::Build do
it { is_expected.to include(text) }
it { expect(subject.length).to be >= text.length }
end
context 'if build.trace hides token' do
let(:token) { 'my_secret_token' }
before do
build.project.update_attributes(token: token)
build.update_attributes(trace: token)
end
it { is_expected.to_not include(token) }
end
end
describe :timeout do
@@ -185,31 +126,6 @@ describe Ci::Build do
it { is_expected.to eq(commit.project.timeout) }
end
describe :duration do
subject { build.duration }
it { is_expected.to eq(120.0) }
context 'if the building process has not started yet' do
before do
build.started_at = nil
build.finished_at = nil
end
it { is_expected.to be_nil }
end
context 'if the building process has started' do
before do
build.started_at = Time.now - 1.minute
build.finished_at = nil
end
it { is_expected.to be_a(Float) }
it { is_expected.to be > 0.0 }
end
end
describe :options do
let(:options) do
{
@@ -224,30 +140,6 @@ describe Ci::Build do
it { is_expected.to eq(options) }
end
describe :ref do
subject { build.ref }
it { is_expected.to eq(commit.ref) }
end
describe :sha do
subject { build.sha }
it { is_expected.to eq(commit.sha) }
end
describe :short_sha do
subject { build.short_sha }
it { is_expected.to eq(commit.short_sha) }
end
describe :before_sha do
subject { build.before_sha }
it { is_expected.to eq(commit.before_sha) }
end
describe :allow_git_fetch do
subject { build.allow_git_fetch }
@@ -308,13 +200,34 @@ describe Ci::Build do
context 'returns variables' do
subject { build.variables }
let(:variables) do
let(:predefined_variables) do
[
{ key: :CI_BUILD_NAME, value: 'test', public: true },
{ key: :CI_BUILD_STAGE, value: 'stage', public: true },
]
end
let(:yaml_variables) do
[
{ key: :DB_NAME, value: 'postgres', public: true }
]
end
it { is_expected.to eq(variables) }
before { build.update_attributes(stage: 'stage') }
it { is_expected.to eq(predefined_variables + yaml_variables) }
context 'for tag' do
let(:tag_variable) do
[
{ key: :CI_BUILD_TAG, value: 'master', public: true }
]
end
before { build.update_attributes(tag: true) }
it { is_expected.to eq(tag_variable + predefined_variables + yaml_variables) }
end
context 'and secure variables' do
let(:secure_variables) do
@@ -327,7 +240,7 @@ describe Ci::Build do
build.project.variables << Ci::Variable.new(key: 'SECRET_KEY', value: 'secret_value')
end
it { is_expected.to eq(variables + secure_variables) }
it { is_expected.to eq(predefined_variables + yaml_variables + secure_variables) }
context 'and trigger variables' do
let(:trigger) { FactoryGirl.create :ci_trigger, project: project }
@@ -337,14 +250,154 @@ describe Ci::Build do
{ key: :TRIGGER_KEY, value: 'TRIGGER_VALUE', public: false }
]
end
let(:predefined_trigger_variable) do
[
{ key: :CI_BUILD_TRIGGERED, value: 'true', public: true }
]
end
before do
build.trigger_request = trigger_request
end
it { is_expected.to eq(variables + secure_variables + trigger_variables) }
it { is_expected.to eq(predefined_variables + predefined_trigger_variable + yaml_variables + secure_variables + trigger_variables) }
end
end
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 }
before { build.project.runners << runner }
context 'runner without tags' do
it 'can handle builds without tags' do
expect(build.can_be_served?(runner)).to be_truthy
end
it 'cannot handle build with tags' do
build.tag_list = ['aa']
expect(build.can_be_served?(runner)).to be_falsey
end
end
context 'runner with tags' do
before { runner.tag_list = ['bb', 'cc'] }
it 'can handle builds without tags' do
expect(build.can_be_served?(runner)).to be_truthy
end
it 'can handle build with matching tags' do
build.tag_list = ['bb']
expect(build.can_be_served?(runner)).to be_truthy
end
it 'cannot handle build with not matching tags' do
build.tag_list = ['aa']
expect(build.can_be_served?(runner)).to be_falsey
end
end
end
describe :any_runners_online? do
subject { build.any_runners_online? }
context 'when no runners' do
it { is_expected.to be_falsey }
end
context 'if there are runner' do
let(:runner) { FactoryGirl.create :ci_specific_runner }
before do
build.project.runners << runner
runner.update_attributes(contacted_at: 1.second.ago)
end
it { is_expected.to be_truthy }
it 'that is inactive' do
runner.update_attributes(active: false)
is_expected.to be_falsey
end
it 'that is not online' do
runner.update_attributes(contacted_at: nil)
is_expected.to be_falsey
end
it 'that cannot handle build' do
expect_any_instance_of(Ci::Build).to receive(:can_be_served?).and_return(false)
is_expected.to be_falsey
end
end
end
describe :show_warning? do
subject { build.show_warning? }
%w(pending).each do |state|
context "if commit_status.status is #{state}" do
before { build.status = state }
it { is_expected.to be_truthy }
context "and there are specific runner" do
let(:runner) { FactoryGirl.create :ci_specific_runner, contacted_at: 1.second.ago }
before do
build.project.runners << runner
runner.save
end
it { is_expected.to be_falsey }
end
end
end
%w(success failed canceled running).each do |state|
context "if commit_status.status is #{state}" do
before { build.status = state }
it { is_expected.to be_falsey }
end
end
end
end
+265 -112
View File
@@ -19,21 +19,37 @@ require 'spec_helper'
describe Ci::Commit do
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:commit_with_project) { FactoryGirl.create :ci_commit, project: project }
let(:config_processor) { Ci::GitlabCiYamlProcessor.new(gitlab_ci_yaml) }
let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project }
let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project }
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:gl_project) }
it { is_expected.to have_many(:statuses) }
it { is_expected.to have_many(:trigger_requests) }
it { is_expected.to have_many(:builds) }
it { is_expected.to validate_presence_of :before_sha }
it { is_expected.to validate_presence_of :sha }
it { is_expected.to validate_presence_of :ref }
it { is_expected.to validate_presence_of :push_data }
it { is_expected.to respond_to :git_author_name }
it { is_expected.to respond_to :git_author_email }
it { is_expected.to respond_to :short_sha }
describe :ordered 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
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
expect(project.ci_commits.ordered).to eq([commit2, commit4, commit3, commit1])
end
end
describe :last_build do
subject { commit.last_build }
before do
@@ -51,53 +67,12 @@ describe Ci::Commit do
@second = FactoryGirl.create :ci_build, commit: commit
end
it "creates new build" do
it "creates only a new build" do
expect(commit.builds.count(:all)).to eq 2
expect(commit.statuses.count(:all)).to eq 2
commit.retry
expect(commit.builds.count(:all)).to eq 3
end
end
describe :project_recipients do
context 'always sending notification' do
it 'should return commit_pusher_email as only recipient when no additional recipients are given' do
project = FactoryGirl.create :ci_project,
email_add_pusher: true,
email_recipients: ''
commit = FactoryGirl.create :ci_commit, project: project
expected = 'commit_pusher_email'
allow(commit).to receive(:push_data) { { user_email: expected } }
expect(commit.project_recipients).to eq([expected])
end
it 'should return commit_pusher_email and additional recipients' do
project = FactoryGirl.create :ci_project,
email_add_pusher: true,
email_recipients: 'rec1 rec2'
commit = FactoryGirl.create :ci_commit, project: project
expected = 'commit_pusher_email'
allow(commit).to receive(:push_data) { { user_email: expected } }
expect(commit.project_recipients).to eq(['rec1', 'rec2', expected])
end
it 'should return recipients' do
project = FactoryGirl.create :ci_project,
email_add_pusher: false,
email_recipients: 'rec1 rec2'
commit = FactoryGirl.create :ci_commit, project: project
expect(commit.project_recipients).to eq(['rec1', 'rec2'])
end
it 'should return unique recipients only' do
project = FactoryGirl.create :ci_project,
email_add_pusher: true,
email_recipients: 'rec1 rec1 rec2'
commit = FactoryGirl.create :ci_commit, project: project
expected = 'rec2'
allow(commit).to receive(:push_data) { { user_email: expected } }
expect(commit.project_recipients).to eq(['rec1', 'rec2'])
end
expect(commit.statuses.count(:all)).to eq 3
end
end
@@ -112,23 +87,6 @@ describe Ci::Commit do
end
end
describe :compare? do
subject { commit_with_project.compare? }
context 'if commit.before_sha are not nil' do
it { is_expected.to be_truthy }
end
end
describe :short_sha do
subject { commit.short_before_sha }
it 'has 8 items' do
expect(subject.size).to eq(8)
end
it { expect(commit.before_sha).to start_with(subject) }
end
describe :short_sha do
subject { commit.short_sha }
@@ -138,37 +96,113 @@ describe Ci::Commit do
it { expect(commit.sha).to start_with(subject) }
end
describe :create_next_builds do
describe :stage do
subject { commit.stage }
before do
allow(commit).to receive(:config_processor).and_return(config_processor)
@second = FactoryGirl.create :commit_status, commit: commit, name: 'deploy', stage: 'deploy', stage_idx: 1, status: 'pending'
@first = FactoryGirl.create :commit_status, commit: commit, name: 'test', stage: 'test', stage_idx: 0, status: 'pending'
end
it "creates builds for next type" do
expect(commit.create_builds).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
it 'returns first running stage' do
is_expected.to eq('test')
end
expect(commit.create_next_builds(nil)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(4)
context 'first build succeeded' do
before do
@first.success
end
expect(commit.create_next_builds(nil)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(5)
it 'returns last running stage' do
is_expected.to eq('deploy')
end
end
expect(commit.create_next_builds(nil)).to be_falsey
context 'all builds succeeded' do
before do
@first.success
@second.success
end
it 'returns nil' do
is_expected.to be_nil
end
end
end
describe :create_next_builds do
end
describe :refs do
subject { commit.refs }
before do
FactoryGirl.create :commit_status, commit: commit, name: 'deploy'
FactoryGirl.create :commit_status, commit: commit, name: 'deploy', ref: 'develop'
FactoryGirl.create :commit_status, commit: commit, name: 'deploy', ref: 'master'
end
it 'returns all refs' do
is_expected.to contain_exactly('master', 'develop', nil)
end
end
describe :retried do
subject { commit.retried }
before do
@commit1 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy'
@commit2 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy'
end
it 'returns old builds' do
is_expected.to contain_exactly(@commit1)
end
end
describe :create_builds do
before do
allow(commit).to receive(:config_processor).and_return(config_processor)
let!(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project }
def create_builds(trigger_request = nil)
commit.create_builds('master', false, nil, trigger_request)
end
def create_next_builds
commit.create_next_builds(commit.builds.order(:id).last)
end
it 'creates builds' do
expect(commit.create_builds).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
expect(create_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(2)
expect(create_next_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(4)
expect(create_next_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(5)
expect(create_next_builds).to be_falsey
end
context 'for different ref' do
def create_develop_builds
commit.create_builds('develop', false, nil, nil)
end
it 'creates builds' do
expect(create_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(2)
expect(create_develop_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(4)
expect(commit.refs.size).to eq(2)
expect(commit.builds.pluck(:name).uniq.size).to eq(2)
end
end
context 'for build triggers' do
@@ -176,61 +210,179 @@ describe Ci::Commit do
let(:trigger_request) { FactoryGirl.create :ci_trigger_request, commit: commit, trigger: trigger }
it 'creates builds' do
expect(commit.create_builds(trigger_request)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
expect(create_builds(trigger_request)).to be_truthy
expect(commit.builds.count(:all)).to eq(2)
end
it 'rebuilds commit' do
expect(commit.create_builds).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
expect(create_builds).to be_truthy
expect(commit.builds.count(:all)).to eq(2)
expect(commit.create_builds(trigger_request)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(4)
expect(create_builds(trigger_request)).to be_truthy
expect(commit.builds.count(:all)).to eq(4)
end
it 'creates next builds' do
expect(commit.create_builds(trigger_request)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
expect(create_builds(trigger_request)).to be_truthy
expect(commit.builds.count(:all)).to eq(2)
commit.builds.update_all(status: "success")
expect(commit.create_next_builds(trigger_request)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(4)
expect(create_next_builds).to be_truthy
expect(commit.builds.count(:all)).to eq(4)
end
context 'for [ci skip]' do
before do
commit.push_data[:commits][0][:message] = 'skip this commit [ci skip]'
commit.save
allow(commit).to receive(:git_commit_message) { 'message [ci skip]' }
end
it 'rebuilds commit' do
expect(commit.status).to eq('skipped')
expect(commit.create_builds(trigger_request)).to be_truthy
commit.builds.reload
expect(commit.builds.size).to eq(2)
expect(commit.status).to eq('pending')
expect(create_builds).to be_truthy
# since everything in Ci::Commit is cached we need to fetch a new object
new_commit = Ci::Commit.find_by_id(commit.id)
expect(new_commit.status).to eq('pending')
end
end
end
context 'properly creates builds when "when" is defined' do
let(:yaml) do
{
stages: ["build", "test", "test_failure", "deploy", "cleanup"],
build: {
stage: "build",
script: "BUILD",
},
test: {
stage: "test",
script: "TEST",
},
test_failure: {
stage: "test_failure",
script: "ON test failure",
when: "on_failure",
},
deploy: {
stage: "deploy",
script: "PUBLISH",
},
cleanup: {
stage: "cleanup",
script: "TIDY UP",
when: "always",
}
}
end
before do
stub_ci_commit_yaml_file(YAML.dump(yaml))
end
it 'properly creates builds' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'success')
expect(commit.status).to eq('success')
end
it 'properly creates builds when test fails' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'success')
expect(commit.status).to eq('failed')
end
it 'properly creates builds when test and test_failure fails' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'success')
expect(commit.status).to eq('failed')
end
it 'properly creates builds when deploy fails' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'success')
expect(commit.status).to eq('failed')
end
end
end
describe "#finished_at" do
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:commit) { FactoryGirl.create :ci_commit }
it "returns finished_at of latest build" do
build = FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 60
build1 = FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 120
FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 120
expect(commit.finished_at.to_i).to eq(build.finished_at.to_i)
end
it "returns nil if there is no finished build" do
build = FactoryGirl.create :ci_not_started_build, commit: commit
FactoryGirl.create :ci_not_started_build, commit: commit
expect(commit.finished_at).to be_nil
end
@@ -238,7 +390,8 @@ describe Ci::Commit do
describe "coverage" do
let(:project) { FactoryGirl.create :ci_project, coverage_regex: "/.*/" }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project }
let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project }
it "calculates average when there are two builds with coverage" do
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit
@@ -3,72 +3,37 @@ require 'spec_helper'
describe Ci::HipChatMessage do
subject { Ci::HipChatMessage.new(build) }
let(:project) { FactoryGirl.create(:ci_project) }
let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) }
context "One build" do
let(:commit) { FactoryGirl.create(:ci_commit_with_one_job, project: project) }
let(:build) do
commit.builds.first
end
let(:build) do
commit.create_builds
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
context 'when build succeeds' do
it 'returns a successful message' do
build.update(status: "success")
expect( subject.status_color ).to eq 'green'
expect( subject.notify? ).to be_falsey
expect( subject.to_s ).to match(/Build '[^']+' #\d+/)
expect( subject.to_s ).to match(/Successful in \d+ second\(s\)\./)
end
end
context 'when build fails' do
it 'returns a failure message' do
build.update(status: "failed")
expect( subject.status_color ).to eq 'red'
expect( subject.notify? ).to be_truthy
expect( subject.to_s ).to match(/Build '[^']+' #\d+/)
expect( subject.to_s ).to match(/Failed in \d+ second\(s\)\./)
end
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 "Several builds" do
let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs, project: project) }
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")
let(:build) do
commit.builds.first
end
context 'when all matrix builds succeed' do
it 'returns a successful message' do
commit.create_builds
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
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
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
@@ -33,15 +33,14 @@ describe Ci::HipChatService do
describe "Execute" do
let(:service) { Ci::HipChatService.new }
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
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: project,
project_id: project.id,
project: commit.project,
project_id: commit.project_id,
notify_only_broken_builds: false,
hipchat_room: 123,
hipchat_token: 'a1b2c3d4e5f6'
@@ -29,11 +29,13 @@ describe Ci::MailService do
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(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) }
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(
@@ -54,8 +56,9 @@ describe Ci::MailService do
describe 'successfull build' do
let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true, email_only_broken_builds: false) }
let(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) }
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(
@@ -81,8 +84,9 @@ describe Ci::MailService do
email_only_broken_builds: false,
email_recipients: "jeroen@example.com")
end
let(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) }
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(
@@ -109,8 +113,9 @@ describe Ci::MailService do
email_only_broken_builds: true,
email_recipients: "jeroen@example.com")
end
let(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) }
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(
@@ -137,8 +142,9 @@ describe Ci::MailService do
email_only_broken_builds: false,
email_recipients: "jeroen@example.com")
end
let(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) }
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(
@@ -159,8 +165,9 @@ describe Ci::MailService do
email_only_broken_builds: true,
email_recipients: "jeroen@example.com")
end
let(:commit) { FactoryGirl.create(:ci_commit, project: project) }
let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) }
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(
@@ -3,82 +3,41 @@ require 'spec_helper'
describe Ci::SlackMessage do
subject { Ci::SlackMessage.new(commit) }
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) }
context "One build" do
let(:commit) { FactoryGirl.create(:ci_commit_with_one_job, project: project) }
context 'when all matrix builds succeeded' do
let(:color) { 'good' }
let(:build) do
commit.create_builds
commit.builds.first
end
it 'returns a message with success' do
commit.create_builds('master', false, nil)
commit.builds.update_all(status: "success")
commit.reload
context 'when build succeeded' do
let(:color) { 'good' }
it 'returns a message with succeeded build' do
build.update(status: "success")
expect(subject.color).to eq(color)
expect(subject.fallback).to include('Build')
expect(subject.fallback).to include("\##{build.id}")
expect(subject.fallback).to include('succeeded')
expect(subject.attachments.first[:fields]).to be_empty
end
end
context 'when build failed' do
let(:color) { 'danger' }
it 'returns a message with failed build' do
build.update(status: "failed")
expect(subject.color).to eq(color)
expect(subject.fallback).to include('Build')
expect(subject.fallback).to include("\##{build.id}")
expect(subject.fallback).to include('failed')
expect(subject.attachments.first[:fields]).to be_empty
end
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 "Several builds" do
let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs, project: project) }
context 'when one of matrix builds failed' do
let(:color) { 'danger' }
context 'when all matrix builds succeeded' do
let(:color) { 'good' }
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")
it 'returns a message with success' do
commit.create_builds
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
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
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
@@ -31,16 +31,15 @@ describe Ci::SlackService do
describe "Execute" do
let(:slack) { Ci::SlackService.new }
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
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: project,
project_id: project.id,
project: commit.project,
project_id: commit.project_id,
webhook: webhook_url,
notify_only_broken_builds: notify_only_broken_builds
)
+94 -35
View File
@@ -28,13 +28,20 @@
require 'spec_helper'
describe Ci::Project do
subject { FactoryGirl.build :ci_project }
let(:gl_project) { FactoryGirl.create :empty_project }
let(:project) { FactoryGirl.create :ci_project, gl_project: gl_project }
subject { project }
it { is_expected.to have_many(:commits) }
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 :name }
it { is_expected.to validate_presence_of :timeout }
it { is_expected.to validate_presence_of :default_ref }
it { is_expected.to validate_presence_of :gitlab_id }
describe 'before_validation' do
it 'should set an random token if none provided' do
@@ -48,43 +55,89 @@ describe Ci::Project do
end
end
describe "ordered_by_last_commit_date" do
it "returns ordered projects" do
newest_project = FactoryGirl.create :ci_project
oldest_project = FactoryGirl.create :ci_project
project_without_commits = FactoryGirl.create :ci_project
describe :name_with_namespace do
subject { project.name_with_namespace }
FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: newest_project
FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, project: oldest_project
expect(Ci::Project.ordered_by_last_commit_date).to eq([newest_project, oldest_project, project_without_commits])
end
it { is_expected.to eq(project.name) }
it { is_expected.to eq(gl_project.name_with_namespace) }
end
describe 'ordered commits' do
let(:project) { FactoryGirl.create :ci_project }
describe :path_with_namespace do
subject { project.path_with_namespace }
it 'returns ordered list of commits' do
commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: project
commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, project: project
expect(project.commits).to eq([commit2, commit1])
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 'returns commits ordered by committed_at and id, with nulls last' do
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.hour.ago, project: project
commit4 = FactoryGirl.create :ci_commit, committed_at: nil, project: project
expect(project.commits).to eq([commit2, commit4, commit3, commit1])
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(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create(:ci_commit) }
context :project_with_commit_and_builds do
let(:project) { commit.project }
before do
commit = FactoryGirl.create(:ci_commit, project: project)
FactoryGirl.create(:ci_build, commit: commit)
end
@@ -165,13 +218,6 @@ describe Ci::Project do
it { is_expected.to include(project.gitlab_url[7..-1]) }
end
describe :search do
let!(:project) { FactoryGirl.create(:ci_project, name: "foo") }
it { expect(Ci::Project.search('fo')).to include(project) }
it { expect(Ci::Project.search('bar')).to be_empty }
end
describe :any_runners do
it "there are no runners available" do
project = FactoryGirl.create(:ci_project)
@@ -195,5 +241,18 @@ describe Ci::Project do
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
+66 -1
View File
@@ -32,7 +32,7 @@ describe Ci::Runner do
end
it 'should return the token if the description is an empty string' do
runner = FactoryGirl.build(:ci_runner, description: '')
runner = FactoryGirl.build(:ci_runner, description: '', token: 'token')
expect(runner.display_name).to eq runner.token
end
end
@@ -48,6 +48,71 @@ describe Ci::Runner do
it { expect(shared_runner.only_for?(project)).to be_truthy }
end
describe :online do
subject { Ci::Runner.online }
before do
@runner1 = FactoryGirl.create(:ci_shared_runner, contacted_at: 1.year.ago)
@runner2 = FactoryGirl.create(:ci_shared_runner, contacted_at: 1.second.ago)
end
it { is_expected.to eq([@runner2])}
end
describe :online? do
let(:runner) { FactoryGirl.create(:ci_shared_runner) }
subject { runner.online? }
context 'never contacted' do
before { runner.contacted_at = nil }
it { is_expected.to be_falsey }
end
context 'contacted long time ago time' do
before { runner.contacted_at = 1.year.ago }
it { is_expected.to be_falsey }
end
context 'contacted 1s ago' do
before { runner.contacted_at = 1.second.ago }
it { is_expected.to be_truthy }
end
end
describe :status do
let(:runner) { FactoryGirl.create(:ci_shared_runner, contacted_at: 1.second.ago) }
subject { runner.status }
context 'never connected' do
before { runner.contacted_at = nil }
it { is_expected.to eq(:not_connected) }
end
context 'contacted 1s ago' do
before { runner.contacted_at = 1.second.ago }
it { is_expected.to eq(:online) }
end
context 'contacted long time ago' do
before { runner.contacted_at = 1.year.ago }
it { is_expected.to eq(:offline) }
end
context 'inactive' do
before { runner.active = false }
it { is_expected.to eq(:paused) }
end
end
describe "belongs_to_one_project?" do
it "returns false if there are two projects runner assigned to" do
runner = FactoryGirl.create(:ci_specific_runner)
+2 -3
View File
@@ -29,13 +29,12 @@ describe Ci::Service do
end
describe "Testable" do
let(:project) { FactoryGirl.create :ci_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:commit) { FactoryGirl.create :ci_commit }
let(:build) { FactoryGirl.create :ci_build, commit: commit }
before do
allow(@service).to receive_messages(
project: project
project: commit.project
)
build
@testable = @service.can_test?
+2 -2
View File
@@ -89,9 +89,9 @@ eos
end
it_behaves_like 'a mentionable' do
subject { commit }
subject { create(:project).commit }
let(:author) { create(:user, email: commit.author_email) }
let(:author) { create(:user, email: subject.author_email) }
let(:backref_text) { "commit #{subject.id}" }
let(:set_mentionable_text) do
->(txt) { allow(subject).to receive(:safe_message).and_return(txt) }
+164
View File
@@ -0,0 +1,164 @@
require 'spec_helper'
describe CommitStatus 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 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? }
it { is_expected.to respond_to :running? }
it { is_expected.to respond_to :pending? }
describe :author do
subject { commit_status.author }
before { commit_status.author = User.new }
it { is_expected.to eq(commit_status.user) }
end
describe :started? do
subject { commit_status.started? }
context 'without started_at' do
before { commit_status.started_at = nil }
it { is_expected.to be_falsey }
end
%w(running success failed).each do |status|
context "if commit status is #{status}" do
before { commit_status.status = status }
it { is_expected.to be_truthy }
end
end
%w(pending canceled).each do |status|
context "if commit status is #{status}" do
before { commit_status.status = status }
it { is_expected.to be_falsey }
end
end
end
describe :active? do
subject { commit_status.active? }
%w(pending running).each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
it { is_expected.to be_truthy }
end
end
%w(success failed canceled).each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
it { is_expected.to be_falsey }
end
end
end
describe :complete? do
subject { commit_status.complete? }
%w(success failed canceled).each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
it { is_expected.to be_truthy }
end
end
%w(pending running).each do |state|
context "if commit_status.status is #{state}" do
before { commit_status.status = state }
it { is_expected.to be_falsey }
end
end
end
describe :duration do
subject { commit_status.duration }
it { is_expected.to eq(120.0) }
context 'if the building process has not started yet' do
before do
commit_status.started_at = nil
commit_status.finished_at = nil
end
it { is_expected.to be_nil }
end
context 'if the building process has started' do
before do
commit_status.started_at = Time.now - 1.minute
commit_status.finished_at = nil
end
it { is_expected.to be_a(Float) }
it { is_expected.to be > 0.0 }
end
end
describe :latest do
subject { CommitStatus.latest.order(:id) }
before do
@commit1 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'cc', status: 'success'
@commit4 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'bb', status: 'success'
@commit5 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'success'
end
it 'return unique statuses' do
is_expected.to eq([@commit2, @commit3, @commit4, @commit5])
end
end
describe :for_ref do
subject { CommitStatus.for_ref('bb').order(:id) }
before do
@commit1 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: nil, status: 'success'
end
it 'return statuses with equal and nil ref set' do
is_expected.to eq([@commit1])
end
end
describe :running_or_pending do
subject { CommitStatus.running_or_pending.order(:id) }
before do
@commit1 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: nil, status: 'success'
@commit4 = FactoryGirl.create :commit_status, commit: commit, name: 'dd', ref: nil, status: 'failed'
@commit5 = FactoryGirl.create :commit_status, commit: commit, name: 'ee', ref: nil, status: 'canceled'
end
it 'return statuses that are running or pending' do
is_expected.to eq([@commit1, @commit2])
end
end
end
@@ -0,0 +1,189 @@
require 'spec_helper'
describe CaseSensitivity do
describe '.iwhere' do
let(:connection) { ActiveRecord::Base.connection }
let(:model) { Class.new { include CaseSensitivity } }
describe 'using PostgreSQL' do
before do
allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
allow(Gitlab::Database).to receive(:mysql?).and_return(false)
end
describe 'with a single column/value pair' do
it 'returns the criteria for a column and a value' do
criteria = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:foo).
and_return('"foo"')
expect(model).to receive(:where).
with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar').
and_return(criteria)
expect(model.iwhere(foo: 'bar')).to eq(criteria)
end
it 'returns the criteria for a column with a table, and a value' do
criteria = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:'foo.bar').
and_return('"foo"."bar"')
expect(model).to receive(:where).
with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar').
and_return(criteria)
expect(model.iwhere(:'foo.bar' => 'bar')).to eq(criteria)
end
end
describe 'with multiple column/value pairs' do
it 'returns the criteria for a column and a value' do
initial = double(:criteria)
final = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:foo).
and_return('"foo"')
expect(connection).to receive(:quote_table_name).
with(:bar).
and_return('"bar"')
expect(model).to receive(:where).
with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar').
and_return(initial)
expect(initial).to receive(:where).
with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz').
and_return(final)
got = model.iwhere(foo: 'bar', bar: 'baz')
expect(got).to eq(final)
end
it 'returns the criteria for a column with a table, and a value' do
initial = double(:criteria)
final = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:'foo.bar').
and_return('"foo"."bar"')
expect(connection).to receive(:quote_table_name).
with(:'foo.baz').
and_return('"foo"."baz"')
expect(model).to receive(:where).
with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar').
and_return(initial)
expect(initial).to receive(:where).
with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz').
and_return(final)
got = model.iwhere(:'foo.bar' => 'bar',
:'foo.baz' => 'baz')
expect(got).to eq(final)
end
end
end
describe 'using MySQL' do
before do
allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
allow(Gitlab::Database).to receive(:mysql?).and_return(true)
end
describe 'with a single column/value pair' do
it 'returns the criteria for a column and a value' do
criteria = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:foo).
and_return('`foo`')
expect(model).to receive(:where).
with(%q{`foo` = :value}, value: 'bar').
and_return(criteria)
expect(model.iwhere(foo: 'bar')).to eq(criteria)
end
it 'returns the criteria for a column with a table, and a value' do
criteria = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:'foo.bar').
and_return('`foo`.`bar`')
expect(model).to receive(:where).
with(%q{`foo`.`bar` = :value}, value: 'bar').
and_return(criteria)
expect(model.iwhere(:'foo.bar' => 'bar')).
to eq(criteria)
end
end
describe 'with multiple column/value pairs' do
it 'returns the criteria for a column and a value' do
initial = double(:criteria)
final = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:foo).
and_return('`foo`')
expect(connection).to receive(:quote_table_name).
with(:bar).
and_return('`bar`')
expect(model).to receive(:where).
with(%q{`foo` = :value}, value: 'bar').
and_return(initial)
expect(initial).to receive(:where).
with(%q{`bar` = :value}, value: 'baz').
and_return(final)
got = model.iwhere(foo: 'bar', bar: 'baz')
expect(got).to eq(final)
end
it 'returns the criteria for a column with a table, and a value' do
initial = double(:criteria)
final = double(:criteria)
expect(connection).to receive(:quote_table_name).
with(:'foo.bar').
and_return('`foo`.`bar`')
expect(connection).to receive(:quote_table_name).
with(:'foo.baz').
and_return('`foo`.`baz`')
expect(model).to receive(:where).
with(%q{`foo`.`bar` = :value}, value: 'bar').
and_return(initial)
expect(initial).to receive(:where).
with(%q{`foo`.`baz` = :value}, value: 'baz').
and_return(final)
got = model.iwhere(:'foo.bar' => 'bar',
:'foo.baz' => 'baz')
expect(got).to eq(final)
end
end
end
end
end
-1
View File
@@ -68,7 +68,6 @@ describe Issue, "Issuable" do
end
end
describe "#to_hook_data" do
let(:hook_data) { issue.to_hook_data(user) }
+1 -1
View File
@@ -25,7 +25,7 @@ describe Issue, "Mentionable" do
it 'correctly removes already-mentioned Commits' do
expect(SystemNoteService).not_to receive(:cross_reference)
issue.create_cross_references!(project, author, [commit2])
issue.create_cross_references!(author, [commit2])
end
end
+39
View File
@@ -0,0 +1,39 @@
require 'spec_helper'
describe GenericCommitStatus do
let(:commit) { FactoryGirl.create :ci_commit }
let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, commit: commit }
describe :context do
subject { generic_commit_status.context }
before { generic_commit_status.context = 'my_context' }
it { is_expected.to eq(generic_commit_status.name) }
end
describe :tags do
subject { generic_commit_status.tags }
it { is_expected.to eq([:external]) }
end
describe :set_default_values do
before do
generic_commit_status.context = nil
generic_commit_status.stage = nil
generic_commit_status.save
end
describe :context do
subject { generic_commit_status.context }
it { is_expected.to_not be_nil }
end
describe :stage do
subject { generic_commit_status.stage }
it { is_expected.to_not be_nil }
end
end
end
+2 -2
View File
@@ -22,7 +22,7 @@ describe ProjectHook do
describe '.push_hooks' do
it 'should return hooks for push events only' do
hook = create(:project_hook, push_events: true)
hook2 = create(:project_hook, push_events: false)
create(:project_hook, push_events: false)
expect(ProjectHook.push_hooks).to eq([hook])
end
end
@@ -30,7 +30,7 @@ describe ProjectHook do
describe '.tag_push_hooks' do
it 'should return hooks for tag push events only' do
hook = create(:project_hook, tag_push_events: true)
hook2 = create(:project_hook, tag_push_events: false)
create(:project_hook, tag_push_events: false)
expect(ProjectHook.tag_push_hooks).to eq([hook])
end
end
-2
View File
@@ -39,8 +39,6 @@ describe ServiceHook do
end
it "POSTs the data as JSON" do
json = @data.to_json
@service_hook.execute(@data)
expect(WebMock).to have_requested(:post, @service_hook.url).with(
headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'Service Hook' }

Some files were not shown because too many files have changed in this diff Show More