summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorFatih Acet <acetfatih@gmail.com>2016-05-18 13:05:53 -0500
committerFatih Acet <acetfatih@gmail.com>2016-05-18 13:05:53 -0500
commitbb883387f9e4d5564b455cce7d412f730664a2f5 (patch)
tree02f972c30f9a01d605e2c88a22b2c7172694e475 /spec
parent7a4e7ad04e1fc96953d9159e8e1a2208990d34f7 (diff)
parentb7d83acf5b03e08dc9e387e1abb83c5e3c80444c (diff)
downloadgitlab-ce-bb883387f9e4d5564b455cce7d412f730664a2f5.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into awardables
# Conflicts: # app/controllers/projects/merge_requests_controller.rb # app/models/note.rb # db/schema.rb # spec/models/note_spec.rb
Diffstat (limited to 'spec')
-rw-r--r--spec/config/mail_room_spec.rb2
-rw-r--r--spec/controllers/admin/users_controller_spec.rb76
-rw-r--r--spec/controllers/health_check_controller_spec.rb105
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb2
-rw-r--r--spec/controllers/registrations_controller_spec.rb33
-rw-r--r--spec/controllers/users_controller_spec.rb22
-rw-r--r--spec/factories/notes.rb4
-rw-r--r--spec/features/admin/admin_builds_spec.rb1
-rw-r--r--spec/features/admin/admin_health_check_spec.rb55
-rw-r--r--spec/features/admin/admin_users_spec.rb3
-rw-r--r--spec/features/builds_spec.rb1
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb15
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb2
-rw-r--r--spec/features/signup_spec.rb45
-rw-r--r--spec/finders/issues_finder_spec.rb180
-rw-r--r--spec/helpers/auth_helper_spec.rb47
-rw-r--r--spec/helpers/events_helper_spec.rb95
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb85
-rw-r--r--spec/lib/ci/ansi2html_spec.rb111
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/branch_formatter_spec.rb71
-rw-r--r--spec/lib/gitlab/github_import/pull_request_formatter_spec.rb46
-rw-r--r--spec/lib/gitlab/lfs/lfs_router_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/instrumentation_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb16
-rw-r--r--spec/lib/json_web_token/rsa_token_spec.rb43
-rw-r--r--spec/lib/json_web_token/token_spec.rb18
-rw-r--r--spec/models/application_setting_spec.rb9
-rw-r--r--spec/models/commit_spec.rb2
-rw-r--r--spec/models/concerns/subscribable_spec.rb10
-rw-r--r--spec/models/hooks/service_hook_spec.rb4
-rw-r--r--spec/models/hooks/system_hook_spec.rb20
-rw-r--r--spec/models/legacy_diff_note_spec.rb74
-rw-r--r--spec/models/merge_request_spec.rb15
-rw-r--r--spec/models/milestone_spec.rb33
-rw-r--r--spec/models/note_spec.rb18
-rw-r--r--spec/models/project_services/slack_service/issue_message_spec.rb11
-rw-r--r--spec/models/project_services/slack_service/note_message_spec.rb4
-rw-r--r--spec/models/project_wiki_spec.rb3
-rw-r--r--spec/models/user_spec.rb1
-rw-r--r--spec/requests/api/builds_spec.rb4
-rw-r--r--spec/requests/api/group_members_spec.rb10
-rw-r--r--spec/requests/api/issues_spec.rb12
-rw-r--r--spec/requests/api/labels_spec.rb82
-rw-r--r--spec/requests/api/notes_spec.rb67
-rw-r--r--spec/requests/ci/api/builds_spec.rb4
-rw-r--r--spec/requests/jwt_controller_spec.rb72
-rw-r--r--spec/routing/admin_routing_spec.rb7
-rw-r--r--spec/routing/routing_spec.rb51
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb216
-rw-r--r--spec/services/projects/create_service_spec.rb4
-rw-r--r--spec/services/projects/destroy_service_spec.rb8
-rw-r--r--spec/support/jira_service_helper.rb10
-rw-r--r--spec/support/stub_gitlab_calls.rb20
55 files changed, 1579 insertions, 288 deletions
diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb
index 462afb24f08..6fad7e2b9e7 100644
--- a/spec/config/mail_room_spec.rb
+++ b/spec/config/mail_room_spec.rb
@@ -43,7 +43,7 @@ describe "mail_room.yml" do
redis_config_file = Rails.root.join('config', 'resque.yml')
redis_url =
- if File.exists?(redis_config_file)
+ if File.exist?(redis_config_file)
YAML.load_file(redis_config_file)[Rails.env]
else
"redis://localhost:6379"
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index ce2a62ae1fd..6caf37ddc2c 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -114,6 +114,82 @@ describe Admin::UsersController do
end
end
+ describe 'POST update' do
+ context 'when the password has changed' do
+ def update_password(user, password, password_confirmation = nil)
+ params = {
+ id: user.to_param,
+ user: {
+ password: password,
+ password_confirmation: password_confirmation || password
+ }
+ }
+
+ post :update, params
+ end
+
+ context 'when the new password is valid' do
+ it 'redirects to the user' do
+ update_password(user, 'AValidPassword1')
+
+ expect(response).to redirect_to(admin_user_path(user))
+ end
+
+ it 'updates the password' do
+ update_password(user, 'AValidPassword1')
+
+ expect { user.reload }.to change { user.encrypted_password }
+ end
+
+ it 'sets the new password to expire immediately' do
+ update_password(user, 'AValidPassword1')
+
+ expect { user.reload }.to change { user.password_expires_at }.to(a_value <= Time.now)
+ end
+ end
+
+ context 'when the new password is invalid' do
+ it 'shows the edit page again' do
+ update_password(user, 'invalid')
+
+ expect(response).to render_template(:edit)
+ end
+
+ it 'returns the error message' do
+ update_password(user, 'invalid')
+
+ expect(assigns[:user].errors).to contain_exactly(a_string_matching(/too short/))
+ end
+
+ it 'does not update the password' do
+ update_password(user, 'invalid')
+
+ expect { user.reload }.not_to change { user.encrypted_password }
+ end
+ end
+
+ context 'when the new password does not match the password confirmation' do
+ it 'shows the edit page again' do
+ update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+ expect(response).to render_template(:edit)
+ end
+
+ it 'returns the error message' do
+ update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+ expect(assigns[:user].errors).to contain_exactly(a_string_matching(/doesn't match/))
+ end
+
+ it 'does not update the password' do
+ update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+ expect { user.reload }.not_to change { user.encrypted_password }
+ end
+ end
+ end
+ end
+
describe "POST impersonate" do
context "when the user is blocked" do
before do
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
new file mode 100644
index 00000000000..0d8a68bb51a
--- /dev/null
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -0,0 +1,105 @@
+require 'spec_helper'
+
+describe HealthCheckController do
+ let(:token) { current_application_settings.health_check_access_token }
+ let(:json_response) { JSON.parse(response.body) }
+ let(:xml_response) { Hash.from_xml(response.body)['hash'] }
+
+ describe 'GET #index' do
+ context 'when services are up but NO access token' do
+ it 'returns a not found page' do
+ get :index
+ expect(response).to be_not_found
+ end
+ end
+
+ context 'when services are up and an access token is provided' do
+ it 'supports passing the token in the header' do
+ request.headers['TOKEN'] = token
+ get :index
+ expect(response).to be_success
+ expect(response.content_type).to eq 'text/plain'
+ end
+
+ it 'supports successful plaintest response' do
+ get :index, token: token
+ expect(response).to be_success
+ expect(response.content_type).to eq 'text/plain'
+ end
+
+ it 'supports successful json response' do
+ get :index, token: token, format: :json
+ expect(response).to be_success
+ expect(response.content_type).to eq 'application/json'
+ expect(json_response['healthy']).to be true
+ end
+
+ it 'supports successful xml response' do
+ get :index, token: token, format: :xml
+ expect(response).to be_success
+ expect(response.content_type).to eq 'application/xml'
+ expect(xml_response['healthy']).to be true
+ end
+
+ it 'supports successful responses for specific checks' do
+ get :index, token: token, checks: 'email', format: :json
+ expect(response).to be_success
+ expect(response.content_type).to eq 'application/json'
+ expect(json_response['healthy']).to be true
+ end
+ end
+
+ context 'when a service is down but NO access token' do
+ it 'returns a not found page' do
+ get :index
+ expect(response).to be_not_found
+ end
+ end
+
+ context 'when a service is down and an access token is provided' do
+ before do
+ allow(HealthCheck::Utils).to receive(:process_checks).with('standard').and_return('The server is on fire')
+ allow(HealthCheck::Utils).to receive(:process_checks).with('email').and_return('Email is on fire')
+ end
+
+ it 'supports passing the token in the header' do
+ request.headers['TOKEN'] = token
+ get :index
+ expect(response.status).to eq(500)
+ expect(response.content_type).to eq 'text/plain'
+ expect(response.body).to include('The server is on fire')
+ end
+
+ it 'supports failure plaintest response' do
+ get :index, token: token
+ expect(response.status).to eq(500)
+ expect(response.content_type).to eq 'text/plain'
+ expect(response.body).to include('The server is on fire')
+ end
+
+ it 'supports failure json response' do
+ get :index, token: token, format: :json
+ expect(response.status).to eq(500)
+ expect(response.content_type).to eq 'application/json'
+ expect(json_response['healthy']).to be false
+ expect(json_response['message']).to include('The server is on fire')
+ end
+
+ it 'supports failure xml response' do
+ get :index, token: token, format: :xml
+ expect(response.status).to eq(500)
+ expect(response.content_type).to eq 'application/xml'
+ expect(xml_response['healthy']).to be false
+ expect(xml_response['message']).to include('The server is on fire')
+ end
+
+ it 'supports failure responses for specific checks' do
+ get :index, token: token, checks: 'email', format: :json
+ expect(response.status).to eq(500)
+ expect(response.content_type).to eq 'application/json'
+ expect(json_response['healthy']).to be false
+ expect(json_response['message']).to include('Email is on fire')
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 1caa476d37d..fb29274c687 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -42,7 +42,7 @@ describe Projects::RawController do
before do
public_project.lfs_objects << lfs_object
allow_any_instance_of(LfsObjectUploader).to receive(:exists?).and_return(true)
- allow(controller).to receive(:send_file) { controller.render nothing: true }
+ allow(controller).to receive(:send_file) { controller.head :ok }
end
it 'serves the file' do
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
new file mode 100644
index 00000000000..df70a589a89
--- /dev/null
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe RegistrationsController do
+ describe '#create' do
+ around(:each) do |example|
+ perform_enqueued_jobs do
+ example.run
+ end
+ end
+
+ let(:user_params) { { user: { name: "new_user", username: "new_username", email: "new@user.com", password: "Any_password" } } }
+
+ context 'when sending email confirmation' do
+ before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(false) }
+
+ it 'logs user in directly' do
+ post(:create, user_params)
+ expect(ActionMailer::Base.deliveries.last).to be_nil
+ expect(subject.current_user).to_not be_nil
+ end
+ end
+
+ context 'when not sending email confirmation' do
+ before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(true) }
+
+ it 'does not authenticate user and sends confirmation email' do
+ post(:create, user_params)
+ expect(ActionMailer::Base.deliveries.last.to.first).to eq(user_params[:user][:email])
+ expect(subject.current_user).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 8045c8b940d..c61ec174665 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -112,4 +112,26 @@ describe UsersController do
expect(response).to render_template('calendar_activities')
end
end
+
+ describe 'GET #snippets' do
+ before do
+ sign_in(user)
+ end
+
+ context 'format html' do
+ it 'renders snippets page' do
+ get :snippets, username: user.username
+ expect(response.status).to eq(200)
+ expect(response).to render_template('show')
+ end
+ end
+
+ context 'format json' do
+ it 'response with snippets json data' do
+ get :snippets, username: user.username, format: :json
+ expect(response.status).to eq(200)
+ expect(JSON.parse(response.body)).to have_key('html')
+ end
+ end
+ end
end
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index e65204cbe7b..2603b4fb0ce 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -9,10 +9,10 @@ FactoryGirl.define do
author
factory :note_on_commit, traits: [:on_commit]
- factory :note_on_commit_diff, traits: [:on_commit, :on_diff]
+ factory :note_on_commit_diff, traits: [:on_commit, :on_diff], class: LegacyDiffNote
factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note]
factory :note_on_merge_request, traits: [:on_merge_request]
- factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
+ factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff], class: LegacyDiffNote
factory :note_on_project_snippet, traits: [:on_project_snippet]
factory :system_note, traits: [:system]
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index 2e9851fb442..7bbe20fec43 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -19,6 +19,7 @@ describe 'Admin Builds' do
visit admin_builds_path
expect(page).to have_selector('.nav-links li.active', text: 'All')
+ expect(page).to have_selector('.row-content-block', text: 'All builds')
expect(page.all('.build-link').size).to eq(4)
expect(page).to have_link 'Cancel all'
end
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
new file mode 100644
index 00000000000..dec2dedf2b5
--- /dev/null
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+feature "Admin Health Check", feature: true do
+ include WaitForAjax
+
+ before do
+ login_as :admin
+ end
+
+ describe '#show' do
+ before do
+ visit admin_health_check_path
+ end
+
+ it { page.has_text? 'Health Check' }
+ it { page.has_text? 'Health information can be retrieved' }
+
+ it 'has a health check access token' do
+ token = current_application_settings.health_check_access_token
+ expect(page).to have_content("Access token is #{token}")
+ expect(page).to have_selector('#health-check-token', text: token)
+ end
+
+ describe 'reload access token', js: true do
+ it 'changes the access token' do
+ orig_token = current_application_settings.health_check_access_token
+ click_button 'Reset health check access token'
+ wait_for_ajax
+ expect(find('#health-check-token').text).not_to eq orig_token
+ end
+ end
+ end
+
+ context 'when services are up' do
+ before do
+ visit admin_health_check_path
+ end
+
+ it 'shows healthy status' do
+ expect(page).to have_content('Current Status: Healthy')
+ end
+ end
+
+ context 'when a service is down' do
+ before do
+ allow(HealthCheck::Utils).to receive(:process_checks).and_return('The server is on fire')
+ visit admin_health_check_path
+ end
+
+ it 'shows unhealthy status' do
+ expect(page).to have_content('Current Status: Unhealthy')
+ expect(page).to have_content('The server is on fire')
+ end
+ end
+end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 4570e409128..6dee0cd8d47 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -210,6 +210,8 @@ describe "Admin::Users", feature: true do
before do
fill_in "user_name", with: "Big Bang"
fill_in "user_email", with: "bigbang@mail.com"
+ fill_in "user_password", with: "AValidPassword1"
+ fill_in "user_password_confirmation", with: "AValidPassword1"
check "user_admin"
click_button "Save changes"
end
@@ -223,6 +225,7 @@ describe "Admin::Users", feature: true do
@simple_user.reload
expect(@simple_user.name).to eq('Big Bang')
expect(@simple_user.is_admin?).to be_truthy
+ expect(@simple_user.password_expires_at).to be <= Time.now
end
end
end
diff --git a/spec/features/builds_spec.rb b/spec/features/builds_spec.rb
index 090a941958f..f83a78308e3 100644
--- a/spec/features/builds_spec.rb
+++ b/spec/features/builds_spec.rb
@@ -43,6 +43,7 @@ describe "Builds" do
end
it { expect(page).to have_selector('.nav-links li.active', text: 'All') }
+ it { expect(page).to have_selector('.row-content-block', text: 'All builds from this project') }
it { expect(page).to have_content @build.short_sha }
it { expect(page).to have_content @build.ref }
it { expect(page).to have_content @build.name }
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index cc7f78e7325..2c7e1c748ad 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -38,6 +38,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
expect(page).to have_content 'lfs'
expect(page).not_to have_content 'fix'
expect(page).not_to have_content 'markdown'
+ expect(count_merge_requests).to eq(1)
end
it 'filters on a specific assignee' do
@@ -46,6 +47,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
expect(page).not_to have_content 'lfs'
expect(page).to have_content 'fix'
expect(page).to have_content 'markdown'
+ expect(count_merge_requests).to eq(2)
end
it 'sorts by newest' do
@@ -53,6 +55,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
expect(first_merge_request).to include('lfs')
expect(last_merge_request).to include('fix')
+ expect(count_merge_requests).to eq(3)
end
it 'sorts by oldest' do
@@ -60,30 +63,35 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
expect(first_merge_request).to include('fix')
expect(last_merge_request).to include('lfs')
+ expect(count_merge_requests).to eq(3)
end
it 'sorts by last updated' do
visit_merge_requests(project, sort: sort_value_recently_updated)
expect(first_merge_request).to include('lfs')
+ expect(count_merge_requests).to eq(3)
end
it 'sorts by oldest updated' do
visit_merge_requests(project, sort: sort_value_oldest_updated)
expect(first_merge_request).to include('markdown')
+ expect(count_merge_requests).to eq(3)
end
it 'sorts by milestone due soon' do
visit_merge_requests(project, sort: sort_value_milestone_soon)
expect(first_merge_request).to include('fix')
+ expect(count_merge_requests).to eq(3)
end
it 'sorts by milestone due later' do
visit_merge_requests(project, sort: sort_value_milestone_later)
expect(first_merge_request).to include('markdown')
+ expect(count_merge_requests).to eq(3)
end
it 'filters on one label and sorts by due soon' do
@@ -94,6 +102,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
sort: sort_value_due_date_soon)
expect(first_merge_request).to include('fix')
+ expect(count_merge_requests).to eq(1)
end
context 'while filtering on two labels' do
@@ -110,6 +119,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
sort: sort_value_due_date_soon)
expect(first_merge_request).to include('fix')
+ expect(count_merge_requests).to eq(1)
end
context 'filter on assignee and' do
@@ -119,6 +129,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
sort: sort_value_due_date_soon)
expect(first_merge_request).to include('fix')
+ expect(count_merge_requests).to eq(1)
end
end
end
@@ -134,4 +145,8 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
def last_merge_request
page.all('ul.mr-list > li').last.text
end
+
+ def count_merge_requests
+ page.all('ul.mr-list > li').count
+ end
end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index 9e2bdd7f5bb..663b02e4bd3 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -192,7 +192,7 @@ describe 'Comments', feature: true do
end
it 'should be removed when canceled' do
- page.within(".diff-file form[id$='#{line_code}']") do
+ page.within(".diff-file form[id$='#{line_code}-true']") do
find('.js-close-discussion-note-form').trigger('click')
end
diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb
index 58aabd913eb..4229e82b443 100644
--- a/spec/features/signup_spec.rb
+++ b/spec/features/signup_spec.rb
@@ -2,20 +2,45 @@ require 'spec_helper'
feature 'Signup', feature: true do
describe 'signup with no errors' do
- it 'creates the user account and sends a confirmation email' do
- user = build(:user)
- visit root_path
+ context "when sending confirmation email" do
+ before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) }
- fill_in 'new_user_name', with: user.name
- fill_in 'new_user_username', with: user.username
- fill_in 'new_user_email', with: user.email
- fill_in 'new_user_password', with: user.password
- click_button "Sign up"
+ it 'creates the user account and sends a confirmation email' do
+ user = build(:user)
+
+ visit root_path
+
+ fill_in 'new_user_name', with: user.name
+ fill_in 'new_user_username', with: user.username
+ fill_in 'new_user_email', with: user.email
+ fill_in 'new_user_password', with: user.password
+ click_button "Sign up"
- expect(current_path).to eq users_almost_there_path
- expect(page).to have_content("Please check your email to confirm your account")
+ expect(current_path).to eq users_almost_there_path
+ expect(page).to have_content("Please check your email to confirm your account")
+ end
end
+
+ context "when not sending confirmation email" do
+ before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false) }
+
+ it 'creates the user account and goes to dashboard' do
+ user = build(:user)
+
+ visit root_path
+
+ fill_in 'new_user_name', with: user.name
+ fill_in 'new_user_username', with: user.username
+ fill_in 'new_user_email', with: user.email
+ fill_in 'new_user_password', with: user.password
+ click_button "Sign up"
+
+ expect(current_path).to eq dashboard_projects_path
+ expect(page).to have_content("Welcome! You have signed up successfully.")
+ end
+ end
+
end
describe 'signup with errors' do
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index bc607a29751..ec8809e6926 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -1,10 +1,10 @@
require 'spec_helper'
describe IssuesFinder do
- let(:user) { create :user }
- let(:user2) { create :user }
- let(:project1) { create(:project) }
- let(:project2) { create(:project) }
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:project1) { create(:empty_project) }
+ let(:project2) { create(:empty_project) }
let(:milestone) { create(:milestone, project: project1) }
let(:label) { create(:label, project: project2) }
let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) }
@@ -16,101 +16,147 @@ describe IssuesFinder do
project1.team << [user, :master]
project2.team << [user, :developer]
project2.team << [user2, :developer]
+
+ issue1
+ issue2
+ issue3
end
- describe :execute do
- before :each do
- issue1
- issue2
- issue3
- end
+ describe '#execute' do
+ let(:search_user) { user }
+ let(:params) { {} }
+ let(:issues) { IssuesFinder.new(search_user, params.merge(scope: scope, state: 'opened')).execute }
context 'scope: all' do
- it 'should filter by all' do
- params = { scope: "all", state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues.size).to eq(3)
+ let(:scope) { 'all' }
+
+ it 'returns all issues' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3)
end
- it 'should filter by assignee id' do
- params = { scope: "all", assignee_id: user.id, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues.size).to eq(2)
+ context 'filtering by assignee ID' do
+ let(:params) { { assignee_id: user.id } }
+
+ it 'returns issues assigned to that user' do
+ expect(issues).to contain_exactly(issue1, issue2)
+ end
end
- it 'should filter by author id' do
- params = { scope: "all", author_id: user2.id, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues).to eq([issue3])
+ context 'filtering by author ID' do
+ let(:params) { { author_id: user2.id } }
+
+ it 'returns issues created by that user' do
+ expect(issues).to contain_exactly(issue3)
+ end
end
- it 'should filter by milestone id' do
- params = { scope: "all", milestone_title: milestone.title, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues).to eq([issue1])
+ context 'filtering by milestone' do
+ let(:params) { { milestone_title: milestone.title } }
+
+ it 'returns issues assigned to that milestone' do
+ expect(issues).to contain_exactly(issue1)
+ end
end
- it 'should filter by no milestone id' do
- params = { scope: "all", milestone_title: Milestone::None.title, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues).to match_array([issue2, issue3])
+ context 'filtering by no milestone' do
+ let(:params) { { milestone_title: Milestone::None.title } }
+
+ it 'returns issues with no milestone' do
+ expect(issues).to contain_exactly(issue2, issue3)
+ end
end
- it 'should filter by label name' do
- params = { scope: "all", label_name: label.title, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues).to eq([issue2])
+ context 'filtering by upcoming milestone' do
+ let(:params) { { milestone_title: Milestone::Upcoming.name } }
+
+ let(:project_no_upcoming_milestones) { create(:empty_project, :public) }
+ let(:project_next_1_1) { create(:empty_project, :public) }
+ let(:project_next_8_8) { create(:empty_project, :public) }
+
+ let(:yesterday) { Date.today - 1.day }
+ let(:tomorrow) { Date.today + 1.day }
+ let(:two_days_from_now) { Date.today + 2.days }
+ let(:ten_days_from_now) { Date.today + 10.days }
+
+ let(:milestones) do
+ [
+ create(:milestone, :closed, project: project_no_upcoming_milestones),
+ create(:milestone, project: project_next_1_1, title: '1.1', due_date: two_days_from_now),
+ create(:milestone, project: project_next_1_1, title: '8.8', due_date: ten_days_from_now),
+ create(:milestone, project: project_next_8_8, title: '1.1', due_date: yesterday),
+ create(:milestone, project: project_next_8_8, title: '8.8', due_date: tomorrow)
+ ]
+ end
+
+ before do
+ milestones.each do |milestone|
+ create(:issue, project: milestone.project, milestone: milestone, author: user, assignee: user)
+ end
+ end
+
+ it 'returns issues in the upcoming milestone for each project' do
+ expect(issues.map { |issue| issue.milestone.title }).to contain_exactly('1.1', '8.8')
+ expect(issues.map { |issue| issue.milestone.due_date }).to contain_exactly(tomorrow, two_days_from_now)
+ end
end
- it 'returns unique issues when filtering by multiple labels' do
- label2 = create(:label, project: project2)
+ context 'filtering by label' do
+ let(:params) { { label_name: label.title } }
- create(:label_link, label: label2, target: issue2)
+ it 'returns issues with that label' do
+ expect(issues).to contain_exactly(issue2)
+ end
+ end
- params = {
- scope: 'all',
- label_name: [label.title, label2.title].join(','),
- state: 'opened'
- }
+ context 'filtering by multiple labels' do
+ let(:params) { { label_name: [label.title, label2.title].join(',') } }
+ let(:label2) { create(:label, project: project2) }
- issues = IssuesFinder.new(user, params).execute
+ before { create(:label_link, label: label2, target: issue2) }
- expect(issues).to eq([issue2])
+ it 'returns the unique issues with any of those labels' do
+ expect(issues).to contain_exactly(issue2)
+ end
end
- it 'should filter by no label name' do
- params = { scope: "all", label_name: Label::None.title, state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues).to match_array([issue1, issue3])
+ context 'filtering by no label' do
+ let(:params) { { label_name: Label::None.title } }
+
+ it 'returns issues with no labels' do
+ expect(issues).to contain_exactly(issue1, issue3)
+ end
end
- it 'should be empty for unauthorized user' do
- params = { scope: "all", state: 'opened' }
- issues = IssuesFinder.new(nil, params).execute
- expect(issues.size).to be_zero
+ context 'when the user is unauthorized' do
+ let(:search_user) { nil }
+
+ it 'returns no results' do
+ expect(issues).to be_empty
+ end
end
- it 'should not include unauthorized issues' do
- params = { scope: "all", state: 'opened' }
- issues = IssuesFinder.new(user2, params).execute
- expect(issues.size).to eq(2)
- expect(issues).not_to include(issue1)
- expect(issues).to include(issue2)
- expect(issues).to include(issue3)
+ context 'when the user can see some, but not all, issues' do
+ let(:search_user) { user2 }
+
+ it 'returns only issues they can see' do
+ expect(issues).to contain_exactly(issue2, issue3)
+ end
end
end
context 'personal scope' do
- it 'should filter by assignee' do
- params = { scope: "assigned-to-me", state: 'opened' }
- issues = IssuesFinder.new(user, params).execute
- expect(issues.size).to eq(2)
+ let(:scope) { 'assigned-to-me' }
+
+ it 'returns issue assigned to the user' do
+ expect(issues).to contain_exactly(issue1, issue2)
end
- it 'should filter by project' do
- params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id }
- issues = IssuesFinder.new(user, params).execute
- expect(issues.size).to eq(1)
+ context 'filtering by project' do
+ let(:params) { { project_id: project1.id } }
+
+ it 'returns issues assigned to the user in that project' do
+ expect(issues).to contain_exactly(issue1)
+ end
end
end
end
diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb
index e47a54fdac5..16fbb5dcecb 100644
--- a/spec/helpers/auth_helper_spec.rb
+++ b/spec/helpers/auth_helper_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe AuthHelper do
describe "button_based_providers" do
- it 'returns all enabled providers' do
+ it 'returns all enabled providers from devise' do
allow(helper).to receive(:auth_providers) { [:twitter, :github] }
expect(helper.button_based_providers).to include(*[:twitter, :github])
end
@@ -17,4 +17,49 @@ describe AuthHelper do
expect(helper.button_based_providers).to eq([])
end
end
+
+ describe 'enabled_button_based_providers' do
+ before do
+ allow(helper).to receive(:auth_providers) { [:twitter, :github] }
+ end
+
+ context 'all providers are enabled to sign in' do
+ it 'returns all the enabled providers from settings' do
+ expect(helper.enabled_button_based_providers).to include('twitter', 'github')
+ end
+ end
+
+ context 'GitHub OAuth sign in is disabled from application setting' do
+ it "doesn't return github as provider" do
+ stub_application_setting(
+ disabled_oauth_sign_in_sources: ['github']
+ )
+
+ expect(helper.enabled_button_based_providers).to include('twitter')
+ expect(helper.enabled_button_based_providers).to_not include('github')
+ end
+ end
+ end
+
+ describe 'button_based_providers_enabled?' do
+ before do
+ allow(helper).to receive(:auth_providers) { [:twitter, :github] }
+ end
+
+ context 'button based providers enabled' do
+ it 'returns true' do
+ expect(helper.button_based_providers_enabled?).to be true
+ end
+ end
+
+ context 'all the button based providers are disabled via application_setting' do
+ it 'returns false' do
+ stub_application_setting(
+ disabled_oauth_sign_in_sources: ['github', 'twitter']
+ )
+
+ expect(helper.button_based_providers_enabled?).to be false
+ end
+ end
+ end
end
diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb
index e68a5ec29ab..c0d2be98e85 100644
--- a/spec/helpers/events_helper_spec.rb
+++ b/spec/helpers/events_helper_spec.rb
@@ -1,64 +1,65 @@
require 'spec_helper'
describe EventsHelper do
- include ApplicationHelper
- include GitlabMarkdownHelper
+ describe '#event_note' do
+ before do
+ allow(helper).to receive(:current_user).and_return(double)
+ end
- let(:current_user) { create(:user, email: "current@email.com") }
+ it 'should display one line of plain text without alteration' do
+ input = 'A short, plain note'
+ expect(helper.event_note(input)).to match(input)
+ expect(helper.event_note(input)).not_to match(/\.\.\.\z/)
+ end
- it 'should display one line of plain text without alteration' do
- input = 'A short, plain note'
- expect(event_note(input)).to match(input)
- expect(event_note(input)).not_to match(/\.\.\.\z/)
- end
+ it 'should display inline code' do
+ input = 'A note with `inline code`'
+ expected = 'A note with <code>inline code</code>'
- it 'should display inline code' do
- input = 'A note with `inline code`'
- expected = 'A note with <code>inline code</code>'
+ expect(helper.event_note(input)).to match(expected)
+ end
- expect(event_note(input)).to match(expected)
- end
+ it 'should truncate a note with multiple paragraphs' do
+ input = "Paragraph 1\n\nParagraph 2"
+ expected = 'Paragraph 1...'
- it 'should truncate a note with multiple paragraphs' do
- input = "Paragraph 1\n\nParagraph 2"
- expected = 'Paragraph 1...'
+ expect(helper.event_note(input)).to match(expected)
+ end
- expect(event_note(input)).to match(expected)
- end
+ it 'should display the first line of a code block' do
+ input = "```\nCode block\nwith two lines\n```"
+ expected = %r{<pre.+><code>Code block\.\.\.</code></pre>}
- it 'should display the first line of a code block' do
- input = "```\nCode block\nwith two lines\n```"
- expected = %r{<pre.+><code>Code block\.\.\.</code></pre>}
+ expect(helper.event_note(input)).to match(expected)
+ end
- expect(event_note(input)).to match(expected)
- end
+ it 'should truncate a single long line of text' do
+ text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars
+ input = text * 4
+ expected = (text * 2).sub(/.{3}/, '...')
- it 'should truncate a single long line of text' do
- text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars
- input = "#{text}#{text}#{text}#{text}" # 200 chars
- expected = "#{text}#{text}".sub(/.{3}/, '...')
+ expect(helper.event_note(input)).to match(expected)
+ end
- expect(event_note(input)).to match(expected)
- end
-
- it 'should preserve a link href when link text is truncated' do
- text = 'The quick brown fox jumped over the lazy dog' # 44 chars
- input = "#{text}#{text}#{text} " # 133 chars
- link_url = 'http://example.com/foo/bar/baz' # 30 chars
- input << link_url
- expected_link_text = 'http://example...</a>'
+ it 'should preserve a link href when link text is truncated' do
+ text = 'The quick brown fox jumped over the lazy dog' # 44 chars
+ input = "#{text}#{text}#{text} " # 133 chars
+ link_url = 'http://example.com/foo/bar/baz' # 30 chars
+ input << link_url
+ expected_link_text = 'http://example...</a>'
- expect(event_note(input)).to match(link_url)
- expect(event_note(input)).to match(expected_link_text)
- end
+ expect(helper.event_note(input)).to match(link_url)
+ expect(helper.event_note(input)).to match(expected_link_text)
+ end
- it 'should preserve code color scheme' do
- input = "```ruby\ndef test\n 'hello world'\nend\n```"
- expected = '<pre class="code highlight js-syntax-highlight ruby">' \
- "<code><span class=\"k\">def</span> <span class=\"nf\">test</span>\n" \
- " <span class=\"s1\">\'hello world\'</span>\n" \
- "<span class=\"k\">end</span>" \
- '</code></pre>'
- expect(event_note(input)).to eq(expected)
+ it 'should preserve code color scheme' do
+ input = "```ruby\ndef test\n 'hello world'\nend\n```"
+ expected = '<pre class="code highlight js-syntax-highlight ruby">' \
+ "<code><span class=\"k\">def</span> <span class=\"nf\">test</span>\n" \
+ " <span class=\"s1\">\'hello world\'</span>\n" \
+ "<span class=\"k\">end</span>" \
+ '</code></pre>'
+ expect(helper.event_note(input)).to eq(expected)
+ end
end
end
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
new file mode 100644
index 00000000000..185abbb2108
--- /dev/null
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+
+describe Banzai::Filter::WikiLinkFilter, lib: true do
+ include FilterSpecHelper
+
+ let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
+ let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) }
+ let(:user) { double }
+ let(:project_wiki) { ProjectWiki.new(project, user) }
+
+ describe "links within the wiki (relative)" do
+ describe "hierarchical links to the current directory" do
+ it "doesn't rewrite non-file links" do
+ link = "<a href='./page'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('./page')
+ end
+
+ it "doesn't rewrite file links" do
+ link = "<a href='./page.md'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('./page.md')
+ end
+ end
+
+ describe "hierarchical links to the parent directory" do
+ it "doesn't rewrite non-file links" do
+ link = "<a href='../page'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('../page')
+ end
+
+ it "doesn't rewrite file links" do
+ link = "<a href='../page.md'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('../page.md')
+ end
+ end
+
+ describe "hierarchical links to a sub-directory" do
+ it "doesn't rewrite non-file links" do
+ link = "<a href='./subdirectory/page'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('./subdirectory/page')
+ end
+
+ it "doesn't rewrite file links" do
+ link = "<a href='./subdirectory/page.md'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('./subdirectory/page.md')
+ end
+ end
+
+ describe "non-hierarchical links" do
+ it 'rewrites non-file links to be at the scope of the wiki root' do
+ link = "<a href='page'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to match('/wiki_link_ns/wiki_link_project/wikis/page')
+ end
+
+ it "doesn't rewrite file links" do
+ link = "<a href='page.md'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('page.md')
+ end
+ end
+ end
+
+ describe "links outside the wiki (absolute)" do
+ it "doesn't rewrite links" do
+ link = "<a href='http://example.com/page'>Link to Page</a>"
+ filtered_link = filter(link, project_wiki: project_wiki).children[0]
+
+ expect(filtered_link.attribute('href').value).to eq('http://example.com/page')
+ end
+ end
+end
diff --git a/spec/lib/ci/ansi2html_spec.rb b/spec/lib/ci/ansi2html_spec.rb
index 3a2b568f4c7..04afbd06929 100644
--- a/spec/lib/ci/ansi2html_spec.rb
+++ b/spec/lib/ci/ansi2html_spec.rb
@@ -4,131 +4,176 @@ describe Ci::Ansi2html, lib: true do
subject { Ci::Ansi2html }
it "prints non-ansi as-is" do
- expect(subject.convert("Hello")).to eq('Hello')
+ expect(subject.convert("Hello")[:html]).to eq('Hello')
end
it "strips non-color-changing controll sequences" do
- expect(subject.convert("Hello \e[2Kworld")).to eq('Hello world')
+ expect(subject.convert("Hello \e[2Kworld")[:html]).to eq('Hello world')
end
it "prints simply red" do
- expect(subject.convert("\e[31mHello\e[0m")).to eq('<span class="term-fg-red">Hello</span>')
+ expect(subject.convert("\e[31mHello\e[0m")[:html]).to eq('<span class="term-fg-red">Hello</span>')
end
it "prints simply red without trailing reset" do
- expect(subject.convert("\e[31mHello")).to eq('<span class="term-fg-red">Hello</span>')
+ expect(subject.convert("\e[31mHello")[:html]).to eq('<span class="term-fg-red">Hello</span>')
end
it "prints simply yellow" do
- expect(subject.convert("\e[33mHello\e[0m")).to eq('<span class="term-fg-yellow">Hello</span>')
+ expect(subject.convert("\e[33mHello\e[0m")[:html]).to eq('<span class="term-fg-yellow">Hello</span>')
end
it "prints default on blue" do
- expect(subject.convert("\e[39;44mHello")).to eq('<span class="term-bg-blue">Hello</span>')
+ expect(subject.convert("\e[39;44mHello")[:html]).to eq('<span class="term-bg-blue">Hello</span>')
end
it "prints red on blue" do
- expect(subject.convert("\e[31;44mHello")).to eq('<span class="term-fg-red term-bg-blue">Hello</span>')
+ expect(subject.convert("\e[31;44mHello")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span>')
end
it "resets colors after red on blue" do
- expect(subject.convert("\e[31;44mHello\e[0m world")).to eq('<span class="term-fg-red term-bg-blue">Hello</span> world')
+ expect(subject.convert("\e[31;44mHello\e[0m world")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span> world')
end
it "performs color change from red/blue to yellow/blue" do
- expect(subject.convert("\e[31;44mHello \e[33mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-blue">world</span>')
+ expect(subject.convert("\e[31;44mHello \e[33mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-blue">world</span>')
end
it "performs color change from red/blue to yellow/green" do
- expect(subject.convert("\e[31;44mHello \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-green">world</span>')
+ expect(subject.convert("\e[31;44mHello \e[33;42mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-fg-yellow term-bg-green">world</span>')
end
it "performs color change from red/blue to reset to yellow/green" do
- expect(subject.convert("\e[31;44mHello\e[0m \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello</span> <span class="term-fg-yellow term-bg-green">world</span>')
+ expect(subject.convert("\e[31;44mHello\e[0m \e[33;42mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello</span> <span class="term-fg-yellow term-bg-green">world</span>')
end
it "ignores unsupported codes" do
- expect(subject.convert("\e[51mHello\e[0m")).to eq('Hello')
+ expect(subject.convert("\e[51mHello\e[0m")[:html]).to eq('Hello')
end
it "prints light red" do
- expect(subject.convert("\e[91mHello\e[0m")).to eq('<span class="term-fg-l-red">Hello</span>')
+ expect(subject.convert("\e[91mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red">Hello</span>')
end
it "prints default on light red" do
- expect(subject.convert("\e[101mHello\e[0m")).to eq('<span class="term-bg-l-red">Hello</span>')
+ expect(subject.convert("\e[101mHello\e[0m")[:html]).to eq('<span class="term-bg-l-red">Hello</span>')
end
it "performs color change from red/blue to default/blue" do
- expect(subject.convert("\e[31;44mHello \e[39mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
+ expect(subject.convert("\e[31;44mHello \e[39mworld")[:html]).to eq('<span class="term-fg-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
end
it "performs color change from light red/blue to default/blue" do
- expect(subject.convert("\e[91;44mHello \e[39mworld")).to eq('<span class="term-fg-l-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
+ expect(subject.convert("\e[91;44mHello \e[39mworld")[:html]).to eq('<span class="term-fg-l-red term-bg-blue">Hello </span><span class="term-bg-blue">world</span>')
end
it "prints bold text" do
- expect(subject.convert("\e[1mHello")).to eq('<span class="term-bold">Hello</span>')
+ expect(subject.convert("\e[1mHello")[:html]).to eq('<span class="term-bold">Hello</span>')
end
it "resets bold text" do
- expect(subject.convert("\e[1mHello\e[21m world")).to eq('<span class="term-bold">Hello</span> world')
- expect(subject.convert("\e[1mHello\e[22m world")).to eq('<span class="term-bold">Hello</span> world')
+ expect(subject.convert("\e[1mHello\e[21m world")[:html]).to eq('<span class="term-bold">Hello</span> world')
+ expect(subject.convert("\e[1mHello\e[22m world")[:html]).to eq('<span class="term-bold">Hello</span> world')
end
it "prints italic text" do
- expect(subject.convert("\e[3mHello")).to eq('<span class="term-italic">Hello</span>')
+ expect(subject.convert("\e[3mHello")[:html]).to eq('<span class="term-italic">Hello</span>')
end
it "resets italic text" do
- expect(subject.convert("\e[3mHello\e[23m world")).to eq('<span class="term-italic">Hello</span> world')
+ expect(subject.convert("\e[3mHello\e[23m world")[:html]).to eq('<span class="term-italic">Hello</span> world')
end
it "prints underlined text" do
- expect(subject.convert("\e[4mHello")).to eq('<span class="term-underline">Hello</span>')
+ expect(subject.convert("\e[4mHello")[:html]).to eq('<span class="term-underline">Hello</span>')
end
it "resets underlined text" do
- expect(subject.convert("\e[4mHello\e[24m world")).to eq('<span class="term-underline">Hello</span> world')
+ expect(subject.convert("\e[4mHello\e[24m world")[:html]).to eq('<span class="term-underline">Hello</span> world')
end
it "prints concealed text" do
- expect(subject.convert("\e[8mHello")).to eq('<span class="term-conceal">Hello</span>')
+ expect(subject.convert("\e[8mHello")[:html]).to eq('<span class="term-conceal">Hello</span>')
end
it "resets concealed text" do
- expect(subject.convert("\e[8mHello\e[28m world")).to eq('<span class="term-conceal">Hello</span> world')
+ expect(subject.convert("\e[8mHello\e[28m world")[:html]).to eq('<span class="term-conceal">Hello</span> world')
end
it "prints crossed-out text" do
- expect(subject.convert("\e[9mHello")).to eq('<span class="term-cross">Hello</span>')
+ expect(subject.convert("\e[9mHello")[:html]).to eq('<span class="term-cross">Hello</span>')
end
it "resets crossed-out text" do
- expect(subject.convert("\e[9mHello\e[29m world")).to eq('<span class="term-cross">Hello</span> world')
+ expect(subject.convert("\e[9mHello\e[29m world")[:html]).to eq('<span class="term-cross">Hello</span> world')
end
it "can print 256 xterm fg colors" do
- expect(subject.convert("\e[38;5;16mHello")).to eq('<span class="xterm-fg-16">Hello</span>')
+ expect(subject.convert("\e[38;5;16mHello")[:html]).to eq('<span class="xterm-fg-16">Hello</span>')
end
it "can print 256 xterm fg colors on normal magenta background" do
- expect(subject.convert("\e[38;5;16;45mHello")).to eq('<span class="xterm-fg-16 term-bg-magenta">Hello</span>')
+ expect(subject.convert("\e[38;5;16;45mHello")[:html]).to eq('<span class="xterm-fg-16 term-bg-magenta">Hello</span>')
end
it "can print 256 xterm bg colors" do
- expect(subject.convert("\e[48;5;240mHello")).to eq('<span class="xterm-bg-240">Hello</span>')
+ expect(subject.convert("\e[48;5;240mHello")[:html]).to eq('<span class="xterm-bg-240">Hello</span>')
end
it "can print 256 xterm bg colors on normal magenta foreground" do
- expect(subject.convert("\e[48;5;16;35mHello")).to eq('<span class="term-fg-magenta xterm-bg-16">Hello</span>')
+ expect(subject.convert("\e[48;5;16;35mHello")[:html]).to eq('<span class="term-fg-magenta xterm-bg-16">Hello</span>')
end
it "prints bold colored text vividly" do
- expect(subject.convert("\e[1;31mHello\e[0m")).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
+ expect(subject.convert("\e[1;31mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
end
it "prints bold light colored text correctly" do
- expect(subject.convert("\e[1;91mHello\e[0m")).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
+ expect(subject.convert("\e[1;91mHello\e[0m")[:html]).to eq('<span class="term-fg-l-red term-bold">Hello</span>')
+ end
+
+ it "prints &lt;" do
+ expect(subject.convert("<")[:html]).to eq('&lt;')
+ end
+
+ describe "incremental update" do
+ shared_examples 'stateable converter' do
+ let(:pass1) { subject.convert(pre_text) }
+ let(:pass2) { subject.convert(pre_text + text, pass1[:state]) }
+
+ it "to returns html to append" do
+ expect(pass2[:append]).to be_truthy
+ expect(pass2[:html]).to eq(html)
+ expect(pass1[:text] + pass2[:text]).to eq(pre_text + text)
+ expect(pass1[:html] + pass2[:html]).to eq(pre_html + html)
+ end
+ end
+
+ context "with split word" do
+ let(:pre_text) { "\e[1mHello" }
+ let(:pre_html) { "<span class=\"term-bold\">Hello</span>" }
+ let(:text) { "\e[1mWorld" }
+ let(:html) { "<span class=\"term-bold\"></span><span class=\"term-bold\">World</span>" }
+
+ it_behaves_like 'stateable converter'
+ end
+
+ context "with split sequence" do
+ let(:pre_text) { "\e[1m" }
+ let(:pre_html) { "<span class=\"term-bold\"></span>" }
+ let(:text) { "Hello" }
+ let(:html) { "<span class=\"term-bold\">Hello</span>" }
+
+ it_behaves_like 'stateable converter'
+ end
+
+ context "with partial sequence" do
+ let(:pre_text) { "Hello\e" }
+ let(:pre_html) { "Hello" }
+ let(:text) { "[1m World" }
+ let(:html) { "<span class=\"term-bold\"> World</span>" }
+
+ it_behaves_like 'stateable converter'
+ end
end
end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index c7ab3185378..9eef8ea0976 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -443,12 +443,12 @@ module Ci
context 'when job variables are defined' do
context 'when syntax is correct' do
it 'returns job variables' do
- variables = {
+ variables = {
KEY1: 'value1',
SOME_KEY_2: 'value2'
}
- config = YAML.dump(
+ config = YAML.dump(
{ before_script: ['pwd'],
rspec: {
variables: variables,
diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
index acca0b08bab..46a5b7fce65 100644
--- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
@@ -10,8 +10,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
'path/dir_1/subdir/subfile' => { size: 10 },
'path/second_dir' => {},
'path/second_dir/dir_3/file_2' => { size: 10 },
- 'path/second_dir/dir_3/file_3'=> { size: 10 },
- 'another_directory/'=> {},
+ 'path/second_dir/dir_3/file_3' => { size: 10 },
+ 'another_directory/' => {},
'another_file' => {},
'/file/with/absolute_path' => {} }
end
diff --git a/spec/lib/gitlab/github_import/branch_formatter_spec.rb b/spec/lib/gitlab/github_import/branch_formatter_spec.rb
new file mode 100644
index 00000000000..3cb634ba010
--- /dev/null
+++ b/spec/lib/gitlab/github_import/branch_formatter_spec.rb
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe Gitlab::GithubImport::BranchFormatter, lib: true do
+ let(:project) { create(:project) }
+ let(:repo) { double }
+ let(:raw) do
+ {
+ ref: 'feature',
+ repo: repo,
+ sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b'
+ }
+ end
+
+ describe '#exists?' do
+ it 'returns true when branch exists' do
+ branch = described_class.new(project, double(raw))
+
+ expect(branch.exists?).to eq true
+ end
+
+ it 'returns false when branch does not exist' do
+ branch = described_class.new(project, double(raw.merge(ref: 'removed-branch')))
+
+ expect(branch.exists?).to eq false
+ end
+ end
+
+ describe '#name' do
+ it 'returns raw ref when branch exists' do
+ branch = described_class.new(project, double(raw))
+
+ expect(branch.name).to eq 'feature'
+ end
+
+ it 'returns formatted ref when branch does not exist' do
+ branch = described_class.new(project, double(raw.merge(ref: 'removed-branch')))
+
+ expect(branch.name).to eq 'removed-branch-2e5d3239'
+ end
+ end
+
+ describe '#repo' do
+ it 'returns raw repo' do
+ branch = described_class.new(project, double(raw))
+
+ expect(branch.repo).to eq repo
+ end
+ end
+
+ describe '#sha' do
+ it 'returns raw sha' do
+ branch = described_class.new(project, double(raw))
+
+ expect(branch.sha).to eq '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b'
+ end
+ end
+
+ describe '#valid?' do
+ it 'returns true when repository exists' do
+ branch = described_class.new(project, double(raw))
+
+ expect(branch.valid?).to eq true
+ end
+
+ it 'returns false when repository does not exist' do
+ branch = described_class.new(project, double(raw.merge(repo: nil)))
+
+ expect(branch.valid?).to eq false
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
index e59c0ca110e..120f59e6e71 100644
--- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
@@ -4,9 +4,9 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
let(:project) { create(:project) }
let(:repository) { double(id: 1, fork: false) }
let(:source_repo) { repository }
- let(:source_branch) { double(ref: 'feature', repo: source_repo) }
+ let(:source_branch) { double(ref: 'feature', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b') }
let(:target_repo) { repository }
- let(:target_branch) { double(ref: 'master', repo: target_repo) }
+ let(:target_branch) { double(ref: 'master', repo: target_repo, sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7') }
let(:octocat) { double(id: 123456, login: 'octocat') }
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
@@ -41,8 +41,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
description: "*Created by: octocat*\n\nPlease pull these awesome changes",
source_project: project,
source_branch: 'feature',
+ head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
target_project: project,
target_branch: 'master',
+ base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
state: 'opened',
milestone: nil,
author_id: project.creator_id,
@@ -66,8 +68,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
description: "*Created by: octocat*\n\nPlease pull these awesome changes",
source_project: project,
source_branch: 'feature',
+ head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
target_project: project,
target_branch: 'master',
+ base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
state: 'closed',
milestone: nil,
author_id: project.creator_id,
@@ -91,8 +95,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
description: "*Created by: octocat*\n\nPlease pull these awesome changes",
source_project: project,
source_branch: 'feature',
+ head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
target_project: project,
target_branch: 'master',
+ base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
state: 'merged',
milestone: nil,
author_id: project.creator_id,
@@ -137,11 +143,11 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
let(:milestone) { double(number: 45) }
let(:raw_data) { double(base_data.merge(milestone: milestone)) }
- it 'returns nil when milestone does not exists' do
+ it 'returns nil when milestone does not exist' do
expect(pull_request.attributes.fetch(:milestone)).to be_nil
end
- it 'returns milestone when is exists' do
+ it 'returns milestone when it exists' do
milestone = create(:milestone, project: project, iid: 45)
expect(pull_request.attributes.fetch(:milestone)).to eq milestone
@@ -158,36 +164,16 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
describe '#valid?' do
- let(:invalid_branch) { double(ref: 'invalid-branch').as_null_object }
-
- context 'when source, and target repositories are the same' do
- context 'and source and target branches exists' do
- let(:raw_data) { double(base_data.merge(head: source_branch, base: target_branch)) }
-
- it 'returns true' do
- expect(pull_request.valid?).to eq true
- end
- end
-
- context 'and source branch doesn not exists' do
- let(:raw_data) { double(base_data.merge(head: invalid_branch, base: target_branch)) }
-
- it 'returns false' do
- expect(pull_request.valid?).to eq false
- end
- end
-
- context 'and target branch doesn not exists' do
- let(:raw_data) { double(base_data.merge(head: source_branch, base: invalid_branch)) }
+ context 'when source, and target repos are not a fork' do
+ let(:raw_data) { double(base_data) }
- it 'returns false' do
- expect(pull_request.valid?).to eq false
- end
+ it 'returns true' do
+ expect(pull_request.valid?).to eq true
end
end
context 'when source repo is a fork' do
- let(:source_repo) { double(id: 2, fork: true) }
+ let(:source_repo) { double(id: 2) }
let(:raw_data) { double(base_data) }
it 'returns false' do
@@ -196,7 +182,7 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
end
context 'when target repo is a fork' do
- let(:target_repo) { double(id: 2, fork: true) }
+ let(:target_repo) { double(id: 2) }
let(:raw_data) { double(base_data) }
it 'returns false' do
diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb
index 5852b31ab3a..3325190789b 100644
--- a/spec/lib/gitlab/lfs/lfs_router_spec.rb
+++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb
@@ -26,8 +26,8 @@ describe Gitlab::Lfs::Router, lib: true do
let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" }
let(:sample_size) { 499013 }
- let(:respond_with_deprecated) {[ 501, { "Content-Type"=>"application/json; charset=utf-8" }, ["{\"message\":\"Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
- let(:respond_with_disabled) {[ 501, { "Content-Type"=>"application/json; charset=utf-8" }, ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
+ let(:respond_with_deprecated) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
+ let(:respond_with_disabled) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
describe 'when lfs is disabled' do
before do
diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb
index 5c885a7a982..7b86450a223 100644
--- a/spec/lib/gitlab/metrics/instrumentation_spec.rb
+++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb
@@ -56,9 +56,6 @@ describe Gitlab::Metrics::Instrumentation do
allow(described_class).to receive(:transaction).
and_return(transaction)
- expect(transaction).to receive(:increment).
- with(:method_duration, a_kind_of(Numeric))
-
expect(transaction).to receive(:add_metric).
with(described_class::SERIES, an_instance_of(Hash),
method: 'Dummy.foo')
@@ -139,9 +136,6 @@ describe Gitlab::Metrics::Instrumentation do
allow(described_class).to receive(:transaction).
and_return(transaction)
- expect(transaction).to receive(:increment).
- with(:method_duration, a_kind_of(Numeric))
-
expect(transaction).to receive(:add_metric).
with(described_class::SERIES, an_instance_of(Hash),
method: 'Dummy#bar')
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index e01b0b4bd21..d824dc54438 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_read' do
it 'increments the cache_read duration' do
expect(subscriber).to receive(:increment).
- with(:cache_read_duration, event.duration)
+ with(:cache_read, event.duration)
subscriber.cache_read(event)
end
@@ -18,7 +18,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_write' do
it 'increments the cache_write duration' do
expect(subscriber).to receive(:increment).
- with(:cache_write_duration, event.duration)
+ with(:cache_write, event.duration)
subscriber.cache_write(event)
end
@@ -27,7 +27,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_delete' do
it 'increments the cache_delete duration' do
expect(subscriber).to receive(:increment).
- with(:cache_delete_duration, event.duration)
+ with(:cache_delete, event.duration)
subscriber.cache_delete(event)
end
@@ -36,7 +36,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_exist?' do
it 'increments the cache_exists duration' do
expect(subscriber).to receive(:increment).
- with(:cache_exists_duration, event.duration)
+ with(:cache_exists, event.duration)
subscriber.cache_exist?(event)
end
@@ -62,9 +62,15 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
with(:cache_duration, event.duration)
expect(transaction).to receive(:increment).
+ with(:cache_count, 1)
+
+ expect(transaction).to receive(:increment).
with(:cache_delete_duration, event.duration)
- subscriber.increment(:cache_delete_duration, event.duration)
+ expect(transaction).to receive(:increment).
+ with(:cache_delete_count, 1)
+
+ subscriber.increment(:cache_delete, event.duration)
end
end
end
diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb
new file mode 100644
index 00000000000..0c3d3ea7019
--- /dev/null
+++ b/spec/lib/json_web_token/rsa_token_spec.rb
@@ -0,0 +1,43 @@
+describe JSONWebToken::RSAToken do
+ let(:rsa_key) do
+ OpenSSL::PKey::RSA.new <<-eos.strip_heredoc
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIBOgIBAAJBAMA5sXIBE0HwgIB40iNidN4PGWzOyLQK0bsdOBNgpEXkDlZBvnak
+ OUgAPF+rME4PB0Yl415DabUI40T5UNmlwxcCAwEAAQJAZtY2pSwIFm3JAXIh0cZZ
+ iXcAfiJ+YzuqinUOS+eW2sBCAEzjcARlU/o6sFQgtsOi4FOMczAd1Yx8UDMXMmrw
+ 2QIhAPBgVhJiTF09pdmeFWutCvTJDlFFAQNbrbo2X2x/9WF9AiEAzLgqMKeStSRu
+ H9N16TuDrUoO8R+DPqriCwkKrSHaWyMCIFzMhE4inuKcSywBaLmiG4m3GQzs++Al
+ A6PRG/PSTpQtAiBxtBg6zdf+JC3GH3zt/dA0/10tL4OF2wORfYQghRzyYQIhAL2l
+ 0ZQW+yLIZAGrdBFWYEAa52GZosncmzBNlsoTgwE4
+ -----END RSA PRIVATE KEY-----
+ eos
+ end
+ let(:rsa_token) { described_class.new(nil) }
+ let(:rsa_encoded) { rsa_token.encoded }
+
+ before { allow_any_instance_of(described_class).to receive(:key).and_return(rsa_key) }
+
+ context 'token' do
+ context 'for valid key to be validated' do
+ before { rsa_token['key'] = 'value' }
+
+ subject { JWT.decode(rsa_encoded, rsa_key) }
+
+ it { expect{subject}.to_not raise_error }
+ it { expect(subject.first).to include('key' => 'value') }
+ it do
+ expect(subject.second).to eq(
+ "typ" => "JWT",
+ "alg" => "RS256",
+ "kid" => "OGXY:4TR7:FAVO:WEM2:XXEW:E4FP:TKL7:7ACK:TZAF:D54P:SUIA:P3B2")
+ end
+ end
+
+ context 'for invalid key to raise an exception' do
+ let(:new_key) { OpenSSL::PKey::RSA.generate(512) }
+ subject { JWT.decode(rsa_encoded, new_key) }
+
+ it { expect{subject}.to raise_error(JWT::DecodeError) }
+ end
+ end
+end
diff --git a/spec/lib/json_web_token/token_spec.rb b/spec/lib/json_web_token/token_spec.rb
new file mode 100644
index 00000000000..3d955e4d774
--- /dev/null
+++ b/spec/lib/json_web_token/token_spec.rb
@@ -0,0 +1,18 @@
+describe JSONWebToken::Token do
+ let(:token) { described_class.new }
+
+ context 'custom parameters' do
+ let(:value) { 'value' }
+ before { token[:key] = value }
+
+ it { expect(token[:key]).to eq(value) }
+ it { expect(token.payload).to include(key: value) }
+ end
+
+ context 'embeds default payload' do
+ subject { token.payload }
+ let(:default) { token.send(:default_payload) }
+
+ it { is_expected.to include(default) }
+ end
+end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 1ce22feed5c..d84f3e998f5 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -20,6 +20,15 @@ describe ApplicationSetting, models: true do
it { is_expected.to allow_value(https).for(:after_sign_out_path) }
it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
+ describe 'disabled_oauth_sign_in_sources validations' do
+ before do
+ allow(Devise).to receive(:omniauth_providers).and_return([:github])
+ end
+
+ it { is_expected.to allow_value(['github']).for(:disabled_oauth_sign_in_sources) }
+ it { is_expected.not_to allow_value(['test']).for(:disabled_oauth_sign_in_sources) }
+ end
+
it { is_expected.to validate_presence_of(:max_attachment_size) }
it do
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index ad47e338a33..ccb100cd96f 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -56,7 +56,7 @@ describe Commit, models: true do
end
it "does not truncates a message with a newline after 80 but less 100 characters" do
- message =<<eos
+ message = <<eos
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit.
Vivamus egestas lacinia lacus, sed rutrum mauris.
eos
diff --git a/spec/models/concerns/subscribable_spec.rb b/spec/models/concerns/subscribable_spec.rb
index e31fdb0bffb..b7fc5a92497 100644
--- a/spec/models/concerns/subscribable_spec.rb
+++ b/spec/models/concerns/subscribable_spec.rb
@@ -44,6 +44,16 @@ describe Subscribable, 'Subscribable' do
end
end
+ describe '#subscribe' do
+ it 'subscribes the given user' do
+ expect(resource.subscribed?(user)).to be_falsey
+
+ resource.subscribe(user)
+
+ expect(resource.subscribed?(user)).to be_truthy
+ end
+ end
+
describe '#unsubscribe' do
it 'unsubscribes the given current user' do
resource.subscriptions.create(user: user, subscribed: true)
diff --git a/spec/models/hooks/service_hook_spec.rb b/spec/models/hooks/service_hook_spec.rb
index f800f415bd2..534e1b4f128 100644
--- a/spec/models/hooks/service_hook_spec.rb
+++ b/spec/models/hooks/service_hook_spec.rb
@@ -34,14 +34,14 @@ describe ServiceHook, models: true do
it "POSTs to the webhook URL" do
@service_hook.execute(@data)
expect(WebMock).to have_requested(:post, @service_hook.url).with(
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'Service Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'Service Hook' }
).once
end
it "POSTs the data as JSON" do
@service_hook.execute(@data)
expect(WebMock).to have_requested(:post, @service_hook.url).with(
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'Service Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'Service Hook' }
).once
end
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index 56a9fbe9720..4078b9e4ff5 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -33,7 +33,7 @@ describe SystemHook, models: true do
Projects::CreateService.new(user, name: 'empty').execute
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /project_create/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -42,7 +42,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /project_destroy/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -51,7 +51,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_create/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -60,7 +60,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_destroy/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -69,7 +69,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_add_to_team/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -79,7 +79,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_remove_from_team/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -88,7 +88,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /group_create/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -97,7 +97,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /group_destroy/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -106,7 +106,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_add_to_group/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
@@ -116,7 +116,7 @@ describe SystemHook, models: true do
expect(WebMock).to have_requested(:post, system_hook.url).with(
body: /user_remove_from_group/,
- headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
+ headers: { 'Content-Type' => 'application/json', 'X-Gitlab-Event' => 'System Hook' }
).once
end
end
diff --git a/spec/models/legacy_diff_note_spec.rb b/spec/models/legacy_diff_note_spec.rb
new file mode 100644
index 00000000000..7c29bef54e4
--- /dev/null
+++ b/spec/models/legacy_diff_note_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+
+describe LegacyDiffNote, models: true do
+ describe "Commit diff line notes" do
+ let!(:note) { create(:note_on_commit_diff, note: "+1 from me") }
+ let!(:commit) { note.noteable }
+
+ it "should save a valid note" do
+ expect(note.commit_id).to eq(commit.id)
+ expect(note.noteable.id).to eq(commit.id)
+ end
+
+ it "should be recognized by #legacy_diff_note?" do
+ expect(note).to be_legacy_diff_note
+ end
+ end
+
+ describe '#active?' do
+ it 'is always true when the note has no associated diff' do
+ note = build(:note_on_merge_request_diff)
+
+ expect(note).to receive(:diff).and_return(nil)
+
+ expect(note).to be_active
+ end
+
+ it 'is never true when the note has no noteable associated' do
+ note = build(:note_on_merge_request_diff)
+
+ expect(note).to receive(:diff).and_return(double)
+ expect(note).to receive(:noteable).and_return(nil)
+
+ expect(note).not_to be_active
+ end
+
+ it 'returns the memoized value if defined' do
+ note = build(:note_on_merge_request_diff)
+
+ note.instance_variable_set(:@active, 'foo')
+ expect(note).not_to receive(:find_noteable_diff)
+
+ expect(note.active?).to eq 'foo'
+ end
+
+ context 'for a merge request noteable' do
+ it 'is false when noteable has no matching diff' do
+ merge = build_stubbed(:merge_request, :simple)
+ note = build(:note_on_merge_request_diff, noteable: merge)
+
+ allow(note).to receive(:diff).and_return(double)
+ expect(note).to receive(:find_noteable_diff).and_return(nil)
+
+ expect(note).not_to be_active
+ end
+
+ it 'is true when noteable has a matching diff' do
+ merge = create(:merge_request, :simple)
+
+ # Generate a real line_code value so we know it will match. We use a
+ # random line from a random diff just for funsies.
+ diff = merge.diffs.to_a.sample
+ line = Gitlab::Diff::Parser.new.parse(diff.diff.each_line).to_a.sample
+ code = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
+
+ # We're persisting in order to trigger the set_diff callback
+ note = create(:note_on_merge_request_diff, noteable: merge, line_code: code)
+
+ # Make sure we don't get a false positive from a guard clause
+ expect(note).to receive(:find_noteable_diff).and_call_original
+ expect(note).to be_active
+ end
+ end
+ end
+end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index c8578749b21..9eef08c6d00 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -64,7 +64,13 @@ describe MergeRequest, models: true do
describe '#target_sha' do
context 'when the target branch does not exist anymore' do
- subject { create(:merge_request).tap { |mr| mr.update_attribute(:target_branch, 'deleted') } }
+ let(:project) { create(:project) }
+
+ subject { create(:merge_request, source_project: project, target_project: project) }
+
+ before do
+ project.repository.raw_repository.delete_branch(subject.target_branch)
+ end
it 'returns nil' do
expect(subject.target_sha).to be_nil
@@ -289,7 +295,12 @@ describe MergeRequest, models: true do
let(:fork_project) { create(:project, forked_from_project: project) }
context 'when the target branch does not exist anymore' do
- subject { create(:merge_request).tap { |mr| mr.update_attribute(:target_branch, 'deleted') } }
+ subject { create(:merge_request, source_project: project, target_project: project) }
+
+ before do
+ project.repository.raw_repository.delete_branch(subject.target_branch)
+ subject.reload
+ end
it 'does not crash' do
expect{ subject.diverged_commits_count }.not_to raise_error
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 247a9fa9910..1e18c788b50 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -204,4 +204,37 @@ describe Milestone, models: true do
to eq([milestone])
end
end
+
+ describe '.upcoming_ids_by_projects' do
+ let(:project_1) { create(:empty_project) }
+ let(:project_2) { create(:empty_project) }
+ let(:project_3) { create(:empty_project) }
+ let(:projects) { [project_1, project_2, project_3] }
+
+ let!(:past_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now - 1.day) }
+ let!(:current_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 1.day) }
+ let!(:future_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 2.days) }
+
+ let!(:past_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now - 1.day) }
+ let!(:closed_milestone_project_2) { create(:milestone, :closed, project: project_2, due_date: Time.now + 1.day) }
+ let!(:current_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now + 2.days) }
+
+ let!(:past_milestone_project_3) { create(:milestone, project: project_3, due_date: Time.now - 1.day) }
+
+ # The call to `#try` is because this returns a relation with a Postgres DB,
+ # and an array of IDs with a MySQL DB.
+ let(:milestone_ids) { Milestone.upcoming_ids_by_projects(projects).map { |id| id.try(:id) || id } }
+
+ it 'returns the next upcoming open milestone ID for each project' do
+ expect(milestone_ids).to contain_exactly(current_milestone_project_1.id, current_milestone_project_2.id)
+ end
+
+ context 'when the projects have no open upcoming milestones' do
+ let(:projects) { [project_3] }
+
+ it 'returns no results' do
+ expect(milestone_ids).to be_empty
+ end
+ end
+ end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index b479f1c2f1a..4448eefad00 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -34,24 +34,6 @@ describe Note, models: true do
end
end
- describe "Commit diff line notes" do
- let!(:note) { create(:note_on_commit_diff, note: "+1 from me") }
- let!(:commit) { note.noteable }
-
- it "should save a valid note" do
- expect(note.commit_id).to eq(commit.id)
- expect(note.noteable.id).to eq(commit.id)
- end
-
- it "should be recognized by #for_diff_line?" do
- expect(note).to be_for_diff_line
- end
-
- it "should be recognized by #for_commit_diff_line?" do
- expect(note).to be_for_commit_diff_line
- end
- end
-
describe 'authorization' do
before do
@p1 = create(:project)
diff --git a/spec/models/project_services/slack_service/issue_message_spec.rb b/spec/models/project_services/slack_service/issue_message_spec.rb
index f648cbe2dee..0f8889bdf3c 100644
--- a/spec/models/project_services/slack_service/issue_message_spec.rb
+++ b/spec/models/project_services/slack_service/issue_message_spec.rb
@@ -25,7 +25,7 @@ describe SlackService::IssueMessage, models: true do
}
end
- let(:color) { '#345' }
+ let(:color) { '#C95823' }
context '#initialize' do
before do
@@ -40,10 +40,11 @@ describe SlackService::IssueMessage, models: true do
context 'open' do
it 'returns a message regarding opening of issues' do
expect(subject.pretext).to eq(
- 'Test User opened <url|issue #100> in <somewhere.com|project_name>: '\
- '*Issue title*')
+ '<somewhere.com|[project_name>] Issue opened by Test User')
expect(subject.attachments).to eq([
{
+ title: "#100 Issue title",
+ title_link: "url",
text: "issue description",
color: color,
}
@@ -56,10 +57,10 @@ describe SlackService::IssueMessage, models: true do
args[:object_attributes][:action] = 'close'
args[:object_attributes][:state] = 'closed'
end
+
it 'returns a message regarding closing of issues' do
expect(subject.pretext). to eq(
- 'Test User closed <url|issue #100> in <somewhere.com|project_name>: '\
- '*Issue title*')
+ '<somewhere.com|[project_name>] Issue <url|#100 Issue title> closed by Test User')
expect(subject.attachments).to be_empty
end
end
diff --git a/spec/models/project_services/slack_service/note_message_spec.rb b/spec/models/project_services/slack_service/note_message_spec.rb
index d37590cab75..379c3e1219c 100644
--- a/spec/models/project_services/slack_service/note_message_spec.rb
+++ b/spec/models/project_services/slack_service/note_message_spec.rb
@@ -65,7 +65,7 @@ describe SlackService::NoteMessage, models: true do
expect(message.pretext).to eq("Test User commented on " \
"<url|merge request !30> in <somewhere.com|project_name>: " \
"*merge request title*")
- expected_attachments = [
+ expected_attachments = [
{
text: "comment on a merge request",
color: color,
@@ -117,7 +117,7 @@ describe SlackService::NoteMessage, models: true do
expect(message.pretext).to eq("Test User commented on " \
"<url|snippet #5> in <somewhere.com|project_name>: " \
"*snippet title*")
- expected_attachments = [
+ expected_attachments = [
{
text: "comment on a snippet",
color: color,
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 532e3f013fd..91ebb612baa 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -38,7 +38,8 @@ describe ProjectWiki, models: true do
describe "#wiki_base_path" do
it "returns the wiki base path" do
- wiki_base_path = "/#{project.path_with_namespace}/wikis"
+ wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.path_with_namespace}/wikis"
+
expect(subject.wiki_base_path).to eq(wiki_base_path)
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e170cc85a1e..77f745b2660 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -142,6 +142,7 @@ describe User, models: true do
end
describe '#confirm' do
+ before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(true) }
let(:user) { create(:user, confirmed_at: nil, unconfirmed_email: 'test@gitlab.com') }
it 'returns unconfirmed' do
diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb
index 5ead735be48..0fbc984c061 100644
--- a/spec/requests/api/builds_spec.rb
+++ b/spec/requests/api/builds_spec.rb
@@ -106,8 +106,8 @@ describe API::API, api: true do
context 'authorized user' do
let(:download_headers) do
- { 'Content-Transfer-Encoding'=>'binary',
- 'Content-Disposition'=>'attachment; filename=ci_build_artifacts.zip' }
+ { 'Content-Transfer-Encoding' => 'binary',
+ 'Content-Disposition' => 'attachment; filename=ci_build_artifacts.zip' }
end
it 'should return specific build artifacts' do
diff --git a/spec/requests/api/group_members_spec.rb b/spec/requests/api/group_members_spec.rb
index 96d89e69209..02553d0f8e2 100644
--- a/spec/requests/api/group_members_spec.rb
+++ b/spec/requests/api/group_members_spec.rb
@@ -34,11 +34,11 @@ describe API::API, api: true do
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(5)
- expect(json_response.find { |e| e['id']==owner.id }['access_level']).to eq(GroupMember::OWNER)
- expect(json_response.find { |e| e['id']==reporter.id }['access_level']).to eq(GroupMember::REPORTER)
- expect(json_response.find { |e| e['id']==developer.id }['access_level']).to eq(GroupMember::DEVELOPER)
- expect(json_response.find { |e| e['id']==master.id }['access_level']).to eq(GroupMember::MASTER)
- expect(json_response.find { |e| e['id']==guest.id }['access_level']).to eq(GroupMember::GUEST)
+ expect(json_response.find { |e| e['id'] == owner.id }['access_level']).to eq(GroupMember::OWNER)
+ expect(json_response.find { |e| e['id'] == reporter.id }['access_level']).to eq(GroupMember::REPORTER)
+ expect(json_response.find { |e| e['id'] == developer.id }['access_level']).to eq(GroupMember::DEVELOPER)
+ expect(json_response.find { |e| e['id'] == master.id }['access_level']).to eq(GroupMember::MASTER)
+ expect(json_response.find { |e| e['id'] == guest.id }['access_level']).to eq(GroupMember::GUEST)
end
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 7bc7e319ff1..bb926172593 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -622,6 +622,12 @@ describe API::API, api: true do
expect(response.status).to eq(404)
end
+
+ it 'returns 404 if the issue is confidential' do
+ post api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member)
+
+ expect(response.status).to eq(404)
+ end
end
describe 'DELETE :id/issues/:issue_id/subscription' do
@@ -643,5 +649,11 @@ describe API::API, api: true do
expect(response.status).to eq(404)
end
+
+ it 'returns 404 if the issue is confidential' do
+ delete api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member)
+
+ expect(response.status).to eq(404)
+ end
end
end
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index 6943ff9d26c..b2c7f8d9acb 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -190,4 +190,86 @@ describe API::API, api: true do
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
end
+
+ describe "POST /projects/:id/labels/:label_id/subscription" do
+ context "when label_id is a label title" do
+ it "should subscribe to the label" do
+ post api("/projects/#{project.id}/labels/#{label1.title}/subscription", user)
+
+ expect(response.status).to eq(201)
+ expect(json_response["name"]).to eq(label1.title)
+ expect(json_response["subscribed"]).to be_truthy
+ end
+ end
+
+ context "when label_id is a label ID" do
+ it "should subscribe to the label" do
+ post api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
+
+ expect(response.status).to eq(201)
+ expect(json_response["name"]).to eq(label1.title)
+ expect(json_response["subscribed"]).to be_truthy
+ end
+ end
+
+ context "when user is already subscribed to label" do
+ before { label1.subscribe(user) }
+
+ it "should return 304" do
+ post api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
+
+ expect(response.status).to eq(304)
+ end
+ end
+
+ context "when label ID is not found" do
+ it "should a return 404 error" do
+ post api("/projects/#{project.id}/labels/1234/subscription", user)
+
+ expect(response.status).to eq(404)
+ end
+ end
+ end
+
+ describe "DELETE /projects/:id/labels/:label_id/subscription" do
+ before { label1.subscribe(user) }
+
+ context "when label_id is a label title" do
+ it "should unsubscribe from the label" do
+ delete api("/projects/#{project.id}/labels/#{label1.title}/subscription", user)
+
+ expect(response.status).to eq(200)
+ expect(json_response["name"]).to eq(label1.title)
+ expect(json_response["subscribed"]).to be_falsey
+ end
+ end
+
+ context "when label_id is a label ID" do
+ it "should unsubscribe from the label" do
+ delete api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
+
+ expect(response.status).to eq(200)
+ expect(json_response["name"]).to eq(label1.title)
+ expect(json_response["subscribed"]).to be_falsey
+ end
+ end
+
+ context "when user is already unsubscribed from label" do
+ before { label1.unsubscribe(user) }
+
+ it "should return 304" do
+ delete api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
+
+ expect(response.status).to eq(304)
+ end
+ end
+
+ context "when label ID is not found" do
+ it "should a return 404 error" do
+ delete api("/projects/#{project.id}/labels/1234/subscription", user)
+
+ expect(response.status).to eq(404)
+ end
+ end
+ end
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 49091fc0f49..ed1ed5aeb95 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::API, api: true do
include ApiHelpers
let(:user) { create(:user) }
- let!(:project) { create(:project, namespace: user.namespace) }
+ let!(:project) { create(:project, :public, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project, author: user) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
@@ -39,6 +39,7 @@ describe API::API, api: true do
context "when noteable is an Issue" do
it "should return an array of issue notes" do
get api("/projects/#{project.id}/issues/#{issue.id}/notes", user)
+
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(issue_note.note)
@@ -46,20 +47,33 @@ describe API::API, api: true do
it "should return a 404 error when issue id not found" do
get api("/projects/#{project.id}/issues/12345/notes", user)
+
expect(response.status).to eq(404)
end
- context "that references a private issue" do
+ context "and current user cannot view the notes" do
it "should return an empty array" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
+
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response).to be_empty
end
+ context "and issue is confidential" do
+ before { ext_issue.update_attributes(confidential: true) }
+
+ it "returns 404" do
+ get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
+
+ expect(response.status).to eq(404)
+ end
+ end
+
context "and current user can view the note" do
it "should return an empty array" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user)
+
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(cross_reference_note.note)
@@ -71,6 +85,7 @@ describe API::API, api: true do
context "when noteable is a Snippet" do
it "should return an array of snippet notes" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
+
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(snippet_note.note)
@@ -78,6 +93,13 @@ describe API::API, api: true do
it "should return a 404 error when snippet id not found" do
get api("/projects/#{project.id}/snippets/42/notes", user)
+
+ expect(response.status).to eq(404)
+ end
+
+ it "returns 404 when not authorized" do
+ get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user)
+
expect(response.status).to eq(404)
end
end
@@ -85,6 +107,7 @@ describe API::API, api: true do
context "when noteable is a Merge Request" do
it "should return an array of merge_requests notes" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user)
+
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(merge_request_note.note)
@@ -92,6 +115,13 @@ describe API::API, api: true do
it "should return a 404 error if merge request id not found" do
get api("/projects/#{project.id}/merge_requests/4444/notes", user)
+
+ expect(response.status).to eq(404)
+ end
+
+ it "returns 404 when not authorized" do
+ get api("/projects/#{project.id}/merge_requests/4444/notes", private_user)
+
expect(response.status).to eq(404)
end
end
@@ -101,24 +131,39 @@ describe API::API, api: true do
context "when noteable is an Issue" do
it "should return an issue note by id" do
get api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", user)
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq(issue_note.note)
end
it "should return a 404 error if issue note not found" do
get api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user)
+
expect(response.status).to eq(404)
end
- context "that references a private issue" do
+ context "and current user cannot view the note" do
it "should return a 404 error" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", user)
+
expect(response.status).to eq(404)
end
+ context "when issue is confidential" do
+ before { issue.update_attributes(confidential: true) }
+
+ it "returns 404" do
+ get api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", private_user)
+
+ expect(response.status).to eq(404)
+ end
+ end
+
+
context "and current user can view the note" do
it "should return an issue note by id" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", private_user)
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq(cross_reference_note.note)
end
@@ -129,12 +174,14 @@ describe API::API, api: true do
context "when noteable is a Snippet" do
it "should return a snippet note by id" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user)
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq(snippet_note.note)
end
it "should return a 404 error if snippet note not found" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/12345", user)
+
expect(response.status).to eq(404)
end
end
@@ -144,6 +191,7 @@ describe API::API, api: true do
context "when noteable is an Issue" do
it "should create a new issue note" do
post api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!'
+
expect(response.status).to eq(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
@@ -151,11 +199,13 @@ describe API::API, api: true do
it "should return a 400 bad request error if body not given" do
post api("/projects/#{project.id}/issues/#{issue.id}/notes", user)
+
expect(response.status).to eq(400)
end
it "should return a 401 unauthorized error if user not authenticated" do
post api("/projects/#{project.id}/issues/#{issue.id}/notes"), body: 'hi!'
+
expect(response.status).to eq(401)
end
@@ -164,6 +214,7 @@ describe API::API, api: true do
creation_time = 2.weeks.ago
post api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
body: 'hi!', created_at: creation_time
+
expect(response.status).to eq(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
@@ -176,6 +227,7 @@ describe API::API, api: true do
context "when noteable is a Snippet" do
it "should create a new snippet note" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!'
+
expect(response.status).to eq(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
@@ -183,11 +235,13 @@ describe API::API, api: true do
it "should return a 400 bad request error if body not given" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
+
expect(response.status).to eq(400)
end
it "should return a 401 unauthorized error if user not authenticated" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!'
+
expect(response.status).to eq(401)
end
end
@@ -227,6 +281,7 @@ describe API::API, api: true do
it 'should return modified note' do
put api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user), body: 'Hello!'
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -234,12 +289,14 @@ describe API::API, api: true do
it 'should return a 404 error when note id not found' do
put api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user),
body: 'Hello!'
+
expect(response.status).to eq(404)
end
it 'should return a 400 bad request error if body not given' do
put api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user)
+
expect(response.status).to eq(400)
end
end
@@ -248,6 +305,7 @@ describe API::API, api: true do
it 'should return modified note' do
put api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user), body: 'Hello!'
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -255,6 +313,7 @@ describe API::API, api: true do
it 'should return a 404 error when note id not found' do
put api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/12345", user), body: "Hello!"
+
expect(response.status).to eq(404)
end
end
@@ -263,6 +322,7 @@ describe API::API, api: true do
it 'should return modified note' do
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
"notes/#{merge_request_note.id}", user), body: 'Hello!'
+
expect(response.status).to eq(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -270,6 +330,7 @@ describe API::API, api: true do
it 'should return a 404 error when note id not found' do
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
"notes/12345", user), body: "Hello!"
+
expect(response.status).to eq(404)
end
end
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index dfd361a2cdd..cae4656010f 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -402,8 +402,8 @@ describe Ci::API::API do
context 'build has artifacts' do
let(:build) { create(:ci_build, :artifacts) }
let(:download_headers) do
- { 'Content-Transfer-Encoding'=>'binary',
- 'Content-Disposition'=>'attachment; filename=ci_build_artifacts.zip' }
+ { 'Content-Transfer-Encoding' => 'binary',
+ 'Content-Disposition' => 'attachment; filename=ci_build_artifacts.zip' }
end
it 'should download artifact' do
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
new file mode 100644
index 00000000000..7bb71365a48
--- /dev/null
+++ b/spec/requests/jwt_controller_spec.rb
@@ -0,0 +1,72 @@
+require 'spec_helper'
+
+describe JwtController do
+ let(:service) { double(execute: {}) }
+ let(:service_class) { double(new: service) }
+ let(:service_name) { 'test' }
+ let(:parameters) { { service: service_name } }
+
+ before { stub_const('JwtController::SERVICES', service_name => service_class) }
+
+ context 'existing service' do
+ subject! { get '/jwt/auth', parameters }
+
+ it { expect(response.status).to eq(200) }
+
+ context 'returning custom http code' do
+ let(:service) { double(execute: { http_status: 505 }) }
+
+ it { expect(response.status).to eq(505) }
+ end
+ end
+
+ context 'when using authorized request' do
+ context 'using CI token' do
+ let(:project) { create(:empty_project, runners_token: 'token', builds_enabled: builds_enabled) }
+ let(:headers) { { authorization: credentials('gitlab_ci_token', project.runners_token) } }
+
+ subject! { get '/jwt/auth', parameters, headers }
+
+ context 'project with enabled CI' do
+ let(:builds_enabled) { true }
+
+ it { expect(service_class).to have_received(:new).with(project, nil, parameters) }
+ end
+
+ context 'project with disabled CI' do
+ let(:builds_enabled) { false }
+
+ it { expect(response.status).to eq(403) }
+ end
+ end
+
+ context 'using User login' do
+ let(:user) { create(:user) }
+ let(:headers) { { authorization: credentials('user', 'password') } }
+
+ before { expect_any_instance_of(Gitlab::Auth).to receive(:find).with('user', 'password').and_return(user) }
+
+ subject! { get '/jwt/auth', parameters, headers }
+
+ it { expect(service_class).to have_received(:new).with(nil, user, parameters) }
+ end
+
+ context 'using invalid login' do
+ let(:headers) { { authorization: credentials('invalid', 'password') } }
+
+ subject! { get '/jwt/auth', parameters, headers }
+
+ it { expect(response.status).to eq(403) }
+ end
+ end
+
+ context 'unknown service' do
+ subject! { get '/jwt/auth', service: 'unknown' }
+
+ it { expect(response.status).to eq(404) }
+ end
+
+ def credentials(login, password)
+ ActionController::HttpAuthentication::Basic.encode_credentials(login, password)
+ end
+end
diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb
index cd16a8e6322..b5ed8584c8a 100644
--- a/spec/routing/admin_routing_spec.rb
+++ b/spec/routing/admin_routing_spec.rb
@@ -118,3 +118,10 @@ describe Admin::DashboardController, "routing" do
expect(get("/admin")).to route_to('admin/dashboard#index')
end
end
+
+# admin_health_check GET /admin/health_check(.:format) admin/health_check#show
+describe Admin::HealthCheckController, "routing" do
+ it "to #show" do
+ expect(get("/admin/health_check")).to route_to('admin/health_check#show')
+ end
+end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index 1527eddfa48..de13c0db5d1 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -1,5 +1,42 @@
require 'spec_helper'
+# user GET /u/:username/
+# user_groups GET /u/:username/groups(.:format)
+# user_projects GET /u/:username/projects(.:format)
+# user_contributed_projects GET /u/:username/contributed(.:format)
+# user_snippets GET /u/:username/snippets(.:format)
+# user_calendar GET /u/:username/calendar(.:format)
+# user_calendar_activities GET /u/:username/calendar_activities(.:format)
+describe UsersController, "routing" do
+ it "to #show" do
+ expect(get("/u/User")).to route_to('users#show', username: 'User')
+ end
+
+ it "to #groups" do
+ expect(get("/u/User/groups")).to route_to('users#groups', username: 'User')
+ end
+
+ it "to #projects" do
+ expect(get("/u/User/projects")).to route_to('users#projects', username: 'User')
+ end
+
+ it "to #contributed" do
+ expect(get("/u/User/contributed")).to route_to('users#contributed', username: 'User')
+ end
+
+ it "to #snippets" do
+ expect(get("/u/User/snippets")).to route_to('users#snippets', username: 'User')
+ end
+
+ it "to #calendar" do
+ expect(get("/u/User/calendar")).to route_to('users#calendar', username: 'User')
+ end
+
+ it "to #calendar_activities" do
+ expect(get("/u/User/calendar_activities")).to route_to('users#calendar_activities', username: 'User')
+ end
+end
+
# search GET /search(.:format) search#show
describe SearchController, "routing" do
it "to #show" do
@@ -27,10 +64,6 @@ end
# PUT /snippets/:id(.:format) snippets#update
# DELETE /snippets/:id(.:format) snippets#destroy
describe SnippetsController, "routing" do
- it "to #user_index" do
- expect(get("/s/User")).to route_to('snippets#index', username: 'User')
- end
-
it "to #raw" do
expect(get("/snippets/1/raw")).to route_to('snippets#raw', id: '1')
end
@@ -243,3 +276,13 @@ describe "Groups", "routing" do
expect(get('/1')).to route_to('namespaces#show', id: '1')
end
end
+
+describe HealthCheckController, 'routing' do
+ it 'to #index' do
+ expect(get('/health_check')).to route_to('health_check#index')
+ end
+
+ it 'also supports passing checks in the url' do
+ expect(get('/health_check/email')).to route_to('health_check#index', checks: 'email')
+ end
+end
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
new file mode 100644
index 00000000000..3ea252ed44f
--- /dev/null
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -0,0 +1,216 @@
+require 'spec_helper'
+
+describe Auth::ContainerRegistryAuthenticationService, services: true do
+ let(:current_project) { nil }
+ let(:current_user) { nil }
+ let(:current_params) { {} }
+ let(:rsa_key) { OpenSSL::PKey::RSA.generate(512) }
+ let(:registry_settings) do
+ {
+ enabled: true,
+ issuer: 'rspec',
+ key: nil
+ }
+ end
+ let(:payload) { JWT.decode(subject[:token], rsa_key).first }
+
+ subject { described_class.new(current_project, current_user, current_params).execute }
+
+ before do
+ allow(Gitlab.config.registry).to receive_messages(registry_settings)
+ allow_any_instance_of(JSONWebToken::RSAToken).to receive(:key).and_return(rsa_key)
+ end
+
+ shared_examples 'an authenticated' do
+ it { is_expected.to include(:token) }
+ it { expect(payload).to include('access') }
+ end
+
+ shared_examples 'a accessible' do
+ let(:access) do
+ [{
+ 'type' => 'repository',
+ 'name' => project.path_with_namespace,
+ 'actions' => actions,
+ }]
+ end
+
+ it_behaves_like 'an authenticated'
+ it { expect(payload).to include('access' => access) }
+ end
+
+ shared_examples 'a pullable' do
+ it_behaves_like 'a accessible' do
+ let(:actions) { ['pull'] }
+ end
+ end
+
+ shared_examples 'a pushable' do
+ it_behaves_like 'a accessible' do
+ let(:actions) { ['push'] }
+ end
+ end
+
+ shared_examples 'a pullable and pushable' do
+ it_behaves_like 'a accessible' do
+ let(:actions) { ['pull', 'push'] }
+ end
+ end
+
+ shared_examples 'a forbidden' do
+ it { is_expected.to include(http_status: 403) }
+ it { is_expected.to_not include(:token) }
+ end
+
+ context 'user authorization' do
+ let(:project) { create(:project) }
+ let(:current_user) { create(:user) }
+
+ context 'allow to use offline_token' do
+ let(:current_params) do
+ { offline_token: true }
+ end
+
+ it_behaves_like 'an authenticated'
+ end
+
+ context 'allow developer to push images' do
+ before { project.team << [current_user, :developer] }
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:push" }
+ end
+
+ it_behaves_like 'a pushable'
+ end
+
+ context 'allow reporter to pull images' do
+ before { project.team << [current_user, :reporter] }
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull" }
+ end
+
+ it_behaves_like 'a pullable'
+ end
+
+ context 'return a least of privileges' do
+ before { project.team << [current_user, :reporter] }
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:push,pull" }
+ end
+
+ it_behaves_like 'a pullable'
+ end
+
+ context 'disallow guest to pull or push images' do
+ before { project.team << [current_user, :guest] }
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+ end
+
+ context 'project authorization' do
+ let(:current_project) { create(:empty_project) }
+
+ context 'disallow to use offline_token' do
+ let(:current_params) do
+ { offline_token: true }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+
+ context 'allow to pull and push images' do
+ let(:current_params) do
+ { scope: "repository:#{current_project.path_with_namespace}:pull,push" }
+ end
+
+ it_behaves_like 'a pullable and pushable' do
+ let(:project) { current_project }
+ end
+ end
+
+ context 'for other projects' do
+ context 'when pulling' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull" }
+ end
+
+ context 'allow for public' do
+ let(:project) { create(:empty_project, :public) }
+ it_behaves_like 'a pullable'
+ end
+
+ context 'disallow for private' do
+ let(:project) { create(:empty_project, :private) }
+ it_behaves_like 'a forbidden'
+ end
+ end
+
+ context 'when pushing' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:push" }
+ end
+
+ context 'disallow for all' do
+ let(:project) { create(:empty_project, :public) }
+ it_behaves_like 'a forbidden'
+ end
+ end
+ end
+ end
+
+ context 'unauthorized' do
+ context 'disallow to use offline_token' do
+ let(:current_params) do
+ { offline_token: true }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+
+ context 'for invalid scope' do
+ let(:current_params) do
+ { scope: 'invalid:aa:bb' }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+
+ context 'for private project' do
+ let(:project) { create(:empty_project, :private) }
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull" }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+
+ context 'for public project' do
+ let(:project) { create(:empty_project, :public) }
+
+ context 'when pulling and pushing' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ end
+
+ it_behaves_like 'a pullable'
+ end
+
+ context 'when pushing' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:push" }
+ end
+
+ it_behaves_like 'a forbidden'
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index e43903dbd3c..fd114359467 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -64,7 +64,7 @@ describe Projects::CreateService, services: true do
@path = ProjectWiki.new(@project, @user).send(:path_to_repo)
end
- it { expect(File.exists?(@path)).to be_truthy }
+ it { expect(File.exist?(@path)).to be_truthy }
end
context 'wiki_enabled false does not create wiki repository directory' do
@@ -74,7 +74,7 @@ describe Projects::CreateService, services: true do
@path = ProjectWiki.new(@project, @user).send(:path_to_repo)
end
- it { expect(File.exists?(@path)).to be_falsey }
+ it { expect(File.exist?(@path)).to be_falsey }
end
end
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 1ec27077717..a5cb6f382e4 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -13,8 +13,8 @@ describe Projects::DestroyService, services: true do
end
it { expect(Project.all).not_to include(project) }
- it { expect(Dir.exists?(path)).to be_falsey }
- it { expect(Dir.exists?(remove_path)).to be_falsey }
+ it { expect(Dir.exist?(path)).to be_falsey }
+ it { expect(Dir.exist?(remove_path)).to be_falsey }
end
context 'Sidekiq fake' do
@@ -24,8 +24,8 @@ describe Projects::DestroyService, services: true do
end
it { expect(Project.all).not_to include(project) }
- it { expect(Dir.exists?(path)).to be_falsey }
- it { expect(Dir.exists?(remove_path)).to be_truthy }
+ it { expect(Dir.exist?(path)).to be_falsey }
+ it { expect(Dir.exist?(remove_path)).to be_truthy }
end
def destroy_project(project, user, params)
diff --git a/spec/support/jira_service_helper.rb b/spec/support/jira_service_helper.rb
index a3f496359b1..5ebe095743b 100644
--- a/spec/support/jira_service_helper.rb
+++ b/spec/support/jira_service_helper.rb
@@ -2,11 +2,11 @@ module JiraServiceHelper
def jira_service_settings
properties = {
- "title"=>"JIRA tracker",
- "project_url"=>"http://jira.example/issues/?jql=project=A",
- "issues_url"=>"http://jira.example/browse/JIRA-1",
- "new_issue_url"=>"http://jira.example/secure/CreateIssue.jspa",
- "api_url"=>"http://jira.example/rest/api/2"
+ "title" => "JIRA tracker",
+ "project_url" => "http://jira.example/issues/?jql=project=A",
+ "issues_url" => "http://jira.example/browse/JIRA-1",
+ "new_issue_url" => "http://jira.example/secure/CreateIssue.jspa",
+ "api_url" => "http://jira.example/rest/api/2"
}
jira_tracker.update_attributes(properties: properties, active: true)
diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb
index eec2e681117..b5ca34bc028 100644
--- a/spec/support/stub_gitlab_calls.rb
+++ b/spec/support/stub_gitlab_calls.rb
@@ -36,20 +36,20 @@ module StubGitlabCalls
stub_request(:post, "#{gitlab_url}api/v3/session.json").
with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}",
- headers: { 'Content-Type'=>'application/json' }).
- to_return(status: 201, body: f, headers: { 'Content-Type'=>'application/json' })
+ headers: { 'Content-Type' => 'application/json' }).
+ to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_user
f = File.read(Rails.root.join('spec/support/gitlab_stubs/user.json'))
stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type'=>'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type'=>'application/json' })
+ with(headers: { 'Content-Type' => 'application/json' }).
+ to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token").
- with(headers: { 'Content-Type'=>'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type'=>'application/json' })
+ with(headers: { 'Content-Type' => 'application/json' }).
+ to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_project_8
@@ -66,19 +66,19 @@ module StubGitlabCalls
f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json'))
stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type'=>'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type'=>'application/json' })
+ with(headers: { 'Content-Type' => 'application/json' }).
+ to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_projects_owned
stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type'=>'application/json' }).
+ with(headers: { 'Content-Type' => 'application/json' }).
to_return(status: 200, body: "", headers: {})
end
def stub_ci_enable
stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type'=>'application/json' }).
+ with(headers: { 'Content-Type' => 'application/json' }).
to_return(status: 200, body: "", headers: {})
end