Merge branch 'master' into discussions
Conflicts: app/assets/stylesheets/main.scss app/models/project.rb app/views/notes/_common_form.html.haml app/views/notes/_per_line_form.html.haml lib/gitlab/markdown.rb spec/models/note_spec.rb
This commit is contained in:
commit
db2c15369c
276 changed files with 4466 additions and 2603 deletions
|
@ -45,6 +45,7 @@ FactoryGirl.define do
|
|||
factory :users_project do
|
||||
user
|
||||
project
|
||||
project_access { UsersProject::MASTER }
|
||||
end
|
||||
|
||||
factory :issue do
|
||||
|
@ -100,7 +101,7 @@ FactoryGirl.define do
|
|||
factory :note_on_merge_request_line, traits: [:on_merge_request, :on_line]
|
||||
|
||||
trait :on_commit do
|
||||
noteable_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
|
||||
commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
|
||||
noteable_type "Commit"
|
||||
end
|
||||
|
||||
|
@ -114,7 +115,7 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
trait :on_issue do
|
||||
noteable_id 1
|
||||
noteable_id 1
|
||||
noteable_type "Issue"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ describe ApplicationHelper do
|
|||
let(:user_email) { 'user@email.com' }
|
||||
|
||||
it "should return a generic avatar path when Gravatar is disabled" do
|
||||
Gitlab.config.stub(:disable_gravatar?).and_return(true)
|
||||
Gitlab.config.gravatar.stub(:enabled).and_return(false)
|
||||
gravatar_icon(user_email).should == 'no_avatar.png'
|
||||
end
|
||||
|
||||
|
@ -51,14 +51,36 @@ describe ApplicationHelper do
|
|||
gravatar_icon('').should == 'no_avatar.png'
|
||||
end
|
||||
|
||||
it "should return default gravatar url" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
gravatar_icon(user_email).should match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118')
|
||||
end
|
||||
|
||||
it "should use SSL when appropriate" do
|
||||
stub!(:request).and_return(double(:ssl? => true))
|
||||
gravatar_icon(user_email).should match('https://secure.gravatar.com')
|
||||
end
|
||||
|
||||
it "should return custom gravatar path when gravatar_url is set" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
Gitlab.config.gravatar.stub(:plain_url).and_return('http://example.local/?s=%{size}&hash=%{hash}')
|
||||
gravatar_icon(user_email, 20).should == 'http://example.local/?s=20&hash=b58c6f14d292556214bd64909bcdb118'
|
||||
end
|
||||
|
||||
it "should accept a custom size" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
gravatar_icon(user_email, 64).should match(/\?s=64/)
|
||||
end
|
||||
|
||||
it "should use default size when size is wrong" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
gravatar_icon(user_email, nil).should match(/\?s=40/)
|
||||
end
|
||||
|
||||
it "should be case insensitive" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
gravatar_icon(user_email).should == gravatar_icon(user_email.upcase + " ")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require "spec_helper"
|
|||
describe GitlabMarkdownHelper do
|
||||
let!(:project) { create(:project) }
|
||||
|
||||
let(:user) { create(:user, name: 'gfm') }
|
||||
let(:user) { create(:user, username: 'gfm') }
|
||||
let(:commit) { CommitDecorator.decorate(project.commit) }
|
||||
let(:issue) { create(:issue, project: project) }
|
||||
let(:merge_request) { create(:merge_request, project: project) }
|
||||
|
@ -81,11 +81,11 @@ describe GitlabMarkdownHelper do
|
|||
end
|
||||
|
||||
describe "referencing a team member" do
|
||||
let(:actual) { "@#{user.name} you are right." }
|
||||
let(:actual) { "@#{user.username} you are right." }
|
||||
let(:expected) { project_team_member_path(project, member) }
|
||||
|
||||
before do
|
||||
project.users << user
|
||||
project.add_access(user, :admin)
|
||||
end
|
||||
|
||||
it "should link using a simple name" do
|
||||
|
@ -103,18 +103,18 @@ describe GitlabMarkdownHelper do
|
|||
end
|
||||
|
||||
it "should link with adjacent text" do
|
||||
actual = "Mail the admin (@gfm)"
|
||||
actual = "Mail the admin (@#{user.username})"
|
||||
gfm(actual).should match(expected)
|
||||
end
|
||||
|
||||
it "should keep whitespace intact" do
|
||||
actual = "Yes, @#{user.name} is right."
|
||||
expected = /Yes, <a.+>@#{user.name}<\/a> is right/
|
||||
actual = "Yes, @#{user.username} is right."
|
||||
expected = /Yes, <a.+>@#{user.username}<\/a> is right/
|
||||
gfm(actual).should match(expected)
|
||||
end
|
||||
|
||||
it "should not link with an invalid id" do
|
||||
actual = expected = "@#{user.name.reverse} you are right."
|
||||
actual = expected = "@#{user.username.reverse} you are right."
|
||||
gfm(actual).should == expected
|
||||
end
|
||||
|
||||
|
@ -314,12 +314,12 @@ describe GitlabMarkdownHelper do
|
|||
end
|
||||
|
||||
it "should handle references in lists" do
|
||||
project.users << user
|
||||
project.add_access(user, :admin)
|
||||
|
||||
actual = "\n* dark: ##{issue.id}\n* light by @#{member.user_name}"
|
||||
actual = "\n* dark: ##{issue.id}\n* light by @#{member.user.username}"
|
||||
|
||||
markdown(actual).should match(%r{<li>dark: <a.+>##{issue.id}</a></li>})
|
||||
markdown(actual).should match(%r{<li>light by <a.+>@#{member.user_name}</a></li>})
|
||||
markdown(actual).should match(%r{<li>light by <a.+>@#{member.user.username}</a></li>})
|
||||
end
|
||||
|
||||
it "should handle references in <em>" do
|
||||
|
@ -331,9 +331,9 @@ describe GitlabMarkdownHelper do
|
|||
it "should leave code blocks untouched" do
|
||||
helper.stub(:user_color_scheme_class).and_return(:white)
|
||||
|
||||
helper.markdown("\n some code from $#{snippet.id}\n here too\n").should == "<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>"
|
||||
helper.markdown("\n some code from $#{snippet.id}\n here too\n").should include("<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>")
|
||||
|
||||
helper.markdown("\n```\nsome code from $#{snippet.id}\nhere too\n```\n").should == "<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>"
|
||||
helper.markdown("\n```\nsome code from $#{snippet.id}\nhere too\n```\n").should include("<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>")
|
||||
end
|
||||
|
||||
it "should leave inline code untouched" do
|
||||
|
|
|
@ -16,7 +16,7 @@ describe Gitlab::Gitolite do
|
|||
it { should respond_to :create_repository }
|
||||
it { should respond_to :remove_repository }
|
||||
|
||||
it { gitolite.url_to_repo('diaspora').should == Gitlab.config.ssh_path + "diaspora.git" }
|
||||
it { gitolite.url_to_repo('diaspora').should == Gitlab.config.gitolite.ssh_path_prefix + "diaspora.git" }
|
||||
|
||||
it "should call config update" do
|
||||
gitolite_config.should_receive(:update_project!)
|
||||
|
|
|
@ -6,7 +6,7 @@ describe Gitlab::ProjectMover do
|
|||
before do
|
||||
FileUtils.rm_rf base_path if File.exists? base_path
|
||||
|
||||
Gitlab.config.stub(git_base_path: base_path)
|
||||
Gitlab.config.gitolite.stub(repos_path: base_path)
|
||||
|
||||
@project = create(:project)
|
||||
end
|
||||
|
|
|
@ -59,7 +59,7 @@ describe Event do
|
|||
end
|
||||
|
||||
it { @event.push?.should be_true }
|
||||
it { @event.allowed?.should be_true }
|
||||
it { @event.proper?.should be_true }
|
||||
it { @event.new_branch?.should be_true }
|
||||
it { @event.tag?.should be_false }
|
||||
it { @event.branch_name.should == "master" }
|
||||
|
|
|
@ -42,7 +42,7 @@ describe MergeRequest do
|
|||
|
||||
before do
|
||||
merge_request.stub(:commits) { [merge_request.project.commit] }
|
||||
create(:note, noteable: merge_request.commits.first)
|
||||
create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit')
|
||||
create(:note, noteable: merge_request)
|
||||
end
|
||||
|
||||
|
|
|
@ -80,13 +80,13 @@ describe Note do
|
|||
let!(:commit) { note.noteable }
|
||||
|
||||
it "should be accessible through #noteable" do
|
||||
note.noteable_id.should == commit.id
|
||||
note.commit_id.should == commit.id
|
||||
note.noteable.should be_a(Commit)
|
||||
note.noteable.should == commit
|
||||
end
|
||||
|
||||
it "should save a valid note" do
|
||||
note.noteable_id.should == commit.id
|
||||
note.commit_id.should == commit.id
|
||||
note.noteable == commit
|
||||
end
|
||||
|
||||
|
@ -104,7 +104,7 @@ describe Note do
|
|||
let!(:commit) { note.noteable }
|
||||
|
||||
it "should save a valid note" do
|
||||
note.noteable_id.should == commit.id
|
||||
note.commit_id.should == commit.id
|
||||
note.noteable.id.should == commit.id
|
||||
end
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ describe Project, "Hooks" do
|
|||
it { should include(id: @commit.id) }
|
||||
it { should include(message: @commit.safe_message) }
|
||||
it { should include(timestamp: @commit.date.xmlschema) }
|
||||
it { should include(url: "#{Gitlab.config.url}/#{project.code}/commits/#{@commit.id}") }
|
||||
it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
|
||||
|
||||
context "with a author" do
|
||||
subject { @data[:commits].first[:author] }
|
||||
|
|
|
@ -4,38 +4,109 @@ describe Project do
|
|||
describe :authorization do
|
||||
before do
|
||||
@p1 = create(:project)
|
||||
|
||||
@u1 = create(:user)
|
||||
@u2 = create(:user)
|
||||
@u3 = create(:user)
|
||||
@u4 = @p1.chief
|
||||
|
||||
@abilities = Six.new
|
||||
@abilities << Ability
|
||||
end
|
||||
|
||||
describe "read access" do
|
||||
let(:guest_actions) { Ability.project_guest_rules }
|
||||
let(:report_actions) { Ability.project_report_rules }
|
||||
let(:dev_actions) { Ability.project_dev_rules }
|
||||
let(:master_actions) { Ability.project_master_rules }
|
||||
let(:admin_actions) { Ability.project_admin_rules }
|
||||
|
||||
describe "Non member rules" do
|
||||
it "should deny for non-project users any actions" do
|
||||
admin_actions.each do |action|
|
||||
@abilities.allowed?(@u1, action, @p1).should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Guest Rules" do
|
||||
before do
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::GUEST)
|
||||
end
|
||||
|
||||
it "should allow for project user any guest actions" do
|
||||
guest_actions.each do |action|
|
||||
@abilities.allowed?(@u2, action, @p1).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Report Rules" do
|
||||
before do
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::REPORTER)
|
||||
end
|
||||
|
||||
it { @abilities.allowed?(@u1, :read_project, @p1).should be_false }
|
||||
it { @abilities.allowed?(@u2, :read_project, @p1).should be_true }
|
||||
it "should allow for project user any report actions" do
|
||||
report_actions.each do |action|
|
||||
@abilities.allowed?(@u2, action, @p1).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "write access" do
|
||||
describe "Developer Rules" do
|
||||
before do
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::REPORTER)
|
||||
@p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::DEVELOPER)
|
||||
end
|
||||
|
||||
it "should deny for developer master-specific actions" do
|
||||
[dev_actions - report_actions].each do |action|
|
||||
@abilities.allowed?(@u2, action, @p1).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "should allow for project user any dev actions" do
|
||||
dev_actions.each do |action|
|
||||
@abilities.allowed?(@u3, action, @p1).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Master Rules" do
|
||||
before do
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::DEVELOPER)
|
||||
@p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::MASTER)
|
||||
end
|
||||
|
||||
it { @abilities.allowed?(@u1, :write_project, @p1).should be_false }
|
||||
it { @abilities.allowed?(@u2, :write_project, @p1).should be_true }
|
||||
it "should deny for developer master-specific actions" do
|
||||
[master_actions - dev_actions].each do |action|
|
||||
@abilities.allowed?(@u2, action, @p1).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "should allow for project user any master actions" do
|
||||
master_actions.each do |action|
|
||||
@abilities.allowed?(@u3, action, @p1).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "admin access" do
|
||||
describe "Admin Rules" do
|
||||
before do
|
||||
@p1.users_projects.create(project: @p1, user: @u1, project_access: UsersProject::DEVELOPER)
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::MASTER)
|
||||
@p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::DEVELOPER)
|
||||
@p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::MASTER)
|
||||
end
|
||||
|
||||
it { @abilities.allowed?(@u1, :admin_project, @p1).should be_false }
|
||||
it { @abilities.allowed?(@u2, :admin_project, @p1).should be_true }
|
||||
it "should deny for masters admin-specific actions" do
|
||||
[admin_actions - master_actions].each do |action|
|
||||
@abilities.allowed?(@u2, action, @p1).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "should allow for project owner any admin actions" do
|
||||
admin_actions.each do |action|
|
||||
@abilities.allowed?(@u4, action, @p1).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -129,6 +129,13 @@ describe Project do
|
|||
it { should respond_to(:execute_hooks) }
|
||||
it { should respond_to(:post_receive_data) }
|
||||
it { should respond_to(:trigger_post_receive) }
|
||||
|
||||
# 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) }
|
||||
end
|
||||
|
||||
describe 'modules' do
|
||||
|
@ -136,11 +143,12 @@ describe Project do
|
|||
it { should include_module(PushObserver) }
|
||||
it { should include_module(Authority) }
|
||||
it { should include_module(Team) }
|
||||
it { should include_module(NamespacedProject) }
|
||||
end
|
||||
|
||||
it "should return valid url to repo" do
|
||||
project = Project.new(path: "somewhere")
|
||||
project.url_to_repo.should == Gitlab.config.ssh_path + "somewhere.git"
|
||||
project.url_to_repo.should == Gitlab.config.gitolite.ssh_path_prefix + "somewhere.git"
|
||||
end
|
||||
|
||||
it "should return path to repo" do
|
||||
|
@ -150,19 +158,7 @@ describe Project do
|
|||
|
||||
it "returns the full web URL for this repo" do
|
||||
project = Project.new(path: "somewhere")
|
||||
project.web_url.should == "#{Gitlab.config.url}/somewhere"
|
||||
end
|
||||
|
||||
describe :valid_repo? do
|
||||
it "should be valid repo" do
|
||||
project = create(:project)
|
||||
project.valid_repo?.should be_true
|
||||
end
|
||||
|
||||
it "should be invalid repo" do
|
||||
project = Project.new(name: "ok_name", path: "/INVALID_PATH/", path: "NEOK")
|
||||
project.valid_repo?.should be_false
|
||||
end
|
||||
project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
|
||||
end
|
||||
|
||||
describe "last_activity methods" do
|
||||
|
@ -188,85 +184,6 @@ describe Project do
|
|||
end
|
||||
end
|
||||
|
||||
describe "fresh commits" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
it { project.fresh_commits(3).count.should == 3 }
|
||||
it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
|
||||
it { project.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
|
||||
end
|
||||
|
||||
describe "commits_between" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
subject do
|
||||
commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
|
||||
"8470d70da67355c9c009e4401746b1d5410af2e3")
|
||||
commits.map { |c| c.id }
|
||||
end
|
||||
|
||||
it { should have(3).elements }
|
||||
it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
|
||||
it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
|
||||
end
|
||||
|
||||
describe "Git methods" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
describe :repo do
|
||||
it "should return valid repo" do
|
||||
project.repo.should be_kind_of(Grit::Repo)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
lambda { Project.new.repo }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :commit do
|
||||
it "should return first head commit if without params" do
|
||||
project.commit.id.should == project.repo.commits.first.id
|
||||
end
|
||||
|
||||
it "should return valid commit" do
|
||||
project.commit(ValidCommit::ID).should be_valid_commit
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
project.commit("+123_4532530XYZ").should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :tree do
|
||||
before do
|
||||
@commit = project.commit(ValidCommit::ID)
|
||||
end
|
||||
|
||||
it "should raise error w/o arguments" do
|
||||
lambda { project.tree }.should raise_error
|
||||
end
|
||||
|
||||
it "should return root tree for commit" do
|
||||
tree = project.tree(@commit)
|
||||
tree.contents.size.should == ValidCommit::FILES_COUNT
|
||||
tree.contents.map(&:name).should == ValidCommit::FILES
|
||||
end
|
||||
|
||||
it "should return root tree for commit with correct path" do
|
||||
tree = project.tree(@commit, ValidCommit::C_FILE_PATH)
|
||||
tree.contents.map(&:name).should == ValidCommit::C_FILES
|
||||
end
|
||||
|
||||
it "should return root tree for commit with incorrect path" do
|
||||
project.tree(@commit, "invalid_path").should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :update_merge_requests do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ describe SystemHook do
|
|||
user = create(:user)
|
||||
project = create(:project)
|
||||
with_resque do
|
||||
project.users << user
|
||||
project.add_access(user, :admin)
|
||||
end
|
||||
WebMock.should have_requested(:post, @system_hook.url).with(body: /user_add_to_team/).once
|
||||
end
|
||||
|
@ -64,7 +64,7 @@ describe SystemHook do
|
|||
it "project_destroy hook" do
|
||||
user = create(:user)
|
||||
project = create(:project)
|
||||
project.users << user
|
||||
project.add_access(user, :admin)
|
||||
with_resque do
|
||||
project.users_projects.clear
|
||||
end
|
||||
|
|
|
@ -41,7 +41,6 @@ describe User do
|
|||
it { should have_many(:users_projects).dependent(:destroy) }
|
||||
it { should have_many(:projects) }
|
||||
it { should have_many(:groups) }
|
||||
it { should have_many(:my_own_projects).class_name('Project') }
|
||||
it { should have_many(:keys).dependent(:destroy) }
|
||||
it { should have_many(:events).class_name('Event').dependent(:destroy) }
|
||||
it { should have_many(:recent_events).class_name('Event') }
|
||||
|
@ -67,6 +66,10 @@ describe User do
|
|||
it { should ensure_length_of(:bio).is_within(0..255) }
|
||||
end
|
||||
|
||||
describe 'modules' do
|
||||
it { should include_module(Account) }
|
||||
end
|
||||
|
||||
describe "Respond to" do
|
||||
it { should respond_to(:is_admin?) }
|
||||
it { should respond_to(:identifier) }
|
||||
|
|
|
@ -29,6 +29,7 @@ describe UsersProject do
|
|||
it { should validate_uniqueness_of(:user_id).scoped_to(:project_id).with_message(/already exists/) }
|
||||
|
||||
it { should validate_presence_of(:project) }
|
||||
it { should ensure_inclusion_of(:project_access).in_array(UsersProject.access_roles.values) }
|
||||
end
|
||||
|
||||
describe "Delegate methods" do
|
||||
|
|
|
@ -34,15 +34,17 @@ describe ActivityObserver do
|
|||
it { @event.target.should == @issue }
|
||||
end
|
||||
|
||||
#describe "Issue commented" do
|
||||
#before do
|
||||
#@issue = create(:issue, project: project)
|
||||
#@note = create(:note, noteable: @issue, project: project)
|
||||
#@event = Event.last
|
||||
#end
|
||||
describe "Issue commented" do
|
||||
before do
|
||||
Note.observers.enable :activity_observer do
|
||||
@issue = create(:issue, project: project)
|
||||
@note = create(:note, noteable: @issue, project: project, author: @issue.author)
|
||||
@event = Event.last
|
||||
end
|
||||
end
|
||||
|
||||
#it_should_be_valid_event
|
||||
#it { @event.action.should == Event::Commented }
|
||||
#it { @event.target.should == @note }
|
||||
#end
|
||||
it_should_be_valid_event
|
||||
it { @event.action.should == Event::Commented }
|
||||
it { @event.target.should == @note }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -85,7 +85,7 @@ describe IssueObserver do
|
|||
|
||||
it 'notification is delivered if the issue being closed' do
|
||||
issue.stub(:is_being_closed?).and_return(true)
|
||||
Notify.should_receive(:issue_status_changed_email).twice
|
||||
Notify.should_receive(:issue_status_changed_email).twice.and_return(stub(deliver: true))
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue)
|
||||
|
@ -104,7 +104,7 @@ describe IssueObserver do
|
|||
issue_without_assignee.stub(:is_being_reassigned?).and_return(false)
|
||||
issue_without_assignee.stub(:is_being_closed?).and_return(true)
|
||||
issue_without_assignee.stub(:is_being_reopened?).and_return(false)
|
||||
Notify.should_receive(:issue_status_changed_email).once
|
||||
Notify.should_receive(:issue_status_changed_email).once.and_return(stub(deliver: true))
|
||||
Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue_without_assignee)
|
||||
|
@ -128,7 +128,7 @@ describe IssueObserver do
|
|||
|
||||
it 'notification is delivered if the issue being reopened' do
|
||||
issue.stub(:is_being_reopened?).and_return(true)
|
||||
Notify.should_receive(:issue_status_changed_email).twice
|
||||
Notify.should_receive(:issue_status_changed_email).twice.and_return(stub(deliver: true))
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue)
|
||||
|
@ -147,7 +147,7 @@ describe IssueObserver do
|
|||
issue_without_assignee.stub(:is_being_reassigned?).and_return(false)
|
||||
issue_without_assignee.stub(:is_being_closed?).and_return(false)
|
||||
issue_without_assignee.stub(:is_being_reopened?).and_return(true)
|
||||
Notify.should_receive(:issue_status_changed_email).once
|
||||
Notify.should_receive(:issue_status_changed_email).once.and_return(stub(deliver: true))
|
||||
Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue_without_assignee)
|
||||
|
|
|
@ -117,6 +117,14 @@ describe Gitlab::API do
|
|||
json_response.count.should == 2
|
||||
json_response.first['email'].should == user.email
|
||||
end
|
||||
|
||||
it "finds team members with query string" do
|
||||
get api("/projects/#{project.path}/members", user), query: user.username
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.count.should == 1
|
||||
json_response.first['email'].should == user.email
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/members/:user_id" do
|
||||
|
|
|
@ -6,7 +6,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
let(:merge_request) { create(:merge_request, project: project) }
|
||||
let(:fred) do
|
||||
u = create(:user, name: "fred")
|
||||
project.users << u
|
||||
project.add_access(u, :admin)
|
||||
u
|
||||
end
|
||||
|
||||
|
@ -19,7 +19,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
@test_file = "gfm_test_file"
|
||||
i.add(@test_file, "foo\nbar\n")
|
||||
# add commit with gfm
|
||||
i.commit("fix ##{issue.id}\n\nask @#{fred.name} for details", head: @branch_name)
|
||||
i.commit("fix ##{issue.id}\n\nask @#{fred.username} for details", head: @branch_name)
|
||||
|
||||
# add test tag
|
||||
@tag_name = "gfm-test-tag"
|
||||
|
@ -56,7 +56,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
it "should render description in commits#show" do
|
||||
visit project_commit_path(project, commit)
|
||||
|
||||
page.should have_link("@#{fred.name}")
|
||||
page.should have_link("@#{fred.username}")
|
||||
end
|
||||
|
||||
it "should render title in refs#tree", js: true do
|
||||
|
@ -93,7 +93,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
assignee: @user,
|
||||
project: project,
|
||||
title: "fix ##{@other_issue.id}",
|
||||
description: "ask @#{fred.name} for details")
|
||||
description: "ask @#{fred.username} for details")
|
||||
end
|
||||
|
||||
it "should render subject in issues#index" do
|
||||
|
@ -111,7 +111,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
it "should render details in issues#show" do
|
||||
visit project_issue_path(project, @issue)
|
||||
|
||||
page.should have_link("@#{fred.name}")
|
||||
page.should have_link("@#{fred.username}")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -142,7 +142,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
@milestone = create(:milestone,
|
||||
project: project,
|
||||
title: "fix ##{issue.id}",
|
||||
description: "ask @#{fred.name} for details")
|
||||
description: "ask @#{fred.username} for details")
|
||||
end
|
||||
|
||||
it "should render title in milestones#index" do
|
||||
|
@ -160,7 +160,7 @@ describe "Gitlab Flavored Markdown" do
|
|||
it "should render description in milestones#show" do
|
||||
visit project_milestone_path(project, @milestone)
|
||||
|
||||
page.should have_link("@#{fred.name}")
|
||||
page.should have_link("@#{fred.username}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ describe "Issues" do
|
|||
project.add_access(user2, :read, :write)
|
||||
end
|
||||
|
||||
describe "Edit issue", js: true do
|
||||
describe "Edit issue" do
|
||||
let!(:issue) do
|
||||
create(:issue,
|
||||
author: @user,
|
||||
|
@ -91,13 +91,13 @@ describe "Issues" do
|
|||
title: title)
|
||||
end
|
||||
|
||||
issue = Issue.first # with title 'foobar'
|
||||
issue.milestone = create(:milestone, project: project)
|
||||
issue.assignee = nil
|
||||
issue.save
|
||||
@issue = Issue.first # with title 'foobar'
|
||||
@issue.milestone = create(:milestone, project: project)
|
||||
@issue.assignee = nil
|
||||
@issue.save
|
||||
end
|
||||
|
||||
let(:issue) { Issue.first }
|
||||
let(:issue) { @issue }
|
||||
|
||||
it "should allow filtering by issues with no specified milestone" do
|
||||
visit project_issues_path(project, milestone_id: '0')
|
||||
|
|
|
@ -58,7 +58,7 @@ describe "Projects" do
|
|||
|
||||
describe "DELETE /projects/:id" do
|
||||
before do
|
||||
@project = create(:project)
|
||||
@project = create(:project, owner: @user)
|
||||
@project.add_access(@user, :read, :admin)
|
||||
visit edit_project_path(@project)
|
||||
end
|
||||
|
|
|
@ -48,11 +48,11 @@ describe "Snippets" do
|
|||
page.current_path.should == new_project_snippet_path(project)
|
||||
end
|
||||
|
||||
describe "fill in" do
|
||||
describe "fill in", js: true do
|
||||
before do
|
||||
fill_in "snippet_title", with: "login function"
|
||||
fill_in "snippet_file_name", with: "test.rb"
|
||||
fill_in "snippet_content", with: "def login; end"
|
||||
page.execute_script("editor.insert('def login; end');")
|
||||
end
|
||||
|
||||
it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }
|
||||
|
@ -83,7 +83,6 @@ describe "Snippets" do
|
|||
before do
|
||||
fill_in "snippet_title", with: "login function"
|
||||
fill_in "snippet_file_name", with: "test.rb"
|
||||
fill_in "snippet_content", with: "def login; end"
|
||||
end
|
||||
|
||||
it { expect { click_button "Save" }.to_not change {Snippet.count} }
|
||||
|
|
44
spec/roles/account_role_spec.rb
Normal file
44
spec/roles/account_role_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe User, "Account" do
|
||||
describe 'normal user' do
|
||||
let(:user) { create(:user, name: 'John Smith') }
|
||||
|
||||
it { user.is_admin?.should be_false }
|
||||
it { user.require_ssh_key?.should be_true }
|
||||
it { user.can_create_group?.should be_false }
|
||||
it { user.can_create_project?.should be_true }
|
||||
it { user.first_name.should == 'John' }
|
||||
end
|
||||
|
||||
describe 'blocking user' do
|
||||
let(:user) { create(:user, name: 'John Smith') }
|
||||
|
||||
it "should block user" do
|
||||
user.block
|
||||
user.blocked.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'projects' do
|
||||
before do
|
||||
ActiveRecord::Base.observers.enable(:user_observer)
|
||||
@user = create :user
|
||||
@project = create :project, namespace: @user.namespace
|
||||
end
|
||||
|
||||
it { @user.authorized_projects.should include(@project) }
|
||||
it { @user.my_own_projects.should include(@project) }
|
||||
end
|
||||
|
||||
describe 'namespaced' do
|
||||
before do
|
||||
ActiveRecord::Base.observers.enable(:user_observer)
|
||||
@user = create :user
|
||||
@project = create :project, namespace: @user.namespace
|
||||
end
|
||||
|
||||
it { @user.several_namespaces?.should be_false }
|
||||
it { @user.namespaces.should == [@user.namespace] }
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Project, "Repository" do
|
||||
let(:project) { build(:project) }
|
||||
let(:project) { create(:project) }
|
||||
|
||||
describe "#empty_repo?" do
|
||||
it "should return true if the repo doesn't exist" do
|
||||
|
@ -69,4 +69,91 @@ describe Project, "Repository" do
|
|||
project.root_ref?('stable').should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe :repo do
|
||||
it "should return valid repo" do
|
||||
project.repo.should be_kind_of(Grit::Repo)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
lambda { Project.new.repo }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :commit do
|
||||
it "should return first head commit if without params" do
|
||||
project.commit.id.should == project.repo.commits.first.id
|
||||
end
|
||||
|
||||
it "should return valid commit" do
|
||||
project.commit(ValidCommit::ID).should be_valid_commit
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
project.commit("+123_4532530XYZ").should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :tree do
|
||||
before do
|
||||
@commit = project.commit(ValidCommit::ID)
|
||||
end
|
||||
|
||||
it "should raise error w/o arguments" do
|
||||
lambda { project.tree }.should raise_error
|
||||
end
|
||||
|
||||
it "should return root tree for commit" do
|
||||
tree = project.tree(@commit)
|
||||
tree.contents.size.should == ValidCommit::FILES_COUNT
|
||||
tree.contents.map(&:name).should == ValidCommit::FILES
|
||||
end
|
||||
|
||||
it "should return root tree for commit with correct path" do
|
||||
tree = project.tree(@commit, ValidCommit::C_FILE_PATH)
|
||||
tree.contents.map(&:name).should == ValidCommit::C_FILES
|
||||
end
|
||||
|
||||
it "should return root tree for commit with incorrect path" do
|
||||
project.tree(@commit, "invalid_path").should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "fresh commits" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
it { project.fresh_commits(3).count.should == 3 }
|
||||
it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
|
||||
it { project.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
|
||||
end
|
||||
|
||||
describe "commits_between" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
subject do
|
||||
commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
|
||||
"8470d70da67355c9c009e4401746b1d5410af2e3")
|
||||
commits.map { |c| c.id }
|
||||
end
|
||||
|
||||
it { should have(3).elements }
|
||||
it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
|
||||
it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
|
||||
end
|
||||
|
||||
describe :valid_repo? do
|
||||
it "should be valid repo" do
|
||||
project = create(:project)
|
||||
project.valid_repo?.should be_true
|
||||
end
|
||||
|
||||
it "should be invalid repo" do
|
||||
project = Project.new(name: "ok_name", path: "/INVALID_PATH/", path: "NEOK")
|
||||
project.valid_repo?.should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -245,6 +245,7 @@ describe MergeRequestsController, "routing" do
|
|||
|
||||
it_behaves_like "RESTful project resources" do
|
||||
let(:controller) { 'merge_requests' }
|
||||
let(:actions) { [:index, :create, :new, :edit, :show, :update] }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -325,6 +326,7 @@ end
|
|||
describe MilestonesController, "routing" do
|
||||
it_behaves_like "RESTful project resources" do
|
||||
let(:controller) { 'milestones' }
|
||||
let(:actions) { [:index, :create, :new, :edit, :show, :update] }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -360,6 +362,7 @@ describe IssuesController, "routing" do
|
|||
|
||||
it_behaves_like "RESTful project resources" do
|
||||
let(:controller) { 'issues' }
|
||||
let(:actions) { [:index, :create, :new, :edit, :show, :update] }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ end
|
|||
# help_system_hooks GET /help/system_hooks(.:format) help#system_hooks
|
||||
# help_markdown GET /help/markdown(.:format) help#markdown
|
||||
# help_ssh GET /help/ssh(.:format) help#ssh
|
||||
# help_raketasks GET /help/raketasks(.:format) help#raketasks
|
||||
describe HelpController, "routing" do
|
||||
it "to #index" do
|
||||
get("/help").should route_to('help#index')
|
||||
|
@ -65,6 +66,10 @@ describe HelpController, "routing" do
|
|||
it "to #ssh" do
|
||||
get("/help/ssh").should route_to('help#ssh')
|
||||
end
|
||||
|
||||
it "to #raketasks" do
|
||||
get("/help/raketasks").should route_to('help#raketasks')
|
||||
end
|
||||
end
|
||||
|
||||
# errors_githost GET /errors/githost(.:format) errors#githost
|
||||
|
|
|
@ -42,8 +42,8 @@ RSpec.configure do |config|
|
|||
# ActiveRecord::Base.observers.enable(:all)
|
||||
|
||||
# Use tmp dir for FS manipulations
|
||||
Gitlab.config.stub(git_base_path: Rails.root.join('tmp', 'test-git-base-path'))
|
||||
FileUtils.rm_rf Gitlab.config.git_base_path
|
||||
FileUtils.mkdir_p Gitlab.config.git_base_path
|
||||
Gitlab.config.gitolite.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
|
||||
FileUtils.rm_rf Gitlab.config.gitolite.repos_path
|
||||
FileUtils.mkdir_p Gitlab.config.gitolite.repos_path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,8 +15,8 @@ describe 'gitlab:app namespace rake task' do
|
|||
end
|
||||
|
||||
let :run_rake_task do
|
||||
Rake::Task["gitlab:app:backup_restore"].reenable
|
||||
Rake.application.invoke_task "gitlab:app:backup_restore"
|
||||
Rake::Task["gitlab:backup:restore"].reenable
|
||||
Rake.application.invoke_task "gitlab:backup:restore"
|
||||
end
|
||||
|
||||
context 'gitlab version' do
|
||||
|
@ -36,8 +36,8 @@ describe 'gitlab:app namespace rake task' do
|
|||
|
||||
it 'should invoke restoration on mach' do
|
||||
YAML.stub :load_file => {:gitlab_version => gitlab_version}
|
||||
Rake::Task["gitlab:app:db_restore"].should_receive :invoke
|
||||
Rake::Task["gitlab:app:repo_restore"].should_receive :invoke
|
||||
Rake::Task["gitlab:backup:db:restore"].should_receive :invoke
|
||||
Rake::Task["gitlab:backup:repo:restore"].should_receive :invoke
|
||||
expect { run_rake_task }.to_not raise_error SystemExit
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,8 +14,8 @@ describe PostReceive do
|
|||
let(:key_id) { key.identifier }
|
||||
|
||||
it "fetches the correct project" do
|
||||
Project.should_receive(:find_by_path).with(project.path).and_return(project)
|
||||
PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
||||
Project.should_receive(:find_with_namespace).with(project.path_with_namespace).and_return(project)
|
||||
PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
||||
end
|
||||
|
||||
it "does not run if the author is not in the project" do
|
||||
|
@ -24,17 +24,21 @@ describe PostReceive do
|
|||
project.should_not_receive(:observe_push)
|
||||
project.should_not_receive(:execute_hooks)
|
||||
|
||||
PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
|
||||
PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
|
||||
end
|
||||
|
||||
it "asks the project to trigger all hooks" do
|
||||
Project.stub(find_by_path: project)
|
||||
Project.stub(find_with_namespace: project)
|
||||
project.should_receive(:execute_hooks)
|
||||
project.should_receive(:execute_services)
|
||||
project.should_receive(:update_merge_requests)
|
||||
project.should_receive(:observe_push)
|
||||
|
||||
PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
||||
PostReceive.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pwd(project)
|
||||
File.join(Gitlab.config.gitolite.repos_path, project.path_with_namespace)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue