summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2016-06-22 15:59:06 +0200
committerJames Lopez <james@jameslopez.es>2016-06-22 15:59:06 +0200
commit26b612258fe4223a91403e6414cb3f5897e2dd5e (patch)
treef0ec28ee785016faf974bc048342887571614562 /spec
parent4273e07e009b63dfd69b824c244826e7e62ac057 (diff)
parent6f6c6f68ea7cb976b6c1598e705ba8b2bdaf05a1 (diff)
downloadgitlab-ce-26b612258fe4223a91403e6414cb3f5897e2dd5e.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into fix/import-url-validator
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb6
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb8
-rw-r--r--spec/controllers/projects_controller_spec.rb20
-rw-r--r--spec/factories/ci/pipelines.rb (renamed from spec/factories/ci/commits.rb)0
-rw-r--r--spec/features/admin/admin_runners_spec.rb34
-rw-r--r--spec/features/container_registry_spec.rb3
-rw-r--r--spec/features/environments_spec.rb6
-rw-r--r--spec/features/groups/members/last_owner_cannot_leave_group_spec.rb16
-rw-r--r--spec/features/groups/members/member_leaves_group_spec.rb21
-rw-r--r--spec/features/groups/members/owner_manages_access_requests_spec.rb2
-rw-r--r--spec/features/groups/members/user_requests_access_spec.rb1
-rw-r--r--spec/features/issues_spec.rb2
-rw-r--r--spec/features/projects/badges/list_spec.rb8
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb30
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb19
-rw-r--r--spec/features/projects/members/owner_cannot_leave_project_spec.rb16
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb1
-rw-r--r--spec/features/projects_spec.rb16
-rw-r--r--spec/fixtures/container_registry/tag_manifest.json17
-rw-r--r--spec/helpers/application_helper_spec.rb45
-rw-r--r--spec/javascripts/issue_spec.js.coffee13
-rw-r--r--spec/lib/banzai/filter/relative_link_filter_spec.rb7
-rw-r--r--spec/lib/gitlab/lfs/lfs_router_spec.rb561
-rw-r--r--spec/lib/gitlab/template/gitignore_spec.rb (renamed from spec/lib/gitlab/gitignore_spec.rb)6
-rw-r--r--spec/mailers/notify_spec.rb61
-rw-r--r--spec/models/build_spec.rb127
-rw-r--r--spec/models/ci/runner_spec.rb241
-rw-r--r--spec/models/commit_spec.rb12
-rw-r--r--spec/models/commit_status_spec.rb19
-rw-r--r--spec/models/concerns/participable_spec.rb10
-rw-r--r--spec/models/key_spec.rb2
-rw-r--r--spec/models/member_spec.rb12
-rw-r--r--spec/models/members/group_member_spec.rb10
-rw-r--r--spec/models/members/project_member_spec.rb10
-rw-r--r--spec/requests/api/builds_spec.rb11
-rw-r--r--spec/requests/api/gitignores_spec.rb29
-rw-r--r--spec/requests/api/runners_spec.rb24
-rw-r--r--spec/requests/api/templates_spec.rb52
-rw-r--r--spec/services/members/destroy_service_spec.rb71
-rw-r--r--spec/workers/merge_worker_spec.rb2
41 files changed, 987 insertions, 566 deletions
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index 89c2c26a367..c8601341d54 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -118,9 +118,7 @@ describe Groups::GroupMembersController do
it 'cannot removes himself from the group' do
delete :leave, group_id: group
- expect(response).to redirect_to(group_path(group))
- expect(response).to set_flash[:alert].to "You can not leave the \"#{group.name}\" group. Transfer or delete the group."
- expect(group.users).to include user
+ expect(response.status).to eq(403)
end
end
@@ -134,7 +132,7 @@ describe Groups::GroupMembersController do
delete :leave, group_id: group
expect(response).to set_flash.to 'Your access request to the group has been withdrawn.'
- expect(response).to redirect_to(dashboard_groups_path)
+ expect(response).to redirect_to(group_path(group))
expect(group.members.request).to be_empty
expect(group.users).not_to include user
end
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index fc5f458e795..e5e750c855f 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -171,11 +171,7 @@ describe Projects::ProjectMembersController do
delete :leave, namespace_id: project.namespace,
project_id: project
- expect(response).to redirect_to(
- namespace_project_path(project.namespace, project)
- )
- expect(response).to set_flash[:alert].to "You can not leave the \"#{project.human_name}\" project. Transfer or delete the project."
- expect(project.users).to include user
+ expect(response.status).to eq(403)
end
end
@@ -190,7 +186,7 @@ describe Projects::ProjectMembersController do
project_id: project
expect(response).to set_flash.to 'Your access request to the project has been withdrawn.'
- expect(response).to redirect_to(dashboard_projects_path)
+ expect(response).to redirect_to(namespace_project_path(project.namespace, project))
expect(project.members.request).to be_empty
expect(project.users).not_to include user
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index fba545560c7..146b2c2e131 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -237,4 +237,24 @@ describe ProjectsController do
expect(response.status).to eq(401)
end
end
+
+ describe "GET refs" do
+ it "should get a list of branches and tags" do
+ get :refs, namespace_id: public_project.namespace.path, id: public_project.path
+
+ parsed_body = JSON.parse(response.body)
+ expect(parsed_body["Branches"]).to include("master")
+ expect(parsed_body["Tags"]).to include("v1.0.0")
+ expect(parsed_body["Commits"]).to be_nil
+ end
+
+ it "should get a list of branches, tags and commits" do
+ get :refs, namespace_id: public_project.namespace.path, id: public_project.path, ref: "123456"
+
+ parsed_body = JSON.parse(response.body)
+ expect(parsed_body["Branches"]).to include("master")
+ expect(parsed_body["Tags"]).to include("v1.0.0")
+ expect(parsed_body["Commits"]).to include("123456")
+ end
+ end
end
diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/pipelines.rb
index a039bef6f3c..a039bef6f3c 100644
--- a/spec/factories/ci/commits.rb
+++ b/spec/factories/ci/pipelines.rb
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 9499cd4e025..2d297776cb0 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -60,6 +60,40 @@ describe "Admin Runners" do
it { expect(page).to have_content(@project1.name_with_namespace) }
it { expect(page).not_to have_content(@project2.name_with_namespace) }
end
+
+ describe 'enable/create' do
+ before do
+ @project1.runners << runner
+ visit admin_runner_path(runner)
+ end
+
+ it 'enables specific runner for project' do
+ within '.unassigned-projects' do
+ click_on 'Enable'
+ end
+
+ assigned_project = page.find('.assigned-projects')
+
+ expect(assigned_project).to have_content(@project2.path)
+ end
+ end
+
+ describe 'disable/destroy' do
+ before do
+ @project1.runners << runner
+ visit admin_runner_path(runner)
+ end
+
+ it 'enables specific runner for project' do
+ within '.assigned-projects' do
+ click_on 'Disable'
+ end
+
+ new_runner_project = page.find('.unassigned-projects')
+
+ expect(new_runner_project).to have_content(@project1.path)
+ end
+ end
end
describe 'runners registration token' do
diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb
index 53b4f027117..203e55a36f2 100644
--- a/spec/features/container_registry_spec.rb
+++ b/spec/features/container_registry_spec.rb
@@ -26,7 +26,8 @@ describe "Container Registry" do
end
context 'when there are tags' do
- it { expect(page).to have_content(tag_name)}
+ it { expect(page).to have_content(tag_name) }
+ it { expect(page).to have_content('d7a513a66') }
end
end
diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb
index 40fea5211e9..7fb28f4174b 100644
--- a/spec/features/environments_spec.rb
+++ b/spec/features/environments_spec.rb
@@ -20,7 +20,7 @@ feature 'Environments', feature: true do
context 'without environments' do
scenario 'does show no environments' do
- expect(page).to have_content('No environments to show')
+ expect(page).to have_content('You don\'t have any environments right now.')
end
end
@@ -61,7 +61,7 @@ feature 'Environments', feature: true do
context 'without deployments' do
scenario 'does show no deployments' do
- expect(page).to have_content('No deployments for')
+ expect(page).to have_content('You don\'t have any deployments right now.')
end
end
@@ -108,7 +108,7 @@ feature 'Environments', feature: true do
end
scenario 'does create a new pipeline' do
- expect(page).to have_content('production')
+ expect(page).to have_content('Production')
end
end
diff --git a/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb
new file mode 100644
index 00000000000..33bf6d3752f
--- /dev/null
+++ b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+feature 'Groups > Members > Last owner cannot leave group', feature: true do
+ let(:owner) { create(:user) }
+ let(:group) { create(:group) }
+
+ background do
+ group.add_owner(owner)
+ login_as(owner)
+ visit group_path(group)
+ end
+
+ scenario 'user does not see a "Leave Group" link' do
+ expect(page).not_to have_content 'Leave Group'
+ end
+end
diff --git a/spec/features/groups/members/member_leaves_group_spec.rb b/spec/features/groups/members/member_leaves_group_spec.rb
new file mode 100644
index 00000000000..3185ff924b9
--- /dev/null
+++ b/spec/features/groups/members/member_leaves_group_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+feature 'Groups > Members > Member leaves group', feature: true do
+ let(:user) { create(:user) }
+ let(:owner) { create(:user) }
+ let(:group) { create(:group, :public) }
+
+ background do
+ group.add_owner(owner)
+ group.add_developer(user)
+ login_as(user)
+ visit group_path(group)
+ end
+
+ scenario 'user leaves group' do
+ click_link 'Leave Group'
+
+ expect(current_path).to eq(dashboard_groups_path)
+ expect(group.users.exists?(user.id)).to be_falsey
+ end
+end
diff --git a/spec/features/groups/members/owner_manages_access_requests_spec.rb b/spec/features/groups/members/owner_manages_access_requests_spec.rb
index 22525ce530b..321c9bad7d0 100644
--- a/spec/features/groups/members/owner_manages_access_requests_spec.rb
+++ b/spec/features/groups/members/owner_manages_access_requests_spec.rb
@@ -42,7 +42,7 @@ feature 'Groups > Members > Owner manages access requests', feature: true do
def expect_visible_access_request(group, user)
expect(group.members.request.exists?(user_id: user)).to be_truthy
- expect(page).to have_content "#{group.name} access requests (1)"
+ expect(page).to have_content "#{group.name} access requests 1"
expect(page).to have_content user.name
end
end
diff --git a/spec/features/groups/members/user_requests_access_spec.rb b/spec/features/groups/members/user_requests_access_spec.rb
index a878a96b6ee..1ea607cbca0 100644
--- a/spec/features/groups/members/user_requests_access_spec.rb
+++ b/spec/features/groups/members/user_requests_access_spec.rb
@@ -21,6 +21,7 @@ feature 'Groups > Members > User requests access', feature: true do
expect(page).to have_content 'Your request for access has been queued for review.'
expect(page).to have_content 'Withdraw Access Request'
+ expect(page).not_to have_content 'Leave Group'
end
scenario 'user is not listed in the group members page' do
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index c3cb3379440..5065dfb849c 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -22,7 +22,7 @@ describe 'Issues', feature: true do
before do
visit edit_namespace_project_issue_path(project.namespace, project, issue)
- click_button "Go full screen"
+ find('.js-zen-enter').click
end
it 'should open new issue popup' do
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index 51be81d634c..01e90618a98 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
feature 'list of badges' do
- include Select2Helper
-
background do
user = create(:user)
project = create(:project)
@@ -24,7 +22,11 @@ feature 'list of badges' do
end
scenario 'user changes current ref on badges list page', js: true do
- select2('improve/awesome', from: '#ref')
+ first('.js-project-refs-dropdown').click
+
+ page.within '.project-refs-form' do
+ click_link 'improve/awesome'
+ end
expect(page).to have_content 'badges/improve/awesome/build.svg'
end
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
new file mode 100644
index 00000000000..d516e8ce55a
--- /dev/null
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+feature 'User wants to add a .gitlab-ci.yml file', feature: true do
+ include WaitForAjax
+
+ before do
+ user = create(:user)
+ project = create(:project)
+ project.team << [user, :master]
+ login_as user
+ visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitlab-ci.yml')
+ end
+
+ scenario 'user can see .gitlab-ci.yml dropdown' do
+ expect(page).to have_css('.gitlab-ci-yml-selector')
+ end
+
+ scenario 'user can pick a template from the dropdown', js: true do
+ find('.js-gitlab-ci-yml-selector').click
+ wait_for_ajax
+ within '.gitlab-ci-yml-selector' do
+ find('.dropdown-input-field').set('jekyll')
+ find('.dropdown-content li', text: 'jekyll').click
+ end
+ wait_for_ajax
+
+ expect(page).to have_content('This file is a template, and might need editing before it works on your project')
+ expect(page).to have_content('jekyll build -d test')
+ end
+end
diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb
index 5fe4caa12f0..aa2d906fa2e 100644
--- a/spec/features/projects/members/master_manages_access_requests_spec.rb
+++ b/spec/features/projects/members/master_manages_access_requests_spec.rb
@@ -41,7 +41,7 @@ feature 'Projects > Members > Master manages access requests', feature: true do
def expect_visible_access_request(project, user)
expect(project.members.request.exists?(user_id: user)).to be_truthy
- expect(page).to have_content "#{project.name} access requests (1)"
+ expect(page).to have_content "#{project.name} access requests 1"
expect(page).to have_content user.name
end
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
new file mode 100644
index 00000000000..79dec442818
--- /dev/null
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+feature 'Projects > Members > Member leaves project', feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ background do
+ project.team << [user, :developer]
+ login_as(user)
+ visit namespace_project_path(project.namespace, project)
+ end
+
+ scenario 'user leaves project' do
+ click_link 'Leave Project'
+
+ expect(current_path).to eq(dashboard_projects_path)
+ expect(project.users.exists?(user.id)).to be_falsey
+ end
+end
diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
new file mode 100644
index 00000000000..67811b1048e
--- /dev/null
+++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+feature 'Projects > Members > Owner cannot leave project', feature: true do
+ let(:owner) { create(:user) }
+ let(:project) { create(:project) }
+
+ background do
+ project.team << [owner, :owner]
+ login_as(owner)
+ visit namespace_project_path(project.namespace, project)
+ end
+
+ scenario 'user does not see a "Leave Project" link' do
+ expect(page).not_to have_content 'Leave Project'
+ end
+end
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index fd92a3a2f0c..af420c170ef 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -21,6 +21,7 @@ feature 'Projects > Members > User requests access', feature: true do
expect(page).to have_content 'Your request for access has been queued for review.'
expect(page).to have_content 'Withdraw Access Request'
+ expect(page).not_to have_content 'Leave Project'
end
scenario 'user is not listed in the project members page' do
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 9dd0378d165..6fa8298d489 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -70,22 +70,6 @@ feature 'Project', feature: true do
end
end
- describe 'leave project link' do
- let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
-
- before do
- login_with(user)
- project.team.add_user(user, Gitlab::Access::MASTER)
- visit namespace_project_path(project.namespace, project)
- end
-
- it 'click project-settings and find leave project' do
- find('#project-settings-button').click
- expect(page).to have_link('Leave Project')
- end
- end
-
describe 'project title' do
include WaitForAjax
diff --git a/spec/fixtures/container_registry/tag_manifest.json b/spec/fixtures/container_registry/tag_manifest.json
index 1b6008e2872..8d1b874c29b 100644
--- a/spec/fixtures/container_registry/tag_manifest.json
+++ b/spec/fixtures/container_registry/tag_manifest.json
@@ -1 +1,16 @@
-{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/octet-stream","size":1145,"digest":"sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac"},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","size":2319870,"digest":"sha256:420890c9e918b6668faaedd9000e220190f2493b0693ee563ebd7b4cc754a57d"}]}
+{
+ "schemaVersion": 2,
+ "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
+ "config": {
+ "mediaType": "application/octet-stream",
+ "size": 1145,
+ "digest": "sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac"
+ },
+ "layers": [
+ {
+ "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
+ "size": 2319870,
+ "digest": "sha256:420890c9e918b6668faaedd9000e220190f2493b0693ee563ebd7b4cc754a57d"
+ }
+ ]
+}
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index f6c1005d265..bb28866f010 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -174,51 +174,6 @@ describe ApplicationHelper do
end
end
- describe 'grouped_options_refs' do
- let(:options) { helper.grouped_options_refs }
- let(:project) { create(:project) }
-
- before do
- assign(:project, project)
-
- # Override Rails' grouped_options_for_select helper to just return the
- # first argument (`options`), since it's easier to work with than the
- # generated HTML.
- allow(helper).to receive(:grouped_options_for_select).
- and_wrap_original { |_, *args| args.first }
- end
-
- it 'includes a list of branch names' do
- expect(options[0][0]).to eq('Branches')
- expect(options[0][1]).to include('master', 'feature')
- end
-
- it 'includes a list of tag names' do
- expect(options[1][0]).to eq('Tags')
- expect(options[1][1]).to include('v1.0.0', 'v1.1.0')
- end
-
- it 'includes a specific commit ref if defined' do
- # Must be an instance variable
- ref = '2ed06dc41dbb5936af845b87d79e05bbf24c73b8'
- assign(:ref, ref)
-
- expect(options[2][0]).to eq('Commit')
- expect(options[2][1]).to eq([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', 'v2.0rc1¿',
- 'v1.0.9a', 'v2.0-rc1', 'v2.0rc2'])
-
- expect(options[1][1]).
- to eq(['v3.1.4.2', 'v2.0', 'v2.0rc2', 'v2.0rc1¿', 'v2.0-rc1', 'v1.0.10',
- 'v1.0.9', 'v1.0.9a'])
- end
- end
-
describe 'simple_sanitize' do
let(:a_tag) { '<a href="#">Foo</a>' }
diff --git a/spec/javascripts/issue_spec.js.coffee b/spec/javascripts/issue_spec.js.coffee
index ea27f36e9b5..71f0c1076c5 100644
--- a/spec/javascripts/issue_spec.js.coffee
+++ b/spec/javascripts/issue_spec.js.coffee
@@ -1,3 +1,4 @@
+#= require lib/text_utility
#= require issue
describe 'Issue', ->
@@ -38,7 +39,7 @@ describe 'reopen/close issue', ->
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
$btnClose.trigger('click')
-
+
expect($btnReopen).toBeVisible()
expect($btnClose).toBeHidden()
expect($('div.status-box-closed')).toBeVisible()
@@ -50,7 +51,7 @@ describe 'reopen/close issue', ->
expect(req.type).toBe('PUT')
expect(req.url).toBe('http://goesnowhere.nothing/whereami')
req.success saved: false
-
+
$btnClose = $('a.btn-close')
$btnReopen = $('a.btn-reopen')
$btnClose.attr('href','http://goesnowhere.nothing/whereami')
@@ -59,7 +60,7 @@ describe 'reopen/close issue', ->
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
$btnClose.trigger('click')
-
+
expect($btnReopen).toBeHidden()
expect($btnClose).toBeVisible()
expect($('div.status-box-closed')).toBeHidden()
@@ -73,7 +74,7 @@ describe 'reopen/close issue', ->
expect(req.type).toBe('PUT')
expect(req.url).toBe('http://goesnowhere.nothing/whereami')
req.error()
-
+
$btnClose = $('a.btn-close')
$btnReopen = $('a.btn-reopen')
$btnClose.attr('href','http://goesnowhere.nothing/whereami')
@@ -82,7 +83,7 @@ describe 'reopen/close issue', ->
expect(typeof $btnClose.prop('disabled')).toBe('undefined')
$btnClose.trigger('click')
-
+
expect($btnReopen).toBeHidden()
expect($btnClose).toBeVisible()
expect($('div.status-box-closed')).toBeHidden()
@@ -105,4 +106,4 @@ describe 'reopen/close issue', ->
expect($btnReopen).toBeHidden()
expect($btnClose).toBeVisible()
expect($('div.status-box-open')).toBeVisible()
- expect($('div.status-box-closed')).toBeHidden() \ No newline at end of file
+ expect($('div.status-box-closed')).toBeHidden()
diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb
index 0e6685f0ffb..b9e4a4eaf0e 100644
--- a/spec/lib/banzai/filter/relative_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb
@@ -132,11 +132,8 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do
path = 'files/images/한글.png'
escaped = Addressable::URI.escape(path)
- # Stub these methods so the file doesn't actually need to be in the repo
- allow_any_instance_of(described_class).
- to receive(:file_exists?).and_return(true)
- allow_any_instance_of(described_class).
- to receive(:image?).with(path).and_return(true)
+ # Stub this method so the file doesn't actually need to be in the repo
+ allow_any_instance_of(described_class).to receive(:uri_type).and_return(:raw)
doc = filter(image(escaped))
expect(doc.at_css('img')['src']).to match '/raw/'
diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb
index 88814bc474d..659facd6c19 100644
--- a/spec/lib/gitlab/lfs/lfs_router_spec.rb
+++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb
@@ -17,12 +17,15 @@ describe Gitlab::Lfs::Router, lib: true do
}
end
- let(:lfs_router_auth) { new_lfs_router(project, user) }
- let(:lfs_router_noauth) { new_lfs_router(project, nil) }
- let(:lfs_router_public_auth) { new_lfs_router(public_project, user) }
- let(:lfs_router_public_noauth) { new_lfs_router(public_project, nil) }
- let(:lfs_router_forked_noauth) { new_lfs_router(forked_project, nil) }
- let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user_two) }
+ let(:lfs_router_auth) { new_lfs_router(project, user: user) }
+ let(:lfs_router_ci_auth) { new_lfs_router(project, ci: true) }
+ let(:lfs_router_noauth) { new_lfs_router(project) }
+ let(:lfs_router_public_auth) { new_lfs_router(public_project, user: user) }
+ let(:lfs_router_public_ci_auth) { new_lfs_router(public_project, ci: true) }
+ let(:lfs_router_public_noauth) { new_lfs_router(public_project) }
+ let(:lfs_router_forked_noauth) { new_lfs_router(forked_project) }
+ let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user: user_two) }
+ let(:lfs_router_forked_ci_auth) { new_lfs_router(forked_project, ci: true) }
let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" }
let(:sample_size) { 499013 }
@@ -80,6 +83,7 @@ describe Gitlab::Lfs::Router, lib: true do
context 'with required headers' do
before do
+ project.lfs_objects << lfs_object
env['HTTP_X_SENDFILE_TYPE'] = "X-Sendfile"
end
@@ -91,7 +95,6 @@ describe Gitlab::Lfs::Router, lib: true do
context 'when user has project access' do
before do
- project.lfs_objects << lfs_object
project.team << [user, :master]
end
@@ -104,6 +107,17 @@ describe Gitlab::Lfs::Router, lib: true do
expect(lfs_router_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
end
end
+
+ context 'when CI is authorized' do
+ it "responds with status 200" do
+ expect(lfs_router_ci_auth.try_call.first).to eq(200)
+ end
+
+ it "responds with the file location" do
+ expect(lfs_router_ci_auth.try_call[1]['Content-Type']).to eq("application/octet-stream")
+ expect(lfs_router_ci_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
+ end
+ end
end
context 'without required headers' do
@@ -134,143 +148,145 @@ describe Gitlab::Lfs::Router, lib: true do
end
describe 'download' do
- describe 'when user is authenticated' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
+ before do
+ body = { 'operation' => 'download',
+ 'objects' => [
+ { 'oid' => sample_oid,
+ 'size' => sample_size
+ }]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ end
- describe 'when user has download access' do
+ shared_examples 'an authorized requests' do
+ context 'when downloading an lfs object that is assigned to our project' do
before do
- @auth = authorize(user)
- env["HTTP_AUTHORIZATION"] = @auth
- project.team << [user, :reporter]
+ project.lfs_objects << lfs_object
end
- context 'when downloading an lfs object that is assigned to our project' do
- before do
- project.lfs_objects << lfs_object
- end
-
- it 'responds with status 200 and href to download' do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
+ it 'responds with status 200 and href to download' do
+ response = router.try_call
+ expect(response.first).to eq(200)
+ response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body).to eq('objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'actions' => {
- 'download' => {
- 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
- 'header' => { 'Authorization' => @auth }
- }
+ expect(response_body).to eq('objects' => [
+ { 'oid' => sample_oid,
+ 'size' => sample_size,
+ 'actions' => {
+ 'download' => {
+ 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
+ 'header' => { 'Authorization' => auth }
}
- }])
- end
+ }
+ }])
end
+ end
- context 'when downloading an lfs object that is assigned to other project' do
- before do
- public_project.lfs_objects << lfs_object
- end
+ context 'when downloading an lfs object that is assigned to other project' do
+ before do
+ public_project.lfs_objects << lfs_object
+ end
- it 'responds with status 200 and error message' do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
+ it 'responds with status 200 and error message' do
+ response = router.try_call
+ expect(response.first).to eq(200)
+ response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body).to eq('objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- }])
- end
+ expect(response_body).to eq('objects' => [
+ { 'oid' => sample_oid,
+ 'size' => sample_size,
+ 'error' => {
+ 'code' => 404,
+ 'message' => "Object does not exist on the server or you don't have permissions to access it",
+ }
+ }])
end
+ end
- context 'when downloading a lfs object that does not exist' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
+ context 'when downloading a lfs object that does not exist' do
+ before do
+ body = { 'operation' => 'download',
+ 'objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078
+ }]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ end
- it "responds with status 200 and error message" do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
+ it "responds with status 200 and error message" do
+ response = router.try_call
+ expect(response.first).to eq(200)
+ response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body).to eq('objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- }])
- end
+ expect(response_body).to eq('objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078,
+ 'error' => {
+ 'code' => 404,
+ 'message' => "Object does not exist on the server or you don't have permissions to access it",
+ }
+ }])
end
+ end
- context 'when downloading one new and one existing lfs object' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- },
- { 'oid' => sample_oid,
- 'size' => sample_size
- }
- ]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- project.lfs_objects << lfs_object
- end
+ context 'when downloading one new and one existing lfs object' do
+ before do
+ body = { 'operation' => 'download',
+ 'objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078
+ },
+ { 'oid' => sample_oid,
+ 'size' => sample_size
+ }
+ ]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ project.lfs_objects << lfs_object
+ end
- it "responds with status 200 with upload hypermedia link for the new object" do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
+ it "responds with status 200 with upload hypermedia link for the new object" do
+ response = router.try_call
+ expect(response.first).to eq(200)
+ response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body).to eq('objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- },
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'actions' => {
- 'download' => {
- 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
- 'header' => { 'Authorization' => @auth }
- }
+ expect(response_body).to eq('objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078,
+ 'error' => {
+ 'code' => 404,
+ 'message' => "Object does not exist on the server or you don't have permissions to access it",
+ }
+ },
+ { 'oid' => sample_oid,
+ 'size' => sample_size,
+ 'actions' => {
+ 'download' => {
+ 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
+ 'header' => { 'Authorization' => auth }
}
- }])
- end
+ }
+ }])
end
end
+ end
+
+ context 'when user is authenticated' do
+ let(:auth) { authorize(user) }
+
+ before do
+ env["HTTP_AUTHORIZATION"] = auth
+ project.team << [user, role]
+ end
+
+ it_behaves_like 'an authorized requests' do
+ let(:role) { :reporter }
+ let(:router) { lfs_router_auth }
+ end
context 'when user does is not member of the project' do
- before do
- @auth = authorize(user)
- env["HTTP_AUTHORIZATION"] = @auth
- project.team << [user, :guest]
- end
+ let(:role) { :guest }
it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403)
@@ -278,11 +294,7 @@ describe Gitlab::Lfs::Router, lib: true do
end
context 'when user does not have download access' do
- before do
- @auth = authorize(user)
- env["HTTP_AUTHORIZATION"] = @auth
- project.team << [user, :guest]
- end
+ let(:role) { :guest }
it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403)
@@ -290,18 +302,19 @@ describe Gitlab::Lfs::Router, lib: true do
end
end
- context 'when user is not authenticated' do
+ context 'when CI is authorized' do
+ let(:auth) { 'gitlab-ci-token:password' }
+
before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }],
+ env["HTTP_AUTHORIZATION"] = auth
+ end
- }.to_json
- env['rack.input'] = StringIO.new(body)
+ it_behaves_like 'an authorized requests' do
+ let(:router) { lfs_router_ci_auth }
end
+ end
+ context 'when user is not authenticated' do
describe 'is accessing public project' do
before do
public_project.lfs_objects << lfs_object
@@ -338,17 +351,17 @@ describe Gitlab::Lfs::Router, lib: true do
end
describe 'upload' do
- describe 'when user is authenticated' do
- before do
- body = { 'operation' => 'upload',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
+ before do
+ body = { 'operation' => 'upload',
+ 'objects' => [
+ { 'oid' => sample_oid,
+ 'size' => sample_size
+ }]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ end
+ describe 'when request is authenticated' do
describe 'when user has project push access' do
before do
@auth = authorize(user)
@@ -440,15 +453,15 @@ describe Gitlab::Lfs::Router, lib: true do
expect(lfs_router_auth.try_call.first).to eq(403)
end
end
- end
- context 'when user is not authenticated' do
- before do
- env['rack.input'] = StringIO.new(
- { 'objects' => [], 'operation' => 'upload' }.to_json
- )
+ context 'when CI is authorized' do
+ it 'responds with 401' do
+ expect(lfs_router_ci_auth.try_call.first).to eq(401)
+ end
end
+ end
+ context 'when user is not authenticated' do
context 'when user has push access' do
before do
project.team << [user, :master]
@@ -465,6 +478,18 @@ describe Gitlab::Lfs::Router, lib: true do
end
end
end
+
+ context 'when CI is authorized' do
+ let(:auth) { 'gitlab-ci-token:password' }
+
+ before do
+ env["HTTP_AUTHORIZATION"] = auth
+ end
+
+ it "responds with status 403" do
+ expect(lfs_router_public_ci_auth.try_call.first).to eq(401)
+ end
+ end
end
describe 'unsupported' do
@@ -490,13 +515,68 @@ describe Gitlab::Lfs::Router, lib: true do
env['REQUEST_METHOD'] = 'PUT'
end
- describe 'to one project' do
- describe 'when user has push access to the project' do
+ shared_examples 'unauthorized' do
+ context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
- project.team << [user, :master]
+ header_for_upload_authorize(router.project)
+ end
+
+ it 'responds with status 401' do
+ expect(router.try_call.first).to eq(401)
+ end
+ end
+
+ context 'and request is sent by gitlab-workhorse to finalize the upload' do
+ before do
+ headers_for_upload_finalize(router.project)
+ end
+
+ it 'responds with status 401' do
+ expect(router.try_call.first).to eq(401)
+ end
+ end
+
+ context 'and request is sent with a malformed headers' do
+ before do
+ env["PATH_INFO"] = "#{router.project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
+ env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
+ end
+
+ it 'does not recognize it as a valid lfs command' do
+ expect(router.try_call).to eq(nil)
+ end
+ end
+ end
+
+ shared_examples 'forbidden' do
+ context 'and request is sent by gitlab-workhorse to authorize the request' do
+ before do
+ header_for_upload_authorize(router.project)
+ end
+
+ it 'responds with 403' do
+ expect(router.try_call.first).to eq(403)
+ end
+ end
+
+ context 'and request is sent by gitlab-workhorse to finalize the upload' do
+ before do
+ headers_for_upload_finalize(router.project)
+ end
+
+ it 'responds with 403' do
+ expect(router.try_call.first).to eq(403)
end
+ end
+ end
+
+ describe 'to one project' do
+ describe 'when user is authenticated' do
+ describe 'when user has push access to the project' do
+ before do
+ project.team << [user, :developer]
+ end
- describe 'when user is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(project)
@@ -524,100 +604,35 @@ describe Gitlab::Lfs::Router, lib: true do
end
end
- describe 'when user is unauthenticated' do
- let(:lfs_router_noauth) { new_lfs_router(project, nil) }
+ describe 'and user does not have push access' do
+ let(:router) { lfs_router_auth }
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(project)
- end
-
- it 'responds with status 401' do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(project)
- end
-
- it 'responds with status 401' do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
-
- context 'and request is sent with a malformed headers' do
- before do
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
- env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
- end
-
- it 'does not recognize it as a valid lfs command' do
- expect(lfs_router_noauth.try_call).to eq(nil)
- end
- end
+ it_behaves_like 'forbidden'
end
end
- describe 'and user does not have push access' do
- describe 'when user is authenticated' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(project)
- end
-
- it 'responds with 403' do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(project)
- end
-
- it 'responds with 403' do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
- end
+ context 'when CI is authenticated' do
+ let(:router) { lfs_router_ci_auth }
- describe 'when user is unauthenticated' do
- let(:lfs_router_noauth) { new_lfs_router(project, nil) }
-
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(project)
- end
+ it_behaves_like 'unauthorized'
+ end
- it 'responds with 401' do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
+ context 'for unauthenticated' do
+ let(:router) { new_lfs_router(project) }
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(project)
- end
-
- it 'responds with 401' do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
- end
+ it_behaves_like 'unauthorized'
end
end
- describe "to a forked project" do
+ describe 'to a forked project' do
let(:forked_project) { fork_project(public_project, user) }
- describe 'when user has push access to the project' do
- before do
- forked_project.team << [user_two, :master]
- end
+ describe 'when user is authenticated' do
+ describe 'when user has push access to the project' do
+ before do
+ forked_project.team << [user_two, :developer]
+ end
- describe 'when user is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(forked_project)
@@ -645,78 +660,28 @@ describe Gitlab::Lfs::Router, lib: true do
end
end
- describe 'when user is unauthenticated' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(forked_project)
- end
-
- it 'responds with status 401' do
- expect(lfs_router_forked_noauth.try_call.first).to eq(401)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(forked_project)
- end
+ describe 'and user does not have push access' do
+ let(:router) { lfs_router_forked_auth }
- it 'responds with status 401' do
- expect(lfs_router_forked_noauth.try_call.first).to eq(401)
- end
- end
+ it_behaves_like 'forbidden'
end
end
- describe 'and user does not have push access' do
- describe 'when user is authenticated' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(forked_project)
- end
+ context 'when CI is authenticated' do
+ let(:router) { lfs_router_forked_ci_auth }
- it 'responds with 403' do
- expect(lfs_router_forked_auth.try_call.first).to eq(403)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(forked_project)
- end
-
- it 'responds with 403' do
- expect(lfs_router_forked_auth.try_call.first).to eq(403)
- end
- end
- end
-
- describe 'when user is unauthenticated' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(forked_project)
- end
-
- it 'responds with 401' do
- expect(lfs_router_forked_noauth.try_call.first).to eq(401)
- end
- end
+ it_behaves_like 'unauthorized'
+ end
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(forked_project)
- end
+ context 'for unauthenticated' do
+ let(:router) { lfs_router_forked_noauth }
- it 'responds with 401' do
- expect(lfs_router_forked_noauth.try_call.first).to eq(401)
- end
- end
- end
+ it_behaves_like 'unauthorized'
end
describe 'and second project not related to fork or a source project' do
let(:second_project) { create(:project) }
- let(:lfs_router_second_project) { new_lfs_router(second_project, user) }
+ let(:lfs_router_second_project) { new_lfs_router(second_project, user: user) }
before do
public_project.lfs_objects << lfs_object
@@ -745,8 +710,8 @@ describe Gitlab::Lfs::Router, lib: true do
ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password)
end
- def new_lfs_router(project, user)
- Gitlab::Lfs::Router.new(project, user, request)
+ def new_lfs_router(project, user: nil, ci: false)
+ Gitlab::Lfs::Router.new(project, user, ci, request)
end
def header_for_upload_authorize(project)
diff --git a/spec/lib/gitlab/gitignore_spec.rb b/spec/lib/gitlab/template/gitignore_spec.rb
index 72baa516cc4..bc0ec9325cc 100644
--- a/spec/lib/gitlab/gitignore_spec.rb
+++ b/spec/lib/gitlab/template/gitignore_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
-describe Gitlab::Gitignore do
- subject { Gitlab::Gitignore }
+describe Gitlab::Template::Gitignore do
+ subject { described_class }
describe '.all' do
it 'strips the gitignore suffix' do
@@ -24,7 +24,7 @@ describe Gitlab::Gitignore do
it 'returns the Gitignore object of a valid file' do
ruby = subject.find('Ruby')
- expect(ruby).to be_a Gitlab::Gitignore
+ expect(ruby).to be_a Gitlab::Template::Gitignore
expect(ruby.name).to eq('Ruby')
end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 1e6eb20ab39..ae55a01ebea 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -401,23 +401,56 @@ describe Notify do
end
describe 'project access requested' do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
- let(:project_member) do
- project.request_access(user)
- project.members.request.find_by(user_id: user.id)
+ context 'for a project in a user namespace' do
+ let(:project) { create(:project).tap { |p| p.team << [p.owner, :master, p.owner] } }
+ let(:user) { create(:user) }
+ let(:project_member) do
+ project.request_access(user)
+ project.members.request.find_by(user_id: user.id)
+ end
+ subject { Notify.member_access_requested_email('project', project_member.id) }
+
+ it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'it should not have Gmail Actions links'
+ it_behaves_like "a user cannot unsubscribe through footer link"
+
+ it 'contains all the useful information' do
+ to_emails = subject.header[:to].addrs
+ expect(to_emails.size).to eq(1)
+ expect(to_emails[0].address).to eq(project.members.owners_and_masters.first.user.notification_email)
+
+ is_expected.to have_subject "Request to join the #{project.name_with_namespace} project"
+ is_expected.to have_body_text /#{project.name_with_namespace}/
+ is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/
+ is_expected.to have_body_text /#{project_member.human_access}/
+ end
end
- subject { Notify.member_access_requested_email('project', project_member.id) }
- it_behaves_like 'an email sent from GitLab'
- it_behaves_like 'it should not have Gmail Actions links'
- it_behaves_like "a user cannot unsubscribe through footer link"
+ context 'for a project in a group' do
+ let(:group_owner) { create(:user) }
+ let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
+ let(:project) { create(:project, namespace: group) }
+ let(:user) { create(:user) }
+ let(:project_member) do
+ project.request_access(user)
+ project.members.request.find_by(user_id: user.id)
+ end
+ subject { Notify.member_access_requested_email('project', project_member.id) }
- it 'contains all the useful information' do
- is_expected.to have_subject "Request to join the #{project.name_with_namespace} project"
- is_expected.to have_body_text /#{project.name_with_namespace}/
- is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/
- is_expected.to have_body_text /#{project_member.human_access}/
+ it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'it should not have Gmail Actions links'
+ it_behaves_like "a user cannot unsubscribe through footer link"
+
+ it 'contains all the useful information' do
+ to_emails = subject.header[:to].addrs
+ expect(to_emails.size).to eq(1)
+ expect(to_emails[0].address).to eq(group.members.owners_and_masters.first.user.notification_email)
+
+ is_expected.to have_subject "Request to join the #{project.name_with_namespace} project"
+ is_expected.to have_body_text /#{project.name_with_namespace}/
+ is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/
+ is_expected.to have_body_text /#{project_member.human_access}/
+ end
end
end
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index 5d1fa8226e5..8154001cf46 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -2,7 +2,12 @@ require 'spec_helper'
describe Ci::Build, models: true do
let(:project) { create(:project) }
- let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ let(:pipeline) do
+ create(:ci_pipeline, project: project,
+ sha: project.commit.id)
+ end
+
let(:build) { create(:ci_build, pipeline: pipeline) }
it { is_expected.to validate_presence_of :ref }
@@ -36,32 +41,44 @@ describe Ci::Build, models: true do
subject { build.ignored? }
context 'if build is not allowed to fail' do
- before { build.allow_failure = false }
+ before do
+ build.allow_failure = false
+ end
context 'and build.status is success' do
- before { build.status = 'success' }
+ before do
+ build.status = 'success'
+ end
it { is_expected.to be_falsey }
end
context 'and build.status is failed' do
- before { build.status = 'failed' }
+ before do
+ build.status = 'failed'
+ end
it { is_expected.to be_falsey }
end
end
context 'if build is allowed to fail' do
- before { build.allow_failure = true }
+ before do
+ build.allow_failure = true
+ end
context 'and build.status is success' do
- before { build.status = 'success' }
+ before do
+ build.status = 'success'
+ end
it { is_expected.to be_falsey }
end
context 'and build.status is failed' do
- before { build.status = 'failed' }
+ before do
+ build.status = 'failed'
+ end
it { is_expected.to be_truthy }
end
@@ -75,7 +92,9 @@ describe Ci::Build, models: true do
context 'if build.trace contains text' do
let(:text) { 'example output' }
- before { build.trace = text }
+ before do
+ build.trace = text
+ end
it { is_expected.to include(text) }
it { expect(subject.length).to be >= text.length }
@@ -188,7 +207,9 @@ describe Ci::Build, models: true do
]
end
- before { build.update_attributes(stage: 'stage') }
+ before do
+ build.update_attributes(stage: 'stage')
+ end
it { is_expected.to eq(predefined_variables + yaml_variables) }
@@ -199,7 +220,9 @@ describe Ci::Build, models: true do
]
end
- before { build.update_attributes(tag: true) }
+ before do
+ build.update_attributes(tag: true)
+ end
it { is_expected.to eq(tag_variable + predefined_variables + yaml_variables) }
end
@@ -257,57 +280,6 @@ describe Ci::Build, models: true do
end
end
- describe '#can_be_served?' do
- let(:runner) { create(:ci_runner) }
-
- before { build.project.runners << runner }
-
- context 'when runner does not have tags' do
- it 'can handle builds without tags' do
- expect(build.can_be_served?(runner)).to be_truthy
- end
-
- it 'cannot handle build with tags' do
- build.tag_list = ['aa']
- expect(build.can_be_served?(runner)).to be_falsey
- end
- end
-
- context 'when runner has tags' do
- before { runner.tag_list = ['bb', 'cc'] }
-
- shared_examples 'tagged build picker' do
- it 'can handle build with matching tags' do
- build.tag_list = ['bb']
- expect(build.can_be_served?(runner)).to be_truthy
- end
-
- it 'cannot handle build without matching tags' do
- build.tag_list = ['aa']
- expect(build.can_be_served?(runner)).to be_falsey
- end
- end
-
- context 'when runner can pick untagged jobs' do
- it 'can handle builds without tags' do
- expect(build.can_be_served?(runner)).to be_truthy
- end
-
- it_behaves_like 'tagged build picker'
- end
-
- context 'when runner can not pick untagged jobs' do
- before { runner.run_untagged = false }
-
- it 'can not handle builds without tags' do
- expect(build.can_be_served?(runner)).to be_falsey
- end
-
- it_behaves_like 'tagged build picker'
- end
- end
- end
-
describe '#has_tags?' do
context 'when build has tags' do
subject { create(:ci_build, tag_list: ['tag']) }
@@ -348,7 +320,7 @@ describe Ci::Build, models: true do
end
it 'that cannot handle build' do
- expect_any_instance_of(Ci::Build).to receive(:can_be_served?).and_return(false)
+ expect_any_instance_of(Ci::Runner).to receive(:can_pick?).and_return(false)
is_expected.to be_falsey
end
@@ -360,7 +332,9 @@ describe Ci::Build, models: true do
%w(pending).each do |state|
context "if commit_status.status is #{state}" do
- before { build.status = state }
+ before do
+ build.status = state
+ end
it { is_expected.to be_truthy }
@@ -379,7 +353,9 @@ describe Ci::Build, models: true do
%w(success failed canceled running).each do |state|
context "if commit_status.status is #{state}" do
- before { build.status = state }
+ before do
+ build.status = state
+ end
it { is_expected.to be_falsey }
end
@@ -390,7 +366,10 @@ describe Ci::Build, models: true do
subject { build.artifacts? }
context 'artifacts archive does not exist' do
- before { build.update_attributes(artifacts_file: nil) }
+ before do
+ build.update_attributes(artifacts_file: nil)
+ end
+
it { is_expected.to be_falsy }
end
@@ -623,7 +602,9 @@ describe Ci::Build, models: true do
let!(:build) { create(:ci_build, :trace, :success, :artifacts) }
describe '#erase' do
- before { build.erase(erased_by: user) }
+ before do
+ build.erase(erased_by: user)
+ end
context 'erased by user' do
let!(:user) { create(:user, username: 'eraser') }
@@ -660,7 +641,9 @@ describe Ci::Build, models: true do
end
context 'build has been erased' do
- before { build.erase }
+ before do
+ build.erase
+ end
it { is_expected.to be true }
end
@@ -668,7 +651,9 @@ describe Ci::Build, models: true do
context 'metadata and build trace are not available' do
let!(:build) { create(:ci_build, :success, :artifacts) }
- before { build.remove_artifacts_metadata! }
+ before do
+ build.remove_artifacts_metadata!
+ end
describe '#erase' do
it 'should not raise error' do
@@ -678,4 +663,10 @@ describe Ci::Build, models: true do
end
end
end
+
+ describe '#commit' do
+ it 'returns commit pipeline has been created for' do
+ expect(build.commit).to eq project.commit
+ end
+ end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 5d04d8ffcff..ef65eb99328 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -20,34 +20,36 @@ describe Ci::Runner, models: true do
end
describe '#display_name' do
- it 'should return the description if it has a value' do
+ it 'returns the description if it has a value' do
runner = FactoryGirl.build(:ci_runner, description: 'Linux/Ruby-1.9.3-p448')
expect(runner.display_name).to eq 'Linux/Ruby-1.9.3-p448'
end
- it 'should return the token if it does not have a description' do
+ it 'returns the token if it does not have a description' do
runner = FactoryGirl.create(:ci_runner)
expect(runner.display_name).to eq runner.description
end
- it 'should return the token if the description is an empty string' do
+ it 'returns the token if the description is an empty string' do
runner = FactoryGirl.build(:ci_runner, description: '', token: 'token')
expect(runner.display_name).to eq runner.token
end
end
- describe :assign_to do
+ describe '#assign_to' do
let!(:project) { FactoryGirl.create :empty_project }
let!(:shared_runner) { FactoryGirl.create(:ci_runner, :shared) }
- before { shared_runner.assign_to(project) }
+ before do
+ shared_runner.assign_to(project)
+ end
it { expect(shared_runner).to be_specific }
it { expect(shared_runner.projects).to eq([project]) }
it { expect(shared_runner.only_for?(project)).to be_truthy }
end
- describe :online do
+ describe '.online' do
subject { Ci::Runner.online }
before do
@@ -58,60 +60,269 @@ describe Ci::Runner, models: true do
it { is_expected.to eq([@runner2])}
end
- describe :online? do
+ describe '#online?' do
let(:runner) { FactoryGirl.create(:ci_runner, :shared) }
subject { runner.online? }
context 'never contacted' do
- before { runner.contacted_at = nil }
+ before do
+ runner.contacted_at = nil
+ end
it { is_expected.to be_falsey }
end
context 'contacted long time ago time' do
- before { runner.contacted_at = 1.year.ago }
+ before do
+ runner.contacted_at = 1.year.ago
+ end
it { is_expected.to be_falsey }
end
context 'contacted 1s ago' do
- before { runner.contacted_at = 1.second.ago }
+ before do
+ runner.contacted_at = 1.second.ago
+ end
it { is_expected.to be_truthy }
end
end
- describe :status do
+ describe '#can_pick?' do
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:runner) { create(:ci_runner) }
+
+ before do
+ build.project.runners << runner
+ end
+
+ context 'when runner does not have tags' do
+ it 'can handle builds without tags' do
+ expect(runner.can_pick?(build)).to be_truthy
+ end
+
+ it 'cannot handle build with tags' do
+ build.tag_list = ['aa']
+
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+ end
+
+ context 'when runner has tags' do
+ before do
+ runner.tag_list = ['bb', 'cc']
+ end
+
+ shared_examples 'tagged build picker' do
+ it 'can handle build with matching tags' do
+ build.tag_list = ['bb']
+
+ expect(runner.can_pick?(build)).to be_truthy
+ end
+
+ it 'cannot handle build without matching tags' do
+ build.tag_list = ['aa']
+
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+ end
+
+ context 'when runner can pick untagged jobs' do
+ it 'can handle builds without tags' do
+ expect(runner.can_pick?(build)).to be_truthy
+ end
+
+ it_behaves_like 'tagged build picker'
+ end
+
+ context 'when runner cannot pick untagged jobs' do
+ before do
+ runner.run_untagged = false
+ end
+
+ it 'cannot handle builds without tags' do
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+
+ it_behaves_like 'tagged build picker'
+ end
+ end
+
+ context 'when runner is locked' do
+ before do
+ runner.locked = true
+ end
+
+ shared_examples 'locked build picker' do
+ context 'when runner cannot pick untagged jobs' do
+ before do
+ runner.run_untagged = false
+ end
+
+ it 'cannot handle builds without tags' do
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+ end
+
+ context 'when having runner tags' do
+ before do
+ runner.tag_list = ['bb', 'cc']
+ end
+
+ it 'cannot handle it for builds without matching tags' do
+ build.tag_list = ['aa']
+
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+ end
+ end
+
+ context 'when serving the same project' do
+ it 'can handle it' do
+ expect(runner.can_pick?(build)).to be_truthy
+ end
+
+ it_behaves_like 'locked build picker'
+
+ context 'when having runner tags' do
+ before do
+ runner.tag_list = ['bb', 'cc']
+ build.tag_list = ['bb']
+ end
+
+ it 'can handle it for matching tags' do
+ expect(runner.can_pick?(build)).to be_truthy
+ end
+ end
+ end
+
+ context 'serving a different project' do
+ before do
+ runner.runner_projects.destroy_all
+ end
+
+ it 'cannot handle it' do
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+
+ it_behaves_like 'locked build picker'
+
+ context 'when having runner tags' do
+ before do
+ runner.tag_list = ['bb', 'cc']
+ build.tag_list = ['bb']
+ end
+
+ it 'cannot handle it for matching tags' do
+ expect(runner.can_pick?(build)).to be_falsey
+ end
+ end
+ end
+ end
+ end
+
+ describe '#status' do
let(:runner) { FactoryGirl.create(:ci_runner, :shared, contacted_at: 1.second.ago) }
subject { runner.status }
context 'never connected' do
- before { runner.contacted_at = nil }
+ before do
+ runner.contacted_at = nil
+ end
it { is_expected.to eq(:not_connected) }
end
context 'contacted 1s ago' do
- before { runner.contacted_at = 1.second.ago }
+ before do
+ runner.contacted_at = 1.second.ago
+ end
it { is_expected.to eq(:online) }
end
context 'contacted long time ago' do
- before { runner.contacted_at = 1.year.ago }
+ before do
+ runner.contacted_at = 1.year.ago
+ end
it { is_expected.to eq(:offline) }
end
context 'inactive' do
- before { runner.active = false }
+ before do
+ runner.active = false
+ end
it { is_expected.to eq(:paused) }
end
end
+ describe '.assignable_for' do
+ let(:runner) { create(:ci_runner) }
+ let(:project) { create(:project) }
+ let(:another_project) { create(:project) }
+
+ before do
+ project.runners << runner
+ end
+
+ context 'with shared runners' do
+ before do
+ runner.update(is_shared: true)
+ end
+
+ context 'does not give owned runner' do
+ subject { Ci::Runner.assignable_for(project) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'does not give shared runner' do
+ subject { Ci::Runner.assignable_for(another_project) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ context 'with unlocked runner' do
+ context 'does not give owned runner' do
+ subject { Ci::Runner.assignable_for(project) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'does give a specific runner' do
+ subject { Ci::Runner.assignable_for(another_project) }
+
+ it { is_expected.to contain_exactly(runner) }
+ end
+ end
+
+ context 'with locked runner' do
+ before do
+ runner.update(locked: true)
+ end
+
+ context 'does not give owned runner' do
+ subject { Ci::Runner.assignable_for(project) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'does not give a locked runner' do
+ subject { Ci::Runner.assignable_for(another_project) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+ end
+
describe "belongs_to_one_project?" do
it "returns false if there are two projects runner assigned to" do
runner = FactoryGirl.create(:ci_runner)
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index beca8708c9d..ba02d5fe977 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -207,4 +207,16 @@ eos
expect(commit.participants).to include(note1.author, note2.author)
end
end
+
+ describe '#uri_type' do
+ it 'returns the URI type at the given path' do
+ expect(commit.uri_type('files/html')).to be(:tree)
+ expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
+ expect(commit.uri_type('files/js/application.js')).to be(:blob)
+ end
+
+ it "returns nil if the path doesn't exists" do
+ expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
+ end
+ end
end
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 8fb605fff8a..96397d7c8a9 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -1,8 +1,13 @@
require 'spec_helper'
describe CommitStatus, models: true do
- let(:pipeline) { FactoryGirl.create :ci_pipeline }
- let(:commit_status) { FactoryGirl.create :commit_status, pipeline: pipeline }
+ let(:project) { create(:project) }
+
+ let(:pipeline) do
+ create(:ci_pipeline, project: project, sha: project.commit.id)
+ end
+
+ let(:commit_status) { create(:commit_status, pipeline: pipeline) }
it { is_expected.to belong_to(:pipeline) }
it { is_expected.to belong_to(:user) }
@@ -13,7 +18,7 @@ describe CommitStatus, models: true do
it { is_expected.to delegate_method(:sha).to(:pipeline) }
it { is_expected.to delegate_method(:short_sha).to(:pipeline) }
-
+
it { is_expected.to respond_to :success? }
it { is_expected.to respond_to :failed? }
it { is_expected.to respond_to :running? }
@@ -116,7 +121,7 @@ describe CommitStatus, models: true do
it { is_expected.to be > 0.0 }
end
end
-
+
describe :latest do
subject { CommitStatus.latest.order(:id) }
@@ -198,4 +203,10 @@ describe CommitStatus, models: true do
end
end
end
+
+ describe '#commit' do
+ it 'returns commit pipeline has been created for' do
+ expect(commit_status.commit).to eq project.commit
+ end
+ end
end
diff --git a/spec/models/concerns/participable_spec.rb b/spec/models/concerns/participable_spec.rb
index 7e4ea0f2d66..a9f4ef9ee5e 100644
--- a/spec/models/concerns/participable_spec.rb
+++ b/spec/models/concerns/participable_spec.rb
@@ -37,6 +37,16 @@ describe Participable, models: true do
expect(participants).to include(user3)
end
+ it 'caches the raw list of participants' do
+ instance = model.new
+ user1 = build(:user)
+
+ expect(instance).to receive(:raw_participants).once
+
+ instance.participants(user1)
+ instance.participants(user1)
+ end
+
it 'supports attributes returning another Participable' do
other_model = Class.new { include Participable }
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index 26fbedbef2f..49cf3d8633a 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -26,7 +26,7 @@ describe Key, models: true do
end
end
- context "validation of uniqueness" do
+ context "validation of uniqueness (based on fingerprint uniqueness)" do
let(:user) { create(:user) }
it "accepts the key once" do
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 3ed3202ac6c..e9134a3d283 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -134,18 +134,6 @@ describe Member, models: true do
it { is_expected.to respond_to(:user_email) }
end
- describe 'Callbacks' do
- describe 'after_destroy :post_decline_request, if: :request?' do
- let(:member) { create(:project_member, requested_at: Time.now.utc) }
-
- it 'calls #post_decline_request' do
- expect(member).to receive(:post_decline_request)
-
- member.destroy
- end
- end
- end
-
describe ".add_user" do
let!(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index eeb74a462ac..18439cac2a4 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -61,16 +61,6 @@ describe GroupMember, models: true do
end
end
- describe '#post_decline_request' do
- it 'calls NotificationService.decline_group_access_request' do
- member = create(:group_member, user: build_stubbed(:user), requested_at: Time.now)
-
- expect_any_instance_of(NotificationService).to receive(:decline_group_access_request)
-
- member.__send__(:post_decline_request)
- end
- end
-
describe '#real_source_type' do
subject { create(:group_member).real_source_type }
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 1e466f9c620..bbf65edb27c 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -152,15 +152,5 @@ describe ProjectMember, models: true do
member.__send__(:after_accept_request)
end
end
-
- describe '#post_decline_request' do
- it 'calls NotificationService.decline_project_access_request' do
- member = create(:project_member, user: build_stubbed(:user), requested_at: Time.now)
-
- expect_any_instance_of(NotificationService).to receive(:decline_project_access_request)
-
- member.__send__(:post_decline_request)
- end
- end
end
end
diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb
index ac85f340922..47e9253a10c 100644
--- a/spec/requests/api/builds_spec.rb
+++ b/spec/requests/api/builds_spec.rb
@@ -9,8 +9,8 @@ describe API::API, api: true do
let!(:project) { create(:project, creator_id: user.id) }
let!(:developer) { create(:project_member, :developer, user: user, project: project) }
let!(:reporter) { create(:project_member, :reporter, user: user2, project: project) }
- let(:pipeline) { create(:ci_pipeline, project: project)}
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.id) }
+ let!(:build) { create(:ci_build, pipeline: pipeline) }
describe 'GET /projects/:id/builds ' do
let(:query) { '' }
@@ -23,6 +23,11 @@ describe API::API, api: true do
expect(json_response).to be_an Array
end
+ it 'returns correct values' do
+ expect(json_response).not_to be_empty
+ expect(json_response.first['commit']['id']).to eq project.commit.id
+ end
+
context 'filter project with one scope element' do
let(:query) { 'scope=pending' }
@@ -132,7 +137,7 @@ describe API::API, api: true do
describe 'GET /projects/:id/builds/:build_id/trace' do
let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
-
+
before { get api("/projects/#{project.id}/builds/#{build.id}/trace", api_user) }
context 'authorized user' do
diff --git a/spec/requests/api/gitignores_spec.rb b/spec/requests/api/gitignores_spec.rb
deleted file mode 100644
index aab2d8c81b9..00000000000
--- a/spec/requests/api/gitignores_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require 'spec_helper'
-
-describe API::Gitignores, api: true do
- include ApiHelpers
-
- describe 'Entity Gitignore' do
- before { get api('/gitignores/Ruby') }
-
- it { expect(json_response['name']).to eq('Ruby') }
- it { expect(json_response['content']).to include('*.gem') }
- end
-
- describe 'Entity GitignoresList' do
- before { get api('/gitignores') }
-
- it { expect(json_response.first['name']).not_to be_nil }
- it { expect(json_response.first['content']).to be_nil }
- end
-
- describe 'GET /gitignores' do
- it 'returns a list of available license templates' do
- get api('/gitignores')
-
- expect(response.status).to eq(200)
- expect(json_response).to be_an Array
- expect(json_response.size).to be > 15
- end
- end
-end
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 73ae8ef631c..b4c826522a5 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -187,14 +187,16 @@ describe API::Runners, api: true do
update_runner(shared_runner.id, admin, description: "#{description}_updated",
active: !active,
tag_list: ['ruby2.1', 'pgsql', 'mysql'],
- run_untagged: 'false')
+ run_untagged: 'false',
+ locked: 'true')
shared_runner.reload
expect(response.status).to eq(200)
expect(shared_runner.description).to eq("#{description}_updated")
expect(shared_runner.active).to eq(!active)
expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql')
- expect(shared_runner.run_untagged?).to be false
+ expect(shared_runner.run_untagged?).to be(false)
+ expect(shared_runner.locked?).to be(true)
end
end
@@ -360,11 +362,13 @@ describe API::Runners, api: true do
describe 'POST /projects/:id/runners' do
context 'authorized user' do
- it 'should enable specific runner' do
- specific_runner2 = create(:ci_runner).tap do |runner|
+ let(:specific_runner2) do
+ create(:ci_runner).tap do |runner|
create(:ci_runner_project, runner: runner, project: project2)
end
+ end
+ it 'should enable specific runner' do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
end.to change{ project.runners.count }.by(+1)
@@ -375,7 +379,17 @@ describe API::Runners, api: true do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner.id
end.to change{ project.runners.count }.by(0)
- expect(response.status).to eq(201)
+ expect(response.status).to eq(409)
+ end
+
+ it 'should not enable locked runner' do
+ specific_runner2.update(locked: true)
+
+ expect do
+ post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
+ end.to change{ project.runners.count }.by(0)
+
+ expect(response.status).to eq(403)
end
it 'should not enable shared runner' do
diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb
new file mode 100644
index 00000000000..a6d5ade3013
--- /dev/null
+++ b/spec/requests/api/templates_spec.rb
@@ -0,0 +1,52 @@
+require 'spec_helper'
+
+describe API::Templates, api: true do
+ include ApiHelpers
+
+ describe 'the Template Entity' do
+ before { get api('/gitignores/Ruby') }
+
+ it { expect(json_response['name']).to eq('Ruby') }
+ it { expect(json_response['content']).to include('*.gem') }
+ end
+
+ describe 'the TemplateList Entity' do
+ before { get api('/gitignores') }
+
+ it { expect(json_response.first['name']).not_to be_nil }
+ it { expect(json_response.first['content']).to be_nil }
+ end
+
+ context 'requesting gitignores' do
+ describe 'GET /gitignores' do
+ it 'returns a list of available gitignore templates' do
+ get api('/gitignores')
+
+ expect(response.status).to eq(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to be > 15
+ end
+ end
+ end
+
+ context 'requesting gitlab-ci-ymls' do
+ describe 'GET /gitlab_ci_ymls' do
+ it 'returns a list of available gitlab_ci_ymls' do
+ get api('/gitlab_ci_ymls')
+
+ expect(response.status).to eq(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['name']).not_to be_nil
+ end
+ end
+ end
+
+ describe 'GET /gitlab_ci_ymls/Ruby' do
+ it 'adds a disclaimer on the top' do
+ get api('/gitlab_ci_ymls/Ruby')
+
+ expect(response.status).to eq(200)
+ expect(json_response['content']).to start_with("# This file is a template,")
+ end
+ end
+end
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
new file mode 100644
index 00000000000..2395445e7fd
--- /dev/null
+++ b/spec/services/members/destroy_service_spec.rb
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe Members::DestroyService, services: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let!(:member) { create(:project_member, source: project) }
+
+ context 'when member is nil' do
+ before do
+ project.team << [user, :developer]
+ end
+
+ it 'does not destroy the member' do
+ expect { destroy_member(nil, user) }.to raise_error(Gitlab::Access::AccessDeniedError)
+ end
+ end
+
+ context 'when current user cannot destroy the given member' do
+ before do
+ project.team << [user, :developer]
+ end
+
+ it 'does not destroy the member' do
+ expect { destroy_member(member, user) }.to raise_error(Gitlab::Access::AccessDeniedError)
+ end
+ end
+
+ context 'when current user can destroy the given member' do
+ before do
+ project.team << [user, :master]
+ end
+
+ it 'destroys the member' do
+ destroy_member(member, user)
+
+ expect(member).to be_destroyed
+ end
+
+ context 'when the given member is a requester' do
+ before do
+ member.update_column(:requested_at, Time.now)
+ end
+
+ it 'calls Member#after_decline_request' do
+ expect_any_instance_of(NotificationService).to receive(:decline_access_request).with(member)
+
+ destroy_member(member, user)
+ end
+
+ context 'when current user is the member' do
+ it 'does not call Member#after_decline_request' do
+ expect_any_instance_of(NotificationService).not_to receive(:decline_access_request).with(member)
+
+ destroy_member(member, member.user)
+ end
+ end
+
+ context 'when current user is the member and ' do
+ it 'does not call Member#after_decline_request' do
+ expect_any_instance_of(NotificationService).not_to receive(:decline_access_request).with(member)
+
+ destroy_member(member, member.user)
+ end
+ end
+ end
+ end
+
+ def destroy_member(member, user)
+ Members::DestroyService.new(member, user).execute
+ end
+end
diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb
index 1abd87d7d33..b5e1fdb8ded 100644
--- a/spec/workers/merge_worker_spec.rb
+++ b/spec/workers/merge_worker_spec.rb
@@ -9,7 +9,7 @@ describe MergeWorker do
before do
source_project.team << [author, :master]
- source_project.repository.expire_branch_names
+ source_project.repository.expire_branches_cache
end
it 'clears cache of source repo after removing source branch' do