project_spec.rb 8.91 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
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
9 10
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
11
#  creator_id             :integer
12 13 14 15
#  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
16
#  namespace_id           :integer
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
17 18
#  issues_tracker         :string(255)      default("gitlab"), not null
#  issues_tracker_id      :string(255)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
19
#  snippets_enabled       :boolean          default(TRUE), not null
20
#  last_activity_at       :datetime
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
21
#  imported               :boolean          default(FALSE), not null
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
22
#  import_url             :string(255)
23
#  visibility_level       :integer          default(0), not null
24
#  archived               :boolean          default(FALSE), not null
25 26
#

gitlabhq's avatar
gitlabhq committed
27 28 29
require 'spec_helper'

describe Project do
30 31
  before { enable_observers }
  after { disable_observers }
32

gitlabhq's avatar
gitlabhq committed
33
  describe "Associations" do
34
    it { should belong_to(:group) }
35
    it { should belong_to(:namespace) }
36
    it { should belong_to(:creator).class_name('User') }
gitlabhq's avatar
gitlabhq committed
37
    it { should have_many(:users) }
38 39 40
    it { should have_many(:events).dependent(:destroy) }
    it { should have_many(:merge_requests).dependent(:destroy) }
    it { should have_many(:issues).dependent(:destroy) }
41 42
    it { should have_many(:milestones).dependent(:destroy) }
    it { should have_many(:users_projects).dependent(:destroy) }
43
    it { should have_many(:notes).dependent(:destroy) }
Andrew8xx8's avatar
Andrew8xx8 committed
44
    it { should have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) }
45 46
    it { should have_many(:deploy_keys_projects).dependent(:destroy) }
    it { should have_many(:deploy_keys) }
47 48
    it { should have_many(:hooks).dependent(:destroy) }
    it { should have_many(:protected_branches).dependent(:destroy) }
49
    it { should have_one(:forked_project_link).dependent(:destroy) }
gitlabhq's avatar
gitlabhq committed
50 51
  end

52
  describe "Mass assignment" do
53
    it { should_not allow_mass_assignment_of(:namespace_id) }
54
    it { should_not allow_mass_assignment_of(:creator_id) }
55 56
  end

gitlabhq's avatar
gitlabhq committed
57
  describe "Validation" do
58 59
    let!(:project) { create(:project) }

gitlabhq's avatar
gitlabhq committed
60
    it { should validate_presence_of(:name) }
61
    it { should validate_uniqueness_of(:name).scoped_to(:namespace_id) }
62 63
    it { should ensure_length_of(:name).is_within(0..255) }

gitlabhq's avatar
gitlabhq committed
64
    it { should validate_presence_of(:path) }
65
    it { should validate_uniqueness_of(:path).scoped_to(:namespace_id) }
66 67
    it { should ensure_length_of(:path).is_within(0..255) }
    it { should ensure_length_of(:description).is_within(0..2000) }
68
    it { should validate_presence_of(:creator) }
Andrew8xx8's avatar
Andrew8xx8 committed
69
    it { should ensure_length_of(:issues_tracker_id).is_within(0..255) }
70
    it { should validate_presence_of(:namespace) }
71 72

    it "should not allow new projects beyond user limits" do
73
      project2 = build(:project)
74
      project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
75 76
      project2.should_not be_valid
      project2.errors[:limit_reached].first.should match(/Your own projects limit is 0/)
77
    end
gitlabhq's avatar
gitlabhq committed
78 79 80 81 82
  end

  describe "Respond to" do
    it { should respond_to(:url_to_repo) }
    it { should respond_to(:repo_exists?) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
83 84 85
    it { should respond_to(:satellite) }
    it { should respond_to(:update_merge_requests) }
    it { should respond_to(:execute_hooks) }
86 87
    it { should respond_to(:transfer) }
    it { should respond_to(:name_with_namespace) }
88
    it { should respond_to(:owner) }
89
    it { should respond_to(:path_with_namespace) }
gitlabhq's avatar
gitlabhq committed
90 91
  end

Nihad Abbasov's avatar
Nihad Abbasov committed
92
  it "should return valid url to repo" do
93
    project = Project.new(path: "somewhere")
94
    project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + "somewhere.git"
gitlabhq's avatar
gitlabhq committed
95 96
  end

97
  it "returns the full web URL for this repo" do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
98
    project = Project.new(path: "somewhere")
99
    project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
100 101
  end

102 103
  it "returns the web URL without the protocol for this repo" do
    project = Project.new(path: "somewhere")
104
    project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split("://")[1]}/somewhere"
105 106
  end

107
  describe "last_activity methods" do
108
    let(:project) { create(:project) }
109
    let(:last_event) { double(created_at: Time.now) }
gitlabhq's avatar
gitlabhq committed
110

111
    describe "last_activity" do
112
      it "should alias last_activity to last_event" do
113 114 115
        project.stub(last_event: last_event)
        project.last_activity.should == last_event
      end
