summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2017-02-02 11:54:35 +0800
committerLin Jen-Shin <godfat@godfat.org>2017-02-02 11:54:35 +0800
commit54fca95160389fe7993df5d82635b83804833fee (patch)
tree8552f29a7bfbf24af39a5d6a3f8b110c1695f7de /spec
parenteb242fc865c032f6408f3b68700da9b840b416dd (diff)
parent40a824357c700280f3d2f8e2cda2fabc65af7f69 (diff)
downloadgitlab-ce-54fca95160389fe7993df5d82635b83804833fee.tar.gz
Merge remote-tracking branch 'upstream/master' into fix-git-hooks-when-creating-filefix-git-hooks-when-creating-file
* upstream/master: (190 commits) Remove unnecessary returns / unset variables from the CoffeeScript -> JS conversion. update spec Change the reply shortcut to focus the field even without a selection. use destroy_all Remove settings cog from within admin scroll tabs; keep links centered add changelog remove old project members from project add spec replicating validation error Fix small typo on new branch button spec Improve styling of the new issue message Don't capitalize environment name in show page Abillity to promote project labels to group labels Edited the column header for the environments list from created to updated and added created to environments detail page colum header titles Update and pin the `jwt` gem to ~> 1.5.6 refactor merge request build service Update index.md Clarify that Auto Deploy requires a public project. 19164 Add settings dropdown to mobile screens cop for gem fetched from a git source Add CHANGELOG entry ...
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb27
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb24
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb45
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb45
-rw-r--r--spec/factories/trending_project.rb6
-rw-r--r--spec/features/boards/sidebar_spec.rb30
-rw-r--r--spec/features/environment_spec.rb4
-rw-r--r--spec/features/environments_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb34
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb18
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb17
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb17
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb25
-rw-r--r--spec/features/issues/new_branch_button_spec.rb20
-rw-r--r--spec/features/login_spec.rb5
-rw-r--r--spec/features/merge_requests/toggler_behavior_spec.rb29
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb2
-rw-r--r--spec/features/merge_requests/widget_spec.rb34
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb3
-rw-r--r--spec/features/projects/import_export/test_project_export.tar.gzbin682154 -> 681799 bytes
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb8
-rw-r--r--spec/features/projects/new_project_spec.rb20
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb18
-rw-r--r--spec/features/projects/project_settings_spec.rb4
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb9
-rw-r--r--spec/features/todos/todos_spec.rb2
-rw-r--r--spec/helpers/issuables_helper_spec.rb40
-rw-r--r--spec/helpers/search_helper_spec.rb5
-rw-r--r--spec/javascripts/commits_spec.js.es650
-rw-r--r--spec/javascripts/filtered_search/dropdown_user_spec.js.es640
-rw-r--r--spec/javascripts/filtered_search/dropdown_utils_spec.js.es6156
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js.es668
-rw-r--r--spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es66
-rw-r--r--spec/javascripts/gl_form_spec.js.es6122
-rw-r--r--spec/javascripts/shortcuts_issuable_spec.js49
-rw-r--r--spec/lib/gitlab/auth_spec.rb96
-rw-r--r--spec/lib/gitlab/chat_commands/command_spec.rb50
-rw-r--r--spec/lib/gitlab/chat_commands/deploy_spec.rb24
-rw-r--r--spec/lib/gitlab/chat_commands/issue_new_spec.rb (renamed from spec/lib/gitlab/chat_commands/issue_create_spec.rb)14
-rw-r--r--spec/lib/gitlab/chat_commands/issue_search_spec.rb12
-rw-r--r--spec/lib/gitlab/chat_commands/issue_show_spec.rb25
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/access_spec.rb49
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb47
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb17
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb23
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb37
-rw-r--r--spec/lib/gitlab/ci/status/build/cancelable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/play_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/retryable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/stop_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/trace_reader_spec.rb16
-rw-r--r--spec/lib/gitlab/import_export/members_mapper_spec.rb24
-rw-r--r--spec/lib/gitlab/import_export/project.json13
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb14
-rw-r--r--spec/lib/gitlab/import_export/relation_factory_spec.rb15
-rw-r--r--spec/lib/gitlab/view/presenter/delegated_spec.rb14
-rw-r--r--spec/lib/gitlab/view/presenter/factory_spec.rb7
-rw-r--r--spec/lib/gitlab/view/presenter/simple_spec.rb15
-rw-r--r--spec/models/ability_spec.rb10
-rw-r--r--spec/models/ci/build_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb8
-rw-r--r--spec/models/ci/runner_spec.rb7
-rw-r--r--spec/models/commit_range_spec.rb2
-rw-r--r--spec/models/commit_spec.rb14
-rw-r--r--spec/models/commit_status_spec.rb2
-rw-r--r--spec/models/compare_spec.rb2
-rw-r--r--spec/models/concerns/issuable_spec.rb6
-rw-r--r--spec/models/concerns/mentionable_spec.rb8
-rw-r--r--spec/models/concerns/milestoneish_spec.rb2
-rw-r--r--spec/models/concerns/project_features_compatibility_spec.rb2
-rw-r--r--spec/models/cycle_analytics/code_spec.rb2
-rw-r--r--spec/models/cycle_analytics/issue_spec.rb2
-rw-r--r--spec/models/cycle_analytics/plan_spec.rb2
-rw-r--r--spec/models/cycle_analytics/production_spec.rb2
-rw-r--r--spec/models/cycle_analytics/review_spec.rb2
-rw-r--r--spec/models/cycle_analytics/staging_spec.rb3
-rw-r--r--spec/models/cycle_analytics/test_spec.rb2
-rw-r--r--spec/models/deploy_keys_project_spec.rb4
-rw-r--r--spec/models/deployment_spec.rb2
-rw-r--r--spec/models/diff_note_spec.rb4
-rw-r--r--spec/models/environment_spec.rb9
-rw-r--r--spec/models/event_spec.rb6
-rw-r--r--spec/models/forked_project_link_spec.rb4
-rw-r--r--spec/models/global_milestone_spec.rb6
-rw-r--r--spec/models/group_milestone_spec.rb2
-rw-r--r--spec/models/guest_spec.rb6
-rw-r--r--spec/models/hooks/system_hook_spec.rb2
-rw-r--r--spec/models/hooks/web_hook_spec.rb2
-rw-r--r--spec/models/issue/metrics_spec.rb2
-rw-r--r--spec/models/issue_collection_spec.rb2
-rw-r--r--spec/models/issue_spec.rb83
-rw-r--r--spec/models/member_spec.rb2
-rw-r--r--spec/models/members/project_member_spec.rb8
-rw-r--r--spec/models/merge_request/metrics_spec.rb4
-rw-r--r--spec/models/milestone_spec.rb6
-rw-r--r--spec/models/namespace_spec.rb4
-rw-r--r--spec/models/network/graph_spec.rb2
-rw-r--r--spec/models/note_spec.rb12
-rw-r--r--spec/models/project_feature_spec.rb4
-rw-r--r--spec/models/project_group_link_spec.rb2
-rw-r--r--spec/models/project_label_spec.rb2
-rw-r--r--spec/models/project_services/asana_service_spec.rb2
-rw-r--r--spec/models/project_services/assembla_service_spec.rb2
-rw-r--r--spec/models/project_services/campfire_service_spec.rb2
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb2
-rw-r--r--spec/models/project_services/external_wiki_service_spec.rb2
-rw-r--r--spec/models/project_services/flowdock_service_spec.rb2
-rw-r--r--spec/models/project_services/gemnasium_service_spec.rb2
-rw-r--r--spec/models/project_services/gitlab_issue_tracker_service_spec.rb6
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb6
-rw-r--r--spec/models/project_services/irker_service_spec.rb2
-rw-r--r--spec/models/project_services/jira_service_spec.rb12
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb5
-rw-r--r--spec/models/project_services/pipeline_email_service_spec.rb2
-rw-r--r--spec/models/project_services/pushover_service_spec.rb2
-rw-r--r--spec/models/project_spec.rb46
-rw-r--r--spec/models/project_team_spec.rb10
-rw-r--r--spec/models/repository_spec.rb26
-rw-r--r--spec/models/service_spec.rb16
-rw-r--r--spec/models/snippet_spec.rb6
-rw-r--r--spec/models/todo_spec.rb16
-rw-r--r--spec/models/tree_spec.rb2
-rw-r--r--spec/models/user_spec.rb6
-rw-r--r--spec/policies/ci/build_policy_spec.rb93
-rw-r--r--spec/requests/api/branches_spec.rb2
-rw-r--r--spec/requests/api/builds_spec.rb2
-rw-r--r--spec/requests/api/commit_statuses_spec.rb2
-rw-r--r--spec/requests/api/commits_spec.rb2
-rw-r--r--spec/requests/api/files_spec.rb4
-rw-r--r--spec/requests/api/fork_spec.rb21
-rw-r--r--spec/requests/api/groups_spec.rb3
-rw-r--r--spec/requests/api/internal_spec.rb2
-rw-r--r--spec/requests/api/merge_requests_spec.rb16
-rw-r--r--spec/requests/api/pipelines_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb1
-rw-r--r--spec/requests/api/repositories_spec.rb14
-rw-r--r--spec/requests/api/tags_spec.rb6
-rw-r--r--spec/requests/api/triggers_spec.rb2
-rw-r--r--spec/requests/ci/api/triggers_spec.rb6
-rw-r--r--spec/requests/git_http_spec.rb2
-rw-r--r--spec/requests/projects/artifacts_controller_spec.rb2
-rw-r--r--spec/requests/projects/cycle_analytics_events_spec.rb2
-rw-r--r--spec/serializers/analytics_build_serializer_spec.rb10
-rw-r--r--spec/serializers/analytics_issue_serializer_spec.rb5
-rw-r--r--spec/serializers/analytics_merge_request_serializer_spec.rb5
-rw-r--r--spec/serializers/analytics_stage_serializer_spec.rb14
-rw-r--r--spec/serializers/analytics_summary_serializer_spec.rb19
-rw-r--r--spec/serializers/environment_serializer_spec.rb9
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb6
-rw-r--r--spec/services/labels/promote_service_spec.rb187
-rw-r--r--spec/services/notification_service_spec.rb339
-rw-r--r--spec/services/search_service_spec.rb19
-rw-r--r--spec/services/system_hooks_service_spec.rb2
-rw-r--r--spec/services/system_note_service_spec.rb4
-rw-r--r--spec/spec_helper.rb4
-rw-r--r--spec/support/cycle_analytics_helpers/test_generation.rb2
-rw-r--r--spec/support/mentionable_shared_examples.rb2
-rw-r--r--spec/support/mobile_helpers.rb13
-rw-r--r--spec/support/slack_mattermost_notifications_shared_examples.rb6
-rw-r--r--spec/views/ci/lints/show.html.haml_spec.rb2
-rw-r--r--spec/views/projects/builds/show.html.haml_spec.rb30
163 files changed, 2123 insertions, 686 deletions
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
new file mode 100644
index 00000000000..9dceeca168d
--- /dev/null
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe Explore::ProjectsController do
+ describe 'GET #trending' do
+ context 'sorting by update date' do
+ let(:project1) { create(:empty_project, :public, updated_at: 3.days.ago) }
+ let(:project2) { create(:empty_project, :public, updated_at: 1.day.ago) }
+
+ before do
+ create(:trending_project, project: project1)
+ create(:trending_project, project: project2)
+ end
+
+ it 'sorts by last updated' do
+ get :trending, sort: 'updated_desc'
+
+ expect(assigns(:projects)).to eq [project2, project1]
+ end
+
+ it 'sorts by oldest updated' do
+ get :trending, sort: 'updated_asc'
+
+ expect(assigns(:projects)).to eq [project1, project2]
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index a95cfc5c6be..ebd2d0e092b 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -4,7 +4,6 @@ describe Projects::CommitController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:commit) { project.commit("master") }
- let(:pipeline) { create(:ci_pipeline, project: project, commit: commit) }
let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
let(:master_pickable_commit) { project.commit(master_pickable_sha) }
@@ -322,11 +321,26 @@ describe Projects::CommitController do
end
context 'when the commit exists' do
- context 'when the commit has one or more pipelines' do
- it 'shows pipelines' do
- get_pipelines(id: commit.id)
+ context 'when the commit has pipelines' do
+ before do
+ create(:ci_pipeline, project: project, sha: commit.id)
+ end
+
+ context 'when rendering a HTML format' do
+ it 'shows pipelines' do
+ get_pipelines(id: commit.id)
+
+ expect(response).to be_ok
+ end
+ end
- expect(response).to be_ok
+ context 'when rendering a JSON format' do
+ it 'responds with serialized pipelines' do
+ get_pipelines(id: commit.id, format: :json)
+
+ expect(response).to be_ok
+ expect(JSON.parse(response.body)).not_to be_empty
+ end
end
end
end
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index ec6cea5c0f4..3e0326dd47d 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -112,4 +112,49 @@ describe Projects::LabelsController do
post :toggle_subscription, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label.to_param
end
end
+
+ describe 'POST #promote' do
+ let!(:promoted_label_name) { "Promoted Label" }
+ let!(:label_1) { create(:label, title: promoted_label_name, project: project) }
+
+ context 'not group owner' do
+ it 'denies access' do
+ post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'group owner' do
+ before do
+ GroupMember.add_users_to_group(group, [user], :owner)
+ end
+
+ it 'gives access' do
+ post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
+
+ expect(response).to redirect_to(namespace_project_labels_path)
+ end
+
+ it 'promotes the label' do
+ post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
+
+ expect(Label.where(id: label_1.id)).to be_empty
+ expect(GroupLabel.find_by(title: promoted_label_name)).not_to be_nil
+ end
+
+ context 'service raising InvalidRecord' do
+ before do
+ expect_any_instance_of(Labels::PromoteService).to receive(:execute) do |label|
+ raise ActiveRecord::RecordInvalid.new(label_1)
+ end
+ end
+
+ it 'returns to label list' do
+ post :promote, namespace_id: project.namespace.to_param, project_id: project.to_param, id: label_1.to_param
+ expect(response).to redirect_to(namespace_project_labels_path)
+ end
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 2ae635a1244..cae733f0cfb 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -13,13 +13,13 @@ describe Projects::MattermostsController do
before do
allow_any_instance_of(MattermostSlashCommandsService).
to receive(:list_teams).and_return([])
+ end
+ it 'accepts the request' do
get(:new,
namespace_id: project.namespace.to_param,
project_id: project.to_param)
- end
- it 'accepts the request' do
expect(response).to have_http_status(200)
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 7ea3ea4f376..e019541e74f 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Projects::MergeRequestsController do
+ include ApiHelpers
+
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
@@ -455,7 +457,7 @@ describe Projects::MergeRequestsController do
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(JSON.parse(response.body)).to have_key('html')
+ expect(json_response).to have_key('html')
end
end
@@ -494,7 +496,7 @@ describe Projects::MergeRequestsController do
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(JSON.parse(response.body)).to have_key('html')
+ expect(json_response).to have_key('html')
end
end
end
@@ -662,18 +664,45 @@ describe Projects::MergeRequestsController do
go format: 'json'
expect(response).to render_template('projects/merge_requests/show/_commits')
- expect(JSON.parse(response.body)).to have_key('html')
+ expect(json_response).to have_key('html')
end
end
end
describe 'GET pipelines' do
- it_behaves_like "loads labels", :pipelines
+ before do
+ create(:ci_pipeline, project: merge_request.source_project,
+ ref: merge_request.source_branch,
+ sha: merge_request.diff_head_sha)
+ end
+
+ context 'when using HTML format' do
+ it_behaves_like "loads labels", :pipelines
+ end
+
+ context 'when using JSON format' do
+ before do
+ get :pipelines,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: merge_request.iid,
+ format: :json
+ end
+
+ it 'responds with a rendered HTML partial' do
+ expect(response)
+ .to render_template('projects/merge_requests/show/_pipelines')
+ expect(json_response).to have_key 'html'
+ end
+
+ it 'responds with serialized pipelines' do
+ expect(json_response).to have_key 'pipelines'
+ expect(json_response['pipelines']).not_to be_empty
+ end
+ end
end
describe 'GET conflicts' do
- let(:json_response) { JSON.parse(response.body) }
-
context 'when the conflicts cannot be resolved in the UI' do
before do
allow_any_instance_of(Gitlab::Conflict::Parser).
@@ -770,8 +799,6 @@ describe Projects::MergeRequestsController do
end
describe 'GET conflict_for_path' do
- let(:json_response) { JSON.parse(response.body) }
-
def conflict_for_path(path)
get :conflict_for_path,
namespace_id: merge_request_with_conflicts.project.namespace.to_param,
@@ -826,7 +853,6 @@ describe Projects::MergeRequestsController do
end
context 'POST resolve_conflicts' do
- let(:json_response) { JSON.parse(response.body) }
let!(:original_head_sha) { merge_request_with_conflicts.diff_head_sha }
def resolve_conflicts(files)
@@ -1024,7 +1050,6 @@ describe Projects::MergeRequestsController do
let!(:forked) { create(:project) }
let!(:environment) { create(:environment, project: forked) }
let!(:deployment) { create(:deployment, environment: environment, sha: forked.commit.id, ref: 'master') }
- let(:json_response) { JSON.parse(response.body) }
let(:admin) { create(:admin) }
let(:merge_request) do
diff --git a/spec/factories/trending_project.rb b/spec/factories/trending_project.rb
new file mode 100644
index 00000000000..246176611dc
--- /dev/null
+++ b/spec/factories/trending_project.rb
@@ -0,0 +1,6 @@
+FactoryGirl.define do
+ # TrendingProject
+ factory :trending_project, class: 'TrendingProject' do
+ project
+ end
+end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 188d33e8ef4..c28bb0dcdae 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -141,6 +141,36 @@ describe 'Issue Boards', feature: true, js: true do
end
end
end
+
+ it 'resets assignee dropdown' do
+ page.within(first('.board')) do
+ first('.card').click
+ end
+
+ page.within('.assignee') do
+ click_link 'Edit'
+
+ wait_for_ajax
+
+ page.within('.dropdown-menu-user') do
+ click_link user.name
+
+ wait_for_vue_resource
+ end
+
+ expect(page).to have_content(user.name)
+ end
+
+ page.within(first('.board')) do
+ find('.card:nth-child(2)').click
+ end
+
+ page.within('.assignee') do
+ click_link 'Edit'
+
+ expect(page).not_to have_selector('.is-active')
+ end
+ end
end
context 'milestone' do
diff --git a/spec/features/environment_spec.rb b/spec/features/environment_spec.rb
index 56f6cd2e095..511c95b758f 100644
--- a/spec/features/environment_spec.rb
+++ b/spec/features/environment_spec.rb
@@ -19,6 +19,10 @@ feature 'Environment', :feature do
visit_environment(environment)
end
+ scenario 'shows environment name' do
+ expect(page).to have_content(environment.name)
+ end
+
context 'without deployments' do
scenario 'does show no deployments' do
expect(page).to have_content('You don\'t have any deployments right now.')
diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb
index 72b984cfab8..c033b693213 100644
--- a/spec/features/environments_spec.rb
+++ b/spec/features/environments_spec.rb
@@ -194,7 +194,7 @@ feature 'Environments page', :feature, :js do
end
scenario 'does create a new pipeline' do
- expect(page).to have_content('Production')
+ expect(page).to have_content('production')
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index 8a155c3bfc5..93763f092fb 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -43,14 +43,6 @@ describe 'Dropdown assignee', js: true, feature: true do
expect(page).to have_css(js_dropdown_assignee, visible: true)
end
- it 'shows assigned to me link' do
- filtered_search.set('assignee:')
-
- page.within js_dropdown_assignee do
- expect(page).to have_content('Assigned to me')
- end
- end
-
it 'closes when the search bar is unfocused' do
find('body').click()
@@ -129,14 +121,6 @@ describe 'Dropdown assignee', js: true, feature: true do
filtered_search.set('assignee:')
end
- it 'filters by current user' do
- page.within js_dropdown_assignee do
- click_button 'Assigned to me'
- end
-
- expect(filtered_search.value).to eq("assignee:#{user.to_reference} ")
- end
-
it 'fills in the assignee username when the assignee has not been filtered' do
click_assignee(user_jacob.name)
@@ -185,4 +169,22 @@ describe 'Dropdown assignee', js: true, feature: true do
expect(page).to have_css(js_dropdown_assignee, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('assignee')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_assignee_size
+
+ expect(initial_size).to be > 0
+
+ new_user = create(:user)
+ project.team << [new_user, :master]
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('assignee')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_assignee_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index a5d5d9d4c5e..59e302f0e2d 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -157,4 +157,22 @@ describe 'Dropdown author', js: true, feature: true do
expect(page).to have_css(js_dropdown_author, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('author')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_author_size
+
+ expect(initial_size).to be > 0
+
+ new_user = create(:user)
+ project.team << [new_user, :master]
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('author')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_author_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index f09ad2dd86b..5079eb8dd00 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -249,4 +249,21 @@ describe 'Dropdown label', js: true, feature: true do
expect(page).to have_css(js_dropdown_label, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('label')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_label_size
+
+ expect(initial_size).to be > 0
+
+ create(:label, project: project)
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('label')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_label_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 134e58ad586..0ce16715b86 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -219,4 +219,21 @@ describe 'Dropdown milestone', js: true, feature: true do
expect(page).to have_css(js_dropdown_milestone, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('milestone')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_milestone_size
+
+ expect(initial_size).to be > 0
+
+ create(:milestone, project: project)
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('milestone')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_milestone_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index f48a0193545..3f70a6aa75f 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -773,7 +773,7 @@ describe 'Filter issues', js: true, feature: true do
describe 'RSS feeds' do
it 'updates atom feed link for project issues' do
visit namespace_project_issues_path(project.namespace, project, milestone_title: milestone.title, assignee_id: user.id)
- link = find('.nav-controls a', text: 'Subscribe')
+ link = find_link('Subscribe')
params = CGI.parse(URI.parse(link[:href]).query)
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index bc068b5e7e0..1eb981942ea 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -2,6 +2,7 @@ require 'rails_helper'
feature 'Issue Sidebar', feature: true do
include WaitForAjax
+ include MobileHelpers
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
@@ -59,6 +60,23 @@ feature 'Issue Sidebar', feature: true do
end
end
+ context 'sidebar', js: true do
+ it 'changes size when the screen size is smaller' do
+ sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ # Resize the window
+ resize_screen_sm
+ # Make sure the sidebar is collapsed
+ expect(page).to have_css(sidebar_selector)
+ # Once is collapsed let's open the sidebard and reload
+ open_issue_sidebar
+ refresh
+ expect(page).to have_css(sidebar_selector)
+ # Restore the window size as it was including the sidebar
+ restore_window_size
+ open_issue_sidebar
+ end
+ end
+
context 'creating a new label', js: true do
it 'shows option to crate a new label is present' do
page.within('.block.labels') do
@@ -109,4 +127,11 @@ feature 'Issue Sidebar', feature: true do
def visit_issue(project, issue)
visit namespace_project_issue_path(project.namespace, project, issue)
end
+
+ def open_issue_sidebar
+ page.within('aside.right-sidebar.right-sidebar-collapsed') do
+ find('.js-sidebar-toggle').click
+ sleep 1
+ end
+ end
end
diff --git a/spec/features/issues/new_branch_button_spec.rb b/spec/features/issues/new_branch_button_spec.rb
index a4d3053d10c..c0ab42c6822 100644
--- a/spec/features/issues/new_branch_button_spec.rb
+++ b/spec/features/issues/new_branch_button_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Start new branch from an issue', feature: true do
+feature 'Start new branch from an issue', feature: true, js: true do
let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
@@ -11,7 +11,7 @@ feature 'Start new branch from an issue', feature: true do
login_as(user)
end
- it 'shows the new branch button', js: true do
+ it 'shows the new branch button' do
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_css('#new-branch .available')
@@ -34,16 +34,26 @@ feature 'Start new branch from an issue', feature: true do
visit namespace_project_issue_path(project.namespace, project, issue)
end
- it "hides the new branch button", js: true do
+ it "hides the new branch button" do
expect(page).to have_css('#new-branch .unavailable')
expect(page).not_to have_css('#new-branch .available')
expect(page).to have_content /1 Related Merge Request/
end
end
+
+ context 'when issue is confidential' do
+ it 'hides the new branch button' do
+ issue = create(:issue, :confidential, project: project)
+
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ expect(page).not_to have_css('#new-branch')
+ end
+ end
end
- context "for visiters" do
- it 'shows no buttons', js: true do
+ context 'for visitors' do
+ it 'shows no buttons' do
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).not_to have_css('#new-branch')
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index 76bcfbe523a..ab7d89306db 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -25,6 +25,11 @@ feature 'Login', feature: true do
expect(current_path).to eq root_path
end
+
+ it 'does not show flash messages when login page' do
+ visit root_path
+ expect(page).not_to have_content('You need to sign in or sign up before continuing.')
+ end
end
describe 'with two-factor authentication' do
diff --git a/spec/features/merge_requests/toggler_behavior_spec.rb b/spec/features/merge_requests/toggler_behavior_spec.rb
new file mode 100644
index 00000000000..6958f6a2c9f
--- /dev/null
+++ b/spec/features/merge_requests/toggler_behavior_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+feature 'toggler_behavior', js: true, feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:merge_request) { create(:merge_request, source_project: project, author: user) }
+ let(:note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) }
+ let(:fragment_id) { "#note_#{note.id}" }
+
+ before do
+ login_as :admin
+ project = merge_request.source_project
+ visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}"
+ page.current_window.resize_to(1000, 300)
+ end
+
+ describe 'scroll position' do
+ it 'should be scrolled down to fragment' do
+ page_height = page.current_window.size[1]
+ page_scroll_y = page.evaluate_script("window.scrollY")
+ fragment_position_top = page.evaluate_script("document.querySelector('#{fragment_id}').getBoundingClientRect().top")
+
+ expect(find('.js-toggle-content').visible?).to eq true
+ expect(find(fragment_id).visible?).to eq true
+ expect(fragment_position_top).to be > page_scroll_y
+ expect(fragment_position_top).to be < (page_scroll_y + page_height)
+ end
+ end
+end
diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
index b13674b4db9..2582a540240 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -11,7 +11,7 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
it_behaves_like 'issuable record that supports slash commands in its description and notes', :merge_request do
let(:issuable) { create(:merge_request, source_project: project) }
- let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } }
+ let(:new_url_opts) { { merge_request: { source_branch: 'feature', target_branch: 'master' } } }
end
describe 'merge-request-only commands' do
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
new file mode 100644
index 00000000000..7d1805f5001
--- /dev/null
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+describe 'Merge request', :feature, :js do
+ include WaitForAjax
+
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+
+ visit new_namespace_project_merge_request_path(
+ project.namespace,
+ project,
+ merge_request: {
+ source_project_id: project.id,
+ target_project_id: project.id,
+ source_branch: 'feature',
+ target_branch: 'master'
+ }
+ )
+ end
+
+ it 'shows widget status after creating new merge request' do
+ click_button 'Submit merge request'
+
+ expect(find('.mr-state-widget')).to have_content('Checking ability to merge automatically')
+
+ wait_for_ajax
+
+ expect(page).to have_selector('.accept_merge_request')
+ end
+end
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 52d08982c7a..16dddb2a86b 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -74,6 +74,9 @@ feature 'Import/Export - project export integration test', feature: true, js: tr
Otherwise, please add the exception to +safe_list+ in CURRENT_SPEC using #{sensitive_word} as the key and the
correspondent hash or model as the value.
+ Also, if the attribute is a generated unique token, please add it to RelationFactory::TOKEN_RESET_MODELS if it needs to be
+ reset (to prevent duplicate column problems while importing to the same instance).
+
IMPORT_EXPORT_CONFIG: #{Gitlab::ImportExport.config_file}
CURRENT_SPEC: #{__FILE__}
MSG
diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz
index 7655c2b351f..20cdfbae24f 100644
--- a/spec/features/projects/import_export/test_project_export.tar.gz
+++ b/spec/features/projects/import_export/test_project_export.tar.gz
Binary files differ
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index c9fa8315e79..97ce9cdfd87 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -20,7 +20,7 @@ feature 'Prioritize labels', feature: true do
scenario 'user can prioritize a group label', js: true do
visit namespace_project_labels_path(project.namespace, project)
- expect(page).to have_content('No prioritized labels yet')
+ expect(page).to have_content('Star labels to start sorting by priority')
page.within('.other-labels') do
all('.js-toggle-priority')[1].click
@@ -29,7 +29,7 @@ feature 'Prioritize labels', feature: true do
end
page.within('.prioritized-labels') do
- expect(page).not_to have_content('No prioritized labels yet')
+ expect(page).not_to have_content('Star labels to start sorting by priority')
expect(page).to have_content('feature')
end
end
@@ -55,7 +55,7 @@ feature 'Prioritize labels', feature: true do
scenario 'user can prioritize a project label', js: true do
visit namespace_project_labels_path(project.namespace, project)
- expect(page).to have_content('No prioritized labels yet')
+ expect(page).to have_content('Star labels to start sorting by priority')
page.within('.other-labels') do
first('.js-toggle-priority').click
@@ -64,7 +64,7 @@ feature 'Prioritize labels', feature: true do
end
page.within('.prioritized-labels') do
- expect(page).not_to have_content('No prioritized labels yet')
+ expect(page).not_to have_content('Star labels to start sorting by priority')
expect(page).to have_content('bug')
end
end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index abfc46601fb..b56e562b2b6 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -1,11 +1,13 @@
require "spec_helper"
feature "New project", feature: true do
- context "Visibility level selector" do
- let(:user) { create(:admin) }
+ let(:user) { create(:admin) }
- before { login_as(user) }
+ before do
+ login_as(user)
+ end
+ context "Visibility level selector" do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
@@ -16,4 +18,16 @@ feature "New project", feature: true do
end
end
end
+
+ context 'Import project options' do
+ before do
+ visit new_project_path
+ end
+
+ it 'does not autocomplete sensitive git repo URL' do
+ autocomplete = find('#project_import_url')['autocomplete']
+
+ expect(autocomplete).to eq('off')
+ end
+ end
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index e673ece37c3..917b545e98b 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -66,8 +66,8 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has running builds' do
it 'shows a running icon and a cancel action for the running build' do
page.within('#ci-badge-deploy') do
- expect(page).to have_selector('.ci-status-icon-running')
- expect(page).to have_selector('.ci-action-icon-container .fa-ban')
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ expect(page).to have_selector('.js-icon-action-cancel')
expect(page).to have_content('deploy')
end
end
@@ -82,12 +82,12 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has successful builds' do
it 'shows the success icon and a retry action for the successful build' do
page.within('#ci-badge-build') do
- expect(page).to have_selector('.ci-status-icon-success')
+ expect(page).to have_selector('.js-ci-status-icon-success')
expect(page).to have_content('build')
end
page.within('#ci-badge-build .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
+ expect(page).to have_selector('.js-icon-action-retry')
end
end
@@ -101,12 +101,12 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has failed builds' do
it 'shows the failed icon and a retry action for the failed build' do
page.within('#ci-badge-test') do
- expect(page).to have_selector('.ci-status-icon-failed')
+ expect(page).to have_selector('.js-ci-status-icon-failed')
expect(page).to have_content('test')
end
page.within('#ci-badge-test .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
+ expect(page).to have_selector('.js-icon-action-retry')
end
end
@@ -120,12 +120,12 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has manual builds' do
it 'shows the skipped icon and a play action for the manual build' do
page.within('#ci-badge-manual-build') do
- expect(page).to have_selector('.ci-status-icon-manual')
+ expect(page).to have_selector('.js-ci-status-icon-manual')
expect(page).to have_content('manual')
end
page.within('#ci-badge-manual-build .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-play')
+ expect(page).to have_selector('.js-icon-action-play')
end
end
@@ -138,7 +138,7 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has external build' do
it 'shows the success icon and the generic comit status build' do
- expect(page).to have_selector('.ci-status-icon-success')
+ expect(page).to have_selector('.js-ci-status-icon-success')
expect(page).to have_content('jenkins')
expect(page).to have_link('jenkins', href: 'http://gitlab.com/status')
end
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 55d5d082c6e..5d0314d5c09 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -37,7 +37,7 @@ describe 'Edit Project Settings', feature: true do
it 'shows errors for invalid project path/name' do
visit edit_namespace_project_path(project.namespace, project)
- fill_in 'Project name', with: 'foo&bar'
+ fill_in 'project_name', with: 'foo&bar'
fill_in 'Path', with: 'foo&bar'
click_button 'Rename project'
@@ -53,7 +53,7 @@ describe 'Edit Project Settings', feature: true do
it 'shows error for invalid project name' do
visit edit_namespace_project_path(project.namespace, project)
- fill_in 'Project name', with: '🚀 foo bar ☁️'
+ fill_in 'project_name', with: '🚀 foo bar ☁️'
click_button 'Rename project'
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index 86a07b2c679..042a1ccab51 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -99,6 +99,15 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(select_element.all('option').count).to eq(3)
end
+ it 'shows an error alert with the error message if there is an error requesting teams' do
+ allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [[], 'test mattermost error message'] }
+
+ click_link 'Add to Mattermost'
+
+ expect(page).to have_selector('.alert')
+ expect(page).to have_content('test mattermost error message')
+ end
+
def stub_teams(count: 0)
teams = create_teams(count)
diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
index 3850e930b6d..1b352be9331 100644
--- a/spec/features/todos/todos_spec.rb
+++ b/spec/features/todos/todos_spec.rb
@@ -171,7 +171,7 @@ describe 'Dashboard Todos', feature: true do
it 'links to the pipelines for the merge request' do
href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target)
- expect(page).to have_link "merge request #{todo.target.to_reference}", href
+ expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href
end
end
end
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index a4f08dc4af0..df71680e44c 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -115,6 +115,46 @@ describe IssuablesHelper do
end
end
+ describe '#issuable_reference' do
+ context 'when show_full_reference truthy' do
+ it 'display issuable full reference' do
+ assign(:show_full_reference, true)
+ issue = build_stubbed(:issue)
+
+ expect(helper.issuable_reference(issue)).to eql(issue.to_reference(full: true))
+ end
+ end
+
+ context 'when show_full_reference falsey' do
+ context 'when @group present' do
+ it 'display issuable reference to @group' do
+ project = build_stubbed(:project)
+
+ assign(:show_full_reference, nil)
+ assign(:group, project.namespace)
+
+ issue = build_stubbed(:issue)
+
+ expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project.namespace))
+ end
+ end
+
+ context 'when @project present' do
+ it 'display issuable reference to @project' do
+ project = build_stubbed(:project)
+
+ assign(:show_full_reference, nil)
+ assign(:group, nil)
+ assign(:project, project)
+
+ issue = build_stubbed(:issue)
+
+ expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project))
+ end
+ end
+ end
+ end
+
describe '#issuable_filter_present?' do
it 'returns true when any key is present' do
allow(helper).to receive(:params).and_return(
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index e51720f10ed..b7e547dc1f5 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -41,6 +41,11 @@ describe SearchHelper do
expect(search_autocomplete_opts("gro").size).to eq(1)
end
+ it "includes nested group" do
+ create(:group, :nested, name: 'foo').add_owner(user)
+ expect(search_autocomplete_opts('foo').size).to eq(1)
+ end
+
it "includes the user's projects" do
project = create(:empty_project, namespace: create(:namespace, owner: user))
expect(search_autocomplete_opts(project.name).size).to eq(1)
diff --git a/spec/javascripts/commits_spec.js.es6 b/spec/javascripts/commits_spec.js.es6
new file mode 100644
index 00000000000..bb9a9072f3a
--- /dev/null
+++ b/spec/javascripts/commits_spec.js.es6
@@ -0,0 +1,50 @@
+/* global CommitsList */
+
+//= require jquery.endless-scroll
+//= require pager
+//= require commits
+
+(() => {
+ describe('Commits List', () => {
+ beforeEach(() => {
+ setFixtures(`
+ <form class="commits-search-form" action="/h5bp/html5-boilerplate/commits/master">
+ <input id="commits-search">
+ </form>
+ <ol id="commits-list"></ol>
+ `);
+ });
+
+ it('should be defined', () => {
+ expect(CommitsList).toBeDefined();
+ });
+
+ describe('on entering input', () => {
+ let ajaxSpy;
+
+ beforeEach(() => {
+ CommitsList.init(25);
+ CommitsList.searchField.val('');
+ spyOn(history, 'replaceState').and.stub();
+ ajaxSpy = spyOn(jQuery, 'ajax').and.callFake((req) => {
+ req.success({
+ data: '<li>Result</li>',
+ });
+ });
+ });
+
+ it('should save the last search string', () => {
+ CommitsList.searchField.val('GitLab');
+ CommitsList.filterResults();
+ expect(ajaxSpy).toHaveBeenCalled();
+ expect(CommitsList.lastSearch).toEqual('GitLab');
+ });
+
+ it('should not make ajax call if the input does not change', () => {
+ CommitsList.filterResults();
+ expect(ajaxSpy).not.toHaveBeenCalled();
+ expect(CommitsList.lastSearch).toEqual('');
+ });
+ });
+ });
+})();
diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js.es6 b/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
new file mode 100644
index 00000000000..5eba4343a1d
--- /dev/null
+++ b/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
@@ -0,0 +1,40 @@
+//= require filtered_search/dropdown_utils
+//= require filtered_search/filtered_search_tokenizer
+//= require filtered_search/filtered_search_dropdown
+//= require filtered_search/dropdown_user
+
+(() => {
+ describe('Dropdown User', () => {
+ describe('getSearchInput', () => {
+ let dropdownUser;
+
+ beforeEach(() => {
+ spyOn(gl.FilteredSearchDropdown.prototype, 'constructor').and.callFake(() => {});
+ spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
+ spyOn(gl.DropdownUtils, 'getSearchInput').and.callFake(() => {});
+
+ dropdownUser = new gl.DropdownUser();
+ });
+
+ it('should not return the double quote found in value', () => {
+ spyOn(gl.FilteredSearchTokenizer, 'processTokens').and.returnValue({
+ lastToken: {
+ value: '"johnny appleseed',
+ },
+ });
+
+ expect(dropdownUser.getSearchInput()).toBe('johnny appleseed');
+ });
+
+ it('should not return the single quote found in value', () => {
+ spyOn(gl.FilteredSearchTokenizer, 'processTokens').and.returnValue({
+ lastToken: {
+ value: '\'larry boy',
+ },
+ });
+
+ expect(dropdownUser.getSearchInput()).toBe('larry boy');
+ });
+ });
+ });
+})();
diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6 b/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6
index 19bd8d53219..89e49b7c511 100644
--- a/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6
+++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6
@@ -64,6 +64,68 @@
const updatedItem = gl.DropdownUtils.filterWithSymbol('@', input, item);
expect(updatedItem.droplab_hidden).toBe(false);
});
+
+ describe('filters multiple word title', () => {
+ const multipleWordItem = {
+ title: 'Community Contributions',
+ };
+
+ it('should filter with double quote', () => {
+ input.value = 'label:"';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with double quote and symbol', () => {
+ input.value = 'label:~"';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with double quote and multiple words', () => {
+ input.value = 'label:"community con';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with double quote, symbol and multiple words', () => {
+ input.value = 'label:~"community con';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with single quote', () => {
+ input.value = 'label:\'';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with single quote and symbol', () => {
+ input.value = 'label:~\'';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with single quote and multiple words', () => {
+ input.value = 'label:\'community con';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+
+ it('should filter with single quote, symbol and multiple words', () => {
+ input.value = 'label:~\'community con';
+
+ const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+ expect(updatedItem.droplab_hidden).toBe(false);
+ });
+ });
});
describe('filterHint', () => {
@@ -130,5 +192,99 @@
expect(result).toBe(false);
});
});
+
+ describe('getInputSelectionPosition', () => {
+ describe('word with trailing spaces', () => {
+ const value = 'label:none ';
+
+ it('should return selectionStart when cursor is at the trailing space', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 11,
+ value,
+ });
+
+ expect(left).toBe(11);
+ expect(right).toBe(11);
+ });
+
+ it('should return input when cursor is at the start of input', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 0,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(10);
+ });
+
+ it('should return input when cursor is at the middle of input', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 7,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(10);
+ });
+
+ it('should return input when cursor is at the end of input', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 10,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(10);
+ });
+ });
+
+ describe('multiple words', () => {
+ const value = 'label:~"Community Contribution"';
+
+ it('should return input when cursor is after the first word', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 17,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(31);
+ });
+
+ it('should return input when cursor is before the second word', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 18,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(31);
+ });
+ });
+
+ describe('incomplete multiple words', () => {
+ const value = 'label:~"Community Contribution';
+
+ it('should return entire input when cursor is at the start of input', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 0,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(30);
+ });
+
+ it('should return entire input when cursor is at the end of input', () => {
+ const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
+ selectionStart: 30,
+ value,
+ });
+
+ expect(left).toBe(0);
+ expect(right).toBe(30);
+ });
+ });
+ });
});
})();
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
new file mode 100644
index 00000000000..c8b5c2b36ad
--- /dev/null
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
@@ -0,0 +1,68 @@
+/* global Turbolinks */
+
+//= require turbolinks
+//= require lib/utils/common_utils
+//= require filtered_search/filtered_search_token_keys
+//= require filtered_search/filtered_search_tokenizer
+//= require filtered_search/filtered_search_dropdown_manager
+//= require filtered_search/filtered_search_manager
+
+(() => {
+ describe('Filtered Search Manager', () => {
+ describe('search', () => {
+ let manager;
+ const defaultParams = '?scope=all&utf8=✓&state=opened';
+
+ function getInput() {
+ return document.querySelector('.filtered-search');
+ }
+
+ beforeEach(() => {
+ setFixtures(`
+ <input type='text' class='filtered-search' />
+ `);
+
+ spyOn(gl.FilteredSearchManager.prototype, 'bindEvents').and.callFake(() => {});
+ spyOn(gl.FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {});
+ spyOn(gl.FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {});
+ spyOn(gl.utils, 'getParameterByName').and.returnValue(null);
+
+ manager = new gl.FilteredSearchManager();
+ });
+
+ afterEach(() => {
+ getInput().outerHTML = '';
+ });
+
+ it('should search with a single word', () => {
+ getInput().value = 'searchTerm';
+
+ spyOn(Turbolinks, 'visit').and.callFake((url) => {
+ expect(url).toEqual(`${defaultParams}&search=searchTerm`);
+ });
+
+ manager.search();
+ });
+
+ it('should search with multiple words', () => {
+ getInput().value = 'awesome search terms';
+
+ spyOn(Turbolinks, 'visit').and.callFake((url) => {
+ expect(url).toEqual(`${defaultParams}&search=awesome+search+terms`);
+ });
+
+ manager.search();
+ });
+
+ it('should search with special characters', () => {
+ getInput().value = '~!@#$%^&*()_+{}:<>,.?/';
+
+ spyOn(Turbolinks, 'visit').and.callFake((url) => {
+ expect(url).toEqual(`${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`);
+ });
+
+ manager.search();
+ });
+ });
+ });
+})();
diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6
index 6df7c0e44ef..9d9097419ea 100644
--- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6
@@ -72,6 +72,12 @@
const result = gl.FilteredSearchTokenKeys.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
expect(result).toEqual(tokenKeys[0]);
});
+
+ it('should return alternative tokenKey when found by key param', () => {
+ const tokenKeys = gl.FilteredSearchTokenKeys.getAlternatives();
+ const result = gl.FilteredSearchTokenKeys.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
+ expect(result).toEqual(tokenKeys[0]);
+ });
});
describe('searchByConditionUrl', () => {
diff --git a/spec/javascripts/gl_form_spec.js.es6 b/spec/javascripts/gl_form_spec.js.es6
new file mode 100644
index 00000000000..b5f99483bfb
--- /dev/null
+++ b/spec/javascripts/gl_form_spec.js.es6
@@ -0,0 +1,122 @@
+/* global autosize */
+/*= require gl_form */
+/*= require autosize */
+/*= require lib/utils/text_utility */
+/*= require lib/utils/common_utils */
+
+describe('GLForm', () => {
+ const global = window.gl || (window.gl = {});
+ const GLForm = global.GLForm;
+
+ it('should be defined in the global scope', () => {
+ expect(GLForm).toBeDefined();
+ });
+
+ describe('when instantiated', function () {
+ beforeEach((done) => {
+ this.form = $('<form class="gfm-form"><textarea class="js-gfm-input"></form>');
+ this.textarea = this.form.find('textarea');
+ spyOn($.prototype, 'off').and.returnValue(this.textarea);
+ spyOn($.prototype, 'on').and.returnValue(this.textarea);
+ spyOn($.prototype, 'css');
+ spyOn(window, 'autosize');
+
+ this.glForm = new GLForm(this.form);
+ setTimeout(() => {
+ $.prototype.off.calls.reset();
+ $.prototype.on.calls.reset();
+ $.prototype.css.calls.reset();
+ autosize.calls.reset();
+ done();
+ });
+ });
+
+ describe('.setupAutosize', () => {
+ beforeEach((done) => {
+ this.glForm.setupAutosize();
+ setTimeout(() => {
+ done();
+ });
+ });
+
+ it('should register an autosize event handler on the textarea', () => {
+ expect($.prototype.off).toHaveBeenCalledWith('autosize:resized');
+ expect($.prototype.on).toHaveBeenCalledWith('autosize:resized', jasmine.any(Function));
+ });
+
+ it('should register a mouseup event handler on the textarea', () => {
+ expect($.prototype.off).toHaveBeenCalledWith('mouseup.autosize');
+ expect($.prototype.on).toHaveBeenCalledWith('mouseup.autosize', jasmine.any(Function));
+ });
+
+ it('should autosize the textarea', () => {
+ expect(autosize).toHaveBeenCalledWith(jasmine.any(Object));
+ });
+
+ it('should set the resize css property to vertical', () => {
+ expect($.prototype.css).toHaveBeenCalledWith('resize', 'vertical');
+ });
+ });
+
+ describe('.setHeightData', () => {
+ beforeEach(() => {
+ spyOn($.prototype, 'data');
+ spyOn($.prototype, 'outerHeight').and.returnValue(200);
+ this.glForm.setHeightData();
+ });
+
+ it('should set the height data attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height', 200);
+ });
+
+ it('should call outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalled();
+ });
+ });
+
+ describe('.destroyAutosize', () => {
+ describe('when called', () => {
+ beforeEach(() => {
+ spyOn($.prototype, 'data');
+ spyOn($.prototype, 'outerHeight').and.returnValue(200);
+ spyOn(window, 'outerHeight').and.returnValue(400);
+ spyOn(autosize, 'destroy');
+
+ this.glForm.destroyAutosize();
+ });
+
+ it('should call outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalled();
+ });
+
+ it('should get data-height attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height');
+ });
+
+ it('should call autosize destroy', () => {
+ expect(autosize.destroy).toHaveBeenCalledWith(this.textarea);
+ });
+
+ it('should set the data-height attribute', () => {
+ expect($.prototype.data).toHaveBeenCalledWith('height', 200);
+ });
+
+ it('should set the outerHeight', () => {
+ expect($.prototype.outerHeight).toHaveBeenCalledWith(200);
+ });
+
+ it('should set the css', () => {
+ expect($.prototype.css).toHaveBeenCalledWith('max-height', window.outerHeight);
+ });
+ });
+
+ it('should return undefined if the data-height equals the outerHeight', () => {
+ spyOn($.prototype, 'outerHeight').and.returnValue(200);
+ spyOn($.prototype, 'data').and.returnValue(200);
+ spyOn(autosize, 'destroy');
+ expect(this.glForm.destroyAutosize()).toBeUndefined();
+ expect(autosize.destroy).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js
index 386fc8f514e..db11c2516a6 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/shortcuts_issuable_spec.js
@@ -11,9 +11,9 @@
beforeEach(function() {
loadFixtures(fixtureName);
document.querySelector('.js-new-note-form').classList.add('js-main-target-form');
- return this.shortcut = new ShortcutsIssuable();
+ this.shortcut = new ShortcutsIssuable();
});
- return describe('#replyWithSelectedText', function() {
+ describe('#replyWithSelectedText', function() {
var stubSelection;
// Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML.
stubSelection = function(html) {
@@ -24,56 +24,61 @@
};
};
beforeEach(function() {
- return this.selector = 'form.js-main-target-form textarea#note_note';
+ this.selector = 'form.js-main-target-form textarea#note_note';
});
describe('with empty selection', function() {
- return it('does nothing', function() {
- stubSelection('');
+ it('does not return an error', function() {
this.shortcut.replyWithSelectedText();
- return expect($(this.selector).val()).toBe('');
+ expect($(this.selector).val()).toBe('');
+ });
+ it('triggers `input`', function() {
+ var focused = false;
+ $(this.selector).on('focus', function() {
+ focused = true;
+ });
+ this.shortcut.replyWithSelectedText();
+ expect(focused).toBe(true);
});
});
describe('with any selection', function() {
beforeEach(function() {
- return stubSelection('<p>Selected text.</p>');
+ stubSelection('<p>Selected text.</p>');
});
it('leaves existing input intact', function() {
$(this.selector).val('This text was already here.');
expect($(this.selector).val()).toBe('This text was already here.');
this.shortcut.replyWithSelectedText();
- return expect($(this.selector).val()).toBe("This text was already here.\n\n> Selected text.\n\n");
+ expect($(this.selector).val()).toBe("This text was already here.\n\n> Selected text.\n\n");
});
it('triggers `input`', function() {
- var triggered;
- triggered = false;
+ var triggered = false;
$(this.selector).on('input', function() {
- return triggered = true;
+ triggered = true;
});
this.shortcut.replyWithSelectedText();
- return expect(triggered).toBe(true);
+ expect(triggered).toBe(true);
});
- return it('triggers `focus`', function() {
- var focused;
- focused = false;
+ it('triggers `focus`', function() {
+ var focused = false;
$(this.selector).on('focus', function() {
- return focused = true;
+ focused = true;
});
this.shortcut.replyWithSelectedText();
- return expect(focused).toBe(true);
+ expect(focused).toBe(true);
});
});
describe('with a one-line selection', function() {
- return it('quotes the selection', function() {
+ it('quotes the selection', function() {
stubSelection('<p>This text has been selected.</p>');
this.shortcut.replyWithSelectedText();
- return expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
+ expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
});
});
- return describe('with a multi-line selection', function() {
- return it('quotes the selected lines as a group', function() {
+ describe('with a multi-line selection', function() {
+ it('quotes the selected lines as a group', function() {
stubSelection("<p>Selected line one.</p>\n\n<p>Selected line two.</p>\n\n<p>Selected line three.</p>");
this.shortcut.replyWithSelectedText();
- return expect($(this.selector).val()).toBe("> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n");
+ expect($(this.selector).val()).toBe("> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n");
});
});
});
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index f251c0dd25a..b234de4c772 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -58,58 +58,102 @@ describe Gitlab::Auth, lib: true do
expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
end
- it 'recognizes user lfs tokens' do
- user = create(:user)
- token = Gitlab::LfsToken.new(user).token
+ context 'while using LFS authenticate' do
+ it 'recognizes user lfs tokens' do
+ user = create(:user)
+ token = Gitlab::LfsToken.new(user).token
- expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.username)
- expect(gl_auth.find_for_git_client(user.username, token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :lfs_token, full_authentication_abilities))
- end
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.username)
+ expect(gl_auth.find_for_git_client(user.username, token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :lfs_token, full_authentication_abilities))
+ end
- it 'recognizes deploy key lfs tokens' do
- key = create(:deploy_key)
- token = Gitlab::LfsToken.new(key).token
+ it 'recognizes deploy key lfs tokens' do
+ key = create(:deploy_key)
+ token = Gitlab::LfsToken.new(key).token
- expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: "lfs+deploy-key-#{key.id}")
- expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_authentication_abilities))
- end
+ expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: "lfs+deploy-key-#{key.id}")
+ expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_authentication_abilities))
+ end
- context "while using OAuth tokens as passwords" do
- it 'succeeds for OAuth tokens with the `api` scope' do
+ it 'does not try password auth before oauth' do
user = create(:user)
- application = Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user)
- token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: "api")
+ token = Gitlab::LfsToken.new(user).token
+
+ expect(gl_auth).not_to receive(:find_with_user_password)
+ gl_auth.find_for_git_client(user.username, token, project: nil, ip: 'ip')
+ end
+ end
+
+ context 'while using OAuth tokens as passwords' do
+ let(:user) { create(:user) }
+ let(:token_w_api_scope) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
+ let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
+
+ it 'succeeds for OAuth tokens with the `api` scope' do
expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'oauth2')
- expect(gl_auth.find_for_git_client("oauth2", token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :oauth, read_authentication_abilities))
+ expect(gl_auth.find_for_git_client("oauth2", token_w_api_scope.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :oauth, read_authentication_abilities))
end
it 'fails for OAuth tokens with other scopes' do
- user = create(:user)
- application = Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user)
- token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: "read_user")
+ token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'read_user')
expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'oauth2')
expect(gl_auth.find_for_git_client("oauth2", token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil))
end
+
+ it 'does not try password auth before oauth' do
+ expect(gl_auth).not_to receive(:find_with_user_password)
+
+ gl_auth.find_for_git_client("oauth2", token_w_api_scope.token, project: nil, ip: 'ip')
+ end
end
- context "while using personal access tokens as passwords" do
- it 'succeeds for personal access tokens with the `api` scope' do
- user = create(:user)
- personal_access_token = create(:personal_access_token, user: user, scopes: ['api'])
+ context 'while using personal access tokens as passwords' do
+ let(:user) { create(:user) }
+ let(:token_w_api_scope) { create(:personal_access_token, user: user, scopes: ['api']) }
+ it 'succeeds for personal access tokens with the `api` scope' do
expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.email)
- expect(gl_auth.find_for_git_client(user.email, personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :personal_token, full_authentication_abilities))
+ expect(gl_auth.find_for_git_client(user.email, token_w_api_scope.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :personal_token, full_authentication_abilities))
end
it 'fails for personal access tokens with other scopes' do
- user = create(:user)
personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user'])
expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: user.email)
expect(gl_auth.find_for_git_client(user.email, personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil))
end
+
+ it 'does not try password auth before personal access tokens' do
+ expect(gl_auth).not_to receive(:find_with_user_password)
+
+ gl_auth.find_for_git_client(user.email, token_w_api_scope.token, project: nil, ip: 'ip')
+ end
+ end
+
+ context 'while using regular user and password' do
+ it 'falls through lfs authentication' do
+ user = create(
+ :user,
+ username: 'normal_user',
+ password: 'my-secret',
+ )
+
+ expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
+ .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
+ end
+
+ it 'falls through oauth authentication when the username is oauth2' do
+ user = create(
+ :user,
+ username: 'oauth2',
+ password: 'my-secret',
+ )
+
+ expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
+ .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
+ end
end
it 'returns double nil for invalid credentials' do
diff --git a/spec/lib/gitlab/chat_commands/command_spec.rb b/spec/lib/gitlab/chat_commands/command_spec.rb
index 1e81eaef18c..b6e924d67be 100644
--- a/spec/lib/gitlab/chat_commands/command_spec.rb
+++ b/spec/lib/gitlab/chat_commands/command_spec.rb
@@ -24,7 +24,7 @@ describe Gitlab::ChatCommands::Command, service: true do
it 'displays the help message' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to start_with('Available commands')
+ expect(subject[:text]).to start_with('Unknown command')
expect(subject[:text]).to match('/gitlab issue show')
end
end
@@ -34,47 +34,7 @@ describe Gitlab::ChatCommands::Command, service: true do
it 'rejects the actions' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to start_with('Whoops! That action is not allowed')
- end
- end
-
- context 'issue is successfully created' do
- let(:params) { { text: "issue create my new issue" } }
-
- before do
- project.team << [user, :master]
- end
-
- it 'presents the issue' do
- expect(subject[:text]).to match("my new issue")
- end
-
- it 'shows a link to the new issue' do
- expect(subject[:text]).to match(/\/issues\/\d+/)
- end
- end
-
- context 'searching for an issue' do
- let(:params) { { text: 'issue search find me' } }
- let!(:issue) { create(:issue, project: project, title: 'find me') }
-
- before do
- project.team << [user, :master]
- end
-
- context 'a single issue is found' do
- it 'presents the issue' do
- expect(subject[:text]).to match(issue.title)
- end
- end
-
- context 'multiple issues found' do
- let!(:issue2) { create(:issue, project: project, title: "someone find me") }
-
- it 'shows a link to the new issue' do
- expect(subject[:text]).to match(issue.title)
- expect(subject[:text]).to match(issue2.title)
- end
+ expect(subject[:text]).to start_with('Whoops! This action is not allowed')
end
end
@@ -90,7 +50,7 @@ describe Gitlab::ChatCommands::Command, service: true do
context 'and user can not create deployment' do
it 'returns action' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to start_with('Whoops! That action is not allowed')
+ expect(subject[:text]).to start_with('Whoops! This action is not allowed')
end
end
@@ -100,7 +60,7 @@ describe Gitlab::ChatCommands::Command, service: true do
end
it 'returns action' do
- expect(subject[:text]).to include('Deployment from staging to production started.')
+ expect(subject[:text]).to include('Deployment started from staging to production')
expect(subject[:response_type]).to be(:in_channel)
end
@@ -130,7 +90,7 @@ describe Gitlab::ChatCommands::Command, service: true do
context 'IssueCreate is triggered' do
let(:params) { { text: 'issue create my title' } }
- it { is_expected.to eq(Gitlab::ChatCommands::IssueCreate) }
+ it { is_expected.to eq(Gitlab::ChatCommands::IssueNew) }
end
context 'IssueSearch is triggered' do
diff --git a/spec/lib/gitlab/chat_commands/deploy_spec.rb b/spec/lib/gitlab/chat_commands/deploy_spec.rb
index bd8099c92da..b3358a32161 100644
--- a/spec/lib/gitlab/chat_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/chat_commands/deploy_spec.rb
@@ -15,8 +15,9 @@ describe Gitlab::ChatCommands::Deploy, service: true do
end
context 'if no environment is defined' do
- it 'returns nil' do
- expect(subject).to be_nil
+ it 'does not execute an action' do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to eq("No action found to be executed")
end
end
@@ -26,8 +27,9 @@ describe Gitlab::ChatCommands::Deploy, service: true do
let!(:deployment) { create(:deployment, environment: staging, deployable: build) }
context 'without actions' do
- it 'returns nil' do
- expect(subject).to be_nil
+ it 'does not execute an action' do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to eq("No action found to be executed")
end
end
@@ -37,8 +39,8 @@ describe Gitlab::ChatCommands::Deploy, service: true do
end
it 'returns success result' do
- expect(subject.type).to eq(:success)
- expect(subject.message).to include('Deployment from staging to production started')
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject[:text]).to start_with('Deployment started from staging to production')
end
context 'when duplicate action exists' do
@@ -47,8 +49,8 @@ describe Gitlab::ChatCommands::Deploy, service: true do
end
it 'returns error' do
- expect(subject.type).to eq(:error)
- expect(subject.message).to include('Too many actions defined')
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to eq('Too many actions defined')
end
end
@@ -59,9 +61,9 @@ describe Gitlab::ChatCommands::Deploy, service: true do
name: 'teardown', environment: 'production')
end
- it 'returns success result' do
- expect(subject.type).to eq(:success)
- expect(subject.message).to include('Deployment from staging to production started')
+ it 'returns the success message' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject[:text]).to start_with('Deployment started from staging to production')
end
end
end
diff --git a/spec/lib/gitlab/chat_commands/issue_create_spec.rb b/spec/lib/gitlab/chat_commands/issue_new_spec.rb
index 6c71e79ff6d..84c22328064 100644
--- a/spec/lib/gitlab/chat_commands/issue_create_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_new_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::IssueCreate, service: true do
+describe Gitlab::ChatCommands::IssueNew, service: true do
describe '#execute' do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
@@ -18,7 +18,7 @@ describe Gitlab::ChatCommands::IssueCreate, service: true do
it 'creates the issue' do
expect { subject }.to change { project.issues.count }.by(1)
- expect(subject.title).to eq('bird is the word')
+ expect(subject[:response_type]).to be(:in_channel)
end
end
@@ -41,6 +41,16 @@ describe Gitlab::ChatCommands::IssueCreate, service: true do
expect { subject }.to change { project.issues.count }.by(1)
end
end
+
+ context 'issue cannot be created' do
+ let!(:issue) { create(:issue, project: project, title: 'bird is the word') }
+ let(:regex_match) { described_class.match("issue create #{'a' * 512}}") }
+
+ it 'displays the errors' do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to match("- Title is too long")
+ end
+ end
end
describe '.match' do
diff --git a/spec/lib/gitlab/chat_commands/issue_search_spec.rb b/spec/lib/gitlab/chat_commands/issue_search_spec.rb
index 24c06a967fa..551ccb79a58 100644
--- a/spec/lib/gitlab/chat_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_search_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe Gitlab::ChatCommands::IssueSearch, service: true do
describe '#execute' do
- let!(:issue) { create(:issue, title: 'find me') }
+ let!(:issue) { create(:issue, project: project, title: 'find me') }
let!(:confidential) { create(:issue, :confidential, project: project, title: 'mepmep find') }
- let(:project) { issue.project }
+ let(:project) { create(:empty_project) }
let(:user) { issue.author }
let(:regex_match) { described_class.match("issue search find") }
@@ -14,7 +14,8 @@ describe Gitlab::ChatCommands::IssueSearch, service: true do
context 'when the user has no access' do
it 'only returns the open issues' do
- expect(subject).not_to include(confidential)
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to match("not found")
end
end
@@ -24,13 +25,14 @@ describe Gitlab::ChatCommands::IssueSearch, service: true do
end
it 'returns all results' do
- expect(subject).to include(confidential, issue)
+ expect(subject).to have_key(:attachments)
+ expect(subject[:text]).to eq("Here are the 2 issues I found:")
end
end
context 'without hits on the query' do
it 'returns an empty collection' do
- expect(subject).to be_empty
+ expect(subject[:text]).to match("not found")
end
end
end
diff --git a/spec/lib/gitlab/chat_commands/issue_show_spec.rb b/spec/lib/gitlab/chat_commands/issue_show_spec.rb
index 2eab73e49e5..1f20d0a44ce 100644
--- a/spec/lib/gitlab/chat_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_show_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Gitlab::ChatCommands::IssueShow, service: true do
describe '#execute' do
- let(:issue) { create(:issue) }
- let(:project) { issue.project }
+ let(:issue) { create(:issue, project: project) }
+ let(:project) { create(:empty_project) }
let(:user) { issue.author }
let(:regex_match) { described_class.match("issue show #{issue.iid}") }
@@ -16,15 +16,19 @@ describe Gitlab::ChatCommands::IssueShow, service: true do
end
context 'the issue exists' do
+ let(:title) { subject[:attachments].first[:title] }
+
it 'returns the issue' do
- expect(subject.iid).to be issue.iid
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(title).to start_with(issue.title)
end
context 'when its reference is given' do
let(:regex_match) { described_class.match("issue show #{issue.to_reference}") }
it 'shows the issue' do
- expect(subject.iid).to be issue.iid
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(title).to start_with(issue.title)
end
end
end
@@ -32,17 +36,24 @@ describe Gitlab::ChatCommands::IssueShow, service: true do
context 'the issue does not exist' do
let(:regex_match) { described_class.match("issue show 2343242") }
- it "returns nil" do
- expect(subject).to be_nil
+ it "returns not found" do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to match("not found")
end
end
end
- describe 'self.match' do
+ describe '.match' do
it 'matches the iid' do
match = described_class.match("issue show 123")
expect(match[:iid]).to eq("123")
end
+
+ it 'accepts a reference' do
+ match = described_class.match("issue show #{Issue.reference_prefix}123")
+
+ expect(match[:iid]).to eq("123")
+ end
end
end
diff --git a/spec/lib/gitlab/chat_commands/presenters/access_spec.rb b/spec/lib/gitlab/chat_commands/presenters/access_spec.rb
new file mode 100644
index 00000000000..ae41d75ab0c
--- /dev/null
+++ b/spec/lib/gitlab/chat_commands/presenters/access_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe Gitlab::ChatCommands::Presenters::Access do
+ describe '#access_denied' do
+ subject { described_class.new.access_denied }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'displays an error message' do
+ expect(subject[:text]).to match("is not allowed")
+ expect(subject[:response_type]).to be(:ephemeral)
+ end
+ end
+
+ describe '#not_found' do
+ subject { described_class.new.not_found }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'tells the user the resource was not found' do
+ expect(subject[:text]).to match("not found!")
+ expect(subject[:response_type]).to be(:ephemeral)
+ end
+ end
+
+ describe '#authorize' do
+ context 'with an authorization URL' do
+ subject { described_class.new('http://authorize.me').authorize }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'tells the user to authorize' do
+ expect(subject[:text]).to match("connect your GitLab account")
+ expect(subject[:response_type]).to be(:ephemeral)
+ end
+ end
+
+ context 'without authorization url' do
+ subject { described_class.new.authorize }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'tells the user to authorize' do
+ expect(subject[:text]).to match("Couldn't identify you")
+ expect(subject[:response_type]).to be(:ephemeral)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
new file mode 100644
index 00000000000..dc2dd300072
--- /dev/null
+++ b/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe Gitlab::ChatCommands::Presenters::Deploy do
+ let(:build) { create(:ci_build) }
+
+ describe '#present' do
+ subject { described_class.new(build).present('staging', 'prod') }
+
+ it { is_expected.to have_key(:text) }
+ it { is_expected.to have_key(:response_type) }
+ it { is_expected.to have_key(:status) }
+ it { is_expected.not_to have_key(:attachments) }
+
+ it 'messages the channel of the deploy' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject[:text]).to start_with("Deployment started from staging to prod")
+ end
+ end
+
+ describe '#no_actions' do
+ subject { described_class.new(nil).no_actions }
+
+ it { is_expected.to have_key(:text) }
+ it { is_expected.to have_key(:response_type) }
+ it { is_expected.to have_key(:status) }
+ it { is_expected.not_to have_key(:attachments) }
+
+ it 'tells the user there is no action' do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to eq("No action found to be executed")
+ end
+ end
+
+ describe '#too_many_actions' do
+ subject { described_class.new([]).too_many_actions }
+
+ it { is_expected.to have_key(:text) }
+ it { is_expected.to have_key(:response_type) }
+ it { is_expected.to have_key(:status) }
+ it { is_expected.not_to have_key(:attachments) }
+
+ it 'tells the user there is no action' do
+ expect(subject[:response_type]).to be(:ephemeral)
+ expect(subject[:text]).to eq("Too many actions defined")
+ end
+ end
+end
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb
new file mode 100644
index 00000000000..17fcdbc2452
--- /dev/null
+++ b/spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe Gitlab::ChatCommands::Presenters::IssueNew do
+ let(:project) { create(:empty_project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:attachment) { subject[:attachments].first }
+
+ subject { described_class.new(issue).present }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'shows the issue' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject).to have_key(:attachments)
+ expect(attachment[:title]).to start_with(issue.title)
+ end
+end
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
new file mode 100644
index 00000000000..ec6d3e34a96
--- /dev/null
+++ b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe Gitlab::ChatCommands::Presenters::IssueSearch do
+ let(:project) { create(:empty_project) }
+ let(:message) { subject[:text] }
+
+ before { create_list(:issue, 2, project: project) }
+
+ subject { described_class.new(project.issues).present }
+
+ it 'formats the message correct' do
+ is_expected.to have_key(:text)
+ is_expected.to have_key(:status)
+ is_expected.to have_key(:response_type)
+ is_expected.to have_key(:attachments)
+ end
+
+ it 'shows a list of results' do
+ expect(subject[:response_type]).to be(:ephemeral)
+
+ expect(message).to start_with("Here are the 2 issues I found")
+ end
+end
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb
new file mode 100644
index 00000000000..5b678d31fce
--- /dev/null
+++ b/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe Gitlab::ChatCommands::Presenters::IssueShow do
+ let(:project) { create(:empty_project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:attachment) { subject[:attachments].first }
+
+ subject { described_class.new(issue).present }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'shows the issue' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject).to have_key(:attachments)
+ expect(attachment[:title]).to start_with(issue.title)
+ end
+
+ context 'with upvotes' do
+ before do
+ create(:award_emoji, :upvote, awardable: issue)
+ end
+
+ it 'shows the upvote count' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(attachment[:text]).to start_with("**Open** · :+1: 1")
+ end
+ end
+
+ context 'confidential issue' do
+ let(:issue) { create(:issue, project: project) }
+
+ it 'shows an ephemeral response' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(attachment[:text]).to start_with("**Open**")
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
index b3c07347de1..8ad9b7cdf07 100644
--- a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
@@ -62,7 +62,7 @@ describe Gitlab::Ci::Status::Build::Cancelable do
end
describe '#action_icon' do
- it { expect(subject.action_icon).to eq 'ban' }
+ it { expect(subject.action_icon).to eq 'icon_action_cancel' }
end
describe '#action_title' do
diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb
index f1b50a59ce6..f3e72ea1796 100644
--- a/spec/lib/gitlab/ci/status/build/play_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/play_spec.rb
@@ -44,7 +44,7 @@ describe Gitlab::Ci::Status::Build::Play do
end
describe '#action_icon' do
- it { expect(subject.action_icon).to eq 'play' }
+ it { expect(subject.action_icon).to eq 'icon_action_play' }
end
describe '#action_title' do
diff --git a/spec/lib/gitlab/ci/status/build/retryable_spec.rb b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
index 62036f8ec5d..2db0f8d29bd 100644
--- a/spec/lib/gitlab/ci/status/build/retryable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
@@ -62,7 +62,7 @@ describe Gitlab::Ci::Status::Build::Retryable do
end
describe '#action_icon' do
- it { expect(subject.action_icon).to eq 'refresh' }
+ it { expect(subject.action_icon).to eq 'icon_action_retry' }
end
describe '#action_title' do
diff --git a/spec/lib/gitlab/ci/status/build/stop_spec.rb b/spec/lib/gitlab/ci/status/build/stop_spec.rb
index 597e02e86e4..41c2b624774 100644
--- a/spec/lib/gitlab/ci/status/build/stop_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/stop_spec.rb
@@ -46,7 +46,7 @@ describe Gitlab::Ci::Status::Build::Stop do
end
describe '#action_icon' do
- it { expect(subject.action_icon).to eq 'stop' }
+ it { expect(subject.action_icon).to eq 'icon_action_stop' }
end
describe '#action_title' do
diff --git a/spec/lib/gitlab/ci/trace_reader_spec.rb b/spec/lib/gitlab/ci/trace_reader_spec.rb
index f06d78694d6..ff5551bf703 100644
--- a/spec/lib/gitlab/ci/trace_reader_spec.rb
+++ b/spec/lib/gitlab/ci/trace_reader_spec.rb
@@ -11,13 +11,25 @@ describe Gitlab::Ci::TraceReader do
last_lines = random_lines
expected = lines.last(last_lines).join
+ result = subject.read(last_lines: last_lines)
- expect(subject.read(last_lines: last_lines)).to eq(expected)
+ expect(result).to eq(expected)
+ expect(result.encoding).to eq(Encoding.default_external)
end
end
it 'returns everything if trying to get too many lines' do
- expect(build_subject.read(last_lines: lines.size * 2)).to eq(lines.join)
+ result = build_subject.read(last_lines: lines.size * 2)
+
+ expect(result).to eq(lines.join)
+ expect(result.encoding).to eq(Encoding.default_external)
+ end
+
+ it 'returns all contents if last_lines is not specified' do
+ result = build_subject.read
+
+ expect(result).to eq(lines.join)
+ expect(result.encoding).to eq(Encoding.default_external)
end
it 'raises an error if not passing an integer for last_lines' do
diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb
index 0b7984d6ca9..f2cb028206f 100644
--- a/spec/lib/gitlab/import_export/members_mapper_spec.rb
+++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb
@@ -92,5 +92,29 @@ describe Gitlab::ImportExport::MembersMapper, services: true do
expect(members_mapper.map[exported_user_id]).to eq(user2.id)
end
end
+
+ context 'importer same as group member' do
+ let(:user2) { create(:admin, authorized_projects_populated: true) }
+ let(:group) { create(:group) }
+ let(:project) { create(:empty_project, :public, name: 'searchable_project', namespace: group) }
+ let(:members_mapper) do
+ described_class.new(
+ exported_members: exported_members, user: user2, project: project)
+ end
+
+ before do
+ group.add_users([user, user2], GroupMember::DEVELOPER)
+ end
+
+ it 'maps the project member' do
+ expect(members_mapper.map[exported_user_id]).to eq(user2.id)
+ end
+
+ it 'maps the project member if it already exists' do
+ project.add_master(user2)
+
+ expect(members_mapper.map[exported_user_id]).to eq(user2.id)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 2c0750c3377..2e9f60432b4 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -6981,11 +6981,16 @@
]
}
],
- "variables": [
-
- ],
"triggers": [
-
+ {
+ "id": 123,
+ "token": "cdbfasdf44a5958c83654733449e585",
+ "project_id": null,
+ "deleted_at": null,
+ "created_at": "2017-01-16T15:25:28.637Z",
+ "updated_at": "2017-01-16T15:25:28.637Z",
+ "gl_project_id": 123
+ }
],
"deploy_keys": [
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 4b07fa53bf5..40d7d59f03b 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -197,6 +197,20 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
expect(restored_project_json).to be true
end
end
+
+ context 'tokens are regenerated' do
+ before do
+ restored_project_json
+ end
+
+ it 'has a new CI trigger token' do
+ expect(Ci::Trigger.where(token: 'cdbfasdf44a5958c83654733449e585')).to be_empty
+ end
+
+ it 'has a new CI build token' do
+ expect(Ci::Build.where(token: 'abcd')).to be_empty
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/import_export/relation_factory_spec.rb b/spec/lib/gitlab/import_export/relation_factory_spec.rb
index db0084d6823..57e412b0cef 100644
--- a/spec/lib/gitlab/import_export/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/relation_factory_spec.rb
@@ -55,8 +55,8 @@ describe Gitlab::ImportExport::RelationFactory, lib: true do
expect(created_object.project_id).to eq(project.id)
end
- it 'has a token' do
- expect(created_object.token).to eq(token)
+ it 'has a nil token' do
+ expect(created_object.token).to eq(nil)
end
context 'original service exists' do
@@ -178,4 +178,15 @@ describe Gitlab::ImportExport::RelationFactory, lib: true do
expect(created_object.author).to eq(new_user)
end
end
+
+ context 'encrypted attributes' do
+ let(:relation_sym) { 'Ci::Variable' }
+ let(:relation_hash) do
+ create(:ci_variable).as_json
+ end
+
+ it 'has no value for the encrypted attribute' do
+ expect(created_object.value).to be_nil
+ end
+ end
end
diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb
index 888ab80cad5..e9d4af54389 100644
--- a/spec/lib/gitlab/view/presenter/delegated_spec.rb
+++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::View::Presenter::Delegated do
- let(:project) { double(:project, bar: 'baz') }
+ let(:project) { double(:project, user: 'John Doe') }
let(:presenter_class) do
Class.new(described_class)
end
@@ -12,10 +12,14 @@ describe Gitlab::View::Presenter::Delegated do
describe '#initialize' do
it 'takes arbitrary key/values and exposes them' do
- presenter = presenter_class.new(project, user: 'user', foo: 'bar')
+ presenter = presenter_class.new(project, current_user: 'Jane Doe')
- expect(presenter.user).to eq('user')
- expect(presenter.foo).to eq('bar')
+ expect(presenter.current_user).to eq('Jane Doe')
+ end
+
+ it 'raise an error if the presentee already respond to method' do
+ expect { presenter_class.new(project, user: 'Jane Doe') }.
+ to raise_error Gitlab::View::Presenter::CannotOverrideMethodError
end
end
@@ -23,7 +27,7 @@ describe Gitlab::View::Presenter::Delegated do
it 'forwards missing methods to subject' do
presenter = presenter_class.new(project)
- expect(presenter.bar).to eq('baz')
+ expect(presenter.user).to eq('John Doe')
end
end
end
diff --git a/spec/lib/gitlab/view/presenter/factory_spec.rb b/spec/lib/gitlab/view/presenter/factory_spec.rb
index 55c5ecbf92f..70d2e22b48f 100644
--- a/spec/lib/gitlab/view/presenter/factory_spec.rb
+++ b/spec/lib/gitlab/view/presenter/factory_spec.rb
@@ -22,13 +22,6 @@ describe Gitlab::View::Presenter::Factory do
end
describe '#fabricate!' do
- it 'exposes given params' do
- presenter = described_class.new(build, user: 'user', foo: 'bar').fabricate!
-
- expect(presenter.user).to eq('user')
- expect(presenter.foo).to eq('bar')
- end
-
it 'detects the presenter based on the given subject' do
presenter = described_class.new(build).fabricate!
diff --git a/spec/lib/gitlab/view/presenter/simple_spec.rb b/spec/lib/gitlab/view/presenter/simple_spec.rb
index b489bdf1981..1795ed2405b 100644
--- a/spec/lib/gitlab/view/presenter/simple_spec.rb
+++ b/spec/lib/gitlab/view/presenter/simple_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::View::Presenter::Simple do
- let(:project) { double(:project) }
+ let(:project) { double(:project, user: 'John Doe') }
let(:presenter_class) do
Class.new(described_class)
end
@@ -12,10 +12,15 @@ describe Gitlab::View::Presenter::Simple do
describe '#initialize' do
it 'takes arbitrary key/values and exposes them' do
- presenter = presenter_class.new(project, user: 'user', foo: 'bar')
+ presenter = presenter_class.new(project, current_user: 'Jane Doe')
- expect(presenter.user).to eq('user')
- expect(presenter.foo).to eq('bar')
+ expect(presenter.current_user).to eq('Jane Doe')
+ end
+
+ it 'override the presentee attributes' do
+ presenter = presenter_class.new(project, user: 'Jane Doe')
+
+ expect(presenter.user).to eq('Jane Doe')
end
end
@@ -23,7 +28,7 @@ describe Gitlab::View::Presenter::Simple do
it 'does not forward missing methods to subject' do
presenter = presenter_class.new(project)
- expect { presenter.foo }.to raise_error(NoMethodError)
+ expect { presenter.user }.to raise_error(NoMethodError)
end
end
end
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index 4d57efd3c53..2f4a33a1868 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Ability, lib: true do
describe '.can_edit_note?' do
let(:project) { create(:empty_project) }
- let!(:note) { create(:note_on_issue, project: project) }
+ let(:note) { create(:note_on_issue, project: project) }
context 'using an anonymous user' do
it 'returns false' do
@@ -60,7 +60,7 @@ describe Ability, lib: true do
describe '.users_that_can_read_project' do
context 'using a public project' do
it 'returns all the users' do
- project = create(:project, :public)
+ project = create(:empty_project, :public)
user = build(:user)
expect(described_class.users_that_can_read_project([user], project)).
@@ -69,7 +69,7 @@ describe Ability, lib: true do
end
context 'using an internal project' do
- let(:project) { create(:project, :internal) }
+ let(:project) { create(:empty_project, :internal) }
it 'returns users that are administrators' do
user = build(:user, admin: true)
@@ -120,7 +120,7 @@ describe Ability, lib: true do
end
context 'using a private project' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:empty_project, :private) }
it 'returns users that are administrators' do
user = build(:user, admin: true)
@@ -247,7 +247,7 @@ describe Ability, lib: true do
end
describe '.project_disabled_features_rules' do
- let(:project) { create(:project, wiki_access_level: ProjectFeature::DISABLED) }
+ let(:project) { create(:empty_project, wiki_access_level: ProjectFeature::DISABLED) }
subject { described_class.allowed(project.owner, project) }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index f031876e812..47cd5075a7d 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Ci::Build, :models do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:test_trace) { 'This is a test' }
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 2bdd611aeed..426be74cd02 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -284,7 +284,7 @@ describe Ci::Pipeline, models: true do
end
describe 'merge request metrics' do
- let(:project) { FactoryGirl.create :project }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { FactoryGirl.create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master', sha: project.repository.commit('master').id) }
let!(:merge_request) { create(:merge_request, source_project: project, source_branch: pipeline.ref) }
@@ -339,7 +339,7 @@ describe Ci::Pipeline, models: true do
end
context 'with non-empty project' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline,
@@ -890,7 +890,7 @@ describe Ci::Pipeline, models: true do
end
describe "#merge_requests" do
- let(:project) { FactoryGirl.create :project }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { FactoryGirl.create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master', sha: project.repository.commit('master').id) }
it "returns merge requests whose `diff_head_sha` matches the pipeline's SHA" do
@@ -956,7 +956,7 @@ describe Ci::Pipeline, models: true do
end
describe 'notifications when pipeline success or failed' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 2b856ca7af7..3f32248e52b 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -91,8 +91,7 @@ describe Ci::Runner, models: true do
end
describe '#can_pick?' do
- let(:project) { create(:project) }
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:pipeline) { create(:ci_pipeline) }
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:runner) { create(:ci_runner) }
@@ -321,8 +320,8 @@ describe Ci::Runner, models: true do
describe '.assignable_for' do
let(:runner) { create(:ci_runner) }
- let(:project) { create(:project) }
- let(:another_project) { create(:project) }
+ let(:project) { create(:empty_project) }
+ let(:another_project) { create(:empty_project) }
before do
project.runners << runner
diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb
index 30782ca75a0..e4bddf67096 100644
--- a/spec/models/commit_range_spec.rb
+++ b/spec/models/commit_range_spec.rb
@@ -7,7 +7,7 @@ describe CommitRange, models: true do
it { is_expected.to include_module(Referable) }
end
- let!(:project) { create(:project, :public) }
+ let!(:project) { create(:project, :public, :repository) }
let!(:commit1) { project.commit("HEAD~2") }
let!(:commit2) { project.commit }
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index b2202f0fd44..32f9366a14c 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Commit, models: true do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:commit) { project.commit }
describe 'modules' do
@@ -34,7 +34,7 @@ describe Commit, models: true do
end
describe '#to_reference' do
- let(:project) { create(:project, path: 'sample-project') }
+ let(:project) { create(:project, :repository, path: 'sample-project') }
let(:commit) { project.commit }
it 'returns a String reference to the object' do
@@ -42,13 +42,13 @@ describe Commit, models: true do
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:project, :repository, name: 'another-project', namespace: project.namespace)
expect(commit.to_reference(another_project)).to eq "sample-project@#{commit.id}"
end
end
describe '#reference_link_text' do
- let(:project) { create(:project, path: 'sample-project') }
+ let(:project) { create(:project, :repository, path: 'sample-project') }
let(:commit) { project.commit }
it 'returns a String reference to the object' do
@@ -56,7 +56,7 @@ describe Commit, models: true do
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:project, :repository, name: 'another-project', namespace: project.namespace)
expect(commit.reference_link_text(another_project)).to eq "sample-project@#{commit.short_id}"
end
end
@@ -131,7 +131,7 @@ eos
describe '#closes_issues' do
let(:issue) { create :issue, project: project }
- let(:other_project) { create :project, :public }
+ let(:other_project) { create(:empty_project, :public) }
let(:other_issue) { create :issue, project: other_project }
let(:commiter) { create :user }
@@ -154,7 +154,7 @@ eos
end
it_behaves_like 'a mentionable' do
- subject { create(:project).commit }
+ subject { create(:project, :repository).commit }
let(:author) { create(:user, email: subject.author_email) }
let(:backref_text) { "commit #{subject.id}" }
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 64ea607eb95..bf4394f7d5b 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe CommitStatus, models: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline, project: project, sha: project.commit.id)
diff --git a/spec/models/compare_spec.rb b/spec/models/compare_spec.rb
index 49ab3c4b6e9..da003dbf794 100644
--- a/spec/models/compare_spec.rb
+++ b/spec/models/compare_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Compare, models: true do
include RepoHelpers
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:commit) { project.commit }
let(:start_commit) { sample_image_commit }
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index d7d31892e12..545a11912e3 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -301,7 +301,7 @@ describe Issue, "Issuable" do
end
describe '#labels_array' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:issue) { create(:issue, project: project) }
@@ -315,7 +315,7 @@ describe Issue, "Issuable" do
end
describe '#user_notes_count' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
@@ -359,7 +359,7 @@ describe Issue, "Issuable" do
end
describe ".with_label" do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:feature) { create(:label, project: project, title: 'feature') }
let(:enhancement) { create(:label, project: project, title: 'enhancement') }
diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb
index b73028f0bc0..2092576e981 100644
--- a/spec/models/concerns/mentionable_spec.rb
+++ b/spec/models/concerns/mentionable_spec.rb
@@ -13,7 +13,7 @@ describe Mentionable do
end
describe 'references' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:mentionable) { Example.new }
it 'excludes JIRA references' do
@@ -83,13 +83,13 @@ describe Issue, "Mentionable" do
end
describe '#create_cross_references!' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:author) { build(:user) }
let(:commit) { project.commit }
let(:commit2) { project.commit }
let!(:issue) do
- create(:issue, project: project, description: commit.to_reference)
+ create(:issue, project: project, description: "See #{commit.to_reference}")
end
it 'correctly removes already-mentioned Commits' do
@@ -100,7 +100,7 @@ describe Issue, "Mentionable" do
end
describe '#create_new_cross_references!' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:author) { create(:author) }
let(:issues) { create_list(:issue, 2, project: project, author: author) }
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index 0e097559b59..ad703a6c8bb 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -7,7 +7,7 @@ describe Milestone, 'Milestoneish' do
let(:member) { create(:user) }
let(:guest) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:milestone) { create(:milestone, project: project) }
let!(:issue) { create(:issue, project: project, milestone: milestone) }
let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone) }
diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb
index 9041690023f..6cf5877424d 100644
--- a/spec/models/concerns/project_features_compatibility_spec.rb
+++ b/spec/models/concerns/project_features_compatibility_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProjectFeaturesCompatibility do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:features) { %w(issues wiki builds merge_requests snippets) }
# We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table
diff --git a/spec/models/cycle_analytics/code_spec.rb b/spec/models/cycle_analytics/code_spec.rb
index 70f985afefb..3b7cc7d9e2e 100644
--- a/spec/models/cycle_analytics/code_spec.rb
+++ b/spec/models/cycle_analytics/code_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#code', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/cycle_analytics/issue_spec.rb b/spec/models/cycle_analytics/issue_spec.rb
index e4b6a8f4518..5c73edbbc53 100644
--- a/spec/models/cycle_analytics/issue_spec.rb
+++ b/spec/models/cycle_analytics/issue_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#issue', models: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/cycle_analytics/plan_spec.rb b/spec/models/cycle_analytics/plan_spec.rb
index dc5b04852d6..55483fc876a 100644
--- a/spec/models/cycle_analytics/plan_spec.rb
+++ b/spec/models/cycle_analytics/plan_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#plan', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/cycle_analytics/production_spec.rb b/spec/models/cycle_analytics/production_spec.rb
index 3c59c624326..35222e031a0 100644
--- a/spec/models/cycle_analytics/production_spec.rb
+++ b/spec/models/cycle_analytics/production_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#production', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/cycle_analytics/review_spec.rb b/spec/models/cycle_analytics/review_spec.rb
index 45baa5f7006..33d2c0a7416 100644
--- a/spec/models/cycle_analytics/review_spec.rb
+++ b/spec/models/cycle_analytics/review_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#review', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/cycle_analytics/staging_spec.rb b/spec/models/cycle_analytics/staging_spec.rb
index 25c7b19b087..7688985c6a3 100644
--- a/spec/models/cycle_analytics/staging_spec.rb
+++ b/spec/models/cycle_analytics/staging_spec.rb
@@ -3,9 +3,10 @@ require 'spec_helper'
describe 'CycleAnalytics#staging', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
+
subject { CycleAnalytics.new(project, from: from_date) }
generate_cycle_analytics_spec(
diff --git a/spec/models/cycle_analytics/test_spec.rb b/spec/models/cycle_analytics/test_spec.rb
index 27a117d2d76..f857ea6cbec 100644
--- a/spec/models/cycle_analytics/test_spec.rb
+++ b/spec/models/cycle_analytics/test_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'CycleAnalytics#test', feature: true do
extend CycleAnalyticsHelpers::TestGeneration
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
subject { CycleAnalytics.new(project, from: from_date) }
diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb
index 8a1e337c1a3..aacc178a19e 100644
--- a/spec/models/deploy_keys_project_spec.rb
+++ b/spec/models/deploy_keys_project_spec.rb
@@ -12,7 +12,7 @@ describe DeployKeysProject, models: true do
end
describe "Destroying" do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
subject { create(:deploy_keys_project, project: project) }
let(:deploy_key) { subject.deploy_key }
@@ -39,7 +39,7 @@ describe DeployKeysProject, models: true do
end
context "when the deploy key is used by more than one project" do
- let!(:other_project) { create(:project) }
+ let!(:other_project) { create(:empty_project) }
before do
other_project.deploy_keys << deploy_key
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index ca594a320c0..fc4435a2f64 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -17,7 +17,7 @@ describe Deployment, models: true do
it { is_expected.to validate_presence_of(:sha) }
describe '#includes_commit?' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:environment) { create(:environment, project: project) }
let(:deployment) do
create(:deployment, environment: environment, sha: project.commit.id)
diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb
index 3db5937a4f3..9ea3a4b7020 100644
--- a/spec/models/diff_note_spec.rb
+++ b/spec/models/diff_note_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe DiffNote, models: true do
include RepoHelpers
- let(:project) { create(:project) }
- let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.project }
let(:commit) { project.commit(sample_commit.id) }
let(:path) { "files/ruby/popen.rb" }
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 96efe1696c3..eba392044bf 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -32,7 +32,7 @@ describe Environment, models: true do
end
describe '#includes_commit?' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
context 'without a last deployment' do
it "returns false" do
@@ -81,7 +81,7 @@ describe Environment, models: true do
end
describe '#first_deployment_for' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let!(:deployment) { create(:deployment, environment: environment, ref: commit.parent.id) }
let!(:deployment1) { create(:deployment, environment: environment, ref: commit.id) }
let(:head_commit) { project.commit }
@@ -288,6 +288,11 @@ describe Environment, models: true do
"1-foo" => "env-1-foo" + SUFFIX,
"1/foo" => "env-1-foo" + SUFFIX,
"foo-" => "foo" + SUFFIX,
+ "foo--bar" => "foo-bar" + SUFFIX,
+ "foo**bar" => "foo-bar" + SUFFIX,
+ "*-foo" => "env-foo" + SUFFIX,
+ "staging-12345678-" => "staging-12345678" + SUFFIX,
+ "staging-12345678-01234567" => "staging-12345678" + SUFFIX,
}.each do |name, matcher|
it "returns a slug matching #{matcher}, given #{name}" do
slug = described_class.new(name: name).generate_slug
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index f8660da031d..349474bb656 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -27,7 +27,7 @@ describe Event, models: true do
end
describe "Push event" do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:empty_project, :private) }
let(:user) { project.owner }
let(:event) { create_event(project, user) }
@@ -187,7 +187,7 @@ describe Event, models: true do
end
context 'merge request diff note event' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:merge_request) { create(:merge_request, source_project: project, author: author, assignee: assignee) }
let(:note_on_merge_request) { create(:legacy_diff_note_on_merge_request, noteable: merge_request, project: project) }
let(:target) { note_on_merge_request }
@@ -202,7 +202,7 @@ describe Event, models: true do
end
context 'private project' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:empty_project, :private) }
it do
expect(event.visible_to_user?(non_member)).to eq false
diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb
index 1863581f57b..454550c9710 100644
--- a/spec/models/forked_project_link_spec.rb
+++ b/spec/models/forked_project_link_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ForkedProjectLink, "add link on fork" do
- let(:project_from) { create(:project) }
+ let(:project_from) { create(:project, :repository) }
let(:namespace) { create(:namespace) }
let(:user) { create(:user, namespace: namespace) }
@@ -21,7 +21,7 @@ end
describe '#forked?' do
let(:forked_project_link) { build(:forked_project_link) }
- let(:project_from) { create(:project) }
+ let(:project_from) { create(:project, :repository) }
let(:project_to) { create(:project, forked_project_link: forked_project_link) }
before :each do
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
index d87684fd49e..cacbab8bcb1 100644
--- a/spec/models/global_milestone_spec.rb
+++ b/spec/models/global_milestone_spec.rb
@@ -4,9 +4,9 @@ describe GlobalMilestone, models: true do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:group) { create(:group) }
- let(:project1) { create(:project, group: group) }
- let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
- let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
+ let(:project1) { create(:empty_project, group: group) }
+ let(:project2) { create(:empty_project, path: 'gitlab-ci', group: group) }
+ let(:project3) { create(:empty_project, path: 'cookbook-gitlab', group: group) }
describe '.build_collection' do
let(:milestone1_due_date) { 2.weeks.from_now.to_date }
diff --git a/spec/models/group_milestone_spec.rb b/spec/models/group_milestone_spec.rb
index 601167c3bd3..916afb7aaf5 100644
--- a/spec/models/group_milestone_spec.rb
+++ b/spec/models/group_milestone_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe GroupMilestone, models: true do
let(:group) { create(:group) }
- let(:project) { create(:project, group: group) }
+ let(:project) { create(:empty_project, group: group) }
let(:project_milestone) do
create(:milestone, title: "Milestone v1.2", project: project)
end
diff --git a/spec/models/guest_spec.rb b/spec/models/guest_spec.rb
index d79f929f7a1..582b54c0712 100644
--- a/spec/models/guest_spec.rb
+++ b/spec/models/guest_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Guest, lib: true do
- let(:public_project) { create(:project, :public) }
- let(:private_project) { create(:project, :private) }
- let(:internal_project) { create(:project, :internal) }
+ let(:public_project) { build_stubbed(:empty_project, :public) }
+ let(:private_project) { build_stubbed(:empty_project, :private) }
+ let(:internal_project) { build_stubbed(:empty_project, :internal) }
describe '.can_pull?' do
context 'when project is private' do
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index ad2b710041a..e8caad00c44 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -4,7 +4,7 @@ describe SystemHook, models: true do
describe "execute" do
let(:system_hook) { create(:system_hook) }
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:empty_project, namespace: user.namespace) }
let(:group) { create(:group) }
before do
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index e52b9d75cef..9d4db1bfb52 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -25,7 +25,7 @@ describe WebHook, models: true do
end
describe "execute" do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:project_hook) { create(:project_hook) }
before(:each) do
diff --git a/spec/models/issue/metrics_spec.rb b/spec/models/issue/metrics_spec.rb
index 2459a49f095..08712f2a768 100644
--- a/spec/models/issue/metrics_spec.rb
+++ b/spec/models/issue/metrics_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Issue::Metrics, models: true do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
subject { create(:issue, project: project) }
diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb
index d742c814680..d8aed25c041 100644
--- a/spec/models/issue_collection_spec.rb
+++ b/spec/models/issue_collection_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe IssueCollection do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
let(:collection) { described_class.new([issue1, issue2]) }
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 61d72925736..bba9058f394 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -23,21 +23,74 @@ describe Issue, models: true do
end
describe '#to_reference' do
- let(:project) { build(:empty_project, name: 'sample-project') }
- let(:issue) { build(:issue, iid: 1, project: project) }
+ let(:namespace) { build(:namespace, path: 'sample-namespace') }
+ let(:project) { build(:empty_project, name: 'sample-project', namespace: namespace) }
+ let(:issue) { build(:issue, iid: 1, project: project) }
+ let(:group) { create(:group, name: 'Group', path: 'sample-group') }
+
+ context 'when nil argument' do
+ it 'returns issue id' do
+ expect(issue.to_reference).to eq "#1"
+ end
+ end
- it 'returns a String reference to the object' do
- expect(issue.to_reference).to eq "#1"
+ context 'when full is true' do
+ it 'returns complete path to the issue' do
+ expect(issue.to_reference(full: true)).to eq 'sample-namespace/sample-project#1'
+ expect(issue.to_reference(project, full: true)).to eq 'sample-namespace/sample-project#1'
+ expect(issue.to_reference(group, full: true)).to eq 'sample-namespace/sample-project#1'
+ end
end
- it 'returns a String reference with the full path' do
- expect(issue.to_reference(full: true)).to eq(project.path_with_namespace + '#1')
+ context 'when same project argument' do
+ it 'returns issue id' do
+ expect(issue.to_reference(project)).to eq("#1")
+ end
+ end
+
+ context 'when cross namespace project argument' do
+ let(:another_namespace_project) { create(:empty_project, name: 'another-project') }
+
+ it 'returns complete path to the issue' do
+ expect(issue.to_reference(another_namespace_project)).to eq 'sample-namespace/sample-project#1'
+ end
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
expect(issue.to_reference(another_project)).to eq "sample-project#1"
end
+
+ context 'when same namespace / cross-project argument' do
+ let(:another_project) { create(:empty_project, namespace: namespace) }
+
+ it 'returns path to the issue with the project name' do
+ expect(issue.to_reference(another_project)).to eq 'sample-project#1'
+ end
+ end
+
+ context 'when different namespace / cross-project argument' do
+ let(:another_namespace) { create(:namespace, path: 'another-namespace') }
+ let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
+
+ it 'returns full path to the issue' do
+ expect(issue.to_reference(another_project)).to eq 'sample-namespace/sample-project#1'
+ end
+ end
+
+ context 'when argument is a namespace' do
+ context 'with same project path' do
+ it 'returns path to the issue with the project name' do
+ expect(issue.to_reference(namespace)).to eq 'sample-project#1'
+ end
+ end
+
+ context 'with different project path' do
+ it 'returns full path to the issue' do
+ expect(issue.to_reference(group)).to eq 'sample-namespace/sample-project#1'
+ end
+ end
+ end
end
describe '#is_being_reassigned?' do
@@ -60,9 +113,9 @@ describe Issue, models: true do
end
describe '#closed_by_merge_requests' do
- let(:project) { create(:project) }
- let(:issue) { create(:issue, project: project, state: "opened")}
- let(:closed_issue) { build(:issue, project: project, state: "closed")}
+ let(:project) { create(:project, :repository) }
+ let(:issue) { create(:issue, project: project)}
+ let(:closed_issue) { build(:issue, :closed, project: project)}
let(:mr) do
opts = {
@@ -104,7 +157,7 @@ describe Issue, models: true do
describe '#referenced_merge_requests' do
it 'returns the referenced merge requests' do
- project = create(:project, :public)
+ project = create(:empty_project, :public)
mr1 = create(:merge_request,
source_project: project,
@@ -137,7 +190,7 @@ describe Issue, models: true do
end
context 'user is reporter in project issue belongs to' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project) }
before { project.team << [user, :reporter] }
@@ -151,7 +204,7 @@ describe Issue, models: true do
context 'checking destination project also' do
subject { issue.can_move?(user, to_project) }
- let(:to_project) { create(:project) }
+ let(:to_project) { create(:empty_project) }
context 'destination project allowed' do
before { to_project.team << [user, :reporter] }
@@ -246,7 +299,7 @@ describe Issue, models: true do
describe '#participants' do
context 'using a public project' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, project: project) }
let!(:note1) do
@@ -268,7 +321,7 @@ describe Issue, models: true do
context 'using a private project' do
it 'does not include mentioned users that do not have access to the project' do
- project = create(:project)
+ project = create(:empty_project)
user = create(:user)
issue = create(:issue, project: project)
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 4f7c8a36cb5..16e2144d6a1 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -481,7 +481,7 @@ describe Member, models: true do
describe "destroying a record", truncate: true do
it "refreshes user's authorized projects" do
- project = create(:project, :private)
+ project = create(:empty_project, :private)
user = create(:user)
member = project.team << [user, :reporter]
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 68f72f5c86e..90d14c2c0b9 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -83,8 +83,8 @@ describe ProjectMember, models: true do
describe '.import_team' do
before do
- @project_1 = create :project
- @project_2 = create :project
+ @project_1 = create(:empty_project)
+ @project_2 = create(:empty_project)
@user_1 = create :user
@user_2 = create :user
@@ -131,8 +131,8 @@ describe ProjectMember, models: true do
describe '.truncate_teams' do
before do
- @project_1 = create :project
- @project_2 = create :project
+ @project_1 = create(:empty_project)
+ @project_2 = create(:empty_project)
@user_1 = create :user
@user_2 = create :user
diff --git a/spec/models/merge_request/metrics_spec.rb b/spec/models/merge_request/metrics_spec.rb
index 255db41cb19..9afed311e27 100644
--- a/spec/models/merge_request/metrics_spec.rb
+++ b/spec/models/merge_request/metrics_spec.rb
@@ -1,9 +1,7 @@
require 'spec_helper'
describe MergeRequest::Metrics, models: true do
- let(:project) { create(:project) }
-
- subject { create(:merge_request, source_project: project) }
+ subject { create(:merge_request) }
describe "when recording the default set of metrics on merge request save" do
it "records the merge time" do
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 064f29d2d66..3cee2b7714f 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -24,7 +24,7 @@ describe Milestone, models: true do
it { is_expected.to have_many(:issues) }
end
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:milestone) { create(:milestone, project: project) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
@@ -44,7 +44,7 @@ describe Milestone, models: true do
end
it "accepts the same title in another project" do
- project = build(:project)
+ project = build(:empty_project)
new_milestone = Milestone.new(project: project, title: milestone.title)
expect(new_milestone).to be_valid
@@ -257,7 +257,7 @@ describe Milestone, models: true do
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
expect(milestone.to_reference(another_project)).to eq "sample-project%1"
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 8d613a88ca0..4e96f19eb6f 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -107,7 +107,7 @@ describe Namespace, models: true do
describe '#move_dir' do
before do
@namespace = create :namespace
- @project = create :project, namespace: @namespace
+ @project = create(:empty_project, namespace: @namespace)
allow(@namespace).to receive(:path_changed?).and_return(true)
end
@@ -139,7 +139,7 @@ describe Namespace, models: true do
end
describe :rm_dir do
- let!(:project) { create(:project, namespace: namespace) }
+ let!(:project) { create(:empty_project, namespace: namespace) }
let!(:path) { File.join(Gitlab.config.repositories.storages.default, namespace.path) }
it "removes its dirs when deleted" do
diff --git a/spec/models/network/graph_spec.rb b/spec/models/network/graph_spec.rb
index b76513d2a3c..492c4e01bd8 100644
--- a/spec/models/network/graph_spec.rb
+++ b/spec/models/network/graph_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Network::Graph, models: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let!(:note_on_commit) { create(:note_on_commit, project: project) }
it '#initialize' do
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 6f9ae655fed..1cde9e04951 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -42,7 +42,7 @@ describe Note, models: true do
context 'when noteable and note project differ' do
subject do
build(:note, noteable: build_stubbed(:issue),
- project: build_stubbed(:project))
+ project: build_stubbed(:empty_project))
end
it { is_expected.to be_invalid }
@@ -93,8 +93,8 @@ describe Note, models: true do
describe 'authorization' do
before do
- @p1 = create(:project)
- @p2 = create(:project)
+ @p1 = create(:empty_project)
+ @p2 = create(:empty_project)
@u1 = create(:user)
@u2 = create(:user)
@u3 = create(:user)
@@ -191,10 +191,10 @@ describe Note, models: true do
describe "cross_reference_not_visible_for?" do
let(:private_user) { create(:user) }
- let(:private_project) { create(:project, namespace: private_user.namespace).tap { |p| p.team << [private_user, :master] } }
+ let(:private_project) { create(:empty_project, namespace: private_user.namespace) { |p| p.team << [private_user, :master] } }
let(:private_issue) { create(:issue, project: private_project) }
- let(:ext_proj) { create(:project, :public) }
+ let(:ext_proj) { create(:empty_project, :public) }
let(:ext_issue) { create(:issue, project: ext_proj) }
let(:note) do
@@ -237,7 +237,7 @@ describe Note, models: true do
describe '#participants' do
it 'includes the note author' do
- project = create(:project, :public)
+ project = create(:empty_project, :public)
issue = create(:issue, project: project)
note = create(:note_on_issue, noteable: issue, project: project)
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index a55d43ab2f9..8589f1eb712 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProjectFeature do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:user) { create(:user) }
describe '#feature_available?' do
@@ -35,7 +35,7 @@ describe ProjectFeature do
it "returns true when user is a member of project group" do
group = create(:group)
- project = create(:project, namespace: group)
+ project = create(:empty_project, namespace: group)
group.add_developer(user)
features.each do |feature|
diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb
index 47397a822c1..59a4ae1b799 100644
--- a/spec/models/project_group_link_spec.rb
+++ b/spec/models/project_group_link_spec.rb
@@ -17,7 +17,7 @@ describe ProjectGroupLink do
describe "destroying a record", truncate: true do
it "refreshes group users' authorized projects" do
- project = create(:project, :private)
+ project = create(:empty_project, :private)
group = create(:group)
reporter = create(:user)
group_users = group.users
diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb
index 4d538cac007..9cdbfa44e5b 100644
--- a/spec/models/project_label_spec.rb
+++ b/spec/models/project_label_spec.rb
@@ -100,7 +100,7 @@ describe ProjectLabel, models: true do
end
context 'cross project reference' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context 'using name' do
it 'returns cross reference with label name' do
diff --git a/spec/models/project_services/asana_service_spec.rb b/spec/models/project_services/asana_service_spec.rb
index 8e5145e824b..48aef3a93f2 100644
--- a/spec/models/project_services/asana_service_spec.rb
+++ b/spec/models/project_services/asana_service_spec.rb
@@ -18,7 +18,7 @@ describe AsanaService, models: true do
describe 'Execute' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
def create_data_for_commits(*messages)
{
diff --git a/spec/models/project_services/assembla_service_spec.rb b/spec/models/project_services/assembla_service_spec.rb
index 4c5acb7990b..96f00af898e 100644
--- a/spec/models/project_services/assembla_service_spec.rb
+++ b/spec/models/project_services/assembla_service_spec.rb
@@ -8,7 +8,7 @@ describe AssemblaService, models: true do
describe "Execute" do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
@assembla_service = AssemblaService.new
diff --git a/spec/models/project_services/campfire_service_spec.rb b/spec/models/project_services/campfire_service_spec.rb
index a3b9d084a75..953e664fb66 100644
--- a/spec/models/project_services/campfire_service_spec.rb
+++ b/spec/models/project_services/campfire_service_spec.rb
@@ -22,7 +22,7 @@ describe CampfireService, models: true do
describe "#execute" do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
@campfire_service = CampfireService.new
diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb
index 42c2ed668bc..f9307d6de7b 100644
--- a/spec/models/project_services/drone_ci_service_spec.rb
+++ b/spec/models/project_services/drone_ci_service_spec.rb
@@ -27,7 +27,7 @@ describe DroneCiService, models: true, caching: true do
shared_context :drone_ci_service do
let(:drone) { DroneCiService.new }
- let(:project) { create(:project, name: 'project') }
+ let(:project) { create(:project, :repository, name: 'project') }
let(:path) { "#{project.namespace.path}/#{project.path}" }
let(:drone_url) { 'http://drone.example.com' }
let(:sha) { '2ab7834c' }
diff --git a/spec/models/project_services/external_wiki_service_spec.rb b/spec/models/project_services/external_wiki_service_spec.rb
index 342d86aeca9..bdeea1db1e3 100644
--- a/spec/models/project_services/external_wiki_service_spec.rb
+++ b/spec/models/project_services/external_wiki_service_spec.rb
@@ -23,7 +23,7 @@ describe ExternalWikiService, models: true do
end
describe 'External wiki' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context 'when it is active' do
before do
diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb
index d6db02d6e76..a97e8c6e4ce 100644
--- a/spec/models/project_services/flowdock_service_spec.rb
+++ b/spec/models/project_services/flowdock_service_spec.rb
@@ -22,7 +22,7 @@ describe FlowdockService, models: true do
describe "Execute" do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
@flowdock_service = FlowdockService.new
diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb
index 529044d1d8b..a13fbae03eb 100644
--- a/spec/models/project_services/gemnasium_service_spec.rb
+++ b/spec/models/project_services/gemnasium_service_spec.rb
@@ -24,7 +24,7 @@ describe GemnasiumService, models: true do
describe "Execute" do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
@gemnasium_service = GemnasiumService.new
diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
index 9b80f0e7296..dcb70ee28a8 100644
--- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
+++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
@@ -8,21 +8,21 @@ describe GitlabIssueTrackerService, models: true do
describe 'Validations' do
context 'when service is active' do
- subject { described_class.new(project: create(:project), active: true) }
+ subject { described_class.new(project: create(:empty_project), active: true) }
it { is_expected.to validate_presence_of(:issues_url) }
it_behaves_like 'issue tracker service URL attribute', :issues_url
end
context 'when service is inactive' do
- subject { described_class.new(project: create(:project), active: false) }
+ subject { described_class.new(project: create(:empty_project), active: false) }
it { is_expected.not_to validate_presence_of(:issues_url) }
end
end
describe 'project and issue urls' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context 'with absolute urls' do
before do
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index 2da3a9cb09f..bf422ac7ce1 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -22,8 +22,8 @@ describe HipchatService, models: true do
describe "Execute" do
let(:hipchat) { HipchatService.new }
- let(:user) { create(:user, username: 'username') }
- let(:project) { create(:project, name: 'project') }
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
let(:api_url) { 'https://hipchat.example.com/v2/room/123456/notification?auth_token=verySecret' }
let(:project_name) { project.name_with_namespace.gsub(/\s/, '') }
let(:token) { 'verySecret' }
@@ -165,7 +165,7 @@ describe HipchatService, models: true do
context "Note events" do
let(:user) { create(:user) }
- let(:project) { create(:project, creator_id: user.id) }
+ let(:project) { create(:project, :repository, creator: user) }
context 'when commit comment event triggered' do
let(:commit_note) do
diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb
index f8c45b37561..b9fb6f3f6f4 100644
--- a/spec/models/project_services/irker_service_spec.rb
+++ b/spec/models/project_services/irker_service_spec.rb
@@ -25,7 +25,7 @@ describe IrkerService, models: true do
describe 'Execute' do
let(:irker) { IrkerService.new }
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:sample_data) do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 862e3a72a73..2f6b159d76e 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -71,7 +71,7 @@ describe JiraService, models: true do
describe '#close_issue' do
let(:custom_base_url) { 'http://custom_url' }
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:merge_request) { create(:merge_request) }
before do
@@ -207,12 +207,12 @@ describe JiraService, models: true do
end
describe "Stored password invalidation" do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context "when a password was previously set" do
before do
@jira_service = JiraService.create!(
- project: create(:project),
+ project: project,
properties: {
url: 'http://jira.example.com/rest/api/2',
username: 'mic',
@@ -252,7 +252,7 @@ describe JiraService, models: true do
context "when no password was previously set" do
before do
@jira_service = JiraService.create(
- project: create(:project),
+ project: project,
properties: {
url: 'http://jira.example.com/rest/api/2',
username: 'mic'
@@ -281,7 +281,7 @@ describe JiraService, models: true do
end
describe 'description and title' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context 'when it is not set' do
before do
@@ -316,7 +316,7 @@ describe JiraService, models: true do
end
describe 'project and issue urls' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
context 'when gitlab.yml was initialized' do
before do
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index c879edddfdd..98f3d420c8a 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -113,10 +113,7 @@ describe MattermostSlashCommandsService, :models do
end
it 'shows error messages' do
- teams, message = subject
-
- expect(teams).to be_empty
- expect(message).to eq('Failed to get team list.')
+ expect(subject).to eq([[], "Failed to get team list."])
end
end
end
diff --git a/spec/models/project_services/pipeline_email_service_spec.rb b/spec/models/project_services/pipeline_email_service_spec.rb
index 7c8824485f5..03932895b0e 100644
--- a/spec/models/project_services/pipeline_email_service_spec.rb
+++ b/spec/models/project_services/pipeline_email_service_spec.rb
@@ -7,7 +7,7 @@ describe PipelinesEmailService do
create(:ci_pipeline, project: project, sha: project.commit('master').sha)
end
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:recipient) { 'test@gitlab.com' }
let(:data) do
diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb
index 8fc92a9ab51..a7e7594a7d5 100644
--- a/spec/models/project_services/pushover_service_spec.rb
+++ b/spec/models/project_services/pushover_service_spec.rb
@@ -27,7 +27,7 @@ describe PushoverService, models: true do
describe 'Execute' do
let(:pushover) { PushoverService.new }
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:sample_data) do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 646a1311462..48b085781e7 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -282,9 +282,10 @@ describe Project, models: true do
end
describe '#to_reference' do
- let(:owner) { create(:user, name: 'Gitlab') }
+ let(:owner) { create(:user, name: 'Gitlab') }
let(:namespace) { create(:namespace, path: 'sample-namespace', owner: owner) }
- let(:project) { create(:empty_project, path: 'sample-project', namespace: namespace) }
+ let(:project) { create(:empty_project, path: 'sample-project', namespace: namespace) }
+ let(:group) { create(:group, name: 'Group', path: 'sample-group', owner: owner) }
context 'when nil argument' do
it 'returns nil' do
@@ -292,6 +293,14 @@ describe Project, models: true do
end
end
+ context 'when full is true' do
+ it 'returns complete path to the project' do
+ expect(project.to_reference(full: true)).to eq 'sample-namespace/sample-project'
+ expect(project.to_reference(project, full: true)).to eq 'sample-namespace/sample-project'
+ expect(project.to_reference(group, full: true)).to eq 'sample-namespace/sample-project'
+ end
+ end
+
context 'when same project argument' do
it 'returns nil' do
expect(project.to_reference(project)).to be_nil
@@ -309,10 +318,33 @@ describe Project, models: true do
context 'when same namespace / cross-project argument' do
let(:another_project) { create(:empty_project, namespace: namespace) }
- it 'returns complete path to the project' do
+ it 'returns path to the project' do
expect(project.to_reference(another_project)).to eq 'sample-project'
end
end
+
+ context 'when different namespace / cross-project argument' do
+ let(:another_namespace) { create(:namespace, path: 'another-namespace', owner: owner) }
+ let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
+
+ it 'returns full path to the project' do
+ expect(project.to_reference(another_project)).to eq 'sample-namespace/sample-project'
+ end
+ end
+
+ context 'when argument is a namespace' do
+ context 'with same project path' do
+ it 'returns path to the project' do
+ expect(project.to_reference(namespace)).to eq 'sample-project'
+ end
+ end
+
+ context 'with different project path' do
+ it 'returns full path to the project' do
+ expect(project.to_reference(group)).to eq 'sample-namespace/sample-project'
+ end
+ end
+ end
end
describe '#to_human_reference' do
@@ -1801,6 +1833,14 @@ describe Project, models: true do
end
end
+ describe 'inside_path' do
+ let!(:project1) { create(:empty_project) }
+ let!(:project2) { create(:empty_project) }
+ let!(:path) { project1.namespace.path }
+
+ it { expect(Project.inside_path(path)).to eq([project1]) }
+ end
+
def enable_lfs
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 0475cecaa2d..942eeab251d 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -265,10 +265,10 @@ describe ProjectTeam, models: true do
let(:group) { create(:group) }
let(:developer) { create(:user) }
let(:master) { create(:user) }
- let(:personal_project) { create(:project, namespace: developer.namespace) }
- let(:group_project) { create(:project, namespace: group) }
- let(:members_project) { create(:project) }
- let(:shared_project) { create(:project) }
+ let(:personal_project) { create(:empty_project, namespace: developer.namespace) }
+ let(:group_project) { create(:empty_project, namespace: group) }
+ let(:members_project) { create(:empty_project) }
+ let(:shared_project) { create(:empty_project) }
before do
group.add_master(master)
@@ -330,7 +330,7 @@ describe ProjectTeam, models: true do
reporter = create(:user)
promoted_guest = create(:user)
guest = create(:user)
- project = create(:project)
+ project = create(:empty_project)
project.add_master(master)
project.add_reporter(reporter)
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 28100f2d0b3..901cfb907f2 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -4,7 +4,7 @@ describe Repository, models: true do
include RepoHelpers
TestBlob = Struct.new(:name)
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user) }
@@ -90,6 +90,30 @@ describe Repository, models: true do
it { is_expected.to eq(['v1.1.0', 'v1.0.0']) }
end
+
+ context 'annotated tag pointing to a blob' do
+ let(:annotated_tag_name) { 'annotated-tag' }
+
+ subject { repository.tags_sorted_by('updated_asc').map(&:name) }
+
+ before do
+ options = { message: 'test tag message\n',
+ tagger: { name: 'John Smith', email: 'john@gmail.com' } }
+ repository.rugged.tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', options)
+
+ double_first = double(committed_date: Time.now - 1.second)
+ double_last = double(committed_date: Time.now)
+
+ allow(tag_a).to receive(:dereferenced_target).and_return(double_last)
+ allow(tag_b).to receive(:dereferenced_target).and_return(double_first)
+ end
+
+ it { is_expected.to eq(['v1.1.0', 'v1.0.0', annotated_tag_name]) }
+
+ after do
+ repository.rugged.tags.delete(annotated_tag_name)
+ end
+ end
end
end
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index 691511cd93f..0e2f07e945f 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -12,7 +12,7 @@ describe Service, models: true do
end
describe "Testable" do
- let(:project) { create :project }
+ let(:project) { create(:project, :repository) }
before do
allow(@service).to receive(:project).and_return(project)
@@ -35,7 +35,7 @@ describe Service, models: true do
end
describe "With commits" do
- let(:project) { create :project }
+ let(:project) { create(:project, :repository) }
before do
allow(@service).to receive(:project).and_return(project)
@@ -60,7 +60,7 @@ describe Service, models: true do
api_key: '123456789'
})
end
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
describe 'is prefilled for projects pushover service' do
it "has all fields prefilled" do
@@ -79,7 +79,7 @@ describe Service, models: true do
describe "{property}_changed?" do
let(:service) do
BambooService.create(
- project: create(:project),
+ project: create(:empty_project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -119,7 +119,7 @@ describe Service, models: true do
describe "{property}_touched?" do
let(:service) do
BambooService.create(
- project: create(:project),
+ project: create(:empty_project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -159,7 +159,7 @@ describe Service, models: true do
describe "{property}_was" do
let(:service) do
BambooService.create(
- project: create(:project),
+ project: create(:empty_project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -199,7 +199,7 @@ describe Service, models: true do
describe 'initialize service with no properties' do
let(:service) do
GitlabIssueTrackerService.create(
- project: create(:project),
+ project: create(:empty_project),
title: 'random title'
)
end
@@ -214,7 +214,7 @@ describe Service, models: true do
end
describe "callbacks" do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let!(:service) do
RedmineService.new(
project: project,
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 7425a897769..219ab1989ea 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -42,7 +42,7 @@ describe Snippet, models: true do
end
it 'supports a cross-project reference' do
- another_project = build(:project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
expect(snippet.to_reference(another_project)).to eq "sample-project$1"
end
end
@@ -55,7 +55,7 @@ describe Snippet, models: true do
end
it 'still returns shortest reference when project arg present' do
- another_project = build(:project, name: 'another-project')
+ another_project = build(:empty_project, name: 'another-project')
expect(snippet.to_reference(another_project)).to eq "$1"
end
end
@@ -173,7 +173,7 @@ describe Snippet, models: true do
end
describe '#participants' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:snippet) { create(:snippet, content: 'foo', project: project) }
let!(:note1) do
diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb
index 623b82c01d8..581305ad39f 100644
--- a/spec/models/todo_spec.rb
+++ b/spec/models/todo_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
describe Todo, models: true do
- let(:project) { create(:project) }
- let(:commit) { project.commit }
let(:issue) { create(:issue) }
describe 'relationships' do
@@ -82,6 +80,9 @@ describe Todo, models: true do
describe '#target' do
context 'for commits' do
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit }
+
it 'returns an instance of Commit when exists' do
subject.project = project
subject.target_type = 'Commit'
@@ -108,17 +109,20 @@ describe Todo, models: true do
end
describe '#target_reference' do
- it 'returns the short commit id for commits' do
+ it 'returns commit full reference with short id' do
+ project = create(:project, :repository)
+ commit = project.commit
+
subject.project = project
subject.target_type = 'Commit'
subject.commit_id = commit.id
- expect(subject.target_reference).to eq commit.short_id
+ expect(subject.target_reference).to eq commit.reference_link_text(full: true)
end
- it 'returns reference for issuables' do
+ it 'returns full reference for issuables' do
subject.target = issue
- expect(subject.target_reference).to eq issue.to_reference
+ expect(subject.target_reference).to eq issue.to_reference(full: true)
end
end
end
diff --git a/spec/models/tree_spec.rb b/spec/models/tree_spec.rb
index 0737999e125..a87983b7492 100644
--- a/spec/models/tree_spec.rb
+++ b/spec/models/tree_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Tree, models: true do
- let(:repository) { create(:project).repository }
+ let(:repository) { create(:project, :repository).repository }
let(:sha) { repository.root_ref }
subject { described_class.new(repository, '54fcc214') }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 0adfc30fe58..6ca5ad747d1 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1382,14 +1382,14 @@ describe User, models: true do
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
- let!(:project) { create(:project, namespace: group) }
- let!(:nested_project) { create(:project, namespace: nested_group) }
+ let!(:project) { create(:empty_project, namespace: group) }
+ let!(:nested_project) { create(:empty_project, namespace: nested_group) }
before do
group.add_owner(user)
# Add more data to ensure method does not include wrong projects
- other_project = create(:project, namespace: create(:group, :nested))
+ other_project = create(:empty_project, namespace: create(:group, :nested))
other_project.add_developer(create(:user))
end
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb
new file mode 100644
index 00000000000..0f280f32eac
--- /dev/null
+++ b/spec/policies/ci/build_policy_spec.rb
@@ -0,0 +1,93 @@
+require 'spec_helper'
+
+describe Ci::BuildPolicy, :models do
+ let(:user) { create(:user) }
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project) }
+
+ let(:policies) do
+ described_class.abilities(user, build).to_set
+ end
+
+ shared_context 'public pipelines disabled' do
+ before { project.update_attribute(:public_builds, false) }
+ end
+
+ describe '#rules' do
+ context 'when user does not have access to the project' do
+ let(:project) { create(:empty_project, :private) }
+
+ context 'when public builds are enabled' do
+ it 'does not include ability to read build' do
+ expect(policies).not_to include :read_build
+ end
+ end
+
+ context 'when public builds are disabled' do
+ include_context 'public pipelines disabled'
+
+ it 'does not include ability to read build' do
+ expect(policies).not_to include :read_build
+ end
+ end
+ end
+
+ context 'when anonymous user has access to the project' do
+ let(:project) { create(:empty_project, :public) }
+
+ context 'when public builds are enabled' do
+ it 'includes ability to read build' do
+ expect(policies).to include :read_build
+ end
+ end
+
+ context 'when public builds are disabled' do
+ include_context 'public pipelines disabled'
+
+ it 'does not include ability to read build' do
+ expect(policies).not_to include :read_build
+ end
+ end
+ end
+
+ context 'when team member has access to the project' do
+ let(:project) { create(:empty_project, :public) }
+
+ context 'team member is a guest' do
+ before { project.team << [user, :guest] }
+
+ context 'when public builds are enabled' do
+ it 'includes ability to read build' do
+ expect(policies).to include :read_build
+ end
+ end
+
+ context 'when public builds are disabled' do
+ include_context 'public pipelines disabled'
+
+ it 'does not include ability to read build' do
+ expect(policies).not_to include :read_build
+ end
+ end
+ end
+
+ context 'team member is a reporter' do
+ before { project.team << [user, :reporter] }
+
+ context 'when public builds are enabled' do
+ it 'includes ability to read build' do
+ expect(policies).to include :read_build
+ end
+ end
+
+ context 'when public builds are disabled' do
+ include_context 'public pipelines disabled'
+
+ it 'does not include ability to read build' do
+ expect(policies).to include :read_build
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 2878e0cb59b..5a3ffc284f2 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -6,7 +6,7 @@ describe API::Branches, api: true do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project) { create(:project, :repository, creator: user) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
let!(:branch_name) { 'feature' }
diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb
index 7be7acebb19..645e36683bc 100644
--- a/spec/requests/api/builds_spec.rb
+++ b/spec/requests/api/builds_spec.rb
@@ -5,7 +5,7 @@ describe API::Builds, api: true do
let(:user) { create(:user) }
let(:api_user) { user }
- let!(:project) { create(:project, creator_id: user.id, public_builds: false) }
+ let!(:project) { create(:project, :repository, creator: user, public_builds: false) }
let!(:developer) { create(:project_member, :developer, user: user, project: project) }
let(:reporter) { create(:project_member, :reporter, project: project) }
let(:guest) { create(:project_member, :guest, project: project) }
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index c1c7c0882de..88361def3cf 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::CommitStatuses, api: true do
include ApiHelpers
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let(:commit) { project.repository.commit }
let(:commit_status) { create(:commit_status, pipeline: pipeline) }
let(:guest) { create_user(:guest) }
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 7f8ea5251f0..af9028a8978 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -5,7 +5,7 @@ describe API::Commits, api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let!(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 685da28c673..5e26e779366 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe API::Files, api: true do
include ApiHelpers
let(:user) { create(:user) }
- let!(:project) { create(:project, namespace: user.namespace ) }
- let(:guest) { create(:user).tap { |u| create(:project_member, :guest, user: u, project: project) } }
+ let!(:project) { create(:project, :repository, namespace: user.namespace ) }
+ let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:file_path) { 'files/ruby/popen.rb' }
let(:params) do
{
diff --git a/spec/requests/api/fork_spec.rb b/spec/requests/api/fork_spec.rb
index df29099bc2f..92ac4fd334d 100644
--- a/spec/requests/api/fork_spec.rb
+++ b/spec/requests/api/fork_spec.rb
@@ -4,7 +4,6 @@ describe API::Projects, api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let(:user3) { create(:user) }
let(:admin) { create(:admin) }
let(:group) { create(:group) }
let(:group2) do
@@ -13,17 +12,14 @@ describe API::Projects, api: true do
group
end
- let(:project) do
- create(:project, creator_id: user.id, namespace: user.namespace)
- end
-
- let(:project_user2) do
- create(:project_member, :reporter, user: user2, project: project)
- end
-
describe 'POST /projects/fork/:id' do
- before { project_user2 }
- before { user3 }
+ let(:project) do
+ create(:project, :repository, creator: user, namespace: user.namespace)
+ end
+
+ before do
+ project.add_reporter(user2)
+ end
context 'when authenticated' do
it 'forks if user has sufficient access to project' do
@@ -49,7 +45,8 @@ describe API::Projects, api: true do
end
it 'fails on missing project access for the project to fork' do
- post api("/projects/fork/#{project.id}", user3)
+ new_user = create(:user)
+ post api("/projects/fork/#{project.id}", new_user)
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index edbf0140583..1187d2e609d 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -176,6 +176,9 @@ describe API::Groups, api: true do
expect(json_response['visibility_level']).to eq(group1.visibility_level)
expect(json_response['avatar_url']).to eq(group1.avatar_url)
expect(json_response['web_url']).to eq(group1.web_url)
+ expect(json_response['request_access_enabled']).to eq(group1.request_access_enabled)
+ expect(json_response['full_name']).to eq(group1.full_name)
+ expect(json_response['full_path']).to eq(group1.full_path)
expect(json_response['projects']).to be_an Array
expect(json_response['projects'].length).to eq(2)
expect(json_response['shared_projects']).to be_an Array
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index 91202244227..ffeacb15f17 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -4,7 +4,7 @@ describe API::Internal, api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:key) { create(:key, user: user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:secret_token) { Gitlab::Shell.secret_token }
describe "GET /internal/check", no_db: true do
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 71a7994e544..21a2c583aa8 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -6,12 +6,10 @@ describe API::MergeRequests, api: true do
let(:user) { create(:user) }
let(:admin) { create(:user, :admin) }
let(:non_member) { create(:user) }
- let!(:project) { create(:project, :public, creator_id: user.id, namespace: user.namespace) }
- let!(:merge_request) { create(:merge_request, :simple, author: user, assignee: user, source_project: project, target_project: project, title: "Test", created_at: base_time) }
- let!(:merge_request_closed) { create(:merge_request, state: "closed", author: user, assignee: user, source_project: project, target_project: project, title: "Closed test", created_at: base_time + 1.second) }
- let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, target_project: project, title: "Merged test", created_at: base_time + 2.seconds, merge_commit_sha: '9999999999999999999999999999999999999999') }
- let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
- let!(:note2) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") }
+ let!(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace) }
+ let!(:merge_request) { create(:merge_request, :simple, author: user, assignee: user, source_project: project, title: "Test", created_at: base_time) }
+ let!(:merge_request_closed) { create(:merge_request, state: "closed", author: user, assignee: user, source_project: project, title: "Closed test", created_at: base_time + 1.second) }
+ let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, title: "Merged test", created_at: base_time + 2.seconds, merge_commit_sha: '9999999999999999999999999999999999999999') }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
before do
@@ -556,11 +554,12 @@ describe API::MergeRequests, api: true do
original_count = merge_request.notes.size
post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user), note: "My comment"
+
expect(response).to have_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['author']['name']).to eq(user.name)
expect(json_response['author']['username']).to eq(user.username)
- expect(merge_request.notes.size).to eq(original_count + 1)
+ expect(merge_request.reload.notes.size).to eq(original_count + 1)
end
it "returns 400 if note is missing" do
@@ -576,6 +575,9 @@ describe API::MergeRequests, api: true do
end
describe "GET :id/merge_requests/:merge_request_id/comments" do
+ let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
+ let!(:note2) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") }
+
it "returns merge_request comments ordered by created_at" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
expect(response).to have_http_status(200)
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 9a01f7fa1c4..b7a0b5a9e13 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -5,7 +5,7 @@ describe API::Pipelines, api: true do
let(:user) { create(:user) }
let(:non_member) { create(:user) }
- let(:project) { create(:project, creator_id: user.id) }
+ let(:project) { create(:project, :repository, creator: user) }
let!(:pipeline) do
create(:ci_empty_pipeline, project: project, sha: project.commit.id,
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index cc5c532de83..a1db81ce18c 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -17,6 +17,7 @@ describe API::Projects, api: true do
let(:project3) do
create(:project,
:private,
+ :repository,
name: 'second_project',
path: 'second_project',
creator_id: user.id,
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 0b19fa38c55..c61208e395c 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -8,7 +8,7 @@ describe API::Repositories, api: true do
let(:user) { create(:user) }
let(:guest) { create(:user).tap { |u| create(:project_member, :guest, user: u, project: project) } }
- let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project) { create(:project, :repository, creator: user) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
describe "GET /projects/:id/repository/tree" do
@@ -74,7 +74,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository tree' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -144,7 +144,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository blob' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -198,7 +198,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository raw blob' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -273,7 +273,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository archive' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -347,7 +347,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository compare' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -394,7 +394,7 @@ describe API::Repositories, api: true do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository contributors' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb
index a1c32ae65ba..898d2b27e5c 100644
--- a/spec/requests/api/tags_spec.rb
+++ b/spec/requests/api/tags_spec.rb
@@ -7,7 +7,7 @@ describe API::Tags, api: true do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project) { create(:project, :repository, creator: user) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
@@ -29,7 +29,7 @@ describe API::Tags, api: true do
context 'when unauthenticated' do
it_behaves_like 'repository tags' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -88,7 +88,7 @@ describe API::Tags, api: true do
context 'when unauthenticated' do
it_behaves_like 'repository tag' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index cd01283b655..84104aa66ee 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -7,7 +7,7 @@ describe API::Triggers do
let(:user2) { create(:user) }
let!(:trigger_token) { 'secure_token' }
let!(:trigger_token_2) { 'secure_token_2' }
- let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project) { create(:project, :repository, creator: user) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:developer) { create(:project_member, :developer, user: user2, project: project) }
let!(:trigger) { create(:ci_trigger, project: project, token: trigger_token) }
diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb
index 2d434ab5dd8..a30be767119 100644
--- a/spec/requests/ci/api/triggers_spec.rb
+++ b/spec/requests/ci/api/triggers_spec.rb
@@ -5,9 +5,9 @@ describe Ci::API::Triggers do
describe 'POST /projects/:project_id/refs/:ref/trigger' do
let!(:trigger_token) { 'secure token' }
- let!(:project) { FactoryGirl.create(:project, ci_id: 10) }
- let!(:project2) { FactoryGirl.create(:empty_project, ci_id: 11) }
- let!(:trigger) { FactoryGirl.create(:ci_trigger, project: project, token: trigger_token) }
+ let!(:project) { create(:project, :repository, ci_id: 10) }
+ let!(:project2) { create(:empty_project, ci_id: 11) }
+ let!(:trigger) { create(:ci_trigger, project: project, token: trigger_token) }
let(:options) do
{
token: trigger_token
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 6a5ad6deb74..4a16824de04 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -12,7 +12,7 @@ describe 'Git HTTP requests', lib: true do
describe "User with no identities" do
let(:user) { create(:user) }
- let(:project) { create(:project, path: 'project.git-project') }
+ let(:project) { create(:project, :repository, path: 'project.git-project') }
context "when the project doesn't exist" do
context "when no authentication is provided" do
diff --git a/spec/requests/projects/artifacts_controller_spec.rb b/spec/requests/projects/artifacts_controller_spec.rb
index e02f0eacc93..d20866c0d44 100644
--- a/spec/requests/projects/artifacts_controller_spec.rb
+++ b/spec/requests/projects/artifacts_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::ArtifactsController do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb
index 28b485e4b15..0edbffbcd3b 100644
--- a/spec/requests/projects/cycle_analytics_events_spec.rb
+++ b/spec/requests/projects/cycle_analytics_events_spec.rb
@@ -4,7 +4,7 @@ describe 'cycle analytics events' do
include ApiHelpers
let(:user) { create(:user) }
- let(:project) { create(:project, public_builds: false) }
+ let(:project) { create(:project, :repository, public_builds: false) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
describe 'GET /:namespace/:project/cycle_analytics/events/issues' do
diff --git a/spec/serializers/analytics_build_serializer_spec.rb b/spec/serializers/analytics_build_serializer_spec.rb
index f0551c78671..e3b1dd93dc2 100644
--- a/spec/serializers/analytics_build_serializer_spec.rb
+++ b/spec/serializers/analytics_build_serializer_spec.rb
@@ -1,17 +1,13 @@
require 'spec_helper'
describe AnalyticsBuildSerializer do
- let(:serializer) do
- described_class
- .new.represent(resource)
- end
-
- let(:json) { serializer.as_json }
let(:resource) { create(:ci_build) }
+ subject { described_class.new.represent(resource) }
+
context 'when there is a single object provided' do
it 'contains important elements of analyticsBuild' do
- expect(json)
+ expect(subject)
.to include(:name, :branch, :short_sha, :date, :total_time, :url, :author)
end
end
diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb
index 6afbb2df35c..2f08958a783 100644
--- a/spec/serializers/analytics_issue_serializer_spec.rb
+++ b/spec/serializers/analytics_issue_serializer_spec.rb
@@ -1,14 +1,13 @@
require 'spec_helper'
describe AnalyticsIssueSerializer do
- let(:serializer) do
+ subject do
described_class
.new(project: project, entity: :merge_request)
.represent(resource)
end
let(:user) { create(:user) }
- let(:json) { serializer.as_json }
let(:project) { create(:project) }
let(:resource) do
{
@@ -23,7 +22,7 @@ describe AnalyticsIssueSerializer do
context 'when there is a single object provided' do
it 'contains important elements of the issue' do
- expect(json).to include(:title, :iid, :created_at, :total_time, :url, :author)
+ expect(subject).to include(:title, :iid, :created_at, :total_time, :url, :author)
end
end
end
diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb
index cdfae27193f..62067cc0ef2 100644
--- a/spec/serializers/analytics_merge_request_serializer_spec.rb
+++ b/spec/serializers/analytics_merge_request_serializer_spec.rb
@@ -1,14 +1,13 @@
require 'spec_helper'
describe AnalyticsMergeRequestSerializer do
- let(:serializer) do
+ subject do
described_class
.new(project: project, entity: :merge_request)
.represent(resource)
end
let(:user) { create(:user) }
- let(:json) { serializer.as_json }
let(:project) { create(:project) }
let(:resource) do
{
@@ -24,7 +23,7 @@ describe AnalyticsMergeRequestSerializer do
context 'when there is a single object provided' do
it 'contains important elements of the merge request' do
- expect(json).to include(:title, :iid, :created_at, :total_time, :url, :author, :state)
+ expect(subject).to include(:title, :iid, :created_at, :total_time, :url, :author, :state)
end
end
end
diff --git a/spec/serializers/analytics_stage_serializer_spec.rb b/spec/serializers/analytics_stage_serializer_spec.rb
index f9951826683..be6aa7c65c3 100644
--- a/spec/serializers/analytics_stage_serializer_spec.rb
+++ b/spec/serializers/analytics_stage_serializer_spec.rb
@@ -1,13 +1,13 @@
require 'spec_helper'
describe AnalyticsStageSerializer do
- let(:serializer) do
- described_class
- .new.represent(resource)
+ subject do
+ described_class.new.represent(resource)
end
- let(:json) { serializer.as_json }
- let(:resource) { Gitlab::CycleAnalytics::CodeStage.new(project: double, options: {}) }
+ let(:resource) do
+ Gitlab::CycleAnalytics::CodeStage.new(project: double, options: {})
+ end
before do
allow_any_instance_of(Gitlab::CycleAnalytics::BaseStage).to receive(:median).and_return(1.12)
@@ -15,10 +15,10 @@ describe AnalyticsStageSerializer do
end
it 'it generates payload for single object' do
- expect(json).to be_kind_of Hash
+ expect(subject).to be_kind_of Hash
end
it 'contains important elements of AnalyticsStage' do
- expect(json).to include(:title, :description, :value)
+ expect(subject).to include(:title, :description, :value)
end
end
diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb
index 7a84c8b0b40..5d7a94c2d02 100644
--- a/spec/serializers/analytics_summary_serializer_spec.rb
+++ b/spec/serializers/analytics_summary_serializer_spec.rb
@@ -1,29 +1,28 @@
require 'spec_helper'
describe AnalyticsSummarySerializer do
- let(:serializer) do
- described_class
- .new.represent(resource)
+ subject do
+ described_class.new.represent(resource)
end
- let(:json) { serializer.as_json }
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
+
let(:resource) do
- Gitlab::CycleAnalytics::Summary::Issue.new(project: double,
- from: 1.day.ago,
- current_user: user)
+ Gitlab::CycleAnalytics::Summary::Issue
+ .new(project: double, from: 1.day.ago, current_user: user)
end
before do
- allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue).to receive(:value).and_return(1.12)
+ allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue)
+ .to receive(:value).and_return(1.12)
end
it 'it generates payload for single object' do
- expect(json).to be_kind_of Hash
+ expect(subject).to be_kind_of Hash
end
it 'contains important elements of AnalyticsStage' do
- expect(json).to include(:title, :value)
+ expect(subject).to include(:title, :value)
end
end
diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb
index b7ed4eb0239..3c37660885d 100644
--- a/spec/serializers/environment_serializer_spec.rb
+++ b/spec/serializers/environment_serializer_spec.rb
@@ -1,16 +1,15 @@
require 'spec_helper'
describe EnvironmentSerializer do
- let(:serializer) do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ let(:json) do
described_class
.new(user: user, project: project)
.represent(resource)
end
- let(:json) { serializer.as_json }
- let(:user) { create(:user) }
- let(:project) { create(:project) }
-
context 'when there is a single object provided' do
before do
create(:ci_build, :manual, name: 'manual1',
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 3a32cb394dd..7cbf131e41e 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -7,11 +7,7 @@ describe PipelineSerializer do
described_class.new(user: user)
end
- let(:entity) do
- serializer.represent(resource)
- end
-
- subject { entity.as_json }
+ subject { serializer.represent(resource) }
describe '#represent' do
context 'when used without pagination' do
diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb
new file mode 100644
index 00000000000..4b90ad19640
--- /dev/null
+++ b/spec/services/labels/promote_service_spec.rb
@@ -0,0 +1,187 @@
+require 'spec_helper'
+
+describe Labels::PromoteService, services: true do
+ describe '#execute' do
+ let!(:user) { create(:user) }
+
+ context 'project without group' do
+ let!(:project_1) { create(:empty_project) }
+
+ let!(:project_label_1_1) { create(:label, project: project_1) }
+
+ subject(:service) { described_class.new(project_1, user) }
+
+ it 'fails on project without group' do
+ expect(service.execute(project_label_1_1)).to be_falsey
+ end
+ end
+
+ context 'project with group' do
+ let!(:promoted_label_name) { "Promoted Label" }
+ let!(:untouched_label_name) { "Untouched Label" }
+ let!(:promoted_description) { "Promoted Description" }
+ let!(:promoted_color) { "#0000FF" }
+ let!(:label_2_1_priority) { 1 }
+ let!(:label_3_1_priority) { 2 }
+
+ let!(:group_1) { create(:group) }
+ let!(:group_2) { create(:group) }
+
+ let!(:project_1) { create(:empty_project, namespace: group_1) }
+ let!(:project_2) { create(:empty_project, namespace: group_1) }
+ let!(:project_3) { create(:empty_project, namespace: group_1) }
+ let!(:project_4) { create(:empty_project, namespace: group_2) }
+
+ # Labels/issues can't be lazily created so we might as well eager initialize
+ # all other objects too since we use them inside
+ let!(:project_label_1_1) { create(:label, project: project_1, name: promoted_label_name, color: promoted_color, description: promoted_description) }
+ let!(:project_label_1_2) { create(:label, project: project_1, name: untouched_label_name) }
+ let!(:project_label_2_1) { create(:label, project: project_2, priority: label_2_1_priority, name: promoted_label_name, color: "#FF0000") }
+ let!(:project_label_3_1) { create(:label, project: project_3, priority: label_3_1_priority, name: promoted_label_name) }
+ let!(:project_label_3_2) { create(:label, project: project_3, priority: 1, name: untouched_label_name) }
+ let!(:project_label_4_1) { create(:label, project: project_4, name: promoted_label_name) }
+
+ let!(:issue_1_1) { create(:labeled_issue, project: project_1, labels: [project_label_1_1, project_label_1_2]) }
+ let!(:issue_1_2) { create(:labeled_issue, project: project_1, labels: [project_label_1_2]) }
+ let!(:issue_2_1) { create(:labeled_issue, project: project_2, labels: [project_label_2_1]) }
+ let!(:issue_4_1) { create(:labeled_issue, project: project_4, labels: [project_label_4_1]) }
+
+ let!(:merge_3_1) { create(:labeled_merge_request, source_project: project_3, target_project: project_3, labels: [project_label_3_1, project_label_3_2]) }
+
+ let!(:issue_board_2_1) { create(:board, project: project_2) }
+ let!(:issue_board_list_2_1) { create(:list, board: issue_board_2_1, label: project_label_2_1) }
+
+ let(:new_label) { group_1.labels.find_by(title: promoted_label_name) }
+
+ subject(:service) { described_class.new(project_1, user) }
+
+ it 'fails on group label' do
+ group_label = create(:group_label, group: group_1)
+
+ expect(service.execute(group_label)).to be_falsey
+ end
+
+ it 'is truthy on success' do
+ expect(service.execute(project_label_1_1)).to be_truthy
+ end
+
+ it 'recreates the label as a group label' do
+ expect { service.execute(project_label_1_1) }.
+ to change(project_1.labels, :count).by(-1).
+ and change(group_1.labels, :count).by(1)
+ expect(new_label).not_to be_nil
+ end
+
+ it 'copies title, description and color' do
+ service.execute(project_label_1_1)
+
+ expect(new_label.title).to eq(promoted_label_name)
+ expect(new_label.description).to eq(promoted_description)
+ expect(new_label.color).to eq(promoted_color)
+ end
+
+ it 'merges labels with the same name in group' do
+ expect { service.execute(project_label_1_1) }.to change(project_2.labels, :count).by(-1).and \
+ change(project_3.labels, :count).by(-1)
+ end
+
+ it 'recreates priorities' do
+ service.execute(project_label_1_1)
+
+ expect(new_label.priority(project_1)).to be_nil
+ expect(new_label.priority(project_2)).to eq(label_2_1_priority)
+ expect(new_label.priority(project_3)).to eq(label_3_1_priority)
+ end
+
+ it 'does not touch project out of promoted group' do
+ service.execute(project_label_1_1)
+ project_4_new_label = project_4.labels.find_by(title: promoted_label_name)
+
+ expect(project_4_new_label).not_to be_nil
+ expect(project_4_new_label.id).to eq(project_label_4_1.id)
+ end
+
+ it 'does not touch out of group priority' do
+ service.execute(project_label_1_1)
+
+ expect(new_label.priority(project_4)).to be_nil
+ end
+
+ it 'relinks issue with the promoted label' do
+ service.execute(project_label_1_1)
+ issue_label = issue_1_1.labels.find_by(title: promoted_label_name)
+
+ expect(issue_label).not_to be_nil
+ expect(issue_label.id).to eq(new_label.id)
+ end
+
+ it 'does not remove untouched labels from issue' do
+ expect { service.execute(project_label_1_1) }.not_to change(issue_1_1.labels, :count)
+ end
+
+ it 'does not relink untouched label in issue' do
+ service.execute(project_label_1_1)
+ issue_label = issue_1_2.labels.find_by(title: untouched_label_name)
+
+ expect(issue_label).not_to be_nil
+ expect(issue_label.id).to eq(project_label_1_2.id)
+ end
+
+ it 'relinks issues with merged labels' do
+ service.execute(project_label_1_1)
+ issue_label = issue_2_1.labels.find_by(title: promoted_label_name)
+
+ expect(issue_label).not_to be_nil
+ expect(issue_label.id).to eq(new_label.id)
+ end
+
+ it 'does not relink issues from other group' do
+ service.execute(project_label_1_1)
+ issue_label = issue_4_1.labels.find_by(title: promoted_label_name)
+
+ expect(issue_label).not_to be_nil
+ expect(issue_label.id).to eq(project_label_4_1.id)
+ end
+
+ it 'updates merge request' do
+ service.execute(project_label_1_1)
+ merge_label = merge_3_1.labels.find_by(title: promoted_label_name)
+
+ expect(merge_label).not_to be_nil
+ expect(merge_label.id).to eq(new_label.id)
+ end
+
+ it 'updates board lists' do
+ service.execute(project_label_1_1)
+ list = issue_board_2_1.lists.find_by(label: new_label)
+
+ expect(list).not_to be_nil
+ end
+
+ # In case someone adds a new relation to Label.rb and forgets to relink it
+ # and the database doesn't have foreign key constraints
+ it 'relinks all relations' do
+ service.execute(project_label_1_1)
+
+ Label.reflect_on_all_associations.each do |association|
+ expect(project_label_1_1.send(association.name).any?).to be_falsey
+ end
+ end
+
+ context 'with invalid group label' do
+ before do
+ allow(service).to receive(:clone_label_to_group_label).and_wrap_original do |m, *args|
+ label = m.call(*args)
+ allow(label).to receive(:valid?).and_return(false)
+
+ label
+ end
+ end
+
+ it 'raises an exception' do
+ expect { service.execute(project_label_1_1) }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index bfbee7ca35f..7cf2cd9968f 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -33,6 +33,49 @@ describe NotificationService, services: true do
end
end
+ # Next shared examples are intended to test notifications of "participants"
+ #
+ # they take the following parameters:
+ # * issuable
+ # * notification trigger
+ # * participant
+ #
+ shared_examples 'participating by note notification' do
+ it 'emails the participant' do
+ create(:note_on_issue, noteable: issuable, project_id: project.id, note: 'anything', author: participant)
+
+ notification_trigger
+
+ should_email(participant)
+ end
+ end
+
+ shared_examples 'participating by assignee notification' do
+ it 'emails the participant' do
+ issuable.update_attribute(:assignee, participant)
+
+ notification_trigger
+
+ should_email(participant)
+ end
+ end
+
+ shared_examples 'participating by author notification' do
+ it 'emails the participant' do
+ issuable.author = participant
+
+ notification_trigger
+
+ should_email(participant)
+ end
+ end
+
+ shared_examples_for 'participating notifications' do
+ it_should_behave_like 'participating by note notification'
+ it_should_behave_like 'participating by author notification'
+ it_should_behave_like 'participating by assignee notification'
+ end
+
describe 'Keys' do
describe '#new_key' do
let!(:key) { create(:personal_key) }
@@ -400,6 +443,8 @@ describe NotificationService, services: true do
before do
build_team(issue.project)
+ build_group(issue.project)
+
add_users_with_subscription(issue.project, issue)
reset_delivered_emails!
update_custom_notification(:new_issue, @u_guest_custom, project)
@@ -416,6 +461,8 @@ describe NotificationService, services: true do
should_email(@u_guest_custom)
should_email(@u_custom_global)
should_email(@u_participant_mentioned)
+ should_email(@g_global_watcher)
+ should_email(@g_watcher)
should_not_email(@u_mentioned)
should_not_email(@u_participating)
should_not_email(@u_disabled)
@@ -588,32 +635,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- issue.update_attribute(:assignee, @u_lazy_participant)
- notification.reassigned_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.reassigned_issue(issue, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- issue.author = @u_lazy_participant
- notification.reassigned_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { issue }
+ let(:notification_trigger) { notification.reassigned_issue(issue, @u_disabled) }
end
end
@@ -720,32 +745,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- issue.update_attribute(:assignee, @u_lazy_participant)
- notification.close_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.close_issue(issue, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- issue.author = @u_lazy_participant
- notification.close_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { issue }
+ let(:notification_trigger) { notification.close_issue(issue, @u_disabled) }
end
end
@@ -772,32 +775,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- issue.update_attribute(:assignee, @u_lazy_participant)
- notification.reopen_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.reopen_issue(issue, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- issue.author = @u_lazy_participant
- notification.reopen_issue(issue, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { issue }
+ let(:notification_trigger) { notification.reopen_issue(issue, @u_disabled) }
end
end
end
@@ -858,31 +839,28 @@ describe NotificationService, services: true do
end
context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.new_merge_request(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
+ it_should_behave_like 'participating by assignee notification' do
+ let(:participant) { create(:user, username: 'user-participant')}
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.new_merge_request(merge_request, @u_disabled) }
end
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.new_merge_request(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
+ it_should_behave_like 'participating by note notification' do
+ let(:participant) { create(:user, username: 'user-participant')}
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.new_merge_request(merge_request, @u_disabled) }
end
context 'by author' do
+ let(:participant) { create(:user, username: 'user-participant')}
+
before do
- merge_request.author = @u_lazy_participant
+ merge_request.author = participant
merge_request.save
notification.new_merge_request(merge_request, @u_disabled)
end
- it { should_not_email(@u_lazy_participant) }
+ it { should_not_email(participant) }
end
end
end
@@ -917,33 +895,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.reassigned_merge_request(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.reassigned_merge_request(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- merge_request.author = @u_lazy_participant
- merge_request.save
- notification.reassigned_merge_request(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.reassigned_merge_request(merge_request, @u_disabled) }
end
end
@@ -1014,33 +969,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.close_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.close_mr(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- merge_request.author = @u_lazy_participant
- merge_request.save
- notification.close_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.close_mr(merge_request, @u_disabled) }
end
end
@@ -1081,33 +1013,10 @@ describe NotificationService, services: true do
should_not_email(@u_watcher)
end
- context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.merge_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.merge_mr(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- merge_request.author = @u_lazy_participant
- merge_request.save
- notification.merge_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.merge_mr(merge_request, @u_disabled) }
end
end
@@ -1134,33 +1043,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.reopen_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.reopen_mr(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- merge_request.author = @u_lazy_participant
- merge_request.save
- notification.reopen_mr(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.reopen_mr(merge_request, @u_disabled) }
end
end
@@ -1180,33 +1066,10 @@ describe NotificationService, services: true do
should_not_email(@u_lazy_participant)
end
- context 'participating' do
- context 'by assignee' do
- before do
- merge_request.update_attribute(:assignee, @u_lazy_participant)
- notification.resolve_all_discussions(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by note' do
- let!(:note) { create(:note_on_issue, noteable: merge_request, project_id: project.id, note: 'anything', author: @u_lazy_participant) }
-
- before { notification.resolve_all_discussions(merge_request, @u_disabled) }
-
- it { should_email(@u_lazy_participant) }
- end
-
- context 'by author' do
- before do
- merge_request.author = @u_lazy_participant
- merge_request.save
- notification.resolve_all_discussions(merge_request, @u_disabled)
- end
-
- it { should_email(@u_lazy_participant) }
- end
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.resolve_all_discussions(merge_request, @u_disabled) }
end
end
end
@@ -1359,6 +1222,22 @@ describe NotificationService, services: true do
project.add_master(@u_custom_global)
end
+ # Users in the project's group but not part of project's team
+ # with different notification settings
+ def build_group(project)
+ group = create(:group, :public)
+ project.group = group
+
+ # Group member: global=disabled, group=watch
+ @g_watcher = create_user_with_notification(:watch, 'group_watcher', project.group)
+ @g_watcher.notification_settings_for(nil).disabled!
+
+ # Group member: global=watch, group=global
+ @g_global_watcher = create_global_setting_for(create(:user), :watch)
+ group.add_users([@g_watcher, @g_global_watcher], :master)
+ group
+ end
+
def create_global_setting_for(user, level)
setting = user.global_notification_setting
setting.level = level
@@ -1367,9 +1246,9 @@ describe NotificationService, services: true do
user
end
- def create_user_with_notification(level, username)
+ def create_user_with_notification(level, username, resource = project)
user = create(:user, username: username)
- setting = user.notification_settings_for(project)
+ setting = user.notification_settings_for(resource)
setting.level = level
setting.save
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index bd89c4a7c11..bed1031e40a 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -41,6 +41,25 @@ describe 'Search::GlobalService', services: true do
results = context.execute
expect(results.objects('projects')).to match_array [found_project]
end
+
+ context 'nested group' do
+ let!(:nested_group) { create(:group, :nested) }
+ let!(:project) { create(:project, namespace: nested_group) }
+
+ before { project.add_master(user) }
+
+ it 'returns result from nested group' do
+ context = Search::GlobalService.new(user, search: project.path)
+ results = context.execute
+ expect(results.objects('projects')).to match_array [project]
+ end
+
+ it 'returns result from descendants when search inside group' do
+ context = Search::GlobalService.new(user, search: project.path, group_id: nested_group.parent)
+ results = context.execute
+ expect(results.objects('projects')).to match_array [project]
+ end
+ end
end
end
end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index fef211ded50..db9f1231682 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -12,6 +12,7 @@ describe SystemHooksService, services: true do
it { expect(event_data(user, :create)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id, :username) }
it { expect(event_data(user, :destroy)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id, :username) }
it { expect(event_data(project, :create)).to include(:event_name, :name, :created_at, :updated_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
+ it { expect(event_data(project, :update)).to include(:event_name, :name, :created_at, :updated_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
it { expect(event_data(project, :destroy)).to include(:event_name, :name, :created_at, :updated_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
it { expect(event_data(project_member, :create)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) }
it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) }
@@ -68,6 +69,7 @@ describe SystemHooksService, services: true do
it { expect(event_name(project, :destroy)).to eq "project_destroy" }
it { expect(event_name(project, :rename)).to eq "project_rename" }
it { expect(event_name(project, :transfer)).to eq "project_transfer" }
+ it { expect(event_name(project, :update)).to eq "project_update" }
it { expect(event_name(project_member, :create)).to eq "user_add_to_team" }
it { expect(event_name(project_member, :destroy)).to eq "user_remove_from_team" }
it { expect(event_name(key, :create)).to eq 'key_create' }
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 9f5a0ac4ec6..bd7269045e1 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -245,6 +245,8 @@ describe SystemNoteService, services: true do
end
describe '.change_title' do
+ let(:noteable) { create(:issue, project: project, title: 'Lorem ipsum') }
+
subject { described_class.change_title(noteable, project, author, 'Old title') }
context 'when noteable responds to `title`' do
@@ -252,7 +254,7 @@ describe SystemNoteService, services: true do
it 'sets the note text' do
expect(subject.note).
- to eq "changed title from **{-Old title-}** to **{+#{noteable.title}+}**"
+ to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**"
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e160c11111b..ab38dac65c5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -9,6 +9,10 @@ require 'rspec/rails'
require 'shoulda/matchers'
require 'rspec/retry'
+if ENV['RSPEC_PROFILING_POSTGRES_URL'] || ENV['RSPEC_PROFILING']
+ require 'rspec_profiling/rspec'
+end
+
if ENV['CI'] && !ENV['NO_KNAPSACK']
require 'knapsack'
Knapsack::Adapters::RSpecAdapter.bind
diff --git a/spec/support/cycle_analytics_helpers/test_generation.rb b/spec/support/cycle_analytics_helpers/test_generation.rb
index 35b40d73191..10b90b40ba7 100644
--- a/spec/support/cycle_analytics_helpers/test_generation.rb
+++ b/spec/support/cycle_analytics_helpers/test_generation.rb
@@ -54,7 +54,7 @@ module CycleAnalyticsHelpers
end
context "when the data belongs to another project" do
- let(:other_project) { create(:project) }
+ let(:other_project) { create(:project, :repository) }
it "returns nil" do
# Use a stub to "trick" the data/condition functions
diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb
index f57c82809a6..87936bb4859 100644
--- a/spec/support/mentionable_shared_examples.rb
+++ b/spec/support/mentionable_shared_examples.rb
@@ -12,7 +12,7 @@ shared_context 'mentionable context' do
let!(:mentioned_mr) { create(:merge_request, source_project: project) }
let(:mentioned_commit) { project.commit("HEAD~1") }
- let(:ext_proj) { create(:project, :public) }
+ let(:ext_proj) { create(:project, :public, :repository) }
let(:ext_issue) { create(:issue, project: ext_proj) }
let(:ext_mr) { create(:merge_request, :simple, source_project: ext_proj) }
let(:ext_commit) { ext_proj.commit("HEAD~2") }
diff --git a/spec/support/mobile_helpers.rb b/spec/support/mobile_helpers.rb
new file mode 100644
index 00000000000..20d5849bcab
--- /dev/null
+++ b/spec/support/mobile_helpers.rb
@@ -0,0 +1,13 @@
+module MobileHelpers
+ def resize_screen_sm
+ resize_window(900, 768)
+ end
+
+ def restore_window_size
+ resize_window(1366, 768)
+ end
+
+ def resize_window(width, height)
+ page.driver.resize_window width, height
+ end
+end
diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb
index 74d9b8c6313..704922b6cf4 100644
--- a/spec/support/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/slack_mattermost_notifications_shared_examples.rb
@@ -26,7 +26,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do
describe "#execute" do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:username) { 'slack_username' }
let(:channel) { 'slack_channel' }
@@ -196,7 +196,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do
describe "Note events" do
let(:user) { create(:user) }
- let(:project) { create(:project, creator_id: user.id) }
+ let(:project) { create(:project, :repository, creator: user) }
before do
allow(chat_service).to receive_messages(
@@ -269,7 +269,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do
describe 'Pipeline events' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/views/ci/lints/show.html.haml_spec.rb b/spec/views/ci/lints/show.html.haml_spec.rb
index 2dac5ee23c8..3390ae247ff 100644
--- a/spec/views/ci/lints/show.html.haml_spec.rb
+++ b/spec/views/ci/lints/show.html.haml_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'ci/lints/show' do
- include Devise::TestHelpers
+ include Devise::Test::ControllerHelpers
describe 'XSS protection' do
let(:config_processor) { Ci::GitlabCiYamlProcessor.new(YAML.dump(content)) }
diff --git a/spec/views/projects/builds/show.html.haml_spec.rb b/spec/views/projects/builds/show.html.haml_spec.rb
index 745d0c745bd..44870cfcfb3 100644
--- a/spec/views/projects/builds/show.html.haml_spec.rb
+++ b/spec/views/projects/builds/show.html.haml_spec.rb
@@ -15,6 +15,36 @@ describe 'projects/builds/show', :view do
allow(view).to receive(:can?).and_return(true)
end
+ describe 'build information in header' do
+ let(:build) do
+ create(:ci_build, :success, environment: 'staging')
+ end
+
+ before do
+ render
+ end
+
+ it 'shows status name' do
+ expect(rendered).to have_css('.ci-status.ci-success', text: 'passed')
+ end
+
+ it 'does not render a link to the build' do
+ expect(rendered).not_to have_link('passed')
+ end
+
+ it 'shows build id' do
+ expect(rendered).to have_css('.js-build-id', text: build.id)
+ end
+
+ it 'shows a link to the pipeline' do
+ expect(rendered).to have_link(build.pipeline.id)
+ end
+
+ it 'shows a link to the commit' do
+ expect(rendered).to have_link(build.pipeline.short_sha)
+ end
+ end
+
describe 'environment info in build view' do
context 'build with latest deployment' do
let(:build) do