436 lines
15 KiB
Ruby
436 lines
15 KiB
Ruby
require 'spec_helper_core'
|
|
|
|
describe Repository do
|
|
include Support::ActiveRecord
|
|
|
|
describe '#last_completed_build' do
|
|
let(:repo) { Factory(:repository, name: 'foobarbaz', builds: [build1, build2]) }
|
|
let(:build1) { Factory(:build, finished_at: 1.hour.ago, state: :passed) }
|
|
let(:build2) { Factory(:build, finished_at: Time.now, state: :failed) }
|
|
|
|
before do
|
|
build1.update_attributes(branch: 'master')
|
|
build2.update_attributes(branch: 'development')
|
|
end
|
|
|
|
it 'returns last completed build' do
|
|
repo.last_completed_build.should == build2
|
|
end
|
|
|
|
it 'returns last completed build for a branch' do
|
|
repo.last_completed_build('master').should == build1
|
|
end
|
|
end
|
|
|
|
describe '#regenerate_key!' do
|
|
it 'regenerates key' do
|
|
repo = Factory(:repository)
|
|
|
|
expect { repo.regenerate_key! }.to change { repo.key.private_key }
|
|
end
|
|
end
|
|
|
|
describe 'associations' do
|
|
describe 'owner' do
|
|
let(:user) { Factory(:user) }
|
|
let(:org) { Factory(:org) }
|
|
|
|
it 'can be a user' do
|
|
repo = Factory(:repository, owner: user)
|
|
repo.reload.owner.should == user
|
|
end
|
|
|
|
it 'can be an organization' do
|
|
repo = Factory(:repository, owner: org)
|
|
repo.reload.owner.should == org
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'class methods' do
|
|
describe 'find_by' do
|
|
let(:minimal) { Factory(:repository) }
|
|
|
|
it "should find a repository by it's github_id" do
|
|
Repository.find_by(github_id: minimal.github_id).should == minimal
|
|
end
|
|
|
|
it "should find a repository by it's id" do
|
|
Repository.find_by(id: minimal.id).id.should == minimal.id
|
|
end
|
|
|
|
it "should find a repository by it's name and owner_name" do
|
|
repo = Repository.find_by(name: minimal.name, owner_name: minimal.owner_name)
|
|
repo.owner_name.should == minimal.owner_name
|
|
repo.name.should == minimal.name
|
|
end
|
|
|
|
it "returns nil when a repository couldn't be found using params" do
|
|
Repository.find_by(name: 'emptiness').should be_nil
|
|
end
|
|
end
|
|
|
|
describe 'timeline' do
|
|
before do
|
|
Factory(:repository, name: 'unbuilt 1', active: true, last_build_started_at: nil, last_build_finished_at: nil)
|
|
Factory(:repository, name: 'unbuilt 2', active: true, last_build_started_at: nil, last_build_finished_at: nil)
|
|
Factory(:repository, name: 'finished 1', active: true, last_build_started_at: '2011-11-12 12:00:00', last_build_finished_at: '2011-11-12 12:00:05')
|
|
Factory(:repository, name: 'finished 2', active: true, last_build_started_at: '2011-11-12 12:00:01', last_build_finished_at: '2011-11-11 12:00:06')
|
|
Factory(:repository, name: 'started 1', active: true, last_build_started_at: '2011-11-11 12:00:00', last_build_finished_at: nil)
|
|
Factory(:repository, name: 'started 2', active: true, last_build_started_at: '2011-11-11 12:00:01', last_build_finished_at: nil)
|
|
Factory(:repository, name: 'invalidated', active: true, last_build_started_at: '2011-11-11 12:00:01', last_build_finished_at: nil, invalidated_at: '2012-11-11 12:00:06')
|
|
end
|
|
|
|
it 'sorts repositories with running builds to the top, most recent builds next, un-built repos last' do
|
|
repositories = Repository.timeline
|
|
repositories.map(&:name).should == ['started 2', 'started 1', 'finished 2', 'finished 1', 'unbuilt 2', 'unbuilt 1']
|
|
end
|
|
|
|
it 'does not include invalidated repos' do
|
|
repositories = Repository.timeline
|
|
repositories.map(&:name).should_not include('invalidated')
|
|
end
|
|
end
|
|
|
|
describe 'with_builds' do
|
|
it 'gets only projects with existing builds' do
|
|
one = Factory(:repository, name: 'one', last_build_started_at: '2011-11-11', last_build_id: nil)
|
|
two = Factory(:repository, name: 'two', last_build_started_at: '2011-11-12', last_build_id: 101)
|
|
three = Factory(:repository, name: 'three', last_build_started_at: nil, last_build_id: 100)
|
|
|
|
repositories = Repository.with_builds.all
|
|
repositories.map(&:id).sort.should == [two, three].map(&:id).sort
|
|
end
|
|
end
|
|
|
|
describe 'active' do
|
|
let(:active) { Factory(:repository, active: true) }
|
|
let(:inactive) { Factory(:repository, active: false) }
|
|
let(:invalidated) { Factory(:repository, invalidated_at: Time.now) }
|
|
|
|
it 'contains active repositories' do
|
|
Repository.active.should include(active)
|
|
end
|
|
|
|
it 'does not include inactive repositories' do
|
|
Repository.active.should_not include(inactive)
|
|
end
|
|
|
|
it 'does not include invalidated repositories' do
|
|
Repository.active.should_not include(invalidated)
|
|
end
|
|
end
|
|
|
|
describe 'search' do
|
|
before(:each) do
|
|
Factory(:repository, name: 'repo 1', last_build_started_at: '2011-11-11')
|
|
Factory(:repository, name: 'repo 2', last_build_started_at: '2011-11-12')
|
|
Factory(:repository, name: 'invalidated', invalidated_at: Time.now)
|
|
end
|
|
|
|
it 'performs searches case-insensitive' do
|
|
Repository.search('rEpO').to_a.count.should == 2
|
|
end
|
|
|
|
it 'performs searches with / entered' do
|
|
Repository.search('fuchs/').to_a.count.should == 2
|
|
end
|
|
|
|
it 'performs searches with \ entered' do
|
|
Repository.search('fuchs\\').to_a.count.should == 2
|
|
end
|
|
|
|
it 'does not find invalidated repos' do
|
|
Repository.search('fuchs').map(&:name).should_not include('invalidated')
|
|
end
|
|
end
|
|
|
|
describe 'by_member' do
|
|
let(:user) { Factory(:user) }
|
|
let(:org) { Factory(:org) }
|
|
let(:user_repo) { Factory(:repository, owner: user)}
|
|
let(:org_repo) { Factory(:repository, owner: org, name: 'globalize')}
|
|
let(:invalidated) { Factory(:repository, owner: org, name: 'invalidated', invalidated_at: Time.now)}
|
|
before do
|
|
Permission.create!(user: user, repository: user_repo, pull: true, push: true)
|
|
Permission.create!(user: user, repository: org_repo, pull: true)
|
|
Permission.create!(user: user, repository: invalidated, pull: true)
|
|
end
|
|
|
|
it 'returns all repositories a user has rights to' do
|
|
Repository.by_member('svenfuchs').should have(2).items
|
|
end
|
|
|
|
it 'does not find invalidated repos' do
|
|
Repository.by_member('svenfuchs').map(&:name).should_not include('invalidated')
|
|
end
|
|
end
|
|
|
|
describe 'counts_by_owner_names' do
|
|
let!(:repositories) do
|
|
Factory(:repository, owner_name: 'svenfuchs', name: 'minimal')
|
|
Factory(:repository, owner_name: 'travis-ci', name: 'travis-ci')
|
|
Factory(:repository, owner_name: 'travis-ci', name: 'invalidated', invalidated_at: Time.now)
|
|
end
|
|
|
|
it 'returns repository counts per owner_name for the given owner_names' do
|
|
counts = Repository.counts_by_owner_names(%w(svenfuchs travis-ci))
|
|
counts.should == { 'svenfuchs' => 1, 'travis-ci' => 1 }
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'api_url' do
|
|
let(:repo) { Repository.new(owner_name: 'travis-ci', name: 'travis-ci') }
|
|
|
|
before :each do
|
|
Travis.config.github.api_url = 'https://api.github.com'
|
|
end
|
|
|
|
it 'returns the api url for the repository' do
|
|
repo.api_url.should == 'https://api.github.com/repos/travis-ci/travis-ci'
|
|
end
|
|
end
|
|
|
|
describe 'source_url' do
|
|
describe 'default source endpoint' do
|
|
let(:repo) { Repository.new(owner_name: 'travis-ci', name: 'travis-ci') }
|
|
|
|
before :each do
|
|
Travis.config.github.source_host = nil
|
|
end
|
|
|
|
it 'returns the public git source url for a public repository' do
|
|
repo.private = false
|
|
repo.source_url.should == 'git://github.com/travis-ci/travis-ci.git'
|
|
end
|
|
|
|
it 'returns the private git source url for a private repository' do
|
|
repo.private = true
|
|
repo.source_url.should == 'git@github.com:travis-ci/travis-ci.git'
|
|
end
|
|
end
|
|
|
|
describe 'custom source endpoint' do
|
|
let(:repo) { Repository.new(owner_name: 'travis-ci', name: 'travis-ci') }
|
|
|
|
before :each do
|
|
Travis.config.github.source_host = 'localhost'
|
|
end
|
|
|
|
it 'returns the private git source url for a public repository' do
|
|
repo.private = false
|
|
repo.source_url.should == 'git@localhost:travis-ci/travis-ci.git'
|
|
end
|
|
|
|
it 'returns the private git source url for a private repository' do
|
|
repo.private = true
|
|
repo.source_url.should == 'git@localhost:travis-ci/travis-ci.git'
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'source_host' do
|
|
before :each do
|
|
Travis.config.github.stubs(:source_host).returns('localhost')
|
|
end
|
|
|
|
it 'returns the source_host name from Travis.config' do
|
|
Repository.new.source_host.should == 'localhost'
|
|
end
|
|
end
|
|
|
|
describe "#last_build" do
|
|
let(:repo) { Factory(:repository) }
|
|
let(:attributes) { { repository: repo, state: 'finished' } }
|
|
let(:api_req) { Factory(:request, {event_type: 'api'}) }
|
|
|
|
before :each do
|
|
Factory(:build, attributes)
|
|
Factory(:build, attributes)
|
|
end
|
|
|
|
context 'when last build is a push build' do
|
|
before :each do
|
|
@build = Factory(:build, attributes)
|
|
end
|
|
|
|
it 'returns the most recent build' do
|
|
repo.last_build('master').id.should == @build.id
|
|
end
|
|
end
|
|
|
|
context 'when last build is an API build' do
|
|
before :each do
|
|
@build = Factory(:build, attributes.merge({request: api_req}))
|
|
end
|
|
|
|
it 'returns the most recent build' do
|
|
repo.last_build('master').id.should == @build.id
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#last_build_on' do
|
|
let(:repo) { Factory(:repository) }
|
|
let(:attributes) { { repository: repo, state: 'finished' } }
|
|
let(:api_req) { Factory(:request, {event_type: 'api'}) }
|
|
|
|
before :each do
|
|
Factory(:build, attributes)
|
|
end
|
|
|
|
context 'when last build is a push build' do
|
|
before :each do
|
|
@build = Factory(:build, attributes)
|
|
end
|
|
|
|
it 'returns the most recent build' do
|
|
repo.last_build_on('master').id.should == @build.id
|
|
end
|
|
end
|
|
|
|
context 'when last build is an API build' do
|
|
before :each do
|
|
@build = Factory(:build, attributes.merge({request: api_req}))
|
|
end
|
|
|
|
it 'returns the most recent build' do
|
|
repo.last_build_on('master').id.should == @build.id
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "keys" do
|
|
let(:repo) { Factory(:repository) }
|
|
|
|
it "should return the public key" do
|
|
repo.public_key.should == repo.key.public_key
|
|
end
|
|
|
|
it "should create a new key when the repository is created" do
|
|
repo = Repository.create!(owner_name: 'travis-ci', name: 'travis-ci')
|
|
repo.key.should_not be_nil
|
|
end
|
|
end
|
|
|
|
describe 'branches' do
|
|
let(:repo) { Factory(:repository) }
|
|
|
|
it 'returns branches for the given repository' do
|
|
%w(master production).each do |branch|
|
|
2.times { Factory(:build, repository: repo, commit: Factory(:commit, branch: branch)) }
|
|
end
|
|
repo.branches.sort.should == %w(master production)
|
|
end
|
|
|
|
it 'is empty for empty repository' do
|
|
repo.branches.should eql []
|
|
end
|
|
end
|
|
|
|
describe 'settings' do
|
|
let(:repo) { Factory.build(:repository) }
|
|
|
|
it 'adds repository_id to collection records' do
|
|
repo.save
|
|
|
|
env_var = repo.settings.env_vars.create(name: 'FOO')
|
|
env_var.repository_id.should == repo.id
|
|
|
|
repo.settings.save
|
|
|
|
repo.reload
|
|
|
|
repo.settings.env_vars.first.repository_id.should == repo.id
|
|
end
|
|
|
|
it "is reset on reload" do
|
|
repo.save
|
|
|
|
repo.settings = {}
|
|
repo.update_column(:settings, { 'build_pushes' => false }.to_json)
|
|
repo.reload
|
|
repo.settings.build_pushes?.should be_false
|
|
repo.update_column(:settings, { 'build_pushes' => true }.to_json)
|
|
repo.reload
|
|
repo.settings.build_pushes?.should be_true
|
|
end
|
|
|
|
it "allows to set nil for settings" do
|
|
repo.settings = nil
|
|
repo.settings.to_hash.should == Repository::Settings.new.to_hash
|
|
end
|
|
|
|
it "allows to set settings as JSON string" do
|
|
repo.settings = '{"maximum_number_of_builds": 44}'
|
|
repo.settings.to_hash.should == Repository::Settings.new(maximum_number_of_builds: 44).to_hash
|
|
end
|
|
|
|
it "allows to set settings as a Hash" do
|
|
repo.settings = { maximum_number_of_builds: 44}
|
|
repo.settings.to_hash.should == Repository::Settings.new(maximum_number_of_builds: 44).to_hash
|
|
end
|
|
|
|
it 'updates settings in the DB' do
|
|
repo.settings = {'build_pushes' => false}
|
|
repo.save
|
|
|
|
repo.reload.settings.build_pushes?.should == false
|
|
|
|
repo.settings.merge('build_pushes' => true)
|
|
repo.settings.save
|
|
|
|
repo.reload.settings.build_pushes?.should == true
|
|
end
|
|
end
|
|
|
|
describe 'last_finished_builds_by_branches' do
|
|
let(:repo) { Factory(:repository) }
|
|
|
|
it 'properly orders branches by last build' do
|
|
Build.delete_all
|
|
one = Factory(:build, repository: repo, finished_at: 2.hours.ago, state: 'finished', commit: Factory(:commit, branch: '1one'))
|
|
two = Factory(:build, repository: repo, finished_at: 1.hours.ago, state: 'finished', commit: Factory(:commit, branch: '2two'))
|
|
|
|
builds = repo.last_finished_builds_by_branches(1)
|
|
builds.should == [two]
|
|
end
|
|
|
|
it 'retrieves last builds on all branches' do
|
|
Build.delete_all
|
|
old = Factory(:build, repository: repo, finished_at: 1.hour.ago, state: 'finished', commit: Factory(:commit, branch: 'one'))
|
|
one = Factory(:build, repository: repo, finished_at: 1.hour.from_now, state: 'finished', commit: Factory(:commit, branch: 'one'))
|
|
two = Factory(:build, repository: repo, finished_at: 1.hour.from_now, state: 'finished', commit: Factory(:commit, branch: 'two'))
|
|
three = Factory(:build, repository: repo, finished_at: 1.hour.from_now, state: 'finished', commit: Factory(:commit, branch: 'three'))
|
|
three.update_attribute(:event_type, 'pull_request')
|
|
|
|
builds = repo.last_finished_builds_by_branches
|
|
builds.size.should == 2
|
|
builds.should include(one)
|
|
builds.should include(two)
|
|
builds.should_not include(old)
|
|
end
|
|
end
|
|
|
|
describe '#users_with_permission' do
|
|
it 'returns users with the given permission linked to that repository' do
|
|
repo = Factory(:repository)
|
|
other_repo = Factory(:repository)
|
|
|
|
user_with_permission = Factory(:user)
|
|
user_with_permission.permissions.create!(repository: repo, admin: true)
|
|
|
|
user_wrong_repo = Factory(:user)
|
|
user_wrong_repo.permissions.create!(repository: other_repo, admin: true)
|
|
|
|
user_wrong_permission = Factory(:user)
|
|
user_wrong_permission.permissions.create!(repository: repo, push: true)
|
|
|
|
repo.users_with_permission(:admin).should include(user_with_permission)
|
|
repo.users_with_permission(:admin).should_not include(user_wrong_repo)
|
|
repo.users_with_permission(:admin).should_not include(user_wrong_permission)
|
|
end
|
|
end
|
|
end
|