project_spec.rb 12.3 KB
Newer Older
1 2 3 4
# == Schema Information
#
# Table name: projects
#
D
Dmitriy Zaporozhets 已提交
5
#  id                     :integer          not null, primary key
6 7 8
#  name                   :string(255)
#  path                   :string(255)
#  description            :text
D
Dmitriy Zaporozhets 已提交
9 10
#  created_at             :datetime
#  updated_at             :datetime
D
Dmitriy Zaporozhets 已提交
11
#  creator_id             :integer
D
Dmitriy Zaporozhets 已提交
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
D
Dmitriy Zaporozhets 已提交
16
#  namespace_id           :integer
D
Dmitriy Zaporozhets 已提交
17 18
#  issues_tracker         :string(255)      default("gitlab"), not null
#  issues_tracker_id      :string(255)
D
Dmitriy Zaporozhets 已提交
19
#  snippets_enabled       :boolean          default(TRUE), not null
20
#  last_activity_at       :datetime
D
Dmitriy Zaporozhets 已提交
21
#  import_url             :string(255)
22
#  visibility_level       :integer          default(0), not null
23
#  archived               :boolean          default(FALSE), not null
D
Dmitriy Zaporozhets 已提交
24
#  import_status          :string(255)
D
Dmitriy Zaporozhets 已提交
25 26
#  repository_size        :float            default(0.0)
#  star_count             :integer          default(0), not null
27 28
#

G
gitlabhq 已提交
29 30 31 32
require 'spec_helper'

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

52 53 54
  describe "Mass assignment" do
  end

G
gitlabhq 已提交
55
  describe "Validation" do
56 57
    let!(:project) { create(:project) }

G
gitlabhq 已提交
58
    it { should validate_presence_of(:name) }
59
    it { should validate_uniqueness_of(:name).scoped_to(:namespace_id) }
60 61
    it { should ensure_length_of(:name).is_within(0..255) }

G
gitlabhq 已提交
62
    it { should validate_presence_of(:path) }
63
    it { should validate_uniqueness_of(:path).scoped_to(:namespace_id) }
64 65
    it { should ensure_length_of(:path).is_within(0..255) }
    it { should ensure_length_of(:description).is_within(0..2000) }
66
    it { should validate_presence_of(:creator) }
A
Andrew8xx8 已提交
67
    it { should ensure_length_of(:issues_tracker_id).is_within(0..255) }
68
    it { should validate_presence_of(:namespace) }
69 70

    it "should not allow new projects beyond user limits" do
71
      project2 = build(:project)
D
Dmitriy Zaporozhets 已提交
72
      project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
73
      project2.should_not be_valid
74
      project2.errors[:limit_reached].first.should match(/Your project limit is 0/)
75
    end
G
gitlabhq 已提交
76 77 78 79 80
  end

  describe "Respond to" do
    it { should respond_to(:url_to_repo) }
    it { should respond_to(:repo_exists?) }
D
Dmitriy Zaporozhets 已提交
81 82 83
    it { should respond_to(:satellite) }
    it { should respond_to(:update_merge_requests) }
    it { should respond_to(:execute_hooks) }
84
    it { should respond_to(:name_with_namespace) }
85
    it { should respond_to(:owner) }
86
    it { should respond_to(:path_with_namespace) }
G
gitlabhq 已提交
87 88
  end

N
Nihad Abbasov 已提交
89
  it "should return valid url to repo" do
90
    project = Project.new(path: "somewhere")
91
    project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + "somewhere.git"
G
gitlabhq 已提交
92 93
  end

A
Ariejan de Vroom 已提交
94
  it "returns the full web URL for this repo" do
D
Dmitriy Zaporozhets 已提交
95
    project = Project.new(path: "somewhere")
96
    project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
A
Ariejan de Vroom 已提交
97 98
  end

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

104
  describe "last_activity methods" do
I
Izaak Alpert 已提交
105
    let(:project) { create(:project) }
106
    let(:last_event) { double(created_at: Time.now) }
G
gitlabhq 已提交
107

108
    describe "last_activity" do
I
Izaak Alpert 已提交
109
      it "should alias last_activity to last_event" do
110 111 112
        project.stub(last_event: last_event)
        project.last_activity.should == last_event
      end
G
gitlabhq 已提交
113 114
    end

115 116
    describe 'last_activity_date' do
      it 'returns the creation date of the project\'s last event if present' do
A
Andrey Kumanyaev 已提交
117
        last_activity_event = create(:event, project: project)
D
Dmitriy Zaporozhets 已提交
118
        project.last_activity_at.to_i.should == last_event.created_at.to_i
119
      end
120

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

127
  describe :update_merge_requests do
D
Dmitriy Zaporozhets 已提交
128
    let(:project) { create(:project) }
129 130 131 132
    let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
    let(:key) { create(:key, user_id: project.owner.id) }
    let(:prev_commit_id) { merge_request.commits.last.id }
    let(:commit_id) { merge_request.commits.first.id }
133 134

    it "should close merge request if last commit from source branch was pushed to target branch" do
135 136 137
      project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user)
      merge_request.reload
      merge_request.merged?.should be_true
138 139
    end

140
    it "should update merge request commits with new one if pushed to source branch" do
141 142 143
      project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user)
      merge_request.reload
      merge_request.last_commit.id.should == commit_id
144 145
    end
  end
