project_spec.rb 11.5 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
#  issues_tracker         :string(255)      default("gitlab"), not null
D
Dmitriy Zaporozhets 已提交
18
#  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
D
Dmitriy Zaporozhets 已提交
27 28
#  import_type            :string(255)
#  import_source          :string(255)
29
#  avatar                 :string(255)
30 31
#

G
gitlabhq 已提交
32 33 34
require 'spec_helper'

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

57
  describe 'Mass assignment' do
58 59
  end

60
  describe 'Validation' do
61 62
    let!(:project) { create(:project) }

63 64 65
    it { is_expected.to validate_presence_of(:name) }
    it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) }
    it { is_expected.to ensure_length_of(:name).is_within(0..255) }
66

67 68 69 70 71 72 73
    it { is_expected.to validate_presence_of(:path) }
    it { is_expected.to validate_uniqueness_of(:path).scoped_to(:namespace_id) }
    it { is_expected.to ensure_length_of(:path).is_within(0..255) }
    it { is_expected.to ensure_length_of(:description).is_within(0..2000) }
    it { is_expected.to validate_presence_of(:creator) }
    it { is_expected.to ensure_length_of(:issues_tracker_id).is_within(0..255) }
    it { is_expected.to validate_presence_of(:namespace) }
74

75
    it 'should not allow new projects beyond user limits' do
76
      project2 = build(:project)
77 78 79
      allow(project2).to receive(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
      expect(project2).not_to be_valid
      expect(project2.errors[:limit_reached].first).to match(/Your project limit is 0/)
80
    end
G
gitlabhq 已提交
81 82
  end

83
  describe 'Respond to' do
84 85 86 87 88 89 90 91
    it { is_expected.to respond_to(:url_to_repo) }
    it { is_expected.to respond_to(:repo_exists?) }
    it { is_expected.to respond_to(:satellite) }
    it { is_expected.to respond_to(:update_merge_requests) }
    it { is_expected.to respond_to(:execute_hooks) }
    it { is_expected.to respond_to(:name_with_namespace) }
    it { is_expected.to respond_to(:owner) }
    it { is_expected.to respond_to(:path_with_namespace) }
G
gitlabhq 已提交
92 93
  end

94 95
  it 'should return valid url to repo' do
    project = Project.new(path: 'somewhere')
96
    expect(project.url_to_repo).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git')
G
gitlabhq 已提交
97 98
  end

99 100
  it 'returns the full web URL for this repo' do
    project = Project.new(path: 'somewhere')
101
    expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/somewhere")
A
Ariejan de Vroom 已提交
102 103
  end

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

109
  describe 'last_activity methods' do
I
Izaak Alpert 已提交
110
    let(:project) { create(:project) }
111
    let(:last_event) { double(created_at: Time.now) }
G
gitlabhq 已提交
112

113 114
    describe 'last_activity' do
      it 'should alias last_activity to last_event' do
115
        project.stub(last_event: last_event)
116
        expect(project.last_activity).to eq(last_event)
117
      end
G
gitlabhq 已提交
118 119
    end

120 121
    describe 'last_activity_date' do
      it 'returns the creation date of the project\'s last event if present' do
A
Andrey Kumanyaev 已提交
122
        last_activity_event = create(:event, project: project)
123
        expect(project.last_activity_at.to_i).to eq(last_event.created_at.to_i)
124
      end
125

126
      it 'returns the project\'s last update date if it has no events' do
127
        expect(project.last_activity_date).to eq(project.updated_at)
128
      end
129 130
    end
  end
131

132
  describe :update_merge_requests do
D
Dmitriy Zaporozhets 已提交
133
    let(:project) { create(:project) }
134 135 136 137
    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 }
138

139
    it 'should close merge request if last commit from source branch was pushed to target branch' do
140 141
      project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user)
      merge_request.reload
142
      expect(merge_request.merged?).to be_truthy
143 144
    end

145
    it 'should update merge request commits with new one if pushed to source branch' do
146 147
      project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user)
      merge_request.reload
148
      expect(merge_request.last_commit.id).to eq(commit_id)
149 150
    end
  end
151 152 153 154 155

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

159 160
      it { expect(Project.find_with_namespace('gitlab/gitlabhq')).to eq(@project) }
      it { expect(Project.find_with_namespace('gitlab-ci')).to be_nil }
161 162 163 164 165 166 167
    end
  end

  describe :to_param do
    context 'with namespace' do
      before do
        @group = create :group, name: 'gitlab'
