diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-14 01:14:46 +0300 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-14 01:14:46 +0300 |
commit | 0958f331d1af67514c80f0bc582c93b0ae1ed491 (patch) | |
tree | 512f37d66e349b1b9e6420cf7739aea7ee1ac324 /spec | |
parent | 509654b3784da2a084a0c8303e9c6cc1498b8d2b (diff) | |
parent | d7a28f3c12950d56a187148fda9dce39a9f2bf08 (diff) |
Merge remote-tracking branch 'origin/master' into docker-registry
# Conflicts:
# config/initializers/1_settings.rb
Diffstat (limited to 'spec')
98 files changed, 1354 insertions, 1096 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/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/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/abuse_reports.rb b/spec/factories/abuse_reports.rb index d0e8c778518..8f6422a7825 100644 --- a/spec/factories/abuse_reports.rb +++ b/spec/factories/abuse_reports.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: abuse_reports -# -# id :integer not null, primary key -# reporter_id :integer -# user_id :integer -# message :text -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :abuse_report do reporter factory: :user diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb index c80e7366551..efe9803b1a7 100644 --- a/spec/factories/broadcast_messages.rb +++ b/spec/factories/broadcast_messages.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - FactoryGirl.define do factory :broadcast_message do message "MyText" diff --git a/spec/factories/forked_project_links.rb b/spec/factories/forked_project_links.rb index 19a54946fe0..b16c1272e68 100644 --- a/spec/factories/forked_project_links.rb +++ b/spec/factories/forked_project_links.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :forked_project_link do association :forked_to_project, factory: :project diff --git a/spec/factories/label_links.rb b/spec/factories/label_links.rb index 2939d4307c5..3580174e873 100644 --- a/spec/factories/label_links.rb +++ b/spec/factories/label_links.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :label_link do label diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb index ea2be8928d5..eb489099854 100644 --- a/spec/factories/labels.rb +++ b/spec/factories/labels.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string(255) -# color :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# template :boolean default(FALSE) -# - FactoryGirl.define do factory :label do sequence(:title) { |n| "label#{n}" } diff --git a/spec/factories/lfs_objects.rb b/spec/factories/lfs_objects.rb index 327858ce435..a81645acd2b 100644 --- a/spec/factories/lfs_objects.rb +++ b/spec/factories/lfs_objects.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects -# -# id :integer not null, primary key -# oid :string(255) not null -# size :integer not null -# created_at :datetime -# updated_at :datetime -# file :string(255) -# - include ActionDispatch::TestProcess FactoryGirl.define do diff --git a/spec/factories/lfs_objects_projects.rb b/spec/factories/lfs_objects_projects.rb index 50b45843c99..1ed0355c8e4 100644 --- a/spec/factories/lfs_objects_projects.rb +++ b/spec/factories/lfs_objects_projects.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects_projects -# -# id :integer not null, primary key -# lfs_object_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :lfs_objects_project do lfs_object diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb index e281e2f227b..c6a08d78b78 100644 --- a/spec/factories/merge_requests.rb +++ b/spec/factories/merge_requests.rb @@ -1,32 +1,3 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# updated_by_id :integer -# merge_error :string(255) -# merge_params :text -# merge_when_build_succeeds :boolean default(FALSE), not null -# merge_user_id :integer -# merge_commit_sha :string -# - FactoryGirl.define do factory :merge_request do title diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index e5dcb159014..840b13196a6 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -1,24 +1,3 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# updated_by_id :integer -# is_award :boolean default(FALSE), not null -# - require_relative '../support/repo_helpers' include ActionDispatch::TestProcess diff --git a/spec/factories/oauth_access_tokens.rb b/spec/factories/oauth_access_tokens.rb index 7700b15d538..ccf02d0719b 100644 --- a/spec/factories/oauth_access_tokens.rb +++ b/spec/factories/oauth_access_tokens.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: oauth_access_tokens -# -# id :integer not null, primary key -# resource_owner_id :integer -# application_id :integer -# token :string not null -# refresh_token :string -# expires_in :integer -# revoked_at :datetime -# created_at :datetime not null -# scopes :string -# - FactoryGirl.define do factory :oauth_access_token do resource_owner diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index c14b99606ba..da8d97c9f82 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -1,43 +1,3 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string(255) default("gitlab"), not null -# issues_tracker_id :string(255) -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string(255) -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# avatar :string(255) -# import_status :string(255) -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string(255) -# import_source :string(255) -# commit_count :integer default(0) -# import_error :text -# ci_id :integer -# builds_enabled :boolean default(TRUE), not null -# shared_runners_enabled :boolean default(TRUE), not null -# runners_token :string -# build_coverage_regex :string -# build_allow_git_fetch :boolean default(TRUE), not null -# build_timeout :integer default(3600), not null -# - FactoryGirl.define do # Project without repository # @@ -61,6 +21,12 @@ FactoryGirl.define do trait :private do visibility_level Gitlab::VisibilityLevel::PRIVATE end + + trait :empty_repo do + after(:create) do |project| + project.create_repository + end + end end # Project with empty repository @@ -68,9 +34,7 @@ FactoryGirl.define do # This is a case when you just created a project # but not pushed any code there yet factory :project_empty_repo, parent: :empty_project do - after :create do |project| - project.create_repository - end + empty_repo end # Project with test repository diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb index 7f331c37256..74497dc82c0 100644 --- a/spec/factories/releases.rb +++ b/spec/factories/releases.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: releases -# -# id :integer not null, primary key -# tag :string(255) -# description :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :release do tag "v1.1.0" diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb index 7ae06c27840..e3681ae93a5 100644 --- a/spec/factories/todos.rb +++ b/spec/factories/todos.rb @@ -1,21 +1,3 @@ -# == Schema Information -# -# Table name: todos -# -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# target_id :integer -# target_type :string not null -# author_id :integer -# action :integer not null -# state :string not null -# created_at :datetime -# updated_at :datetime -# note_id :integer -# commit_id :string -# - FactoryGirl.define do factory :todo do project 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/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 new file mode 100644 index 00000000000..cc7f78e7325 --- /dev/null +++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb @@ -0,0 +1,137 @@ +require 'spec_helper' + +describe 'Projects > Merge requests > User lists merge requests', feature: true do + include SortingHelper + + let(:project) { create(:project, :public) } + let(:user) { create(:user) } + + before do + @fix = create(:merge_request, + title: 'fix', + source_project: project, + source_branch: 'fix', + assignee: user, + milestone: create(:milestone, due_date: '2013-12-11'), + created_at: 1.minute.ago, + updated_at: 1.minute.ago) + create(:merge_request, + title: 'markdown', + source_project: project, + source_branch: 'markdown', + assignee: user, + milestone: create(:milestone, due_date: '2013-12-12'), + created_at: 2.minutes.ago, + updated_at: 2.minutes.ago) + create(:merge_request, + title: 'lfs', + source_project: project, + source_branch: 'lfs', + created_at: 3.minutes.ago, + updated_at: 10.seconds.ago) + end + + it 'filters on no assignee' do + visit_merge_requests(project, assignee_id: IssuableFinder::NONE) + + expect(current_path).to eq(namespace_project_merge_requests_path(project.namespace, project)) + expect(page).to have_content 'lfs' + expect(page).not_to have_content 'fix' + expect(page).not_to have_content 'markdown' + end + + it 'filters on a specific assignee' do + visit_merge_requests(project, assignee_id: user.id) + + expect(page).not_to have_content 'lfs' + expect(page).to have_content 'fix' + expect(page).to have_content 'markdown' + end + + it 'sorts by newest' do + visit_merge_requests(project, sort: sort_value_recently_created) + + expect(first_merge_request).to include('lfs') + expect(last_merge_request).to include('fix') + end + + it 'sorts by oldest' do + visit_merge_requests(project, sort: sort_value_oldest_created) + + expect(first_merge_request).to include('fix') + expect(last_merge_request).to include('lfs') + end + + it 'sorts by last updated' do + visit_merge_requests(project, sort: sort_value_recently_updated) + + expect(first_merge_request).to include('lfs') + end + + it 'sorts by oldest updated' do + visit_merge_requests(project, sort: sort_value_oldest_updated) + + expect(first_merge_request).to include('markdown') + end + + it 'sorts by milestone due soon' do + visit_merge_requests(project, sort: sort_value_milestone_soon) + + expect(first_merge_request).to include('fix') + end + + it 'sorts by milestone due later' do + visit_merge_requests(project, sort: sort_value_milestone_later) + + expect(first_merge_request).to include('markdown') + end + + it 'filters on one label and sorts by due soon' do + label = create(:label, project: project) + create(:label_link, label: label, target: @fix) + + visit_merge_requests(project, label_name: [label.name], + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + end + + context 'while filtering on two labels' do + let(:label) { create(:label, project: project) } + let(:label2) { create(:label, project: project) } + + before do + create(:label_link, label: label, target: @fix) + create(:label_link, label: label2, target: @fix) + end + + it 'sorts by due soon' do + visit_merge_requests(project, label_name: [label.name, label2.name], + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + end + + context 'filter on assignee and' do + it 'sorts by due soon' do + visit_merge_requests(project, label_name: [label.name, label2.name], + assignee_id: user.id, + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + end + end + end + + def visit_merge_requests(project, opts = {}) + visit namespace_project_merge_requests_path(project.namespace, project, opts) + end + + def first_merge_request + page.all('ul.mr-list > li').first.text + end + + def last_merge_request + page.all('ul.mr-list > li').last.text + end +end diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb new file mode 100644 index 00000000000..0c51fe72ca4 --- /dev/null +++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +feature 'Developer views empty project instructions', feature: true do + let(:project) { create(:empty_project, :empty_repo) } + let(:developer) { create(:user) } + + background do + project.team << [developer, :developer] + + login_as(developer) + end + + context 'without an SSH key' do + scenario 'defaults to HTTP' do + visit_project + + expect_instructions_for('http') + end + + scenario 'switches to SSH', js: true do + visit_project + + select_protocol('SSH') + + expect_instructions_for('ssh') + end + end + + context 'with an SSH key' do + background do + create(:personal_key, user: developer) + end + + scenario 'defaults to SSH' do + visit_project + + expect_instructions_for('ssh') + end + + scenario 'switches to HTTP', js: true do + visit_project + + select_protocol('HTTP') + + expect_instructions_for('http') + end + end + + def visit_project + visit namespace_project_path(project.namespace, project) + end + + def select_protocol(protocol) + find('#clone-dropdown').click + find(".#{protocol.downcase}-selector").click + end + + def expect_instructions_for(protocol) + msg = :"#{protocol.downcase}_url_to_repo" + + expect(page).to have_content("git clone #{project.send(msg)}") + end +end diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb new file mode 100644 index 00000000000..08a97085a9c --- /dev/null +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +feature 'Master creates tag', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + project.team << [user, :master] + login_with(user) + visit namespace_project_tags_path(project.namespace, project) + end + + scenario 'with an invalid name displays an error' do + create_tag_in_form(tag: 'v 1.0', ref: 'master') + + expect(page).to have_content 'Tag name invalid' + end + + scenario 'with an invalid reference displays an error' do + create_tag_in_form(tag: 'v2.0', ref: 'foo') + + expect(page).to have_content 'Target foo is invalid' + end + + scenario 'that already exists displays an error' do + create_tag_in_form(tag: 'v1.1.0', ref: 'master') + + expect(page).to have_content 'Tag v1.1.0 already exists' + end + + scenario 'with multiline message displays the message in a <pre> block' do + create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world") + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v3.0')) + expect(page).to have_content 'v3.0' + page.within 'pre.body' do + expect(page).to have_content "Awesome tag message\n\n- hello\n- world" + end + end + + scenario 'with multiline release notes parses the release note as Markdown' do + create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world") + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v4.0')) + expect(page).to have_content 'v4.0' + page.within '.description' do + expect(page).to have_content 'Awesome release notes' + expect(page).to have_selector('ul li', count: 2) + end + end + + def create_tag_in_form(tag:, ref:, message: nil, desc: nil) + click_link 'New tag' + fill_in 'tag_name', with: tag + fill_in 'ref', with: ref + fill_in 'message', with: message unless message.nil? + fill_in 'release_description', with: desc unless desc.nil? + click_button 'Create tag' + end +end diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb new file mode 100644 index 00000000000..f0990118e3c --- /dev/null +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +feature 'Master deletes tag', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + project.team << [user, :master] + login_with(user) + visit namespace_project_tags_path(project.namespace, project) + end + + context 'from the tags list page' do + scenario 'deletes the tag' do + expect(page).to have_content 'v1.1.0' + + page.within('.content') do + first('.btn-remove').click + end + + expect(current_path).to eq( + namespace_project_tags_path(project.namespace, project)) + expect(page).not_to have_content 'v1.1.0' + end + + end + + context 'from a specific tag page' do + scenario 'deletes the tag' do + click_on 'v1.0.0' + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + + click_on 'Delete tag' + + expect(current_path).to eq( + namespace_project_tags_path(project.namespace, project)) + expect(page).not_to have_content 'v1.0.0' + end + end +end diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb new file mode 100644 index 00000000000..c926e9841f3 --- /dev/null +++ b/spec/features/tags/master_updates_tag_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +feature 'Master updates tag', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + project.team << [user, :master] + login_with(user) + visit namespace_project_tags_path(project.namespace, project) + end + + context 'from the tags list page' do + scenario 'updates the release notes' do + page.within(first('.controls')) do + click_link 'Edit release notes' + end + + fill_in 'release_description', with: 'Awesome release notes' + click_button 'Save changes' + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.1.0')) + expect(page).to have_content 'v1.1.0' + expect(page).to have_content 'Awesome release notes' + end + end + + context 'from a specific tag page' do + scenario 'updates the release notes' do + click_on 'v1.1.0' + click_link 'Edit release notes' + fill_in 'release_description', with: 'Awesome release notes' + click_button 'Save changes' + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.1.0')) + expect(page).to have_content 'v1.1.0' + expect(page).to have_content 'Awesome release notes' + end + end +end diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb new file mode 100644 index 00000000000..29d2c244720 --- /dev/null +++ b/spec/features/tags/master_views_tags_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +feature 'Master views tags', feature: true do + let(:user) { create(:user) } + + before do + project.team << [user, :master] + login_with(user) + end + + context 'when project has no tags' do + let(:project) { create(:project_empty_repo) } + before do + visit namespace_project_path(project.namespace, project) + click_on 'README' + fill_in :commit_message, with: 'Add a README file', visible: true + # Remove pre-receive hook so we can push without auth + FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) + click_button 'Commit Changes' + visit namespace_project_tags_path(project.namespace, project) + end + + scenario 'displays a specific message' do + expect(page).to have_content 'Repository has no tags yet.' + end + end + + context 'when project has tags' do + let(:project) { create(:project, namespace: user.namespace) } + before do + visit namespace_project_tags_path(project.namespace, project) + end + + scenario 'views the tags list page' do + expect(page).to have_content 'v1.0.0' + end + + scenario 'views a specific tag page' do + click_on 'v1.0.0' + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + expect(page).to have_content 'v1.0.0' + expect(page).to have_content 'This tag has no release notes.' + end + + describe 'links on the tag page' do + scenario 'has a button to browse files' do + click_on 'v1.0.0' + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + + click_on 'Browse files' + + expect(current_path).to eq( + namespace_project_tree_path(project.namespace, project, 'v1.0.0')) + end + + scenario 'has a button to browse commits' do + click_on 'v1.0.0' + + expect(current_path).to eq( + namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + + click_on 'Browse commits' + + expect(current_path).to eq( + namespace_project_commits_path(project.namespace, project, 'v1.0.0')) + 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/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 29bcb8c5892..ac5af8740dc 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -88,18 +88,18 @@ describe ProjectsHelper do end describe 'default_clone_protocol' do - describe 'using HTTP' do + context 'when user is not logged in and gitlab protocol is HTTP' do it 'returns HTTP' do - expect(helper).to receive(:current_user).and_return(nil) + allow(helper).to receive(:current_user).and_return(nil) expect(helper.send(:default_clone_protocol)).to eq('http') end end - describe 'using HTTPS' do + context 'when user is not logged in and gitlab protocol is HTTPS' do it 'returns HTTPS' do - allow(Gitlab.config.gitlab).to receive(:protocol).and_return('https') - expect(helper).to receive(:current_user).and_return(nil) + stub_config_setting(protocol: 'https') + allow(helper).to receive(:current_user).and_return(nil) expect(helper.send(:default_clone_protocol)).to eq('https') end diff --git a/spec/initializers/trusted_proxies_spec.rb b/spec/initializers/trusted_proxies_spec.rb new file mode 100644 index 00000000000..4bb149f25ff --- /dev/null +++ b/spec/initializers/trusted_proxies_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe 'trusted_proxies', lib: true do + context 'with default config' do + before do + set_trusted_proxies([]) + end + + it 'preserves private IPs as remote_ip' do + request = stub_request('HTTP_X_FORWARDED_FOR' => '10.1.5.89') + expect(request.remote_ip).to eq('10.1.5.89') + end + + it 'filters out localhost from remote_ip' do + request = stub_request('HTTP_X_FORWARDED_FOR' => '1.1.1.1, 10.1.5.89, 127.0.0.1') + expect(request.remote_ip).to eq('10.1.5.89') + end + end + + context 'with private IP ranges added' do + before do + set_trusted_proxies([ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ]) + end + + it 'filters out private and local IPs from remote_ip' do + request = stub_request('HTTP_X_FORWARDED_FOR' => '1.2.3.6, 1.1.1.1, 10.1.5.89, 127.0.0.1') + expect(request.remote_ip).to eq('1.1.1.1') + end + end + + context 'with proxy IP added' do + before do + set_trusted_proxies([ "60.98.25.47" ]) + end + + it 'filters out proxy IP from remote_ip' do + request = stub_request('HTTP_X_FORWARDED_FOR' => '1.2.3.6, 1.1.1.1, 60.98.25.47, 127.0.0.1') + expect(request.remote_ip).to eq('1.1.1.1') + end + end + + def stub_request(headers = {}) + ActionDispatch::RemoteIp.new(Proc.new { }, false, Rails.application.config.action_dispatch.trusted_proxies).call(headers) + ActionDispatch::Request.new(headers) + end + + def set_trusted_proxies(proxies = []) + stub_config_setting('trusted_proxies' => proxies) + load File.join(__dir__, '../../config/initializers/trusted_proxies.rb') + end +end diff --git a/spec/javascripts/merge_request_widget_spec.js.coffee b/spec/javascripts/merge_request_widget_spec.js.coffee index c0bd8a29e43..92b7eeb1116 100644 --- a/spec/javascripts/merge_request_widget_spec.js.coffee +++ b/spec/javascripts/merge_request_widget_spec.js.coffee @@ -47,3 +47,9 @@ describe 'MergeRequestWidget', -> spy = spyOn(@class, 'showCICoverage').and.stub() @class.getCIStatus(false) expect(spy).not.toHaveBeenCalled() + + it 'should not display a notification on the first check after the widget has been created', -> + spy = spyOn(window, 'notify') + @class = new MergeRequestWidget(@opts) + @class.getCIStatus(true) + expect(spy).not.toHaveBeenCalled() diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index ebf3d7489b5..5beb61dac5c 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -43,7 +43,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do milestone.update_attribute(:title, %{"></a>whatever<a title="}) doc = reference_filter("milestone #{reference}") - expect(doc.text).to eq "milestone #{milestone.title}" + expect(doc.text).to eq "milestone \">whatever" end it 'includes default classes' do diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index 27ce312b11c..b38e3b17e64 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -22,6 +22,12 @@ describe Banzai::Filter::SanitizationFilter, lib: true do expect(filter(act).to_html).to eq exp end + it 'sanitizes mixed-cased javascript in attributes' do + act = %q(<a href="javaScript:alert('foo')">Text</a>) + exp = '<a>Text</a>' + expect(filter(act).to_html).to eq exp + end + it 'allows whitelisted HTML tags from the user' do exp = act = "<dl>\n<dt>Term</dt>\n<dd>Definition</dd>\n</dl>" expect(filter(act).to_html).to eq exp diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb index 3b073a90a95..b83be54746c 100644 --- a/spec/lib/banzai/filter/upload_link_filter_spec.rb +++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb @@ -8,6 +8,10 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do project: project }) + raw_filter(doc, contexts) + end + + def raw_filter(doc, contexts = {}) described_class.call(doc, contexts) end @@ -70,4 +74,18 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png" end end + + context 'when project context does not exist' do + let(:upload_link) { link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg') } + + it 'does not raise error' do + expect { raw_filter(upload_link, project: nil) }.not_to raise_error + end + + it 'does not rewrite link' do + doc = raw_filter(upload_link, project: nil) + + expect(doc.to_html).to eq upload_link + 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 <" do + expect(subject.convert("<")[:html]).to eq('<') + 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/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb index b2d7a799810..7d6cce6daec 100644 --- a/spec/lib/gitlab/email/message/repository_push_spec.rb +++ b/spec/lib/gitlab/email/message/repository_push_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::Email::Message::RepositoryPush do let!(:author) { create(:author, name: 'Author') } let(:message) do - described_class.new(Notify, project.id, 'recipient@example.com', opts) + described_class.new(Notify, project.id, opts) end context 'new commits have been pushed to repository' 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/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 495c5cbac00..5f7e4a526e6 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -593,7 +593,7 @@ describe Notify do let(:user) { create(:user) } let(:tree_path) { namespace_project_tree_path(project.namespace, project, "master") } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :create) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :create) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -606,10 +606,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Pushed new branch master/ end @@ -624,7 +620,7 @@ describe Notify do let(:user) { create(:user) } let(:tree_path) { namespace_project_tree_path(project.namespace, project, "v1.0") } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -637,10 +633,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Pushed new tag v1\.0/ end @@ -654,7 +646,7 @@ describe Notify do let(:example_site_path) { root_path } let(:user) { create(:user) } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :delete) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :delete) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -667,10 +659,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Deleted branch master/ end @@ -680,7 +668,7 @@ describe Notify do let(:example_site_path) { root_path } let(:user) { create(:user) } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -693,10 +681,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Deleted tag v1\.0/ end @@ -710,7 +694,7 @@ describe Notify do let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) } let(:send_from_committer_email) { false } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -723,10 +707,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/ end @@ -818,7 +798,7 @@ describe Notify do let(:commits) { Commit.decorate(compare.commits, nil) } let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) } it_behaves_like 'it should show Gmail Actions View Commit link' it_behaves_like "a user cannot unsubscribe through footer link" @@ -831,10 +811,6 @@ describe Notify do expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /#{commits.first.title}/ end diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb index ac12ab6c757..305f8bc88cc 100644 --- a/spec/models/abuse_report_spec.rb +++ b/spec/models/abuse_report_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: abuse_reports -# -# id :integer not null, primary key -# reporter_id :integer -# user_id :integer -# message :text -# created_at :datetime -# updated_at :datetime -# - require 'rails_helper' RSpec.describe AbuseReport, type: :model do diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 520cf1b75de..d84f3e998f5 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -1,49 +1,3 @@ -# == Schema Information -# -# Table name: application_settings -# -# id :integer not null, primary key -# default_projects_limit :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string(255) -# default_branch_protection :integer default(2) -# restricted_visibility_levels :text -# version_check_enabled :boolean default(TRUE) -# max_attachment_size :integer default(10), not null -# default_project_visibility :integer -# default_snippet_visibility :integer -# restricted_signup_domains :text -# user_oauth_applications :boolean default(TRUE) -# after_sign_out_path :string(255) -# session_expire_delay :integer default(10080), not null -# import_sources :text -# help_page_text :text -# admin_notification_email :string(255) -# shared_runners_enabled :boolean default(TRUE), not null -# max_artifacts_size :integer default(100), not null -# runners_registration_token :string -# require_two_factor_authentication :boolean default(FALSE) -# two_factor_grace_period :integer default(48) -# metrics_enabled :boolean default(FALSE) -# metrics_host :string default("localhost") -# metrics_username :string -# metrics_password :string -# metrics_pool_size :integer default(16) -# metrics_timeout :integer default(10) -# metrics_method_call_threshold :integer default(10) -# recaptcha_enabled :boolean default(FALSE) -# recaptcha_site_key :string -# recaptcha_private_key :string -# metrics_port :integer default(8089) -# sentry_enabled :boolean default(FALSE) -# sentry_dsn :string -# - require 'spec_helper' describe ApplicationSetting, models: true do @@ -66,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/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index f6f84db57e6..6ad8bfef4f2 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - require 'spec_helper' describe BroadcastMessage, models: true do diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index a747aa08447..dc071ad1c90 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -1,21 +1,3 @@ -# == Schema Information -# -# Table name: ci_commits -# -# id :integer not null, primary key -# project_id :integer -# ref :string(255) -# sha :string(255) -# before_sha :string(255) -# push_data :text -# created_at :datetime -# updated_at :datetime -# tag :boolean default(FALSE) -# yaml_errors :text -# committed_at :datetime -# gl_project_id :integer -# - require 'spec_helper' describe Ci::Commit, models: true do diff --git a/spec/models/ci/runner_project_spec.rb b/spec/models/ci/runner_project_spec.rb index 000a732db77..95fc160b238 100644 --- a/spec/models/ci/runner_project_spec.rb +++ b/spec/models/ci/runner_project_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: ci_runner_projects -# -# id :integer not null, primary key -# runner_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - require 'spec_helper' describe Ci::RunnerProject, models: true do diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 25e9e5eca48..eaa94228922 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: ci_runners -# -# id :integer not null, primary key -# token :string(255) -# created_at :datetime -# updated_at :datetime -# description :string(255) -# contacted_at :datetime -# active :boolean default(TRUE), not null -# is_shared :boolean default(FALSE) -# name :string(255) -# version :string(255) -# revision :string(255) -# platform :string(255) -# architecture :string(255) -# - require 'spec_helper' describe Ci::Runner, models: true do diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb index 159be939300..474b0b1621d 100644 --- a/spec/models/ci/trigger_spec.rb +++ b/spec/models/ci/trigger_spec.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: ci_triggers -# -# id :integer not null, primary key -# token :string(255) -# project_id :integer -# deleted_at :datetime -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - require 'spec_helper' describe Ci::Trigger, models: true do diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index 71e84091cb7..c712d211b0f 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: ci_variables -# -# id :integer not null, primary key -# project_id :integer -# key :string(255) -# value :text -# encrypted_value :text -# encrypted_value_salt :string(255) -# encrypted_value_iv :string(255) -# gl_project_id :integer -# - require 'spec_helper' describe Ci::Variable, models: true 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/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 971e6750375..434e58cfd06 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -1,37 +1,3 @@ -# == Schema Information -# -# Table name: ci_builds -# -# id :integer not null, primary key -# project_id :integer -# status :string(255) -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# coverage :float -# commit_id :integer -# commands :text -# job_id :integer -# name :string(255) -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null -# stage :string(255) -# trigger_request_id :integer -# stage_idx :integer -# tag :boolean -# ref :string(255) -# user_id :integer -# type :string(255) -# target_url :string(255) -# description :string(255) -# artifacts_file :text -# gl_project_id :integer -# - require 'spec_helper' describe CommitStatus, models: true do 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/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb index 64ba778afea..6a90598a629 100644 --- a/spec/models/deploy_key_spec.rb +++ b/spec/models/deploy_key_spec.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# public :boolean default(FALSE), not null -# - require 'spec_helper' describe DeployKey, models: true do diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb index 8aedbfb8636..8a1e337c1a3 100644 --- a/spec/models/deploy_keys_project_spec.rb +++ b/spec/models/deploy_keys_project_spec.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: deploy_keys_projects -# -# id :integer not null, primary key -# deploy_key_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - require 'spec_helper' describe DeployKeysProject, models: true do diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index a20a6149649..5d0bd31db5a 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: emails -# -# id :integer not null, primary key -# user_id :integer not null -# email :string(255) not null -# created_at :datetime -# updated_at :datetime -# - require 'spec_helper' describe Email, models: true do diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 0c3cd13f399..b0e76fec693 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: events -# -# id :integer not null, primary key -# target_type :string(255) -# target_id :integer -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# action :integer -# author_id :integer -# - require 'spec_helper' describe Event, models: true do diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb index d90fbfe1ea5..3b817608ce0 100644 --- a/spec/models/forked_project_link_spec.rb +++ b/spec/models/forked_project_link_spec.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - require 'spec_helper' describe ForkedProjectLink, "add link on fork" do diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb index 5b0883d8702..0caf5869c24 100644 --- a/spec/models/generic_commit_status_spec.rb +++ b/spec/models/generic_commit_status_spec.rb @@ -1,37 +1,3 @@ -# == Schema Information -# -# Table name: ci_builds -# -# id :integer not null, primary key -# project_id :integer -# status :string(255) -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# coverage :float -# commit_id :integer -# commands :text -# job_id :integer -# name :string(255) -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null -# stage :string(255) -# trigger_request_id :integer -# stage_idx :integer -# tag :boolean -# ref :string(255) -# user_id :integer -# type :string(255) -# target_url :string(255) -# description :string(255) -# artifacts_file :text -# gl_project_id :integer -# - require 'spec_helper' describe GenericCommitStatus, models: true do diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 7bfca1e72c3..6fa16be7f04 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string(255) not null -# path :string(255) not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) -# description :string(255) default(""), not null -# avatar :string(255) -# - require 'spec_helper' describe Group, models: true do 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/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb index 37a27d73aab..f9bab487b96 100644 --- a/spec/models/hooks/web_hook_spec.rb +++ b/spec/models/hooks/web_hook_spec.rb @@ -95,13 +95,13 @@ describe WebHook, models: true do it "handles 200 status code" do WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: "Success") - expect(project_hook.execute(@data, 'push_hooks')).to eq([true, 'Success']) + expect(project_hook.execute(@data, 'push_hooks')).to eq([200, 'Success']) end it "handles 2xx status codes" do WebMock.stub_request(:post, project_hook.url).to_return(status: 201, body: "Success") - expect(project_hook.execute(@data, 'push_hooks')).to eq([true, 'Success']) + expect(project_hook.execute(@data, 'push_hooks')).to eq([201, 'Success']) end end end diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb index 5afe042e154..1b987588f59 100644 --- a/spec/models/identity_spec.rb +++ b/spec/models/identity_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: identities -# -# id :integer not null, primary key -# extern_uid :string(255) -# provider :string(255) -# user_id :integer -# created_at :datetime -# updated_at :datetime -# - require 'spec_helper' RSpec.describe Identity, models: true do diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 060e6599104..8ab00c70f9d 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -1,23 +1,3 @@ -# == Schema Information -# -# Table name: issues -# -# id :integer not null, primary key -# title :string(255) -# assignee_id :integer -# author_id :integer -# project_id :integer -# created_at :datetime -# updated_at :datetime -# position :integer default(0) -# branch_name :string(255) -# description :text -# milestone_id :integer -# state :string(255) -# iid :integer -# updated_by_id :integer -# - require 'spec_helper' describe Issue, models: true do diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index c962b83644a..26fbedbef2f 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# public :boolean default(FALSE), not null -# - require 'spec_helper' describe Key, models: true do diff --git a/spec/models/label_link_spec.rb b/spec/models/label_link_spec.rb index dc7510b1de3..5e6f8ca1528 100644 --- a/spec/models/label_link_spec.rb +++ b/spec/models/label_link_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - require 'spec_helper' describe LabelLink, models: true do diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb index 0614ca1e7c9..dad2628651b 100644 --- a/spec/models/label_spec.rb +++ b/spec/models/label_spec.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string(255) -# color :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# template :boolean default(FALSE) -# - require 'spec_helper' describe Label, models: true do @@ -55,6 +42,14 @@ describe Label, models: true do end end + describe "#title" do + let(:label) { create(:label, title: "<b>test</b>") } + + it "sanitizes title" do + expect(label.title).to eq("test") + end + end + describe '#to_reference' do context 'using id' do it 'returns a String reference to the object' do diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 2d8f1cc1ad3..6e51730eecd 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# created_by_id :integer -# invite_email :string(255) -# invite_token :string(255) -# invite_accepted_at :datetime -# - require 'spec_helper' describe Member, models: true do diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index d7884cea336..c8578749b21 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1,32 +1,3 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# updated_by_id :integer -# merge_error :string(255) -# merge_params :text -# merge_when_build_succeeds :boolean default(FALSE), not null -# merge_user_id :integer -# merge_commit_sha :string -# - require 'spec_helper' describe MergeRequest, models: true do diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 72a4ea70228..247a9fa9910 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: milestones -# -# id :integer not null, primary key -# title :string(255) not null -# project_id :integer not null -# description :text -# due_date :date -# created_at :datetime -# updated_at :datetime -# state :string(255) -# iid :integer -# - require 'spec_helper' describe Milestone, models: true do @@ -34,6 +19,14 @@ describe Milestone, models: true do let(:issue) { create(:issue) } let(:user) { create(:user) } + describe "#title" do + let(:milestone) { create(:milestone, title: "<b>test</b>") } + + it "sanitizes title" do + expect(milestone.title).to eq("test") + end + end + describe "unique milestone title per project" do it "shouldn't accept the same title in a project twice" do new_milestone = Milestone.new(project: milestone.project, title: milestone.title) diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 3c3a580942a..4074f966299 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string(255) not null -# path :string(255) not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) -# description :string(255) default(""), not null -# avatar :string(255) -# - require 'spec_helper' describe Namespace, models: true do diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 6b18936edb1..4b788b57882 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -1,24 +1,3 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# updated_by_id :integer -# is_award :boolean default(FALSE), not null -# - require 'spec_helper' describe Note, models: true do 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_snippet_spec.rb b/spec/models/project_snippet_spec.rb index e0feb606f78..d9d7c0b0aaa 100644 --- a/spec/models/project_snippet_spec.rb +++ b/spec/models/project_snippet_spec.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# type :string(255) -# visibility_level :integer default(0), not null -# - require 'spec_helper' describe ProjectSnippet, models: true do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 5b1cf71337e..f6e5b132643 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1,43 +1,3 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string(255) default("gitlab"), not null -# issues_tracker_id :string(255) -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string(255) -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# avatar :string(255) -# import_status :string(255) -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string(255) -# import_source :string(255) -# commit_count :integer default(0) -# import_error :text -# ci_id :integer -# builds_enabled :boolean default(TRUE), not null -# shared_runners_enabled :boolean default(TRUE), not null -# runners_token :string -# build_coverage_regex :string -# build_allow_git_fetch :boolean default(TRUE), not null -# build_timeout :integer default(3600), not null -# - require 'spec_helper' describe Project, models: true do diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb index 7e956cf6779..b523834c6e9 100644 --- a/spec/models/protected_branch_spec.rb +++ b/spec/models/protected_branch_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: protected_branches -# -# id :integer not null, primary key -# project_id :integer not null -# name :string(255) not null -# created_at :datetime -# updated_at :datetime -# developers_can_push :boolean default(FALSE), not null -# - require 'spec_helper' describe ProtectedBranch, models: true do diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index 72ecb442a36..527005b2b69 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: releases -# -# id :integer not null, primary key -# tag :string(255) -# description :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - require 'rails_helper' RSpec.describe Release, type: :model do diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 173628c08d0..8592e112c50 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -1,24 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# - require 'spec_helper' describe Service, models: true do diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 5077ac7b62b..7a613e360d4 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# type :string(255) -# visibility_level :integer default(0), not null -# - require 'spec_helper' describe Snippet, models: true do diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb index d9b86b9368f..623b82c01d8 100644 --- a/spec/models/todo_spec.rb +++ b/spec/models/todo_spec.rb @@ -1,21 +1,3 @@ -# == Schema Information -# -# Table name: todos -# -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# target_id :integer -# target_type :string not null -# author_id :integer -# action :integer not null -# state :string not null -# created_at :datetime -# updated_at :datetime -# note_id :integer -# commit_id :string -# - require 'spec_helper' describe Todo, models: true do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 8b2fb77e28e..10e7e693571 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,66 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# email :string(255) default(""), not null -# encrypted_password :string(255) default(""), not null -# reset_password_token :string(255) -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default(0) -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string(255) -# last_sign_in_ip :string(255) -# created_at :datetime -# updated_at :datetime -# name :string(255) -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string(255) default(""), not null -# linkedin :string(255) default(""), not null -# twitter :string(255) default(""), not null -# authentication_token :string(255) -# theme_id :integer default(1), not null -# bio :string(255) -# failed_attempts :integer default(0) -# locked_at :datetime -# username :string(255) -# can_create_group :boolean default(TRUE), not null -# can_create_team :boolean default(TRUE), not null -# state :string(255) -# color_scheme_id :integer default(1), not null -# notification_level :integer default(1), not null -# password_expires_at :datetime -# created_by_id :integer -# last_credential_check_at :datetime -# avatar :string(255) -# confirmation_token :string(255) -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string(255) -# hide_no_ssh_key :boolean default(FALSE) -# website_url :string(255) default(""), not null -# notification_email :string(255) -# hide_no_password :boolean default(FALSE) -# password_automatically_set :boolean default(FALSE) -# location :string(255) -# encrypted_otp_secret :string(255) -# encrypted_otp_secret_iv :string(255) -# encrypted_otp_secret_salt :string(255) -# otp_required_for_login :boolean default(FALSE), not null -# otp_backup_codes :text -# public_email :string(255) default(""), not null -# dashboard :integer default(0) -# project_view :integer default(0) -# consumed_timestep :integer -# layout :integer default(0) -# hide_project_limit :boolean default(FALSE) -# unlock_token :string -# otp_grace_period_started_at :datetime -# - require 'spec_helper' describe User, models: true do @@ -845,4 +782,23 @@ describe User, models: true do it { is_expected.to eq([private_project]) } end + + describe '#viewable_starred_projects' do + let(:user) { create(:user) } + let(:public_project) { create(:empty_project, :public) } + let(:private_project) { create(:empty_project, :private) } + let(:private_viewable_project) { create(:empty_project, :private) } + + before do + private_viewable_project.team << [user, Gitlab::Access::MASTER] + + [public_project, private_project, private_viewable_project].each do |project| + user.toggle_star(project) + end + end + + it 'returns only starred projects the user can view' do + expect(user.viewable_starred_projects).not_to include(private_project) + end + end end 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/commit_status_spec.rb b/spec/requests/api/commit_statuses_spec.rb index f3785b19362..633927c8c3e 100644 --- a/spec/requests/api/commit_status_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe API::CommitStatus, api: true do +describe API::CommitStatuses, api: true do include ApiHelpers let!(:project) { create(:project) } 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 f88e39cad9e..37ab9cc8cfe 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -39,6 +39,7 @@ describe API::API, api: true do let!(:empty_milestone) do create(:milestone, title: '2.0.0', project: project) end + let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) } before { project.team << [user, :reporter] } @@ -232,8 +233,28 @@ describe API::API, api: true do end describe "GET /projects/:id/issues/:issue_id" do + it 'exposes known attributes' do + get api("/projects/#{project.id}/issues/#{issue.id}", user) + + expect(response.status).to eq(200) + expect(json_response['id']).to eq(issue.id) + expect(json_response['iid']).to eq(issue.iid) + expect(json_response['project_id']).to eq(issue.project.id) + expect(json_response['title']).to eq(issue.title) + expect(json_response['description']).to eq(issue.description) + expect(json_response['state']).to eq(issue.state) + expect(json_response['created_at']).to be_present + expect(json_response['updated_at']).to be_present + expect(json_response['labels']).to eq(issue.label_names) + expect(json_response['milestone']).to be_a Hash + expect(json_response['assignee']).to be_a Hash + expect(json_response['author']).to be_a Hash + expect(json_response['user_notes_count']).to be(1) + end + it "should return a project issue by id" do get api("/projects/#{project.id}/issues/#{issue.id}", user) + expect(response.status).to eq(200) expect(json_response['title']).to eq(issue.title) expect(json_response['iid']).to eq(issue.iid) @@ -602,6 +623,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 @@ -623,5 +650,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/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 1fa7e76894f..4b0111df149 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -113,6 +113,34 @@ describe API::API, api: true do end describe "GET /projects/:id/merge_requests/:merge_request_id" do + it 'exposes known attributes' do + get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user) + + expect(response.status).to eq(200) + expect(json_response['id']).to eq(merge_request.id) + expect(json_response['iid']).to eq(merge_request.iid) + expect(json_response['project_id']).to eq(merge_request.project.id) + expect(json_response['title']).to eq(merge_request.title) + expect(json_response['description']).to eq(merge_request.description) + expect(json_response['state']).to eq(merge_request.state) + expect(json_response['created_at']).to be_present + expect(json_response['updated_at']).to be_present + expect(json_response['labels']).to eq(merge_request.label_names) + expect(json_response['milestone']).to be_nil + expect(json_response['assignee']).to be_a Hash + expect(json_response['author']).to be_a Hash + expect(json_response['target_branch']).to eq(merge_request.target_branch) + expect(json_response['source_branch']).to eq(merge_request.source_branch) + expect(json_response['upvotes']).to eq(0) + expect(json_response['downvotes']).to eq(0) + expect(json_response['source_project_id']).to eq(merge_request.source_project.id) + expect(json_response['target_project_id']).to eq(merge_request.target_project.id) + expect(json_response['work_in_progress']).to be_falsy + expect(json_response['merge_when_build_succeeds']).to be_falsy + expect(json_response['merge_status']).to eq('can_be_merged') + expect(json_response['user_notes_count']).to be(2) + end + it "should return merge_request" do get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user) expect(response.status).to eq(200) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 66193eac051..f167813e07d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -10,20 +10,20 @@ describe API::API, api: true do let(:admin) { create(:admin) } let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) } - let(:project3) { create(:project, path: 'project3', creator_id: user.id, namespace: user.namespace) } let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') } let(:project_member) { create(:project_member, :master, user: user, project: project) } let(:project_member2) { create(:project_member, :developer, user: user3, project: project) } let(:user4) { create(:user) } let(:project3) do create(:project, + :private, name: 'second_project', path: 'second_project', creator_id: user.id, namespace: user.namespace, merge_requests_enabled: false, issues_enabled: false, wiki_enabled: false, - snippets_enabled: false, visibility_level: 0) + snippets_enabled: false) end let(:project_member3) do create(:project_member, @@ -164,21 +164,18 @@ describe API::API, api: true do end describe 'GET /projects/starred' do + let(:public_project) { create(:project, :public) } + before do - admin.starred_projects << project - admin.save! + project_member2 + user3.update_attributes(starred_projects: [project, project2, project3, public_project]) end - it 'should return the starred projects' do - get api('/projects/all', admin) + it 'should return the starred projects viewable by the user' do + get api('/projects/starred', user3) expect(response.status).to eq(200) expect(json_response).to be_an Array - - expect(json_response).to satisfy do |response| - response.one? do |entry| - entry['name'] == project.name - end - end + expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, public_project.id) 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/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/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/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 240eae10052..5fbf2ae5247 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -506,6 +506,15 @@ describe SystemNoteService, services: true do end end + describe '.new_commit_summary' do + it 'escapes HTML titles' do + commit = double(title: '<pre>This is a test</pre>', short_id: '12345678') + escaped = '* 12345678 - <pre>This is a test</pre>' + + expect(described_class.new_commit_summary([commit])).to eq([escaped]) + end + end + include JiraServiceHelper describe 'JIRA integration' do diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 82b7fbfa816..a075496ee63 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -55,6 +55,25 @@ describe TodoService, services: true do should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED) should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED) end + + context 'when a private group is mentioned' do + let(:group) { create :group, :private } + let(:project) { create :project, :private, group: group } + let(:issue) { create :issue, author: author, project: project, description: group.to_reference } + + before do + group.add_owner(author) + group.add_user(member, Gitlab::Access::DEVELOPER) + group.add_user(john_doe, Gitlab::Access::DEVELOPER) + + service.new_issue(issue, author) + end + + it 'creates a todo for group members' do + should_create_todo(user: member, target: issue) + should_create_todo(user: john_doe, target: issue) + end + end end describe '#update_issue' do 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 diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb index 3600c771075..439da765c2c 100644 --- a/spec/workers/emails_on_push_worker_spec.rb +++ b/spec/workers/emails_on_push_worker_spec.rb @@ -6,29 +6,66 @@ describe EmailsOnPushWorker do let(:project) { create(:project) } let(:user) { create(:user) } let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) } + let(:recipients) { user.email } + let(:perform) { subject.perform(project.id, recipients, data.stringify_keys) } subject { EmailsOnPushWorker.new } - before do - allow(Project).to receive(:find).and_return(project) - end - describe "#perform" do - it "sends mail" do - subject.perform(project.id, user.email, data.stringify_keys) + context "when there are no errors in sending" do + let(:email) { ActionMailer::Base.deliveries.last } + + before { perform } - email = ActionMailer::Base.deliveries.last - expect(email.subject).to include('Change some files') - expect(email.to).to eq([user.email]) + it "sends a mail with the correct subject" do + expect(email.subject).to include('Change some files') + end + + it "sends the mail to the correct recipient" do + expect(email.to).to eq([user.email]) + end end - it "gracefully handles an input SMTP error" do - ActionMailer::Base.deliveries.clear - allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError) + context "when there is an SMTP error" do + before do + ActionMailer::Base.deliveries.clear + allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError) + perform + end + + it "gracefully handles an input SMTP error" do + expect(ActionMailer::Base.deliveries.count).to eq(0) + end + end + + context "when there are multiple recipients" do + let(:recipients) do + 1.upto(5).map { |i| user.email.sub('@', "+#{i}@") }.join("\n") + end + + before do + # This is a hack because we modify the mail object before sending, for efficency, + # but the TestMailer adapter just appends the objects to an array. To clone a mail + # object, create a new one! + # https://github.com/mikel/mail/issues/314#issuecomment-12750108 + allow_any_instance_of(Mail::TestMailer).to receive(:deliver!).and_wrap_original do |original, mail| + original.call(Mail.new(mail.encoded)) + end + + ActionMailer::Base.deliveries.clear + end - subject.perform(project.id, user.email, data.stringify_keys) + it "sends the mail to each of the recipients" do + perform + expect(ActionMailer::Base.deliveries.count).to eq(5) + expect(ActionMailer::Base.deliveries.map(&:to).flatten).to contain_exactly(*recipients.split) + end - expect(ActionMailer::Base.deliveries.count).to eq(0) + it "only generates the mail once" do + expect(Notify).to receive(:repository_push_email).once.and_call_original + expect(Premailer::Rails::CustomizedPremailer).to receive(:new).once.and_call_original + perform + end end end end |