project_spec.rb 8.09 KB
Newer Older
1 2 3 4
# == Schema Information
#
# Table name: projects
#
5
#  id                     :integer          not null, primary key
6 7 8
#  name                   :string(255)
#  path                   :string(255)
#  description            :text
9 10 11
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
#  private_flag           :boolean          default(TRUE), not null
12 13
#  owner_id               :integer
#  default_branch         :string(255)
14 15 16 17
#  issues_enabled         :boolean          default(TRUE), not null
#  wall_enabled           :boolean          default(TRUE), not null
#  merge_requests_enabled :boolean          default(TRUE), not null
#  wiki_enabled           :boolean          default(TRUE), not null
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
18
#  namespace_id           :integer
19 20
#

gitlabhq's avatar
gitlabhq committed
21 22 23 24
require 'spec_helper'

describe Project do
  describe "Associations" do
25
    it { should belong_to(:group) }
26
    it { should belong_to(:namespace) }
27
    it { should belong_to(:owner).class_name('User') }
gitlabhq's avatar
gitlabhq committed
28
    it { should have_many(:users) }
29 30 31
    it { should have_many(:events).dependent(:destroy) }
    it { should have_many(:merge_requests).dependent(:destroy) }
    it { should have_many(:issues).dependent(:destroy) }
32 33
    it { should have_many(:milestones).dependent(:destroy) }
    it { should have_many(:users_projects).dependent(:destroy) }
34 35 36
    it { should have_many(:notes).dependent(:destroy) }
    it { should have_many(:snippets).dependent(:destroy) }
    it { should have_many(:deploy_keys).dependent(:destroy) }
37 38 39
    it { should have_many(:hooks).dependent(:destroy) }
    it { should have_many(:wikis).dependent(:destroy) }
    it { should have_many(:protected_branches).dependent(:destroy) }
gitlabhq's avatar
gitlabhq committed
40 41
  end

42
  describe "Mass assignment" do
43
    it { should_not allow_mass_assignment_of(:namespace_id) }
44 45 46 47
    it { should_not allow_mass_assignment_of(:owner_id) }
    it { should_not allow_mass_assignment_of(:private_flag) }
  end

gitlabhq's avatar
gitlabhq committed
48
  describe "Validation" do
49 50
    let!(:project) { create(:project) }

gitlabhq's avatar
gitlabhq committed
51
    it { should validate_presence_of(:name) }
52 53 54
    it { should validate_uniqueness_of(:name) }
    it { should ensure_length_of(:name).is_within(0..255) }

gitlabhq's avatar
gitlabhq committed
55
    it { should validate_presence_of(:path) }
56 57 58 59 60 61 62 63 64
    it { should validate_uniqueness_of(:path) }
    it { should ensure_length_of(:path).is_within(0..255) }
    # TODO: Formats

    it { should ensure_length_of(:description).is_within(0..2000) }

    # TODO: Formats

    it { should validate_presence_of(:owner) }
65 66 67 68
    it { should ensure_inclusion_of(:issues_enabled).in_array([true, false]) }
    it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) }
    it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) }
    it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) }
69 70 71 72 73 74 75 76 77 78 79

    it "should not allow new projects beyond user limits" do
      project.stub(:owner).and_return(double(can_create_project?: false, projects_limit: 1))
      project.should_not be_valid
      project.errors[:base].first.should match(/Your own projects limit is 1/)
    end

    it "should not allow 'gitolite-admin' as repo name" do
      should allow_value("blah").for(:path)
      should_not allow_value("gitolite-admin").for(:path)
    end