gitlabhq's avatar
gitlabhq committed
116 117
    end

118 119
    describe 'last_activity_date' do
      it 'returns the creation date of the project\'s last event if present' do
Andrey Kumanyaev's avatar
Andrey Kumanyaev committed
120
        last_activity_event = create(:event, project: project)
121
        project.last_activity_at.to_i.should == last_event.created_at.to_i
122
      end
123

124 125 126
      it 'returns the project\'s last update date if it has no events' do
        project.last_activity_date.should == project.updated_at
      end
127 128
    end
  end
129

130
  describe :update_merge_requests do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
131
    let(:project) { create(:project) }
132 133

    before do
134
      @merge_request = create(:merge_request, source_project: project, target_project: project)
135
      @key = create(:key, user_id: project.owner.id)
136 137 138
    end

    it "should close merge request if last commit from source branch was pushed to target branch" do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
139
      @merge_request.reload_code
140 141
      @merge_request.last_commit.id.should == "69b34b7e9ad9f496f0ad10250be37d6265a03bba"
      project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "69b34b7e9ad9f496f0ad10250be37d6265a03bba", "refs/heads/stable", @key.user)
142
      @merge_request.reload
143
      @merge_request.merged?.should be_true
144 145
    end

146
    it "should update merge request commits with new one if pushed to source branch" do
147
      project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "69b34b7e9ad9f496f0ad10250be37d6265a03bba", "refs/heads/master", @key.user)
148
      @merge_request.reload
149
      @merge_request.last_commit.id.should == "69b34b7e9ad9f496f0ad10250be37d6265a03bba"
150 151
    end
  end
152 153 154 155 156 157


  describe :find_with_namespace do
    context 'with namespace' do
      before do
        @group = create :group, name: 'gitlab'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
158
        @project = create(:project, name: 'gitlabhq', namespace: @group)
159 160
      end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
161
      it { Project.find_with_namespace('gitlab/gitlabhq').should == @project }
162 163 164 165 166 167 168 169
      it { Project.find_with_namespace('gitlab-ci').should be_nil }
    end
  end

  describe :to_param do
    context 'with namespace' do
      before do
        @group = create :group, name: 'gitlab'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
170
        @project = create(:project, name: 'gitlabhq', namespace: @group)
171 172
      end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
173
      it { @project.to_param.should == "gitlab/gitlabhq" }
174 175
    end
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
176

177
  describe :repository do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
178 179 180
    let(:project) { create(:project) }

    it "should return valid repo" do
181
      project.repository.should be_kind_of(Repository)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
182 183
    end
  end
184 185 186 187 188 189 190 191

  describe :issue_exists? do
    let(:project) { create(:project) }
    let(:existed_issue) { create(:issue, project: project) }
    let(:not_existed_issue) { create(:issue) }
    let(:ext_project) { create(:redmine_project) }

    it "should be true or if used internal tracker and issue exists" do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
192
      project.issue_exists?(existed_issue.iid).should be_true
193 194 195
    end

    it "should be false or if used internal tracker and issue not exists" do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
196
      project.issue_exists?(not_existed_issue.iid).should be_false
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
    end

    it "should always be true if used other tracker" do
      ext_project.issue_exists?(rand(100)).should be_true
    end
  end

  describe :used_default_issues_tracker? do
    let(:project) { create(:project) }
    let(:ext_project) { create(:redmine_project) }

    it "should be true if used internal tracker" do
      project.used_default_issues_tracker?.should be_true
    end

    it "should be false if used other tracker" do
      ext_project.used_default_issues_tracker?.should be_false
    end
  end

Andrew8xx8's avatar
Andrew8xx8 committed
217 218 219 220 221 222
  describe :can_have_issues_tracker_id? do
    let(:project) { create(:project) }
    let(:ext_project) { create(:redmine_project) }

    it "should be true for projects with external issues tracker if issues enabled" do
      ext_project.can_have_issues_tracker_id?.should be_true
223
    end
Andrew8xx8's avatar
Andrew8xx8 committed
224 225 226 227 228

    it "should be false for projects with internal issue tracker if issues enabled" do
      project.can_have_issues_tracker_id?.should be_false
    end

Johannes Schleifenbaum's avatar
Johannes Schleifenbaum committed
229
    it "should be always false if issues disabled" do
Andrew8xx8's avatar
Andrew8xx8 committed
230 231 232 233 234 235 236
      project.issues_enabled = false
      ext_project.issues_enabled = false

      project.can_have_issues_tracker_id?.should be_false
      ext_project.can_have_issues_tracker_id?.should be_false
    end
  end
237 238

  describe :open_branches do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
239
    let(:project) { create(:project) }
240 241 242 243 244 245 246 247

    before do
      project.protected_branches.create(name: 'master')
    end

    it { project.open_branches.map(&:name).should include('bootstrap') }
    it { project.open_branches.map(&:name).should_not include('master') }
  end
gitlabhq's avatar
gitlabhq committed
248
end