146

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
  describe 'comment merge requests with commits' do
    before do
      @user = create(:user)
      group = create(:group)
      group.add_owner(@user)

      @project = create(:project, namespace: group)
      @fork_project = Projects::ForkService.new(@project, @user).execute
      @merge_request = create(:merge_request, source_project: @project,
                              source_branch: 'master',
                              target_branch: 'feature',
                              target_project: @project)
      @fork_merge_request = create(:merge_request, source_project: @fork_project,
                                   source_branch: 'master',
                                   target_branch: 'feature',
                                   target_project: @project)

      @commits = @merge_request.commits
    end

    context 'push to origin repo source branch' do
      before do
        @project.comment_mr_with_commits('master', @commits, @user)
      end

      it { @merge_request.notes.should_not be_empty }
      it { @fork_merge_request.notes.should be_empty }
    end

    context 'push to origin repo target branch' do
      before do
        @project.comment_mr_with_commits('feature', @commits, @user)
      end

      it { @merge_request.notes.should be_empty }
      it { @fork_merge_request.notes.should be_empty }
    end

    context 'push to fork repo source branch' do
      before do
        @fork_project.comment_mr_with_commits('master', @commits, @user)
      end

      it { @merge_request.notes.should be_empty }
      it { @fork_merge_request.notes.should_not be_empty }
    end

    context 'push to fork repo target branch' do
      before do
        @fork_project.comment_mr_with_commits('feature', @commits, @user)
      end

      it { @merge_request.notes.should be_empty }
      it { @fork_merge_request.notes.should be_empty }
    end
  end
203 204 205 206 207

  describe :find_with_namespace do
    context 'with namespace' do
      before do
        @group = create :group, name: 'gitlab'
D
Dmitriy Zaporozhets 已提交
208
        @project = create(:project, name: 'gitlabhq', namespace: @group)
209 210
      end

D
Dmitriy Zaporozhets 已提交
211
      it { Project.find_with_namespace('gitlab/gitlabhq').should == @project }
212 213 214 215 216 217 218 219
      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'
D
Dmitriy Zaporozhets 已提交
220
        @project = create(:project, name: 'gitlabhq', namespace: @group)
221 222
      end

D
Dmitriy Zaporozhets 已提交
223
      it { @project.to_param.should == "gitlab/gitlabhq" }
224 225
    end
  end
D
Dmitriy Zaporozhets 已提交
226

227
  describe :repository do
D
Dmitriy Zaporozhets 已提交
228 229 230
    let(:project) { create(:project) }

    it "should return valid repo" do
231
      project.repository.should be_kind_of(Repository)
D
Dmitriy Zaporozhets 已提交
232 233
    end
  end
234 235 236 237 238 239 240 241

  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
D
Dmitriy Zaporozhets 已提交
242
      project.issue_exists?(existed_issue.iid).should be_true
243 244 245
    end

    it "should be false or if used internal tracker and issue not exists" do
D
Dmitriy Zaporozhets 已提交
246
      project.issue_exists?(not_existed_issue.iid).should be_false
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    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

A
Andrew8xx8 已提交
267 268 269 270 271 272
  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
273
    end
A
Andrew8xx8 已提交
274 275 276 277 278

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

J
Johannes Schleifenbaum 已提交
279
    it "should be always false if issues disabled" do
A
Andrew8xx8 已提交
280 281 282 283 284 285 286
      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
287 288

  describe :open_branches do
D
Dmitriy Zaporozhets 已提交
289
    let(:project) { create(:project) }
290 291 292 293 294

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

295
    it { project.open_branches.map(&:name).should include('feature') }
296 297
    it { project.open_branches.map(&:name).should_not include('master') }
  end
C
Ciro Santilli 已提交
298

299 300
  describe '#star_count' do
    it 'counts stars from multiple users' do
C
Ciro Santilli 已提交
301 302 303 304 305
      user1 = create :user
      user2 = create :user
      project = create :project, :public

      expect(project.star_count).to eq(0)
306

C
Ciro Santilli 已提交
307
      user1.toggle_star(project)
308 309
      expect(project.reload.star_count).to eq(1)

C
Ciro Santilli 已提交
310
      user2.toggle_star(project)
311 312 313
      project.reload
      expect(project.reload.star_count).to eq(2)

C
Ciro Santilli 已提交
314
      user1.toggle_star(project)
315 316 317
      project.reload
      expect(project.reload.star_count).to eq(1)

C
Ciro Santilli 已提交
318
      user2.toggle_star(project)
319 320 321 322
      project.reload
      expect(project.reload.star_count).to eq(0)
    end

323
    it 'counts stars on the right project' do
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

      expect(project1.star_count).to eq(0)
      expect(project2.star_count).to eq(0)

      user.toggle_star(project1)
      project1.reload
      project2.reload
      expect(project1.star_count).to eq(1)
      expect(project2.star_count).to eq(0)

      user.toggle_star(project1)
      project1.reload
      project2.reload
      expect(project1.star_count).to eq(0)
      expect(project2.star_count).to eq(0)

      user.toggle_star(project2)
      project1.reload
      project2.reload
      expect(project1.star_count).to eq(0)
      expect(project2.star_count).to eq(1)

      user.toggle_star(project2)
      project1.reload
      project2.reload
      expect(project1.star_count).to eq(0)
      expect(project2.star_count).to eq(0)
C
Ciro Santilli 已提交
354
    end
355 356 357 358 359 360 361 362 363 364 365

    it 'is decremented when an upvoter account is deleted' do
      user = create :user
      project = create :project, :public
      user.toggle_star(project)
      project.reload
      expect(project.star_count).to eq(1)
      user.destroy
      project.reload
      expect(project.star_count).to eq(0)
    end
C
Ciro Santilli 已提交
366
  end
G
gitlabhq 已提交
367
end