summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2016-08-16 17:49:53 -0500
committerDouwe Maan <douwe@selenight.nl>2016-08-16 17:49:53 -0500
commite07c27fee427195d8d89f6278d0fc12dfeec3588 (patch)
treec4676e5e953aecef8bf2bb715619027cd556c9cc /spec
parent029b7d2e9266246feff2f165a10b16be1d7fe88e (diff)
parent415159c28da1aec00bb383d46aad67a9de75faae (diff)
downloadgitlab-ce-e07c27fee427195d8d89f6278d0fc12dfeec3588.tar.gz
Merge branch 'master' into 4273-slash-commands
# Conflicts: # app/services/issues/create_service.rb
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/groups_controller_spec.rb5
-rw-r--r--spec/controllers/admin/spam_logs_controller_spec.rb12
-rw-r--r--spec/controllers/groups_controller_spec.rb5
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb50
-rw-r--r--spec/controllers/projects/templates_controller_spec.rb48
-rw-r--r--spec/factories/project_hooks.rb10
-rw-r--r--spec/factories/protected_branches.rb12
-rw-r--r--spec/factories/user_agent_details.rb7
-rw-r--r--spec/features/issuables/default_sort_order_spec.rb14
-rw-r--r--spec/features/issues/filter_issues_spec.rb2
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb2
-rw-r--r--spec/features/profiles/preferences_spec.rb4
-rw-r--r--spec/features/projects/badges/coverage_spec.rb73
-rw-r--r--spec/features/projects/badges/list_spec.rb46
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb34
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb5
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb3
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb98
-rw-r--r--spec/features/projects/issuable_templates_spec.rb89
-rw-r--r--spec/features/protected_branches_spec.rb29
-rw-r--r--spec/features/u2f_spec.rb32
-rw-r--r--spec/features/variables_spec.rb1
-rw-r--r--spec/finders/projects_finder_spec.rb73
-rw-r--r--spec/helpers/notes_helper_spec.rb5
-rw-r--r--spec/lib/gitlab/akismet_helper_spec.rb35
-rw-r--r--spec/lib/gitlab/badge/build/metadata_spec.rb36
-rw-r--r--spec/lib/gitlab/badge/build/status_spec.rb (renamed from spec/lib/gitlab/badge/build_spec.rb)38
-rw-r--r--spec/lib/gitlab/badge/build/template_spec.rb22
-rw-r--r--spec/lib/gitlab/badge/coverage/metadata_spec.rb30
-rw-r--r--spec/lib/gitlab/badge/coverage/report_spec.rb93
-rw-r--r--spec/lib/gitlab/badge/coverage/template_spec.rb130
-rw-r--r--spec/lib/gitlab/badge/shared/metadata.rb21
-rw-r--r--spec/lib/gitlab/checks/change_access_spec.rb99
-rw-r--r--spec/lib/gitlab/data_builder/build_spec.rb (renamed from spec/lib/gitlab/build_data_builder_spec.rb)4
-rw-r--r--spec/lib/gitlab/data_builder/note_spec.rb (renamed from spec/lib/gitlab/note_data_builder_spec.rb)4
-rw-r--r--spec/lib/gitlab/data_builder/pipeline_spec.rb36
-rw-r--r--spec/lib/gitlab/data_builder/push_spec.rb (renamed from spec/lib/gitlab/push_data_builder_spec.rb)2
-rw-r--r--spec/lib/gitlab/import_export/reader_spec.rb3
-rw-r--r--spec/lib/gitlab/template/gitignore_template_spec.rb (renamed from spec/lib/gitlab/template/gitignore_spec.rb)4
-rw-r--r--spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb41
-rw-r--r--spec/lib/gitlab/template/issue_template_spec.rb89
-rw-r--r--spec/lib/gitlab/template/merge_request_template_spec.rb89
-rw-r--r--spec/models/blob_spec.rb22
-rw-r--r--spec/models/build_spec.rb64
-rw-r--r--spec/models/ci/pipeline_spec.rb87
-rw-r--r--spec/models/concerns/spammable_spec.rb33
-rw-r--r--spec/models/deployment_spec.rb24
-rw-r--r--spec/models/environment_spec.rb33
-rw-r--r--spec/models/merge_request_spec.rb15
-rw-r--r--spec/models/project_services/assembla_service_spec.rb2
-rw-r--r--spec/models/project_services/builds_email_service_spec.rb8
-rw-r--r--spec/models/project_services/campfire_service_spec.rb2
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb4
-rw-r--r--spec/models/project_services/flowdock_service_spec.rb2
-rw-r--r--spec/models/project_services/gemnasium_service_spec.rb2
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb24
-rw-r--r--spec/models/project_services/irker_service_spec.rb11
-rw-r--r--spec/models/project_services/jira_service_spec.rb2
-rw-r--r--spec/models/project_services/pivotaltracker_service_spec.rb71
-rw-r--r--spec/models/project_services/pushover_service_spec.rb4
-rw-r--r--spec/models/project_services/slack_service_spec.rb14
-rw-r--r--spec/models/project_spec.rb6
-rw-r--r--spec/models/user_agent_detail_spec.rb31
-rw-r--r--spec/models/user_spec.rb4
-rw-r--r--spec/requests/api/branches_spec.rb2
-rw-r--r--spec/requests/api/issues_spec.rb5
-rw-r--r--spec/requests/api/project_hooks_spec.rb8
-rw-r--r--spec/requests/api/templates_spec.rb65
-rw-r--r--spec/requests/api/todos_spec.rb12
-rw-r--r--spec/services/files/update_service_spec.rb84
-rw-r--r--spec/services/git_push_service_spec.rb12
-rw-r--r--spec/services/merge_requests/get_urls_service_spec.rb34
-rw-r--r--spec/services/todo_service_spec.rb36
-rw-r--r--spec/support/import_export/import_export.yml4
-rw-r--r--spec/views/projects/merge_requests/_heading.html.haml_spec.rb26
-rw-r--r--spec/workers/build_email_worker_spec.rb2
-rw-r--r--spec/workers/emails_on_push_worker_spec.rb2
77 files changed, 1831 insertions, 361 deletions
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index 0239aea47fb..602de72d23f 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -7,12 +7,13 @@ describe Admin::GroupsController do
before do
sign_in(admin)
- Sidekiq::Testing.fake!
end
describe 'DELETE #destroy' do
it 'schedules a group destroy' do
- expect { delete :destroy, id: project.group.path }.to change(GroupDestroyWorker.jobs, :size).by(1)
+ Sidekiq::Testing.fake! do
+ expect { delete :destroy, id: project.group.path }.to change(GroupDestroyWorker.jobs, :size).by(1)
+ end
end
it 'redirects to the admin group path' do
diff --git a/spec/controllers/admin/spam_logs_controller_spec.rb b/spec/controllers/admin/spam_logs_controller_spec.rb
index 520a4f6f9c5..585ca31389d 100644
--- a/spec/controllers/admin/spam_logs_controller_spec.rb
+++ b/spec/controllers/admin/spam_logs_controller_spec.rb
@@ -34,4 +34,16 @@ describe Admin::SpamLogsController do
expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
+
+ describe '#mark_as_ham' do
+ before do
+ allow_any_instance_of(AkismetService).to receive(:submit_ham).and_return(true)
+ end
+ it 'submits the log as ham' do
+ post :mark_as_ham, id: first_spam.id
+
+ expect(response).to have_http_status(302)
+ expect(SpamLog.find(first_spam.id).submitted_as_ham).to be_truthy
+ end
+ end
end
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 4ae6364207b..a763e2c5ba8 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -89,12 +89,13 @@ describe GroupsController do
context 'as the group owner' do
before do
- Sidekiq::Testing.fake!
sign_in(user)
end
it 'schedules a group destroy' do
- expect { delete :destroy, id: group.path }.to change(GroupDestroyWorker.jobs, :size).by(1)
+ Sidekiq::Testing.fake! do
+ expect { delete :destroy, id: group.path }.to change(GroupDestroyWorker.jobs, :size).by(1)
+ end
end
it 'redirects to the root path' do
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index b6a0276846c..0836b71056c 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -274,8 +274,8 @@ describe Projects::IssuesController do
describe 'POST #create' do
context 'Akismet is enabled' do
before do
- allow_any_instance_of(Gitlab::AkismetHelper).to receive(:check_for_spam?).and_return(true)
- allow_any_instance_of(Gitlab::AkismetHelper).to receive(:is_spam?).and_return(true)
+ allow_any_instance_of(SpamService).to receive(:check_for_spam?).and_return(true)
+ allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
end
def post_spam_issue
@@ -300,6 +300,52 @@ describe Projects::IssuesController do
expect(spam_logs[0].title).to eq('Spam Title')
end
end
+
+ context 'user agent details are saved' do
+ before do
+ request.env['action_dispatch.remote_ip'] = '127.0.0.1'
+ end
+
+ def post_new_issue
+ sign_in(user)
+ project = create(:empty_project, :public)
+ post :create, {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ issue: { title: 'Title', description: 'Description' }
+ }
+ end
+
+ it 'creates a user agent detail' do
+ expect{ post_new_issue }.to change(UserAgentDetail, :count).by(1)
+ end
+ end
+ end
+
+ describe 'POST #mark_as_spam' do
+ context 'properly submits to Akismet' do
+ before do
+ allow_any_instance_of(AkismetService).to receive_messages(submit_spam: true)
+ allow_any_instance_of(ApplicationSetting).to receive_messages(akismet_enabled: true)
+ end
+
+ def post_spam
+ admin = create(:admin)
+ create(:user_agent_detail, subject: issue)
+ project.team << [admin, :master]
+ sign_in(admin)
+ post :mark_as_spam, {
+ namespace_id: project.namespace.path,
+ project_id: project.path,
+ id: issue.iid
+ }
+ end
+
+ it 'updates issue' do
+ post_spam
+ expect(issue.submittable_as_spam?).to be_falsey
+ end
+ end
end
describe "DELETE #destroy" do
diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb
new file mode 100644
index 00000000000..7b3a26d7ca7
--- /dev/null
+++ b/spec/controllers/projects/templates_controller_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+describe Projects::TemplatesController do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:file_path_1) { '.gitlab/issue_templates/bug.md' }
+ let(:body) { JSON.parse(response.body) }
+
+ before do
+ project.team << [user, :developer]
+ sign_in(user)
+ end
+
+ before do
+ project.team.add_user(user, Gitlab::Access::MASTER)
+ project.repository.commit_file(user, file_path_1, "something valid", "test 3", "master", false)
+ end
+
+ describe '#show' do
+ it 'renders template name and content as json' do
+ get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project.path, format: :json)
+
+ expect(response.status).to eq(200)
+ expect(body["name"]).to eq("bug")
+ expect(body["content"]).to eq("something valid")
+ end
+
+ it 'renders 404 when unauthorized' do
+ sign_in(user2)
+ get(:show, namespace_id: project.namespace.to_param, template_type: "issue", key: "bug", project_id: project.path, format: :json)
+
+ expect(response.status).to eq(404)
+ end
+
+ it 'renders 404 when template type is not found' do
+ sign_in(user)
+ get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project.path, format: :json)
+
+ expect(response.status).to eq(404)
+ end
+
+ it 'renders 404 without errors' do
+ sign_in(user)
+ expect { get(:show, namespace_id: project.namespace.to_param, template_type: "dont_exist", key: "bug", project_id: project.path, format: :json) }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb
index 3195fb3ddcc..4fd51a23490 100644
--- a/spec/factories/project_hooks.rb
+++ b/spec/factories/project_hooks.rb
@@ -5,5 +5,15 @@ FactoryGirl.define do
trait :token do
token { SecureRandom.hex(10) }
end
+
+ trait :all_events_enabled do
+ push_events true
+ merge_requests_events true
+ tag_push_events true
+ issues_events true
+ note_events true
+ build_events true
+ pipeline_events true
+ end
end
end
diff --git a/spec/factories/protected_branches.rb b/spec/factories/protected_branches.rb
index 5575852c2d7..b2695e0482a 100644
--- a/spec/factories/protected_branches.rb
+++ b/spec/factories/protected_branches.rb
@@ -3,26 +3,26 @@ FactoryGirl.define do
name
project
- after(:create) do |protected_branch|
- protected_branch.create_push_access_level!(access_level: Gitlab::Access::MASTER)
- protected_branch.create_merge_access_level!(access_level: Gitlab::Access::MASTER)
+ after(:build) do |protected_branch|
+ protected_branch.push_access_levels.new(access_level: Gitlab::Access::MASTER)
+ protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MASTER)
end
trait :developers_can_push do
after(:create) do |protected_branch|
- protected_branch.push_access_level.update!(access_level: Gitlab::Access::DEVELOPER)
+ protected_branch.push_access_levels.first.update!(access_level: Gitlab::Access::DEVELOPER)
end
end
trait :developers_can_merge do
after(:create) do |protected_branch|
- protected_branch.merge_access_level.update!(access_level: Gitlab::Access::DEVELOPER)
+ protected_branch.merge_access_levels.first.update!(access_level: Gitlab::Access::DEVELOPER)
end
end
trait :no_one_can_push do
after(:create) do |protected_branch|
- protected_branch.push_access_level.update!(access_level: Gitlab::Access::NO_ACCESS)
+ protected_branch.push_access_levels.first.update!(access_level: Gitlab::Access::NO_ACCESS)
end
end
end
diff --git a/spec/factories/user_agent_details.rb b/spec/factories/user_agent_details.rb
new file mode 100644
index 00000000000..9763cc0cf15
--- /dev/null
+++ b/spec/factories/user_agent_details.rb
@@ -0,0 +1,7 @@
+FactoryGirl.define do
+ factory :user_agent_detail do
+ ip_address '127.0.0.1'
+ user_agent 'AppleWebKit/537.36'
+ association :subject, factory: :issue
+ end
+end
diff --git a/spec/features/issuables/default_sort_order_spec.rb b/spec/features/issuables/default_sort_order_spec.rb
index 0d495cd04aa..9114f751b55 100644
--- a/spec/features/issuables/default_sort_order_spec.rb
+++ b/spec/features/issuables/default_sort_order_spec.rb
@@ -55,7 +55,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last updated"' do
visit_merge_requests_with_state(project, 'merged')
- expect(selected_sort_order).to eq('last updated')
+ expect(find('.issues-other-filters')).to have_content('Last updated')
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
@@ -67,7 +67,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last updated"' do
visit_merge_requests_with_state(project, 'closed')
- expect(selected_sort_order).to eq('last updated')
+ expect(find('.issues-other-filters')).to have_content('Last updated')
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
@@ -79,7 +79,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last created"' do
visit_merge_requests_with_state(project, 'all')
- expect(selected_sort_order).to eq('last created')
+ expect(find('.issues-other-filters')).to have_content('Last created')
expect(first_merge_request).to include(last_created_issuable.title)
expect(last_merge_request).to include(first_created_issuable.title)
end
@@ -108,7 +108,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last created"' do
visit_issues project
- expect(selected_sort_order).to eq('last created')
+ expect(find('.issues-other-filters')).to have_content('Last created')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
@@ -120,7 +120,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last created"' do
visit_issues_with_state(project, 'open')
- expect(selected_sort_order).to eq('last created')
+ expect(find('.issues-other-filters')).to have_content('Last created')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
@@ -132,7 +132,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last updated"' do
visit_issues_with_state(project, 'closed')
- expect(selected_sort_order).to eq('last updated')
+ expect(find('.issues-other-filters')).to have_content('Last updated')
expect(first_issue).to include(last_updated_issuable.title)
expect(last_issue).to include(first_updated_issuable.title)
end
@@ -144,7 +144,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it 'is "last created"' do
visit_issues_with_state(project, 'all')
- expect(selected_sort_order).to eq('last created')
+ expect(find('.issues-other-filters')).to have_content('Last created')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
diff --git a/spec/features/issues/filter_issues_spec.rb b/spec/features/issues/filter_issues_spec.rb
index ea81ee54c90..e262f285868 100644
--- a/spec/features/issues/filter_issues_spec.rb
+++ b/spec/features/issues/filter_issues_spec.rb
@@ -117,7 +117,7 @@ describe 'Filter issues', feature: true do
find('.dropdown-menu-user-link', text: user.username).click
- wait_for_ajax
+ expect(page).not_to have_selector('.issues-list .issue')
find('.js-label-select').click
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index e296078bad8..11c9de3c4bf 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -13,6 +13,8 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'generates a diff for an orphaned branch' do
click_link 'New Merge Request'
+ expect(page).to have_content('Source branch')
+ expect(page).to have_content('Target branch')
first('.js-source-branch').click
first('.dropdown-source-branch .dropdown-content a', text: 'orphaned-branch').click
diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb
index 787bf42d048..d14a1158b67 100644
--- a/spec/features/profiles/preferences_spec.rb
+++ b/spec/features/profiles/preferences_spec.rb
@@ -68,10 +68,14 @@ describe 'Profile > Preferences', feature: true do
allowing_for_delay do
find('#logo').click
+
+ expect(page).to have_content("You don't have starred projects yet")
expect(page.current_path).to eq starred_dashboard_projects_path
end
click_link 'Your Projects'
+
+ expect(page).not_to have_content("You don't have starred projects yet")
expect(page.current_path).to eq dashboard_projects_path
end
end
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
new file mode 100644
index 00000000000..af86d3c338a
--- /dev/null
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+feature 'test coverage badge' do
+ given!(:user) { create(:user) }
+ given!(:project) { create(:project, :private) }
+
+ given!(:pipeline) do
+ create(:ci_pipeline, project: project,
+ ref: 'master',
+ sha: project.commit.id)
+ end
+
+ context 'when user has access to view badge' do
+ background do
+ project.team << [user, :developer]
+ login_as(user)
+ end
+
+ scenario 'user requests coverage badge image for pipeline' do
+ create_job(coverage: 100, name: 'test:1')
+ create_job(coverage: 90, name: 'test:2')
+
+ show_test_coverage_badge
+
+ expect_coverage_badge('95%')
+ end
+
+ scenario 'user requests coverage badge for specific job' do
+ create_job(coverage: 50, name: 'test:1')
+ create_job(coverage: 50, name: 'test:2')
+ create_job(coverage: 85, name: 'coverage')
+
+ show_test_coverage_badge(job: 'coverage')
+
+ expect_coverage_badge('85%')
+ end
+
+ scenario 'user requests coverage badge for pipeline without coverage' do
+ create_job(coverage: nil, name: 'test')
+
+ show_test_coverage_badge
+
+ expect_coverage_badge('unknown')
+ end
+ end
+
+ context 'when user does not have access to view badge' do
+ background { login_as(user) }
+
+ scenario 'user requests test coverage badge image' do
+ show_test_coverage_badge
+
+ expect(page).to have_http_status(404)
+ end
+ end
+
+ def create_job(coverage:, name:)
+ create(:ci_build, name: name,
+ coverage: coverage,
+ pipeline: pipeline)
+ end
+
+ def show_test_coverage_badge(job: nil)
+ visit coverage_namespace_project_badges_path(
+ project.namespace, project, ref: :master, job: job, format: :svg)
+ end
+
+ def expect_coverage_badge(coverage)
+ svg = Nokogiri::XML.parse(page.body)
+ expect(page.response_headers['Content-Type']).to include('image/svg+xml')
+ expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy
+ end
+end
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index 75166bca119..67a4a5d1ab1 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -9,25 +9,43 @@ feature 'list of badges' do
visit namespace_project_pipelines_settings_path(project.namespace, project)
end
- scenario 'user displays list of badges' do
- expect(page).to have_content 'build status'
- expect(page).to have_content 'Markdown'
- expect(page).to have_content 'HTML'
- expect(page).to have_css('.highlight', count: 2)
- expect(page).to have_xpath("//img[@alt='build status']")
-
- page.within('.highlight', match: :first) do
- expect(page).to have_content 'badges/master/build.svg'
+ scenario 'user wants to see build status badge' do
+ page.within('.build-status') do
+ expect(page).to have_content 'build status'
+ expect(page).to have_content 'Markdown'
+ expect(page).to have_content 'HTML'
+ expect(page).to have_css('.highlight', count: 2)
+ expect(page).to have_xpath("//img[@alt='build status']")
+
+ page.within('.highlight', match: :first) do
+ expect(page).to have_content 'badges/master/build.svg'
+ end
end
end
- scenario 'user changes current ref on badges list page', js: true do
- first('.js-project-refs-dropdown').click
+ scenario 'user wants to see coverage report badge' do
+ page.within('.coverage-report') do
+ expect(page).to have_content 'coverage report'
+ expect(page).to have_content 'Markdown'
+ expect(page).to have_content 'HTML'
+ expect(page).to have_css('.highlight', count: 2)
+ expect(page).to have_xpath("//img[@alt='coverage report']")
- page.within '.project-refs-form' do
- click_link 'improve/awesome'
+ page.within('.highlight', match: :first) do
+ expect(page).to have_content 'badges/master/coverage.svg'
+ end
end
+ end
+
+ scenario 'user changes current ref of build status badge', js: true do
+ page.within('.build-status') do
+ first('.js-project-refs-dropdown').click
- expect(page).to have_content 'badges/improve/awesome/build.svg'
+ page.within '.project-refs-form' do
+ click_link 'improve/awesome'
+ end
+
+ expect(page).to have_content 'badges/improve/awesome/build.svg'
+ end
end
end
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
new file mode 100644
index 00000000000..fe047e00409
--- /dev/null
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+feature 'User wants to edit a file', feature: true do
+ include WaitForAjax
+
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:commit_params) do
+ {
+ source_branch: project.default_branch,
+ target_branch: project.default_branch,
+ commit_message: "Committing First Update",
+ file_path: ".gitignore",
+ file_content: "First Update",
+ last_commit_sha: Gitlab::Git::Commit.last_for_path(project.repository, project.default_branch,
+ ".gitignore").sha
+ }
+ end
+
+ background do
+ project.team << [user, :master]
+ login_as user
+ visit namespace_project_edit_blob_path(project.namespace, project,
+ File.join(project.default_branch, '.gitignore'))
+ end
+
+ scenario 'file has been updated since the user opened the edit page' do
+ Files::UpdateService.new(project, user, commit_params).execute
+
+ click_button 'Commit Changes'
+
+ expect(page).to have_content 'Someone edited the file the same time you did.'
+ end
+end
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index e1e105e6bbe..a521ce50f35 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -23,7 +23,7 @@ feature 'project owner creates a license file', feature: true, js: true do
select_template('MIT License')
- file_content = find('.file-content')
+ file_content = first('.file-editor')
expect(file_content).to have_content('The MIT License (MIT)')
expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
@@ -39,6 +39,7 @@ feature 'project owner creates a license file', feature: true, js: true do
scenario 'project master creates a license file from the "Add license" link' do
click_link 'Add License'
+ expect(page).to have_content('New File')
expect(current_path).to eq(
namespace_project_new_blob_path(project.namespace, project, 'master'))
expect(find('#file_name').value).to eq('LICENSE')
@@ -46,7 +47,7 @@ feature 'project owner creates a license file', feature: true, js: true do
select_template('MIT License')
- file_content = find('.file-content')
+ file_content = first('.file-editor')
expect(file_content).to have_content('The MIT License (MIT)')
expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index 67aac25e427..4453b6d485f 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -14,6 +14,7 @@ feature 'project owner sees a link to create a license file in empty project', f
visit namespace_project_path(project.namespace, project)
click_link 'Create empty bare repository'
click_on 'LICENSE'
+ expect(page).to have_content('New File')
expect(current_path).to eq(
namespace_project_new_blob_path(project.namespace, project, 'master'))
@@ -22,7 +23,7 @@ feature 'project owner sees a link to create a license file in empty project', f
select_template('MIT License')
- file_content = find('.file-content')
+ file_content = first('.file-editor')
expect(file_content).to have_content('The MIT License (MIT)')
expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 7835e1678ad..f707ccf4e93 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -3,8 +3,9 @@ require 'spec_helper'
feature 'project import', feature: true, js: true do
include Select2Helper
- let(:user) { create(:admin) }
- let!(:namespace) { create(:namespace, name: "asd", owner: user) }
+ let(:admin) { create(:admin) }
+ let(:normal_user) { create(:user) }
+ let!(:namespace) { create(:namespace, name: "asd", owner: admin) }
let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
let(:export_path) { "#{Dir::tmpdir}/import_file_spec" }
let(:project) { Project.last }
@@ -12,66 +13,87 @@ feature 'project import', feature: true, js: true do
background do
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
- login_as(user)
end
after(:each) do
FileUtils.rm_rf(export_path, secure: true)
end
- scenario 'user imports an exported project successfully' do
- expect(Project.all.count).to be_zero
+ context 'admin user' do
+ before do
+ login_as(admin)
+ end
- visit new_project_path
+ scenario 'user imports an exported project successfully' do
+ expect(Project.all.count).to be_zero
- select2('2', from: '#project_namespace_id')
- fill_in :project_path, with: 'test-project-path', visible: true
- click_link 'GitLab export'
+ visit new_project_path
- expect(page).to have_content('GitLab project export')
- expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path')
+ select2('2', from: '#project_namespace_id')
+ fill_in :project_path, with: 'test-project-path', visible: true
+ click_link 'GitLab export'
- attach_file('file', file)
+ expect(page).to have_content('GitLab project export')
+ expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path')
- click_on 'Import project' # import starts
+ attach_file('file', file)
- expect(project).not_to be_nil
- expect(project.issues).not_to be_empty
- expect(project.merge_requests).not_to be_empty
- expect(project_hook).to exist
- expect(wiki_exists?).to be true
- expect(project.import_status).to eq('finished')
- end
+ click_on 'Import project' # import starts
+
+ expect(project).not_to be_nil
+ expect(project.issues).not_to be_empty
+ expect(project.merge_requests).not_to be_empty
+ expect(project_hook).to exist
+ expect(wiki_exists?).to be true
+ expect(project.import_status).to eq('finished')
+ end
- scenario 'invalid project' do
- project = create(:project, namespace_id: 2)
+ scenario 'invalid project' do
+ project = create(:project, namespace_id: 2)
- visit new_project_path
+ visit new_project_path
- select2('2', from: '#project_namespace_id')
- fill_in :project_path, with: project.name, visible: true
- click_link 'GitLab export'
+ select2('2', from: '#project_namespace_id')
+ fill_in :project_path, with: project.name, visible: true
+ click_link 'GitLab export'
- attach_file('file', file)
- click_on 'Import project'
+ attach_file('file', file)
+ click_on 'Import project'
- page.within('.flash-container') do
- expect(page).to have_content('Project could not be imported')
+ page.within('.flash-container') do
+ expect(page).to have_content('Project could not be imported')
+ end
+ end
+
+ scenario 'project with no name' do
+ create(:project, namespace_id: 2)
+
+ visit new_project_path
+
+ select2('2', from: '#project_namespace_id')
+
+ # click on disabled element
+ find(:link, 'GitLab export').trigger('click')
+
+ page.within('.flash-container') do
+ expect(page).to have_content('Please enter path and name')
+ end
end
end
- scenario 'project with no name' do
- create(:project, namespace_id: 2)
+ context 'normal user' do
+ before do
+ login_as(normal_user)
+ end
- visit new_project_path
+ scenario 'non-admin user is not allowed to import a project' do
+ expect(Project.all.count).to be_zero
- select2('2', from: '#project_namespace_id')
+ visit new_project_path
- # click on disabled element
- find(:link, 'GitLab export').trigger('click')
+ fill_in :project_path, with: 'test-project-path', visible: true
- page.within('.flash-container') do
- expect(page).to have_content('Please enter path and name')
+ expect(page).not_to have_content('GitLab export')
end
end
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
new file mode 100644
index 00000000000..4a83740621a
--- /dev/null
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+feature 'issuable templates', feature: true, js: true do
+ include WaitForAjax
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public) }
+
+ before do
+ project.team << [user, :master]
+ login_as user
+ end
+
+ context 'user creates an issue using templates' do
+ let(:template_content) { 'this is a test "bug" template' }
+ let(:issue) { create(:issue, author: user, assignee: user, project: project) }
+
+ background do
+ project.repository.commit_file(user, '.gitlab/issue_templates/bug.md', template_content, 'added issue template', 'master', false)
+ visit edit_namespace_project_issue_path project.namespace, project, issue
+ fill_in :'issue[title]', with: 'test issue title'
+ end
+
+ scenario 'user selects "bug" template' do
+ select_template 'bug'
+ wait_for_ajax
+ preview_template
+ save_changes
+ end
+ end
+
+ context 'user creates a merge request using templates' do
+ let(:template_content) { 'this is a test "feature-proposal" template' }
+ let(:merge_request) { create(:merge_request, :with_diffs, source_project: project) }
+
+ background do
+ project.repository.commit_file(user, '.gitlab/merge_request_templates/feature-proposal.md', template_content, 'added merge request template', 'master', false)
+ visit edit_namespace_project_merge_request_path project.namespace, project, merge_request
+ fill_in :'merge_request[title]', with: 'test merge request title'
+ end
+
+ scenario 'user selects "feature-proposal" template' do
+ select_template 'feature-proposal'
+ wait_for_ajax
+ preview_template
+ save_changes
+ end
+ end
+
+ context 'user creates a merge request from a forked project using templates' do
+ let(:template_content) { 'this is a test "feature-proposal" template' }
+ let(:fork_user) { create(:user) }
+ let(:fork_project) { create(:project, :public) }
+ let(:merge_request) { create(:merge_request, :with_diffs, source_project: fork_project) }
+
+ background do
+ logout
+ project.team << [fork_user, :developer]
+ fork_project.team << [fork_user, :master]
+ create(:forked_project_link, forked_to_project: fork_project, forked_from_project: project)
+ login_as fork_user
+ fork_project.repository.commit_file(fork_user, '.gitlab/merge_request_templates/feature-proposal.md', template_content, 'added merge request template', 'master', false)
+ visit edit_namespace_project_merge_request_path fork_project.namespace, fork_project, merge_request
+ fill_in :'merge_request[title]', with: 'test merge request title'
+ end
+
+ scenario 'user selects "feature-proposal" template' do
+ select_template 'feature-proposal'
+ wait_for_ajax
+ preview_template
+ save_changes
+ end
+ end
+
+ def preview_template
+ click_link 'Preview'
+ expect(page).to have_content template_content
+ end
+
+ def save_changes
+ click_button "Save changes"
+ expect(page).to have_content template_content
+ end
+
+ def select_template(name)
+ first('.js-issuable-selector').click
+ first('.js-issuable-selector-wrap .dropdown-content a', text: name).click
+ end
+end
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 3499460c84d..a0ee6cab7ec 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -71,7 +71,10 @@ feature 'Projected Branches', feature: true, js: true do
project.repository.add_branch(user, 'production-stable', 'master')
project.repository.add_branch(user, 'staging-stable', 'master')
project.repository.add_branch(user, 'development', 'master')
- create(:protected_branch, project: project, name: "*-stable")
+
+ visit namespace_project_protected_branches_path(project.namespace, project)
+ set_protected_branch_name('*-stable')
+ click_on "Protect"
visit namespace_project_protected_branches_path(project.namespace, project)
click_on "2 matching branches"
@@ -90,13 +93,17 @@ feature 'Projected Branches', feature: true, js: true do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
within('.new_protected_branch') do
- find(".js-allowed-to-push").click
- within(".dropdown.open .dropdown-menu") { click_on access_type_name }
+ allowed_to_push_button = find(".js-allowed-to-push")
+
+ unless allowed_to_push_button.text == access_type_name
+ allowed_to_push_button.click
+ within(".dropdown.open .dropdown-menu") { click_on access_type_name }
+ end
end
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
- expect(ProtectedBranch.last.push_access_level.access_level).to eq(access_type_id)
+ expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to eq([access_type_id])
end
it "allows updating protected branches so that #{access_type_name} can push to them" do
@@ -112,7 +119,7 @@ feature 'Projected Branches', feature: true, js: true do
end
wait_for_ajax
- expect(ProtectedBranch.last.push_access_level.access_level).to eq(access_type_id)
+ expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id)
end
end
@@ -121,13 +128,17 @@ feature 'Projected Branches', feature: true, js: true do
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('master')
within('.new_protected_branch') do
- find(".js-allowed-to-merge").click
- within(".dropdown.open .dropdown-menu") { click_on access_type_name }
+ allowed_to_merge_button = find(".js-allowed-to-merge")
+
+ unless allowed_to_merge_button.text == access_type_name
+ allowed_to_merge_button.click
+ within(".dropdown.open .dropdown-menu") { click_on access_type_name }
+ end
end
click_on "Protect"
expect(ProtectedBranch.count).to eq(1)
- expect(ProtectedBranch.last.merge_access_level.access_level).to eq(access_type_id)
+ expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to eq([access_type_id])
end
it "allows updating protected branches so that #{access_type_name} can merge to them" do
@@ -143,7 +154,7 @@ feature 'Projected Branches', feature: true, js: true do
end
wait_for_ajax
- expect(ProtectedBranch.last.merge_access_level.access_level).to eq(access_type_id)
+ expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id)
end
end
end
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index 9335f5bf120..d370f90f7d9 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -1,8 +1,16 @@
require 'spec_helper'
feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: true, js: true do
+ include WaitForAjax
+
before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) }
+ def manage_two_factor_authentication
+ click_on 'Manage Two-Factor Authentication'
+ expect(page).to have_content("Setup New U2F Device")
+ wait_for_ajax
+ end
+
def register_u2f_device(u2f_device = nil)
u2f_device ||= FakeU2fDevice.new(page)
u2f_device.respond_to_u2f_registration
@@ -34,7 +42,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
describe 'when 2FA via OTP is enabled' do
it 'allows registering a new device' do
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
expect(page.body).to match("You've already enabled two-factor authentication using mobile")
register_u2f_device
@@ -46,15 +54,15 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
visit profile_account_path
# First device
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
register_u2f_device
expect(page.body).to match('Your U2F device was registered')
# Second device
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
register_u2f_device
expect(page.body).to match('Your U2F device was registered')
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
expect(page.body).to match('You have 2 U2F devices registered')
end
end
@@ -62,7 +70,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
it 'allows the same device to be registered for multiple users' do
# First user
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
u2f_device = register_u2f_device
expect(page.body).to match('Your U2F device was registered')
logout
@@ -71,7 +79,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
user = login_as(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
register_u2f_device(u2f_device)
expect(page.body).to match('Your U2F device was registered')
@@ -81,7 +89,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
context "when there are form errors" do
it "doesn't register the device if there are errors" do
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
# Have the "u2f device" respond with bad data
page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };")
@@ -96,7 +104,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
it "allows retrying registration" do
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
# Failed registration
page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };")
@@ -122,7 +130,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
login_as(user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
@u2f_device = register_u2f_device
logout
end
@@ -161,7 +169,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
current_user = login_as(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
register_u2f_device
logout
@@ -182,7 +190,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
current_user = login_as(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
register_u2f_device(@u2f_device)
logout
@@ -248,7 +256,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
user = login_as(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
+ manage_two_factor_authentication
expect(page).to have_content("Your U2F device needs to be set up.")
register_u2f_device
end
diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb
index 61f2bc61e0c..d7880d5778f 100644
--- a/spec/features/variables_spec.rb
+++ b/spec/features/variables_spec.rb
@@ -42,6 +42,7 @@ describe 'Project variables', js: true do
find('.btn-variable-edit').click
end
+ expect(page).to have_content('Update variable')
fill_in('variable_key', with: 'key')
fill_in('variable_value', with: 'key value')
click_button('Save variable')
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 0a1cc3b3df7..7a3a74335e8 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -23,73 +23,36 @@ describe ProjectsFinder do
let(:finder) { described_class.new }
- describe 'without a group' do
- describe 'without a user' do
- subject { finder.execute }
+ describe 'without a user' do
+ subject { finder.execute }
- it { is_expected.to eq([public_project]) }
- end
-
- describe 'with a user' do
- subject { finder.execute(user) }
-
- describe 'without private projects' do
- it { is_expected.to eq([public_project, internal_project]) }
- end
-
- describe 'with private projects' do
- before do
- private_project.team.add_user(user, Gitlab::Access::MASTER)
- end
-
- it do
- is_expected.to eq([public_project, internal_project,
- private_project])
- end
- end
- end
+ it { is_expected.to eq([public_project]) }
end
- describe 'with a group' do
- describe 'without a user' do
- subject { finder.execute(nil, group: group) }
+ describe 'with a user' do
+ subject { finder.execute(user) }
- it { is_expected.to eq([public_project]) }
+ describe 'without private projects' do
+ it { is_expected.to eq([public_project, internal_project]) }
end
- describe 'with a user' do
- subject { finder.execute(user, group: group) }
-
- describe 'without shared projects' do
- it { is_expected.to eq([public_project, internal_project]) }
+ describe 'with private projects' do
+ before do
+ private_project.team.add_user(user, Gitlab::Access::MASTER)
end
- describe 'with shared projects and group membership' do
- before do
- group.add_user(user, Gitlab::Access::DEVELOPER)
-
- shared_project.project_group_links.
- create(group_access: Gitlab::Access::MASTER, group: group)
- end
-
- it do
- is_expected.to eq([shared_project, public_project, internal_project])
- end
+ it do
+ is_expected.to eq([public_project, internal_project, private_project])
end
+ end
+ end
- describe 'with shared projects and project membership' do
- before do
- shared_project.team.add_user(user, Gitlab::Access::DEVELOPER)
+ describe 'with project_ids_relation' do
+ let(:project_ids_relation) { Project.where(id: internal_project.id) }
- shared_project.project_group_links.
- create(group_access: Gitlab::Access::MASTER, group: group)
- end
+ subject { finder.execute(user, project_ids_relation) }
- it do
- is_expected.to eq([shared_project, public_project, internal_project])
- end
- end
- end
+ it { is_expected.to eq([internal_project]) }
end
end
end
diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb
index 153f1864ceb..9c577501f00 100644
--- a/spec/helpers/notes_helper_spec.rb
+++ b/spec/helpers/notes_helper_spec.rb
@@ -38,6 +38,11 @@ describe NotesHelper do
end
describe '#preload_max_access_for_authors' do
+ before do
+ # This method reads cache from RequestStore, so make sure it's clean.
+ RequestStore.clear!
+ end
+
it 'loads multiple users' do
expected_access = {
owner.id => Gitlab::Access::OWNER,
diff --git a/spec/lib/gitlab/akismet_helper_spec.rb b/spec/lib/gitlab/akismet_helper_spec.rb
deleted file mode 100644
index b08396da4d2..00000000000
--- a/spec/lib/gitlab/akismet_helper_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::AkismetHelper, type: :helper do
- let(:project) { create(:project, :public) }
- let(:user) { create(:user) }
-
- before do
- allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url))
- allow_any_instance_of(ApplicationSetting).to receive(:akismet_enabled).and_return(true)
- allow_any_instance_of(ApplicationSetting).to receive(:akismet_api_key).and_return('12345')
- end
-
- describe '#check_for_spam?' do
- it 'returns true for public project' do
- expect(helper.check_for_spam?(project)).to eq(true)
- end
-
- it 'returns false for private project' do
- project.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
- expect(helper.check_for_spam?(project)).to eq(false)
- end
- end
-
- describe '#is_spam?' do
- it 'returns true for spam' do
- environment = {
- 'action_dispatch.remote_ip' => '127.0.0.1',
- 'HTTP_USER_AGENT' => 'Test User Agent'
- }
-
- allow_any_instance_of(::Akismet::Client).to receive(:check).and_return([true, true])
- expect(helper.is_spam?(environment, user, 'Is this spam?')).to eq(true)
- end
- end
-end
diff --git a/spec/lib/gitlab/badge/build/metadata_spec.rb b/spec/lib/gitlab/badge/build/metadata_spec.rb
index ad5388215c2..d678e522721 100644
--- a/spec/lib/gitlab/badge/build/metadata_spec.rb
+++ b/spec/lib/gitlab/badge/build/metadata_spec.rb
@@ -1,37 +1,27 @@
require 'spec_helper'
+require 'lib/gitlab/badge/shared/metadata'
describe Gitlab::Badge::Build::Metadata do
- let(:project) { create(:project) }
- let(:branch) { 'master' }
- let(:badge) { described_class.new(project, branch) }
+ let(:badge) { double(project: create(:project), ref: 'feature') }
+ let(:metadata) { described_class.new(badge) }
- describe '#to_html' do
- let(:html) { Nokogiri::HTML.parse(badge.to_html) }
- let(:a_href) { html.at('a') }
+ it_behaves_like 'badge metadata'
- it 'points to link' do
- expect(a_href[:href]).to eq badge.link_url
- end
-
- it 'contains clickable image' do
- expect(a_href.children.first.name).to eq 'img'
+ describe '#title' do
+ it 'returns build status title' do
+ expect(metadata.title).to eq 'build status'
end
end
- describe '#to_markdown' do
- subject { badge.to_markdown }
-
- it { is_expected.to include badge.image_url }
- it { is_expected.to include badge.link_url }
- end
-
describe '#image_url' do
- subject { badge.image_url }
- it { is_expected.to include "badges/#{branch}/build.svg" }
+ it 'returns valid url' do
+ expect(metadata.image_url).to include 'badges/feature/build.svg'
+ end
end
describe '#link_url' do
- subject { badge.link_url }
- it { is_expected.to include "commits/#{branch}" }
+ it 'returns valid link' do
+ expect(metadata.link_url).to include 'commits/feature'
+ end
end
end
diff --git a/spec/lib/gitlab/badge/build_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb
index bb8144d5122..38eebb2a176 100644
--- a/spec/lib/gitlab/badge/build_spec.rb
+++ b/spec/lib/gitlab/badge/build/status_spec.rb
@@ -1,11 +1,23 @@
require 'spec_helper'
-describe Gitlab::Badge::Build do
+describe Gitlab::Badge::Build::Status do
let(:project) { create(:project) }
let(:sha) { project.commit.sha }
let(:branch) { 'master' }
let(:badge) { described_class.new(project, branch) }
+ describe '#entity' do
+ it 'always says build' do
+ expect(badge.entity).to eq 'build'
+ end
+ end
+
+ describe '#template' do
+ it 'returns badge template' do
+ expect(badge.template.key_text).to eq 'build'
+ end
+ end
+
describe '#metadata' do
it 'returns badge metadata' do
expect(badge.metadata.image_url)
@@ -13,12 +25,6 @@ describe Gitlab::Badge::Build do
end
end
- describe '#key_text' do
- it 'always says build' do
- expect(badge.key_text).to eq 'build'
- end
- end
-
context 'build exists' do
let!(:build) { create_build(project, sha, branch) }
@@ -30,12 +36,6 @@ describe Gitlab::Badge::Build do
expect(badge.status).to eq 'success'
end
end
-
- describe '#value_text' do
- it 'returns correct value text' do
- expect(badge.value_text).to eq 'success'
- end
- end
end
context 'build failed' do
@@ -46,12 +46,6 @@ describe Gitlab::Badge::Build do
expect(badge.status).to eq 'failed'
end
end
-
- describe '#value_text' do
- it 'has correct value text' do
- expect(badge.value_text).to eq 'failed'
- end
- end
end
context 'when outdated pipeline for given ref exists' do
@@ -87,12 +81,6 @@ describe Gitlab::Badge::Build do
expect(badge.status).to eq 'unknown'
end
end
-
- describe '#value_text' do
- it 'has correct value text' do
- expect(badge.value_text).to eq 'unknown'
- end
- end
end
def create_build(project, sha, branch)
diff --git a/spec/lib/gitlab/badge/build/template_spec.rb b/spec/lib/gitlab/badge/build/template_spec.rb
index 86dead3c54e..a7e21fb8bb1 100644
--- a/spec/lib/gitlab/badge/build/template_spec.rb
+++ b/spec/lib/gitlab/badge/build/template_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe Gitlab::Badge::Build::Template do
- let(:status) { 'success' }
- let(:template) { described_class.new(status) }
+ let(:badge) { double(entity: 'build', status: 'success') }
+ let(:template) { described_class.new(badge) }
describe '#key_text' do
it 'is always says build' do
@@ -34,15 +34,15 @@ describe Gitlab::Badge::Build::Template do
describe '#value_color' do
context 'when status is success' do
- let(:status) { 'success' }
-
it 'has expected color' do
expect(template.value_color).to eq '#4c1'
end
end
context 'when status is failed' do
- let(:status) { 'failed' }
+ before do
+ allow(badge).to receive(:status).and_return('failed')
+ end
it 'has expected color' do
expect(template.value_color).to eq '#e05d44'
@@ -50,7 +50,9 @@ describe Gitlab::Badge::Build::Template do
end
context 'when status is running' do
- let(:status) { 'running' }
+ before do
+ allow(badge).to receive(:status).and_return('running')
+ end
it 'has expected color' do
expect(template.value_color).to eq '#dfb317'
@@ -58,7 +60,9 @@ describe Gitlab::Badge::Build::Template do
end
context 'when status is unknown' do
- let(:status) { 'unknown' }
+ before do
+ allow(badge).to receive(:status).and_return('unknown')
+ end
it 'has expected color' do
expect(template.value_color).to eq '#9f9f9f'
@@ -66,7 +70,9 @@ describe Gitlab::Badge::Build::Template do
end
context 'when status does not match any known statuses' do
- let(:status) { 'invalid status' }
+ before do
+ allow(badge).to receive(:status).and_return('invalid')
+ end
it 'has expected color' do
expect(template.value_color).to eq '#9f9f9f'
diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
new file mode 100644
index 00000000000..74eaf7eaf8b
--- /dev/null
+++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+require 'lib/gitlab/badge/shared/metadata'
+
+describe Gitlab::Badge::Coverage::Metadata do
+ let(:badge) do
+ double(project: create(:project), ref: 'feature', job: 'test')
+ end
+
+ let(:metadata) { described_class.new(badge) }
+
+ it_behaves_like 'badge metadata'
+
+ describe '#title' do
+ it 'returns coverage report title' do
+ expect(metadata.title).to eq 'coverage report'
+ end
+ end
+
+ describe '#image_url' do
+ it 'returns valid url' do
+ expect(metadata.image_url).to include 'badges/feature/coverage.svg'
+ end
+ end
+
+ describe '#link_url' do
+ it 'returns valid link' do
+ expect(metadata.link_url).to include 'commits/feature'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb
new file mode 100644
index 00000000000..1ff49602486
--- /dev/null
+++ b/spec/lib/gitlab/badge/coverage/report_spec.rb
@@ -0,0 +1,93 @@
+require 'spec_helper'
+
+describe Gitlab::Badge::Coverage::Report do
+ let(:project) { create(:project) }
+ let(:job_name) { nil }
+
+ let(:badge) do
+ described_class.new(project, 'master', job_name)
+ end
+
+ describe '#entity' do
+ it 'describes a coverage' do
+ expect(badge.entity).to eq 'coverage'
+ end
+ end
+
+ describe '#metadata' do
+ it 'returns correct metadata' do
+ expect(badge.metadata.image_url).to include 'coverage.svg'
+ end
+ end
+
+ describe '#template' do
+ it 'returns correct template' do
+ expect(badge.template.key_text).to eq 'coverage'
+ end
+ end
+
+ shared_examples 'unknown coverage report' do
+ context 'particular job specified' do
+ let(:job_name) { '' }
+
+ it 'returns nil' do
+ expect(badge.status).to be_nil
+ end
+ end
+
+ context 'particular job not specified' do
+ let(:job_name) { nil }
+
+ it 'returns nil' do
+ expect(badge.status).to be_nil
+ end
+ end
+ end
+
+ context 'pipeline exists' do
+ let!(:pipeline) do
+ create(:ci_pipeline, project: project,
+ sha: project.commit.id,
+ ref: 'master')
+ end
+
+ context 'builds exist' do
+ before do
+ create(:ci_build, name: 'first', pipeline: pipeline, coverage: 40)
+ create(:ci_build, pipeline: pipeline, coverage: 60)
+ end
+
+ context 'particular job specified' do
+ let(:job_name) { 'first' }
+
+ it 'returns coverage for the particular job' do
+ expect(badge.status).to eq 40
+ end
+ end
+
+ context 'particular job not specified' do
+ let(:job_name) { '' }
+
+ it 'returns arithemetic mean for the pipeline' do
+ expect(badge.status).to eq 50
+ end
+ end
+ end
+
+ context 'builds do not exist' do
+ it_behaves_like 'unknown coverage report'
+
+ context 'particular job specified' do
+ let(:job_name) { 'nonexistent' }
+
+ it 'retruns nil' do
+ expect(badge.status).to be_nil
+ end
+ end
+ end
+ end
+
+ context 'pipeline does not exist' do
+ it_behaves_like 'unknown coverage report'
+ end
+end
diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb
new file mode 100644
index 00000000000..383bae6e087
--- /dev/null
+++ b/spec/lib/gitlab/badge/coverage/template_spec.rb
@@ -0,0 +1,130 @@
+require 'spec_helper'
+
+describe Gitlab::Badge::Coverage::Template do
+ let(:badge) { double(entity: 'coverage', status: 90) }
+ let(:template) { described_class.new(badge) }
+
+ describe '#key_text' do
+ it 'is always says coverage' do
+ expect(template.key_text).to eq 'coverage'
+ end
+ end
+
+ describe '#value_text' do
+ context 'when coverage is known' do
+ it 'returns coverage percentage' do
+ expect(template.value_text).to eq '90%'
+ end
+ end
+
+ context 'when coverage is unknown' do
+ before do
+ allow(badge).to receive(:status).and_return(nil)
+ end
+
+ it 'returns string that says coverage is unknown' do
+ expect(template.value_text).to eq 'unknown'
+ end
+ end
+ end
+
+ describe '#key_width' do
+ it 'has a fixed key width' do
+ expect(template.key_width).to eq 62
+ end
+ end
+
+ describe '#value_width' do
+ context 'when coverage is known' do
+ it 'is narrower when coverage is known' do
+ expect(template.value_width).to eq 36
+ end
+ end
+
+ context 'when coverage is unknown' do
+ before do
+ allow(badge).to receive(:status).and_return(nil)
+ end
+
+ it 'is wider when coverage is unknown to fit text' do
+ expect(template.value_width).to eq 58
+ end
+ end
+ end
+
+ describe '#key_color' do
+ it 'always has the same color' do
+ expect(template.key_color).to eq '#555'
+ end
+ end
+
+ describe '#value_color' do
+ context 'when coverage is good' do
+ before do
+ allow(badge).to receive(:status).and_return(98)
+ end
+
+ it 'is green' do
+ expect(template.value_color).to eq '#4c1'
+ end
+ end
+
+ context 'when coverage is acceptable' do
+ before do
+ allow(badge).to receive(:status).and_return(90)
+ end
+
+ it 'is green-orange' do
+ expect(template.value_color).to eq '#a3c51c'
+ end
+ end
+
+ context 'when coverage is medium' do
+ before do
+ allow(badge).to receive(:status).and_return(75)
+ end
+
+ it 'is orange-yellow' do
+ expect(template.value_color).to eq '#dfb317'
+ end
+ end
+
+ context 'when coverage is low' do
+ before do
+ allow(badge).to receive(:status).and_return(50)
+ end
+
+ it 'is red' do
+ expect(template.value_color).to eq '#e05d44'
+ end
+ end
+
+ context 'when coverage is unknown' do
+ before do
+ allow(badge).to receive(:status).and_return(nil)
+ end
+
+ it 'is grey' do
+ expect(template.value_color).to eq '#9f9f9f'
+ end
+ end
+ end
+
+ describe '#width' do
+ context 'when coverage is known' do
+ it 'returns the key width plus value width' do
+ expect(template.width).to eq 98
+ end
+ end
+
+ context 'when coverage is unknown' do
+ before do
+ allow(badge).to receive(:status).and_return(nil)
+ end
+
+ it 'returns key width plus wider value width' do
+ expect(template.width).to eq 120
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/badge/shared/metadata.rb b/spec/lib/gitlab/badge/shared/metadata.rb
new file mode 100644
index 00000000000..0cf18514251
--- /dev/null
+++ b/spec/lib/gitlab/badge/shared/metadata.rb
@@ -0,0 +1,21 @@
+shared_examples 'badge metadata' do
+ describe '#to_html' do
+ let(:html) { Nokogiri::HTML.parse(metadata.to_html) }
+ let(:a_href) { html.at('a') }
+
+ it 'points to link' do
+ expect(a_href[:href]).to eq metadata.link_url
+ end
+
+ it 'contains clickable image' do
+ expect(a_href.children.first.name).to eq 'img'
+ end
+ end
+
+ describe '#to_markdown' do
+ subject { metadata.to_markdown }
+
+ it { is_expected.to include metadata.image_url }
+ it { is_expected.to include metadata.link_url }
+ end
+end
diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb
new file mode 100644
index 00000000000..39069b49978
--- /dev/null
+++ b/spec/lib/gitlab/checks/change_access_spec.rb
@@ -0,0 +1,99 @@
+require 'spec_helper'
+
+describe Gitlab::Checks::ChangeAccess, lib: true do
+ describe '#exec' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:user_access) { Gitlab::UserAccess.new(user, project: project) }
+ let(:changes) do
+ {
+ oldrev: 'be93687618e4b132087f430a4d8fc3a609c9b77c',
+ newrev: '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51',
+ ref: 'refs/heads/master'
+ }
+ end
+
+ subject { described_class.new(changes, project: project, user_access: user_access).exec }
+
+ before { allow(user_access).to receive(:can_do_action?).with(:push_code).and_return(true) }
+
+ context 'without failed checks' do
+ it "doesn't return any error" do
+ expect(subject.status).to be(true)
+ end
+ end
+
+ context 'when the user is not allowed to push code' do
+ it 'returns an error' do
+ expect(user_access).to receive(:can_do_action?).with(:push_code).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to push code to this project.')
+ end
+ end
+
+ context 'tags check' do
+ let(:changes) do
+ {
+ oldrev: 'be93687618e4b132087f430a4d8fc3a609c9b77c',
+ newrev: '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51',
+ ref: 'refs/tags/v1.0.0'
+ }
+ end
+
+ it 'returns an error if the user is not allowed to update tags' do
+ expect(user_access).to receive(:can_do_action?).with(:admin_project).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to change existing tags on this project.')
+ end
+ end
+
+ context 'protected branches check' do
+ before do
+ allow(project).to receive(:protected_branch?).with('master').and_return(true)
+ end
+
+ it 'returns an error if the user is not allowed to do forced pushes to protected branches' do
+ expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true)
+ expect(user_access).to receive(:can_do_action?).with(:force_push_code_to_protected_branches).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to force push code to a protected branch on this project.')
+ end
+
+ it 'returns an error if the user is not allowed to merge to protected branches' do
+ expect_any_instance_of(Gitlab::Checks::MatchingMergeRequest).to receive(:match?).and_return(true)
+ expect(user_access).to receive(:can_merge_to_branch?).and_return(false)
+ expect(user_access).to receive(:can_push_to_branch?).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to merge code into protected branches on this project.')
+ end
+
+ it 'returns an error if the user is not allowed to push to protected branches' do
+ expect(user_access).to receive(:can_push_to_branch?).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to push code to protected branches on this project.')
+ end
+
+ context 'branch deletion' do
+ let(:changes) do
+ {
+ oldrev: 'be93687618e4b132087f430a4d8fc3a609c9b77c',
+ newrev: '0000000000000000000000000000000000000000',
+ ref: 'refs/heads/master'
+ }
+ end
+
+ it 'returns an error if the user is not allowed to delete protected branches' do
+ expect(user_access).to receive(:can_do_action?).with(:remove_protected_branches).and_return(false)
+
+ expect(subject.status).to be(false)
+ expect(subject.message).to eq('You are not allowed to delete protected branches from this project.')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/build_data_builder_spec.rb b/spec/lib/gitlab/data_builder/build_spec.rb
index 23ae5cfacc4..6c71e98066b 100644
--- a/spec/lib/gitlab/build_data_builder_spec.rb
+++ b/spec/lib/gitlab/data_builder/build_spec.rb
@@ -1,11 +1,11 @@
require 'spec_helper'
-describe 'Gitlab::BuildDataBuilder' do
+describe Gitlab::DataBuilder::Build do
let(:build) { create(:ci_build) }
describe '.build' do
let(:data) do
- Gitlab::BuildDataBuilder.build(build)
+ described_class.build(build)
end
it { expect(data).to be_a(Hash) }
diff --git a/spec/lib/gitlab/note_data_builder_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb
index 3d6bcdfd873..9a4dec91e56 100644
--- a/spec/lib/gitlab/note_data_builder_spec.rb
+++ b/spec/lib/gitlab/data_builder/note_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-describe 'Gitlab::NoteDataBuilder', lib: true do
+describe Gitlab::DataBuilder::Note, lib: true do
let(:project) { create(:project) }
let(:user) { create(:user) }
- let(:data) { Gitlab::NoteDataBuilder.build(note, user) }
+ let(:data) { described_class.build(note, user) }
let(:fixed_time) { Time.at(1425600000) } # Avoid time precision errors
before(:each) do
diff --git a/spec/lib/gitlab/data_builder/pipeline_spec.rb b/spec/lib/gitlab/data_builder/pipeline_spec.rb
new file mode 100644
index 00000000000..a68f5943a6a
--- /dev/null
+++ b/spec/lib/gitlab/data_builder/pipeline_spec.rb
@@ -0,0 +1,36 @@
+require 'spec_helper'
+
+describe Gitlab::DataBuilder::Pipeline do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ let(:pipeline) do
+ create(:ci_pipeline,
+ project: project,
+ status: 'success',
+ sha: project.commit.sha,
+ ref: project.default_branch)
+ end
+
+ let!(:build) { create(:ci_build, pipeline: pipeline) }
+
+ describe '.build' do
+ let(:data) { described_class.build(pipeline) }
+ let(:attributes) { data[:object_attributes] }
+ let(:build_data) { data[:builds].first }
+ let(:project_data) { data[:project] }
+
+ it { expect(attributes).to be_a(Hash) }
+ it { expect(attributes[:ref]).to eq(pipeline.ref) }
+ it { expect(attributes[:sha]).to eq(pipeline.sha) }
+ it { expect(attributes[:tag]).to eq(pipeline.tag) }
+ it { expect(attributes[:id]).to eq(pipeline.id) }
+ it { expect(attributes[:status]).to eq(pipeline.status) }
+
+ it { expect(build_data).to be_a(Hash) }
+ it { expect(build_data[:id]).to eq(build.id) }
+ it { expect(build_data[:status]).to eq(build.status) }
+
+ it { expect(project_data).to eq(project.hook_attrs(backward: false)) }
+ end
+end
diff --git a/spec/lib/gitlab/push_data_builder_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb
index 6bd7393aaa7..b73434e8dd7 100644
--- a/spec/lib/gitlab/push_data_builder_spec.rb
+++ b/spec/lib/gitlab/data_builder/push_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::PushDataBuilder, lib: true do
+describe Gitlab::DataBuilder::Push, lib: true do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/lib/gitlab/import_export/reader_spec.rb b/spec/lib/gitlab/import_export/reader_spec.rb
index b76e14deca1..b6dec41d218 100644
--- a/spec/lib/gitlab/import_export/reader_spec.rb
+++ b/spec/lib/gitlab/import_export/reader_spec.rb
@@ -12,7 +12,8 @@ describe Gitlab::ImportExport::Reader, lib: true do
except: [:iid],
include: [:merge_request_diff, :merge_request_test]
} },
- { commit_statuses: { include: :commit } }]
+ { commit_statuses: { include: :commit } },
+ { project_members: { include: { user: { only: [:email] } } } }]
}
end
diff --git a/spec/lib/gitlab/template/gitignore_spec.rb b/spec/lib/gitlab/template/gitignore_template_spec.rb
index bc0ec9325cc..9750a012e22 100644
--- a/spec/lib/gitlab/template/gitignore_spec.rb
+++ b/spec/lib/gitlab/template/gitignore_template_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::Template::Gitignore do
+describe Gitlab::Template::GitignoreTemplate do
subject { described_class }
describe '.all' do
@@ -24,7 +24,7 @@ describe Gitlab::Template::Gitignore do
it 'returns the Gitignore object of a valid file' do
ruby = subject.find('Ruby')
- expect(ruby).to be_a Gitlab::Template::Gitignore
+ expect(ruby).to be_a Gitlab::Template::GitignoreTemplate
expect(ruby.name).to eq('Ruby')
end
end
diff --git a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
new file mode 100644
index 00000000000..e3b8321eda3
--- /dev/null
+++ b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe Gitlab::Template::GitlabCiYmlTemplate do
+ subject { described_class }
+
+ describe '.all' do
+ it 'strips the gitlab-ci suffix' do
+ expect(subject.all.first.name).not_to end_with('.gitlab-ci.yml')
+ end
+
+ it 'combines the globals and rest' do
+ all = subject.all.map(&:name)
+
+ expect(all).to include('Elixir')
+ expect(all).to include('Docker')
+ expect(all).to include('Ruby')
+ end
+ end
+
+ describe '.find' do
+ it 'returns nil if the file does not exist' do
+ expect(subject.find('mepmep-yadida')).to be nil
+ end
+
+ it 'returns the GitlabCiYml object of a valid file' do
+ ruby = subject.find('Ruby')
+
+ expect(ruby).to be_a Gitlab::Template::GitlabCiYmlTemplate
+ expect(ruby.name).to eq('Ruby')
+ end
+ end
+
+ describe '#content' do
+ it 'loads the full file' do
+ gitignore = subject.new(Rails.root.join('vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml'))
+
+ expect(gitignore.name).to eq 'Ruby'
+ expect(gitignore.content).to start_with('#')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb
new file mode 100644
index 00000000000..f770857e958
--- /dev/null
+++ b/spec/lib/gitlab/template/issue_template_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe Gitlab::Template::IssueTemplate do
+ subject { described_class }
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:file_path_1) { '.gitlab/issue_templates/bug.md' }
+ let(:file_path_2) { '.gitlab/issue_templates/template_test.md' }
+ let(:file_path_3) { '.gitlab/issue_templates/feature_proposal.md' }
+
+ before do
+ project.team.add_user(user, Gitlab::Access::MASTER)
+ project.repository.commit_file(user, file_path_1, "something valid", "test 3", "master", false)
+ project.repository.commit_file(user, file_path_2, "template_test", "test 1", "master", false)
+ project.repository.commit_file(user, file_path_3, "feature_proposal", "test 2", "master", false)
+ end
+
+ describe '.all' do
+ it 'strips the md suffix' do
+ expect(subject.all(project).first.name).not_to end_with('.issue_template')
+ end
+
+ it 'combines the globals and rest' do
+ all = subject.all(project).map(&:name)
+
+ expect(all).to include('bug')
+ expect(all).to include('feature_proposal')
+ expect(all).to include('template_test')
+ end
+ end
+
+ describe '.find' do
+ it 'returns nil if the file does not exist' do
+ expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+
+ it 'returns the issue object of a valid file' do
+ ruby = subject.find('bug', project)
+
+ expect(ruby).to be_a Gitlab::Template::IssueTemplate
+ expect(ruby.name).to eq('bug')
+ end
+ end
+
+ describe '.by_category' do
+ it 'return array of templates' do
+ all = subject.by_category('', project).map(&:name)
+ expect(all).to include('bug')
+ expect(all).to include('feature_proposal')
+ expect(all).to include('template_test')
+ end
+
+ context 'when repo is bare or empty' do
+ let(:empty_project) { create(:empty_project) }
+ before { empty_project.team.add_user(user, Gitlab::Access::MASTER) }
+
+ it "returns empty array" do
+ templates = subject.by_category('', empty_project)
+ expect(templates).to be_empty
+ end
+ end
+ end
+
+ describe '#content' do
+ it 'loads the full file' do
+ issue_template = subject.new('.gitlab/issue_templates/bug.md', project)
+
+ expect(issue_template.name).to eq 'bug'
+ expect(issue_template.content).to eq('something valid')
+ end
+
+ it 'raises error when file is not found' do
+ issue_template = subject.new('.gitlab/issue_templates/bugnot.md', project)
+ expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+
+ context "when repo is empty" do
+ let(:empty_project) { create(:empty_project) }
+
+ before { empty_project.team.add_user(user, Gitlab::Access::MASTER) }
+
+ it "raises file not found" do
+ issue_template = subject.new('.gitlab/issue_templates/not_existent.md', empty_project)
+ expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb
new file mode 100644
index 00000000000..bb0f68043fa
--- /dev/null
+++ b/spec/lib/gitlab/template/merge_request_template_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe Gitlab::Template::MergeRequestTemplate do
+ subject { described_class }
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:file_path_1) { '.gitlab/merge_request_templates/bug.md' }
+ let(:file_path_2) { '.gitlab/merge_request_templates/template_test.md' }
+ let(:file_path_3) { '.gitlab/merge_request_templates/feature_proposal.md' }
+
+ before do
+ project.team.add_user(user, Gitlab::Access::MASTER)
+ project.repository.commit_file(user, file_path_1, "something valid", "test 3", "master", false)
+ project.repository.commit_file(user, file_path_2, "template_test", "test 1", "master", false)
+ project.repository.commit_file(user, file_path_3, "feature_proposal", "test 2", "master", false)
+ end
+
+ describe '.all' do
+ it 'strips the md suffix' do
+ expect(subject.all(project).first.name).not_to end_with('.issue_template')
+ end
+
+ it 'combines the globals and rest' do
+ all = subject.all(project).map(&:name)
+
+ expect(all).to include('bug')
+ expect(all).to include('feature_proposal')
+ expect(all).to include('template_test')
+ end
+ end
+
+ describe '.find' do
+ it 'returns nil if the file does not exist' do
+ expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+
+ it 'returns the merge request object of a valid file' do
+ ruby = subject.find('bug', project)
+
+ expect(ruby).to be_a Gitlab::Template::MergeRequestTemplate
+ expect(ruby.name).to eq('bug')
+ end
+ end
+
+ describe '.by_category' do
+ it 'return array of templates' do
+ all = subject.by_category('', project).map(&:name)
+ expect(all).to include('bug')
+ expect(all).to include('feature_proposal')
+ expect(all).to include('template_test')
+ end
+
+ context 'when repo is bare or empty' do
+ let(:empty_project) { create(:empty_project) }
+ before { empty_project.team.add_user(user, Gitlab::Access::MASTER) }
+
+ it "returns empty array" do
+ templates = subject.by_category('', empty_project)
+ expect(templates).to be_empty
+ end
+ end
+ end
+
+ describe '#content' do
+ it 'loads the full file' do
+ issue_template = subject.new('.gitlab/merge_request_templates/bug.md', project)
+
+ expect(issue_template.name).to eq 'bug'
+ expect(issue_template.content).to eq('something valid')
+ end
+
+ it 'raises error when file is not found' do
+ issue_template = subject.new('.gitlab/merge_request_templates/bugnot.md', project)
+ expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+
+ context "when repo is empty" do
+ let(:empty_project) { create(:empty_project) }
+
+ before { empty_project.team.add_user(user, Gitlab::Access::MASTER) }
+
+ it "raises file not found" do
+ issue_template = subject.new('.gitlab/merge_request_templates/not_existent.md', empty_project)
+ expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ end
+ end
+ end
+end
diff --git a/spec/models/blob_spec.rb b/spec/models/blob_spec.rb
index 1e5d6a34f83..cee20234e1f 100644
--- a/spec/models/blob_spec.rb
+++ b/spec/models/blob_spec.rb
@@ -94,4 +94,26 @@ describe Blob do
expect(blob.to_partial_path).to eq 'download'
end
end
+
+ describe '#size_within_svg_limits?' do
+ let(:blob) { described_class.decorate(double(:blob)) }
+
+ it 'returns true when the blob size is smaller than the SVG limit' do
+ expect(blob).to receive(:size).and_return(42)
+
+ expect(blob.size_within_svg_limits?).to eq(true)
+ end
+
+ it 'returns true when the blob size is equal to the SVG limit' do
+ expect(blob).to receive(:size).and_return(Blob::MAXIMUM_SVG_SIZE)
+
+ expect(blob.size_within_svg_limits?).to eq(true)
+ end
+
+ it 'returns false when the blob size is larger than the SVG limit' do
+ expect(blob).to receive(:size).and_return(1.terabyte)
+
+ expect(blob.size_within_svg_limits?).to eq(false)
+ end
+ end
end
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index 5980f6ddc32..ee2c3d04984 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -42,7 +42,7 @@ describe Ci::Build, models: true do
describe '#ignored?' do
subject { build.ignored? }
- context 'if build is not allowed to fail' do
+ context 'when build is not allowed to fail' do
before do
build.allow_failure = false
end
@@ -64,7 +64,7 @@ describe Ci::Build, models: true do
end
end
- context 'if build is allowed to fail' do
+ context 'when build is allowed to fail' do
before do
build.allow_failure = true
end
@@ -92,7 +92,7 @@ describe Ci::Build, models: true do
it { is_expected.to be_empty }
- context 'if build.trace contains text' do
+ context 'when build.trace contains text' do
let(:text) { 'example output' }
before do
build.trace = text
@@ -102,7 +102,7 @@ describe Ci::Build, models: true do
it { expect(subject.length).to be >= text.length }
end
- context 'if build.trace hides token' do
+ context 'when build.trace hides token' do
let(:token) { 'my_secret_token' }
before do
@@ -283,13 +283,13 @@ describe Ci::Build, models: true do
stub_ci_pipeline_yaml_file(config)
end
- context 'if config is not found' do
+ context 'when config is not found' do
let(:config) { nil }
it { is_expected.to eq(predefined_variables) }
end
- context 'if config does not have a questioned job' do
+ context 'when config does not have a questioned job' do
let(:config) do
YAML.dump({
test_other: {
@@ -301,7 +301,7 @@ describe Ci::Build, models: true do
it { is_expected.to eq(predefined_variables) }
end
- context 'if config has variables' do
+ context 'when config has variables' do
let(:config) do
YAML.dump({
test: {
@@ -393,7 +393,7 @@ describe Ci::Build, models: true do
it { is_expected.to be_falsey }
end
- context 'if there are runner' do
+ context 'when there are runners' do
let(:runner) { create(:ci_runner) }
before do
@@ -423,29 +423,27 @@ describe Ci::Build, models: true do
describe '#stuck?' do
subject { build.stuck? }
- %w(pending).each do |state|
- context "if commit_status.status is #{state}" do
- before do
- build.status = state
- end
-
- it { is_expected.to be_truthy }
+ context "when commit_status.status is pending" do
+ before do
+ build.status = 'pending'
+ end
- context "and there are specific runner" do
- let(:runner) { create(:ci_runner, contacted_at: 1.second.ago) }
+ it { is_expected.to be_truthy }
- before do
- build.project.runners << runner
- runner.save
- end
+ context "and there are specific runner" do
+ let(:runner) { create(:ci_runner, contacted_at: 1.second.ago) }
- it { is_expected.to be_falsey }
+ before do
+ build.project.runners << runner
+ runner.save
end
+
+ it { is_expected.to be_falsey }
end
end
- %w(success failed canceled running).each do |state|
- context "if commit_status.status is #{state}" do
+ %w[success failed canceled running].each do |state|
+ context "when commit_status.status is #{state}" do
before do
build.status = state
end
@@ -767,7 +765,7 @@ describe Ci::Build, models: true do
describe '#when' do
subject { build.when }
- context 'if is undefined' do
+ context 'when `when` is undefined' do
before do
build.when = nil
end
@@ -777,13 +775,13 @@ describe Ci::Build, models: true do
stub_ci_pipeline_yaml_file(config)
end
- context 'if config is not found' do
+ context 'when config is not found' do
let(:config) { nil }
it { is_expected.to eq('on_success') }
end
- context 'if config does not have a questioned job' do
+ context 'when config does not have a questioned job' do
let(:config) do
YAML.dump({
test_other: {
@@ -795,7 +793,7 @@ describe Ci::Build, models: true do
it { is_expected.to eq('on_success') }
end
- context 'if config has when' do
+ context 'when config has `when`' do
let(:config) do
YAML.dump({
test: {
@@ -881,7 +879,7 @@ describe Ci::Build, models: true do
subject { build.play }
- it 'enques a build' do
+ it 'enqueues a build' do
is_expected.to be_pending
is_expected.to eq(build)
end
@@ -901,7 +899,7 @@ describe Ci::Build, models: true do
describe '#when' do
subject { build.when }
- context 'if is undefined' do
+ context 'when `when` is undefined' do
before do
build.when = nil
end
@@ -911,13 +909,13 @@ describe Ci::Build, models: true do
stub_ci_pipeline_yaml_file(config)
end
- context 'if config is not found' do
+ context 'when config is not found' do
let(:config) { nil }
it { is_expected.to eq('on_success') }
end
- context 'if config does not have a questioned job' do
+ context 'when config does not have a questioned job' do
let(:config) do
YAML.dump({
test_other: {
@@ -929,7 +927,7 @@ describe Ci::Build, models: true do
it { is_expected.to eq('on_success') }
end
- context 'if config has when' do
+ context 'when config has when' do
let(:config) do
YAML.dump({
test: {
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 950833cb219..8137e9f8f71 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::Pipeline, models: true do
let(:project) { FactoryGirl.create :empty_project }
- let(:pipeline) { FactoryGirl.create :ci_empty_pipeline, project: project }
+ let(:pipeline) { FactoryGirl.create :ci_empty_pipeline, status: 'created', project: project }
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:user) }
@@ -18,6 +18,8 @@ describe Ci::Pipeline, models: true do
it { is_expected.to respond_to :git_author_email }
it { is_expected.to respond_to :short_sha }
+ it { is_expected.to delegate_method(:stages).to(:statuses) }
+
describe '#valid_commit_sha' do
context 'commit.sha can not start with 00000000' do
before do
@@ -310,4 +312,87 @@ describe Ci::Pipeline, models: true do
it { is_expected.to eq('running') }
end
end
+
+ describe '#execute_hooks' do
+ let!(:build_a) { create_build('a') }
+ let!(:build_b) { create_build('b') }
+
+ let!(:hook) do
+ create(:project_hook, project: project, pipeline_events: enabled)
+ end
+
+ before do
+ ProjectWebHookWorker.drain
+ end
+
+ context 'with pipeline hooks enabled' do
+ let(:enabled) { true }
+
+ before do
+ WebMock.stub_request(:post, hook.url)
+ end
+
+ context 'with multiple builds' do
+ context 'when build is queued' do
+ before do
+ build_a.enqueue
+ build_b.enqueue
+ end
+
+ it 'receive a pending event once' do
+ expect(WebMock).to have_requested_pipeline_hook('pending').once
+ end
+ end
+
+ context 'when build is run' do
+ before do
+ build_a.enqueue
+ build_a.run
+ build_b.enqueue
+ build_b.run
+ end
+
+ it 'receive a running event once' do
+ expect(WebMock).to have_requested_pipeline_hook('running').once
+ end
+ end
+
+ context 'when all builds succeed' do
+ before do
+ build_a.success
+ build_b.success
+ end
+
+ it 'receive a success event once' do
+ expect(WebMock).to have_requested_pipeline_hook('success').once
+ end
+ end
+
+ def have_requested_pipeline_hook(status)
+ have_requested(:post, hook.url).with do |req|
+ json_body = JSON.parse(req.body)
+ json_body['object_attributes']['status'] == status &&
+ json_body['builds'].length == 2
+ end
+ end
+ end
+ end
+
+ context 'with pipeline hooks disabled' do
+ let(:enabled) { false }
+
+ before do
+ build_a.enqueue
+ build_b.enqueue
+ end
+
+ it 'did not execute pipeline_hook after touched' do
+ expect(WebMock).not_to have_requested(:post, hook.url)
+ end
+ end
+
+ def create_build(name)
+ create(:ci_build, :created, pipeline: pipeline, name: name)
+ end
+ end
end
diff --git a/spec/models/concerns/spammable_spec.rb b/spec/models/concerns/spammable_spec.rb
new file mode 100644
index 00000000000..32935bc0b09
--- /dev/null
+++ b/spec/models/concerns/spammable_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe Issue, 'Spammable' do
+ let(:issue) { create(:issue, description: 'Test Desc.') }
+
+ describe 'Associations' do
+ it { is_expected.to have_one(:user_agent_detail).dependent(:destroy) }
+ end
+
+ describe 'ClassMethods' do
+ it 'should return correct attr_spammable' do
+ expect(issue.spammable_text).to eq("#{issue.title}\n#{issue.description}")
+ end
+ end
+
+ describe 'InstanceMethods' do
+ it 'should be invalid if spam' do
+ issue = build(:issue, spam: true)
+ expect(issue.valid?).to be_falsey
+ end
+
+ describe '#check_for_spam?' do
+ it 'returns true for public project' do
+ issue.project.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
+ expect(issue.check_for_spam?).to eq(true)
+ end
+
+ it 'returns false for other visibility levels' do
+ expect(issue.check_for_spam?).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index 7df3df4bb9e..bfff639ad78 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -15,4 +15,28 @@ describe Deployment, models: true do
it { is_expected.to validate_presence_of(:ref) }
it { is_expected.to validate_presence_of(:sha) }
+
+ describe '#includes_commit?' do
+ let(:project) { create(:project) }
+ let(:environment) { create(:environment, project: project) }
+ let(:deployment) do
+ create(:deployment, environment: environment, sha: project.commit.id)
+ end
+
+ context 'when there is no project commit' do
+ it 'returns false' do
+ commit = project.commit('feature')
+
+ expect(deployment.includes_commit?(commit)).to be false
+ end
+ end
+
+ context 'when they share the same tree branch' do
+ it 'returns true' do
+ commit = project.commit
+
+ expect(deployment.includes_commit?(commit)).to be true
+ end
+ end
+ end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 8a84ac0a7c7..c881897926e 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -30,4 +30,37 @@ describe Environment, models: true do
expect(env.external_url).to be_nil
end
end
+
+ describe '#includes_commit?' do
+ context 'without a last deployment' do
+ it "returns false" do
+ expect(environment.includes_commit?('HEAD')).to be false
+ end
+ end
+
+ context 'with a last deployment' do
+ let(:project) { create(:project) }
+ let(:environment) { create(:environment, project: project) }
+
+ let!(:deployment) do
+ create(:deployment, environment: environment, sha: project.commit('master').id)
+ end
+
+ context 'in the same branch' do
+ it 'returns true' do
+ expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be true
+ end
+ end
+
+ context 'not in the same branch' do
+ before do
+ deployment.update(sha: project.commit('feature').id)
+ end
+
+ it 'returns false' do
+ expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be false
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 3270b877c1a..35a4418ebb3 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -674,6 +674,21 @@ describe MergeRequest, models: true do
end
end
+ describe "#environments" do
+ let(:project) { create(:project) }
+ let!(:environment) { create(:environment, project: project) }
+ let!(:environment1) { create(:environment, project: project) }
+ let!(:environment2) { create(:environment, project: project) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+
+ it 'selects deployed environments' do
+ create(:deployment, environment: environment, sha: project.commit('master').id)
+ create(:deployment, environment: environment1, sha: project.commit('feature').id)
+
+ expect(merge_request.environments).to eq [environment]
+ end
+ end
+
describe "#reload_diff" do
let(:note) { create(:diff_note_on_merge_request, project: subject.project, noteable: subject) }
diff --git a/spec/models/project_services/assembla_service_spec.rb b/spec/models/project_services/assembla_service_spec.rb
index 00c4e0fb64c..d672d80156c 100644
--- a/spec/models/project_services/assembla_service_spec.rb
+++ b/spec/models/project_services/assembla_service_spec.rb
@@ -39,7 +39,7 @@ describe AssemblaService, models: true do
token: 'verySecret',
subdomain: 'project_name'
)
- @sample_data = Gitlab::PushDataBuilder.build_sample(project, user)
+ @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
@api_url = 'https://atlas.assembla.com/spaces/project_name/github_tool?secret_key=verySecret'
WebMock.stub_request(:post, @api_url)
end
diff --git a/spec/models/project_services/builds_email_service_spec.rb b/spec/models/project_services/builds_email_service_spec.rb
index ca2cd8aa551..0194f9e2563 100644
--- a/spec/models/project_services/builds_email_service_spec.rb
+++ b/spec/models/project_services/builds_email_service_spec.rb
@@ -1,7 +1,9 @@
require 'spec_helper'
describe BuildsEmailService do
- let(:data) { Gitlab::BuildDataBuilder.build(create(:ci_build)) }
+ let(:data) do
+ Gitlab::DataBuilder::Build.build(create(:ci_build))
+ end
describe 'Validations' do
context 'when service is active' do
@@ -39,7 +41,7 @@ describe BuildsEmailService do
describe '#test' do
it 'sends email' do
- data = Gitlab::BuildDataBuilder.build(create(:ci_build))
+ data = Gitlab::DataBuilder::Build.build(create(:ci_build))
subject.recipients = 'test@gitlab.com'
expect(BuildEmailWorker).to receive(:perform_async)
@@ -49,7 +51,7 @@ describe BuildsEmailService do
context 'notify only failed builds is true' do
it 'sends email' do
- data = Gitlab::BuildDataBuilder.build(create(:ci_build))
+ data = Gitlab::DataBuilder::Build.build(create(:ci_build))
data[:build_status] = "success"
subject.recipients = 'test@gitlab.com'
diff --git a/spec/models/project_services/campfire_service_spec.rb b/spec/models/project_services/campfire_service_spec.rb
index 1adf93258f3..c76ae21421b 100644
--- a/spec/models/project_services/campfire_service_spec.rb
+++ b/spec/models/project_services/campfire_service_spec.rb
@@ -54,7 +54,7 @@ describe CampfireService, models: true do
subdomain: 'project-name',
room: 'test-room'
)
- @sample_data = Gitlab::PushDataBuilder.build_sample(project, user)
+ @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
@rooms_url = 'https://verySecret:X@project-name.campfirenow.com/rooms.json'
@headers = { 'Content-Type' => 'application/json; charset=utf-8' }
end
diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb
index 3a8e67438fc..8ef892259f2 100644
--- a/spec/models/project_services/drone_ci_service_spec.rb
+++ b/spec/models/project_services/drone_ci_service_spec.rb
@@ -84,7 +84,9 @@ describe DroneCiService, models: true do
include_context :drone_ci_service
let(:user) { create(:user, username: 'username') }
- let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:push_sample_data) do
+ Gitlab::DataBuilder::Push.build_sample(project, user)
+ end
it do
service_hook = double
diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb
index 6518098ceea..d2557019756 100644
--- a/spec/models/project_services/flowdock_service_spec.rb
+++ b/spec/models/project_services/flowdock_service_spec.rb
@@ -52,7 +52,7 @@ describe FlowdockService, models: true do
service_hook: true,
token: 'verySecret'
)
- @sample_data = Gitlab::PushDataBuilder.build_sample(project, user)
+ @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
@api_url = 'https://api.flowdock.com/v1/messages'
WebMock.stub_request(:post, @api_url)
end
diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb
index 2c5583bdaa2..3d0b6c9816b 100644
--- a/spec/models/project_services/gemnasium_service_spec.rb
+++ b/spec/models/project_services/gemnasium_service_spec.rb
@@ -55,7 +55,7 @@ describe GemnasiumService, models: true do
token: 'verySecret',
api_key: 'GemnasiumUserApiKey'
)
- @sample_data = Gitlab::PushDataBuilder.build_sample(project, user)
+ @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
end
it "calls Gemnasium service" do
expect(Gemnasium::GitlabService).to receive(:execute).with(an_instance_of(Hash)).once
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index 1b383219eb9..34eafbe555d 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -48,7 +48,9 @@ describe HipchatService, models: true do
let(:project_name) { project.name_with_namespace.gsub(/\s/, '') }
let(:token) { 'verySecret' }
let(:server_url) { 'https://hipchat.example.com'}
- let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:push_sample_data) do
+ Gitlab::DataBuilder::Push.build_sample(project, user)
+ end
before(:each) do
allow(hipchat).to receive_messages(
@@ -108,7 +110,15 @@ describe HipchatService, models: true do
end
context 'tag_push events' do
- let(:push_sample_data) { Gitlab::PushDataBuilder.build(project, user, Gitlab::Git::BLANK_SHA, '1' * 40, 'refs/tags/test', []) }
+ let(:push_sample_data) do
+ Gitlab::DataBuilder::Push.build(
+ project,
+ user,
+ Gitlab::Git::BLANK_SHA,
+ '1' * 40,
+ 'refs/tags/test',
+ [])
+ end
it "calls Hipchat API for tag push events" do
hipchat.execute(push_sample_data)
@@ -185,7 +195,7 @@ describe HipchatService, models: true do
end
it "calls Hipchat API for commit comment events" do
- data = Gitlab::NoteDataBuilder.build(commit_note, user)
+ data = Gitlab::DataBuilder::Note.build(commit_note, user)
hipchat.execute(data)
expect(WebMock).to have_requested(:post, api_url).once
@@ -217,7 +227,7 @@ describe HipchatService, models: true do
end
it "calls Hipchat API for merge request comment events" do
- data = Gitlab::NoteDataBuilder.build(merge_request_note, user)
+ data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
hipchat.execute(data)
expect(WebMock).to have_requested(:post, api_url).once
@@ -244,7 +254,7 @@ describe HipchatService, models: true do
end
it "calls Hipchat API for issue comment events" do
- data = Gitlab::NoteDataBuilder.build(issue_note, user)
+ data = Gitlab::DataBuilder::Note.build(issue_note, user)
hipchat.execute(data)
message = hipchat.send(:create_message, data)
@@ -270,7 +280,7 @@ describe HipchatService, models: true do
end
it "calls Hipchat API for snippet comment events" do
- data = Gitlab::NoteDataBuilder.build(snippet_note, user)
+ data = Gitlab::DataBuilder::Note.build(snippet_note, user)
hipchat.execute(data)
expect(WebMock).to have_requested(:post, api_url).once
@@ -293,7 +303,7 @@ describe HipchatService, models: true do
context 'build events' do
let(:pipeline) { create(:ci_empty_pipeline) }
let(:build) { create(:ci_build, pipeline: pipeline) }
- let(:data) { Gitlab::BuildDataBuilder.build(build) }
+ let(:data) { Gitlab::DataBuilder::Build.build(build) }
context 'for failed' do
before { build.drop }
diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb
index b528baaf15c..ffb17fd3259 100644
--- a/spec/models/project_services/irker_service_spec.rb
+++ b/spec/models/project_services/irker_service_spec.rb
@@ -46,25 +46,28 @@ describe IrkerService, models: true do
let(:irker) { IrkerService.new }
let(:user) { create(:user) }
let(:project) { create(:project) }
- let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:sample_data) do
+ Gitlab::DataBuilder::Push.build_sample(project, user)
+ end
let(:recipients) { '#commits irc://test.net/#test ftp://bad' }
let(:colorize_messages) { '1' }
before do
+ @irker_server = TCPServer.new 'localhost', 0
+
allow(irker).to receive_messages(
active: true,
project: project,
project_id: project.id,
service_hook: true,
- server_host: 'localhost',
- server_port: 6659,
+ server_host: @irker_server.addr[2],
+ server_port: @irker_server.addr[1],
default_irc_uri: 'irc://chat.freenode.net/',
recipients: recipients,
colorize_messages: colorize_messages)
irker.valid?
- @irker_server = TCPServer.new 'localhost', 6659
end
after do
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 342403f6354..9037ca5cc20 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -66,7 +66,7 @@ describe JiraService, models: true do
password: 'gitlab_jira_password'
)
@jira_service.save # will build API URL, as api_url was not specified above
- @sample_data = Gitlab::PushDataBuilder.build_sample(project, user)
+ @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
# https://github.com/bblimke/webmock#request-with-basic-authentication
@api_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/transitions'
@comment_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/comment'
diff --git a/spec/models/project_services/pivotaltracker_service_spec.rb b/spec/models/project_services/pivotaltracker_service_spec.rb
index f37edd4d970..d098d988521 100644
--- a/spec/models/project_services/pivotaltracker_service_spec.rb
+++ b/spec/models/project_services/pivotaltracker_service_spec.rb
@@ -39,4 +39,75 @@ describe PivotaltrackerService, models: true do
it { is_expected.not_to validate_presence_of(:token) }
end
end
+
+ describe 'Execute' do
+ let(:service) do
+ PivotaltrackerService.new.tap do |service|
+ service.token = 'secret_api_token'
+ end
+ end
+
+ let(:url) { PivotaltrackerService::API_ENDPOINT }
+
+ def push_data(branch: 'master')
+ {
+ object_kind: 'push',
+ ref: "refs/heads/#{branch}",
+ commits: [
+ {
+ id: '21c12ea',
+ author: {
+ name: 'Some User'
+ },
+ url: 'https://example.com/commit',
+ message: 'commit message',
+ }
+ ]
+ }
+ end
+
+ before do
+ WebMock.stub_request(:post, url)
+ end
+
+ it 'should post correct message' do
+ service.execute(push_data)
+ expect(WebMock).to have_requested(:post, url).with(
+ body: {
+ 'source_commit' => {
+ 'commit_id' => '21c12ea',
+ 'author' => 'Some User',
+ 'url' => 'https://example.com/commit',
+ 'message' => 'commit message'
+ }
+ },
+ headers: {
+ 'Content-Type' => 'application/json',
+ 'X-TrackerToken' => 'secret_api_token'
+ }
+ ).once
+ end
+
+ context 'when allowed branches is specified' do
+ let(:service) do
+ super().tap do |service|
+ service.restrict_to_branch = 'master,v10'
+ end
+ end
+
+ it 'should post message if branch is in the list' do
+ service.execute(push_data(branch: 'master'))
+ service.execute(push_data(branch: 'v10'))
+
+ expect(WebMock).to have_requested(:post, url).twice
+ end
+
+ it 'should not post message if branch is not in the list' do
+ service.execute(push_data(branch: 'mas'))
+ service.execute(push_data(branch: 'v11'))
+
+ expect(WebMock).not_to have_requested(:post, url)
+ end
+ end
+ end
end
diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb
index 19c0270a493..5959c81577d 100644
--- a/spec/models/project_services/pushover_service_spec.rb
+++ b/spec/models/project_services/pushover_service_spec.rb
@@ -48,7 +48,9 @@ describe PushoverService, models: true do
let(:pushover) { PushoverService.new }
let(:user) { create(:user) }
let(:project) { create(:project) }
- let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:sample_data) do
+ Gitlab::DataBuilder::Push.build_sample(project, user)
+ end
let(:api_key) { 'verySecret' }
let(:user_key) { 'verySecret' }
diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb
index 45a5f4ef12a..28af68d13b4 100644
--- a/spec/models/project_services/slack_service_spec.rb
+++ b/spec/models/project_services/slack_service_spec.rb
@@ -45,7 +45,9 @@ describe SlackService, models: true do
let(:slack) { SlackService.new }
let(:user) { create(:user) }
let(:project) { create(:project) }
- let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:push_sample_data) do
+ Gitlab::DataBuilder::Push.build_sample(project, user)
+ end
let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' }
let(:username) { 'slack_username' }
let(:channel) { 'slack_channel' }
@@ -195,7 +197,7 @@ describe SlackService, models: true do
it "uses the right channel" do
slack.update_attributes(note_channel: "random")
- note_data = Gitlab::NoteDataBuilder.build(issue_note, user)
+ note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
@@ -235,7 +237,7 @@ describe SlackService, models: true do
end
it "calls Slack API for commit comment events" do
- data = Gitlab::NoteDataBuilder.build(commit_note, user)
+ data = Gitlab::DataBuilder::Note.build(commit_note, user)
slack.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
@@ -249,7 +251,7 @@ describe SlackService, models: true do
end
it "calls Slack API for merge request comment events" do
- data = Gitlab::NoteDataBuilder.build(merge_request_note, user)
+ data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
slack.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
@@ -262,7 +264,7 @@ describe SlackService, models: true do
end
it "calls Slack API for issue comment events" do
- data = Gitlab::NoteDataBuilder.build(issue_note, user)
+ data = Gitlab::DataBuilder::Note.build(issue_note, user)
slack.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
@@ -276,7 +278,7 @@ describe SlackService, models: true do
end
it "calls Slack API for snippet comment events" do
- data = Gitlab::NoteDataBuilder.build(snippet_note, user)
+ data = Gitlab::DataBuilder::Note.build(snippet_note, user)
slack.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 9c3b4712cab..0a32a486703 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1089,13 +1089,13 @@ describe Project, models: true do
let(:project) { create(:project) }
it 'returns true when the branch matches a protected branch via direct match' do
- project.protected_branches.create!(name: 'foo')
+ create(:protected_branch, project: project, name: "foo")
expect(project.protected_branch?('foo')).to eq(true)
end
it 'returns true when the branch matches a protected branch via wildcard match' do
- project.protected_branches.create!(name: 'production/*')
+ create(:protected_branch, project: project, name: "production/*")
expect(project.protected_branch?('production/some-branch')).to eq(true)
end
@@ -1105,7 +1105,7 @@ describe Project, models: true do
end
it 'returns false when the branch does not match a protected branch via wildcard match' do
- project.protected_branches.create!(name: 'production/*')
+ create(:protected_branch, project: project, name: "production/*")
expect(project.protected_branch?('staging/some-branch')).to eq(false)
end
diff --git a/spec/models/user_agent_detail_spec.rb b/spec/models/user_agent_detail_spec.rb
new file mode 100644
index 00000000000..a8c25766e73
--- /dev/null
+++ b/spec/models/user_agent_detail_spec.rb
@@ -0,0 +1,31 @@
+require 'rails_helper'
+
+describe UserAgentDetail, type: :model do
+ describe '.submittable?' do
+ it 'is submittable when not already submitted' do
+ detail = build(:user_agent_detail)
+
+ expect(detail.submittable?).to be_truthy
+ end
+
+ it 'is not submittable when already submitted' do
+ detail = build(:user_agent_detail, submitted: true)
+
+ expect(detail.submittable?).to be_falsey
+ end
+ end
+
+ describe '.valid?' do
+ it 'is valid with a subject' do
+ detail = build(:user_agent_detail)
+
+ expect(detail).to be_valid
+ end
+
+ it 'is invalid without a subject' do
+ detail = build(:user_agent_detail, subject: nil)
+
+ expect(detail).not_to be_valid
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index f67acbbef37..54505f6b822 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -895,7 +895,9 @@ describe User, models: true do
subject { create(:user) }
let!(:project1) { create(:project) }
let!(:project2) { create(:project, forked_from_project: project1) }
- let!(:push_data) { Gitlab::PushDataBuilder.build_sample(project2, subject) }
+ let!(:push_data) do
+ Gitlab::DataBuilder::Push.build_sample(project2, subject)
+ end
let!(:push_event) { create(:event, action: Event::PUSHED, project: project2, target: project1, author: subject, data: push_data) }
before do
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 9444138f93d..3fd989dd7a6 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -243,7 +243,7 @@ describe API::API, api: true do
end
it "removes protected branch" do
- project.protected_branches.create(name: branch_name)
+ create(:protected_branch, project: project, name: branch_name)
delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user)
expect(response).to have_http_status(405)
expect(json_response['message']).to eq('Protected branch cant be removed')
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 3cd4e981fb2..a40e1a93b71 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -531,8 +531,8 @@ describe API::API, api: true do
describe 'POST /projects/:id/issues with spam filtering' do
before do
- allow_any_instance_of(Gitlab::AkismetHelper).to receive(:check_for_spam?).and_return(true)
- allow_any_instance_of(Gitlab::AkismetHelper).to receive(:is_spam?).and_return(true)
+ allow_any_instance_of(SpamService).to receive(:check_for_spam?).and_return(true)
+ allow_any_instance_of(AkismetService).to receive_messages(is_spam?: true)
end
let(:params) do
@@ -554,7 +554,6 @@ describe API::API, api: true do
expect(spam_logs[0].description).to eq('content here')
expect(spam_logs[0].user).to eq(user)
expect(spam_logs[0].noteable_type).to eq('Issue')
- expect(spam_logs[0].project_id).to eq(project.id)
end
end
diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb
index 34fac297923..914e88c9487 100644
--- a/spec/requests/api/project_hooks_spec.rb
+++ b/spec/requests/api/project_hooks_spec.rb
@@ -7,9 +7,9 @@ describe API::API, 'ProjectHooks', api: true do
let!(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:hook) do
create(:project_hook,
- project: project, url: "http://example.com",
- push_events: true, merge_requests_events: true, tag_push_events: true,
- issues_events: true, note_events: true, build_events: true,
+ :all_events_enabled,
+ project: project,
+ url: 'http://example.com',
enable_ssl_verification: true)
end
@@ -33,6 +33,7 @@ describe API::API, 'ProjectHooks', api: true do
expect(json_response.first['tag_push_events']).to eq(true)
expect(json_response.first['note_events']).to eq(true)
expect(json_response.first['build_events']).to eq(true)
+ expect(json_response.first['pipeline_events']).to eq(true)
expect(json_response.first['enable_ssl_verification']).to eq(true)
end
end
@@ -91,6 +92,7 @@ describe API::API, 'ProjectHooks', api: true do
expect(json_response['tag_push_events']).to eq(false)
expect(json_response['note_events']).to eq(false)
expect(json_response['build_events']).to eq(false)
+ expect(json_response['pipeline_events']).to eq(false)
expect(json_response['enable_ssl_verification']).to eq(true)
end
diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb
index 68d0f41b489..5bd5b861792 100644
--- a/spec/requests/api/templates_spec.rb
+++ b/spec/requests/api/templates_spec.rb
@@ -3,50 +3,53 @@ require 'spec_helper'
describe API::Templates, api: true do
include ApiHelpers
- describe 'the Template Entity' do
- before { get api('/gitignores/Ruby') }
+ context 'global templates' do
+ 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
+ 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') }
+ 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
+ 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')
+ context 'requesting gitignores' do
+ describe 'GET /gitignores' do
+ it 'returns a list of available gitignore templates' do
+ get api('/gitignores')
- expect(response).to have_http_status(200)
- expect(json_response).to be_an Array
- expect(json_response.size).to be > 15
+ expect(response.status).to eq(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to be > 15
+ end
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')
+ 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).to have_http_status(200)
- expect(json_response).to be_an Array
- expect(json_response.first['name']).not_to be_nil
+ 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
- end
- describe 'GET /gitlab_ci_ymls/Ruby' do
- it 'adds a disclaimer on the top' do
- get api('/gitlab_ci_ymls/Ruby')
+ describe 'GET /gitlab_ci_ymls/Ruby' do
+ it 'adds a disclaimer on the top' do
+ get api('/gitlab_ci_ymls/Ruby')
- expect(response).to have_http_status(200)
- expect(json_response['content']).to start_with("# This file is a template,")
+ expect(response).to have_http_status(200)
+ expect(json_response['name']).not_to be_nil
+ expect(json_response['content']).to start_with("# This file is a template,")
+ end
end
end
end
diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb
index 3ccd0af652f..887a2ba5b84 100644
--- a/spec/requests/api/todos_spec.rb
+++ b/spec/requests/api/todos_spec.rb
@@ -117,6 +117,12 @@ describe API::Todos, api: true do
expect(response.status).to eq(200)
expect(pending_1.reload).to be_done
end
+
+ it 'updates todos cache' do
+ expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original
+
+ delete api("/todos/#{pending_1.id}", john_doe)
+ end
end
end
@@ -139,6 +145,12 @@ describe API::Todos, api: true do
expect(pending_2.reload).to be_done
expect(pending_3.reload).to be_done
end
+
+ it 'updates todos cache' do
+ expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original
+
+ delete api("/todos", john_doe)
+ end
end
end
diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb
new file mode 100644
index 00000000000..d019e50649f
--- /dev/null
+++ b/spec/services/files/update_service_spec.rb
@@ -0,0 +1,84 @@
+require "spec_helper"
+
+describe Files::UpdateService do
+ subject { described_class.new(project, user, commit_params) }
+
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:file_path) { 'files/ruby/popen.rb' }
+ let(:new_contents) { "New Content" }
+ let(:commit_params) do
+ {
+ file_path: file_path,
+ commit_message: "Update File",
+ file_content: new_contents,
+ file_content_encoding: "text",
+ last_commit_sha: last_commit_sha,
+ source_project: project,
+ source_branch: project.default_branch,
+ target_branch: project.default_branch,
+ }
+ end
+
+ before do
+ project.team << [user, :master]
+ end
+
+ describe "#execute" do
+ context "when the file's last commit sha does not match the supplied last_commit_sha" do
+ let(:last_commit_sha) { "foo" }
+
+ it "returns a hash with the correct error message and a :error status " do
+ expect { subject.execute }.
+ to raise_error(Files::UpdateService::FileChangedError,
+ "You are attempting to update a file that has changed since you started editing it.")
+ end
+ end
+
+ context "when the file's last commit sha does match the supplied last_commit_sha" do
+ let(:last_commit_sha) { Gitlab::Git::Commit.last_for_path(project.repository, project.default_branch, file_path).sha }
+
+ it "returns a hash with the :success status " do
+ results = subject.execute
+
+ expect(results).to match({ status: :success })
+ end
+
+ it "updates the file with the new contents" do
+ subject.execute
+
+ results = project.repository.blob_at_branch(project.default_branch, file_path)
+
+ expect(results.data).to eq(new_contents)
+ end
+ end
+
+ context "when the last_commit_sha is not supplied" do
+ let(:commit_params) do
+ {
+ file_path: file_path,
+ commit_message: "Update File",
+ file_content: new_contents,
+ file_content_encoding: "text",
+ source_project: project,
+ source_branch: project.default_branch,
+ target_branch: project.default_branch,
+ }
+ end
+
+ it "returns a hash with the :success status " do
+ results = subject.execute
+
+ expect(results).to match({ status: :success })
+ end
+
+ it "updates the file with the new contents" do
+ subject.execute
+
+ results = project.repository.blob_at_branch(project.default_branch, file_path)
+
+ expect(results.data).to eq(new_contents)
+ end
+ end
+ end
+end
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 80f6ebac86c..6ac1fa8f182 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -227,8 +227,8 @@ describe GitPushService, services: true do
expect(project.default_branch).to eq("master")
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
expect(project.protected_branches).not_to be_empty
- expect(project.protected_branches.first.push_access_level.access_level).to eq(Gitlab::Access::MASTER)
- expect(project.protected_branches.first.merge_access_level.access_level).to eq(Gitlab::Access::MASTER)
+ expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
+ expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
end
it "when pushing a branch for the first time with default branch protection disabled" do
@@ -249,8 +249,8 @@ describe GitPushService, services: true do
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
expect(project.protected_branches).not_to be_empty
- expect(project.protected_branches.last.push_access_level.access_level).to eq(Gitlab::Access::DEVELOPER)
- expect(project.protected_branches.last.merge_access_level.access_level).to eq(Gitlab::Access::MASTER)
+ expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
+ expect(project.protected_branches.last.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
end
it "when pushing a branch for the first time with default branch protection set to 'developers can merge'" do
@@ -260,8 +260,8 @@ describe GitPushService, services: true do
expect(project.default_branch).to eq("master")
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
expect(project.protected_branches).not_to be_empty
- expect(project.protected_branches.first.push_access_level.access_level).to eq(Gitlab::Access::MASTER)
- expect(project.protected_branches.first.merge_access_level.access_level).to eq(Gitlab::Access::DEVELOPER)
+ expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
+ expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
end
it "when pushing new commits to existing branch" do
diff --git a/spec/services/merge_requests/get_urls_service_spec.rb b/spec/services/merge_requests/get_urls_service_spec.rb
index ec26770c3eb..8a4b76367e3 100644
--- a/spec/services/merge_requests/get_urls_service_spec.rb
+++ b/spec/services/merge_requests/get_urls_service_spec.rb
@@ -7,7 +7,9 @@ describe MergeRequests::GetUrlsService do
let(:new_merge_request_url) { "http://localhost/#{project.namespace.name}/#{project.path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{source_branch}" }
let(:show_merge_request_url) { "http://localhost/#{project.namespace.name}/#{project.path}/merge_requests/#{merge_request.iid}" }
let(:new_branch_changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{source_branch}" }
+ let(:deleted_branch_changes) { "d14d6c0abdd253381df51a723d58691b2ee1ab08 #{Gitlab::Git::BLANK_SHA} refs/heads/#{source_branch}" }
let(:existing_branch_changes) { "d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{source_branch}" }
+ let(:default_branch_changes) { "d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master" }
describe "#execute" do
shared_examples 'new_merge_request_link' do
@@ -32,6 +34,28 @@ describe MergeRequests::GetUrlsService do
end
end
+ shared_examples 'no_merge_request_url' do
+ it 'returns no URL' do
+ result = service.execute(changes)
+ expect(result).to be_empty
+ end
+ end
+
+ context 'pushing to default branch' do
+ let(:changes) { default_branch_changes }
+ it_behaves_like 'no_merge_request_url'
+ end
+
+ context 'pushing to project with MRs disabled' do
+ let(:changes) { new_branch_changes }
+
+ before do
+ project.merge_requests_enabled = false
+ end
+
+ it_behaves_like 'no_merge_request_url'
+ end
+
context 'pushing one completely new branch' do
let(:changes) { new_branch_changes }
it_behaves_like 'new_merge_request_link'
@@ -42,6 +66,11 @@ describe MergeRequests::GetUrlsService do
it_behaves_like 'new_merge_request_link'
end
+ context 'pushing to deleted branch' do
+ let(:changes) { deleted_branch_changes }
+ it_behaves_like 'no_merge_request_url'
+ end
+
context 'pushing to existing branch and merge request opened' do
let!(:merge_request) { create(:merge_request, source_project: project, source_branch: source_branch) }
let(:changes) { existing_branch_changes }
@@ -61,6 +90,11 @@ describe MergeRequests::GetUrlsService do
let(:changes) { existing_branch_changes }
# Source project is now the forked one
let(:service) { MergeRequests::GetUrlsService.new(forked_project) }
+
+ before do
+ allow(forked_project).to receive(:empty_repo?).and_return(false)
+ end
+
it_behaves_like 'show_merge_request_url'
end
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 4c41df0d4f5..0815da8826a 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -484,6 +484,42 @@ describe TodoService, services: true do
expect(john_doe.todos_pending_count).to eq(1)
end
+ describe '#mark_todos_as_done' do
+ let(:issue) { create(:issue, project: project, author: author, assignee: john_doe) }
+
+ it 'marks a relation of todos as done' do
+ create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+
+ todos = TodosFinder.new(john_doe, {}).execute
+ expect { TodoService.new.mark_todos_as_done(todos, john_doe) }
+ .to change { john_doe.todos.done.count }.from(0).to(1)
+ end
+
+ it 'marks an array of todos as done' do
+ todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+
+ expect { TodoService.new.mark_todos_as_done([todo], john_doe) }
+ .to change { todo.reload.state }.from('pending').to('done')
+ end
+
+ it 'returns the number of updated todos' do # Needed on API
+ todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+
+ expect(TodoService.new.mark_todos_as_done([todo], john_doe)).to eq(1)
+ end
+
+ it 'caches the number of todos of a user', :caching do
+ create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ TodoService.new.mark_todos_as_done([todo], john_doe)
+
+ expect_any_instance_of(TodosFinder).not_to receive(:execute)
+
+ expect(john_doe.todos_done_count).to eq(1)
+ expect(john_doe.todos_pending_count).to eq(1)
+ end
+ end
+
def should_create_todo(attributes = {})
attributes.reverse_merge!(
project: project,
diff --git a/spec/support/import_export/import_export.yml b/spec/support/import_export/import_export.yml
index 3ceec506401..17136dee000 100644
--- a/spec/support/import_export/import_export.yml
+++ b/spec/support/import_export/import_export.yml
@@ -7,6 +7,8 @@ project_tree:
- :merge_request_test
- commit_statuses:
- :commit
+ - project_members:
+ - :user
included_attributes:
project:
@@ -14,6 +16,8 @@ included_attributes:
- :path
merge_requests:
- :id
+ user:
+ - :email
excluded_attributes:
merge_requests:
diff --git a/spec/views/projects/merge_requests/_heading.html.haml_spec.rb b/spec/views/projects/merge_requests/_heading.html.haml_spec.rb
new file mode 100644
index 00000000000..733b2dfa7ff
--- /dev/null
+++ b/spec/views/projects/merge_requests/_heading.html.haml_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe 'projects/merge_requests/widget/_heading' do
+ include Devise::TestHelpers
+
+ context 'when released to an environment' do
+ let(:project) { merge_request.target_project }
+ let(:merge_request) { create(:merge_request, :merged) }
+ let(:environment) { create(:environment, project: project) }
+ let!(:deployment) do
+ create(:deployment, environment: environment, sha: project.commit('master').id)
+ end
+
+ before do
+ assign(:merge_request, merge_request)
+ assign(:project, project)
+
+ render
+ end
+
+ it 'displays that the environment is deployed' do
+ expect(rendered).to match("Deployed to")
+ expect(rendered).to match("#{environment.name}")
+ end
+ end
+end
diff --git a/spec/workers/build_email_worker_spec.rb b/spec/workers/build_email_worker_spec.rb
index 98deae0a588..788b92c1b84 100644
--- a/spec/workers/build_email_worker_spec.rb
+++ b/spec/workers/build_email_worker_spec.rb
@@ -5,7 +5,7 @@ describe BuildEmailWorker do
let(:build) { create(:ci_build) }
let(:user) { create(:user) }
- let(:data) { Gitlab::BuildDataBuilder.build(build) }
+ let(:data) { Gitlab::DataBuilder::Build.build(build) }
subject { BuildEmailWorker.new }
diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb
index 796751efe8d..eecc32875a5 100644
--- a/spec/workers/emails_on_push_worker_spec.rb
+++ b/spec/workers/emails_on_push_worker_spec.rb
@@ -5,7 +5,7 @@ describe EmailsOnPushWorker do
let(:project) { create(:project) }
let(:user) { create(:user) }
- let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) }
+ let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
let(:recipients) { user.email }
let(:perform) { subject.perform(project.id, recipients, data.stringify_keys) }