D
Dmitriy Zaporozhets 已提交
168
        @project = create(:project, name: 'gitlabhq', namespace: @group)
169 170
      end

V
Vinnie Okada 已提交
171
      it { expect(@project.to_param).to eq('gitlabhq') }
172 173
    end
  end
D
Dmitriy Zaporozhets 已提交
174

175
  describe :repository do
D
Dmitriy Zaporozhets 已提交
176 177
    let(:project) { create(:project) }

178
    it 'should return valid repo' do
179
      expect(project.repository).to be_kind_of(Repository)
D
Dmitriy Zaporozhets 已提交
180 181
    end
  end
182 183 184 185 186 187 188

  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) }

189
    it 'should be true or if used internal tracker and issue exists' do
190
      expect(project.issue_exists?(existed_issue.iid)).to be_truthy
191 192
    end

193
    it 'should be false or if used internal tracker and issue not exists' do
194
      expect(project.issue_exists?(not_existed_issue.iid)).to be_falsey
195 196
    end

197
    it 'should always be true if used other tracker' do
198
      expect(ext_project.issue_exists?(rand(100))).to be_truthy
199 200 201
    end
  end

202
  describe :default_issues_tracker? do
203 204 205 206
    let(:project) { create(:project) }
    let(:ext_project) { create(:redmine_project) }

    it "should be true if used internal tracker" do
207
      expect(project.default_issues_tracker?).to be_truthy
208 209 210
    end

    it "should be false if used other tracker" do
211
      expect(ext_project.default_issues_tracker?).to be_falsey
212 213 214
    end
  end

A
Andrew8xx8 已提交
215 216 217 218
  describe :can_have_issues_tracker_id? do
    let(:project) { create(:project) }
    let(:ext_project) { create(:redmine_project) }

219
    it 'should be true for projects with external issues tracker if issues enabled' do
220
      expect(ext_project.can_have_issues_tracker_id?).to be_truthy
221
    end
A
Andrew8xx8 已提交
222

223
    it 'should be false for projects with internal issue tracker if issues enabled' do
224
      expect(project.can_have_issues_tracker_id?).to be_falsey
A
Andrew8xx8 已提交
225 226
    end

227
    it 'should be always false if issues disabled' do
A
Andrew8xx8 已提交
228 229 230
      project.issues_enabled = false
      ext_project.issues_enabled = false

231 232
      expect(project.can_have_issues_tracker_id?).to be_falsey
      expect(ext_project.can_have_issues_tracker_id?).to be_falsey
A
Andrew8xx8 已提交
233 234
    end
  end
235 236

  describe :open_branches do
D
Dmitriy Zaporozhets 已提交
237
    let(:project) { create(:project) }
238 239 240 241 242

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

243 244
    it { expect(project.open_branches.map(&:name)).to include('feature') }
    it { expect(project.open_branches.map(&:name)).not_to include('master') }
245
  end
C
Ciro Santilli 已提交
246

247 248
  describe '#star_count' do
    it 'counts stars from multiple users' do
C
Ciro Santilli 已提交
249 250 251 252 253
      user1 = create :user
      user2 = create :user
      project = create :project, :public

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

C
Ciro Santilli 已提交
255
      user1.toggle_star(project)
256 257
      expect(project.reload.star_count).to eq(1)

C
Ciro Santilli 已提交
258
      user2.toggle_star(project)
259 260 261
      project.reload
      expect(project.reload.star_count).to eq(2)

C
Ciro Santilli 已提交
262
      user1.toggle_star(project)
263 264 265
      project.reload
      expect(project.reload.star_count).to eq(1)

C
Ciro Santilli 已提交
266
      user2.toggle_star(project)
267 268 269 270
      project.reload
      expect(project.reload.star_count).to eq(0)
    end

271
    it 'counts stars on the right project' do
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
      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 已提交
302
    end
303 304 305 306 307 308 309 310 311 312 313

    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 已提交
314
  end
315 316 317 318 319 320

  describe :avatar_type do
    let(:project) { create(:project) }

    it 'should be true if avatar is image' do
      project.update_attribute(:avatar, 'uploads/avatar.png')
321
      expect(project.avatar_type).to be_truthy
322 323 324 325
    end

    it 'should be false if avatar is html page' do
      project.update_attribute(:avatar, 'uploads/avatar.html')
326
      expect(project.avatar_type).to eq(['only images allowed'])
327 328
    end
  end
G
gitlabhq 已提交
329
end