gitlabhq's avatar
gitlabhq committed
80 81 82 83 84 85 86 87 88
  end

  describe "Respond to" do
    it { should respond_to(:public?) }
    it { should respond_to(:private?) }
    it { should respond_to(:url_to_repo) }
    it { should respond_to(:path_to_repo) }
    it { should respond_to(:valid_repo?) }
    it { should respond_to(:repo_exists?) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
89 90 91 92

    # Repository Role
    it { should respond_to(:tree) }
    it { should respond_to(:root_ref) }
gitlabhq's avatar
gitlabhq committed
93 94 95
    it { should respond_to(:repo) }
    it { should respond_to(:tags) }
    it { should respond_to(:commit) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
96
    it { should respond_to(:commits) }
97
    it { should respond_to(:commits_between) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    it { should respond_to(:commits_with_refs) }
    it { should respond_to(:commits_since) }
    it { should respond_to(:commits_between) }
    it { should respond_to(:satellite) }
    it { should respond_to(:update_repository) }
    it { should respond_to(:destroy_repository) }
    it { should respond_to(:archive_repo) }

    # Authority Role
    it { should respond_to(:add_access) }
    it { should respond_to(:reset_access) }
    it { should respond_to(:repository_writers) }
    it { should respond_to(:repository_masters) }
    it { should respond_to(:repository_readers) }
    it { should respond_to(:allow_read_for?) }
    it { should respond_to(:guest_access_for?) }
    it { should respond_to(:report_access_for?) }
    it { should respond_to(:dev_access_for?) }
    it { should respond_to(:master_access_for?) }

    # Team Role
    it { should respond_to(:team_member_by_name_or_email) }
    it { should respond_to(:team_member_by_id) }
    it { should respond_to(:add_user_to_team) }
    it { should respond_to(:add_users_to_team) }
    it { should respond_to(:add_user_id_to_team) }
    it { should respond_to(:add_users_ids_to_team) }

    # Project Push Role
    it { should respond_to(:observe_push) }
    it { should respond_to(:update_merge_requests) }
    it { should respond_to(:execute_hooks) }
    it { should respond_to(:post_receive_data) }
    it { should respond_to(:trigger_post_receive) }
132 133 134 135 136 137 138

    # Namespaced Project Role
    it { should respond_to(:transfer) }
    it { should respond_to(:name_with_namespace) }
    it { should respond_to(:namespace_owner) }
    it { should respond_to(:chief) }
    it { should respond_to(:path_with_namespace) }
gitlabhq's avatar
gitlabhq committed
139 140
  end

141 142 143 144 145
  describe 'modules' do
    it { should include_module(Repository) }
    it { should include_module(PushObserver) }
    it { should include_module(Authority) }
    it { should include_module(Team) }
146
    it { should include_module(NamespacedProject) }
gitlabhq's avatar
gitlabhq committed
147 148
  end

Nihad Abbasov's avatar
Nihad Abbasov committed
149
  it "should return valid url to repo" do
150
    project = Project.new(path: "somewhere")
151
    project.url_to_repo.should == Gitlab.config.gitolite.ssh_path_prefix + "somewhere.git"
gitlabhq's avatar
gitlabhq committed
152 153
  end

Nihad Abbasov's avatar
Nihad Abbasov committed
154
  it "should return path to repo" do
155
    project = Project.new(path: "somewhere")
156
    project.path_to_repo.should == Rails.root.join("tmp", "repositories", "somewhere")
gitlabhq's avatar
gitlabhq committed
157 158
  end

159
  it "returns the full web URL for this repo" do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
160
    project = Project.new(path: "somewhere")
161
    project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
162 163
  end

164
  describe "last_activity methods" do
165
    let(:project)    { create(:project) }
166
    let(:last_event) { double(created_at: Time.now) }
gitlabhq's avatar
gitlabhq committed
167

168 169 170 171 172
    describe "last_activity" do
      it "should alias last_activity to last_event"do
        project.stub(last_event: last_event)
        project.last_activity.should == last_event
      end
gitlabhq's avatar
gitlabhq committed
173 174
    end

175 176 177 178 179
    describe 'last_activity_date' do
      it 'returns the creation date of the project\'s last event if present' do
        project.stub(last_event: last_event)
        project.last_activity_date.should == last_event.created_at
      end
180

181 182 183
      it 'returns the project\'s last update date if it has no events' do
        project.last_activity_date.should == project.updated_at
      end
184 185
    end
  end
186

187
  describe :update_merge_requests do
188
    let(:project) { create(:project) }
189 190

    before do
191 192 193 194 195
      @merge_request = create(:merge_request,
                              project: project,
                              merged: false,
                              closed: false)
      @key = create(:key, user_id: project.owner.id)
196 197 198 199 200
    end

    it "should close merge request if last commit from source branch was pushed to target branch" do
      @merge_request.reloaded_commits
      @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
201
      project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.user)
202 203 204 205 206
      @merge_request.reload
      @merge_request.merged.should be_true
      @merge_request.closed.should be_true
    end

207
    it "should update merge request commits with new one if pushed to source branch" do
208
      @merge_request.last_commit.should == nil
209
      project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.user)
210 211 212 213
      @merge_request.reload
      @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
    end
  end
gitlabhq's avatar
gitlabhq committed
214
end