Non-interactive AWS install by running a single script.
Merge branch 'master' into non-interactive-aws-install Conflicts: doc/installation.md Fix merge mess in installation.md
This commit is contained in:
parent
eae41ad1df
commit
b80dd3d242
215 changed files with 3829 additions and 3348 deletions
|
@ -1,92 +1,130 @@
|
|||
require File.join(Rails.root, 'spec', 'factory')
|
||||
|
||||
Factory.add(:project, Project) do |obj|
|
||||
obj.name = Faker::Internet.user_name
|
||||
obj.path = 'gitlabhq'
|
||||
obj.owner = Factory(:user)
|
||||
obj.code = 'LGT'
|
||||
# Backwards compatibility with the old method
|
||||
def Factory(type, *args)
|
||||
FactoryGirl.create(type, *args)
|
||||
end
|
||||
|
||||
Factory.add(:project_without_owner, Project) do |obj|
|
||||
obj.name = Faker::Internet.user_name
|
||||
obj.path = 'gitlabhq'
|
||||
obj.code = 'LGT'
|
||||
module Factory
|
||||
def self.create(type, *args)
|
||||
FactoryGirl.create(type, *args)
|
||||
end
|
||||
|
||||
def self.new(type, *args)
|
||||
FactoryGirl.build(type, *args)
|
||||
end
|
||||
end
|
||||
|
||||
Factory.add(:public_project, Project) do |obj|
|
||||
obj.name = Faker::Internet.user_name
|
||||
obj.path = 'gitlabhq'
|
||||
obj.private_flag = false
|
||||
obj.owner = Factory(:user)
|
||||
obj.code = 'LGT'
|
||||
end
|
||||
FactoryGirl.define do
|
||||
sequence :sentence, aliases: [:title, :content] do
|
||||
Faker::Lorem.sentence
|
||||
end
|
||||
|
||||
Factory.add(:user, User) do |obj|
|
||||
obj.email = Faker::Internet.email
|
||||
obj.password = "123456"
|
||||
obj.name = Faker::Name.name
|
||||
obj.password_confirmation = "123456"
|
||||
end
|
||||
sequence :name, aliases: [:file_name] do
|
||||
Faker::Name.name
|
||||
end
|
||||
|
||||
Factory.add(:admin, User) do |obj|
|
||||
obj.email = Faker::Internet.email
|
||||
obj.password = "123456"
|
||||
obj.name = Faker::Name.name
|
||||
obj.password_confirmation = "123456"
|
||||
obj.admin = true
|
||||
end
|
||||
sequence(:url) { Faker::Internet.uri('http') }
|
||||
|
||||
Factory.add(:issue, Issue) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.author = Factory :user
|
||||
obj.assignee = Factory :user
|
||||
end
|
||||
factory :user, aliases: [:author, :assignee, :owner] do
|
||||
email { Faker::Internet.email }
|
||||
name
|
||||
password "123456"
|
||||
password_confirmation "123456"
|
||||
|
||||
Factory.add(:merge_request, MergeRequest) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.author = Factory :user
|
||||
obj.assignee = Factory :user
|
||||
obj.source_branch = "master"
|
||||
obj.target_branch = "stable"
|
||||
obj.closed = false
|
||||
end
|
||||
trait :admin do
|
||||
admin true
|
||||
end
|
||||
|
||||
Factory.add(:snippet, Snippet) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.file_name = Faker::Lorem.sentence
|
||||
obj.content = Faker::Lorem.sentences
|
||||
end
|
||||
factory :admin, traits: [:admin]
|
||||
end
|
||||
|
||||
Factory.add(:note, Note) do |obj|
|
||||
obj.note = Faker::Lorem.sentence
|
||||
end
|
||||
factory :project do
|
||||
sequence(:name) { |n| "project#{n}" }
|
||||
path { name }
|
||||
code { name }
|
||||
owner
|
||||
end
|
||||
|
||||
Factory.add(:key, Key) do |obj|
|
||||
obj.title = "Example key"
|
||||
obj.key = File.read(File.join(Rails.root, "db", "pkey.example"))
|
||||
end
|
||||
factory :users_project do
|
||||
user
|
||||
project
|
||||
end
|
||||
|
||||
Factory.add(:project_hook, ProjectHook) do |obj|
|
||||
obj.url = Faker::Internet.uri("http")
|
||||
end
|
||||
factory :issue do
|
||||
title
|
||||
author
|
||||
project
|
||||
|
||||
Factory.add(:system_hook, SystemHook) do |obj|
|
||||
obj.url = Faker::Internet.uri("http")
|
||||
end
|
||||
trait :closed do
|
||||
closed true
|
||||
end
|
||||
|
||||
Factory.add(:wiki, Wiki) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.content = Faker::Lorem.sentence
|
||||
obj.user = Factory(:user)
|
||||
obj.project = Factory(:project)
|
||||
end
|
||||
factory :closed_issue, traits: [:closed]
|
||||
end
|
||||
|
||||
Factory.add(:event, Event) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.project = Factory(:project)
|
||||
end
|
||||
factory :merge_request do
|
||||
title
|
||||
author
|
||||
project
|
||||
source_branch "master"
|
||||
target_branch "stable"
|
||||
end
|
||||
|
||||
Factory.add(:milestone, Milestone) do |obj|
|
||||
obj.title = Faker::Lorem.sentence
|
||||
obj.due_date = Date.today + 1.month
|
||||
factory :note do
|
||||
project
|
||||
note "Note"
|
||||
end
|
||||
|
||||
factory :event do
|
||||
end
|
||||
|
||||
factory :key do
|
||||
title
|
||||
key do
|
||||
"""
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4
|
||||
596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4
|
||||
soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=
|
||||
"""
|
||||
end
|
||||
|
||||
factory :deploy_key do
|
||||
project
|
||||
end
|
||||
|
||||
factory :personal_key do
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
factory :milestone do
|
||||
title
|
||||
project
|
||||
end
|
||||
|
||||
factory :system_hook do
|
||||
url
|
||||
end
|
||||
|
||||
factory :project_hook do
|
||||
url
|
||||
end
|
||||
|
||||
factory :wiki do
|
||||
title
|
||||
content
|
||||
user
|
||||
end
|
||||
|
||||
factory :snippet do
|
||||
project
|
||||
author
|
||||
title
|
||||
content
|
||||
file_name
|
||||
end
|
||||
|
||||
factory :protected_branch do
|
||||
name
|
||||
project
|
||||
end
|
||||
end
|
||||
|
|
91
spec/factories_spec.rb
Normal file
91
spec/factories_spec.rb
Normal file
|
@ -0,0 +1,91 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Factories" do
|
||||
describe 'User' do
|
||||
it "builds a valid instance" do
|
||||
build(:user).should be_valid
|
||||
end
|
||||
|
||||
it "builds a valid admin instance" do
|
||||
build(:admin).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Project' do
|
||||
it "builds a valid instance" do
|
||||
build(:project).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Issue' do
|
||||
it "builds a valid instance" do
|
||||
build(:issue).should be_valid
|
||||
end
|
||||
|
||||
it "builds a valid closed instance" do
|
||||
build(:closed_issue).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'MergeRequest' do
|
||||
it "builds a valid instance" do
|
||||
build(:merge_request).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Note' do
|
||||
it "builds a valid instance" do
|
||||
build(:note).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Event' do
|
||||
it "builds a valid instance" do
|
||||
build(:event).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Key' do
|
||||
it "builds a valid instance" do
|
||||
build(:key).should be_valid
|
||||
end
|
||||
|
||||
it "builds a valid deploy key instance" do
|
||||
build(:deploy_key).should be_valid
|
||||
end
|
||||
|
||||
it "builds a valid personal key instance" do
|
||||
build(:personal_key).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Milestone' do
|
||||
it "builds a valid instance" do
|
||||
build(:milestone).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'SystemHook' do
|
||||
it "builds a valid instance" do
|
||||
build(:system_hook).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'ProjectHook' do
|
||||
it "builds a valid instance" do
|
||||
build(:project_hook).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Wiki' do
|
||||
it "builds a valid instance" do
|
||||
build(:wiki).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Snippet' do
|
||||
it "builds a valid instance" do
|
||||
build(:snippet).should be_valid
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
class Factory
|
||||
@factories = {}
|
||||
|
||||
class << self
|
||||
def add(name, klass, &block)
|
||||
@factories[name] = [klass, block]
|
||||
end
|
||||
|
||||
def create(name, opts = {})
|
||||
new(name, opts).tap(&:save!)
|
||||
end
|
||||
|
||||
def new(name, opts = {})
|
||||
factory= @factories[name]
|
||||
factory[0].new.tap do |obj|
|
||||
factory[1].call(obj)
|
||||
end.tap do |obj|
|
||||
opts.each do |k, opt|
|
||||
obj.send("#{k}=", opt)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def Factory(name, opts={})
|
||||
Factory.create name, opts
|
||||
end
|
||||
|
26
spec/helpers/application_helper_spec.rb
Normal file
26
spec/helpers/application_helper_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApplicationHelper do
|
||||
describe "gravatar_icon" 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)
|
||||
gravatar_icon(user_email).should == 'no_avatar.png'
|
||||
end
|
||||
|
||||
it "should return a generic avatar path when email is blank" do
|
||||
gravatar_icon('').should == 'no_avatar.png'
|
||||
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 accept a custom size" do
|
||||
stub!(:request).and_return(double(:ssl? => false))
|
||||
gravatar_icon(user_email, 64).should match(/\?s=64/)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ require "spec_helper"
|
|||
|
||||
describe GitlabMarkdownHelper do
|
||||
before do
|
||||
@project = Project.find_by_path("gitlabhq") || Factory(:project)
|
||||
@project = Factory(:project)
|
||||
@commit = @project.repo.commits.first.parents.first
|
||||
@commit = CommitDecorator.decorate(Commit.new(@commit))
|
||||
@other_project = Factory :project, path: "OtherPath", code: "OtherCode"
|
||||
|
@ -157,7 +157,7 @@ describe GitlabMarkdownHelper do
|
|||
gfm("Let @#{user.name} fix the *mess* in #{@commit.id}").should == "Let #{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "} fix the *mess* in #{link_to @commit.id, project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "}"
|
||||
end
|
||||
|
||||
it "should not trip over other stuff", focus: true do
|
||||
it "should not trip over other stuff" do
|
||||
gfm("_Please_ *stop* 'helping' and all the other b*$#%' you do.").should == "_Please_ *stop* 'helping' and all the other b*$#%' you do."
|
||||
end
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ describe Notify do
|
|||
end
|
||||
|
||||
it 'has the correct subject' do
|
||||
should have_subject /Account was created for you/
|
||||
should have_subject /^gitlab \| Account was created for you$/
|
||||
end
|
||||
|
||||
it 'contains the new user\'s login name' do
|
||||
|
@ -60,7 +60,7 @@ describe Notify do
|
|||
it_behaves_like 'an assignee email'
|
||||
|
||||
it 'has the correct subject' do
|
||||
should have_subject /new issue ##{issue.id}/
|
||||
should have_subject /new issue ##{issue.id} \| #{issue.title} \| #{project.name}/
|
||||
end
|
||||
|
||||
it 'contains a link to the new issue' do
|
||||
|
@ -76,7 +76,7 @@ describe Notify do
|
|||
it_behaves_like 'a multiple recipients email'
|
||||
|
||||
it 'has the correct subject' do
|
||||
should have_subject /changed issue/
|
||||
should have_subject /changed issue ##{issue.id} \| #{issue.title}/
|
||||
end
|
||||
|
||||
it 'contains the name of the previous assignee' do
|
||||
|
@ -91,6 +91,29 @@ describe Notify do
|
|||
should have_body_text /#{project_issue_path project, issue}/
|
||||
end
|
||||
end
|
||||
|
||||
describe 'status changed' do
|
||||
let(:current_user) { Factory.create :user, email: "current@email.com" }
|
||||
let(:status) { 'closed' }
|
||||
subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) }
|
||||
|
||||
it 'has the correct subject' do
|
||||
should have_subject /changed issue ##{issue.id} \| #{issue.title}/i
|
||||
end
|
||||
|
||||
it 'contains the new status' do
|
||||
should have_body_text /#{status}/i
|
||||
end
|
||||
|
||||
it 'contains the user name' do
|
||||
should have_body_text /#{current_user.name}/i
|
||||
end
|
||||
|
||||
it 'contains a link to the issue' do
|
||||
should have_body_text /#{project_issue_path project, issue}/
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'for merge requests' do
|
||||
|
@ -145,6 +168,26 @@ describe Notify do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'project access changed' do
|
||||
let(:project) { Factory.create(:project,
|
||||
path: "Fuu",
|
||||
code: "Fuu") }
|
||||
let(:user) { Factory.create :user }
|
||||
let(:users_project) { Factory.create(:users_project,
|
||||
project: project,
|
||||
user: user) }
|
||||
subject { Notify.project_access_granted_email(users_project.id) }
|
||||
it 'has the correct subject' do
|
||||
should have_subject /access to project was granted/
|
||||
end
|
||||
it 'contains name of project' do
|
||||
should have_body_text /#{project.name}/
|
||||
end
|
||||
it 'contains new user role' do
|
||||
should have_body_text /#{users_project.project_access_human}/
|
||||
end
|
||||
end
|
||||
|
||||
context 'items that are noteable, the email for a note' do
|
||||
let(:note_author) { Factory.create(:user, name: 'author_name') }
|
||||
let(:note) { Factory.create(:note, project: project, author: note_author) }
|
||||
|
|
|
@ -1,24 +1,9 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: events
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# target_type :string(255)
|
||||
# target_id :integer(4)
|
||||
# title :string(255)
|
||||
# data :text
|
||||
# project_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# action :integer(4)
|
||||
# author_id :integer(4)
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Event do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:target) }
|
||||
end
|
||||
|
||||
describe "Respond to" do
|
||||
|
@ -29,16 +14,6 @@ describe Event do
|
|||
it { should respond_to(:commits) }
|
||||
end
|
||||
|
||||
describe "Creation" do
|
||||
before do
|
||||
@event = Factory :event
|
||||
end
|
||||
|
||||
it "should create a valid event" do
|
||||
@event.should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "Push event" do
|
||||
before do
|
||||
project = Factory :project
|
||||
|
|
|
@ -2,28 +2,19 @@ require 'spec_helper'
|
|||
|
||||
describe Issue do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:author) }
|
||||
it { should belong_to(:assignee) }
|
||||
it { should belong_to(:milestone) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should validate_presence_of(:author_id) }
|
||||
it { should validate_presence_of(:project_id) }
|
||||
it { should ensure_length_of(:description).is_within(0..2000) }
|
||||
end
|
||||
|
||||
describe "Scope" do
|
||||
it { Issue.should respond_to :closed }
|
||||
it { Issue.should respond_to :opened }
|
||||
describe 'modules' do
|
||||
it { should include_module(IssueCommonality) }
|
||||
it { should include_module(Upvote) }
|
||||
end
|
||||
|
||||
subject { Factory.create(:issue,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: Factory.create(:project)) }
|
||||
it { should be_valid }
|
||||
subject { Factory.create(:issue) }
|
||||
|
||||
describe '#is_being_reassigned?' do
|
||||
it 'returns true if the issue assignee has changed' do
|
||||
|
@ -41,11 +32,7 @@ describe Issue do
|
|||
subject.is_being_closed?.should be_true
|
||||
end
|
||||
it 'returns false if the closed attribute has changed and is now false' do
|
||||
issue = Factory.create(:issue,
|
||||
closed: true,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: Factory.create(:project))
|
||||
issue = Factory.create(:closed_issue)
|
||||
issue.closed = false
|
||||
issue.is_being_closed?.should be_false
|
||||
end
|
||||
|
@ -57,11 +44,7 @@ describe Issue do
|
|||
|
||||
describe '#is_being_reopened?' do
|
||||
it 'returns true if the closed attribute has changed and is now false' do
|
||||
issue = Factory.create(:issue,
|
||||
closed: true,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: Factory.create(:project))
|
||||
issue = Factory.create(:closed_issue)
|
||||
issue.closed = false
|
||||
issue.is_being_reopened?.should be_true
|
||||
end
|
||||
|
@ -73,64 +56,4 @@ describe Issue do
|
|||
subject.is_being_reopened?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe "plus 1" do
|
||||
let(:project) { Factory(:project) }
|
||||
subject {
|
||||
Factory.create(:issue,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: project)
|
||||
}
|
||||
|
||||
it "with no notes has a 0/0 score" do
|
||||
subject.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize non-+1 notes" do
|
||||
subject.notes << Factory(:note, note: "No +1 here", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.should have(1).note
|
||||
subject.notes.first.upvote?.should be_false
|
||||
subject.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize a single +1 note" do
|
||||
subject.notes << Factory(:note, note: "+1 This is awesome", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.upvotes.should == 1
|
||||
end
|
||||
|
||||
it "should recognize a multiple +1 notes" do
|
||||
subject.notes << Factory(:note, note: "+1 This is awesome", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.notes << Factory(:note, note: "+1 I want this", project: Factory(:project, path: 'plustwo', code: 'plustwo'))
|
||||
subject.upvotes.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe ".search" do
|
||||
let!(:issue) { Factory.create(:issue, title: "Searchable issue",
|
||||
project: Factory.create(:project)) }
|
||||
|
||||
it "matches by title" do
|
||||
Issue.search('able').all.should == [issue]
|
||||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: issues
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# title :string(255)
|
||||
# assignee_id :integer(4)
|
||||
# author_id :integer(4)
|
||||
# project_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# closed :boolean(1) default(FALSE), not null
|
||||
# position :integer(4) default(0)
|
||||
# critical :boolean(1) default(FALSE), not null
|
||||
# branch_name :string(255)
|
||||
# description :text
|
||||
# milestone_id :integer(4)
|
||||
#
|
||||
|
||||
|
|
|
@ -2,12 +2,15 @@ require 'spec_helper'
|
|||
|
||||
describe Key do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:user) or belong_to(:project) }
|
||||
it { should belong_to(:user) }
|
||||
it { should belong_to(:project) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should validate_presence_of(:key) }
|
||||
it { should ensure_length_of(:title).is_within(0..255) }
|
||||
it { should ensure_length_of(:key).is_within(0..5000) }
|
||||
end
|
||||
|
||||
describe "Methods" do
|
||||
|
@ -17,20 +20,15 @@ describe Key do
|
|||
context "validation of uniqueness" do
|
||||
|
||||
context "as a deploy key" do
|
||||
let(:project) { Factory.create(:project, path: 'alpha', code: 'alpha') }
|
||||
let(:another_project) { Factory.create(:project, path: 'beta', code: 'beta') }
|
||||
|
||||
before do
|
||||
deploy_key = Factory.create(:key, project: project)
|
||||
end
|
||||
let!(:deploy_key) { create(:deploy_key) }
|
||||
|
||||
it "does not accept the same key twice for a project" do
|
||||
key = Factory.new(:key, project: project)
|
||||
key = build(:key, project: deploy_key.project)
|
||||
key.should_not be_valid
|
||||
end
|
||||
|
||||
it "does accept the same key for another project" do
|
||||
key = Factory.new(:key, project: another_project)
|
||||
key = build(:key, project_id: 0)
|
||||
key.should be_valid
|
||||
end
|
||||
end
|
||||
|
@ -39,27 +37,13 @@ describe Key do
|
|||
let(:user) { Factory.create(:user) }
|
||||
|
||||
it "accepts the key once" do
|
||||
Factory.new(:key, user: user).should be_valid
|
||||
build(:key, user: user).should be_valid
|
||||
end
|
||||
|
||||
it "does not accepts the key twice" do
|
||||
Factory.create(:key, user: user)
|
||||
Factory.new(:key, user: user).should_not be_valid
|
||||
create(:key, user: user)
|
||||
build(:key, user: user).should_not be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: keys
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# user_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# key :text
|
||||
# title :string(255)
|
||||
# identifier :string(255)
|
||||
# project_id :integer(4)
|
||||
#
|
||||
|
||||
|
|
|
@ -1,88 +1,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe MergeRequest do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:author) }
|
||||
it { should belong_to(:assignee) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:target_branch) }
|
||||
it { should validate_presence_of(:source_branch) }
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should validate_presence_of(:author_id) }
|
||||
it { should validate_presence_of(:project_id) }
|
||||
end
|
||||
|
||||
describe "Scope" do
|
||||
it { MergeRequest.should respond_to :closed }
|
||||
it { MergeRequest.should respond_to :opened }
|
||||
end
|
||||
|
||||
it { Factory.create(:merge_request,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: Factory.create(:project)).should be_valid }
|
||||
|
||||
describe "plus 1" do
|
||||
let(:project) { Factory(:project) }
|
||||
subject {
|
||||
Factory.create(:merge_request,
|
||||
author: Factory(:user),
|
||||
assignee: Factory(:user),
|
||||
project: project)
|
||||
}
|
||||
|
||||
it "with no notes has a 0/0 score" do
|
||||
subject.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize non-+1 notes" do
|
||||
subject.notes << Factory(:note, note: "No +1 here", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.should have(1).note
|
||||
subject.notes.first.upvote?.should be_false
|
||||
subject.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize a single +1 note" do
|
||||
subject.notes << Factory(:note, note: "+1 This is awesome", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.upvotes.should == 1
|
||||
end
|
||||
|
||||
it "should recognize a multiple +1 notes" do
|
||||
subject.notes << Factory(:note, note: "+1 This is awesome", project: Factory(:project, path: 'plusone', code: 'plusone'))
|
||||
subject.notes << Factory(:note, note: "+1 I want this", project: Factory(:project, path: 'plustwo', code: 'plustwo'))
|
||||
subject.upvotes.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe ".search" do
|
||||
let!(:issue) { Factory.create(:issue, title: "Searchable issue",
|
||||
project: Factory.create(:project)) }
|
||||
|
||||
it "matches by title" do
|
||||
Issue.search('able').all.should == [issue]
|
||||
end
|
||||
describe 'modules' do
|
||||
it { should include_module(IssueCommonality) }
|
||||
it { should include_module(Upvote) }
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: merge_requests
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# target_branch :string(255) not null
|
||||
# source_branch :string(255) not null
|
||||
# project_id :integer(4) not null
|
||||
# author_id :integer(4)
|
||||
# assignee_id :integer(4)
|
||||
# title :string(255)
|
||||
# closed :boolean(1) default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# st_commits :text(2147483647
|
||||
# st_diffs :text(2147483647
|
||||
# merged :boolean(1) default(FALSE), not null
|
||||
# state :integer(4) default(1), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: milestones
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# title :string(255) not null
|
||||
# project_id :integer(4) not null
|
||||
# description :text
|
||||
# due_date :date
|
||||
# closed :boolean(1) default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Milestone do
|
||||
|
@ -25,30 +11,36 @@ describe Milestone do
|
|||
it { should validate_presence_of(:project_id) }
|
||||
end
|
||||
|
||||
let(:project) { Factory :project }
|
||||
let(:milestone) { Factory :milestone, project: project }
|
||||
let(:issue) { Factory :issue, project: project }
|
||||
let(:milestone) { Factory :milestone }
|
||||
let(:issue) { Factory :issue }
|
||||
|
||||
it { milestone.should be_valid }
|
||||
|
||||
describe "Issues" do
|
||||
before do
|
||||
describe "#percent_complete" do
|
||||
it "should not count open issues" do
|
||||
milestone.issues << issue
|
||||
milestone.percent_complete.should == 0
|
||||
end
|
||||
|
||||
it { milestone.percent_complete.should == 0 }
|
||||
it "should count closed issues" do
|
||||
issue.update_attributes(closed: true)
|
||||
milestone.issues << issue
|
||||
milestone.percent_complete.should == 100
|
||||
end
|
||||
|
||||
it do
|
||||
issue.update_attributes closed: true
|
||||
it "should recover from dividing by zero" do
|
||||
milestone.issues.should_receive(:count).and_return(0)
|
||||
milestone.percent_complete.should == 100
|
||||
end
|
||||
end
|
||||
|
||||
describe :expires_at do
|
||||
before do
|
||||
milestone.update_attributes due_date: Date.today + 1.day
|
||||
describe "#expires_at" do
|
||||
it "should be nil when due_date is unset" do
|
||||
milestone.update_attributes(due_date: nil)
|
||||
milestone.expires_at.should be_nil
|
||||
end
|
||||
|
||||
it { milestone.expires_at.should_not be_nil }
|
||||
it "should not be nil when due_date is set" do
|
||||
milestone.update_attributes(due_date: Date.tomorrow)
|
||||
milestone.expires_at.should be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Note do
|
||||
let(:project) { Factory :project }
|
||||
let!(:commit) { project.commit }
|
||||
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:noteable) }
|
||||
it { should belong_to(:author).class_name('User') }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
|
@ -13,8 +12,6 @@ describe Note do
|
|||
it { should validate_presence_of(:project) }
|
||||
end
|
||||
|
||||
it { Factory.create(:note,
|
||||
project: project).should be_valid }
|
||||
describe "Scopes" do
|
||||
it "should have a today named scope that returns ..." do
|
||||
Note.today.where_values.should == ["created_at >= '#{Date.today}'"]
|
||||
|
@ -25,26 +22,27 @@ describe Note do
|
|||
let(:project) { Factory(:project) }
|
||||
|
||||
it "recognizes a neutral note" do
|
||||
note = Factory(:note, project: project, note: "This is not a +1 note")
|
||||
note = Factory(:note, note: "This is not a +1 note")
|
||||
note.should_not be_upvote
|
||||
end
|
||||
|
||||
it "recognizes a +1 note" do
|
||||
note = Factory(:note, project: project, note: "+1 for this")
|
||||
note = Factory(:note, note: "+1 for this")
|
||||
note.should be_upvote
|
||||
end
|
||||
|
||||
it "recognizes a -1 note as no vote" do
|
||||
note = Factory(:note, project: project, note: "-1 for this")
|
||||
note = Factory(:note, note: "-1 for this")
|
||||
note.should_not be_upvote
|
||||
end
|
||||
end
|
||||
|
||||
describe "Commit notes" do
|
||||
let(:project) { create(:project) }
|
||||
let(:commit) { project.commit }
|
||||
|
||||
describe "Commit notes" do
|
||||
before do
|
||||
@note = Factory :note,
|
||||
project: project,
|
||||
noteable_id: commit.id,
|
||||
noteable_type: "Commit"
|
||||
end
|
||||
|
@ -58,7 +56,6 @@ describe Note do
|
|||
describe "Pre-line commit notes" do
|
||||
before do
|
||||
@note = Factory :note,
|
||||
project: project,
|
||||
noteable_id: commit.id,
|
||||
noteable_type: "Commit",
|
||||
line_code: "0_16_1"
|
||||
|
@ -91,8 +88,8 @@ describe Note do
|
|||
|
||||
describe :authorization do
|
||||
before do
|
||||
@p1 = project
|
||||
@p2 = Factory :project, code: "alien", path: "gitlabhq_1"
|
||||
@p1 = create(:project)
|
||||
@p2 = Factory :project
|
||||
@u1 = Factory :user
|
||||
@u2 = Factory :user
|
||||
@u3 = Factory :user
|
||||
|
@ -135,19 +132,3 @@ describe Note do
|
|||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: notes
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# note :text
|
||||
# noteable_id :string(255)
|
||||
# noteable_type :string(255)
|
||||
# author_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# project_id :integer(4)
|
||||
# attachment :string(255)
|
||||
# line_code :string(255)
|
||||
#
|
||||
|
||||
|
|
|
@ -2,23 +2,52 @@ require 'spec_helper'
|
|||
|
||||
describe Project do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:owner).class_name('User') }
|
||||
it { should have_many(:users) }
|
||||
it { should have_many(:protected_branches).dependent(:destroy) }
|
||||
it { should have_many(:events).dependent(:destroy) }
|
||||
it { should have_many(:wikis).dependent(:destroy) }
|
||||
it { should have_many(:merge_requests).dependent(:destroy) }
|
||||
it { should have_many(:users_projects).dependent(:destroy) }
|
||||
it { should have_many(:issues).dependent(:destroy) }
|
||||
it { should have_many(:milestones).dependent(:destroy) }
|
||||
it { should have_many(:users_projects).dependent(:destroy) }
|
||||
it { should have_many(:notes).dependent(:destroy) }
|
||||
it { should have_many(:snippets).dependent(:destroy) }
|
||||
it { should have_many(:hooks).dependent(:destroy) }
|
||||
it { should have_many(:deploy_keys).dependent(:destroy) }
|
||||
it { should have_many(:hooks).dependent(:destroy) }
|
||||
it { should have_many(:wikis).dependent(:destroy) }
|
||||
it { should have_many(:protected_branches).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
let!(:project) { create(:project) }
|
||||
|
||||
it { should validate_presence_of(:name) }
|
||||
it { should validate_uniqueness_of(:name) }
|
||||
it { should ensure_length_of(:name).is_within(0..255) }
|
||||
|
||||
it { should validate_presence_of(:path) }
|
||||
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) }
|
||||
|
||||
it { should validate_presence_of(:code) }
|
||||
it { should validate_uniqueness_of(:code) }
|
||||
it { should ensure_length_of(:code).is_within(1..255) }
|
||||
# TODO: Formats
|
||||
|
||||
it { should validate_presence_of(:owner) }
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
describe "Respond to" do
|
||||
|
@ -40,7 +69,6 @@ describe Project do
|
|||
it { should respond_to(:commits_with_refs) }
|
||||
it { should respond_to(:commits_since) }
|
||||
it { should respond_to(:commits_between) }
|
||||
it { should respond_to(:write_hooks) }
|
||||
it { should respond_to(:satellite) }
|
||||
it { should respond_to(:update_repository) }
|
||||
it { should respond_to(:destroy_repository) }
|
||||
|
@ -74,9 +102,11 @@ describe Project do
|
|||
it { should respond_to(:trigger_post_receive) }
|
||||
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)
|
||||
describe 'modules' do
|
||||
it { should include_module(Repository) }
|
||||
it { should include_module(PushObserver) }
|
||||
it { should include_module(Authority) }
|
||||
it { should include_module(Team) }
|
||||
end
|
||||
|
||||
it "should return valid url to repo" do
|
||||
|
@ -86,7 +116,7 @@ describe Project do
|
|||
|
||||
it "should return path to repo" do
|
||||
project = Project.new(path: "somewhere")
|
||||
project.path_to_repo.should == File.join(Rails.root, "tmp", "tests", "somewhere")
|
||||
project.path_to_repo.should == File.join(Rails.root, "tmp", "repositories", "somewhere")
|
||||
end
|
||||
|
||||
it "returns the full web URL for this repo" do
|
||||
|
@ -111,7 +141,7 @@ describe Project do
|
|||
let(:last_event) { double }
|
||||
|
||||
before do
|
||||
project.stub(:events).and_return( [ double, double, last_event ] )
|
||||
project.stub_chain(:events, :order).and_return( [ double, double, last_event ] )
|
||||
end
|
||||
|
||||
it { project.last_activity.should == last_event }
|
||||
|
@ -237,23 +267,3 @@ describe Project do
|
|||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: projects
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# name :string(255)
|
||||
# path :string(255)
|
||||
# description :text
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# private_flag :boolean(1) default(TRUE), not null
|
||||
# code :string(255)
|
||||
# owner_id :integer(4)
|
||||
# default_branch :string(255) default("master"), not null
|
||||
# issues_enabled :boolean(1) default(TRUE), not null
|
||||
# wall_enabled :boolean(1) default(TRUE), not null
|
||||
# merge_requests_enabled :boolean(1) default(TRUE), not null
|
||||
# wiki_enabled :boolean(1) default(TRUE), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: protected_branches
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# project_id :integer(4) not null
|
||||
# name :string(255) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProtectedBranch do
|
||||
let(:project) { Factory(:project) }
|
||||
|
||||
describe 'Associations' do
|
||||
it { should belong_to(:project) }
|
||||
end
|
||||
|
@ -24,26 +11,26 @@ describe ProtectedBranch do
|
|||
end
|
||||
|
||||
describe 'Callbacks' do
|
||||
subject { ProtectedBranch.new(project: project, name: 'branch_name') }
|
||||
let(:branch) { build(:protected_branch) }
|
||||
|
||||
it 'call update_repository after save' do
|
||||
subject.should_receive(:update_repository)
|
||||
subject.save
|
||||
branch.should_receive(:update_repository)
|
||||
branch.save
|
||||
end
|
||||
|
||||
it 'call update_repository after destroy' do
|
||||
subject.should_receive(:update_repository)
|
||||
subject.destroy
|
||||
branch.save
|
||||
branch.should_receive(:update_repository)
|
||||
branch.destroy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#commit' do
|
||||
subject { ProtectedBranch.new(project: project, name: 'cant_touch_this') }
|
||||
let(:branch) { create(:protected_branch) }
|
||||
|
||||
it 'commits itself to its project' do
|
||||
project.should_receive(:commit).with('cant_touch_this')
|
||||
|
||||
subject.commit
|
||||
branch.project.should_receive(:commit).with(branch.name)
|
||||
branch.commit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,29 +3,21 @@ require 'spec_helper'
|
|||
describe Snippet do
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:author) }
|
||||
it { should belong_to(:author).class_name('User') }
|
||||
it { should have_many(:notes).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should validate_presence_of(:author_id) }
|
||||
it { should validate_presence_of(:project_id) }
|
||||
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should ensure_length_of(:title).is_within(0..255) }
|
||||
|
||||
it { should validate_presence_of(:file_name) }
|
||||
it { should ensure_length_of(:title).is_within(0..255) }
|
||||
|
||||
it { should validate_presence_of(:content) }
|
||||
it { should ensure_length_of(:content).is_within(0..10_000) }
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: snippets
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# title :string(255)
|
||||
# content :text
|
||||
# author_id :integer(4) not null
|
||||
# project_id :integer(4) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# file_name :string(255)
|
||||
# expires_at :datetime
|
||||
#
|
||||
|
||||
|
|
|
@ -10,13 +10,12 @@ describe SystemHook do
|
|||
end
|
||||
|
||||
it "project_create hook" do
|
||||
user = Factory :user
|
||||
with_resque do
|
||||
project = Factory :project_without_owner, owner: user
|
||||
project = Factory :project
|
||||
end
|
||||
WebMock.should have_requested(:post, @system_hook.url).with(body: /project_create/).once
|
||||
end
|
||||
|
||||
|
||||
it "project_destroy hook" do
|
||||
project = Factory :project
|
||||
with_resque do
|
||||
|
@ -31,7 +30,7 @@ describe SystemHook do
|
|||
end
|
||||
WebMock.should have_requested(:post, @system_hook.url).with(body: /user_create/).once
|
||||
end
|
||||
|
||||
|
||||
it "user_destroy hook" do
|
||||
user = Factory :user
|
||||
with_resque do
|
||||
|
@ -39,7 +38,7 @@ describe SystemHook do
|
|||
end
|
||||
WebMock.should have_requested(:post, @system_hook.url).with(body: /user_destroy/).once
|
||||
end
|
||||
|
||||
|
||||
it "project_create hook" do
|
||||
user = Factory :user
|
||||
project = Factory :project
|
||||
|
@ -48,7 +47,7 @@ describe SystemHook do
|
|||
end
|
||||
WebMock.should have_requested(:post, @system_hook.url).with(body: /user_add_to_team/).once
|
||||
end
|
||||
|
||||
|
||||
it "project_destroy hook" do
|
||||
user = Factory :user
|
||||
project = Factory :project
|
||||
|
|
|
@ -2,12 +2,26 @@ require 'spec_helper'
|
|||
|
||||
describe User do
|
||||
describe "Associations" do
|
||||
it { should have_many(:users_projects).dependent(:destroy) }
|
||||
it { should have_many(:projects) }
|
||||
it { should have_many(:users_projects) }
|
||||
it { should have_many(:issues) }
|
||||
it { should have_many(:assigned_issues) }
|
||||
it { should have_many(:merge_requests) }
|
||||
it { should have_many(:assigned_merge_requests) }
|
||||
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') }
|
||||
it { should have_many(:issues).dependent(:destroy) }
|
||||
it { should have_many(:notes).dependent(:destroy) }
|
||||
it { should have_many(:assigned_issues).dependent(:destroy) }
|
||||
it { should have_many(:merge_requests).dependent(:destroy) }
|
||||
it { should have_many(:assigned_merge_requests).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { should validate_presence_of(:projects_limit) }
|
||||
it { should validate_numericality_of(:projects_limit) }
|
||||
it { should allow_value(0).for(:projects_limit) }
|
||||
it { should_not allow_value(-1).for(:projects_limit) }
|
||||
|
||||
it { should ensure_length_of(:bio).is_within(0..255) }
|
||||
end
|
||||
|
||||
describe "Respond to" do
|
||||
|
@ -49,49 +63,4 @@ describe User do
|
|||
user = Factory(:user)
|
||||
user.authentication_token.should_not == ""
|
||||
end
|
||||
|
||||
describe "dependent" do
|
||||
before do
|
||||
@user = Factory :user
|
||||
@note = Factory :note,
|
||||
author: @user,
|
||||
project: Factory(:project)
|
||||
end
|
||||
|
||||
it "should destroy all notes with user" do
|
||||
Note.find_by_id(@note.id).should_not be_nil
|
||||
@user.destroy
|
||||
Note.find_by_id(@note.id).should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# email :string(255) default(""), not null
|
||||
# encrypted_password :string(128) default(""), not null
|
||||
# reset_password_token :string(255)
|
||||
# reset_password_sent_at :datetime
|
||||
# remember_created_at :datetime
|
||||
# sign_in_count :integer(4) default(0)
|
||||
# current_sign_in_at :datetime
|
||||
# last_sign_in_at :datetime
|
||||
# current_sign_in_ip :string(255)
|
||||
# last_sign_in_ip :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# name :string(255)
|
||||
# admin :boolean(1) default(FALSE), not null
|
||||
# projects_limit :integer(4) default(10)
|
||||
# skype :string(255) default(""), not null
|
||||
# linkedin :string(255) default(""), not null
|
||||
# twitter :string(255) default(""), not null
|
||||
# authentication_token :string(255)
|
||||
# dark_scheme :boolean(1) default(FALSE), not null
|
||||
# theme_id :integer(4) default(1), not null
|
||||
# bio :string(255)
|
||||
# blocked :boolean(1) default(FALSE), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -7,7 +7,11 @@ describe UsersProject do
|
|||
end
|
||||
|
||||
describe "Validation" do
|
||||
let!(:users_project) { create(:users_project) }
|
||||
|
||||
it { should validate_presence_of(:user_id) }
|
||||
it { should validate_uniqueness_of(:user_id).scoped_to(:project_id) }
|
||||
|
||||
it { should validate_presence_of(:project_id) }
|
||||
end
|
||||
|
||||
|
@ -16,15 +20,3 @@ describe UsersProject do
|
|||
it { should respond_to(:user_email) }
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: users_projects
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# user_id :integer(4) not null
|
||||
# project_id :integer(4) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# project_access :integer(4) default(0), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -52,14 +52,3 @@ describe ProjectHook do
|
|||
end
|
||||
end
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: web_hooks
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# url :string(255)
|
||||
# project_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
|
|
|
@ -4,27 +4,13 @@ describe Wiki do
|
|||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:user) }
|
||||
it { should have_many(:notes).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should ensure_length_of(:title).is_within(1..250) }
|
||||
it { should validate_presence_of(:content) }
|
||||
it { should validate_presence_of(:user_id) }
|
||||
end
|
||||
|
||||
it { Factory(:wiki).should be_valid }
|
||||
end
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: wikis
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# title :string(255)
|
||||
# content :text
|
||||
# project_id :integer(4)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# slug :string(255)
|
||||
# user_id :integer(4)
|
||||
#
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
# Stubbing Project <-> git host path
|
||||
# create project using Factory only
|
||||
class Project
|
||||
def update_repository
|
||||
true
|
||||
end
|
||||
|
||||
def destroy_repository
|
||||
true
|
||||
end
|
||||
|
||||
def path_to_repo
|
||||
File.join(Rails.root, "tmp", "tests", path)
|
||||
end
|
||||
|
||||
def satellite
|
||||
@satellite ||= FakeSatellite.new
|
||||
end
|
||||
end
|
||||
|
||||
class Key
|
||||
def update_repository
|
||||
true
|
||||
end
|
||||
|
||||
def repository_delete_key
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class UsersProject
|
||||
def update_repository
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class FakeSatellite
|
||||
def exists?
|
||||
true
|
||||
end
|
||||
|
||||
def create
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class ProtectedBranch
|
||||
def update_repository
|
||||
true
|
||||
end
|
||||
end
|
|
@ -3,7 +3,8 @@ require 'spec_helper'
|
|||
describe IssueObserver do
|
||||
let(:some_user) { double(:user, id: 1) }
|
||||
let(:assignee) { double(:user, id: 2) }
|
||||
let(:issue) { double(:issue, id: 42, assignee: assignee) }
|
||||
let(:author) { double(:user, id: 3) }
|
||||
let(:issue) { double(:issue, id: 42, assignee: assignee, author: author) }
|
||||
|
||||
before(:each) { subject.stub(:current_user).and_return(some_user) }
|
||||
|
||||
|
@ -67,36 +68,90 @@ describe IssueObserver do
|
|||
end
|
||||
end
|
||||
|
||||
context 'a status "closed" note' do
|
||||
it 'is created if the issue is being closed' do
|
||||
context 'a status "closed"' do
|
||||
it 'note is created if the issue is being closed' do
|
||||
issue.should_receive(:is_being_closed?).and_return(true)
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'is not created if the issue is not being closed' do
|
||||
it 'note is not created if the issue is not being closed' do
|
||||
issue.should_receive(:is_being_closed?).and_return(false)
|
||||
Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
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
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'notification is not delivered if the issue not being closed' do
|
||||
issue.stub(:is_being_closed?).and_return(false)
|
||||
Notify.should_not_receive(:issue_status_changed_email)
|
||||
Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'notification is delivered only to author if the issue being closed' do
|
||||
issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil)
|
||||
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
|
||||
Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'closed')
|
||||
|
||||
subject.after_update(issue_without_assignee)
|
||||
end
|
||||
end
|
||||
|
||||
context 'a status "reopened" note' do
|
||||
it 'is created if the issue is being reopened' do
|
||||
context 'a status "reopened"' do
|
||||
it 'note is created if the issue is being reopened' do
|
||||
issue.should_receive(:is_being_reopened?).and_return(true)
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'is not created if the issue is not being reopened' do
|
||||
it 'note is not created if the issue is not being reopened' do
|
||||
issue.should_receive(:is_being_reopened?).and_return(false)
|
||||
Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
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
|
||||
Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'notification is not delivered if the issue not being reopened' do
|
||||
issue.stub(:is_being_reopened?).and_return(false)
|
||||
Notify.should_not_receive(:issue_status_changed_email)
|
||||
Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue)
|
||||
end
|
||||
|
||||
it 'notification is delivered only to author if the issue being reopened' do
|
||||
issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil)
|
||||
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
|
||||
Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'reopened')
|
||||
|
||||
subject.after_update(issue_without_assignee)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
34
spec/observers/key_observer_spec.rb
Normal file
34
spec/observers/key_observer_spec.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe KeyObserver do
|
||||
before do
|
||||
@key = double('Key',
|
||||
identifier: 'admin_654654',
|
||||
key: '== a vaild ssh key',
|
||||
projects: [],
|
||||
is_deploy_key: false
|
||||
)
|
||||
|
||||
@gitolite = double('Gitlab::Gitolite',
|
||||
set_key: true,
|
||||
remove_key: true
|
||||
)
|
||||
|
||||
@observer = KeyObserver.instance
|
||||
@observer.stub(:git_host => @gitolite)
|
||||
end
|
||||
|
||||
context :after_save do
|
||||
it do
|
||||
@gitolite.should_receive(:set_key).with(@key.identifier, @key.key, @key.projects)
|
||||
@observer.after_save(@key)
|
||||
end
|
||||
end
|
||||
|
||||
context :after_destroy do
|
||||
it do
|
||||
@gitolite.should_receive(:remove_key).with(@key.identifier, @key.projects)
|
||||
@observer.after_destroy(@key)
|
||||
end
|
||||
end
|
||||
end
|
40
spec/observers/users_project_observer_spec.rb
Normal file
40
spec/observers/users_project_observer_spec.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe UsersProjectObserver do
|
||||
let(:user) { Factory.create :user }
|
||||
let(:project) { Factory.create(:project,
|
||||
code: "Fuu",
|
||||
path: "Fuu" ) }
|
||||
let(:users_project) { Factory.create(:users_project,
|
||||
project: project,
|
||||
user: user )}
|
||||
subject { UsersProjectObserver.instance }
|
||||
|
||||
describe "#after_create" do
|
||||
it "should called when UsersProject created" do
|
||||
subject.should_receive(:after_create)
|
||||
UsersProject.observers.enable :users_project_observer do
|
||||
Factory.create(:users_project,
|
||||
project: project,
|
||||
user: user)
|
||||
end
|
||||
end
|
||||
it "should send email to user" do
|
||||
Notify.should_receive(:project_access_granted_email).with(users_project.id).and_return(double(deliver: true))
|
||||
subject.after_create(users_project)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#after_update" do
|
||||
it "should called when UsersProject updated" do
|
||||
subject.should_receive(:after_update)
|
||||
UsersProject.observers.enable :users_project_observer do
|
||||
users_project.update_attribute(:project_access, 40)
|
||||
end
|
||||
end
|
||||
it "should send email to user" do
|
||||
Notify.should_receive(:project_access_granted_email).with(users_project.id).and_return(double(deliver: true))
|
||||
subject.after_update(users_project)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -87,7 +87,7 @@ describe "Admin::Projects" do
|
|||
visit new_admin_project_path
|
||||
fill_in 'project_name', with: 'NewProject'
|
||||
fill_in 'project_code', with: 'NPR'
|
||||
fill_in 'project_path', with: 'gitlabhq_1'
|
||||
fill_in 'project_path', with: 'newproject'
|
||||
expect { click_button "Create project" }.to change { Project.count }.by(1)
|
||||
@project = Project.last
|
||||
end
|
||||
|
|
|
@ -2,20 +2,26 @@ require 'spec_helper'
|
|||
|
||||
describe "Admin::Projects" do
|
||||
describe "GET /admin/projects" do
|
||||
it { admin_projects_path.should be_allowed_for :admin }
|
||||
it { admin_projects_path.should be_denied_for :user }
|
||||
it { admin_projects_path.should be_denied_for :visitor }
|
||||
subject { admin_projects_path }
|
||||
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /admin/users" do
|
||||
it { admin_users_path.should be_allowed_for :admin }
|
||||
it { admin_users_path.should be_denied_for :user }
|
||||
it { admin_users_path.should be_denied_for :visitor }
|
||||
subject { admin_users_path }
|
||||
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /admin/hooks" do
|
||||
it { admin_hooks_path.should be_allowed_for :admin }
|
||||
it { admin_hooks_path.should be_denied_for :user }
|
||||
it { admin_hooks_path.should be_denied_for :visitor }
|
||||
subject { admin_hooks_path }
|
||||
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::API do
|
||||
include ApiHelpers
|
||||
|
||||
let(:user) { Factory :user }
|
||||
let!(:project) { Factory :project, owner: user }
|
||||
let!(:issue) { Factory :issue, author: user, assignee: user, project: project }
|
||||
|
@ -8,13 +10,13 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /issues" do
|
||||
it "should return authentication error" do
|
||||
get "#{api_prefix}/issues"
|
||||
get api("/issues")
|
||||
response.status.should == 401
|
||||
end
|
||||
|
||||
describe "authenticated GET /issues" do
|
||||
it "should return an array of issues" do
|
||||
get "#{api_prefix}/issues?private_token=#{user.private_token}"
|
||||
get api("/issues", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['title'].should == issue.title
|
||||
|
@ -24,7 +26,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/issues" do
|
||||
it "should return project issues" do
|
||||
get "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/issues", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['title'].should == issue.title
|
||||
|
@ -33,7 +35,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/issues/:issue_id" do
|
||||
it "should return a project issue by id" do
|
||||
get "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/issues/#{issue.id}", user)
|
||||
response.status.should == 200
|
||||
json_response['title'].should == issue.title
|
||||
end
|
||||
|
@ -41,7 +43,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "POST /projects/:id/issues" do
|
||||
it "should create a new project issue" do
|
||||
post "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}",
|
||||
post api("/projects/#{project.code}/issues", user),
|
||||
title: 'new issue', labels: 'label, label2'
|
||||
response.status.should == 201
|
||||
json_response['title'].should == 'new issue'
|
||||
|
@ -52,7 +54,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "PUT /projects/:id/issues/:issue_id" do
|
||||
it "should update a project issue" do
|
||||
put "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}",
|
||||
put api("/projects/#{project.code}/issues/#{issue.id}", user),
|
||||
title: 'updated title', labels: 'label2', closed: 1
|
||||
response.status.should == 200
|
||||
json_response['title'].should == 'updated title'
|
||||
|
@ -63,9 +65,8 @@ describe Gitlab::API do
|
|||
|
||||
describe "DELETE /projects/:id/issues/:issue_id" do
|
||||
it "should delete a project issue" do
|
||||
expect {
|
||||
delete "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
|
||||
}.to change { Issue.count }.by(-1)
|
||||
delete api("/projects/#{project.code}/issues/#{issue.id}", user)
|
||||
response.status.should == 405
|
||||
end
|
||||
end
|
||||
end
|
47
spec/requests/api/milestones_spec.rb
Normal file
47
spec/requests/api/milestones_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::API do
|
||||
include ApiHelpers
|
||||
|
||||
let(:user) { Factory :user }
|
||||
let!(:project) { Factory :project, owner: user }
|
||||
let!(:milestone) { Factory :milestone, project: project }
|
||||
|
||||
before { project.add_access(user, :read) }
|
||||
|
||||
describe "GET /projects/:id/milestones" do
|
||||
it "should return project milestones" do
|
||||
get api("/projects/#{project.code}/milestones", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['title'].should == milestone.title
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/milestones/:milestone_id" do
|
||||
it "should return a project milestone by id" do
|
||||
get api("/projects/#{project.code}/milestones/#{milestone.id}", user)
|
||||
response.status.should == 200
|
||||
json_response['title'].should == milestone.title
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /projects/:id/milestones" do
|
||||
it "should create a new project milestone" do
|
||||
post api("/projects/#{project.code}/milestones", user),
|
||||
title: 'new milestone'
|
||||
response.status.should == 201
|
||||
json_response['title'].should == 'new milestone'
|
||||
json_response['description'].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /projects/:id/milestones/:milestone_id" do
|
||||
it "should update a project milestone" do
|
||||
put api("/projects/#{project.code}/milestones/#{milestone.id}", user),
|
||||
title: 'updated title'
|
||||
response.status.should == 200
|
||||
json_response['title'].should == 'updated title'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::API do
|
||||
include ApiHelpers
|
||||
|
||||
let(:user) { Factory :user }
|
||||
let!(:project) { Factory :project, owner: user }
|
||||
let!(:snippet) { Factory :snippet, author: user, project: project, title: 'example' }
|
||||
|
@ -8,13 +10,13 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects" do
|
||||
it "should return authentication error" do
|
||||
get "#{api_prefix}/projects"
|
||||
get api("/projects")
|
||||
response.status.should == 401
|
||||
end
|
||||
|
||||
describe "authenticated GET /projects" do
|
||||
it "should return an array of projects" do
|
||||
get "#{api_prefix}/projects?private_token=#{user.private_token}"
|
||||
get api("/projects", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['name'].should == project.name
|
||||
|
@ -25,20 +27,20 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id" do
|
||||
it "should return a project by id" do
|
||||
get "#{api_prefix}/projects/#{project.id}?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.id}", user)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project.name
|
||||
json_response['owner']['email'].should == user.email
|
||||
end
|
||||
|
||||
it "should return a project by code name" do
|
||||
get "#{api_prefix}/projects/#{project.code}?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}", user)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project.name
|
||||
end
|
||||
|
||||
it "should return a 404 error if not found" do
|
||||
get "#{api_prefix}/projects/42?private_token=#{user.private_token}"
|
||||
get api("/projects/42", user)
|
||||
response.status.should == 404
|
||||
json_response['message'].should == '404 Not found'
|
||||
end
|
||||
|
@ -46,7 +48,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/repository/branches" do
|
||||
it "should return an array of project branches" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/branches?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/repository/branches", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name
|
||||
|
@ -55,7 +57,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/repository/branches/:branch" do
|
||||
it "should return the branch information for a single branch" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/branches/new_design?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/repository/branches/new_design", user)
|
||||
response.status.should == 200
|
||||
|
||||
json_response['name'].should == 'new_design'
|
||||
|
@ -65,7 +67,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/repository/tags" do
|
||||
it "should return an array of project tags" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/tags?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/repository/tags", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
|
||||
|
@ -74,7 +76,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id/snippets/:snippet_id" do
|
||||
it "should return a project snippet" do
|
||||
get "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/snippets/#{snippet.id}", user)
|
||||
response.status.should == 200
|
||||
json_response['title'].should == snippet.title
|
||||
end
|
||||
|
@ -82,7 +84,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "POST /projects/:id/snippets" do
|
||||
it "should create a new project snippet" do
|
||||
post "#{api_prefix}/projects/#{project.code}/snippets?private_token=#{user.private_token}",
|
||||
post api("/projects/#{project.code}/snippets", user),
|
||||
title: 'api test', file_name: 'sample.rb', code: 'test'
|
||||
response.status.should == 201
|
||||
json_response['title'].should == 'api test'
|
||||
|
@ -91,7 +93,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "PUT /projects/:id/snippets" do
|
||||
it "should update an existing project snippet" do
|
||||
put "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}",
|
||||
put api("/projects/#{project.code}/snippets/#{snippet.id}", user),
|
||||
code: 'updated code'
|
||||
response.status.should == 200
|
||||
json_response['title'].should == 'example'
|
||||
|
@ -102,34 +104,31 @@ describe Gitlab::API do
|
|||
describe "DELETE /projects/:id/snippets/:snippet_id" do
|
||||
it "should delete existing project snippet" do
|
||||
expect {
|
||||
delete "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}"
|
||||
delete api("/projects/#{project.code}/snippets/#{snippet.id}", user)
|
||||
}.to change { Snippet.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/snippets/:snippet_id/raw" do
|
||||
it "should get a raw project snippet" do
|
||||
get "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}/raw?private_token=#{user.private_token}"
|
||||
get api("/projects/#{project.code}/snippets/#{snippet.id}/raw", user)
|
||||
response.status.should == 200
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/:sha/blob" do
|
||||
it "should get the raw file contents" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.md&private_token=#{user.private_token}"
|
||||
|
||||
get api("/projects/#{project.code}/repository/commits/master/blob?filepath=README.md", user)
|
||||
response.status.should == 200
|
||||
end
|
||||
|
||||
it "should return 404 for invalid branch_name" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/commits/invalid_branch_name/blob?filepath=README.md&private_token=#{user.private_token}"
|
||||
|
||||
get api("/projects/#{project.code}/repository/commits/invalid_branch_name/blob?filepath=README.md", user)
|
||||
response.status.should == 404
|
||||
end
|
||||
|
||||
it "should return 404 for invalid file" do
|
||||
get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.invalid&private_token=#{user.private_token}"
|
||||
|
||||
get api("/projects/#{project.code}/repository/commits/master/blob?filepath=README.invalid", user)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
|
@ -1,17 +1,19 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::API do
|
||||
include ApiHelpers
|
||||
|
||||
let(:user) { Factory :user }
|
||||
|
||||
describe "GET /users" do
|
||||
it "should return authentication error" do
|
||||
get "#{api_prefix}/users"
|
||||
get api("/users")
|
||||
response.status.should == 401
|
||||
end
|
||||
|
||||
describe "authenticated GET /users" do
|
||||
it "should return an array of users" do
|
||||
get "#{api_prefix}/users?private_token=#{user.private_token}"
|
||||
get api("/users", user)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['email'].should == user.email
|
||||
|
@ -21,7 +23,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /users/:id" do
|
||||
it "should return a user by id" do
|
||||
get "#{api_prefix}/users/#{user.id}?private_token=#{user.private_token}"
|
||||
get api("/users/#{user.id}", user)
|
||||
response.status.should == 200
|
||||
json_response['email'].should == user.email
|
||||
end
|
||||
|
@ -29,7 +31,7 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /user" do
|
||||
it "should return current user" do
|
||||
get "#{api_prefix}/user?private_token=#{user.private_token}"
|
||||
get api("/user", user)
|
||||
response.status.should == 200
|
||||
json_response['email'].should == user.email
|
||||
end
|
|
@ -6,13 +6,9 @@ describe "User Issues Dashboard" do
|
|||
|
||||
login_as :user
|
||||
|
||||
@project1 = Factory :project,
|
||||
path: "project1",
|
||||
code: "TEST1"
|
||||
@project1 = Factory :project
|
||||
|
||||
@project2 = Factory :project,
|
||||
path: "project2",
|
||||
code: "TEST2"
|
||||
@project2 = Factory :project
|
||||
|
||||
@project1.add_access(@user, :read, :write)
|
||||
@project2.add_access(@user, :read, :write)
|
||||
|
|
|
@ -42,7 +42,7 @@ describe "Projects", "DeployKeys" do
|
|||
describe "fill in" do
|
||||
before do
|
||||
fill_in "key_title", with: "laptop"
|
||||
fill_in "key_key", with: "publickey234="
|
||||
fill_in "key_key", with: "ssh-rsa publickey234="
|
||||
end
|
||||
|
||||
it { expect { click_button "Save" }.to change {Key.count}.by(1) }
|
||||
|
@ -55,12 +55,12 @@ describe "Projects", "DeployKeys" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "Show page" do
|
||||
describe "Show page" do
|
||||
before do
|
||||
@key = Factory :key, project: project
|
||||
visit project_deploy_key_path(project, @key)
|
||||
visit project_deploy_key_path(project, @key)
|
||||
end
|
||||
|
||||
|
||||
it { page.should have_content @key.title }
|
||||
it { page.should have_content @key.key[0..10] }
|
||||
end
|
||||
|
|
|
@ -11,24 +11,30 @@ describe "Users Security" do
|
|||
end
|
||||
|
||||
describe "GET /keys" do
|
||||
it { keys_path.should be_allowed_for @u1 }
|
||||
it { keys_path.should be_allowed_for :admin }
|
||||
it { keys_path.should be_allowed_for :user }
|
||||
it { keys_path.should be_denied_for :visitor }
|
||||
subject { keys_path }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_allowed_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /profile" do
|
||||
it { profile_path.should be_allowed_for @u1 }
|
||||
it { profile_path.should be_allowed_for :admin }
|
||||
it { profile_path.should be_allowed_for :user }
|
||||
it { profile_path.should be_denied_for :visitor }
|
||||
subject { profile_path }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_allowed_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /profile/password" do
|
||||
it { profile_password_path.should be_allowed_for @u1 }
|
||||
it { profile_password_path.should be_allowed_for :admin }
|
||||
it { profile_password_path.should be_allowed_for :user }
|
||||
it { profile_password_path.should be_denied_for :visitor }
|
||||
subject { profile_password_path }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for :admin }
|
||||
it { should be_allowed_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,64 +26,76 @@ describe "Application access" do
|
|||
end
|
||||
|
||||
describe "GET /project_code" do
|
||||
it { project_path(@project).should be_allowed_for @u1 }
|
||||
it { project_path(@project).should be_allowed_for @u3 }
|
||||
it { project_path(@project).should be_denied_for :admin }
|
||||
it { project_path(@project).should be_denied_for @u2 }
|
||||
it { project_path(@project).should be_denied_for :user }
|
||||
it { project_path(@project).should be_denied_for :visitor }
|
||||
subject { project_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/master/tree" do
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_allowed_for @u1 }
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_allowed_for @u3 }
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :admin }
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for @u2 }
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :user }
|
||||
it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :visitor }
|
||||
subject { tree_project_ref_path(@project, @project.root_ref) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/commits" do
|
||||
it { project_commits_path(@project).should be_allowed_for @u1 }
|
||||
it { project_commits_path(@project).should be_allowed_for @u3 }
|
||||
it { project_commits_path(@project).should be_denied_for :admin }
|
||||
it { project_commits_path(@project).should be_denied_for @u2 }
|
||||
it { project_commits_path(@project).should be_denied_for :user }
|
||||
it { project_commits_path(@project).should be_denied_for :visitor }
|
||||
subject { project_commits_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/commit" do
|
||||
it { project_commit_path(@project, @project.commit.id).should be_allowed_for @u1 }
|
||||
it { project_commit_path(@project, @project.commit.id).should be_allowed_for @u3 }
|
||||
it { project_commit_path(@project, @project.commit.id).should be_denied_for :admin }
|
||||
it { project_commit_path(@project, @project.commit.id).should be_denied_for @u2 }
|
||||
it { project_commit_path(@project, @project.commit.id).should be_denied_for :user }
|
||||
it { project_commit_path(@project, @project.commit.id).should be_denied_for :visitor }
|
||||
subject { project_commit_path(@project, @project.commit.id) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/team" do
|
||||
it { team_project_path(@project).should be_allowed_for @u1 }
|
||||
it { team_project_path(@project).should be_allowed_for @u3 }
|
||||
it { team_project_path(@project).should be_denied_for :admin }
|
||||
it { team_project_path(@project).should be_denied_for @u2 }
|
||||
it { team_project_path(@project).should be_denied_for :user }
|
||||
it { team_project_path(@project).should be_denied_for :visitor }
|
||||
subject { team_project_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/wall" do
|
||||
it { wall_project_path(@project).should be_allowed_for @u1 }
|
||||
it { wall_project_path(@project).should be_allowed_for @u3 }
|
||||
it { wall_project_path(@project).should be_denied_for :admin }
|
||||
it { wall_project_path(@project).should be_denied_for @u2 }
|
||||
it { wall_project_path(@project).should be_denied_for :user }
|
||||
it { wall_project_path(@project).should be_denied_for :visitor }
|
||||
subject { wall_project_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/blob" do
|
||||
before do
|
||||
@commit = @project.commit
|
||||
@path = @commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
|
||||
@blob_path = blob_project_ref_path(@project, @commit.id, path: @path)
|
||||
commit = @project.commit
|
||||
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
|
||||
@blob_path = blob_project_ref_path(@project, commit.id, path: path)
|
||||
end
|
||||
|
||||
it { @blob_path.should be_allowed_for @u1 }
|
||||
|
@ -95,93 +107,113 @@ describe "Application access" do
|
|||
end
|
||||
|
||||
describe "GET /project_code/edit" do
|
||||
it { edit_project_path(@project).should be_allowed_for @u1 }
|
||||
it { edit_project_path(@project).should be_denied_for @u3 }
|
||||
it { edit_project_path(@project).should be_denied_for :admin }
|
||||
it { edit_project_path(@project).should be_denied_for @u2 }
|
||||
it { edit_project_path(@project).should be_denied_for :user }
|
||||
it { edit_project_path(@project).should be_denied_for :visitor }
|
||||
subject { edit_project_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_denied_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/deploy_keys" do
|
||||
it { project_deploy_keys_path(@project).should be_allowed_for @u1 }
|
||||
it { project_deploy_keys_path(@project).should be_denied_for @u3 }
|
||||
it { project_deploy_keys_path(@project).should be_denied_for :admin }
|
||||
it { project_deploy_keys_path(@project).should be_denied_for @u2 }
|
||||
it { project_deploy_keys_path(@project).should be_denied_for :user }
|
||||
it { project_deploy_keys_path(@project).should be_denied_for :visitor }
|
||||
subject { project_deploy_keys_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_denied_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/issues" do
|
||||
it { project_issues_path(@project).should be_allowed_for @u1 }
|
||||
it { project_issues_path(@project).should be_allowed_for @u3 }
|
||||
it { project_issues_path(@project).should be_denied_for :admin }
|
||||
it { project_issues_path(@project).should be_denied_for @u2 }
|
||||
it { project_issues_path(@project).should be_denied_for :user }
|
||||
it { project_issues_path(@project).should be_denied_for :visitor }
|
||||
subject { project_issues_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/snippets" do
|
||||
it { project_snippets_path(@project).should be_allowed_for @u1 }
|
||||
it { project_snippets_path(@project).should be_allowed_for @u3 }
|
||||
it { project_snippets_path(@project).should be_denied_for :admin }
|
||||
it { project_snippets_path(@project).should be_denied_for @u2 }
|
||||
it { project_snippets_path(@project).should be_denied_for :user }
|
||||
it { project_snippets_path(@project).should be_denied_for :visitor }
|
||||
subject { project_snippets_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/merge_requests" do
|
||||
it { project_merge_requests_path(@project).should be_allowed_for @u1 }
|
||||
it { project_merge_requests_path(@project).should be_allowed_for @u3 }
|
||||
it { project_merge_requests_path(@project).should be_denied_for :admin }
|
||||
it { project_merge_requests_path(@project).should be_denied_for @u2 }
|
||||
it { project_merge_requests_path(@project).should be_denied_for :user }
|
||||
it { project_merge_requests_path(@project).should be_denied_for :visitor }
|
||||
subject { project_merge_requests_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/repository" do
|
||||
it { project_repository_path(@project).should be_allowed_for @u1 }
|
||||
it { project_repository_path(@project).should be_allowed_for @u3 }
|
||||
it { project_repository_path(@project).should be_denied_for :admin }
|
||||
it { project_repository_path(@project).should be_denied_for @u2 }
|
||||
it { project_repository_path(@project).should be_denied_for :user }
|
||||
it { project_repository_path(@project).should be_denied_for :visitor }
|
||||
subject { project_repository_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/repository/branches" do
|
||||
it { branches_project_repository_path(@project).should be_allowed_for @u1 }
|
||||
it { branches_project_repository_path(@project).should be_allowed_for @u3 }
|
||||
it { branches_project_repository_path(@project).should be_denied_for :admin }
|
||||
it { branches_project_repository_path(@project).should be_denied_for @u2 }
|
||||
it { branches_project_repository_path(@project).should be_denied_for :user }
|
||||
it { branches_project_repository_path(@project).should be_denied_for :visitor }
|
||||
subject { branches_project_repository_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/repository/tags" do
|
||||
it { tags_project_repository_path(@project).should be_allowed_for @u1 }
|
||||
it { tags_project_repository_path(@project).should be_allowed_for @u3 }
|
||||
it { tags_project_repository_path(@project).should be_denied_for :admin }
|
||||
it { tags_project_repository_path(@project).should be_denied_for @u2 }
|
||||
it { tags_project_repository_path(@project).should be_denied_for :user }
|
||||
it { tags_project_repository_path(@project).should be_denied_for :visitor }
|
||||
subject { tags_project_repository_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/hooks" do
|
||||
it { project_hooks_path(@project).should be_allowed_for @u1 }
|
||||
it { project_hooks_path(@project).should be_allowed_for @u3 }
|
||||
it { project_hooks_path(@project).should be_denied_for :admin }
|
||||
it { project_hooks_path(@project).should be_denied_for @u2 }
|
||||
it { project_hooks_path(@project).should be_denied_for :user }
|
||||
it { project_hooks_path(@project).should be_denied_for :visitor }
|
||||
subject { project_hooks_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /project_code/files" do
|
||||
it { files_project_path(@project).should be_allowed_for @u1 }
|
||||
it { files_project_path(@project).should be_allowed_for @u3 }
|
||||
it { files_project_path(@project).should be_denied_for :admin }
|
||||
it { files_project_path(@project).should be_denied_for @u2 }
|
||||
it { files_project_path(@project).should be_denied_for :user }
|
||||
it { files_project_path(@project).should be_denied_for :visitor }
|
||||
subject { files_project_path(@project) }
|
||||
|
||||
it { should be_allowed_for @u1 }
|
||||
it { should be_allowed_for @u3 }
|
||||
it { should be_denied_for :admin }
|
||||
it { should be_denied_for @u2 }
|
||||
it { should be_denied_for :user }
|
||||
it { should be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
69
spec/roles/issue_commonality_spec.rb
Normal file
69
spec/roles/issue_commonality_spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Issue, "IssueCommonality" do
|
||||
let(:issue) { create(:issue) }
|
||||
|
||||
describe "Associations" do
|
||||
it { should belong_to(:project) }
|
||||
it { should belong_to(:author) }
|
||||
it { should belong_to(:assignee) }
|
||||
it { should have_many(:notes).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "Validation" do
|
||||
it { should validate_presence_of(:project_id) }
|
||||
it { should validate_presence_of(:author_id) }
|
||||
it { should validate_presence_of(:title) }
|
||||
it { should ensure_length_of(:title).is_at_least(0).is_at_most(255) }
|
||||
end
|
||||
|
||||
describe "Scope" do
|
||||
it { described_class.should respond_to(:opened) }
|
||||
it { described_class.should respond_to(:closed) }
|
||||
it { described_class.should respond_to(:assigned) }
|
||||
end
|
||||
|
||||
it "has an :author_id_of_changes accessor" do
|
||||
issue.should respond_to(:author_id_of_changes)
|
||||
issue.should respond_to(:author_id_of_changes=)
|
||||
end
|
||||
|
||||
describe ".search" do
|
||||
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
|
||||
|
||||
it "matches by title" do
|
||||
described_class.search('able').all.should == [searchable_issue]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#today?" do
|
||||
it "returns true when created today" do
|
||||
# Avoid timezone differences and just return exactly what we want
|
||||
Date.stub(:today).and_return(issue.created_at.to_date)
|
||||
issue.today?.should be_true
|
||||
end
|
||||
|
||||
it "returns false when not created today" do
|
||||
Date.stub(:today).and_return(Date.yesterday)
|
||||
issue.today?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#new?" do
|
||||
it "returns true when created today and record hasn't been updated" do
|
||||
issue.stub(:today?).and_return(true)
|
||||
issue.new?.should be_true
|
||||
end
|
||||
|
||||
it "returns false when not created today" do
|
||||
issue.stub(:today?).and_return(false)
|
||||
issue.new?.should be_false
|
||||
end
|
||||
|
||||
it "returns false when record has been updated" do
|
||||
issue.stub(:today?).and_return(true)
|
||||
issue.touch
|
||||
issue.new?.should be_false
|
||||
end
|
||||
end
|
||||
end
|
27
spec/roles/upvote_spec.rb
Normal file
27
spec/roles/upvote_spec.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Issue, "Upvote" do
|
||||
let(:issue) { create(:issue) }
|
||||
|
||||
it "with no notes has a 0/0 score" do
|
||||
issue.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize non-+1 notes" do
|
||||
issue.notes << create(:note, note: "No +1 here")
|
||||
issue.should have(1).note
|
||||
issue.notes.first.upvote?.should be_false
|
||||
issue.upvotes.should == 0
|
||||
end
|
||||
|
||||
it "should recognize a single +1 note" do
|
||||
issue.notes << create(:note, note: "+1 This is awesome")
|
||||
issue.upvotes.should == 1
|
||||
end
|
||||
|
||||
it "should recognize multiple +1 notes" do
|
||||
issue.notes << create(:note, note: "+1 This is awesome")
|
||||
issue.notes << create(:note, note: "+1 I want this")
|
||||
issue.upvotes.should == 2
|
||||
end
|
||||
end
|
|
@ -1,5 +1,7 @@
|
|||
require 'simplecov'
|
||||
SimpleCov.start 'rails'
|
||||
unless ENV['CI']
|
||||
require 'simplecov'
|
||||
SimpleCov.start 'rails'
|
||||
end
|
||||
|
||||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
|
@ -7,10 +9,7 @@ require File.expand_path("../../config/environment", __FILE__)
|
|||
require 'rspec/rails'
|
||||
require 'capybara/rails'
|
||||
require 'capybara/rspec'
|
||||
require 'capybara/dsl'
|
||||
require 'webmock/rspec'
|
||||
require 'factories'
|
||||
require 'monkeypatch'
|
||||
require 'email_spec'
|
||||
require 'headless'
|
||||
|
||||
|
@ -21,10 +20,14 @@ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
|||
# Use capybara-webkit
|
||||
Capybara.javascript_driver = :webkit
|
||||
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.mock_with :rspec
|
||||
|
||||
config.include LoginMacros
|
||||
config.include LoginHelpers, type: :request
|
||||
config.include GitoliteStub
|
||||
config.include FactoryGirl::Syntax::Methods
|
||||
|
||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
||||
# examples within a transaction, remove the following line or assign false
|
||||
|
@ -36,35 +39,11 @@ RSpec.configure do |config|
|
|||
headless.start
|
||||
end
|
||||
|
||||
config.before :each, type: :integration do
|
||||
DeviseSessionMock.disable
|
||||
end
|
||||
|
||||
config.before do
|
||||
if example.metadata[:js]
|
||||
DatabaseCleaner.strategy = :truncation
|
||||
Capybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = true
|
||||
else
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
end
|
||||
|
||||
DatabaseCleaner.start
|
||||
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
stub_gitolite!
|
||||
|
||||
# !!! Observers disabled by default in tests
|
||||
#
|
||||
# Use next code to enable observers
|
||||
# before(:each) { ActiveRecord::Base.observers.enable(:all) }
|
||||
#
|
||||
ActiveRecord::Base.observers.disable :all
|
||||
ActiveRecord::Base.observers.disable(:all)
|
||||
# ActiveRecord::Base.observers.enable(:all)
|
||||
end
|
||||
|
||||
config.after do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
config.include RSpec::Rails::RequestExampleGroup, type: :request, example_group: {
|
||||
file_path: /spec\/api/
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
def api_prefix
|
||||
"/api/#{Gitlab::API::VERSION}"
|
||||
end
|
||||
|
||||
def json_response
|
||||
JSON.parse(response.body)
|
||||
end
|
34
spec/support/api_helpers.rb
Normal file
34
spec/support/api_helpers.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module ApiHelpers
|
||||
# Public: Prepend a request path with the path to the API
|
||||
#
|
||||
# path - Path to append
|
||||
# user - User object - If provided, automatically appends private_token query
|
||||
# string for authenticated requests
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# >> api('/issues')
|
||||
# => "/api/v2/issues"
|
||||
#
|
||||
# >> api('/issues', User.last)
|
||||
# => "/api/v2/issues?private_token=..."
|
||||
#
|
||||
# >> api('/issues?foo=bar', User.last)
|
||||
# => "/api/v2/issues?foo=bar&private_token=..."
|
||||
#
|
||||
# Returns the relative path to the requested API resource
|
||||
def api(path, user = nil)
|
||||
"/api/#{Gitlab::API::VERSION}#{path}" +
|
||||
|
||||
# Normalize query string
|
||||
(path.index('?') ? '' : '?') +
|
||||
|
||||
# Append private_token if given a User object
|
||||
(user.respond_to?(:private_token) ?
|
||||
"&private_token=#{user.private_token}" : "")
|
||||
end
|
||||
|
||||
def json_response
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
end
|
18
spec/support/db_cleaner.rb
Normal file
18
spec/support/db_cleaner.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require 'database_cleaner'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.before do
|
||||
if example.metadata[:js]
|
||||
DatabaseCleaner.strategy = :truncation
|
||||
Capybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = true
|
||||
else
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
end
|
||||
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
|
||||
config.after do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
end
|
35
spec/support/gitolite_stub.rb
Normal file
35
spec/support/gitolite_stub.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
module GitoliteStub
|
||||
def stub_gitolite!
|
||||
stub_gitlab_gitolite
|
||||
stub_gitolite_admin
|
||||
end
|
||||
|
||||
def stub_gitolite_admin
|
||||
gitolite_repo = mock(
|
||||
clean_permissions: true,
|
||||
add_permission: true
|
||||
)
|
||||
|
||||
gitolite_config = mock(
|
||||
add_repo: true,
|
||||
get_repo: gitolite_repo,
|
||||
has_repo?: true
|
||||
)
|
||||
|
||||
gitolite_admin = double(
|
||||
'Gitolite::GitoliteAdmin',
|
||||
config: gitolite_config,
|
||||
save: true,
|
||||
)
|
||||
|
||||
Gitolite::GitoliteAdmin.stub(new: gitolite_admin)
|
||||
|
||||
end
|
||||
|
||||
def stub_gitlab_gitolite
|
||||
gitlab_gitolite = Gitlab::Gitolite.new
|
||||
Gitlab::Gitolite.stub(new: gitlab_gitolite)
|
||||
gitlab_gitolite.stub(configure: ->() { yield(self) })
|
||||
gitlab_gitolite.stub(update_keys: true)
|
||||
end
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
module JsPatch
|
||||
def confirm_js_popup
|
||||
page.evaluate_script("window.alert = function(msg) { return true; }")
|
||||
page.evaluate_script("window.confirm = function(msg) { return true; }")
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
module LoginMacros
|
||||
def login_as role
|
||||
@user = User.create(email: "user#{User.count}@mail.com",
|
||||
name: "John Smith",
|
||||
password: "123456",
|
||||
password_confirmation: "123456",
|
||||
skype: 'user_skype')
|
||||
|
||||
if role == :admin
|
||||
@user.admin = true
|
||||
@user.save!
|
||||
end
|
||||
|
||||
visit new_user_session_path
|
||||
fill_in "user_email", with: @user.email
|
||||
fill_in "user_password", with: "123456"
|
||||
click_button "Sign in"
|
||||
end
|
||||
|
||||
def login_with(user)
|
||||
visit new_user_session_path
|
||||
fill_in "user_email", with: user.email
|
||||
fill_in "user_password", with: "123456"
|
||||
click_button "Sign in"
|
||||
end
|
||||
|
||||
def logout
|
||||
click_link "Logout" rescue nil
|
||||
end
|
||||
end
|
23
spec/support/login_helpers.rb
Normal file
23
spec/support/login_helpers.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
module LoginHelpers
|
||||
# Internal: Create and log in as a user of the specified role
|
||||
#
|
||||
# role - User role (e.g., :admin, :user)
|
||||
def login_as(role)
|
||||
@user = Factory(role)
|
||||
login_with(@user)
|
||||
end
|
||||
|
||||
# Internal: Login as the specified user
|
||||
#
|
||||
# user - User instance to login with
|
||||
def login_with(user)
|
||||
visit new_user_session_path
|
||||
fill_in "user_email", with: user.email
|
||||
fill_in "user_password", with: "123456"
|
||||
click_button "Sign in"
|
||||
end
|
||||
|
||||
def logout
|
||||
click_link "Logout" rescue nil
|
||||
end
|
||||
end
|
|
@ -28,6 +28,16 @@ RSpec::Matchers.define :be_404_for do |user|
|
|||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.define :include_module do |expected|
|
||||
match do
|
||||
described_class.included_modules.include?(expected)
|
||||
end
|
||||
|
||||
failure_message_for_should do
|
||||
"expected #{described_class} to include the #{expected} module"
|
||||
end
|
||||
end
|
||||
|
||||
module UrlAccess
|
||||
def url_allowed?(user, url)
|
||||
emulate_user(user)
|
||||
|
@ -57,3 +67,17 @@ module UrlAccess
|
|||
login_with(user) if user
|
||||
end
|
||||
end
|
||||
|
||||
# Extend shoulda-matchers
|
||||
module Shoulda::Matchers::ActiveModel
|
||||
class EnsureLengthOfMatcher
|
||||
# Shortcut for is_at_least and is_at_most
|
||||
def is_within(range)
|
||||
if range.exclude_end?
|
||||
is_at_least(range.first) && is_at_most(range.last - 1)
|
||||
else
|
||||
is_at_least(range.first) && is_at_most(range.last)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
shared_examples_for :project_side_pane do
|
||||
subject { page }
|
||||
it { should have_content((@project || project).name) }
|
||||
it { should have_content("Commits") }
|
||||
it { should have_content("Files") }
|
||||
end
|
||||
|
||||
shared_examples_for :tree_view do
|
||||
subject { page }
|
||||
|
||||
it "should have Tree View of project" do
|
||||
should have_content("app")
|
||||
should have_content("History")
|
||||
should have_content("Gemfile")
|
||||
end
|
||||
end
|
31
spec/support/stubbed_repository.rb
Normal file
31
spec/support/stubbed_repository.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Stubs out all Git repository access done by models so that specs can run
|
||||
# against fake repositories without Grit complaining that they don't exist.
|
||||
module StubbedRepository
|
||||
def path_to_repo
|
||||
if new_record? || path == 'newproject'
|
||||
# There are a couple Project specs and features that expect the Project's
|
||||
# path to be in the returned path, so let's patronize them.
|
||||
File.join(Rails.root, 'tmp', 'repositories', path)
|
||||
else
|
||||
# For everything else, just give it the path to one of our real seeded
|
||||
# repos.
|
||||
File.join(Rails.root, 'tmp', 'repositories', 'gitlabhq')
|
||||
end
|
||||
end
|
||||
|
||||
def satellite
|
||||
FakeSatellite.new
|
||||
end
|
||||
|
||||
class FakeSatellite
|
||||
def exists?
|
||||
true
|
||||
end
|
||||
|
||||
def create
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Project.send(:include, StubbedRepository)
|
Loading…
Add table
Add a link
Reference in a new issue