Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/contexts/filter_context_spec.rb59
-rw-r--r--spec/contexts/projects_create_context_spec.rb75
-rw-r--r--spec/controllers/application_controller_spec.rb8
-rw-r--r--spec/controllers/blob_controller_spec.rb2
-rw-r--r--spec/controllers/commit_controller_spec.rb2
-rw-r--r--spec/controllers/commits_controller_spec.rb2
-rw-r--r--spec/controllers/merge_requests_controller_spec.rb6
-rw-r--r--spec/controllers/profile_keys_controller_spec.rb59
-rw-r--r--spec/controllers/tree_controller_spec.rb2
-rw-r--r--spec/factories.rb132
-rw-r--r--spec/factories/broadcast_messages.rb27
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb5
-rw-r--r--spec/features/gitlab_flavored_markdown_spec.rb2
-rw-r--r--spec/features/issues_spec.rb206
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb59
-rw-r--r--spec/features/security/group/group_access_spec.rb (renamed from spec/features/security/group_access_spec.rb)1
-rw-r--r--spec/features/security/group/internal_group_access_spec.rb82
-rw-r--r--spec/features/security/group/mixed_group_access_spec.rb83
-rw-r--r--spec/features/security/group/public_group_access_spec.rb82
-rw-r--r--spec/features/security/project/internal_access_spec.rb246
-rw-r--r--spec/features/security/project/private_access_spec.rb8
-rw-r--r--spec/features/security/project/public_access_spec.rb4
-rw-r--r--spec/finders/issues_finder_spec.rb58
-rw-r--r--spec/finders/merge_requests_finder_spec.rb33
-rw-r--r--spec/finders/projects_finder_spec.rb51
-rw-r--r--spec/helpers/application_helper_spec.rb83
-rw-r--r--spec/helpers/broadcast_messages_helper_spec.rb21
-rw-r--r--spec/helpers/gitlab_markdown_helper_spec.rb49
-rw-r--r--spec/helpers/notifications_helper_spec.rb8
-rw-r--r--spec/helpers/projects_helper_spec.rb12
-rw-r--r--spec/helpers/search_helper_spec.rb35
-rw-r--r--spec/helpers/submodule_helper_spec.rb118
-rw-r--r--spec/helpers/tab_helper_spec.rb4
-rw-r--r--spec/javascripts/stat_graph_contributors_graph_spec.js27
-rw-r--r--spec/javascripts/stat_graph_contributors_util_spec.js65
-rw-r--r--spec/javascripts/support/jasmine_helper.rb14
-rw-r--r--spec/lib/auth_spec.rb10
-rw-r--r--spec/lib/extracts_path_spec.rb2
-rw-r--r--spec/lib/gitlab/ldap/ldap_user_auth_spec.rb17
-rw-r--r--spec/lib/gitlab/popen_spec.rb20
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb2
-rw-r--r--spec/lib/gitlab/satellite/action_spec.rb2
-rw-r--r--spec/lib/gitlab/satellite/merge_action_spec.rb13
-rw-r--r--spec/lib/gitlab/upgrader_spec.rb24
-rw-r--r--spec/lib/oauth_spec.rb8
-rw-r--r--spec/mailers/notify_spec.rb226
-rw-r--r--spec/models/assembla_service_spec.rb52
-rw-r--r--spec/models/broadcast_message_spec.rb39
-rw-r--r--spec/models/commit_spec.rb2
-rw-r--r--spec/models/concerns/issuable_spec.rb7
-rw-r--r--spec/models/event_spec.rb4
-rw-r--r--spec/models/flowdock_service_spec.rb5
-rw-r--r--spec/models/forked_project_link_spec.rb4
-rw-r--r--spec/models/gemnasium_service_spec.rb47
-rw-r--r--spec/models/gitlab_ci_service_spec.rb1
-rw-r--r--spec/models/gollum_wiki_spec.rb6
-rw-r--r--spec/models/group_spec.rb15
-rw-r--r--spec/models/merge_request_spec.rb19
-rw-r--r--spec/models/note_spec.rb53
-rw-r--r--spec/models/project_hook_spec.rb19
-rw-r--r--spec/models/project_spec.rb35
-rw-r--r--spec/models/service_hook_spec.rb17
-rw-r--r--spec/models/service_spec.rb5
-rw-r--r--spec/models/slack_message_spec.rb56
-rw-r--r--spec/models/slack_service_spec.rb69
-rw-r--r--spec/models/system_hook_spec.rb17
-rw-r--r--spec/models/user_spec.rb117
-rw-r--r--spec/models/web_hook_spec.rb17
-rw-r--r--spec/models/wiki_page_spec.rb6
-rw-r--r--spec/observers/activity_observer_spec.rb61
-rw-r--r--spec/observers/email_observer_spec.rb17
-rw-r--r--spec/observers/issue_observer_spec.rb2
-rw-r--r--spec/observers/merge_request_observer_spec.rb32
-rw-r--r--spec/observers/note_observer_spec.rb2
-rw-r--r--spec/observers/user_observer_spec.rb2
-rw-r--r--spec/observers/users_group_observer_spec.rb7
-rw-r--r--spec/observers/users_project_observer_spec.rb55
-rw-r--r--spec/requests/api/commits_spec.rb87
-rw-r--r--spec/requests/api/files_spec.rb145
-rw-r--r--spec/requests/api/groups_spec.rb2
-rw-r--r--spec/requests/api/internal_spec.rb27
-rw-r--r--spec/requests/api/issues_spec.rb12
-rw-r--r--spec/requests/api/merge_requests_spec.rb57
-rw-r--r--spec/requests/api/namespaces_spec.rb31
-rw-r--r--spec/requests/api/project_hooks_spec.rb132
-rw-r--r--spec/requests/api/project_members_spec.rb156
-rw-r--r--spec/requests/api/projects_spec.rb425
-rw-r--r--spec/requests/api/repositories_spec.rb103
-rw-r--r--spec/requests/api/services_spec.rb33
-rw-r--r--spec/requests/api/session_spec.rb2
-rw-r--r--spec/requests/api/users_spec.rb2
-rw-r--r--spec/routing/project_routing_spec.rb8
-rw-r--r--spec/routing/routing_spec.rb36
-rw-r--r--spec/seed_project.tar.gzbin9795570 -> 9769010 bytes
-rw-r--r--spec/services/event_create_service_spec.rb103
-rw-r--r--spec/services/fork_service_spec.rb (renamed from spec/contexts/fork_context_spec.rb)6
-rw-r--r--spec/services/git_push_service_spec.rb35
-rw-r--r--spec/services/git_tag_push_service_spec.rb47
-rw-r--r--spec/services/issues/bulk_update_context_spec.rb (renamed from spec/contexts/issues/bulk_update_context_spec.rb)12
-rw-r--r--spec/services/notification_service_spec.rb60
-rw-r--r--spec/services/projects/create_service_spec.rb163
-rw-r--r--spec/services/projects/transfer_service_spec.rb (renamed from spec/services/project_transfer_service_spec.rb)0
-rw-r--r--spec/services/projects/update_service_spec.rb111
-rw-r--r--spec/services/search_service_spec.rb47
-rw-r--r--spec/services/system_hooks_service_spec.rb4
-rw-r--r--spec/services/test_hook_service_spec.rb14
-rw-r--r--spec/spec_helper.rb101
-rw-r--r--spec/support/chosen_helper.rb21
-rw-r--r--spec/support/login_helpers.rb2
-rw-r--r--spec/support/mentionable_shared_examples.rb6
-rw-r--r--spec/support/test_env.rb32
-rw-r--r--spec/support/valid_commit.rb1
-rw-r--r--spec/support/valid_commit_with_alt_email.rb6
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb11
-rw-r--r--spec/workers/post_receive_spec.rb4
115 files changed, 3769 insertions, 1119 deletions
diff --git a/spec/contexts/filter_context_spec.rb b/spec/contexts/filter_context_spec.rb
deleted file mode 100644
index db27742b9b5..00000000000
--- a/spec/contexts/filter_context_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-require 'spec_helper'
-
-describe FilterContext do
-
- let(:user) { create :user }
- let(:user2) { create :user }
- let(:project1) { create(:project, creator_id: user.id) }
- let(:project2) { create(:project, creator_id: user.id) }
- let(:merge_request1) { create(:merge_request, author_id: user.id, source_project: project1, target_project: project2) }
- let(:merge_request2) { create(:merge_request, author_id: user.id, source_project: project2, target_project: project1) }
- let(:merge_request3) { create(:merge_request, author_id: user.id, source_project: project2, target_project: project2) }
- let(:merge_request4) { create(:merge_request, author_id: user2.id, source_project: project2, target_project: project2, target_branch:"notes_refactoring") }
- let(:issue1) { create(:issue, assignee_id: user.id, project: project1) }
- let(:issue2) { create(:issue, assignee_id: user.id, project: project2) }
- let(:issue3) { create(:issue, assignee_id: user2.id, project: project2) }
-
- describe 'merge requests' do
- before :each do
- merge_request1
- merge_request2
- merge_request3
- merge_request4
- end
-
- it 'should by default filter properly' do
- merge_requests = user.cared_merge_requests
- params ={}
- merge_requests = FilterContext.new(merge_requests, params).execute
- merge_requests.size.should == 3
- end
-
- it 'should apply blocks passed in on creation to the filters' do
- merge_requests = user.cared_merge_requests
- params = {:project_id => project1.id}
- merge_requests = FilterContext.new(merge_requests, params).execute
- merge_requests.size.should == 1
- end
- end
-
- describe 'issues' do
- before :each do
- issue1
- issue2
- issue3
- end
- it 'should by default filter projects properly' do
- issues = user.assigned_issues
- params = {}
- issues = FilterContext.new(issues, params).execute
- issues.size.should == 2
- end
- it 'should apply blocks passed in on creation to the filters' do
- issues = user.assigned_issues
- params = {:project_id => project1.id}
- issues = FilterContext.new(issues, params).execute
- issues.size.should == 1
- end
- end
-end
diff --git a/spec/contexts/projects_create_context_spec.rb b/spec/contexts/projects_create_context_spec.rb
deleted file mode 100644
index 8b2a49dbee5..00000000000
--- a/spec/contexts/projects_create_context_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'spec_helper'
-
-describe Projects::CreateContext do
- before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
- after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
-
- describe :create_by_user do
- before do
- @user = create :user
- @opts = {
- name: "GitLab",
- namespace: @user.namespace
- }
- end
-
- context 'user namespace' do
- before do
- @project = create_project(@user, @opts)
- end
-
- it { @project.should be_valid }
- it { @project.owner.should == @user }
- it { @project.namespace.should == @user.namespace }
- end
-
- context 'group namespace' do
- before do
- @group = create :group
- @group.add_owner(@user)
-
- @opts.merge!(namespace_id: @group.id)
- @project = create_project(@user, @opts)
- end
-
- it { @project.should be_valid }
- it { @project.owner.should == @group }
- it { @project.namespace.should == @group }
- end
-
- context 'respect configured public setting' do
- before(:each) do
- @settings = double("settings")
- @settings.stub(:issues) { true }
- @settings.stub(:merge_requests) { true }
- @settings.stub(:wiki) { true }
- @settings.stub(:wall) { true }
- @settings.stub(:snippets) { true }
- stub_const("Settings", Class.new)
- Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings)
- end
-
- context 'should be public when setting is public' do
- before do
- @settings.stub(:public) { true }
- @project = create_project(@user, @opts)
- end
-
- it { @project.public.should be_true }
- end
-
- context 'should be private when setting is not public' do
- before do
- @settings.stub(:public) { false }
- @project = create_project(@user, @opts)
- end
-
- it { @project.public.should be_false }
- end
- end
- end
-
- def create_project(user, opts)
- Projects::CreateContext.new(user, opts).execute
- end
-end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index d528d12c66c..e1c0269b295 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -8,7 +8,7 @@ describe ApplicationController do
it 'should redirect if the user is over their password expiry' do
user.password_expires_at = Time.new(2002)
user.ldap_user?.should be_false
- controller.stub!(:current_user).and_return(user)
+ controller.stub(:current_user).and_return(user)
controller.should_receive(:redirect_to)
controller.should_receive(:new_profile_password_path)
controller.send(:check_password_expiration)
@@ -17,15 +17,15 @@ describe ApplicationController do
it 'should not redirect if the user is under their password expiry' do
user.password_expires_at = Time.now + 20010101
user.ldap_user?.should be_false
- controller.stub!(:current_user).and_return(user)
+ controller.stub(:current_user).and_return(user)
controller.should_not_receive(:redirect_to)
controller.send(:check_password_expiration)
end
it 'should not redirect if the user is over their password expiry but they are an ldap user' do
user.password_expires_at = Time.new(2002)
- user.stub!(:ldap_user?).and_return(true)
- controller.stub!(:current_user).and_return(user)
+ user.stub(:ldap_user?).and_return(true)
+ controller.stub(:current_user).and_return(user)
controller.should_not_receive(:redirect_to)
controller.send(:check_password_expiration)
end
diff --git a/spec/controllers/blob_controller_spec.rb b/spec/controllers/blob_controller_spec.rb
index 479d8fc1a1d..cea6922e1c3 100644
--- a/spec/controllers/blob_controller_spec.rb
+++ b/spec/controllers/blob_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::BlobController do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/commit_controller_spec.rb b/spec/controllers/commit_controller_spec.rb
index fdf0884f4e2..f5822157ea4 100644
--- a/spec/controllers/commit_controller_spec.rb
+++ b/spec/controllers/commit_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::CommitController do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:commit) { project.repository.commit("master") }
diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb
index 8263afc97a2..fbf4f29acfd 100644
--- a/spec/controllers/commits_controller_spec.rb
+++ b/spec/controllers/commits_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::CommitsController do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/merge_requests_controller_spec.rb b/spec/controllers/merge_requests_controller_spec.rb
index 69708edd8b1..1502bded97f 100644
--- a/spec/controllers/merge_requests_controller_spec.rb
+++ b/spec/controllers/merge_requests_controller_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Projects::MergeRequestsController do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
- let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, target_branch: "stable", source_branch: "master") }
before do
sign_in(user)
@@ -61,7 +61,7 @@ describe Projects::MergeRequestsController do
it "should really be a git email patch with commit" do
get :show, project_id: project.to_param, id: merge_request.iid, format: format
- expect(response.body[0..100]).to start_with("From #{merge_request.commits.last.id}")
+ expect(response.body[0..100]).to start_with("From 6ea87c47f0f8a24ae031c3fff17bc913889ecd00")
end
it "should contain git diffs" do
diff --git a/spec/controllers/profile_keys_controller_spec.rb b/spec/controllers/profile_keys_controller_spec.rb
new file mode 100644
index 00000000000..593d3e9eb56
--- /dev/null
+++ b/spec/controllers/profile_keys_controller_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+
+describe Profiles::KeysController do
+ let(:user) { create(:user) }
+
+ describe "#get_keys" do
+ describe "non existant user" do
+ it "should generally not work" do
+ get :get_keys, username: 'not-existent'
+
+ expect(response).not_to be_success
+ end
+ end
+
+ describe "user with no keys" do
+ it "should generally work" do
+ get :get_keys, username: user.username
+
+ expect(response).to be_success
+ end
+
+ it "should render all keys separated with a new line" do
+ get :get_keys, username: user.username
+
+ expect(response.body).to eq("")
+ end
+
+ it "should respond with text/plain content type" do
+ get :get_keys, username: user.username
+ expect(response.content_type).to eq("text/plain")
+ end
+ end
+
+ describe "user with keys" do
+ before do
+ user.keys << create(:key)
+ user.keys << create(:another_key)
+ end
+
+ it "should generally work" do
+ get :get_keys, username: user.username
+
+ expect(response).to be_success
+ end
+
+ it "should render all keys separated with a new line" do
+ get :get_keys, username: user.username
+
+ expect(response.body).not_to eq("")
+ expect(response.body).to eq(user.all_ssh_keys.join("\n"))
+ end
+
+ it "should respond with text/plain content type" do
+ get :get_keys, username: user.username
+ expect(response.content_type).to eq("text/plain")
+ end
+ end
+ end
+end
diff --git a/spec/controllers/tree_controller_spec.rb b/spec/controllers/tree_controller_spec.rb
index bb1232e6264..479118a3465 100644
--- a/spec/controllers/tree_controller_spec.rb
+++ b/spec/controllers/tree_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::TreeController do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/factories.rb b/spec/factories.rb
index 624cb0f7654..148477d6389 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -15,7 +15,7 @@ FactoryGirl.define do
email { Faker::Internet.email }
name
sequence(:username) { |n| "#{Faker::Internet.user_name}#{n}" }
- password "123456"
+ password "12345678"
password_confirmation { password }
confirmed_at { Time.now }
confirmation_token { nil }
@@ -27,49 +27,50 @@ FactoryGirl.define do
factory :admin, traits: [:admin]
end
- factory :project do
+ factory :empty_project, class: 'Project' do
sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') }
namespace
creator
- trait :source do
- sequence(:name) { |n| "source project#{n}" }
+ trait :public do
+ visibility_level Gitlab::VisibilityLevel::PUBLIC
end
- trait :target do
- sequence(:name) { |n| "target project#{n}" }
- end
-
- factory :source_project, traits: [:source]
- factory :target_project, traits: [:target]
- end
-
-
- factory :redmine_project, parent: :project do
- issues_tracker { "redmine" }
- issues_tracker_id { "project_name_in_redmine" }
- end
- factory :project_with_code, parent: :project do
- path { 'gitlabhq' }
-
- trait :source_path do
- path { 'source_gitlabhq' }
+ trait :internal do
+ visibility_level Gitlab::VisibilityLevel::INTERNAL
end
- trait :target_path do
- path { 'target_gitlabhq' }
+ trait :private do
+ visibility_level Gitlab::VisibilityLevel::PRIVATE
end
+ end
- factory :source_project_with_code, traits: [:source, :source_path]
- factory :target_project_with_code, traits: [:target, :target_path]
+ # Generates a test repository from the repository stored under `spec/seed_project.tar.gz`.
+ # Once you run `rake gitlab:setup`, you can see what the repository looks like under `tmp/repositories/gitlabhq`.
+ # In order to modify files in the repository, you must untar the seed, modify and remake the tar.
+ # Before recompressing, do not forget to `git checkout master`.
+ # After recompressing, you need to run `RAILS_ENV=test bundle exec rake gitlab:setup` to regenerate the seeds under tmp.
+ #
+ # If you want to modify the repository only for an specific type of tests, e.g., markdown tests,
+ # consider using a feature branch to reduce the chances of collision with other tests.
+ # Create a new commit, and use the same commit message that you will use for the change in the main repo.
+ # Changing the commig message and SHA of branch `master` may break tests.
+ factory :project, parent: :empty_project do
+ path { 'gitlabhq' }
after :create do |project|
TestEnv.clear_repo_dir(project.namespace, project.path)
+ TestEnv.reset_satellite_dir
TestEnv.create_repo(project.namespace, project.path)
end
end
+ factory :redmine_project, parent: :project do
+ issues_tracker { "redmine" }
+ issues_tracker_id { "project_name_in_redmine" }
+ end
+
factory :group do
sequence(:name) { |n| "group#{n}" }
path { name.downcase.gsub(/\s/, '_') }
@@ -108,25 +109,45 @@ FactoryGirl.define do
factory :merge_request do
title
author
- source_project factory: :source_project_with_code
- target_project factory: :target_project_with_code
+ source_project factory: :project
+ target_project { source_project }
+
+ # → git log stable..master --pretty=oneline
+ # b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828 tree css fixes
+ # 8716fc78f3c65bbf7bcf7b574febd583bc5d2812 Added loading animation for notes
+ # cd5c4bac5042c5469dcdf7e7b2f768d3c6fd7088 notes count for wall
+ # 8470d70da67355c9c009e4401746b1d5410af2e3 notes controller refactored
+ # 1e689bfba39525ead225eaf611948cfbe8ac34cf fixed notes logic
+ # f0f14c8eaba69ebddd766498a9d0b0e79becd633 finished scss refactoring
+ # 3a4b4fb4cde7809f033822a171b9feae19d41fff Moving ui styles to one scss file, Added ui class to body
+ # 065c200c33f68c2bb781e35a43f9dc8138a893b5 removed unnecessary hr tags & titles
+ # 1e8b111be85df0db6c8000ef9a710bc0221eae83 Merge branch 'master' of github.com:gitlabhq/gitlabhq
+ # f403da73f5e62794a0447aca879360494b08f678 Fixed ajax loading image. Fixed wrong wording
+ # e6ea73c77600d413d370249b8e392734f7d1dbee Merge pull request #468 from bencevans/patch-1
+ # 4a3c05b69355deee25767a74d0512ec4b510d4ef Merge pull request #470 from bgondy/patch-1
+ # 0347fe2412eb51d3efeccc35210e9268bc765ac5 Update app/views/projects/team.html.haml
+ # 2b5c61bdece1f7eb2b901ceea7d364065cdf76ac Title for a link fixed
+ # 460eeb13b7560b40104044973ff933b1a6dbbcaa Increased count of notes loaded when visit wall page
+ # 21c141afb1c53a9180a99d2cca29ffa613eb7e3a Merge branch 'notes_refactoring'
+ # 292a41cbe295f16f7148913b31eb0fb91f3251c3 Fixed comments for snippets. Tests fixed
+ # d41d8ffb02fa74fd4571603548bd7e401ec99e0c Reply button, Comments for Merge Request diff
+ # b1a36b552be2a7a6bc57fbed6c52dc6ed82111f8 Merge pull request #466 from skroutz/no-rbenv
+ # db75dae913e8365453ca231f101b067314a7ea71 Merge pull request #465 from skroutz/branches_commit_link
+ # 75f040fbfe4b5af23ff004ad3207c3976df097a8 Don't enforce rbenv version
+ # e42fb4fda475370dcb0d8f8f1268bfdc7a0cc437 Fix broken commit link in branches page
+ # 215a01f63ccdc085f75a48f6f7ab6f2b15b5852c move notes login to one controller
+ # 81092c01984a481e312de10a28e3f1a6dda182a3 Status codes for errors, New error pages
+ # 7d279f9302151e3c8f4c5df9c5200a72799409b9 better error handling for not found resource, gitolite error
+ # 9e6d0710e927aa8ea834b8a9ae9f277be617ac7d Merge pull request #443 from CedricGatay/fix/incorrectLineNumberingInDiff
+ # 6ea87c47f0f8a24ae031c3fff17bc913889ecd00 Incorrect line numbering in diff
+ #
+ # → git log master..stable --pretty=oneline
+ # empty
+
source_branch "master"
target_branch "stable"
- # pick 3 commits "at random" (from bcf03b5d~3 to bcf03b5d)
trait :with_diffs do
- target_branch "master" # pretend bcf03b5d~3
- source_branch "stable" # pretend bcf03b5d
- st_commits do
- [
- source_project.repository.commit('bcf03b5d').to_hash,
- source_project.repository.commit('bcf03b5d~1').to_hash,
- source_project.repository.commit('bcf03b5d~2').to_hash
- ]
- end
- st_diffs do
- source_project.repo.diff("bcf03b5d~3", "bcf03b5d")
- end
end
trait :closed do
@@ -137,6 +158,11 @@ FactoryGirl.define do
state :reopened
end
+ trait :simple do
+ source_branch "simple_merge_request"
+ target_branch "master"
+ end
+
factory :closed_merge_request, traits: [:closed]
factory :reopened_merge_request, traits: [:reopened]
factory :merge_request_with_diffs, traits: [:with_diffs]
@@ -152,10 +178,9 @@ FactoryGirl.define do
factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note]
factory :note_on_merge_request, traits: [:on_merge_request]
factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
- factory :note_on_merge_request_with_attachment, traits: [:on_merge_request, :with_attachment]
trait :on_commit do
- project factory: :project_with_code
+ project factory: :project
commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
noteable_type "Commit"
end
@@ -165,7 +190,7 @@ FactoryGirl.define do
end
trait :on_merge_request do
- project factory: :project_with_code
+ project factory: :project
noteable_id 1
noteable_type "MergeRequest"
end
@@ -208,12 +233,31 @@ FactoryGirl.define do
end
end
+ factory :another_key do
+ key do
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDmTillFzNTrrGgwaCKaSj+QCz81E6jBc/s9av0+3b1Hwfxgkqjl4nAK/OD2NjgyrONDTDfR8cRN4eAAy6nY8GLkOyYBDyuc5nTMqs5z3yVuTwf3koGm/YQQCmo91psZ2BgDFTor8SVEE5Mm1D1k3JDMhDFxzzrOtRYFPci9lskTJaBjpqWZ4E9rDTD2q/QZntCqbC3wE9uSemRQB5f8kik7vD/AD8VQXuzKladrZKkzkONCPWsXDspUitjM8HkQdOf0PsYn1CMUC1xKYbCxkg5TkEosIwGv6CoEArUrdu/4+10LVslq494mAvEItywzrluCLCnwELfW+h/m8UHoVhZ"
+ end
+ end
+
factory :invalid_key do
key do
"ssh-rsa this_is_invalid_key=="
end
end
end
+
+ factory :email do
+ user
+ email do
+ Faker::Internet.email('alias')
+ end
+
+ factory :another_email do
+ email do
+ Faker::Internet.email('another.alias')
+ end
+ end
+ end
factory :milestone do
title
diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb
new file mode 100644
index 00000000000..6339d5c4003
--- /dev/null
+++ b/spec/factories/broadcast_messages.rb
@@ -0,0 +1,27 @@
+# == Schema Information
+#
+# Table name: broadcast_messages
+#
+# id :integer not null, primary key
+# message :text default(""), not null
+# starts_at :datetime
+# ends_at :datetime
+# alert_type :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# color :string(255)
+# font :string(255)
+#
+
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :broadcast_message do
+ message "MyText"
+ starts_at "2013-11-12 13:43:25"
+ ends_at "2013-11-12 13:43:25"
+ alert_type 1
+ color "#555555"
+ font "#BBBBBB"
+ end
+end
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index 6f5d51d16b6..62f44690349 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -8,6 +8,11 @@ describe "Dashboard Issues Feed" do
let!(:issue1) { create(:issue, author: user, assignee: user, project: project1) }
let!(:issue2) { create(:issue, author: user, assignee: user, project: project2) }
+ before do
+ project1.team << [user, :master]
+ project2.team << [user, :master]
+ end
+
describe "atom feed" do
it "should render atom feed via private token" do
visit issues_dashboard_path(:atom, private_token: user.private_token)
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
index 2ea569a6208..a507f0314c6 100644
--- a/spec/features/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "GitLab Flavored Markdown" do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:fred) do
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 8cb984946b4..b9dab7846b1 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -43,6 +43,31 @@ describe "Issues" do
page.should have_content project.name
end
end
+
+ end
+
+ describe "Editing issue assignee" do
+ let!(:issue) do
+ create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project)
+ end
+
+ it 'allows user to select unasigned', :js => true do
+ visit edit_project_issue_path(project, issue)
+
+ page.should have_content "Assign to #{@user.name}"
+
+ page.first('#s2id_issue_assignee_id').click
+ sleep 2 # wait for ajax stuff to complete
+ page.first('.user-result').click
+
+ click_button "Save changes"
+
+ page.should have_content "Assignee: Select assignee"
+ issue.reload.assignee.should be_nil
+ end
end
describe "Filter issue" do
@@ -95,4 +120,185 @@ describe "Issues" do
page.should have_content 'gitlab'
end
end
+
+ describe 'filter issue' do
+ titles = ['foo','bar','baz']
+ titles.each_with_index do |title, index|
+ let!(title.to_sym) { create(:issue, title: title, project: project, created_at: Time.now - (index * 60)) }
+ end
+ let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') }
+ let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') }
+
+ it 'sorts by newest' do
+ visit project_issues_path(project, sort: 'newest')
+
+ first_issue.should include("foo")
+ last_issue.should include("baz")
+ end
+
+ it 'sorts by oldest' do
+ visit project_issues_path(project, sort: 'oldest')
+
+ first_issue.should include("baz")
+ last_issue.should include("foo")
+ end
+
+ it 'sorts by most recently updated' do
+ baz.updated_at = Time.now + 100
+ baz.save
+ visit project_issues_path(project, sort: 'recently_updated')
+
+ first_issue.should include("baz")
+ end
+
+ it 'sorts by least recently updated' do
+ baz.updated_at = Time.now - 100
+ baz.save
+ visit project_issues_path(project, sort: 'last_updated')
+
+ first_issue.should include("baz")
+ end
+
+ describe 'sorting by milestone' do
+ before :each do
+ foo.milestone = newer_due_milestone
+ foo.save
+ bar.milestone = later_due_milestone
+ bar.save
+ end
+
+ it 'sorts by recently due milestone' do
+ visit project_issues_path(project, sort: 'milestone_due_soon')
+
+ first_issue.should include("foo")
+ end
+
+ it 'sorts by least recently due milestone' do
+ visit project_issues_path(project, sort: 'milestone_due_later')
+
+ first_issue.should include("bar")
+ end
+ end
+
+ describe 'combine filter and sort' do
+ let(:user2) { create(:user) }
+
+ before :each do
+ foo.assignee = user2
+ foo.save
+ bar.assignee = user2
+ bar.save
+ end
+
+ it 'sorts with a filter applied' do
+ visit project_issues_path(project, sort: 'oldest', assignee_id: user2.id)
+
+ first_issue.should include("bar")
+ last_issue.should include("foo")
+ page.should_not have_content 'baz'
+ end
+ end
+ end
+
+ describe 'update assignee from issue#show' do
+ let(:issue) { create(:issue, project: project, author: @user) }
+
+ context 'by autorized user' do
+
+ it 'with dropdown menu' do
+ visit project_issue_path(project, issue)
+
+ find('.edit-issue.inline-update #issue_assignee_id').set project.team.members.first.id
+ click_button 'Update Issue'
+
+ page.should have_content "Assignee:"
+ page.has_select?('issue_assignee_id', :selected => project.team.members.first.name)
+ end
+ end
+
+ context 'by unauthorized user' do
+
+ let(:guest) { create(:user) }
+
+ before :each do
+ project.team << [[guest], :guest]
+ issue.assignee = @user
+ issue.save
+ end
+
+ it 'shows assignee text' do
+ logout
+ login_with guest
+
+ visit project_issue_path(project, issue)
+ page.should have_content issue.assignee.name
+ end
+ end
+ end
+
+ describe 'update milestone from issue#show' do
+ let!(:issue) { create(:issue, project: project, author: @user) }
+ let!(:milestone) { create(:milestone, project: project) }
+
+ context 'by authorized user' do
+
+ it 'with dropdown menu' do
+ visit project_issue_path(project, issue)
+
+ find('.edit-issue.inline-update').select(milestone.title, from: 'issue_milestone_id')
+ click_button 'Update Issue'
+
+ page.should have_content "Milestone"
+ page.has_select?('issue_assignee_id', :selected => milestone.title)
+ end
+ end
+
+ context 'by unauthorized user' do
+ let(:guest) { create(:user) }
+
+ before :each do
+ project.team << [guest, :guest]
+ issue.milestone = milestone
+ issue.save
+ end
+
+ it 'shows milestone text' do
+ logout
+ login_with guest
+
+ visit project_issue_path(project, issue)
+ page.should have_content milestone.title
+ end
+ end
+
+ describe 'removing assignee' do
+ let(:user2) { create(:user) }
+
+ before :each do
+ issue.assignee = user2
+ issue.save
+ end
+
+ it 'allows user to remove assignee', :js => true do
+ visit project_issue_path(project, issue)
+ page.should have_content "Assignee: #{user2.name}"
+
+ page.first('#s2id_issue_assignee_id').click
+ sleep 2 # wait for ajax stuff to complete
+ page.first('.user-result').click
+
+ page.should have_content "Assignee: Unassigned"
+ sleep 2 # wait for ajax stuff to complete
+ issue.reload.assignee.should be_nil
+ end
+ end
+ end
+
+ def first_issue
+ all("ul.issues-list li").first.text
+ end
+
+ def last_issue
+ all("ul.issues-list li").last.text
+ end
end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index d29bed4dea7..25a86b11fa9 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -1,14 +1,12 @@
require 'spec_helper'
describe "On a merge request", js: true do
- let!(:project) { create(:project_with_code) }
- let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let!(:note) { create(:note_on_merge_request_with_attachment, project: project) }
+ let!(:merge_request) { create(:merge_request, :simple) }
+ let!(:project) { merge_request.source_project }
+ let!(:note) { create(:note_on_merge_request, :with_attachment, project: project) }
before do
- login_as :user
- project.team << [@user, :master]
-
+ login_as :admin
visit project_merge_request_path(project, merge_request)
end
@@ -108,7 +106,7 @@ describe "On a merge request", js: true do
within("#note_#{note.id}") do
should have_css(".note-last-update small")
- find(".note-last-update small").text.should match(/Edited just now/)
+ find(".note-last-update small").text.should match(/Edited less than a minute ago/)
end
end
end
@@ -134,22 +132,20 @@ describe "On a merge request", js: true do
end
end
-describe "On a merge request diff", js: true, focus: true do
- let!(:project) { create(:source_project_with_code) }
- let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) }
+describe "On a merge request diff", js: true do
+ let(:merge_request) { create(:merge_request, :with_diffs, :simple) }
+ let(:project) { merge_request.source_project }
before do
- login_as :user
- project.team << [@user, :master]
+ login_as :admin
visit diffs_project_merge_request_path(project, merge_request)
end
-
subject { page }
describe "when adding a note" do
before do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
end
describe "the notes holder" do
@@ -159,22 +155,14 @@ describe "On a merge request diff", js: true, focus: true do
end
describe "the note form" do
- it 'should be valid' do
- within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" }
- within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s }
- within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" }
- within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" }
- should have_css(".js-close-discussion-note-form", text: "Cancel")
- end
-
it "shouldn't add a second form for same row" do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
- should have_css("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder form", count: 1)
+ should have_css("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder form", count: 1)
end
it "should be removed when canceled" do
- within(".file form[rel$='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185']") do
+ within(".diff-file form[rel$='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7']") do
find(".js-close-discussion-note-form").trigger("click")
end
@@ -184,12 +172,9 @@ describe "On a merge request diff", js: true, focus: true do
end
describe "with muliple note forms" do
- let!(:project) { create(:source_project_with_code) }
- let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) }
-
before do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
- find('a[data-line-code="342e16cbbd482ac2047dc679b2749d248cc1428f_18_17"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10"]').click
end
it { should have_css(".js-temp-notes-holder", count: 2) }
@@ -197,12 +182,12 @@ describe "On a merge request diff", js: true, focus: true do
describe "previewing them separately" do
before do
# add two separate texts and trigger previews on both
- within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "One comment on line 185"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "One comment on line 7"
find(".js-note-preview-button").trigger("click")
end
- within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "Another comment on line 17"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 10"
find(".js-note-preview-button").trigger("click")
end
end
@@ -210,14 +195,14 @@ describe "On a merge request diff", js: true, focus: true do
describe "posting a note" do
before do
- within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "Another comment on line 17"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 10"
click_button("Add Comment")
end
end
it 'should be added as discussion' do
- should have_content("Another comment on line 17")
+ should have_content("Another comment on line 10")
should have_css(".notes_holder")
should have_css(".notes_holder .note", count: 1)
should have_link("Reply")
diff --git a/spec/features/security/group_access_spec.rb b/spec/features/security/group/group_access_spec.rb
index dea957962a8..c262d76ab54 100644
--- a/spec/features/security/group_access_spec.rb
+++ b/spec/features/security/group/group_access_spec.rb
@@ -14,6 +14,7 @@ describe "Group access" do
let(:master) { create(:user) }
let(:reporter) { create(:user) }
let(:guest) { create(:user) }
+ let(:nonmember) { create(:user) }
before do
group.add_user(owner, Gitlab::Access::OWNER)
diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb
new file mode 100644
index 00000000000..79a6aee41b5
--- /dev/null
+++ b/spec/features/security/group/internal_group_access_spec.rb
@@ -0,0 +1,82 @@
+require 'spec_helper'
+
+describe "Group with internal project access" do
+ describe "Group" do
+ let(:group) { create(:group) }
+
+ let(:owner) { create(:owner) }
+ let(:master) { create(:user) }
+ let(:reporter) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:nonmember) { create(:user) }
+
+ before do
+ group.add_user(owner, Gitlab::Access::OWNER)
+ group.add_user(master, Gitlab::Access::MASTER)
+ group.add_user(reporter, Gitlab::Access::REPORTER)
+ group.add_user(guest, Gitlab::Access::GUEST)
+
+ create(:project, :internal, group: group)
+ end
+
+ describe "GET /groups/:path" do
+ subject { group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /groups/:path/issues" do
+ subject { issues_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /groups/:path/merge_requests" do
+ subject { merge_requests_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /groups/:path/members" do
+ subject { members_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /groups/:path/edit" do
+ subject { edit_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_denied_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb
new file mode 100644
index 00000000000..028cd32d2bb
--- /dev/null
+++ b/spec/features/security/group/mixed_group_access_spec.rb
@@ -0,0 +1,83 @@
+require 'spec_helper'
+
+describe "Group access" do
+ describe "Group" do
+ let(:group) { create(:group) }
+
+ let(:owner) { create(:owner) }
+ let(:master) { create(:user) }
+ let(:reporter) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:nonmember) { create(:user) }
+
+ before do
+ group.add_user(owner, Gitlab::Access::OWNER)
+ group.add_user(master, Gitlab::Access::MASTER)
+ group.add_user(reporter, Gitlab::Access::REPORTER)
+ group.add_user(guest, Gitlab::Access::GUEST)
+
+ create(:project, :internal, path: "internal_project", group: group)
+ create(:project, :public, path: "public_project", group: group)
+ end
+
+ describe "GET /groups/:path" do
+ subject { group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/issues" do
+ subject { issues_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/merge_requests" do
+ subject { merge_requests_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/members" do
+ subject { members_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/edit" do
+ subject { edit_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_denied_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb
new file mode 100644
index 00000000000..f0ed7649eb5
--- /dev/null
+++ b/spec/features/security/group/public_group_access_spec.rb
@@ -0,0 +1,82 @@
+require 'spec_helper'
+
+describe "Group with public project access" do
+ describe "Group" do
+ let(:group) { create(:group) }
+
+ let(:owner) { create(:owner) }
+ let(:master) { create(:user) }
+ let(:reporter) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:nonmember) { create(:user) }
+
+ before do
+ group.add_user(owner, Gitlab::Access::OWNER)
+ group.add_user(master, Gitlab::Access::MASTER)
+ group.add_user(reporter, Gitlab::Access::REPORTER)
+ group.add_user(guest, Gitlab::Access::GUEST)
+
+ create(:project, :public, group: group)
+ end
+
+ describe "GET /groups/:path" do
+ subject { group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/issues" do
+ subject { issues_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/merge_requests" do
+ subject { merge_requests_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/members" do
+ subject { members_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_allowed_for :visitor }
+ end
+
+ describe "GET /groups/:path/edit" do
+ subject { edit_group_path(group) }
+
+ it { should be_allowed_for owner }
+ it { should be_denied_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
new file mode 100644
index 00000000000..152cf66dcfd
--- /dev/null
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -0,0 +1,246 @@
+require 'spec_helper'
+
+describe "Internal Project Access" do
+ let(:project) { create(:project, :internal) }
+
+ let(:master) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:reporter) { create(:user) }
+
+ before do
+ # full access
+ project.team << [master, :master]
+
+ # readonly
+ project.team << [reporter, :reporter]
+ end
+
+ describe "Project should be internal" do
+ subject { project }
+
+ its(:internal?) { should be_true }
+ end
+
+ describe "GET /:project_path" do
+ subject { project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/tree/master" do
+ subject { project_tree_path(project, project.repository.root_ref) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/commits/master" do
+ subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/commit/:sha" do
+ subject { project_commit_path(project, project.repository.commit) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/compare" do
+ subject { project_compare_index_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/team" do
+ subject { project_team_index_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/wall" do
+ subject { project_wall_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/blob" do
+ before do
+ commit = project.repository.commit
+ path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
+ @blob_path = project_blob_path(project, File.join(commit.id, path))
+ end
+
+ it { @blob_path.should be_allowed_for master }
+ it { @blob_path.should be_allowed_for reporter }
+ it { @blob_path.should be_allowed_for :admin }
+ it { @blob_path.should be_allowed_for guest }
+ it { @blob_path.should be_allowed_for :user }
+ it { @blob_path.should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/edit" do
+ subject { edit_project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/deploy_keys" do
+ subject { project_deploy_keys_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/issues" do
+ subject { project_issues_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/snippets" do
+ subject { project_snippets_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/snippets/new" do
+ subject { new_project_snippet_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/merge_requests" do
+ subject { project_merge_requests_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/merge_requests/new" do
+ subject { new_project_merge_request_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/branches/recent" do
+ subject { recent_project_branches_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/branches" do
+ subject { project_branches_path(project) }
+
+ before do
+ # Speed increase
+ Project.any_instance.stub(:branches).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/tags" do
+ subject { project_tags_path(project) }
+
+ before do
+ # Speed increase
+ Project.any_instance.stub(:tags).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for guest }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /:project_path/hooks" do
+ subject { project_hooks_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_allowed_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+end
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index 7f3f8c50f02..0402ff39735 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "Private Project Access" do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
@@ -15,6 +15,12 @@ describe "Private Project Access" do
project.team << [reporter, :reporter]
end
+ describe "Project should be private" do
+ subject { project }
+
+ its(:private?) { should be_true }
+ end
+
describe "GET /:project_path" do
subject { project_path(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 267643fd8ef..7e6a39fad69 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "Public Project Access" do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
@@ -9,7 +9,7 @@ describe "Public Project Access" do
before do
# public project
- project.public = true
+ project.visibility_level = Gitlab::VisibilityLevel::PUBLIC
project.save!
# full access
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
new file mode 100644
index 00000000000..7489e56f423
--- /dev/null
+++ b/spec/finders/issues_finder_spec.rb
@@ -0,0 +1,58 @@
+require 'spec_helper'
+
+describe IssuesFinder do
+ let(:user) { create :user }
+ let(:user2) { create :user }
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
+ let(:issue1) { create(:issue, assignee: user, project: project1) }
+ let(:issue2) { create(:issue, assignee: user, project: project2) }
+ let(:issue3) { create(:issue, assignee: user2, project: project2) }
+
+ before do
+ project1.team << [user, :master]
+ project2.team << [user, :developer]
+ project2.team << [user2, :developer]
+ end
+
+ describe :execute do
+ before :each do
+ issue1
+ issue2
+ issue3
+ end
+
+ it 'should filter by all' do
+ params = { scope: "all", state: 'opened' }
+ issues = IssuesFinder.new.execute(user, params)
+ issues.size.should == 3
+ end
+
+ it 'should filter by assignee' do
+ params = { scope: "assigned-to-me", state: 'opened' }
+ issues = IssuesFinder.new.execute(user, params)
+ issues.size.should == 2
+ end
+
+ it 'should filter by project' do
+ params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id }
+ issues = IssuesFinder.new.execute(user, params)
+ issues.size.should == 1
+ end
+
+ it 'should be empty for unauthorized user' do
+ params = { scope: "all", state: 'opened' }
+ issues = IssuesFinder.new.execute(nil, params)
+ issues.size.should be_zero
+ end
+
+ it 'should not include unauthorized issues' do
+ params = { scope: "all", state: 'opened' }
+ issues = IssuesFinder.new.execute(user2, params)
+ issues.size.should == 2
+ issues.should_not include(issue1)
+ issues.should include(issue2)
+ issues.should include(issue3)
+ end
+ end
+end
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
new file mode 100644
index 00000000000..0bd2ccafcc1
--- /dev/null
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe MergeRequestsFinder do
+ let(:user) { create :user }
+ let(:user2) { create :user }
+
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
+
+ let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2) }
+ let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
+ let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2) }
+
+ before do
+ project1.team << [user, :master]
+ project2.team << [user, :developer]
+ project2.team << [user2, :developer]
+ end
+
+ describe "#execute" do
+ it 'should filter by scope' do
+ params = { scope: 'authored', state: 'opened' }
+ merge_requests = MergeRequestsFinder.new.execute(user, params)
+ merge_requests.size.should == 3
+ end
+
+ it 'should filter by project' do
+ params = { project_id: project1.id, scope: 'authored', state: 'opened' }
+ merge_requests = MergeRequestsFinder.new.execute(user, params)
+ merge_requests.size.should == 1
+ end
+ end
+end
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
new file mode 100644
index 00000000000..6e3ae4d615b
--- /dev/null
+++ b/spec/finders/projects_finder_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+describe ProjectsFinder do
+ let(:user) { create :user }
+ let(:group) { create :group }
+
+ let(:project1) { create(:empty_project, :public, group: group) }
+ let(:project2) { create(:empty_project, :internal, group: group) }
+ let(:project3) { create(:empty_project, :private, group: group) }
+ let(:project4) { create(:empty_project, :private, group: group) }
+
+ context 'non authenticated' do
+ subject { ProjectsFinder.new.execute(nil, group: group) }
+
+ it { should include(project1) }
+ it { should_not include(project2) }
+ it { should_not include(project3) }
+ it { should_not include(project4) }
+ end
+
+ context 'authenticated' do
+ subject { ProjectsFinder.new.execute(user, group: group) }
+
+ it { should include(project1) }
+ it { should include(project2) }
+ it { should_not include(project3) }
+ it { should_not include(project4) }
+ end
+
+ context 'authenticated, project member' do
+ before { project3.team << [user, :developer] }
+
+ subject { ProjectsFinder.new.execute(user, group: group) }
+
+ it { should include(project1) }
+ it { should include(project2) }
+ it { should include(project3) }
+ it { should_not include(project4) }
+ end
+
+ context 'authenticated, group member' do
+ before { group.add_user(user, Gitlab::Access::DEVELOPER) }
+
+ subject { ProjectsFinder.new.execute(user, group: group) }
+
+ it { should include(project1) }
+ it { should include(project2) }
+ it { should include(project3) }
+ it { should include(project4) }
+ end
+end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index d63a2de8806..61c561335e5 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe ApplicationHelper do
describe 'current_controller?' do
before do
- controller.stub!(:controller_name).and_return('foo')
+ controller.stub(:controller_name).and_return('foo')
end
it "returns true when controller matches argument" do
@@ -22,7 +22,7 @@ describe ApplicationHelper do
describe 'current_action?' do
before do
- stub!(:action_name).and_return('foo')
+ allow(self).to receive(:action_name).and_return('foo')
end
it "returns true when action matches argument" do
@@ -38,7 +38,24 @@ describe ApplicationHelper do
current_action?(:baz, :bar, :foo).should be_true
end
end
-
+
+ describe "group_icon" do
+ avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
+
+ it "should return an url for the avatar" do
+ group = create(:group)
+ group.avatar = File.open(avatar_file_path)
+ group.save!
+ group_icon(group.path).to_s.should == "/uploads/group/avatar/#{ group.id }/gitlab_logo.png"
+ end
+
+ it "should give default avatar_icon when no avatar is present" do
+ group = create(:group)
+ group.save!
+ group_icon(group.path).should match("group_avatar.png")
+ end
+ end
+
describe "avatar_icon" do
avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png')
@@ -52,7 +69,7 @@ describe ApplicationHelper do
it "should call gravatar_icon when no avatar is present" do
user = create(:user)
user.save!
- stub!(:gravatar_icon).and_return('gravatar_method_called')
+ allow(self).to receive(:gravatar_icon).and_return('gravatar_method_called')
avatar_icon(user.email).to_s.should == "gravatar_method_called"
end
end
@@ -62,50 +79,88 @@ describe ApplicationHelper do
it "should return a generic avatar path when Gravatar is disabled" do
Gitlab.config.gravatar.stub(:enabled).and_return(false)
- gravatar_icon(user_email).should == 'no_avatar.png'
+ gravatar_icon(user_email).should == '/assets/no_avatar.png'
end
it "should return a generic avatar path when email is blank" do
- gravatar_icon('').should == 'no_avatar.png'
+ gravatar_icon('').should == '/assets/no_avatar.png'
end
it "should return default gravatar url" do
- stub!(:request).and_return(double(:ssl? => false))
+ allow(self).to receive(:request).and_return(double(:ssl? => false))
gravatar_icon(user_email).should match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118')
end
it "should use SSL when appropriate" do
- stub!(:request).and_return(double(:ssl? => true))
+ allow(self).to receive(:request).and_return(double(:ssl? => true))
gravatar_icon(user_email).should match('https://secure.gravatar.com')
end
it "should return custom gravatar path when gravatar_url is set" do
- stub!(:request).and_return(double(:ssl? => false))
+ allow(self).to receive(:request).and_return(double(:ssl? => false))
Gitlab.config.gravatar.stub(:plain_url).and_return('http://example.local/?s=%{size}&hash=%{hash}')
gravatar_icon(user_email, 20).should == 'http://example.local/?s=20&hash=b58c6f14d292556214bd64909bcdb118'
end
it "should accept a custom size" do
- stub!(:request).and_return(double(:ssl? => false))
+ allow(self).to receive(:request).and_return(double(:ssl? => false))
gravatar_icon(user_email, 64).should match(/\?s=64/)
end
it "should use default size when size is wrong" do
- stub!(:request).and_return(double(:ssl? => false))
+ allow(self).to receive(:request).and_return(double(:ssl? => false))
gravatar_icon(user_email, nil).should match(/\?s=40/)
end
it "should be case insensitive" do
- stub!(:request).and_return(double(:ssl? => false))
+ allow(self).to receive(:request).and_return(double(:ssl? => false))
gravatar_icon(user_email).should == gravatar_icon(user_email.upcase + " ")
end
+ end
+
+ describe "grouped_options_refs" do
+ # Override Rails' grouped_options_for_select helper since HTML is harder to work with
+ def grouped_options_for_select(options, *args)
+ options
+ end
+
+ let(:options) { grouped_options_refs }
+ before do
+ # Must be an instance variable
+ @project = create(:project)
+ end
+
+ it "includes a list of branch names" do
+ options[0][0].should == 'Branches'
+ options[0][1].should include('master', 'stable')
+ end
+
+ it "includes a list of tag names" do
+ options[1][0].should == 'Tags'
+ options[1][1].should include('v0.9.4','v1.2.0')
+ end
+
+ it "includes a specific commit ref if defined" do
+ # Must be an instance variable
+ @ref = '2ed06dc41dbb5936af845b87d79e05bbf24c73b8'
+
+ options[2][0].should == 'Commit'
+ options[2][1].should == [@ref]
+ end
+
+ it "sorts tags in a natural order" do
+ # Stub repository.tag_names to make sure we get some valid testing data
+ expect(@project.repository).to receive(:tag_names).and_return(["v1.0.9", "v1.0.10", "v2.0", "v3.1.4.2", "v1.0.9a"])
+
+ options[1][1].should == ["v3.1.4.2", "v2.0", "v1.0.10", "v1.0.9a", "v1.0.9"]
+ end
end
describe "user_color_scheme_class" do
context "with current_user is nil" do
it "should return a string" do
- stub!(:current_user).and_return(nil)
+ allow(self).to receive(:current_user).and_return(nil)
user_color_scheme_class.should be_kind_of(String)
end
end
@@ -115,7 +170,7 @@ describe ApplicationHelper do
context "with color_scheme_id == #{color_scheme_id}" do
it "should return a string" do
current_user = double(:color_scheme_id => color_scheme_id)
- stub!(:current_user).and_return(current_user)
+ allow(self).to receive(:current_user).and_return(current_user)
user_color_scheme_class.should be_kind_of(String)
end
end
diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb
new file mode 100644
index 00000000000..1338ce4873d
--- /dev/null
+++ b/spec/helpers/broadcast_messages_helper_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe BroadcastMessagesHelper do
+ describe 'broadcast_styling' do
+ let(:broadcast_message) { double(color: "", font: "") }
+
+ context "default style" do
+ it "should have no style" do
+ broadcast_styling(broadcast_message).should match('')
+ end
+ end
+
+ context "customiezd style" do
+ before { broadcast_message.stub(color: "#f2dede", font: "#b94a48") }
+
+ it "should have a customized style" do
+ broadcast_styling(broadcast_message).should match('background-color:#f2dede;color:#b94a48')
+ end
+ end
+ end
+end
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index a0bbc026421..5bd16d1c16c 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -4,7 +4,7 @@ describe GitlabMarkdownHelper do
include ApplicationHelper
include IssuesHelper
- let!(:project) { create(:project_with_code) }
+ let!(:project) { create(:project) }
let(:user) { create(:user, username: 'gfm') }
let(:commit) { project.repository.commit }
@@ -16,6 +16,7 @@ describe GitlabMarkdownHelper do
before do
# Helper expects a @project instance variable
@project = project
+ @repository = project.repository
end
describe "#gfm" do
@@ -347,8 +348,21 @@ describe GitlabMarkdownHelper do
it "should handle references in headers" do
actual = "\n# Working around ##{issue.iid}\n## Apply !#{merge_request.iid}"
- markdown(actual).should match(%r{<h1[^<]*>Working around <a.+>##{issue.iid}</a></h1>})
- markdown(actual).should match(%r{<h2[^<]*>Apply <a.+>!#{merge_request.iid}</a></h2>})
+ markdown(actual, {no_header_anchors:true}).should match(%r{<h1[^<]*>Working around <a.+>##{issue.iid}</a></h1>})
+ markdown(actual, {no_header_anchors:true}).should match(%r{<h2[^<]*>Apply <a.+>!#{merge_request.iid}</a></h2>})
+ end
+
+ it "should add ids and links to headers" do
+ # Test every rule except nested tags.
+ text = '..Ab_c-d. e..'
+ id = 'ab_c-d-e'
+ markdown("# #{text}").should match(%r{<h1 id="#{id}">#{text}<a href="[^"]*##{id}"></a></h1>})
+ markdown("# #{text}", {no_header_anchors:true}).should == "<h1>#{text}</h1>"
+
+ id = 'link-text'
+ markdown("# [link text](url) ![img alt](url)").should match(
+ %r{<h1 id="#{id}"><a href="[^"]*url">link text</a> <img[^>]*><a href="[^"]*##{id}"></a></h1>}
+ )
end
it "should handle references in lists" do
@@ -378,9 +392,10 @@ describe GitlabMarkdownHelper do
it "should leave code blocks untouched" do
helper.stub(:user_color_scheme_class).and_return(:white)
- helper.markdown("\n some code from $#{snippet.id}\n here too\n").should include("<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>")
+ target_html = "\n<div class=\"highlighted-data white\">\n <div class=\"highlight\">\n <pre><code class=\"\">some code from $#{snippet.id}\nhere too\n</code></pre>\n </div>\n</div>\n\n"
- helper.markdown("\n```\nsome code from $#{snippet.id}\nhere too\n```\n").should include("<div class=\"white\"><div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre></div></div>")
+ helper.markdown("\n some code from $#{snippet.id}\n here too\n").should == target_html
+ helper.markdown("\n```\nsome code from $#{snippet.id}\nhere too\n```\n").should == target_html
end
it "should leave inline code untouched" do
@@ -392,7 +407,7 @@ describe GitlabMarkdownHelper do
end
it "should leave ref-like href of 'manual' links untouched" do
- markdown("why not [inspect !#{merge_request.iid}](http://example.tld/#!#{merge_request.iid})").should == "<p>why not <a href=\"http://example.tld/#!#{merge_request.iid}\">inspect </a><a href=\"#{project_merge_request_url(project, merge_request)}\" class=\"gfm gfm-merge_request \" title=\"Merge Request: #{merge_request.title}\">!#{merge_request.iid}</a><a href=\"http://example.tld/#!#{merge_request.iid}\"></a></p>\n"
+ markdown("why not [inspect !#{merge_request.iid}](http://example.tld/#!#{merge_request.iid})").should == "<p>why not <a href=\"http://example.tld/#!#{merge_request.iid}\">inspect </a><a class=\"gfm gfm-merge_request \" href=\"#{project_merge_request_url(project, merge_request)}\" title=\"Merge Request: #{merge_request.title}\">!#{merge_request.iid}</a><a href=\"http://example.tld/#!#{merge_request.iid}\"></a></p>\n"
end
it "should leave ref-like src of images untouched" do
@@ -425,16 +440,28 @@ describe GitlabMarkdownHelper do
markdown(actual).should match(expected)
end
- it "should handle wiki urls" do
- actual = "[Link](test/link)\n"
- expected = "<p><a href=\"/#{project.path_with_namespace}/wikis/test/link\">Link</a></p>\n"
+ it "should handle relative urls in reference links for a file in master" do
+ actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n"
+ expected = "<p><a href=\"/#{project.path_with_namespace}/blob/master/doc/api/README.md\">GitLab API doc</a></p>\n"
+ markdown(actual).should match(expected)
+ end
+
+ it "should handle relative urls in reference links for a directory in master" do
+ actual = "[GitLab API doc directory][GitLab readmes]\n [GitLab readmes]: doc/api/\n"
+ expected = "<p><a href=\"/#{project.path_with_namespace}/tree/master/doc/api\">GitLab API doc directory</a></p>\n"
+ markdown(actual).should match(expected)
+ end
+
+ it "should not handle malformed relative urls in reference links for a file in master" do
+ actual = "[GitLab readme]: doc/api/README.md\n"
+ expected = ""
markdown(actual).should match(expected)
end
end
describe "#render_wiki_content" do
before do
- @wiki = stub('WikiPage')
+ @wiki = double('WikiPage')
@wiki.stub(:content).and_return('wiki content')
end
@@ -448,7 +475,7 @@ describe GitlabMarkdownHelper do
it "should use the Gollum renderer for all other file types" do
@wiki.stub(:format).and_return(:rdoc)
- formatted_content_stub = stub('formatted_content')
+ formatted_content_stub = double('formatted_content')
formatted_content_stub.should_receive(:html_safe)
@wiki.stub(:formatted_content).and_return(formatted_content_stub)
diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb
index 328f66237c3..dce28525ca4 100644
--- a/spec/helpers/notifications_helper_spec.rb
+++ b/spec/helpers/notifications_helper_spec.rb
@@ -2,13 +2,13 @@ require 'spec_helper'
describe NotificationsHelper do
describe 'notification_icon' do
- let(:notification) { stub(disabled?: false, participating?: false, watch?: false) }
+ let(:notification) { double(disabled?: false, participating?: false, watch?: false) }
context "disabled notification" do
before { notification.stub(disabled?: true) }
it "has a red icon" do
- notification_icon(notification).should match('class="icon-circle cred"')
+ notification_icon(notification).should match('class="icon-volume-off cred"')
end
end
@@ -16,7 +16,7 @@ describe NotificationsHelper do
before { notification.stub(participating?: true) }
it "has a blue icon" do
- notification_icon(notification).should match('class="icon-circle cblue"')
+ notification_icon(notification).should match('class="icon-volume-down cblue"')
end
end
@@ -24,7 +24,7 @@ describe NotificationsHelper do
before { notification.stub(watch?: true) }
it "has a green icon" do
- notification_icon(notification).should match('class="icon-circle cgreen"')
+ notification_icon(notification).should match('class="icon-volume-up cgreen"')
end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 62f88dd522b..114058e3095 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -7,5 +7,17 @@ describe ProjectsHelper do
"<option value=\"redmine\">Redmine</option>\n" \
"<option value=\"gitlab\">GitLab</option>"
end
+
+ it "returns the correct issues trackers available with current tracker 'gitlab' selected" do
+ project_issues_trackers('gitlab').should ==
+ "<option value=\"redmine\">Redmine</option>\n" \
+ "<option selected=\"selected\" value=\"gitlab\">GitLab</option>"
+ end
+
+ it "returns the correct issues trackers available with current tracker 'redmine' selected" do
+ project_issues_trackers('redmine').should ==
+ "<option selected=\"selected\" value=\"redmine\">Redmine</option>\n" \
+ "<option value=\"gitlab\">GitLab</option>"
+ end
end
end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index 55b6b6b4dad..733f2754727 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -8,55 +8,46 @@ describe SearchHelper do
describe 'search_autocomplete_source' do
context "with no current user" do
- before { stub!(:current_user).and_return(nil) }
+ before do
+ allow(self).to receive(:current_user).and_return(nil)
+ end
it "it returns nil" do
- search_autocomplete_source.should be_nil
+ search_autocomplete_opts("q").should be_nil
end
end
context "with a user" do
let(:user) { create(:user) }
- let(:result) { JSON.parse(search_autocomplete_source) }
before do
- stub!(:current_user).and_return(user)
+ allow(self).to receive(:current_user).and_return(user)
end
it "includes Help sections" do
- result.select { |h| h['label'] =~ /^help:/ }.length.should == 9
+ search_autocomplete_opts("hel").size.should == 9
end
it "includes default sections" do
- result.count { |h| h['label'] =~ /^(My|Admin)\s/ }.should == 4
+ search_autocomplete_opts("adm").size.should == 1
end
it "includes the user's groups" do
create(:group).add_owner(user)
- result.count { |h| h['label'] =~ /^group:/ }.should == 1
+ search_autocomplete_opts("gro").size.should == 1
end
it "includes the user's projects" do
- create(:project, namespace: create(:namespace, owner: user))
- result.count { |h| h['label'] =~ /^project:/ }.should == 1
+ project = create(:project, namespace: create(:namespace, owner: user))
+ search_autocomplete_opts(project.name).size.should == 1
end
context "with a current project" do
- before { @project = create(:project_with_code) }
+ before { @project = create(:project) }
it "includes project-specific sections" do
- result.count { |h| h['label'] =~ /^#{@project.name_with_namespace} - / }.should == 11
- end
-
- it "uses @ref in urls if defined" do
- @ref = "foo_bar"
- result.count { |h| h['url'] == project_tree_path(@project, @ref) }.should == 1
- end
- end
-
- context "with no current project" do
- it "does not include project-specific sections" do
- result.count { |h| h['label'] =~ /Files$/ }.should == 0
+ search_autocomplete_opts("Files").size.should == 1
+ search_autocomplete_opts("Commits").size.should == 1
end
end
end
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
new file mode 100644
index 00000000000..20378b1b17d
--- /dev/null
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -0,0 +1,118 @@
+require 'spec_helper'
+
+describe SubmoduleHelper do
+ describe 'submodule links' do
+ let(:submodule_item) { double(id: 'hash', path: 'rack') }
+ let(:config) { Gitlab.config.gitlab }
+ let(:repo) { double() }
+
+ before do
+ self.instance_variable_set(:@repository, repo)
+ end
+
+ context 'submodule on self' do
+ before do
+ Gitlab.config.gitlab.stub(protocol: 'http') # set this just to be sure
+ end
+
+ it 'should detect ssh on standard port' do
+ Gitlab.config.gitlab.stub(ssh_port: 22) # set this just to be sure
+ stub_url([ config.user, '@', config.host, ':gitlab-org/gitlab-ce.git' ].join(''))
+ submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
+ end
+
+ it 'should detect ssh on non-standard port' do
+ Gitlab.config.gitlab_shell.stub(ssh_port: 2222)
+ Gitlab.config.gitlab_shell.stub(ssh_path_prefix: Settings.send(:build_gitlab_shell_ssh_path_prefix))
+ stub_url([ 'ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-ce.git' ].join(''))
+ submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
+ end
+
+ it 'should detect http on standard port' do
+ Gitlab.config.gitlab.stub(port: 80)
+ Gitlab.config.gitlab.stub(url: Settings.send(:build_gitlab_url))
+ stub_url([ 'http://', config.host, '/gitlab-org/gitlab-ce.git' ].join(''))
+ submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
+ end
+
+ it 'should detect http on non-standard port' do
+ Gitlab.config.gitlab.stub(port: 3000)
+ Gitlab.config.gitlab.stub(url: Settings.send(:build_gitlab_url))
+ stub_url([ 'http://', config.host, ':3000/gitlab-org/gitlab-ce.git' ].join(''))
+ submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
+ end
+
+ it 'should work with relative_url_root' do
+ Gitlab.config.gitlab.stub(port: 80) # set this just to be sure
+ Gitlab.config.gitlab.stub(relative_url_root: '/gitlab/root')
+ Gitlab.config.gitlab.stub(url: Settings.send(:build_gitlab_url))
+ stub_url([ 'http://', config.host, '/gitlab/root/gitlab-org/gitlab-ce.git' ].join(''))
+ submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
+ end
+ end
+
+ context 'submodule on github.com' do
+ it 'should detect ssh' do
+ stub_url('git@github.com:gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should detect http' do
+ stub_url('http://github.com/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should detect https' do
+ stub_url('https://github.com/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should return original with non-standard url' do
+ stub_url('http://github.com/gitlab-org/gitlab-ce')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+
+ stub_url('http://github.com/another/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+ end
+ end
+
+ context 'submodule on gitlab.com' do
+ it 'should detect ssh' do
+ stub_url('git@gitlab.com:gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should detect http' do
+ stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should detect https' do
+ stub_url('https://gitlab.com/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]
+ end
+
+ it 'should return original with non-standard url' do
+ stub_url('http://gitlab.com/gitlab-org/gitlab-ce')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+
+ stub_url('http://gitlab.com/another/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+ end
+ end
+
+ context 'submodule on unsupported' do
+ it 'should return original' do
+ stub_url('http://mygitserver.com/gitlab-org/gitlab-ce')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+
+ stub_url('http://mygitserver.com/gitlab-org/gitlab-ce.git')
+ submodule_links(submodule_item).should == [ repo.submodule_url_for, nil ]
+ end
+ end
+ end
+
+ def stub_url(url)
+ repo.stub(submodule_url_for: url)
+ end
+end
diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb
index ef8e4cf6375..fa8a3f554f7 100644
--- a/spec/helpers/tab_helper_spec.rb
+++ b/spec/helpers/tab_helper_spec.rb
@@ -5,8 +5,8 @@ describe TabHelper do
describe 'nav_link' do
before do
- controller.stub!(:controller_name).and_return('foo')
- stub!(:action_name).and_return('foo')
+ controller.stub(:controller_name).and_return('foo')
+ allow(self).to receive(:action_name).and_return('foo')
end
it "captures block output" do
diff --git a/spec/javascripts/stat_graph_contributors_graph_spec.js b/spec/javascripts/stat_graph_contributors_graph_spec.js
index 8d2e2038a55..1090cb7f620 100644
--- a/spec/javascripts/stat_graph_contributors_graph_spec.js
+++ b/spec/javascripts/stat_graph_contributors_graph_spec.js
@@ -88,19 +88,20 @@ describe("ContributorsGraph", function () {
describe("ContributorsMasterGraph", function () {
- describe("#process_dates", function () {
- it("gets and parses dates", function () {
- var graph = new ContributorsMasterGraph()
- var data = 'random data here'
- spyOn(graph, 'parse_dates')
- spyOn(graph, 'get_dates').andReturn("get")
- spyOn(ContributorsGraph,'set_dates').andCallThrough()
- graph.process_dates(data)
- expect(graph.parse_dates).toHaveBeenCalledWith(data)
- expect(graph.get_dates).toHaveBeenCalledWith(data)
- expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get")
- })
- })
+ // TODO: fix or remove
+ //describe("#process_dates", function () {
+ //it("gets and parses dates", function () {
+ //var graph = new ContributorsMasterGraph()
+ //var data = 'random data here'
+ //spyOn(graph, 'parse_dates')
+ //spyOn(graph, 'get_dates').andReturn("get")
+ //spyOn(ContributorsGraph,'set_dates').andCallThrough()
+ //graph.process_dates(data)
+ //expect(graph.parse_dates).toHaveBeenCalledWith(data)
+ //expect(graph.get_dates).toHaveBeenCalledWith(data)
+ //expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get")
+ //})
+ //})
describe("#get_dates", function () {
it("plucks the date field from data collection", function () {
diff --git a/spec/javascripts/stat_graph_contributors_util_spec.js b/spec/javascripts/stat_graph_contributors_util_spec.js
index 2e52479ccbb..9c1b588861d 100644
--- a/spec/javascripts/stat_graph_contributors_util_spec.js
+++ b/spec/javascripts/stat_graph_contributors_util_spec.js
@@ -54,16 +54,17 @@ describe("ContributorsStatGraphUtil", function () {
})
- describe("#store_commits", function () {
- var fake_total = "fake_total"
- var fake_by_author = "fake_by_author"
-
- it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- spyOn(ContributorsStatGraphUtil, 'add')
- ContributorsStatGraphUtil.store_commits(fake_total, fake_by_author)
- expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "commits", 1], ["fake_by_author", "commits", 1]])
- })
- })
+ // TODO: fix or remove
+ //describe("#store_commits", function () {
+ //var fake_total = "fake_total"
+ //var fake_by_author = "fake_by_author"
+
+ //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
+ //spyOn(ContributorsStatGraphUtil, 'add')
+ //ContributorsStatGraphUtil.store_commits(fake_total, fake_by_author)
+ //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "commits", 1], ["fake_by_author", "commits", 1]])
+ //})
+ //})
describe("#add", function () {
it("adds 1 to current test_field in collection", function () {
@@ -79,27 +80,29 @@ describe("ContributorsStatGraphUtil", function () {
})
})
- describe("#store_additions", function () {
- var fake_entry = {additions: 10}
- var fake_total= "fake_total"
- var fake_by_author = "fake_by_author"
- it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- spyOn(ContributorsStatGraphUtil, 'add')
- ContributorsStatGraphUtil.store_additions(fake_entry, fake_total, fake_by_author)
- expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "additions", 10], ["fake_by_author", "additions", 10]])
- })
- })
-
- describe("#store_deletions", function () {
- var fake_entry = {deletions: 10}
- var fake_total= "fake_total"
- var fake_by_author = "fake_by_author"
- it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
- spyOn(ContributorsStatGraphUtil, 'add')
- ContributorsStatGraphUtil.store_deletions(fake_entry, fake_total, fake_by_author)
- expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "deletions", 10], ["fake_by_author", "deletions", 10]])
- })
- })
+ // TODO: fix or remove
+ //describe("#store_additions", function () {
+ //var fake_entry = {additions: 10}
+ //var fake_total= "fake_total"
+ //var fake_by_author = "fake_by_author"
+ //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
+ //spyOn(ContributorsStatGraphUtil, 'add')
+ //ContributorsStatGraphUtil.store_additions(fake_entry, fake_total, fake_by_author)
+ //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "additions", 10], ["fake_by_author", "additions", 10]])
+ //})
+ //})
+
+ // TODO: fix or remove
+ //describe("#store_deletions", function () {
+ //var fake_entry = {deletions: 10}
+ //var fake_total= "fake_total"
+ //var fake_by_author = "fake_by_author"
+ //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () {
+ //spyOn(ContributorsStatGraphUtil, 'add')
+ //ContributorsStatGraphUtil.store_deletions(fake_entry, fake_total, fake_by_author)
+ //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "deletions", 10], ["fake_by_author", "deletions", 10]])
+ //})
+ //})
describe("#add_date", function () {
it("adds a date field to the collection", function () {
diff --git a/spec/javascripts/support/jasmine_helper.rb b/spec/javascripts/support/jasmine_helper.rb
index 34b418a9ca3..b4919802afe 100644
--- a/spec/javascripts/support/jasmine_helper.rb
+++ b/spec/javascripts/support/jasmine_helper.rb
@@ -1,5 +1,11 @@
-WebMock.allow_net_connect!
+#Use this file to set/override Jasmine configuration options
+#You can remove it if you don't need it.
+#This file is loaded *after* jasmine.yml is interpreted.
+#
+#Example: using a different boot file.
+#Jasmine.configure do |config|
+# config.boot_dir = '/absolute/path/to/boot_dir'
+# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
+#end
+#
-Jasmine.configure do |config|
- config.browser = :phantomjs
-end
diff --git a/spec/lib/auth_spec.rb b/spec/lib/auth_spec.rb
index e05fde95731..073b811c3fb 100644
--- a/spec/lib/auth_spec.rb
+++ b/spec/lib/auth_spec.rb
@@ -8,21 +8,21 @@ describe Gitlab::Auth do
@user = create(
:user,
username: 'john',
- password: '888777',
- password_confirmation: '888777'
+ password: '88877711',
+ password_confirmation: '88877711'
)
end
it "should find user by valid login/password" do
- gl_auth.find('john', '888777').should == @user
+ gl_auth.find('john', '88877711').should == @user
end
it "should not find user with invalid password" do
- gl_auth.find('john', 'invalid').should_not == @user
+ gl_auth.find('john', 'invalid11').should_not == @user
end
it "should not find user with invalid login and password" do
- gl_auth.find('jon', 'invalid').should_not == @user
+ gl_auth.find('jon', 'invalid11').should_not == @user
end
end
end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index aac72c63ea5..7b3818ea5c8 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -7,7 +7,7 @@ describe ExtractsPath do
before do
@project = project
- project.stub(repository: stub(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0']))
+ project.stub(repository: double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0']))
project.stub(path_with_namespace: 'gitlab/gitlab-ci')
end
diff --git a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb
index b1c583c0476..501642dca79 100644
--- a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb
+++ b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb
@@ -6,16 +6,17 @@ describe Gitlab::LDAP do
before do
Gitlab.config.stub(omniauth: {})
- @info = mock(
+ @info = double(
uid: '12djsak321',
name: 'John',
- email: 'john@mail.com'
+ email: 'john@mail.com',
+ nickname: 'john'
)
end
describe :find_for_ldap_auth do
before do
- @auth = mock(
+ @auth = double(
uid: '12djsak321',
info: @info,
provider: 'ldap'
@@ -25,7 +26,7 @@ describe Gitlab::LDAP do
it "should update credentials by email if missing uid" do
user = double('User')
User.stub find_by_extern_uid_and_provider: nil
- User.stub find_by_email: user
+ User.stub(:find_by).with(hash_including(email: anything())) { user }
user.should_receive :update_attributes
gl_auth.find_or_create(@auth)
end
@@ -35,8 +36,8 @@ describe Gitlab::LDAP do
value = Gitlab.config.ldap.allow_username_or_email_login
Gitlab.config.ldap['allow_username_or_email_login'] = true
User.stub find_by_extern_uid_and_provider: nil
- User.stub find_by_email: nil
- User.stub find_by_username: user
+ User.stub(:find_by).with(hash_including(email: anything())) { nil }
+ User.stub(:find_by).with(hash_including(username: anything())) { user }
user.should_receive :update_attributes
gl_auth.find_or_create(@auth)
Gitlab.config.ldap['allow_username_or_email_login'] = value
@@ -47,8 +48,8 @@ describe Gitlab::LDAP do
value = Gitlab.config.ldap.allow_username_or_email_login
Gitlab.config.ldap['allow_username_or_email_login'] = false
User.stub find_by_extern_uid_and_provider: nil
- User.stub find_by_email: nil
- User.stub find_by_username: user
+ User.stub(:find_by).with(hash_including(email: anything())) { nil }
+ User.stub(:find_by).with(hash_including(username: anything())) { user }
user.should_not_receive :update_attributes
gl_auth.find_or_create(@auth)
Gitlab.config.ldap['allow_username_or_email_login'] = value
diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
index 4791be41613..76d506eb3c0 100644
--- a/spec/lib/gitlab/popen_spec.rb
+++ b/spec/lib/gitlab/popen_spec.rb
@@ -10,7 +10,7 @@ describe 'Gitlab::Popen', no_db: true do
context 'zero status' do
before do
- @output, @status = @klass.new.popen('ls', path)
+ @output, @status = @klass.new.popen(%W(ls), path)
end
it { @status.should be_zero }
@@ -19,11 +19,27 @@ describe 'Gitlab::Popen', no_db: true do
context 'non-zero status' do
before do
- @output, @status = @klass.new.popen('cat NOTHING', path)
+ @output, @status = @klass.new.popen(%W(cat NOTHING), path)
end
it { @status.should == 1 }
it { @output.should include('No such file or directory') }
end
+
+ context 'unsafe string command' do
+ it 'raises an error when it gets called with a string argument' do
+ expect { @klass.new.popen('ls', path) }.to raise_error
+ end
+ end
+
+ context 'without a directory argument' do
+ before do
+ @output, @status = @klass.new.popen(%W(ls))
+ end
+
+ it { @status.should be_zero }
+ it { @output.should include('spec') }
+ end
+
end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 7d805f8c72a..19259a8b79c 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -43,7 +43,7 @@ describe Gitlab::ReferenceExtractor do
end
context 'with a project' do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
it 'accesses valid user objects on the project team' do
@u_foo = create(:user, username: 'foo')
diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb
index 5e0a825c3c3..d65e7c42b7e 100644
--- a/spec/lib/gitlab/satellite/action_spec.rb
+++ b/spec/lib/gitlab/satellite/action_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'Gitlab::Satellite::Action' do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
describe '#prepare_satellite!' do
diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb
index e40ff73b7f0..ef06c742846 100644
--- a/spec/lib/gitlab/satellite/merge_action_spec.rb
+++ b/spec/lib/gitlab/satellite/merge_action_spec.rb
@@ -2,20 +2,21 @@ require 'spec_helper'
describe 'Gitlab::Satellite::MergeAction' do
before(:each) do
-# TestEnv.init(mailer: false, init_repos: true, repos: true)
- @master = ['master', 'b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828']
+ @master = ['master', '69b34b7e9ad9f496f0ad10250be37d6265a03bba']
@one_after_stable = ['stable', '6ea87c47f0f8a24ae031c3fff17bc913889ecd00'] #this commit sha is one after stable
@wiki_branch = ['wiki', '635d3e09b72232b6e92a38de6cc184147e5bcb41'] #this is the commit sha where the wiki branch goes off from master
@conflicting_metior = ['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f'] #this branch conflicts with the wiki branch
- #these commits are quite close together, itended to make string diffs/format patches small
+ # these commits are quite close together, itended to make string diffs/format patches small
@close_commit1 = ['2_3_notes_fix', '8470d70da67355c9c009e4401746b1d5410af2e3']
@close_commit2 = ['scss_refactoring', 'f0f14c8eaba69ebddd766498a9d0b0e79becd633']
end
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project, namespace: create(:group)) }
+ let(:fork_project) { create(:project, namespace: create(:group)) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let(:merge_request_fork) { create(:merge_request) }
+ let(:merge_request_fork) { create(:merge_request, source_project: fork_project, target_project: project) }
+
describe '#commits_between' do
def verify_commits(commits, first_commit_sha, last_commit_sha)
commits.each { |commit| commit.class.should == Gitlab::Git::Commit }
@@ -145,4 +146,4 @@ describe 'Gitlab::Satellite::MergeAction' do
end
end
end
-end \ No newline at end of file
+end
diff --git a/spec/lib/gitlab/upgrader_spec.rb b/spec/lib/gitlab/upgrader_spec.rb
new file mode 100644
index 00000000000..2b254d6b3a6
--- /dev/null
+++ b/spec/lib/gitlab/upgrader_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe Gitlab::Upgrader do
+ let(:upgrader) { Gitlab::Upgrader.new }
+ let(:current_version) { Gitlab::VERSION }
+
+ describe 'current_version_raw' do
+ it { upgrader.current_version_raw.should == current_version }
+ end
+
+ describe 'latest_version?' do
+ it 'should be true if newest version' do
+ upgrader.stub(latest_version_raw: current_version)
+ upgrader.latest_version?.should be_true
+ end
+ end
+
+ describe 'latest_version_raw' do
+ it 'should be latest version for GitLab 5' do
+ upgrader.stub(current_version_raw: "5.3.0")
+ upgrader.latest_version_raw.should == "v5.4.2"
+ end
+ end
+end
diff --git a/spec/lib/oauth_spec.rb b/spec/lib/oauth_spec.rb
index e21074554b6..3dfe95a8e38 100644
--- a/spec/lib/oauth_spec.rb
+++ b/spec/lib/oauth_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::OAuth::User do
before do
Gitlab.config.stub(omniauth: {})
- @info = mock(
+ @info = double(
uid: '12djsak321',
name: 'John',
email: 'john@mail.com'
@@ -15,7 +15,7 @@ describe Gitlab::OAuth::User do
describe :create do
it "should create user from LDAP" do
- @auth = mock(info: @info, provider: 'ldap')
+ @auth = double(info: @info, provider: 'ldap')
user = gl_auth.create(@auth)
user.should be_valid
@@ -24,7 +24,7 @@ describe Gitlab::OAuth::User do
end
it "should create user from Omniauth" do
- @auth = mock(info: @info, provider: 'twitter')
+ @auth = double(info: @info, provider: 'twitter')
user = gl_auth.create(@auth)
user.should be_valid
@@ -33,7 +33,7 @@ describe Gitlab::OAuth::User do
end
it "should apply defaults to user" do
- @auth = mock(info: @info, provider: 'ldap')
+ @auth = double(info: @info, provider: 'ldap')
user = gl_auth.create(@auth)
user.should be_valid
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 666c6ccefff..22d60429ccd 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -4,8 +4,9 @@ describe Notify do
include EmailSpec::Helpers
include EmailSpec::Matchers
+ let(:gitlab_sender) { Gitlab.config.gitlab.email_from }
let(:recipient) { create(:user, email: 'recipient@example.com') }
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
shared_examples 'a multiple recipients email' do
it 'is sent to the given recipient' do
@@ -13,18 +14,28 @@ describe Notify do
end
end
+ shared_examples 'an email sent from GitLab' do
+ it 'is sent from GitLab' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq('GitLab')
+ sender.address.should eq(gitlab_sender)
+ end
+ end
+
describe 'for new users, the email' do
let(:example_site_path) { root_path }
let(:new_user) { create(:user, email: 'newguy@example.com', created_by_id: 1) }
subject { Notify.new_user_email(new_user.id, new_user.password) }
+ it_behaves_like 'an email sent from GitLab'
+
it 'is sent to the new user' do
should deliver_to new_user.email
end
it 'has the correct subject' do
- should have_subject /^gitlab \| Account was created for you$/i
+ should have_subject /^Account was created for you$/i
end
it 'contains the new user\'s login name' do
@@ -47,12 +58,14 @@ describe Notify do
subject { Notify.new_user_email(new_user.id, new_user.password) }
+ it_behaves_like 'an email sent from GitLab'
+
it 'is sent to the new user' do
should deliver_to new_user.email
end
it 'has the correct subject' do
- should have_subject /^gitlab \| Account was created for you$/i
+ should have_subject /^Account was created for you$/i
end
it 'contains the new user\'s login name' do
@@ -73,12 +86,14 @@ describe Notify do
subject { Notify.new_ssh_key_email(key.id) }
+ it_behaves_like 'an email sent from GitLab'
+
it 'is sent to the new user' do
should deliver_to key.user.email
end
it 'has the correct subject' do
- should have_subject /^gitlab \| SSH key was added to your account$/i
+ should have_subject /^SSH key was added to your account$/i
end
it 'contains the new ssh key title' do
@@ -90,19 +105,49 @@ describe Notify do
end
end
+ describe 'user added email' do
+ let(:email) { create(:email) }
+
+ subject { Notify.new_email_email(email.id) }
+
+ it 'is sent to the new user' do
+ should deliver_to email.user.email
+ end
+
+ it 'has the correct subject' do
+ should have_subject /^Email was added to your account$/i
+ end
+
+ it 'contains the new email address' do
+ should have_body_text /#{email.email}/
+ end
+
+ it 'includes a link to emails page' do
+ should have_body_text /#{profile_emails_path}/
+ end
+ end
+
context 'for a project' do
describe 'items that are assignable, the email' do
+ let(:current_user) { create(:user, email: "current@email.com") }
let(:assignee) { create(:user, email: 'assignee@example.com') }
let(:previous_assignee) { create(:user, name: 'Previous Assignee') }
shared_examples 'an assignee email' do
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(current_user.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
it 'is sent to the assignee' do
should deliver_to assignee.email
end
end
context 'for issues' do
- let(:issue) { create(:issue, assignee: assignee, project: project ) }
+ let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) }
+ let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: Faker::Lorem.sentence) }
describe 'that are new' do
subject { Notify.new_issue_email(issue.assignee_id, issue.id) }
@@ -110,7 +155,7 @@ describe Notify do
it_behaves_like 'an assignee email'
it 'has the correct subject' do
- should have_subject /#{project.name} \| new issue ##{issue.iid} \| #{issue.title}/
+ should have_subject /#{project.name} \| #{issue.title} \(##{issue.iid}\)/
end
it 'contains a link to the new issue' do
@@ -118,15 +163,27 @@ describe Notify do
end
end
- describe 'that have been reassigned' do
- before(:each) { issue.stub(:assignee_id_was).and_return(previous_assignee.id) }
+ describe 'that are new with a description' do
+ subject { Notify.new_issue_email(issue_with_description.assignee_id, issue_with_description.id) }
+
+ it 'contains the description' do
+ should have_body_text /#{issue_with_description.description}/
+ end
+ end
- subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id) }
+ describe 'that have been reassigned' do
+ subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user) }
it_behaves_like 'a multiple recipients email'
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(current_user.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
it 'has the correct subject' do
- should have_subject /changed issue ##{issue.iid} \| #{issue.title}/
+ should have_subject /#{issue.title} \(##{issue.iid}\)/
end
it 'contains the name of the previous assignee' do
@@ -143,12 +200,17 @@ describe Notify do
end
describe 'status changed' do
- let(:current_user) { create(:user, email: "current@email.com") }
let(:status) { 'closed' }
subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) }
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(current_user.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
it 'has the correct subject' do
- should have_subject /changed issue ##{issue.iid} \| #{issue.title}/i
+ should have_subject /#{issue.title} \(##{issue.iid}\)/i
end
it 'contains the new status' do
@@ -167,7 +229,9 @@ describe Notify do
end
context 'for merge requests' do
- let(:merge_request) { create(:merge_request, assignee: assignee, source_project: project, target_project: project) }
+ let(:merge_author) { create(:user) }
+ let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
+ let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) }
describe 'that are new' do
subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) }
@@ -175,7 +239,7 @@ describe Notify do
it_behaves_like 'an assignee email'
it 'has the correct subject' do
- should have_subject /new merge request !#{merge_request.iid}/
+ should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
end
it 'contains a link to the new merge request' do
@@ -191,15 +255,27 @@ describe Notify do
end
end
- describe 'that are reassigned' do
- before(:each) { merge_request.stub(:assignee_id_was).and_return(previous_assignee.id) }
+ describe 'that are new with a description' do
+ subject { Notify.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) }
+
+ it 'contains the description' do
+ should have_body_text /#{merge_request_with_description.description}/
+ end
+ end
- subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id) }
+ describe 'that are reassigned' do
+ subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) }
it_behaves_like 'a multiple recipients email'
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(current_user.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
it 'has the correct subject' do
- should have_subject /changed merge request !#{merge_request.iid}/
+ should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
end
it 'contains the name of the previous assignee' do
@@ -213,7 +289,30 @@ describe Notify do
it 'contains a link to the merge request' do
should have_body_text /#{project_merge_request_path project, merge_request}/
end
+ end
+
+ describe 'that are merged' do
+ subject { Notify.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) }
+
+ it_behaves_like 'a multiple recipients email'
+
+ it 'is sent as the merge author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(merge_author.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
+ it 'has the correct subject' do
+ should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+ end
+ it 'contains the new status' do
+ should have_body_text /merged/i
+ end
+
+ it 'contains a link to the merge request' do
+ should have_body_text /#{project_merge_request_path project, merge_request}/
+ end
end
end
end
@@ -223,8 +322,10 @@ describe Notify do
let(:user) { create(:user) }
subject { Notify.project_was_moved_email(project.id, user.id) }
+ it_behaves_like 'an email sent from GitLab'
+
it 'has the correct subject' do
- should have_subject /project was moved/
+ should have_subject /Project was moved/
end
it 'contains name of project' do
@@ -243,8 +344,11 @@ describe Notify do
project: project,
user: user) }
subject { Notify.project_access_granted_email(users_project.id) }
+
+ it_behaves_like 'an email sent from GitLab'
+
it 'has the correct subject' do
- should have_subject /access to project was granted/
+ should have_subject /Access to project was granted/
end
it 'contains name of project' do
should have_body_text /#{project.name}/
@@ -263,12 +367,14 @@ describe Notify do
end
shared_examples 'a note email' do
- it 'is sent to the given recipient' do
- should deliver_to recipient.email
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(note_author.name)
+ sender.address.should eq(gitlab_sender)
end
- it 'contains the name of the note\'s author' do
- should have_body_text /#{note_author.name}/
+ it 'is sent to the given recipient' do
+ should deliver_to recipient.email
end
it 'contains the message from the note' do
@@ -302,7 +408,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for commit #{commit.short_id}/
+ should have_subject /#{commit.title} \(#{commit.short_id}\)/
end
it 'contains a link to the commit' do
@@ -320,7 +426,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for merge request ##{merge_request.iid}/
+ should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
end
it 'contains a link to the merge request note' do
@@ -338,7 +444,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for issue ##{issue.iid}/
+ should have_subject /#{issue.title} \(##{issue.iid}\)/
end
it 'contains a link to the issue note' do
@@ -355,8 +461,10 @@ describe Notify do
subject { Notify.group_access_granted_email(membership.id) }
+ it_behaves_like 'an email sent from GitLab'
+
it 'has the correct subject' do
- should have_subject /access to group was granted/
+ should have_subject /Access to group was granted/
end
it 'contains name of project' do
@@ -367,4 +475,66 @@ describe Notify do
should have_body_text /#{membership.human_access}/
end
end
+
+ describe 'confirmation if email changed' do
+ let(:example_site_path) { root_path }
+ let(:user) { create(:user, email: 'old-email@mail.com') }
+
+ before do
+ user.email = "new-email@mail.com"
+ user.save
+ end
+
+ subject { ActionMailer::Base.deliveries.last }
+
+ it_behaves_like 'an email sent from GitLab'
+
+ it 'is sent to the new user' do
+ should deliver_to 'new-email@mail.com'
+ end
+
+ it 'has the correct subject' do
+ should have_subject "Confirmation instructions"
+ end
+
+ it 'includes a link to the site' do
+ should have_body_text /#{example_site_path}/
+ end
+ end
+
+ describe 'email on push' do
+ let(:example_site_path) { root_path }
+ let(:user) { create(:user) }
+ let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, 'cd5c4bac', 'b1e6a9db') }
+ let(:commits) { Commit.decorate(compare.commits) }
+ let(:diff_path) { project_compare_path(project, from: commits.first, to: commits.last) }
+
+ subject { Notify.repository_push_email(project.id, 'devs@company.name', user.id, 'master', compare) }
+
+ it 'is sent as the author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(user.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
+ it 'is sent to recipient' do
+ should deliver_to 'devs@company.name'
+ end
+
+ it 'has the correct subject' do
+ should have_subject /New push to repository/
+ end
+
+ it 'includes commits list' do
+ should have_body_text /tree css fixes/
+ end
+
+ it 'includes diffs' do
+ should have_body_text /Checkout wiki pages for installation information/
+ end
+
+ it 'contains a link to the diff' do
+ should have_body_text /#{diff_path}/
+ end
+ end
end
diff --git a/spec/models/assembla_service_spec.rb b/spec/models/assembla_service_spec.rb
new file mode 100644
index 00000000000..1730a64283a
--- /dev/null
+++ b/spec/models/assembla_service_spec.rb
@@ -0,0 +1,52 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+require 'spec_helper'
+
+describe AssemblaService do
+ describe "Associations" do
+ it { should belong_to :project }
+ it { should have_one :service_hook }
+ end
+
+ describe "Execute" do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ before do
+ @assembla_service = AssemblaService.new
+ @assembla_service.stub(
+ project_id: project.id,
+ project: project,
+ service_hook: true,
+ token: 'verySecret',
+ subdomain: 'project_name'
+ )
+ @sample_data = GitPushService.new.sample_data(project, user)
+ @api_url = 'https://atlas.assembla.com/spaces/project_name/github_tool?secret_key=verySecret'
+ WebMock.stub_request(:post, @api_url)
+ end
+
+ it "should call Assembla API" do
+ @assembla_service.execute(@sample_data)
+ WebMock.should have_requested(:post, @api_url).with(
+ body: /#{@sample_data[:before]}.*#{@sample_data[:after]}.*#{project.path}/
+ ).once
+ end
+ end
+end
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb
new file mode 100644
index 00000000000..cf0b36a2830
--- /dev/null
+++ b/spec/models/broadcast_message_spec.rb
@@ -0,0 +1,39 @@
+# == Schema Information
+#
+# Table name: broadcast_messages
+#
+# id :integer not null, primary key
+# message :text default(""), not null
+# starts_at :datetime
+# ends_at :datetime
+# alert_type :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# color :string(255)
+# font :string(255)
+#
+
+require 'spec_helper'
+
+describe BroadcastMessage do
+ subject { create(:broadcast_message) }
+
+ it { should be_valid }
+
+ describe :current do
+ it "should return last message if time match" do
+ broadcast_message = create(:broadcast_message, starts_at: Time.now.yesterday, ends_at: Time.now.tomorrow)
+ BroadcastMessage.current.should == broadcast_message
+ end
+
+ it "should return nil if time not come" do
+ broadcast_message = create(:broadcast_message, starts_at: Time.now.tomorrow, ends_at: Time.now + 2.days)
+ BroadcastMessage.current.should be_nil
+ end
+
+ it "should return nil if time has passed" do
+ broadcast_message = create(:broadcast_message, starts_at: Time.now - 2.days, ends_at: Time.now.yesterday)
+ BroadcastMessage.current.should be_nil
+ end
+ end
+end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index fa556f94a1d..d8ab171d3ee 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Commit do
- let(:project) { create :project_with_code }
+ let(:project) { create :project }
let(:commit) { project.repository.commit }
describe '#title' do
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 852146ebaec..9cbc8990676 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -25,16 +25,11 @@ describe Issue, "Issuable" do
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]
+ described_class.search('able').should == [searchable_issue]
end
end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index 85bdf08ae64..53ede0d5ee9 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -67,12 +67,12 @@ describe Event do
end
describe 'Team events' do
- let(:user_project) { stub.as_null_object }
+ let(:user_project) { double.as_null_object }
let(:observer) { UsersProjectObserver.instance }
before {
Event.should_receive :create
- observer.stub(notification: stub.as_null_object)
+ observer.stub(notification: double.as_null_object)
}
describe "Joined project team" do
diff --git a/spec/models/flowdock_service_spec.rb b/spec/models/flowdock_service_spec.rb
index b22193c9e93..97414585331 100644
--- a/spec/models/flowdock_service_spec.rb
+++ b/spec/models/flowdock_service_spec.rb
@@ -11,6 +11,9 @@
# updated_at :datetime not null
# active :boolean default(FALSE), not null
# project_url :string(255)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
#
require 'spec_helper'
@@ -23,7 +26,7 @@ describe FlowdockService do
describe "Execute" do
let(:user) { create(:user) }
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
before do
@flowdock_service = FlowdockService.new
diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb
index 44b8c6155be..e719e3bfcc8 100644
--- a/spec/models/forked_project_link_spec.rb
+++ b/spec/models/forked_project_link_spec.rb
@@ -58,8 +58,8 @@ describe :forked_from_project do
end
def fork_project(from_project, user)
- context = Projects::ForkContext.new(from_project, user)
- shell = mock("gitlab_shell")
+ context = Projects::ForkService.new(from_project, user)
+ shell = double("gitlab_shell")
shell.stub(fork_repository: true)
context.stub(gitlab_shell: shell)
context.execute
diff --git a/spec/models/gemnasium_service_spec.rb b/spec/models/gemnasium_service_spec.rb
new file mode 100644
index 00000000000..dfc99849d60
--- /dev/null
+++ b/spec/models/gemnasium_service_spec.rb
@@ -0,0 +1,47 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+require 'spec_helper'
+
+describe GemnasiumService do
+ describe "Associations" do
+ it { should belong_to :project }
+ it { should have_one :service_hook }
+ end
+
+ describe "Execute" do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ before do
+ @gemnasium_service = GemnasiumService.new
+ @gemnasium_service.stub(
+ project_id: project.id,
+ project: project,
+ service_hook: true,
+ token: 'verySecret',
+ api_key: 'GemnasiumUserApiKey'
+ )
+ @sample_data = GitPushService.new.sample_data(project, user)
+ end
+ it "should call Gemnasium service" do
+ Gemnasium::GitlabService.should_receive(:execute).with(an_instance_of(Hash)).once
+ @gemnasium_service.execute(@sample_data)
+ end
+ end
+end
diff --git a/spec/models/gitlab_ci_service_spec.rb b/spec/models/gitlab_ci_service_spec.rb
index 56efa9df457..8ec15cb3466 100644
--- a/spec/models/gitlab_ci_service_spec.rb
+++ b/spec/models/gitlab_ci_service_spec.rb
@@ -13,6 +13,7 @@
# project_url :string(255)
# subdomain :string(255)
# room :string(255)
+# api_key :string(255)
#
require 'spec_helper'
diff --git a/spec/models/gollum_wiki_spec.rb b/spec/models/gollum_wiki_spec.rb
index 9e07d9ee191..9b9d15b4ff4 100644
--- a/spec/models/gollum_wiki_spec.rb
+++ b/spec/models/gollum_wiki_spec.rb
@@ -2,12 +2,6 @@ require "spec_helper"
describe GollumWiki do
- def create_temp_repo(path)
- FileUtils.mkdir_p path
- command = "git init --quiet #{path};"
- system(command)
- end
-
def remove_temp_repo(path)
FileUtils.rm_rf path
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 12b84700eb1..686e43d8d10 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -54,4 +54,19 @@ describe Group do
group.users_groups.guests.map(&:user).should_not include(user)
end
end
+
+ describe :avatar_type do
+ let(:user) { create(:user) }
+ before { group.add_user(user, UsersGroup::MASTER) }
+
+ it "should be true if avatar is image" do
+ group.update_attribute(:avatar, 'uploads/avatar.png')
+ group.avatar_type.should be_true
+ end
+
+ it "should be false if avatar is html page" do
+ group.update_attribute(:avatar, 'uploads/avatar.html')
+ group.avatar_type.should == ["only images allowed"]
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index b17183a281c..f1ad679b658 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -73,14 +73,13 @@ describe MergeRequest do
describe '#for_fork?' do
it 'returns true if the merge request is for a fork' do
- subject.source_project = create(:source_project)
- subject.target_project = create(:target_project)
+ subject.source_project = create(:project, namespace: create(:group))
+ subject.target_project = create(:project, namespace: create(:group))
subject.for_fork?.should be_true
end
+
it 'returns false if is not for a fork' do
- subject.source_project = create(:source_project)
- subject.target_project = subject.source_project
subject.for_fork?.should be_false
end
end
@@ -107,22 +106,22 @@ describe MergeRequest do
describe 'detection of issues to be closed' do
let(:issue0) { create :issue, project: subject.project }
let(:issue1) { create :issue, project: subject.project }
- let(:commit0) { mock('commit0', closes_issues: [issue0]) }
- let(:commit1) { mock('commit1', closes_issues: [issue0]) }
- let(:commit2) { mock('commit2', closes_issues: [issue1]) }
+ let(:commit0) { double('commit0', closes_issues: [issue0]) }
+ let(:commit1) { double('commit1', closes_issues: [issue0]) }
+ let(:commit2) { double('commit2', closes_issues: [issue1]) }
before do
- subject.stub(unmerged_commits: [commit0, commit1, commit2])
+ subject.stub(commits: [commit0, commit1, commit2])
end
it 'accesses the set of issues that will be closed on acceptance' do
- subject.project.default_branch = subject.target_branch
+ subject.project.stub(default_branch: subject.target_branch)
subject.closes_issues.should == [issue0, issue1].sort_by(&:id)
end
it 'only lists issues as to be closed if it targets the default branch' do
- subject.project.default_branch = 'master'
+ subject.project.stub(default_branch: 'master')
subject.target_branch = 'something-else'
subject.closes_issues.should be_empty
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 42c405d8e50..6be8a6a13f6 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -61,6 +61,11 @@ describe Note do
note.should be_upvote
end
+ it "recognizes a thumbsup emoji as a vote" do
+ note = build(:votable_note, note: ":thumbsup: for this")
+ note.should be_upvote
+ end
+
it "recognizes a -1 note" do
note = create(:votable_note, note: "-1 for this")
note.should be_downvote
@@ -70,6 +75,11 @@ describe Note do
note = build(:votable_note, note: ":-1: for this")
note.should be_downvote
end
+
+ it "recognizes a thumbsdown emoji as a vote" do
+ note = build(:votable_note, note: ":thumbsdown: for this")
+ note.should be_downvote
+ end
end
let(:project) { create(:project) }
@@ -170,8 +180,33 @@ describe Note do
end
end
+ describe '#create_assignee_change_note' do
+ let(:project) { create(:project) }
+ let(:thing) { create(:issue, project: project) }
+ let(:author) { create(:user) }
+ let(:assignee) { create(:user) }
+
+ subject { Note.create_assignee_change_note(thing, project, author, assignee) }
+
+ context 'creates and saves a Note' do
+ it { should be_a Note }
+ its(:id) { should_not be_nil }
+ end
+
+ its(:noteable) { should == thing }
+ its(:project) { should == thing.project }
+ its(:author) { should == author }
+ its(:note) { should =~ /Reassigned to @#{assignee.username}/ }
+
+ context 'assignee is removed' do
+ let(:assignee) { nil }
+
+ its(:note) { should =~ /Assignee removed/ }
+ end
+ end
+
describe '#create_cross_reference_note' do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:author) { create(:user) }
let(:issue) { create(:issue, project: project) }
let(:mergereq) { create(:merge_request, target_project: project) }
@@ -215,6 +250,16 @@ describe Note do
its(:project) { should == project }
its(:note) { should == "_mentioned in merge request !#{mergereq.iid}_" }
end
+
+ context 'commit from issue' do
+ subject { Note.create_cross_reference_note(commit, issue, author, project) }
+
+ it { should be_valid }
+ its(:noteable_type) { should == "Commit" }
+ its(:noteable_id) { should be_nil }
+ its(:commit_id) { should == commit.id }
+ its(:note) { should == "_mentioned in issue ##{issue.iid}_" }
+ end
end
describe '#cross_reference_exists?' do
@@ -242,6 +287,7 @@ describe Note do
let(:issue) { create(:issue, project: project) }
let(:other) { create(:issue, project: project) }
let(:author) { create(:user) }
+ let(:assignee) { create(:user) }
it 'should recognize user-supplied notes as non-system' do
@note = create(:note_on_issue)
@@ -257,6 +303,11 @@ describe Note do
@note = Note.create_cross_reference_note(issue, other, author, project)
@note.should be_system
end
+
+ it 'should identify assignee-change notes as system notes' do
+ @note = Note.create_assignee_change_note(issue, project, author, assignee)
+ @note.should be_system
+ end
end
describe :authorization do
diff --git a/spec/models/project_hook_spec.rb b/spec/models/project_hook_spec.rb
new file mode 100644
index 00000000000..7bd7c431bcd
--- /dev/null
+++ b/spec/models/project_hook_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe ProjectHook do
+ describe '.push_hooks' do
+ it 'should return hooks for push events only' do
+ hook = create(:project_hook, push_events: true)
+ hook2 = create(:project_hook, push_events: false)
+ expect(ProjectHook.push_hooks).to eq([hook])
+ end
+ end
+
+ describe '.tag_push_hooks' do
+ it 'should return hooks for tag push events only' do
+ hook = create(:project_hook, tag_push_events: true)
+ hook2 = create(:project_hook, tag_push_events: false)
+ expect(ProjectHook.tag_push_hooks).to eq([hook])
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 88ea6926790..839350bafbf 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -9,19 +9,19 @@
# created_at :datetime not null
# updated_at :datetime not null
# creator_id :integer
-# default_branch :string(255)
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
-# public :boolean default(FALSE), not null
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
# imported :boolean default(FALSE), not null
# import_url :string(255)
+# visibility_level :integer default(0), not null
+# archived :boolean default(FALSE), not null
#
require 'spec_helper'
@@ -47,6 +47,7 @@ describe Project do
it { should have_many(:hooks).dependent(:destroy) }
it { should have_many(:protected_branches).dependent(:destroy) }
it { should have_one(:forked_project_link).dependent(:destroy) }
+ it { should have_one(:slack_service).dependent(:destroy) }
end
describe "Mass assignment" do
@@ -71,7 +72,7 @@ describe Project do
it "should not allow new projects beyond user limits" do
project2 = build(:project)
- project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0))
+ project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
project2.should_not be_valid
project2.errors[:limit_reached].first.should match(/Your own projects limit is 0/)
end
@@ -99,6 +100,11 @@ describe Project do
project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
end
+ it "returns the web URL without the protocol for this repo" do
+ project = Project.new(path: "somewhere")
+ project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split("://")[1]}/somewhere"
+ end
+
describe "last_activity methods" do
let(:project) { create(:project) }
let(:last_event) { double(created_at: Time.now) }
@@ -123,7 +129,7 @@ describe Project do
end
describe :update_merge_requests do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
before do
@merge_request = create(:merge_request, source_project: project, target_project: project)
@@ -131,18 +137,17 @@ describe Project do
end
it "should close merge request if last commit from source branch was pushed to target branch" do
- @merge_request.reloaded_commits
- @merge_request.last_commit.id.should == "b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828"
- project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828", "refs/heads/stable", @key.user)
+ @merge_request.reload_code
+ @merge_request.last_commit.id.should == "69b34b7e9ad9f496f0ad10250be37d6265a03bba"
+ project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "69b34b7e9ad9f496f0ad10250be37d6265a03bba", "refs/heads/stable", @key.user)
@merge_request.reload
@merge_request.merged?.should be_true
end
it "should update merge request commits with new one if pushed to source branch" do
- @merge_request.last_commit.should == nil
- project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828", "refs/heads/master", @key.user)
+ project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "69b34b7e9ad9f496f0ad10250be37d6265a03bba", "refs/heads/master", @key.user)
@merge_request.reload
- @merge_request.last_commit.id.should == "b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828"
+ @merge_request.last_commit.id.should == "69b34b7e9ad9f496f0ad10250be37d6265a03bba"
end
end
@@ -151,10 +156,10 @@ describe Project do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
- @project = create(:project, name: 'gitlab-ci', namespace: @group)
+ @project = create(:project, name: 'gitlabhq', namespace: @group)
end
- it { Project.find_with_namespace('gitlab/gitlab-ci').should == @project }
+ it { Project.find_with_namespace('gitlab/gitlabhq').should == @project }
it { Project.find_with_namespace('gitlab-ci').should be_nil }
end
end
@@ -163,10 +168,10 @@ describe Project do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
- @project = create(:project, name: 'gitlab-ci', namespace: @group)
+ @project = create(:project, name: 'gitlabhq', namespace: @group)
end
- it { @project.to_param.should == "gitlab/gitlab-ci" }
+ it { @project.to_param.should == "gitlab/gitlabhq" }
end
end
@@ -232,7 +237,7 @@ describe Project do
end
describe :open_branches do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
before do
project.protected_branches.create(name: 'master')
diff --git a/spec/models/service_hook_spec.rb b/spec/models/service_hook_spec.rb
index 0b0262c97f1..40a5fbc71d9 100644
--- a/spec/models/service_hook_spec.rb
+++ b/spec/models/service_hook_spec.rb
@@ -2,13 +2,16 @@
#
# Table name: web_hooks
#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime not null
-# updated_at :datetime not null
-# type :string(255) default("ProjectHook")
-# service_id :integer
+# id :integer not null, primary key
+# url :string(255)
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# type :string(255) default("ProjectHook")
+# service_id :integer
+# push_events :boolean default(TRUE), not null
+# issues_events :boolean default(FALSE), not null
+# merge_requests_events :boolean default(FALSE), not null
#
require "spec_helper"
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index 667c80bcf19..94542074967 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -13,6 +13,7 @@
# project_url :string(255)
# subdomain :string(255)
# room :string(255)
+# api_key :string(255)
#
require 'spec_helper'
@@ -44,12 +45,12 @@ describe Service do
end
describe :can_test do
- it { @testable.should == false }
+ it { @testable.should == true }
end
end
describe "With commits" do
- let (:project) { create :project_with_code }
+ let (:project) { create :project }
before do
@service.stub(
diff --git a/spec/models/slack_message_spec.rb b/spec/models/slack_message_spec.rb
new file mode 100644
index 00000000000..b39cd4edf82
--- /dev/null
+++ b/spec/models/slack_message_spec.rb
@@ -0,0 +1,56 @@
+require_relative '../../app/models/project_services/slack_message'
+
+describe SlackMessage do
+ subject { SlackMessage.new(args) }
+
+ let(:args) {
+ {
+ after: 'after',
+ before: 'before',
+ project_name: 'project_name',
+ ref: 'refs/heads/master',
+ user_name: 'user_name',
+ project_url: 'url'
+ }
+ }
+
+ context 'push' do
+ before do
+ args[:commits] = [
+ { message: 'message1', url: 'url1', id: 'abcdefghi' },
+ { message: 'message2', url: 'url2', id: '123456789' },
+ ]
+ end
+
+ it 'returns a message regarding pushes' do
+ subject.compose.should ==
+ 'user_name pushed to branch <url/commits/master|master> of ' <<
+ '<url|project_name> (<url/compare/before...after|Compare changes>)' <<
+ "\n - message1 (<url1|abcdef>)" <<
+ "\n - message2 (<url2|123456>)"
+ end
+ end
+
+ context 'new branch' do
+ before do
+ args[:before] = '000000'
+ end
+
+ it 'returns a message regarding a new branch' do
+ subject.compose.should ==
+ 'user_name pushed new branch <url/commits/master|master> to ' <<
+ '<url|project_name>'
+ end
+ end
+
+ context 'removed branch' do
+ before do
+ args[:after] = '000000'
+ end
+
+ it 'returns a message regarding a removed branch' do
+ subject.compose.should ==
+ 'user_name removed branch master from <url|project_name>'
+ end
+ end
+end
diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb
new file mode 100644
index 00000000000..387455cb25e
--- /dev/null
+++ b/spec/models/slack_service_spec.rb
@@ -0,0 +1,69 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+require 'spec_helper'
+
+describe SlackService do
+ describe "Associations" do
+ it { should belong_to :project }
+ it { should have_one :service_hook }
+ end
+
+ describe "Validations" do
+ context "active" do
+ before do
+ subject.active = true
+ end
+
+ it { should validate_presence_of :room }
+ it { should validate_presence_of :subdomain }
+ it { should validate_presence_of :token }
+ end
+ end
+
+ describe "Execute" do
+ let(:slack) { SlackService.new }
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:sample_data) { GitPushService.new.sample_data(project, user) }
+ let(:subdomain) { 'gitlab' }
+ let(:token) { 'verySecret' }
+ let(:api_url) {
+ "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}"
+ }
+
+ before do
+ slack.stub(
+ project: project,
+ project_id: project.id,
+ room: '#gitlab',
+ service_hook: true,
+ subdomain: subdomain,
+ token: token
+ )
+
+ WebMock.stub_request(:post, api_url)
+ end
+
+ it "should call Slack API" do
+ slack.execute(sample_data)
+
+ WebMock.should have_requested(:post, api_url).once
+ end
+ end
+end
diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb
index a9ed6a5fa7c..6a0d99dcc53 100644
--- a/spec/models/system_hook_spec.rb
+++ b/spec/models/system_hook_spec.rb
@@ -2,13 +2,16 @@
#
# Table name: web_hooks
#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime not null
-# updated_at :datetime not null
-# type :string(255) default("ProjectHook")
-# service_id :integer
+# id :integer not null, primary key
+# url :string(255)
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# type :string(255) default("ProjectHook")
+# service_id :integer
+# push_events :boolean default(TRUE), not null
+# issues_events :boolean default(FALSE), not null
+# merge_requests_events :boolean default(FALSE), not null
#
require "spec_helper"
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index f6c9f82c4ee..fef6314f23a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -36,6 +36,13 @@
# notification_level :integer default(1), not null
# password_expires_at :datetime
# created_by_id :integer
+# avatar :string(255)
+# confirmation_token :string(255)
+# confirmed_at :datetime
+# confirmation_sent_at :datetime
+# unconfirmed_email :string(255)
+# hide_no_ssh_key :boolean default(FALSE)
+# website_url :string(255) default(""), not null
#
require 'spec_helper'
@@ -69,6 +76,27 @@ describe User do
it { should_not allow_value(-1).for(:projects_limit) }
it { should ensure_length_of(:bio).is_within(0..255) }
+
+ describe 'email' do
+ it 'accepts info@example.com' do
+ user = build(:user, email: 'info@example.com')
+ expect(user).to be_valid
+ end
+ it 'accepts info+test@example.com' do
+ user = build(:user, email: 'info+test@example.com')
+ expect(user).to be_valid
+ end
+
+ it 'rejects test@test@example.com' do
+ user = build(:user, email: 'test@test@example.com')
+ expect(user).to be_invalid
+ end
+
+ it 'rejects mailto:test@example.com' do
+ user = build(:user, email: 'mailto:test@example.com')
+ expect(user).to be_invalid
+ end
+ end
end
describe "Respond to" do
@@ -85,8 +113,8 @@ describe User do
end
it "should not generate password by default" do
- user = create(:user, password: 'abcdefg')
- user.password.should == 'abcdefg'
+ user = create(:user, password: 'abcdefghe')
+ user.password.should == 'abcdefghe'
end
it "should generate password when forcing random password" do
@@ -135,7 +163,6 @@ describe User do
end
it { @user.several_namespaces?.should be_true }
- it { @user.namespaces.should include(@user.namespace) }
it { @user.authorized_groups.should == [@group] }
it { @user.owned_groups.should == [@group] }
end
@@ -162,7 +189,6 @@ describe User do
end
it { @user.several_namespaces?.should be_false }
- it { @user.namespaces.should == [@user.namespace] }
end
describe 'blocking user' do
@@ -266,6 +292,20 @@ describe User do
end
end
+ describe 'search' do
+ let(:user1) { create(:user, username: 'James', email: 'james@testing.com') }
+ let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') }
+
+ it "should be case insensitive" do
+ User.search(user1.username.upcase).to_a.should == [user1]
+ User.search(user1.username.downcase).to_a.should == [user1]
+ User.search(user2.username.upcase).to_a.should == [user2]
+ User.search(user2.username.downcase).to_a.should == [user2]
+ User.search(user1.username.downcase).to_a.count.should == 2
+ User.search(user2.username.downcase).to_a.count.should == 1
+ end
+ end
+
describe 'by_username_or_id' do
let(:user1) { create(:user, username: 'foo') }
@@ -276,4 +316,73 @@ describe User do
User.by_username_or_id('bar').should be_nil
end
end
+
+ describe 'all_ssh_keys' do
+ it { should have_many(:keys).dependent(:destroy) }
+
+ it "should have all ssh keys" do
+ user = create :user
+ key = create :key, key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD33bWLBxu48Sev9Fert1yzEO4WGcWglWF7K/AwblIUFselOt/QdOL9DSjpQGxLagO1s9wl53STIO8qGS4Ms0EJZyIXOEFMjFJ5xmjSy+S37By4sG7SsltQEHMxtbtFOaW5LV2wCrX+rUsRNqLMamZjgjcPO0/EgGCXIGMAYW4O7cwGZdXWYIhQ1Vwy+CsVMDdPkPgBXqK7nR/ey8KMs8ho5fMNgB5hBw/AL9fNGhRw3QTD6Q12Nkhl4VZES2EsZqlpNnJttnPdp847DUsT6yuLRlfiQfz5Cn9ysHFdXObMN5VYIiPFwHeYCZp1X2S4fDZooRE8uOLTfxWHPXwrhqSH", user_id: user.id
+
+ user.all_ssh_keys.should include(key.key)
+ end
+ end
+
+ describe :avatar_type do
+ let(:user) { create(:user) }
+
+ it "should be true if avatar is image" do
+ user.update_attribute(:avatar, 'uploads/avatar.png')
+ user.avatar_type.should be_true
+ end
+
+ it "should be false if avatar is html page" do
+ user.update_attribute(:avatar, 'uploads/avatar.html')
+ user.avatar_type.should == ["only images allowed"]
+ end
+ end
+
+ describe '#full_website_url' do
+ let(:user) { create(:user) }
+
+ it 'begins with http if website url omits it' do
+ user.website_url = 'test.com'
+
+ expect(user.full_website_url).to eq 'http://test.com'
+ end
+
+ it 'begins with http if website url begins with http' do
+ user.website_url = 'http://test.com'
+
+ expect(user.full_website_url).to eq 'http://test.com'
+ end
+
+ it 'begins with https if website url begins with https' do
+ user.website_url = 'https://test.com'
+
+ expect(user.full_website_url).to eq 'https://test.com'
+ end
+ end
+
+ describe '#short_website_url' do
+ let(:user) { create(:user) }
+
+ it 'does not begin with http if website url omits it' do
+ user.website_url = 'test.com'
+
+ expect(user.short_website_url).to eq 'test.com'
+ end
+
+ it 'does not begin with http if website url begins with http' do
+ user.website_url = 'http://test.com'
+
+ expect(user.short_website_url).to eq 'test.com'
+ end
+
+ it 'does not begin with https if website url begins with https' do
+ user.website_url = 'https://test.com'
+
+ expect(user.short_website_url).to eq 'test.com'
+ end
+ end
end
diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb
index 2d9301732dd..d6034081018 100644
--- a/spec/models/web_hook_spec.rb
+++ b/spec/models/web_hook_spec.rb
@@ -2,13 +2,16 @@
#
# Table name: web_hooks
#
-# id :integer not null, primary key
-# url :string(255)
-# project_id :integer
-# created_at :datetime not null
-# updated_at :datetime not null
-# type :string(255) default("ProjectHook")
-# service_id :integer
+# id :integer not null, primary key
+# url :string(255)
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# type :string(255) default("ProjectHook")
+# service_id :integer
+# push_events :boolean default(TRUE), not null
+# issues_events :boolean default(FALSE), not null
+# merge_requests_events :boolean default(FALSE), not null
#
require 'spec_helper'
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 67f2a6da42d..1c70edf0d4d 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -2,12 +2,6 @@ require "spec_helper"
describe WikiPage do
- def create_temp_repo(path)
- FileUtils.mkdir_p path
- command = "git init --quiet #{path};"
- system(command)
- end
-
def remove_temp_repo(path)
FileUtils.rm_rf path
end
diff --git a/spec/observers/activity_observer_spec.rb b/spec/observers/activity_observer_spec.rb
deleted file mode 100644
index dc14ab86b6d..00000000000
--- a/spec/observers/activity_observer_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-require 'spec_helper'
-
-describe ActivityObserver do
- let(:project) { create(:project) }
-
- before { Thread.current[:current_user] = create(:user) }
-
- def self.it_should_be_valid_event
- it { @event.should_not be_nil }
- it { @event.project.should == project }
- end
-
- describe "Issue created" do
- before do
- Issue.observers.enable :activity_observer do
- @issue = create(:issue, project: project)
- @event = Event.last
- end
- end
-
- it_should_be_valid_event
- it { @event.action.should == Event::CREATED }
- it { @event.target.should == @issue }
- end
-
- describe "Issue commented" do
- before do
- Note.observers.enable :activity_observer do
- @issue = create(:issue, project: project)
- @note = create(:note, noteable: @issue, project: project, author: @issue.author)
- @event = Event.last
- end
- end
-
- it_should_be_valid_event
- it { @event.action.should == Event::COMMENTED }
- it { @event.target.should == @note }
- end
-
- describe "Ignore system notes" do
- let(:author) { create(:user) }
- let!(:issue) { create(:issue, project: project) }
- let!(:other) { create(:issue) }
-
- it "should not create events for status change notes" do
- expect do
- Note.observers.enable :activity_observer do
- Note.create_status_change_note(issue, project, author, 'reopened', nil)
- end
- end.to_not change { Event.count }
- end
-
- it "should not create events for cross-reference notes" do
- expect do
- Note.observers.enable :activity_observer do
- Note.create_cross_reference_note(issue, other, author, issue.project)
- end
- end.to_not change { Event.count }
- end
- end
-end
diff --git a/spec/observers/email_observer_spec.rb b/spec/observers/email_observer_spec.rb
new file mode 100644
index 00000000000..599b9a6ffba
--- /dev/null
+++ b/spec/observers/email_observer_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe EmailObserver do
+ let(:email) { create(:email) }
+
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
+
+ subject { EmailObserver.instance }
+
+ describe '#after_create' do
+ it 'trigger notification to send emails' do
+ subject.should_receive(:notification)
+
+ subject.after_create(email)
+ end
+ end
+end
diff --git a/spec/observers/issue_observer_spec.rb b/spec/observers/issue_observer_spec.rb
index 4155ff31193..9a0a2c4329c 100644
--- a/spec/observers/issue_observer_spec.rb
+++ b/spec/observers/issue_observer_spec.rb
@@ -9,7 +9,7 @@ describe IssueObserver do
before { subject.stub(:current_user).and_return(some_user) }
before { subject.stub(:current_commit).and_return(nil) }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
before { mock_issue.project.stub_chain(:repository, :commit).and_return(nil) }
subject { IssueObserver.instance }
diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb
index 3f5250a0040..18df8b78513 100644
--- a/spec/observers/merge_request_observer_spec.rb
+++ b/spec/observers/merge_request_observer_spec.rb
@@ -4,16 +4,17 @@ describe MergeRequestObserver do
let(:some_user) { create :user }
let(:assignee) { create :user }
let(:author) { create :user }
- let(:mr_mock) { double(:merge_request, id: 42, assignee: assignee, author: author) }
- let(:assigned_mr) { create(:merge_request, assignee: assignee, author: author, target_project: create(:project)) }
- let(:unassigned_mr) { create(:merge_request, author: author, target_project: create(:project)) }
- let(:closed_assigned_mr) { create(:closed_merge_request, assignee: assignee, author: author, target_project: create(:project)) }
- let(:closed_unassigned_mr) { create(:closed_merge_request, author: author, target_project: create(:project)) }
+ let(:project) { create :project }
+ let(:mr_mock) { double(:merge_request, id: 42, assignee: assignee, author: author).as_null_object }
+ let(:assigned_mr) { create(:merge_request, assignee: assignee, author: author, source_project: project) }
+ let(:unassigned_mr) { create(:merge_request, author: author, source_project: project) }
+ let(:closed_assigned_mr) { create(:closed_merge_request, assignee: assignee, author: author, source_project: project) }
+ let(:closed_unassigned_mr) { create(:closed_merge_request, author: author, source_project: project) }
before { subject.stub(:current_user).and_return(some_user) }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
before { mr_mock.stub(:author_id) }
- before { mr_mock.stub(:target_project) }
+ before { mr_mock.stub(:source_project) }
before { mr_mock.stub(:source_project) }
before { mr_mock.stub(:project) }
before { mr_mock.stub(:create_cross_references!).and_return(true) }
@@ -46,7 +47,7 @@ describe MergeRequestObserver do
end
it 'is called when a merge request is changed' do
- changed = create(:merge_request, source_project: create(:project))
+ changed = create(:merge_request, source_project: project)
subject.should_receive(:after_update)
MergeRequest.observers.enable :merge_request_observer do
@@ -81,13 +82,13 @@ describe MergeRequestObserver do
context '#after_close' do
context 'a status "closed"' do
it 'note is created if the merge request is being closed' do
- Note.should_receive(:create_status_change_note).with(assigned_mr, assigned_mr.target_project, some_user, 'closed', nil)
+ Note.should_receive(:create_status_change_note).with(assigned_mr, assigned_mr.source_project, some_user, 'closed', nil)
assigned_mr.close
end
it 'notification is delivered only to author if the merge request is being closed' do
- Note.should_receive(:create_status_change_note).with(unassigned_mr, unassigned_mr.target_project, some_user, 'closed', nil)
+ Note.should_receive(:create_status_change_note).with(unassigned_mr, unassigned_mr.source_project, some_user, 'closed', nil)
unassigned_mr.close
end
@@ -97,13 +98,13 @@ describe MergeRequestObserver do
context '#after_reopen' do
context 'a status "reopened"' do
it 'note is created if the merge request is being reopened' do
- Note.should_receive(:create_status_change_note).with(closed_assigned_mr, closed_assigned_mr.target_project, some_user, 'reopened', nil)
+ Note.should_receive(:create_status_change_note).with(closed_assigned_mr, closed_assigned_mr.source_project, some_user, 'reopened', nil)
closed_assigned_mr.reopen
end
it 'notification is delivered only to author if the merge request is being reopened' do
- Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, closed_unassigned_mr.target_project, some_user, 'reopened', nil)
+ Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, closed_unassigned_mr.source_project, some_user, 'reopened', nil)
closed_unassigned_mr.reopen
end
@@ -118,20 +119,13 @@ describe MergeRequestObserver do
it { @event.project.should == project }
end
- let(:project) { create(:project) }
before do
- TestEnv.enable_observers
@merge_request = create(:merge_request, source_project: project, target_project: project)
@event = Event.last
end
- after do
- TestEnv.disable_observers
- end
-
it_should_be_valid_event
it { @event.action.should == Event::CREATED }
it { @event.target.should == @merge_request }
end
-
end
diff --git a/spec/observers/note_observer_spec.rb b/spec/observers/note_observer_spec.rb
index f9b96c255c1..f8693355b23 100644
--- a/spec/observers/note_observer_spec.rb
+++ b/spec/observers/note_observer_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe NoteObserver do
subject { NoteObserver.instance }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
let(:team_without_author) { (1..2).map { |n| double :user, id: n } }
let(:note) { double(:note).as_null_object }
diff --git a/spec/observers/user_observer_spec.rb b/spec/observers/user_observer_spec.rb
index b74fceb98b1..9aeade535f9 100644
--- a/spec/observers/user_observer_spec.rb
+++ b/spec/observers/user_observer_spec.rb
@@ -4,7 +4,7 @@ describe UserObserver do
before(:each) { enable_observers }
after(:each) {disable_observers}
subject { UserObserver.instance }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
it 'calls #after_create when new users are created' do
new_user = build(:user)
diff --git a/spec/observers/users_group_observer_spec.rb b/spec/observers/users_group_observer_spec.rb
index 3bf562edbb7..2ab99c33b78 100644
--- a/spec/observers/users_group_observer_spec.rb
+++ b/spec/observers/users_group_observer_spec.rb
@@ -5,7 +5,7 @@ describe UsersGroupObserver do
after(:each) { disable_observers }
subject { UsersGroupObserver.instance }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
describe "#after_create" do
it "should send email to user" do
@@ -23,5 +23,10 @@ describe UsersGroupObserver do
subject.should_receive(:notification)
@membership.update_attribute(:group_access, UsersGroup::MASTER)
end
+
+ it "does not send an email when the access level has not changed" do
+ subject.should_not_receive(:notification)
+ @membership.update_attribute(:group_access, UsersGroup::OWNER)
+ end
end
end
diff --git a/spec/observers/users_project_observer_spec.rb b/spec/observers/users_project_observer_spec.rb
index e7c624fce59..be277b4dbd2 100644
--- a/spec/observers/users_project_observer_spec.rb
+++ b/spec/observers/users_project_observer_spec.rb
@@ -7,27 +7,7 @@ describe UsersProjectObserver do
let(:user) { create(:user) }
let(:project) { create(:project) }
subject { UsersProjectObserver.instance }
- before { subject.stub(notification: mock('NotificationService').as_null_object) }
-
- describe "#after_commit" do
- it "should called when UsersProject created" do
- subject.should_receive(:after_commit)
- create(:users_project)
- end
-
- it "should send email to user" do
- subject.should_receive(:notification)
- Event.stub(create: true)
-
- create(:users_project)
- end
-
- it "should create new event" do
- Event.should_receive(:create)
-
- create(:users_project)
- end
- end
+ before { subject.stub(notification: double('NotificationService').as_null_object) }
describe "#after_update" do
before do
@@ -35,7 +15,7 @@ describe UsersProjectObserver do
end
it "should called when UsersProject updated" do
- subject.should_receive(:after_commit)
+ subject.should_receive(:after_update)
@users_project.update_attribute(:project_access, UsersProject::MASTER)
end
@@ -45,7 +25,7 @@ describe UsersProjectObserver do
end
it "should not called after UsersProject destroyed" do
- subject.should_not_receive(:after_commit)
+ subject.should_not_receive(:after_update)
@users_project.destroy
end
end
@@ -67,28 +47,17 @@ describe UsersProjectObserver do
end
describe "#after_create" do
- context 'wiki_enabled creates repository directory' do
- context 'wiki_enabled true creates wiki repository directory' do
- before do
- @project = create(:project, wiki_enabled: true)
- @path = GollumWiki.new(@project, user).send(:path_to_repo)
- end
-
- after do
- FileUtils.rm_rf(@path)
- end
+ it "should send email to user" do
+ subject.should_receive(:notification)
+ Event.stub(create: true)
- it { File.exists?(@path).should be_true }
- end
+ create(:users_project)
+ end
- context 'wiki_enabled false does not create wiki repository directory' do
- before do
- @project = create(:project, wiki_enabled: false)
- @path = GollumWiki.new(@project, user).send(:path_to_repo)
- end
+ it "should create new event" do
+ Event.should_receive(:create)
- it { File.exists?(@path).should be_false }
- end
+ create(:users_project)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
new file mode 100644
index 00000000000..ea317e1137a
--- /dev/null
+++ b/spec/requests/api/commits_spec.rb
@@ -0,0 +1,87 @@
+require 'spec_helper'
+require 'mime/types'
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { enable_observers }
+ after(:each) {disable_observers}
+
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let!(:project) { create(:project, creator_id: user.id) }
+ let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
+ let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) }
+
+ before { project.team << [user, :reporter] }
+
+ describe "GET /projects/:id/repository/commits" do
+ context "authorized user" do
+ before { project.team << [user2, :reporter] }
+
+ it "should return project commits" do
+ get api("/projects/#{project.id}/repository/commits", user)
+ response.status.should == 200
+
+ json_response.should be_an Array
+ json_response.first['id'].should == project.repository.commit.id
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not return project commits" do
+ get api("/projects/#{project.id}/repository/commits")
+ response.status.should == 401
+ end
+ end
+ end
+
+ describe "GET /projects:id/repository/commits/:sha" do
+ context "authorized user" do
+ it "should return a commit by sha" do
+ get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
+ response.status.should == 200
+ json_response['id'].should == project.repository.commit.id
+ json_response['title'].should == project.repository.commit.title
+ end
+
+ it "should return a 404 error if not found" do
+ get api("/projects/#{project.id}/repository/commits/invalid_sha", user)
+ response.status.should == 404
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not return the selected commit" do
+ get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}")
+ response.status.should == 401
+ end
+ end
+ end
+
+ describe "GET /projects:id/repository/commits/:sha/diff" do
+ context "authorized user" do
+ before { project.team << [user2, :reporter] }
+
+ it "should return the diff of the selected commit" do
+ get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
+ response.status.should == 200
+
+ json_response.should be_an Array
+ json_response.length.should >= 1
+ json_response.first.keys.should include "diff"
+ end
+
+ it "should return a 404 error if invalid commit" do
+ get api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user)
+ response.status.should == 404
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not return the diff of the selected commit" do
+ get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff")
+ response.status.should == 401
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
new file mode 100644
index 00000000000..fa25a4bec6a
--- /dev/null
+++ b/spec/requests/api/files_spec.rb
@@ -0,0 +1,145 @@
+require 'spec_helper'
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
+ after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
+
+ let(:user) { create(:user) }
+ let!(:project) { create(:project, namespace: user.namespace ) }
+ before { project.team << [user, :developer] }
+
+ describe "GET /projects/:id/repository/files" do
+ it "should return file info" do
+ params = {
+ file_path: 'app/models/key.rb',
+ ref: 'master',
+ }
+
+ get api("/projects/#{project.id}/repository/files", user), params
+ response.status.should == 200
+ json_response['file_path'].should == 'app/models/key.rb'
+ json_response['file_name'].should == 'key.rb'
+ Base64.decode64(json_response['content']).lines.first.should == "class Key < ActiveRecord::Base\n"
+ end
+
+ it "should return a 400 bad request if no params given" do
+ get api("/projects/#{project.id}/repository/files", user)
+ response.status.should == 400
+ end
+
+ it "should return a 404 if such file does not exist" do
+ params = {
+ file_path: 'app/models/application.rb',
+ ref: 'master',
+ }
+
+ get api("/projects/#{project.id}/repository/files", user), params
+ response.status.should == 404
+ end
+ end
+
+ describe "POST /projects/:id/repository/files" do
+ let(:valid_params) {
+ {
+ file_path: 'newfile.rb',
+ branch_name: 'master',
+ content: 'puts 8',
+ commit_message: 'Added newfile'
+ }
+ }
+
+ it "should create a new file in project repo" do
+ Gitlab::Satellite::NewFileAction.any_instance.stub(
+ commit!: true,
+ )
+
+ post api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 201
+ json_response['file_path'].should == 'newfile.rb'
+ end
+
+ it "should return a 400 bad request if no params given" do
+ post api("/projects/#{project.id}/repository/files", user)
+ response.status.should == 400
+ end
+
+ it "should return a 400 if satellite fails to create file" do
+ Gitlab::Satellite::NewFileAction.any_instance.stub(
+ commit!: false,
+ )
+
+ post api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 400
+ end
+ end
+
+ describe "PUT /projects/:id/repository/files" do
+ let(:valid_params) {
+ {
+ file_path: 'spec/spec_helper.rb',
+ branch_name: 'master',
+ content: 'puts 8',
+ commit_message: 'Changed file'
+ }
+ }
+
+ it "should update existing file in project repo" do
+ Gitlab::Satellite::EditFileAction.any_instance.stub(
+ commit!: true,
+ )
+
+ put api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 200
+ json_response['file_path'].should == 'spec/spec_helper.rb'
+ end
+
+ it "should return a 400 bad request if no params given" do
+ put api("/projects/#{project.id}/repository/files", user)
+ response.status.should == 400
+ end
+
+ it "should return a 400 if satellite fails to create file" do
+ Gitlab::Satellite::EditFileAction.any_instance.stub(
+ commit!: false,
+ )
+
+ put api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 400
+ end
+ end
+
+ describe "DELETE /projects/:id/repository/files" do
+ let(:valid_params) {
+ {
+ file_path: 'spec/spec_helper.rb',
+ branch_name: 'master',
+ commit_message: 'Changed file'
+ }
+ }
+
+ it "should delete existing file in project repo" do
+ Gitlab::Satellite::DeleteFileAction.any_instance.stub(
+ commit!: true,
+ )
+
+ delete api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 200
+ json_response['file_path'].should == 'spec/spec_helper.rb'
+ end
+
+ it "should return a 400 bad request if no params given" do
+ delete api("/projects/#{project.id}/repository/files", user)
+ response.status.should == 400
+ end
+
+ it "should return a 400 if satellite fails to create file" do
+ Gitlab::Satellite::DeleteFileAction.any_instance.stub(
+ commit!: false,
+ )
+
+ delete api("/projects/#{project.id}/repository/files", user), valid_params
+ response.status.should == 400
+ end
+ end
+end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 25b9a10bd8c..1a5f11038b7 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -147,7 +147,7 @@ describe API::API do
describe "POST /groups/:id/projects/:project_id" do
let(:project) { create(:project) }
before(:each) do
- project.stub!(:transfer).and_return(true)
+ project.stub(:transfer).and_return(true)
Project.stub(:find).and_return(project)
end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index e8870f4d5d8..5f6dff92c0a 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -103,6 +103,33 @@ describe API::API do
end
end
+ context "archived project" do
+ let(:personal_project) { create(:project, namespace: user.namespace) }
+
+ before do
+ project.team << [user, :developer]
+ project.archive!
+ end
+
+ context "git pull" do
+ it do
+ pull(key, project)
+
+ response.status.should == 200
+ response.body.should == 'true'
+ end
+ end
+
+ context "git push" do
+ it do
+ push(key, project)
+
+ response.status.should == 200
+ response.body.should == 'false'
+ end
+ end
+ end
+
context "deploy key" do
let(:key) { create(:deploy_key) }
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 505e9597e1b..0b4f22bfb3d 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -106,16 +106,4 @@ describe API::API do
response.status.should == 405
end
end
-
- describe "PUT /projects/:id/issues/:issue_id to test observer on close" do
- before { enable_observers }
- after { disable_observers }
-
- it "should create an activity event when an issue is closed" do
- Event.should_receive(:create)
-
- put api("/projects/#{project.id}/issues/#{issue.id}", user),
- state_event: "close"
- end
- end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index f31b4da90cd..138f218d46c 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -5,8 +5,9 @@ describe API::API do
before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
let(:user) { create(:user) }
- let!(:project) {create(:project_with_code, creator_id: user.id, namespace: user.namespace) }
+ let!(:project) {create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:merge_request) { create(:merge_request, author: user, assignee: user, source_project: project, target_project: project, title: "Test") }
+ let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
before {
project.team << [user, :reporters]
}
@@ -47,32 +48,32 @@ describe API::API do
context 'between branches projects' do
it "should return merge_request" do
post api("/projects/#{project.id}/merge_requests", user),
- title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user
+ title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user
response.status.should == 201
json_response['title'].should == 'Test merge_request'
end
it "should return 422 when source_branch equals target_branch" do
post api("/projects/#{project.id}/merge_requests", user),
- title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
+ title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
response.status.should == 422
end
it "should return 400 when source_branch is missing" do
post api("/projects/#{project.id}/merge_requests", user),
- title: "Test merge_request", target_branch: "master", author: user
+ title: "Test merge_request", target_branch: "master", author: user
response.status.should == 400
end
it "should return 400 when target_branch is missing" do
post api("/projects/#{project.id}/merge_requests", user),
- title: "Test merge_request", source_branch: "stable", author: user
+ title: "Test merge_request", source_branch: "stable", author: user
response.status.should == 400
end
it "should return 400 when title is missing" do
post api("/projects/#{project.id}/merge_requests", user),
- target_branch: 'master', source_branch: 'stable'
+ target_branch: 'master', source_branch: 'stable'
response.status.should == 400
end
end
@@ -80,8 +81,8 @@ describe API::API do
context 'forked projects' do
let!(:user2) {create(:user)}
let!(:forked_project_link) { build(:forked_project_link) }
- let!(:fork_project) { create(:source_project_with_code, forked_project_link: forked_project_link, namespace: user2.namespace, creator_id: user2.id) }
- let!(:unrelated_project) { create(:target_project_with_code, namespace: user2.namespace, creator_id: user2.id) }
+ let!(:fork_project) { create(:project, forked_project_link: forked_project_link, namespace: user2.namespace, creator_id: user2.id) }
+ let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) }
before :each do |each|
fork_project.team << [user2, :reporters]
@@ -92,9 +93,10 @@ describe API::API do
it "should return merge_request" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id
+ title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
response.status.should == 201
json_response['title'].should == 'Test merge_request'
+ json_response['description'].should == 'Test description for Test merge_request'
end
it "should not return 422 when source_branch equals target_branch" do
@@ -102,44 +104,44 @@ describe API::API do
fork_project.forked?.should be_true
fork_project.forked_from_project.should == project
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id
+ title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id
response.status.should == 201
json_response['title'].should == 'Test merge_request'
end
it "should return 400 when source_branch is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
+ title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
response.status.should == 400
end
it "should return 400 when target_branch is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
+ title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
response.status.should == 400
end
it "should return 400 when title is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: project.id
+ target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: project.id
response.status.should == 400
end
it "should return 400 when target_branch is specified and not a forked project" do
post api("/projects/#{project.id}/merge_requests", user),
- title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user, target_project_id: fork_project.id
+ title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user, target_project_id: fork_project.id
response.status.should == 400
end
it "should return 400 when target_branch is specified and for a different fork" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: unrelated_project.id
+ title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: unrelated_project.id
response.status.should == 400
end
it "should return 201 when target_branch is specified and for the same project" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: fork_project.id
+ title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: fork_project.id
response.status.should == 201
end
end
@@ -168,9 +170,15 @@ describe API::API do
json_response['title'].should == 'New title'
end
+ it "should return merge_request" do
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), description: "New description"
+ response.status.should == 200
+ json_response['description'].should == 'New description'
+ end
+
it "should return 422 when source_branch and target_branch are renamed the same" do
put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user),
- source_branch: "master", target_branch: "master"
+ source_branch: "master", target_branch: "master"
response.status.should == 422
end
@@ -199,4 +207,19 @@ describe API::API do
end
end
+ describe "GET :id/merge_request/:merge_request_id/comments" do
+ it "should return merge_request comments" do
+ get api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.length.should == 1
+ json_response.first['note'].should == "a comment on a MR"
+ json_response.first['author']['id'].should == user.id
+ end
+
+ it "should return a 404 error if merge_request_id not found" do
+ get api("/projects/#{project.id}/merge_request/999/comments", user)
+ response.status.should == 404
+ end
+ end
end
diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb
new file mode 100644
index 00000000000..2b1a4bf6ec8
--- /dev/null
+++ b/spec/requests/api/namespaces_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
+ after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
+
+ let(:admin) { create(:admin) }
+ let!(:group1) { create(:group) }
+ let!(:group2) { create(:group) }
+
+ describe "GET /namespaces" do
+ context "when unauthenticated" do
+ it "should return authentication error" do
+ get api("/namespaces")
+ response.status.should == 401
+ end
+ end
+
+ context "when authenticated as admin" do
+ it "admin: should return an array of all namespaces" do
+ get api("/namespaces", admin)
+ response.status.should == 200
+ json_response.should be_an Array
+
+ # Admin namespace + 2 group namespaces
+ json_response.length.should == 3
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb
new file mode 100644
index 00000000000..c8ace0b9462
--- /dev/null
+++ b/spec/requests/api/project_hooks_spec.rb
@@ -0,0 +1,132 @@
+require 'spec_helper'
+
+describe API::API, 'ProjectHooks' do
+ include ApiHelpers
+ before(:each) { enable_observers }
+ after(:each) { disable_observers }
+
+ let(:user) { create(:user) }
+ let(:user3) { create(:user) }
+ let!(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
+
+ before do
+ project.team << [user, :master]
+ project.team << [user3, :developer]
+ end
+
+ describe "GET /projects/:id/hooks" do
+ context "authorized user" do
+ it "should return project hooks" do
+ get api("/projects/#{project.id}/hooks", user)
+ response.status.should == 200
+
+ json_response.should be_an Array
+ json_response.count.should == 1
+ json_response.first['url'].should == "http://example.com"
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not access project hooks" do
+ get api("/projects/#{project.id}/hooks", user3)
+ response.status.should == 403
+ end
+ end
+ end
+
+ describe "GET /projects/:id/hooks/:hook_id" do
+ context "authorized user" do
+ it "should return a project hook" do
+ get api("/projects/#{project.id}/hooks/#{hook.id}", user)
+ response.status.should == 200
+ json_response['url'].should == hook.url
+ end
+
+ it "should return a 404 error if hook id is not available" do
+ get api("/projects/#{project.id}/hooks/1234", user)
+ response.status.should == 404
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not access an existing hook" do
+ get api("/projects/#{project.id}/hooks/#{hook.id}", user3)
+ response.status.should == 403
+ end
+ end
+
+ it "should return a 404 error if hook id is not available" do
+ get api("/projects/#{project.id}/hooks/1234", user)
+ response.status.should == 404
+ end
+ end
+
+ describe "POST /projects/:id/hooks" do
+ it "should add hook to project" do
+ expect {
+ post api("/projects/#{project.id}/hooks", user),
+ url: "http://example.com", issues_events: true
+ }.to change {project.hooks.count}.by(1)
+ response.status.should == 201
+ end
+
+ it "should return a 400 error if url not given" do
+ post api("/projects/#{project.id}/hooks", user)
+ response.status.should == 400
+ end
+
+ it "should return a 422 error if url not valid" do
+ post api("/projects/#{project.id}/hooks", user), "url" => "ftp://example.com"
+ response.status.should == 422
+ end
+ end
+
+ describe "PUT /projects/:id/hooks/:hook_id" do
+ it "should update an existing project hook" do
+ put api("/projects/#{project.id}/hooks/#{hook.id}", user),
+ url: 'http://example.org', push_events: false
+ response.status.should == 200
+ json_response['url'].should == 'http://example.org'
+ end
+
+ it "should return 404 error if hook id not found" do
+ put api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org'
+ response.status.should == 404
+ end
+
+ it "should return 400 error if url is not given" do
+ put api("/projects/#{project.id}/hooks/#{hook.id}", user)
+ response.status.should == 400
+ end
+
+ it "should return a 422 error if url is not valid" do
+ put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com'
+ response.status.should == 422
+ end
+ end
+
+ describe "DELETE /projects/:id/hooks/:hook_id" do
+ it "should delete hook from project" do
+ expect {
+ delete api("/projects/#{project.id}/hooks/#{hook.id}", user)
+ }.to change {project.hooks.count}.by(-1)
+ response.status.should == 200
+ end
+
+ it "should return success when deleting hook" do
+ delete api("/projects/#{project.id}/hooks/#{hook.id}", user)
+ response.status.should == 200
+ end
+
+ it "should return success when deleting non existent hook" do
+ delete api("/projects/#{project.id}/hooks/42", user)
+ response.status.should == 200
+ end
+
+ it "should return a 405 error if hook id not given" do
+ delete api("/projects/#{project.id}/hooks", user)
+ response.status.should == 405
+ end
+ end
+end
diff --git a/spec/requests/api/project_members_spec.rb b/spec/requests/api/project_members_spec.rb
new file mode 100644
index 00000000000..f3c0529da92
--- /dev/null
+++ b/spec/requests/api/project_members_spec.rb
@@ -0,0 +1,156 @@
+require 'spec_helper'
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { enable_observers }
+ after(:each) { disable_observers }
+
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:user3) { create(:user) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
+ let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
+
+ describe "GET /projects/:id/members" do
+ before { users_project }
+ before { users_project2 }
+
+ it "should return project team members" do
+ get api("/projects/#{project.id}/members", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.count.should == 2
+ json_response.map { |u| u['email'] }.should include user.email
+ end
+
+ it "finds team members with query string" do
+ get api("/projects/#{project.id}/members", user), query: user.username
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.count.should == 1
+ json_response.first['email'].should == user.email
+ end
+
+ it "should return a 404 error if id not found" do
+ get api("/projects/9999/members", user)
+ response.status.should == 404
+ end
+ end
+
+ describe "GET /projects/:id/members/:user_id" do
+ before { users_project }
+
+ it "should return project team member" do
+ get api("/projects/#{project.id}/members/#{user.id}", user)
+ response.status.should == 200
+ json_response['email'].should == user.email
+ json_response['access_level'].should == UsersProject::MASTER
+ end
+
+ it "should return a 404 error if user id not found" do
+ get api("/projects/#{project.id}/members/1234", user)
+ response.status.should == 404
+ end
+ end
+
+ describe "POST /projects/:id/members" do
+ it "should add user to project team" do
+ expect {
+ post api("/projects/#{project.id}/members", user), user_id: user2.id,
+ access_level: UsersProject::DEVELOPER
+ }.to change { UsersProject.count }.by(1)
+
+ response.status.should == 201
+ json_response['email'].should == user2.email
+ json_response['access_level'].should == UsersProject::DEVELOPER
+ end
+
+ it "should return a 201 status if user is already project member" do
+ post api("/projects/#{project.id}/members", user), user_id: user2.id,
+ access_level: UsersProject::DEVELOPER
+ expect {
+ post api("/projects/#{project.id}/members", user), user_id: user2.id,
+ access_level: UsersProject::DEVELOPER
+ }.not_to change { UsersProject.count }.by(1)
+
+ response.status.should == 201
+ json_response['email'].should == user2.email
+ json_response['access_level'].should == UsersProject::DEVELOPER
+ end
+
+ it "should return a 400 error when user id is not given" do
+ post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER
+ response.status.should == 400
+ end
+
+ it "should return a 400 error when access level is not given" do
+ post api("/projects/#{project.id}/members", user), user_id: user2.id
+ response.status.should == 400
+ end
+
+ it "should return a 422 error when access level is not known" do
+ post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234
+ response.status.should == 422
+ end
+ end
+
+ describe "PUT /projects/:id/members/:user_id" do
+ before { users_project2 }
+
+ it "should update project team member" do
+ put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: UsersProject::MASTER
+ response.status.should == 200
+ json_response['email'].should == user3.email
+ json_response['access_level'].should == UsersProject::MASTER
+ end
+
+ it "should return a 404 error if user_id is not found" do
+ put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER
+ response.status.should == 404
+ end
+
+ it "should return a 400 error when access level is not given" do
+ put api("/projects/#{project.id}/members/#{user3.id}", user)
+ response.status.should == 400
+ end
+
+ it "should return a 422 error when access level is not known" do
+ put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123
+ response.status.should == 422
+ end
+ end
+
+ describe "DELETE /projects/:id/members/:user_id" do
+ before { users_project }
+ before { users_project2 }
+
+ it "should remove user from project team" do
+ expect {
+ delete api("/projects/#{project.id}/members/#{user3.id}", user)
+ }.to change { UsersProject.count }.by(-1)
+ end
+
+ it "should return 200 if team member is not part of a project" do
+ delete api("/projects/#{project.id}/members/#{user3.id}", user)
+ expect {
+ delete api("/projects/#{project.id}/members/#{user3.id}", user)
+ }.to_not change { UsersProject.count }.by(1)
+ end
+
+ it "should return 200 if team member already removed" do
+ delete api("/projects/#{project.id}/members/#{user3.id}", user)
+ delete api("/projects/#{project.id}/members/#{user3.id}", user)
+ response.status.should == 200
+ end
+
+ it "should return 200 OK when the user was not member" do
+ expect {
+ delete api("/projects/#{project.id}/members/1000000", user)
+ }.to change { UsersProject.count }.by(0)
+ response.status.should == 200
+ json_response['message'].should == "Access revoked"
+ json_response['id'].should == 1000000
+ end
+ end
+end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index bf4a1749418..7fe65639657 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -9,15 +9,15 @@ describe API::API do
let(:user2) { create(:user) }
let(:user3) { create(:user) }
let(:admin) { create(:admin) }
- let!(:project) { create(:project_with_code, creator_id: user.id, namespace: user.namespace) }
- let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
- let!(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
- let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
- let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
-
- before { project.team << [user, :reporter] }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
+ let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
+ let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
+ let(:issue_with_labels) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") }
describe "GET /projects" do
+ before { project }
+
context "when unauthenticated" do
it "should return authentication error" do
get api("/projects")
@@ -36,6 +36,34 @@ describe API::API do
end
end
+ describe "GET /projects/all" do
+ before { project }
+
+ context "when unauthenticated" do
+ it "should return authentication error" do
+ get api("/projects/all")
+ response.status.should == 401
+ end
+ end
+
+ context "when authenticated as regular user" do
+ it "should return authentication error" do
+ get api("/projects/all", user)
+ response.status.should == 403
+ end
+ end
+
+ context "when authenticated as admin" do
+ it "should return an array of all projects" do
+ get api("/projects/all", admin)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.name
+ json_response.first['owner']['email'].should == user.email
+ end
+ end
+ end
+
describe "POST /projects" do
context "maximum number of projects reached" do
before do
@@ -91,7 +119,6 @@ describe API::API do
it "should assign attributes to project" do
project = attributes_for(:project, {
description: Faker::Lorem.sentence,
- default_branch: 'stable',
issues_enabled: false,
wall_enabled: false,
merge_requests_enabled: false,
@@ -107,22 +134,50 @@ describe API::API do
end
it "should set a project as public" do
+ project = attributes_for(:project, :public)
+ post api("/projects", user), project
+ json_response['public'].should be_true
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
+ end
+
+ it "should set a project as public using :public" do
project = attributes_for(:project, { public: true })
post api("/projects", user), project
json_response['public'].should be_true
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
+ end
+ it "should set a project as internal" do
+ project = attributes_for(:project, :internal)
+ post api("/projects", user), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
- it "should set a project as private" do
- project = attributes_for(:project, { public: false })
+ it "should set a project as internal overriding :public" do
+ project = attributes_for(:project, :internal, { public: true })
post api("/projects", user), project
json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
+ end
+ it "should set a project as private" do
+ project = attributes_for(:project, :private)
+ post api("/projects", user), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
+ it "should set a project as private using :public" do
+ project = attributes_for(:project, { public: false })
+ post api("/projects", user), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
+ end
end
describe "POST /projects/user/:id" do
+ before { project }
before { admin }
it "should create new project without path" do
@@ -146,7 +201,6 @@ describe API::API do
it "should assign attributes to project" do
project = attributes_for(:project, {
description: Faker::Lorem.sentence,
- default_branch: 'stable',
issues_enabled: false,
wall_enabled: false,
merge_requests_enabled: false,
@@ -162,22 +216,52 @@ describe API::API do
end
it "should set a project as public" do
+ project = attributes_for(:project, :public)
+ post api("/projects/user/#{user.id}", admin), project
+ json_response['public'].should be_true
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
+ end
+
+ it "should set a project as public using :public" do
project = attributes_for(:project, { public: true })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_true
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
+ end
+ it "should set a project as internal" do
+ project = attributes_for(:project, :internal)
+ post api("/projects/user/#{user.id}", admin), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
- it "should set a project as private" do
- project = attributes_for(:project, { public: false })
+ it "should set a project as internal overriding :public" do
+ project = attributes_for(:project, :internal, { public: true })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
+ end
+ it "should set a project as private" do
+ project = attributes_for(:project, :private)
+ post api("/projects/user/#{user.id}", admin), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
+ it "should set a project as private using :public" do
+ project = attributes_for(:project, { public: false })
+ post api("/projects/user/#{user.id}", admin), project
+ json_response['public'].should be_false
+ json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
+ end
end
describe "GET /projects/:id" do
+ before { project }
+ before { users_project }
+
it "should return a project by id" do
get api("/projects/#{project.id}", user)
response.status.should == 200
@@ -202,9 +286,33 @@ describe API::API do
get api("/projects/#{project.id}", other_user)
response.status.should == 404
end
+
+ describe 'permissions' do
+ context 'personal project' do
+ before { get api("/projects/#{project.id}", user) }
+
+ it { response.status.should == 200 }
+ it { json_response['permissions']["project_access"]["access_level"].should == Gitlab::Access::MASTER }
+ it { json_response['permissions']["group_access"].should be_nil }
+ end
+
+ context 'group project' do
+ before do
+ project2 = create(:project, group: create(:group))
+ project2.group.add_owner(user)
+ get api("/projects/#{project2.id}", user)
+ end
+
+ it { response.status.should == 200 }
+ it { json_response['permissions']["project_access"].should be_nil }
+ it { json_response['permissions']["group_access"]["access_level"].should == Gitlab::Access::OWNER }
+ end
+ end
end
describe "GET /projects/:id/events" do
+ before { users_project }
+
it "should return a project events" do
get api("/projects/#{project.id}/events", user)
response.status.should == 200
@@ -227,256 +335,9 @@ describe API::API do
end
end
- describe "GET /projects/:id/members" do
- it "should return project team members" do
- get api("/projects/#{project.id}/members", user)
- response.status.should == 200
- json_response.should be_an Array
- json_response.count.should == 2
- json_response.map { |u| u['email'] }.should include user.email
- end
-
- it "finds team members with query string" do
- get api("/projects/#{project.id}/members", user), query: user.username
- response.status.should == 200
- json_response.should be_an Array
- json_response.count.should == 1
- json_response.first['email'].should == user.email
- end
-
- it "should return a 404 error if id not found" do
- get api("/projects/9999/members", user)
- response.status.should == 404
- end
- end
-
- describe "GET /projects/:id/members/:user_id" do
- it "should return project team member" do
- get api("/projects/#{project.id}/members/#{user.id}", user)
- response.status.should == 200
- json_response['email'].should == user.email
- json_response['access_level'].should == UsersProject::MASTER
- end
-
- it "should return a 404 error if user id not found" do
- get api("/projects/#{project.id}/members/1234", user)
- response.status.should == 404
- end
- end
-
- describe "POST /projects/:id/members" do
- it "should add user to project team" do
- expect {
- post api("/projects/#{project.id}/members", user), user_id: user2.id,
- access_level: UsersProject::DEVELOPER
- }.to change { UsersProject.count }.by(1)
-
- response.status.should == 201
- json_response['email'].should == user2.email
- json_response['access_level'].should == UsersProject::DEVELOPER
- end
-
- it "should return a 201 status if user is already project member" do
- post api("/projects/#{project.id}/members", user), user_id: user2.id,
- access_level: UsersProject::DEVELOPER
- expect {
- post api("/projects/#{project.id}/members", user), user_id: user2.id,
- access_level: UsersProject::DEVELOPER
- }.not_to change { UsersProject.count }.by(1)
-
- response.status.should == 201
- json_response['email'].should == user2.email
- json_response['access_level'].should == UsersProject::DEVELOPER
- end
-
- it "should return a 400 error when user id is not given" do
- post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER
- response.status.should == 400
- end
-
- it "should return a 400 error when access level is not given" do
- post api("/projects/#{project.id}/members", user), user_id: user2.id
- response.status.should == 400
- end
-
- it "should return a 422 error when access level is not known" do
- post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234
- response.status.should == 422
- end
- end
-
- describe "PUT /projects/:id/members/:user_id" do
- it "should update project team member" do
- put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: UsersProject::MASTER
- response.status.should == 200
- json_response['email'].should == user3.email
- json_response['access_level'].should == UsersProject::MASTER
- end
-
- it "should return a 404 error if user_id is not found" do
- put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER
- response.status.should == 404
- end
-
- it "should return a 400 error when access level is not given" do
- put api("/projects/#{project.id}/members/#{user3.id}", user)
- response.status.should == 400
- end
-
- it "should return a 422 error when access level is not known" do
- put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123
- response.status.should == 422
- end
- end
-
- describe "DELETE /projects/:id/members/:user_id" do
- it "should remove user from project team" do
- expect {
- delete api("/projects/#{project.id}/members/#{user3.id}", user)
- }.to change { UsersProject.count }.by(-1)
- end
-
- it "should return 200 if team member is not part of a project" do
- delete api("/projects/#{project.id}/members/#{user3.id}", user)
- expect {
- delete api("/projects/#{project.id}/members/#{user3.id}", user)
- }.to_not change { UsersProject.count }.by(1)
- end
-
- it "should return 200 if team member already removed" do
- delete api("/projects/#{project.id}/members/#{user3.id}", user)
- delete api("/projects/#{project.id}/members/#{user3.id}", user)
- response.status.should == 200
- end
- end
-
- describe "DELETE /projects/:id/members/:user_id" do
- it "should return 200 OK when the user was not member" do
- expect {
- delete api("/projects/#{project.id}/members/1000000", user)
- }.to change { UsersProject.count }.by(0)
- response.status.should == 200
- json_response['message'].should == "Access revoked"
- json_response['id'].should == 1000000
- end
- end
-
- describe "GET /projects/:id/hooks" do
- context "authorized user" do
- it "should return project hooks" do
- get api("/projects/#{project.id}/hooks", user)
- response.status.should == 200
-
- json_response.should be_an Array
- json_response.count.should == 1
- json_response.first['url'].should == "http://example.com"
- end
- end
-
- context "unauthorized user" do
- it "should not access project hooks" do
- get api("/projects/#{project.id}/hooks", user3)
- response.status.should == 403
- end
- end
- end
-
- describe "GET /projects/:id/hooks/:hook_id" do
- context "authorized user" do
- it "should return a project hook" do
- get api("/projects/#{project.id}/hooks/#{hook.id}", user)
- response.status.should == 200
- json_response['url'].should == hook.url
- end
-
- it "should return a 404 error if hook id is not available" do
- get api("/projects/#{project.id}/hooks/1234", user)
- response.status.should == 404
- end
- end
-
- context "unauthorized user" do
- it "should not access an existing hook" do
- get api("/projects/#{project.id}/hooks/#{hook.id}", user3)
- response.status.should == 403
- end
- end
-
- it "should return a 404 error if hook id is not available" do
- get api("/projects/#{project.id}/hooks/1234", user)
- response.status.should == 404
- end
- end
-
- describe "POST /projects/:id/hooks" do
- it "should add hook to project" do
- expect {
- post api("/projects/#{project.id}/hooks", user),
- url: "http://example.com"
- }.to change {project.hooks.count}.by(1)
- response.status.should == 201
- end
-
- it "should return a 400 error if url not given" do
- post api("/projects/#{project.id}/hooks", user)
- response.status.should == 400
- end
-
- it "should return a 422 error if url not valid" do
- post api("/projects/#{project.id}/hooks", user), "url" => "ftp://example.com"
- response.status.should == 422
- end
- end
-
- describe "PUT /projects/:id/hooks/:hook_id" do
- it "should update an existing project hook" do
- put api("/projects/#{project.id}/hooks/#{hook.id}", user),
- url: 'http://example.org'
- response.status.should == 200
- json_response['url'].should == 'http://example.org'
- end
-
- it "should return 404 error if hook id not found" do
- put api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org'
- response.status.should == 404
- end
-
- it "should return 400 error if url is not given" do
- put api("/projects/#{project.id}/hooks/#{hook.id}", user)
- response.status.should == 400
- end
-
- it "should return a 422 error if url is not valid" do
- put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com'
- response.status.should == 422
- end
- end
-
- describe "DELETE /projects/:id/hooks/:hook_id" do
- it "should delete hook from project" do
- expect {
- delete api("/projects/#{project.id}/hooks/#{hook.id}", user)
- }.to change {project.hooks.count}.by(-1)
- response.status.should == 200
- end
-
- it "should return success when deleting hook" do
- delete api("/projects/#{project.id}/hooks/#{hook.id}", user)
- response.status.should == 200
- end
-
- it "should return success when deleting non existent hook" do
- delete api("/projects/#{project.id}/hooks/42", user)
- response.status.should == 200
- end
-
- it "should return a 405 error if hook id not given" do
- delete api("/projects/#{project.id}/hooks", user)
- response.status.should == 405
- end
- end
-
describe "GET /projects/:id/snippets" do
+ before { snippet }
+
it "should return an array of project snippets" do
get api("/projects/#{project.id}/snippets", user)
response.status.should == 200
@@ -543,6 +404,8 @@ describe API::API do
end
describe "DELETE /projects/:id/snippets/:snippet_id" do
+ before { snippet }
+
it "should delete existing project snippet" do
expect {
delete api("/projects/#{project.id}/snippets/#{snippet.id}", user)
@@ -628,10 +491,10 @@ describe API::API do
describe :fork_admin do
let(:project_fork_target) { create(:project) }
- let(:project_fork_source) { create(:project, public: true) }
+ let(:project_fork_source) { create(:project, :public) }
describe "POST /projects/:id/fork/:forked_from_id" do
- let(:new_project_fork_source) { create(:project, public: true) }
+ let(:new_project_fork_source) { create(:project, :public) }
it "shouldn't available for non admin users" do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
@@ -695,13 +558,15 @@ describe API::API do
describe "GET /projects/search/:query" do
let!(:query) { 'query'}
- let!(:search) { create(:project, name: query, creator_id: user.id, namespace: user.namespace) }
- let!(:pre) { create(:project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) }
- let!(:post) { create(:project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
- let!(:pre_post) { create(:project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
- let!(:unfound) { create(:project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
- let!(:public) { create(:project, name: "another #{query}",public: true) }
- let!(:unfound_public) { create(:project, name: 'unfound public', public: true) }
+ let!(:search) { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) }
+ let!(:pre) { create(:empty_project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) }
+ let!(:post) { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
+ let!(:pre_post) { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
+ let!(:unfound) { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
+ let!(:internal) { create(:empty_project, :internal, name: "internal #{query}") }
+ let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') }
+ let!(:public) { create(:empty_project, :public, name: "public #{query}") }
+ let!(:unfound_public) { create(:empty_project, :public, name: 'unfound public') }
context "when unauthenticated" do
it "should return authentication error" do
@@ -715,7 +580,7 @@ describe API::API do
get api("/projects/search/#{query}",user)
response.status.should == 200
json_response.should be_an Array
- json_response.size.should == 5
+ json_response.size.should == 6
json_response.each {|project| project['name'].should =~ /.*query.*/}
end
end
@@ -725,8 +590,8 @@ describe API::API do
get api("/projects/search/#{query}", user2)
response.status.should == 200
json_response.should be_an Array
- json_response.size.should == 1
- json_response.first['name'].should == "another #{query}"
+ json_response.size.should == 2
+ json_response.each {|project| project['name'].should =~ /(internal|public) query/}
end
end
end
@@ -768,4 +633,16 @@ describe API::API do
end
end
end
+
+ describe "GET /projects/:id/labels" do
+ before { issue_with_labels }
+
+ it "should return project labels" do
+ get api("/projects/#{project.id}/labels", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == issue_with_labels.labels.first.name
+ json_response.last['name'].should == issue_with_labels.labels.last.name
+ end
+ end
end
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 9649c4d09c8..99d966edc38 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -1,4 +1,5 @@
require 'spec_helper'
+require 'mime/types'
describe API::API do
include ApiHelpers
@@ -7,7 +8,7 @@ describe API::API do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let!(:project) { create(:project_with_code, creator_id: user.id) }
+ let!(:project) { create(:project, creator_id: user.id) }
let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) }
@@ -102,77 +103,6 @@ describe API::API do
end
end
- describe "GET /projects/:id/repository/commits" do
- context "authorized user" do
- before { project.team << [user2, :reporter] }
-
- it "should return project commits" do
- get api("/projects/#{project.id}/repository/commits", user)
- response.status.should == 200
-
- json_response.should be_an Array
- json_response.first['id'].should == project.repository.commit.id
- end
- end
-
- context "unauthorized user" do
- it "should not return project commits" do
- get api("/projects/#{project.id}/repository/commits")
- response.status.should == 401
- end
- end
- end
-
- describe "GET /projects:id/repository/commits/:sha" do
- context "authorized user" do
- it "should return a commit by sha" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
- response.status.should == 200
- json_response['id'].should == project.repository.commit.id
- json_response['title'].should == project.repository.commit.title
- end
-
- it "should return a 404 error if not found" do
- get api("/projects/#{project.id}/repository/commits/invalid_sha", user)
- response.status.should == 404
- end
- end
-
- context "unauthorized user" do
- it "should not return the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}")
- response.status.should == 401
- end
- end
- end
-
- describe "GET /projects:id/repository/commits/:sha/diff" do
- context "authorized user" do
- before { project.team << [user2, :reporter] }
-
- it "should return the diff of the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
- response.status.should == 200
-
- json_response.should be_an Array
- json_response.length.should >= 1
- json_response.first.keys.should include "diff"
- end
-
- it "should return a 404 error if invalid commit" do
- get api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user)
- response.status.should == 404
- end
- end
-
- context "unauthorized user" do
- it "should not return the diff of the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff")
- response.status.should == 401
- end
- end
- end
-
describe "GET /projects/:id/repository/tree" do
context "authorized user" do
before { project.team << [user2, :reporter] }
@@ -225,11 +155,36 @@ describe API::API do
end
end
- describe "GET /projects/:id/repository/archive/:sha" do
+ describe "GET /projects/:id/repository/raw_blobs/:sha" do
+ it "should get the raw file contents" do
+ get api("/projects/#{project.id}/repository/raw_blobs/d1aff2896d99d7acc4d9780fbb716b113c45ecf7", user)
+ response.status.should == 200
+ end
+ end
+
+ describe "GET /projects/:id/repository/archive(.:format)?:sha" do
it "should get the archive" do
get api("/projects/#{project.id}/repository/archive", user)
+ repo_name = project.repository.name.gsub("\.git", "")
+ response.status.should == 200
+ response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/
+ response.content_type.should == MIME::Types.type_for('file.tar.gz').first.content_type
+ end
+
+ it "should get the archive.zip" do
+ get api("/projects/#{project.id}/repository/archive.zip", user)
+ repo_name = project.repository.name.gsub("\.git", "")
+ response.status.should == 200
+ response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.zip\"/
+ response.content_type.should == MIME::Types.type_for('file.zip').first.content_type
+ end
+
+ it "should get the archive.tar.bz2" do
+ get api("/projects/#{project.id}/repository/archive.tar.bz2", user)
+ repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
- response.content_type.should == 'application/x-gzip'
+ response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/
+ response.content_type.should == MIME::Types.type_for('file.tar.bz2').first.content_type
end
it "should return 404 for invalid sha" do
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
new file mode 100644
index 00000000000..aecd18bc14a
--- /dev/null
+++ b/spec/requests/api/services_spec.rb
@@ -0,0 +1,33 @@
+require "spec_helper"
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
+ after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
+
+ let(:user) { create(:user) }
+ let(:project) {create(:project, creator_id: user.id, namespace: user.namespace) }
+
+ describe "POST /projects/:id/services/gitlab-ci" do
+ it "should update gitlab-ci settings" do
+ put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'secret-token', project_url: "http://ci.example.com/projects/1"
+
+ response.status.should == 200
+ end
+
+ it "should return if required fields missing" do
+ put api("/projects/#{project.id}/services/gitlab-ci", user), project_url: "http://ci.example.com/projects/1", active: true
+
+ response.status.should == 400
+ end
+ end
+
+ describe "DELETE /projects/:id/services/gitlab-ci" do
+ it "should update gitlab-ci settings" do
+ delete api("/projects/#{project.id}/services/gitlab-ci", user)
+
+ response.status.should == 200
+ project.gitlab_ci_service.should be_nil
+ end
+ end
+end
diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb
index 0fd90c567e0..668007dc29f 100644
--- a/spec/requests/api/session_spec.rb
+++ b/spec/requests/api/session_spec.rb
@@ -8,7 +8,7 @@ describe API::API do
describe "POST /session" do
context "when valid password" do
it "should return private token" do
- post api("/session"), email: user.email, password: '123456'
+ post api("/session"), email: user.email, password: '12345678'
response.status.should == 201
json_response['email'].should == user.email
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 4ef78b8e5d0..c4be5102002 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -93,7 +93,7 @@ describe API::API do
expect {
post api("/users", admin), attr
}.to change { User.count }.by(1)
- user = User.find_by_username(attr[:username])
+ user = User.find_by(username: attr[:username])
user.projects_limit.should == limit
user.theme_id.should == Gitlab::Theme::MARS
Gitlab.config.gitlab.unstub(:default_projects_limit)
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 5597f08d186..97f7392e50a 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" do
get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq')
end
+ it "to #archive format:zip" do
+ get("/gitlab/gitlabhq/repository/archive.zip").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'zip')
+ end
+
+ it "to #archive format:tar.bz2" do
+ get("/gitlab/gitlabhq/repository/archive.tar.bz2").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'tar.bz2')
+ end
+
it "to #show" do
get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq')
end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index 1b1d19d26b1..9b67cd432bc 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -111,13 +111,6 @@ describe HelpController, "routing" do
end
end
-# errors_githost GET /errors/githost(.:format) errors#githost
-describe ErrorsController, "routing" do
- it "to #githost" do
- get("/errors/githost").should route_to('errors#githost')
- end
-end
-
# profile_account GET /profile/account(.:format) profile#account
# profile_history GET /profile/history(.:format) profile#history
# profile_password PUT /profile/password(.:format) profile#password_update
@@ -183,6 +176,35 @@ describe Profiles::KeysController, "routing" do
it "to #destroy" do
delete("/profile/keys/1").should route_to('profiles/keys#destroy', id: '1')
end
+
+ # get all the ssh-keys of a user
+ it "to #get_keys" do
+ get("/foo.keys").should route_to('profiles/keys#get_keys', username: 'foo')
+ end
+end
+
+# emails GET /emails(.:format) emails#index
+# POST /keys(.:format) emails#create
+# DELETE /keys/:id(.:format) keys#destroy
+describe Profiles::EmailsController, "routing" do
+ it "to #index" do
+ get("/profile/emails").should route_to('profiles/emails#index')
+ end
+
+ it "to #create" do
+ post("/profile/emails").should route_to('profiles/emails#create')
+ end
+
+ it "to #destroy" do
+ delete("/profile/emails/1").should route_to('profiles/emails#destroy', id: '1')
+ end
+end
+
+# profile_avatar DELETE /profile/avatar(.:format) profiles/avatars#destroy
+describe Profiles::AvatarsController, "routing" do
+ it "to #destroy" do
+ delete("/profile/avatar").should route_to('profiles/avatars#destroy')
+ end
end
# dashboard GET /dashboard(.:format) dashboard#show
diff --git a/spec/seed_project.tar.gz b/spec/seed_project.tar.gz
index 7abb51ebdfd..8d32a927da8 100644
--- a/spec/seed_project.tar.gz
+++ b/spec/seed_project.tar.gz
Binary files differ
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
new file mode 100644
index 00000000000..713aa3e7e74
--- /dev/null
+++ b/spec/services/event_create_service_spec.rb
@@ -0,0 +1,103 @@
+require 'spec_helper'
+
+describe EventCreateService do
+ let(:service) { EventCreateService.new }
+
+ describe 'Issues' do
+ describe :open_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.open_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.open_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+
+ describe :close_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.close_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.close_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+
+ describe :reopen_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.reopen_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.reopen_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+ end
+
+ describe 'Merge Requests' do
+ describe :open_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.open_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.open_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :close_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.close_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.close_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :merge_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.merge_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.merge_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :reopen_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.reopen_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+ end
+
+ describe 'Milestone' do
+ let(:user) { create :user }
+
+ describe :open_milestone do
+ let(:milestone) { create(:milestone) }
+
+ it { service.open_milestone(milestone, user).should be_true }
+
+ it "should create new event" do
+ expect { service.open_milestone(milestone, user) }.to change { Event.count }
+ end
+ end
+
+ describe :close_mr do
+ let(:milestone) { create(:milestone) }
+
+ it { service.close_milestone(milestone, user).should be_true }
+
+ it "should create new event" do
+ expect { service.close_milestone(milestone, user) }.to change { Event.count }
+ end
+ end
+ end
+end
diff --git a/spec/contexts/fork_context_spec.rb b/spec/services/fork_service_spec.rb
index ed51b0c3f8e..b6573095dbd 100644
--- a/spec/contexts/fork_context_spec.rb
+++ b/spec/services/fork_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Projects::ForkContext do
+describe Projects::ForkService do
describe :fork_by_user do
before do
@from_namespace = create(:namespace)
@@ -47,8 +47,8 @@ describe Projects::ForkContext do
end
def fork_project(from_project, user, fork_success = true)
- context = Projects::ForkContext.new(from_project, user)
- shell = mock("gitlab_shell")
+ context = Projects::ForkService.new(from_project, user)
+ shell = double("gitlab_shell")
shell.stub(fork_repository: fork_success)
context.stub(gitlab_shell: shell)
context.execute
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 2870f59195a..90738c681fa 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe GitPushService do
let (:user) { create :user }
- let (:project) { create :project_with_code }
+ let (:project) { create :project }
let (:service) { GitPushService.new }
before do
@@ -74,38 +74,19 @@ describe GitPushService do
end
describe "Web Hooks" do
- context "with web hooks" do
- before do
- @project_hook = create(:project_hook)
- @project_hook_2 = create(:project_hook)
- project.hooks << [@project_hook, @project_hook_2]
-
- stub_request(:post, @project_hook.url)
- stub_request(:post, @project_hook_2.url)
- end
-
- it "executes multiple web hook" do
- @project_hook.should_receive(:async_execute).once
- @project_hook_2.should_receive(:async_execute).once
-
- service.execute(project, user, @oldrev, @newrev, @ref)
- end
- end
-
context "execute web hooks" do
- before do
- @project_hook = create(:project_hook)
- project.hooks << [@project_hook]
- stub_request(:post, @project_hook.url)
- end
-
it "when pushing a branch for the first time" do
- @project_hook.should_receive(:async_execute)
+ project.should_receive(:execute_hooks)
service.execute(project, user, @blankrev, 'newrev', 'refs/heads/master')
end
+ it "when pushing new commits to existing branch" do
+ project.should_receive(:execute_hooks)
+ service.execute(project, user, 'oldrev', 'newrev', 'refs/heads/master')
+ end
+
it "when pushing tags" do
- @project_hook.should_not_receive(:async_execute)
+ project.should_not_receive(:execute_hooks)
service.execute(project, user, 'newrev', 'newrev', 'refs/tags/v1.0.0')
end
end
diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb
new file mode 100644
index 00000000000..e65a8204c54
--- /dev/null
+++ b/spec/services/git_tag_push_service_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe GitTagPushService do
+ let (:user) { create :user }
+ let (:project) { create :project }
+ let (:service) { GitTagPushService.new }
+
+ before do
+ @ref = 'refs/tags/super-tag'
+ @oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81'
+ @newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb'
+ end
+
+ describe 'Git Tag Push Data' do
+ before do
+ service.execute(project, user, @oldrev, @newrev, @ref)
+ @push_data = service.push_data
+ end
+
+ subject { @push_data }
+
+ it { should include(ref: @ref) }
+ it { should include(before: @oldrev) }
+ it { should include(after: @newrev) }
+ it { should include(user_id: user.id) }
+ it { should include(user_name: user.name) }
+ it { should include(project_id: project.id) }
+
+ context 'With repository data' do
+ subject { @push_data[:repository] }
+
+ it { should include(name: project.name) }
+ it { should include(url: project.url_to_repo) }
+ it { should include(description: project.description) }
+ it { should include(homepage: project.web_url) }
+ end
+ end
+
+ describe "Web Hooks" do
+ context "execute web hooks" do
+ it "when pushing tags" do
+ project.should_receive(:execute_hooks)
+ service.execute(project, user, 'oldrev', 'newrev', 'refs/tags/v1.0.0')
+ end
+ end
+ end
+end
diff --git a/spec/contexts/issues/bulk_update_context_spec.rb b/spec/services/issues/bulk_update_context_spec.rb
index 058e43ba090..548109a8450 100644
--- a/spec/contexts/issues/bulk_update_context_spec.rb
+++ b/spec/services/issues/bulk_update_context_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Issues::BulkUpdateContext do
+describe Issues::BulkUpdateService do
before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
@@ -14,7 +14,7 @@ describe Issues::BulkUpdateContext do
name: "GitLab",
namespace: @user.namespace
}
- @project = Projects::CreateContext.new(@user, opts).execute
+ @project = Projects::CreateService.new(@user, opts).execute
end
describe :close_issue do
@@ -32,7 +32,7 @@ describe Issues::BulkUpdateContext do
end
it {
- result = Issues::BulkUpdateContext.new(@project, @user, @params).execute
+ result = Issues::BulkUpdateService.new(@project, @user, @params).execute
result[:success].should be_true
result[:count].should == @issues.count
@@ -57,7 +57,7 @@ describe Issues::BulkUpdateContext do
end
it {
- result = Issues::BulkUpdateContext.new(@project, @user, @params).execute
+ result = Issues::BulkUpdateService.new(@project, @user, @params).execute
result[:success].should be_true
result[:count].should == @issues.count
@@ -80,7 +80,7 @@ describe Issues::BulkUpdateContext do
end
it {
- result = Issues::BulkUpdateContext.new(@project, @user, @params).execute
+ result = Issues::BulkUpdateService.new(@project, @user, @params).execute
result[:success].should be_true
result[:count].should == 1
@@ -102,7 +102,7 @@ describe Issues::BulkUpdateContext do
end
it {
- result = Issues::BulkUpdateContext.new(@project, @user, @params).execute
+ result = Issues::BulkUpdateService.new(@project, @user, @params).execute
result[:success].should be_true
result[:count].should == 1
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index a112835d4d0..fbd73a7086f 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -16,9 +16,23 @@ describe NotificationService do
end
end
+ describe 'Email' do
+ describe :new_email do
+ let(:email) { create(:email) }
+
+ it { notification.new_email(email).should be_true }
+
+ it 'should send email to email owner' do
+ Notify.should_receive(:new_email_email).with(email.id)
+ notification.new_email(email)
+ end
+ end
+ end
+
describe 'Notes' do
context 'issue note' do
let(:issue) { create(:issue, assignee: create(:user)) }
+ let(:mentioned_issue) { create(:issue, assignee: issue.assignee) }
let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') }
before do
@@ -37,6 +51,13 @@ describe NotificationService do
notification.new_note(note)
end
+ it 'filters out "mentioned in" notes' do
+ mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project)
+
+ Notify.should_not_receive(:note_issue_email)
+ notification.new_note(mentioned_note)
+ end
+
def should_email(user_id)
Notify.should_receive(:note_issue_email).with(user_id, note.id)
end
@@ -124,11 +145,11 @@ describe NotificationService do
end
def should_email(user_id)
- Notify.should_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
+ Notify.should_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id, @u_disabled.id)
end
def should_not_email(user_id)
- Notify.should_not_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id)
+ Notify.should_not_receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id, @u_disabled.id)
end
end
@@ -188,11 +209,11 @@ describe NotificationService do
end
def should_email(user_id)
- Notify.should_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
+ Notify.should_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id, merge_request.author_id)
end
def should_not_email(user_id)
- Notify.should_not_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id)
+ Notify.should_not_receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id, merge_request.author_id)
end
end
@@ -220,15 +241,40 @@ describe NotificationService do
should_email(@u_watcher.id)
should_not_email(@u_participating.id)
should_not_email(@u_disabled.id)
- notification.merge_mr(merge_request)
+ notification.merge_mr(merge_request, @u_disabled)
+ end
+
+ def should_email(user_id)
+ Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
+ end
+
+ def should_not_email(user_id)
+ Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
+ end
+ end
+ end
+
+ describe 'Projects' do
+ let(:project) { create :project }
+
+ before do
+ build_team(project)
+ end
+
+ describe :project_was_moved do
+ it do
+ should_email(@u_watcher.id)
+ should_email(@u_participating.id)
+ should_not_email(@u_disabled.id)
+ notification.project_was_moved(project)
end
def should_email(user_id)
- Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+ Notify.should_receive(:project_was_moved_email).with(project.id, user_id)
end
def should_not_email(user_id)
- Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+ Notify.should_not_receive(:project_was_moved_email).with(project.id, user_id)
end
end
end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
new file mode 100644
index 00000000000..f2a784df103
--- /dev/null
+++ b/spec/services/projects/create_service_spec.rb
@@ -0,0 +1,163 @@
+require 'spec_helper'
+
+describe Projects::CreateService do
+ before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
+ after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
+
+ describe :create_by_user do
+ before do
+ @user = create :user
+ @admin = create :user, admin: true
+ @opts = {
+ name: "GitLab",
+ namespace: @user.namespace
+ }
+ end
+
+ context 'user namespace' do
+ before do
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.should be_valid }
+ it { @project.owner.should == @user }
+ it { @project.namespace.should == @user.namespace }
+ end
+
+ context 'group namespace' do
+ before do
+ @group = create :group
+ @group.add_owner(@user)
+
+ @opts.merge!(namespace_id: @group.id)
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.should be_valid }
+ it { @project.owner.should == @group }
+ it { @project.namespace.should == @group }
+ end
+
+ context 'wiki_enabled creates repository directory' do
+ context 'wiki_enabled true creates wiki repository directory' do
+ before do
+ @project = create_project(@user, @opts)
+ @path = GollumWiki.new(@project, @user).send(:path_to_repo)
+ end
+
+ it { File.exists?(@path).should be_true }
+ end
+
+ context 'wiki_enabled false does not create wiki repository directory' do
+ before do
+ @opts.merge!(wiki_enabled: false)
+ @project = create_project(@user, @opts)
+ @path = GollumWiki.new(@project, @user).send(:path_to_repo)
+ end
+
+ it { File.exists?(@path).should be_false }
+ end
+ end
+
+ context 'respect configured visibility setting' do
+ before(:each) do
+ @settings = double("settings")
+ @settings.stub(:issues) { true }
+ @settings.stub(:merge_requests) { true }
+ @settings.stub(:wiki) { true }
+ @settings.stub(:wall) { true }
+ @settings.stub(:snippets) { true }
+ stub_const("Settings", Class.new)
+ @restrictions = double("restrictions")
+ @restrictions.stub(:restricted_visibility_levels) { [] }
+ Settings.stub_chain(:gitlab).and_return(@restrictions)
+ Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings)
+ end
+
+ context 'should be public when setting is public' do
+ before do
+ @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC }
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.public?.should be_true }
+ end
+
+ context 'should be private when setting is private' do
+ before do
+ @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE }
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be internal when setting is internal' do
+ before do
+ @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::INTERNAL }
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.internal?.should be_true }
+ end
+ end
+
+ context 'respect configured visibility restrictions setting' do
+ before(:each) do
+ @settings = double("settings")
+ @settings.stub(:issues) { true }
+ @settings.stub(:merge_requests) { true }
+ @settings.stub(:wiki) { true }
+ @settings.stub(:wall) { true }
+ @settings.stub(:snippets) { true }
+ @settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE }
+ stub_const("Settings", Class.new)
+ @restrictions = double("restrictions")
+ @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] }
+ Settings.stub_chain(:gitlab).and_return(@restrictions)
+ Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings)
+ end
+
+ context 'should be private when option is public' do
+ before do
+ @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be public when option is public for admin' do
+ before do
+ @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ @project = create_project(@admin, @opts)
+ end
+
+ it { @project.public?.should be_true }
+ end
+
+ context 'should be private when option is private' do
+ before do
+ @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be internal when option is internal' do
+ before do
+ @opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ @project = create_project(@user, @opts)
+ end
+
+ it { @project.internal?.should be_true }
+ end
+ end
+ end
+
+ def create_project(user, opts)
+ Projects::CreateService.new(user, opts).execute
+ end
+end
+
diff --git a/spec/services/project_transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 109b429967e..109b429967e 100644
--- a/spec/services/project_transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
new file mode 100644
index 00000000000..1854c0d8233
--- /dev/null
+++ b/spec/services/projects/update_service_spec.rb
@@ -0,0 +1,111 @@
+require 'spec_helper'
+
+describe Projects::UpdateService do
+ before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
+ after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
+
+ describe :update_by_user do
+ before do
+ @user = create :user
+ @admin = create :user, admin: true
+ @project = create :project, creator_id: @user.id, namespace: @user.namespace
+ @opts = { project: {} }
+ end
+
+ context 'should be private when updated to private' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be internal when updated to internal' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.internal?.should be_true }
+ end
+
+ context 'should be public when updated to public' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.public?.should be_true }
+ end
+
+ context 'respect configured visibility restrictions setting' do
+ before(:each) do
+ @restrictions = double("restrictions")
+ @restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] }
+ Settings.stub_chain(:gitlab).and_return(@restrictions)
+ end
+
+ context 'should be private when updated to private' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be internal when updated to internal' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.internal?.should be_true }
+ end
+
+ context 'should be private when updated to public' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ update_project(@project, @user, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.private?.should be_true }
+ end
+
+ context 'should be public when updated to public by admin' do
+ before do
+ @created_private = @project.private?
+
+ @opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ update_project(@project, @admin, @opts)
+ end
+
+ it { @created_private.should be_true }
+ it { @project.public?.should be_true }
+ end
+ end
+ end
+
+ def update_project(project, user, opts)
+ Projects::UpdateService.new(project, user, opts).execute
+ end
+end
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
new file mode 100644
index 00000000000..b467282a5d6
--- /dev/null
+++ b/spec/services/search_service_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe 'Search::GlobalService' do
+ let(:user) { create(:user, namespace: found_namespace) }
+ let(:public_user) { create(:user, namespace: public_namespace) }
+ let(:internal_user) { create(:user, namespace: internal_namespace) }
+
+ let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') }
+ let(:unfound_namespace) { create(:namespace, name: 'unfound namespace', path: 'yet_something_else') }
+ let(:internal_namespace) { create(:namespace, name: 'searchable internal namespace', path: 'something_internal') }
+ let(:public_namespace) { create(:namespace, name: 'searchable public namespace', path: 'something_public') }
+
+ let!(:found_project) { create(:project, :private, name: 'searchable_project', creator_id: user.id, namespace: found_namespace) }
+ let!(:unfound_project) { create(:project, :private, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace) }
+ let!(:internal_project) { create(:project, :internal, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace) }
+ let!(:public_project) { create(:project, :public, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace) }
+
+ describe '#execute' do
+ context 'unauthenticated' do
+ it 'should return public projects only' do
+ context = Search::GlobalService.new(nil, search: "searchable")
+ results = context.execute
+ results[:projects].should match_array [public_project]
+ end
+ end
+
+ context 'authenticated' do
+ it 'should return public, internal and private projects' do
+ context = Search::GlobalService.new(user, search: "searchable")
+ results = context.execute
+ results[:projects].should match_array [public_project, found_project, internal_project]
+ end
+
+ it 'should return only public & internal projects' do
+ context = Search::GlobalService.new(internal_user, search: "searchable")
+ results = context.execute
+ results[:projects].should match_array [internal_project, public_project]
+ end
+
+ it 'namespace name should be searchable' do
+ context = Search::GlobalService.new(user, search: "searchable namespace")
+ results = context.execute
+ results[:projects].should match_array [found_project]
+ end
+ end
+ end
+end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index ebc1ed51d2e..f1df7e55dd0 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -24,10 +24,10 @@ describe SystemHooksService do
end
def event_data(*args)
- SystemHooksService.build_event_data(*args)
+ SystemHooksService.new.send :build_event_data, *args
end
def event_name(*args)
- SystemHooksService.build_event_name(*args)
+ SystemHooksService.new.send :build_event_name, *args
end
end
diff --git a/spec/services/test_hook_service_spec.rb b/spec/services/test_hook_service_spec.rb
new file mode 100644
index 00000000000..76af5bf7b88
--- /dev/null
+++ b/spec/services/test_hook_service_spec.rb
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+describe TestHookService do
+ let (:user) { create :user }
+ let (:project) { create :project }
+ let (:hook) { create :project_hook, project: project }
+
+ describe :execute do
+ it "should execute successfully" do
+ stub_request(:post, hook.url).to_return(status: 200)
+ TestHookService.new.execute(hook, user).should be_true
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index dd008ed02ad..e6b1f816df0 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,63 +1,50 @@
-require 'rubygems'
-require 'spork'
+# This file is copied to spec/ when you run 'rails generate rspec:install'
+ENV["RAILS_ENV"] ||= 'test'
+require File.expand_path("../../config/environment", __FILE__)
-Spork.prefork do
- require 'simplecov' unless ENV['CI']
+require 'simplecov' unless ENV['CI']
- if ENV['TRAVIS']
- require 'coveralls'
- Coveralls.wear!
- end
-
- # This file is copied to spec/ when you run 'rails generate rspec:install'
- ENV["RAILS_ENV"] ||= 'test'
- require File.expand_path("../../config/environment", __FILE__)
- require 'rspec/rails'
- require 'capybara/rails'
- require 'capybara/rspec'
- require 'webmock/rspec'
- require 'email_spec'
- require 'sidekiq/testing/inline'
- require 'capybara/poltergeist'
-
- # Loading more in this block will cause your tests to run faster. However,
-
- # if you change any configuration or code from libraries loaded here, you'll
- # need to restart spork for it take effect.
- Capybara.javascript_driver = :poltergeist
- Capybara.default_wait_time = 10
-
- # Requires supporting ruby files with custom matchers and macros, etc,
- # in spec/support/ and its subdirectories.
- Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
-
- WebMock.disable_net_connect!(allow_localhost: true)
-
- RSpec.configure do |config|
- config.mock_with :rspec
-
- config.include LoginHelpers, type: :feature
- config.include LoginHelpers, type: :request
- config.include FactoryGirl::Syntax::Methods
- config.include Devise::TestHelpers, type: :controller
-
- config.include TestEnv
-
- # 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
- # instead of true.
- config.use_transactional_fixtures = false
-
- config.before(:suite) do
- TestEnv.init(observers: false, init_repos: true, repos: false)
- end
- config.before(:each) do
- TestEnv.setup_stubs
- end
- end
+if ENV['TRAVIS']
+ require 'coveralls'
+ Coveralls.wear!
end
-Spork.each_run do
- # This code will be run each time you run your specs.
+require 'rspec/rails'
+require 'capybara/rails'
+require 'capybara/rspec'
+require 'webmock/rspec'
+require 'email_spec'
+require 'sidekiq/testing/inline'
+require 'capybara/poltergeist'
+
+Capybara.javascript_driver = :poltergeist
+Capybara.default_wait_time = 10
+
+# Requires supporting ruby files with custom matchers and macros, etc,
+# in spec/support/ and its subdirectories.
+Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+WebMock.disable_net_connect!(allow_localhost: true)
+RSpec.configure do |config|
+ config.mock_with :rspec
+
+ config.include LoginHelpers, type: :feature
+ config.include LoginHelpers, type: :request
+ config.include FactoryGirl::Syntax::Methods
+ config.include Devise::TestHelpers, type: :controller
+
+ config.include TestEnv
+
+ # 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
+ # instead of true.
+ config.use_transactional_fixtures = false
+
+ config.before(:suite) do
+ TestEnv.init(observers: false, init_repos: true, repos: false)
+ end
+ config.before(:each) do
+ TestEnv.setup_stubs
+ end
end
diff --git a/spec/support/chosen_helper.rb b/spec/support/chosen_helper.rb
deleted file mode 100644
index 42c9342c77a..00000000000
--- a/spec/support/chosen_helper.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# Chosen programmatic helper
-# It allows you to select value from chosen select
-#
-# Params
-# value - real value of selected item
-# opts - options containing css selector
-#
-# Usage:
-#
-# chosen(2, from: '#user_ids')
-#
-
-module ChosenHelper
- def chosen(value, options={})
- raise "Must pass a hash containing 'from'" if not options.is_a?(Hash) or not options.has_key?(:from)
-
- selector = options[:from]
-
- page.execute_script("$('#{selector}').val('#{value}').trigger('chosen:updated');")
- end
-end
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index 025534a900d..cc0ec2f4e3d 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -16,7 +16,7 @@ module LoginHelpers
def login_with(user)
visit new_user_session_path
fill_in "user_login", with: user.email
- fill_in "user_password", with: "123456"
+ fill_in "user_password", with: "12345678"
click_button "Sign in"
Thread.current[:current_user] = user
end
diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb
index a7f189777c8..3802e94ecf0 100644
--- a/spec/support/mentionable_shared_examples.rb
+++ b/spec/support/mentionable_shared_examples.rb
@@ -11,8 +11,8 @@ def common_mentionable_setup
let(:mentioned_issue) { create :issue, project: mproject }
let(:other_issue) { create :issue, project: mproject }
- let(:mentioned_mr) { create :merge_request, target_project: mproject, source_branch: 'different' }
- let(:mentioned_commit) { mock('commit', sha: '1234567890abcdef').as_null_object }
+ let(:mentioned_mr) { create :merge_request, source_project: mproject, source_branch: 'different' }
+ let(:mentioned_commit) { double('commit', sha: '1234567890abcdef').as_null_object }
# Override to add known commits to the repository stub.
let(:extra_commits) { [] }
@@ -30,7 +30,7 @@ def common_mentionable_setup
commitmap = { '123456' => mentioned_commit }
extra_commits.each { |c| commitmap[c.sha[0..5]] = c }
- repo = mock('repository')
+ repo = double('repository')
repo.stub(:commit) { |sha| commitmap[sha] }
mproject.stub(repository: repo)
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 16e10b1a62b..d237f7ad094 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -29,7 +29,6 @@ module TestEnv
disable_mailer if opts[:mailer] == false
setup_stubs
-
clear_test_repo_dir if opts[:init_repos] == true
setup_test_repos(opts) if opts[:repos] == true
end
@@ -45,6 +44,7 @@ module TestEnv
def disable_mailer
NotificationService.any_instance.stub(mailer: double.as_null_object)
end
+
def enable_mailer
NotificationService.any_instance.unstub(:mailer)
end
@@ -68,7 +68,12 @@ module TestEnv
remove_repository: true,
update_repository_head: true,
add_key: true,
- remove_key: true
+ remove_key: true,
+ version: '6.3.0'
+ )
+
+ Gitlab::Satellite::MergeAction.any_instance.stub(
+ merge!: true,
)
Gitlab::Satellite::Satellite.any_instance.stub(
@@ -85,7 +90,7 @@ module TestEnv
size: 12.45
)
- ActivityObserver.any_instance.stub(
+ BaseObserver.any_instance.stub(
current_user: double("current_user", id: 1)
)
end
@@ -96,13 +101,24 @@ module TestEnv
FileUtils.rm_rf File.join(testing_path(), "#{name}.wiki.git")
end
+ def reset_satellite_dir
+ setup_stubs
+ [
+ %W(git reset --hard --quiet),
+ %W(git clean -fx --quiet),
+ %W(git checkout --quiet origin/master)
+ ].each do |git_cmd|
+ system(*git_cmd, chdir: seed_satellite_path)
+ end
+ end
+
# Create a repo and it's satellite
def create_repo(namespace, name)
setup_stubs
repo = repo(namespace, name)
# Symlink tmp/repositories/gitlabhq to tmp/test-git-base-path/gitlabhq
- system("ln -s -f #{seed_repo_path()} #{repo}")
+ FileUtils.ln_sf(seed_repo_path, repo)
create_satellite(repo, namespace, name)
end
@@ -148,8 +164,7 @@ module TestEnv
def clear_test_repo_dir
setup_stubs
- # Use tmp dir for FS manipulations
- repos_path = testing_path()
+
# Remove tmp/test-git-base-path
FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
@@ -166,12 +181,11 @@ module TestEnv
# Symlink tmp/satellite/gitlabhq to tmp/test-git-base-path/satellite/gitlabhq, create the directory if it doesn't exist already
satellite_dir = File.dirname(satellite_repo)
FileUtils.mkdir_p(satellite_dir) unless File.exists?(satellite_dir)
- system("ln -s -f #{seed_satellite_path} #{satellite_repo}")
+ FileUtils.ln_sf(seed_satellite_path, satellite_repo)
end
def create_temp_repo(path)
FileUtils.mkdir_p path
- command = "git init --quiet --bare #{path};"
- system(command)
+ system(*%W(git init --quiet --bare -- #{path}))
end
end
diff --git a/spec/support/valid_commit.rb b/spec/support/valid_commit.rb
index 8094b679e99..98bc59b573f 100644
--- a/spec/support/valid_commit.rb
+++ b/spec/support/valid_commit.rb
@@ -2,6 +2,7 @@ module ValidCommit
ID = "8470d70da67355c9c009e4401746b1d5410af2e3"
MESSAGE = "notes controller refactored"
AUTHOR_FULL_NAME = "Dmitriy Zaporozhets"
+ AUTHOR_EMAIL = "dmitriy.zaporozhets@gmail.com"
FILES = [".foreman", ".gitignore", ".rails_footnotes", ".rspec", ".travis.yml", "CHANGELOG", "Gemfile", "Gemfile.lock", "LICENSE", "Procfile", "Procfile.production", "README.md", "Rakefile", "VERSION", "app", "config.ru", "config", "db", "doc", "lib", "log", "public", "resque.sh", "script", "spec", "vendor"]
FILES_COUNT = 26
diff --git a/spec/support/valid_commit_with_alt_email.rb b/spec/support/valid_commit_with_alt_email.rb
new file mode 100644
index 00000000000..d6e364c41f1
--- /dev/null
+++ b/spec/support/valid_commit_with_alt_email.rb
@@ -0,0 +1,6 @@
+module ValidCommitWithAltEmail
+ ID = "1e689bfba39525ead225eaf611948cfbe8ac34cf"
+ MESSAGE = "fixed notes logic"
+ AUTHOR_FULL_NAME = "Dmitriy Zaporozhets"
+ AUTHOR_EMAIL = "dzaporozhets@sphereconsultinginc.com"
+end \ No newline at end of file
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index cba243226db..71a45eb2fa6 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -5,6 +5,7 @@ describe 'gitlab:app namespace rake task' do
before :all do
Rake.application.rake_require "tasks/gitlab/task_helpers"
Rake.application.rake_require "tasks/gitlab/backup"
+ Rake.application.rake_require "tasks/gitlab/shell"
# empty task as env is already loaded
Rake::Task.define_task :environment
end
@@ -26,12 +27,15 @@ describe 'gitlab:app namespace rake task' do
Dir.stub :chdir
File.stub exists?: true
Kernel.stub system: true
+ FileUtils.stub cp_r: true
+ FileUtils.stub mv: true
+ Rake::Task["gitlab:shell:setup"].stub invoke: true
end
- let(:gitlab_version) { %x{git rev-parse HEAD}.gsub(/\n/,"") }
+ let(:gitlab_version) { Gitlab::VERSION }
it 'should fail on mismatch' do
- YAML.stub load_file: {gitlab_version: gitlab_version.reverse}
+ YAML.stub load_file: {gitlab_version: "not #{gitlab_version}" }
expect { run_rake_task }.to raise_error SystemExit
end
@@ -39,7 +43,8 @@ describe 'gitlab:app namespace rake task' do
YAML.stub load_file: {gitlab_version: gitlab_version}
Rake::Task["gitlab:backup:db:restore"].should_receive :invoke
Rake::Task["gitlab:backup:repo:restore"].should_receive :invoke
- expect { run_rake_task }.to_not raise_error SystemExit
+ Rake::Task["gitlab:shell:setup"].should_receive :invoke
+ expect { run_rake_task }.to_not raise_error
end
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 46e86dbe00a..e6bf79b853c 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -9,7 +9,7 @@ describe PostReceive do
end
context "web hook" do
- let(:project) { create(:project_with_code) }
+ let(:project) { create(:project) }
let(:key) { create(:key, user: project.owner) }
let(:key_id) { key.shell_id }
@@ -19,7 +19,7 @@ describe PostReceive do
end
it "does not run if the author is not in the project" do
- Key.stub(find_by_id: nil)
+ Key.stub(:find_by).with(hash_including(id: anything())) { nil }
project.should_not_receive(:execute_hooks)