summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_settings_spec.rb90
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb17
-rw-r--r--spec/features/dashboard/issues_filter_spec.rb36
-rw-r--r--spec/features/dashboard/issues_spec.rb9
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb14
-rw-r--r--spec/features/groups/settings/group_badges_spec.rb124
-rw-r--r--spec/features/issuables/discussion_lock_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb9
-rw-r--r--spec/features/issues/form_spec.rb17
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb44
-rw-r--r--spec/features/issues/spam_issues_spec.rb3
-rw-r--r--spec/features/issues/user_uses_slash_commands_spec.rb26
-rw-r--r--spec/features/labels_hierarchy_spec.rb305
-rw-r--r--spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb9
-rw-r--r--spec/features/merge_request/user_uses_slash_commands_spec.rb22
-rw-r--r--spec/features/profile_spec.rb8
-rw-r--r--spec/features/profiles/account_spec.rb12
-rw-r--r--spec/features/projects/activity/rss_spec.rb7
-rw-r--r--spec/features/projects/activity/user_sees_activity_spec.rb21
-rw-r--r--spec/features/projects/badges/list_spec.rb2
-rw-r--r--spec/features/projects/edit_spec.rb62
-rw-r--r--spec/features/projects/files/browse_files_spec.rb46
-rw-r--r--spec/features/projects/files/creating_a_file_spec.rb37
-rw-r--r--spec/features/projects/files/dockerfile_dropdown_spec.rb13
-rw-r--r--spec/features/projects/files/download_buttons_spec.rb34
-rw-r--r--spec/features/projects/files/edit_file_soft_wrap_spec.rb7
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb9
-rw-r--r--spec/features/projects/files/files_sort_submodules_with_folders_spec.rb7
-rw-r--r--spec/features/projects/files/find_file_keyboard_spec.rb5
-rw-r--r--spec/features/projects/files/gitignore_dropdown_spec.rb13
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb13
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb12
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb9
-rw-r--r--spec/features/projects/files/template_selector_menu_spec.rb66
-rw-r--r--spec/features/projects/files/template_type_dropdown_spec.rb31
-rw-r--r--spec/features/projects/files/undo_template_spec.rb9
-rw-r--r--spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb (renamed from spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb)4
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb (renamed from spec/features/projects/user_browses_files_spec.rb)82
-rw-r--r--spec/features/projects/files/user_browses_lfs_files_spec.rb57
-rw-r--r--spec/features/projects/files/user_creates_directory_spec.rb (renamed from spec/features/projects/user_creates_directory_spec.rb)2
-rw-r--r--spec/features/projects/files/user_creates_files_spec.rb (renamed from spec/features/projects/user_creates_files_spec.rb)27
-rw-r--r--spec/features/projects/files/user_deletes_files_spec.rb (renamed from spec/features/projects/user_deletes_files_spec.rb)2
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb (renamed from spec/features/projects/user_edits_files_spec.rb)2
-rw-r--r--spec/features/projects/files/user_replaces_files_spec.rb (renamed from spec/features/projects/user_replaces_files_spec.rb)2
-rw-r--r--spec/features/projects/files/user_searches_for_files_spec.rb18
-rw-r--r--spec/features/projects/files/user_uploads_files_spec.rb (renamed from spec/features/projects/user_uploads_files_spec.rb)24
-rw-r--r--spec/features/projects/guest_navigation_menu_spec.rb82
-rw-r--r--spec/features/projects/issues/user_comments_on_issue_spec.rb73
-rw-r--r--spec/features/projects/issues/user_creates_issue_spec.rb87
-rw-r--r--spec/features/projects/issues/user_edits_issue_spec.rb25
-rw-r--r--spec/features/projects/issues/user_sorts_issues_spec.rb39
-rw-r--r--spec/features/projects/issues/user_toggles_subscription_spec.rb28
-rw-r--r--spec/features/projects/issues/user_views_issue_spec.rb16
-rw-r--r--spec/features/projects/issues/user_views_issues_spec.rb120
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb35
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb11
-rw-r--r--spec/features/projects/jobs_spec.rb57
-rw-r--r--spec/features/projects/labels/user_creates_labels_spec.rb88
-rw-r--r--spec/features/projects/labels/user_edits_labels_spec.rb25
-rw-r--r--spec/features/projects/labels/user_removes_labels_spec.rb52
-rw-r--r--spec/features/projects/labels/user_views_labels_spec.rb23
-rw-r--r--spec/features/projects/milestones/milestones_sorting_spec.rb1
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb16
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb17
-rw-r--r--spec/features/projects/project_settings_spec.rb205
-rw-r--r--spec/features/projects/settings/forked_project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/integration_settings_spec.rb28
-rw-r--r--spec/features/projects/settings/lfs_settings_spec.rb21
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb14
-rw-r--r--spec/features/projects/settings/project_badges_spec.rb125
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb47
-rw-r--r--spec/features/projects/settings/user_archives_project_spec.rb (renamed from spec/features/projects/user_archives_project_spec.rb)12
-rw-r--r--spec/features/projects/settings/user_changes_avatar_spec.rb44
-rw-r--r--spec/features/projects/settings/user_changes_default_branch_spec.rb20
-rw-r--r--spec/features/projects/settings/user_manages_group_links_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb (renamed from spec/features/projects/settings/merge_requests_settings_spec.rb)52
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb2
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb100
-rw-r--r--spec/features/projects/settings/user_tags_project_spec.rb23
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb73
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb40
-rw-r--r--spec/features/projects/show/developer_views_empty_project_instructions_spec.rb (renamed from spec/features/projects/developer_views_empty_project_instructions_spec.rb)2
-rw-r--r--spec/features/projects/show/download_buttons_spec.rb (renamed from spec/features/projects/main/download_buttons_spec.rb)2
-rw-r--r--spec/features/projects/show/no_password_spec.rb (renamed from spec/features/projects/no_password_spec.rb)0
-rw-r--r--spec/features/projects/show/redirects_spec.rb (renamed from spec/features/projects/redirects_spec.rb)2
-rw-r--r--spec/features/projects/show/rss_spec.rb (renamed from spec/features/projects/main/rss_spec.rb)2
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb (renamed from spec/features/projects/user_interacts_with_stars_spec.rb)2
-rw-r--r--spec/features/projects/show/user_manages_notifications_spec.rb19
-rw-r--r--spec/features/projects/show/user_sees_deletion_failure_message_spec.rb18
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb (renamed from spec/features/projects/user_views_details_spec.rb)23
-rw-r--r--spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb18
-rw-r--r--spec/features/projects/show/user_sees_readme_spec.rb16
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb318
-rw-r--r--spec/features/projects/show_project_spec.rb359
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/show_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_comments_on_snippet_spec.rb14
-rw-r--r--spec/features/projects/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_updates_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_views_snippets_spec.rb14
-rw-r--r--spec/features/projects/snippets_spec.rb49
-rw-r--r--spec/features/projects/user_sees_sidebar_spec.rb106
-rw-r--r--spec/features/projects/user_transfers_a_project_spec.rb49
-rw-r--r--spec/features/protected_branches_spec.rb5
-rw-r--r--spec/features/protected_tags_spec.rb5
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb127
-rw-r--r--spec/features/user_sorts_things_spec.rb57
107 files changed, 2846 insertions, 1344 deletions
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index c89bc54cad4..846b8040be6 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -120,6 +120,73 @@ feature 'Admin updates settings' do
expect(page).to have_content "Application settings saved successfully"
end
+ scenario 'Change Performance bar settings' do
+ group = create(:group)
+
+ page.within('.as-performance-bar') do
+ check 'Enable the Performance Bar'
+ fill_in 'Allowed group', with: group.path
+ click_on 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(find_field('Enable the Performance Bar')).to be_checked
+ expect(find_field('Allowed group').value).to eq group.path
+
+ page.within('.as-performance-bar') do
+ uncheck 'Enable the Performance Bar'
+ click_on 'Save changes'
+ end
+
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(find_field('Enable the Performance Bar')).not_to be_checked
+ expect(find_field('Allowed group').value).to be_nil
+ end
+
+ scenario 'Change Background jobs settings' do
+ page.within('.as-background') do
+ fill_in 'Throttling Factor', with: 1
+ click_button 'Save changes'
+ end
+
+ expect(Gitlab::CurrentSettings.sidekiq_throttling_factor).to eq(1)
+ expect(page).to have_content "Application settings saved successfully"
+ end
+
+ scenario 'Change Spam settings' do
+ page.within('.as-spam') do
+ check 'Enable reCAPTCHA'
+ fill_in 'reCAPTCHA Site Key', with: 'key'
+ fill_in 'reCAPTCHA Private Key', with: 'key'
+ fill_in 'IPs per user', with: 15
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.recaptcha_enabled).to be true
+ expect(Gitlab::CurrentSettings.unique_ips_limit_per_user).to eq(15)
+ end
+
+ scenario 'Configure web terminal' do
+ page.within('.as-terminal') do
+ fill_in 'Max session time', with: 15
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.terminal_max_session_time).to eq(15)
+ end
+
+ scenario 'Enable outbound requests' do
+ page.within('.as-outbound') do
+ check 'Allow requests to the local network from hooks and services'
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true
+ end
+
scenario 'Change Slack Notifications Service template settings' do
first(:link, 'Service Templates').click
click_link 'Slack notifications'
@@ -172,29 +239,6 @@ feature 'Admin updates settings' do
expect(find_field('ED25519 SSH keys').value).to eq(forbidden)
end
- scenario 'Change Performance Bar settings' do
- group = create(:group)
-
- check 'Enable the Performance Bar'
- fill_in 'Allowed group', with: group.path
-
- click_on 'Save'
-
- expect(page).to have_content 'Application settings saved successfully'
-
- expect(find_field('Enable the Performance Bar')).to be_checked
- expect(find_field('Allowed group').value).to eq group.path
-
- uncheck 'Enable the Performance Bar'
-
- click_on 'Save'
-
- expect(page).to have_content 'Application settings saved successfully'
-
- expect(find_field('Enable the Performance Bar')).not_to be_checked
- expect(find_field('Allowed group').value).to be_nil
- end
-
def check_all_events
page.check('Active')
page.check('Push')
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index d673bac4995..fb6c71ce997 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -13,17 +13,26 @@ describe "Dashboard Issues Feed" do
end
describe "atom feed" do
- it "renders atom feed via personal access token" do
+ it "returns 400 if no filter is used" do
personal_access_token = create(:personal_access_token, user: user)
visit issues_dashboard_path(:atom, private_token: personal_access_token.token)
expect(response_headers['Content-Type']).to have_content('application/atom+xml')
+ expect(page.status_code).to eq(400)
+ end
+
+ it "renders atom feed via personal access token" do
+ personal_access_token = create(:personal_access_token, user: user)
+
+ visit issues_dashboard_path(:atom, private_token: personal_access_token.token, assignee_id: user.id)
+
+ expect(response_headers['Content-Type']).to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{user.name} issues")
end
it "renders atom feed via RSS token" do
- visit issues_dashboard_path(:atom, rss_token: user.rss_token)
+ visit issues_dashboard_path(:atom, rss_token: user.rss_token, assignee_id: user.id)
expect(response_headers['Content-Type']).to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{user.name} issues")
@@ -44,7 +53,7 @@ describe "Dashboard Issues Feed" do
let!(:issue2) { create(:issue, author: user, assignees: [assignee], project: project2, description: 'test desc') }
it "renders issue fields" do
- visit issues_dashboard_path(:atom, rss_token: user.rss_token)
+ visit issues_dashboard_path(:atom, rss_token: user.rss_token, assignee_id: assignee.id)
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue2.title}')]")
@@ -67,7 +76,7 @@ describe "Dashboard Issues Feed" do
end
it "renders issue label and milestone info" do
- visit issues_dashboard_path(:atom, rss_token: user.rss_token)
+ visit issues_dashboard_path(:atom, rss_token: user.rss_token, assignee_id: assignee.id)
entry = find(:xpath, "//feed/entry[contains(summary/text(),'#{issue1.title}')]")
diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb
index 8759950e013..bab34ac9346 100644
--- a/spec/features/dashboard/issues_filter_spec.rb
+++ b/spec/features/dashboard/issues_filter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Dashboard Issues filtering', :js do
- include SortingHelper
+ include Spec::Support::Helpers::Features::SortingHelpers
let(:user) { create(:user) }
let(:project) { create(:project) }
@@ -17,6 +17,12 @@ feature 'Dashboard Issues filtering', :js do
visit_issues
end
+ context 'without any filter' do
+ it 'shows error message' do
+ expect(page).to have_content 'Please select at least one filter to see results'
+ end
+ end
+
context 'filtering by milestone' do
it 'shows all issues with no milestone' do
show_milestone_dropdown
@@ -27,15 +33,6 @@ feature 'Dashboard Issues filtering', :js do
expect(page).to have_selector('.issue', count: 1)
end
- it 'shows all issues with any milestone' do
- show_milestone_dropdown
-
- click_link 'Any Milestone'
-
- expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
- expect(page).to have_selector('.issue', count: 2)
- end
-
it 'shows all issues with the selected milestone' do
show_milestone_dropdown
@@ -68,13 +65,6 @@ feature 'Dashboard Issues filtering', :js do
let(:label) { create(:label, project: project) }
let!(:label_link) { create(:label_link, label: label, target: issue) }
- it 'shows all issues without filter' do
- page.within 'ul.content-list' do
- expect(page).to have_content issue.title
- expect(page).to have_content issue2.title
- end
- end
-
it 'shows all issues with the selected label' do
page.within '.labels-filter' do
find('.dropdown').click
@@ -89,15 +79,19 @@ feature 'Dashboard Issues filtering', :js do
end
context 'sorting' do
- it 'shows sorted issues' do
- sorting_by('Created date')
- visit_issues
+ before do
+ visit_issues(assignee_id: user.id)
+ end
+
+ it 'remembers last sorting value' do
+ sort_by('Created date')
+ visit_issues(assignee_id: user.id)
expect(find('.issues-filters')).to have_content('Created date')
end
it 'keeps sorting issues after visiting Projects Issues page' do
- sorting_by('Created date')
+ sort_by('Created date')
visit project_issues_path(project)
expect(find('.issues-filters')).to have_content('Created date')
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index 8d1d5a51750..e41a2e4ce09 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -51,15 +51,6 @@ RSpec.describe 'Dashboard Issues' do
expect(page).not_to have_content(other_issue.title)
end
- it 'shows all issues' do
- click_link('Reset filters')
-
- expect(page).to have_content(authored_issue.title)
- expect(page).to have_content(authored_issue_on_public_project.title)
- expect(page).to have_content(assigned_issue.title)
- expect(page).to have_content(other_issue.title)
- end
-
it 'state filter tabs work' do
find('#state-closed').click
expect(page).to have_current_path(issues_dashboard_url(assignee_id: current_user.id, state: 'closed'), url: true)
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index c8f3a8449f5..0965b745c03 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Dashboard Merge Requests' do
+ include Spec::Support::Helpers::Features::SortingHelpers
include FilterItemSelectHelper
- include SortingHelper
include ProjectForksHelper
let(:current_user) { create :user }
@@ -103,19 +103,15 @@ feature 'Dashboard Merge Requests' do
expect(page).not_to have_content(other_merge_request.title)
end
- it 'shows all merge requests', :js do
+ it 'shows error message without filter', :js do
filter_item_select('Any Assignee', '.js-assignee-search')
filter_item_select('Any Author', '.js-author-search')
- expect(page).to have_content(authored_merge_request.title)
- expect(page).to have_content(authored_merge_request_from_fork.title)
- expect(page).to have_content(assigned_merge_request.title)
- expect(page).to have_content(assigned_merge_request_from_fork.title)
- expect(page).to have_content(other_merge_request.title)
+ expect(page).to have_content('Please select at least one filter to see results')
end
it 'shows sorted merge requests' do
- sorting_by('Created date')
+ sort_by('Created date')
visit merge_requests_dashboard_path(assignee_id: current_user.id)
@@ -123,7 +119,7 @@ feature 'Dashboard Merge Requests' do
end
it 'keeps sorting merge requests after visiting Projects MR page' do
- sorting_by('Created date')
+ sort_by('Created date')
visit project_merge_requests_path(project)
diff --git a/spec/features/groups/settings/group_badges_spec.rb b/spec/features/groups/settings/group_badges_spec.rb
new file mode 100644
index 00000000000..92217294446
--- /dev/null
+++ b/spec/features/groups/settings/group_badges_spec.rb
@@ -0,0 +1,124 @@
+require 'spec_helper'
+
+feature 'Group Badges' do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:badge_link_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/commits/master'}
+ let(:badge_image_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/badges/master/build.svg'}
+ let!(:badge_1) { create(:group_badge, group: group) }
+ let!(:badge_2) { create(:group_badge, group: group) }
+
+ before do
+ group.add_owner(user)
+ sign_in(user)
+
+ visit(group_settings_badges_path(group))
+ end
+
+ it 'shows a list of badges', :js do
+ page.within '.badge-settings' do
+ wait_for_requests
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ expect(rows[0]).to have_content badge_1.link_url
+ expect(rows[1]).to have_content badge_2.link_url
+ end
+ end
+
+ context 'adding a badge', :js do
+ it 'user can preview a badge' do
+ page.within '.badge-settings form' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+ within '#badge-preview' do
+ expect(find('a')[:href]).to eq badge_link_url
+ expect(find('a img')[:src]).to eq badge_image_url
+ end
+ end
+ end
+
+ it do
+ page.within '.badge-settings' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+
+ click_button 'Add badge'
+ wait_for_requests
+
+ within '.panel-body' do
+ expect(find('a')[:href]).to eq badge_link_url
+ expect(find('a img')[:src]).to eq badge_image_url
+ end
+ end
+ end
+ end
+
+ context 'editing a badge', :js do
+ it 'form is shown when clicking edit button in list' do
+ page.within '.badge-settings' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ rows[1].find('[aria-label="Edit"]').click
+
+ within 'form' do
+ expect(find('#badge-link-url').value).to eq badge_2.link_url
+ expect(find('#badge-image-url').value).to eq badge_2.image_url
+ end
+ end
+ end
+
+ it 'updates a badge when submitting the edit form' do
+ page.within '.badge-settings' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ rows[1].find('[aria-label="Edit"]').click
+ within 'form' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+
+ click_button 'Save changes'
+ wait_for_requests
+ end
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ expect(rows[1]).to have_content badge_link_url
+ end
+ end
+ end
+
+ context 'deleting a badge', :js do
+ def click_delete_button(badge_row)
+ badge_row.find('[aria-label="Delete"]').click
+ end
+
+ it 'shows a modal when deleting a badge' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+
+ click_delete_button(rows[1])
+
+ expect(find('.modal .modal-title')).to have_content 'Delete badge?'
+ end
+
+ it 'deletes a badge when confirming the modal' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ click_delete_button(rows[1])
+
+ find('.modal .btn-danger').click
+ wait_for_requests
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 1
+ expect(rows[0]).to have_content badge_1.link_url
+ end
+ end
+end
diff --git a/spec/features/issuables/discussion_lock_spec.rb b/spec/features/issuables/discussion_lock_spec.rb
index ecbe51a7bc2..7ea29ff252b 100644
--- a/spec/features/issuables/discussion_lock_spec.rb
+++ b/spec/features/issuables/discussion_lock_spec.rb
@@ -14,7 +14,7 @@ describe 'Discussion Lock', :js do
project.add_developer(user)
end
- context 'when the discussion is unlocked' do
+ context 'when the discussion is unlocked' do
it 'the user can lock the issue' do
visit project_issue_path(project, issue)
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index b3c50964810..08ba91a2682 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -22,15 +22,6 @@ describe 'Filter issues', :js do
end
end
- def expect_issues_list_count(open_count, closed_count = 0)
- all_count = open_count + closed_count
-
- expect(page).to have_issuable_counts(open: open_count, closed: closed_count, all: all_count)
- page.within '.issues-list' do
- expect(page).to have_selector('.issue', count: open_count)
- end
- end
-
before do
project.add_master(user)
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 38c618d300e..4625a50b8d9 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -226,6 +226,23 @@ describe 'New/edit issue', :js do
expect(page).to have_selector('.atwho-view')
end
+
+ describe 'milestone' do
+ let!(:milestone) { create(:milestone, title: '"><img src=x onerror=alert(document.domain)>', project: project) }
+
+ it 'escapes milestone' do
+ click_button 'Milestone'
+
+ page.within '.issue-milestone' do
+ click_link milestone.title
+ end
+
+ page.within '.js-milestone-select' do
+ expect(page).to have_content milestone.title
+ expect(page).not_to have_selector 'img'
+ end
+ end
+ end
end
context 'edit issue' do
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index b835558b142..27551bb70ee 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -161,6 +161,50 @@ feature 'Issue Sidebar' do
end
end
end
+
+ context 'interacting with collapsed sidebar', :js do
+ collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
+ confidentiality_sidebar_block = '.block.confidentiality'
+ lock_sidebar_block = '.block.lock'
+ collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
+
+ before do
+ resize_screen_sm
+ end
+
+ it 'confidentiality block expands then collapses sidebar' do
+ expect(page).to have_css(collapsed_sidebar_selector)
+
+ page.within(confidentiality_sidebar_block) do
+ find(collapsed_sidebar_block_icon).click
+ end
+
+ expect(page).to have_css(expanded_sidebar_selector)
+
+ page.within(confidentiality_sidebar_block) do
+ page.find('button', text: 'Cancel').click
+ end
+
+ expect(page).to have_css(collapsed_sidebar_selector)
+ end
+
+ it 'lock block expands then collapses sidebar' do
+ expect(page).to have_css(collapsed_sidebar_selector)
+
+ page.within(lock_sidebar_block) do
+ find(collapsed_sidebar_block_icon).click
+ end
+
+ expect(page).to have_css(expanded_sidebar_selector)
+
+ page.within(lock_sidebar_block) do
+ page.find('button', text: 'Cancel').click
+ end
+
+ expect(page).to have_css(collapsed_sidebar_selector)
+ end
+ end
end
context 'as a guest' do
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index a75ca1d42b3..73022afbda2 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -34,9 +34,6 @@ describe 'New issue', :js do
click_button 'Submit issue'
- # reCAPTCHA alerts when it can't contact the server, so just accept it and move on
- page.driver.browser.switch_to.alert.accept
-
# it is impossible to test recaptcha automatically and there is no possibility to fill in recaptcha
# recaptcha verification is skipped in test environment and it always returns true
expect(page).not_to have_content('issue title')
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb
index ea7a97d02a0..ff2a0e15719 100644
--- a/spec/features/issues/user_uses_slash_commands_spec.rb
+++ b/spec/features/issues/user_uses_slash_commands_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Issues > User uses quick actions', :js do
- include QuickActionsHelpers
+ include Spec::Support::Helpers::Features::NotesHelpers
it_behaves_like 'issuable record that supports quick actions in its description and notes', :issue do
let(:issuable) { create(:issue, project: project) }
@@ -36,7 +36,7 @@ feature 'Issues > User uses quick actions', :js do
context 'when the current user can update the due date' do
it 'does not create a note, and sets the due date accordingly' do
- write_note("/due 2016-08-28")
+ add_note("/due 2016-08-28")
expect(page).not_to have_content '/due 2016-08-28'
expect(page).to have_content 'Commands applied'
@@ -57,7 +57,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and sets the due date accordingly' do
- write_note("/due 2016-08-28")
+ add_note("/due 2016-08-28")
expect(page).not_to have_content 'Commands applied'
@@ -75,7 +75,7 @@ feature 'Issues > User uses quick actions', :js do
it 'does not create a note, and removes the due date accordingly' do
expect(issue.due_date).to eq Date.new(2016, 8, 28)
- write_note("/remove_due_date")
+ add_note("/remove_due_date")
expect(page).not_to have_content '/remove_due_date'
expect(page).to have_content 'Commands applied'
@@ -96,7 +96,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and sets the due date accordingly' do
- write_note("/remove_due_date")
+ add_note("/remove_due_date")
expect(page).not_to have_content 'Commands applied'
@@ -111,7 +111,7 @@ feature 'Issues > User uses quick actions', :js do
let(:issue) { create(:issue, project: project) }
it 'does not recognize the command nor create a note' do
- write_note("/wip")
+ add_note("/wip")
expect(page).not_to have_content '/wip'
end
@@ -123,7 +123,7 @@ feature 'Issues > User uses quick actions', :js do
context 'when the current user can update issues' do
it 'does not create a note, and marks the issue as a duplicate' do
- write_note("/duplicate ##{original_issue.to_reference}")
+ add_note("/duplicate ##{original_issue.to_reference}")
expect(page).not_to have_content "/duplicate #{original_issue.to_reference}"
expect(page).to have_content 'Commands applied'
@@ -143,7 +143,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and does not mark the issue as a duplicate' do
- write_note("/duplicate ##{original_issue.to_reference}")
+ add_note("/duplicate ##{original_issue.to_reference}")
expect(page).not_to have_content 'Commands applied'
expect(page).not_to have_content "marked this issue as a duplicate of #{original_issue.to_reference}"
@@ -166,7 +166,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'moves the issue' do
- write_note("/move #{target_project.full_path}")
+ add_note("/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
@@ -186,7 +186,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not move the issue' do
- write_note("/move #{project_unauthorized.full_path}")
+ add_note("/move #{project_unauthorized.full_path}")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
@@ -200,7 +200,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not move the issue' do
- write_note("/move not/valid")
+ add_note("/move not/valid")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
@@ -223,7 +223,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'applies the commands to both issues and moves the issue' do
- write_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}")
+ add_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
@@ -242,7 +242,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'moves the issue and applies the commands to both issues' do
- write_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"")
+ add_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
new file mode 100644
index 00000000000..3e05e7b7f38
--- /dev/null
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -0,0 +1,305 @@
+require 'spec_helper'
+
+feature 'Labels Hierarchy', :js, :nested_groups do
+ include FilteredSearchHelpers
+
+ let!(:user) { create(:user) }
+ let!(:grandparent) { create(:group) }
+ let!(:parent) { create(:group, parent: grandparent) }
+ let!(:child) { create(:group, parent: parent) }
+ let!(:project_1) { create(:project, namespace: parent) }
+
+ let!(:grandparent_group_label) { create(:group_label, group: grandparent, title: 'Label_1') }
+ let!(:parent_group_label) { create(:group_label, group: parent, title: 'Label_2') }
+ let!(:child_group_label) { create(:group_label, group: child, title: 'Label_3') }
+ let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
+
+ before do
+ grandparent.add_owner(user)
+
+ sign_in(user)
+ end
+
+ shared_examples 'assigning labels from sidebar' do
+ it 'can assign all ancestors labels' do
+ [grandparent_group_label, parent_group_label, project_label_1].each do |label|
+ page.within('.block.labels') do
+ find('.edit-link').click
+ end
+
+ wait_for_requests
+
+ find('a.label-item', text: label.title).click
+ find('.dropdown-menu-close-icon').click
+
+ wait_for_requests
+
+ expect(page).to have_selector('span.label', text: label.title)
+ end
+ end
+
+ it 'does not find child group labels on dropdown' do
+ page.within('.block.labels') do
+ find('.edit-link').click
+ end
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('span.label', text: child_group_label.title)
+ end
+ end
+
+ shared_examples 'filtering by ancestor labels for projects' do |board = false|
+ it 'filters by ancestor labels' do
+ [grandparent_group_label, parent_group_label, project_label_1].each do |label|
+ select_label_on_dropdown(label.title)
+
+ wait_for_requests
+
+ if board
+ expect(page).to have_selector('.card-title') do |card|
+ expect(card).to have_selector('a', text: labeled_issue.title)
+ end
+ else
+ expect_issues_list_count(1)
+ expect(page).to have_selector('span.issue-title-text', text: labeled_issue.title)
+ end
+ end
+ end
+
+ it 'does not filter by descendant group labels' do
+ filtered_search.set("label:")
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.btn-link', text: child_group_label.title)
+ end
+ end
+
+ shared_examples 'filtering by ancestor labels for groups' do |board = false|
+ let(:project_2) { create(:project, namespace: parent) }
+ let!(:project_label_2) { create(:label, project: project_2, title: 'Label_4') }
+
+ let(:project_3) { create(:project, namespace: child) }
+ let!(:group_label_3) { create(:group_label, group: child, title: 'Label_5') }
+ let!(:project_label_3) { create(:label, project: project_3, title: 'Label_6') }
+
+ let!(:labeled_issue_2) { create(:labeled_issue, project: project_2, labels: [grandparent_group_label, parent_group_label, project_label_2]) }
+ let!(:labeled_issue_3) { create(:labeled_issue, project: project_3, labels: [grandparent_group_label, parent_group_label, group_label_3]) }
+
+ let!(:issue_2) { create(:issue, project: project_2) }
+
+ it 'filters by ancestors and current group labels' do
+ [grandparent_group_label, parent_group_label].each do |label|
+ select_label_on_dropdown(label.title)
+
+ wait_for_requests
+
+ if board
+ expect(page).to have_selector('.card-title') do |card|
+ expect(card).to have_selector('a', text: labeled_issue.title)
+ end
+
+ expect(page).to have_selector('.card-title') do |card|
+ expect(card).to have_selector('a', text: labeled_issue_2.title)
+ end
+ else
+ expect_issues_list_count(3)
+ expect(page).to have_selector('span.issue-title-text', text: labeled_issue.title)
+ expect(page).to have_selector('span.issue-title-text', text: labeled_issue_2.title)
+ expect(page).to have_selector('span.issue-title-text', text: labeled_issue_3.title)
+ end
+ end
+ end
+
+ it 'filters by descendant group labels' do
+ wait_for_requests
+
+ select_label_on_dropdown(group_label_3.title)
+
+ if board
+ expect(page).to have_selector('.card-title') do |card|
+ expect(card).not_to have_selector('a', text: labeled_issue_2.title)
+ end
+
+ expect(page).to have_selector('.card-title') do |card|
+ expect(card).to have_selector('a', text: labeled_issue_3.title)
+ end
+ else
+ expect_issues_list_count(1)
+ expect(page).to have_selector('span.issue-title-text', text: labeled_issue_3.title)
+ end
+ end
+
+ it 'does not filter by descendant group project labels' do
+ filtered_search.set("label:")
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.btn-link', text: project_label_3.title)
+ end
+ end
+
+ context 'when creating new issuable' do
+ before do
+ visit new_project_issue_path(project_1)
+ end
+
+ it 'should be able to assign ancestor group labels' do
+ fill_in 'issue_title', with: 'new created issue'
+ fill_in 'issue_description', with: 'new issue description'
+
+ find(".js-label-select").click
+ wait_for_requests
+
+ find('a.label-item', text: grandparent_group_label.title).click
+ find('a.label-item', text: parent_group_label.title).click
+ find('a.label-item', text: project_label_1.title).click
+
+ find('.btn-create').click
+
+ expect(page.find('.issue-details h2.title')).to have_content('new created issue')
+ expect(page).to have_selector('span.label', text: grandparent_group_label.title)
+ expect(page).to have_selector('span.label', text: parent_group_label.title)
+ expect(page).to have_selector('span.label', text: project_label_1.title)
+ end
+ end
+
+ context 'issuable sidebar' do
+ let!(:issue) { create(:issue, project: project_1) }
+
+ context 'on issue sidebar' do
+ before do
+ visit project_issue_path(project_1, issue)
+ end
+
+ it_behaves_like 'assigning labels from sidebar'
+ end
+
+ context 'on project board issue sidebar' do
+ let(:board) { create(:board, project: project_1) }
+
+ before do
+ visit project_board_path(project_1, board)
+
+ wait_for_requests
+
+ find('.card').click
+ end
+
+ it_behaves_like 'assigning labels from sidebar'
+ end
+
+ context 'on group board issue sidebar' do
+ let(:board) { create(:board, group: parent) }
+
+ before do
+ visit group_board_path(parent, board)
+
+ wait_for_requests
+
+ find('.card').click
+ end
+
+ it_behaves_like 'assigning labels from sidebar'
+ end
+ end
+
+ context 'issuable filtering' do
+ let!(:labeled_issue) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, project_label_1]) }
+ let!(:issue) { create(:issue, project: project_1) }
+
+ context 'on project issuable list' do
+ before do
+ visit project_issues_path(project_1)
+ end
+
+ it_behaves_like 'filtering by ancestor labels for projects'
+
+ it 'does not filter by descendant group labels' do
+ filtered_search.set("label:")
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.btn-link', text: child_group_label.title)
+ end
+ end
+
+ context 'on group issuable list' do
+ before do
+ visit issues_group_path(parent)
+ end
+
+ it_behaves_like 'filtering by ancestor labels for groups'
+ end
+
+ context 'on project boards filter' do
+ let(:board) { create(:board, project: project_1) }
+
+ before do
+ visit project_board_path(project_1, board)
+ end
+
+ it_behaves_like 'filtering by ancestor labels for projects', true
+ end
+
+ context 'on group boards filter' do
+ let(:board) { create(:board, group: parent) }
+
+ before do
+ visit group_board_path(parent, board)
+ end
+
+ it_behaves_like 'filtering by ancestor labels for groups', true
+ end
+ end
+
+ context 'creating boards lists' do
+ context 'on project boards' do
+ let(:board) { create(:board, project: project_1) }
+
+ before do
+ visit project_board_path(project_1, board)
+ find('.js-new-board-list').click
+ wait_for_requests
+ end
+
+ it 'creates lists from all ancestor labels' do
+ [grandparent_group_label, parent_group_label, project_label_1].each do |label|
+ find('a', text: label.title).click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
+ expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
+ expect(page).to have_selector('.board-title-text', text: project_label_1.title)
+ end
+ end
+
+ context 'on group boards' do
+ let(:board) { create(:board, group: parent) }
+
+ before do
+ visit group_board_path(parent, board)
+ find('.js-new-board-list').click
+ wait_for_requests
+ end
+
+ it 'creates lists from all ancestor group labels' do
+ [grandparent_group_label, parent_group_label].each do |label|
+ find('a', text: label.title).click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
+ expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
+ end
+
+ it 'does not create lists from descendant groups' do
+ expect(page).not_to have_selector('a', text: child_group_label.title)
+ end
+ end
+ end
+end
diff --git a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
index a43ba05c64c..fd1629746ef 100644
--- a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
@@ -9,6 +9,7 @@ describe 'Merge request < User sees mini pipeline graph', :js do
before do
build.run
+ build.trace.set('hello')
sign_in(user)
visit_merge_request
end
@@ -26,15 +27,15 @@ describe 'Merge request < User sees mini pipeline graph', :js do
let(:artifacts_file2) { fixture_file_upload(Rails.root.join('spec/fixtures/dk.png'), 'image/png') }
before do
- create(:ci_build, pipeline: pipeline, legacy_artifacts_file: artifacts_file1)
- create(:ci_build, pipeline: pipeline, when: 'manual')
+ create(:ci_build, :success, :trace_artifact, pipeline: pipeline, legacy_artifacts_file: artifacts_file1)
+ create(:ci_build, :manual, pipeline: pipeline, when: 'manual')
end
it 'avoids repeated database queries' do
before = ActiveRecord::QueryRecorder.new { visit_merge_request(format: :json, serializer: 'widget') }
- create(:ci_build, pipeline: pipeline, legacy_artifacts_file: artifacts_file2)
- create(:ci_build, pipeline: pipeline, when: 'manual')
+ create(:ci_build, :success, :trace_artifact, pipeline: pipeline, legacy_artifacts_file: artifacts_file2)
+ create(:ci_build, :manual, pipeline: pipeline, when: 'manual')
after = ActiveRecord::QueryRecorder.new { visit_merge_request(format: :json, serializer: 'widget') }
diff --git a/spec/features/merge_request/user_uses_slash_commands_spec.rb b/spec/features/merge_request/user_uses_slash_commands_spec.rb
index bd739e69d6c..7f261b580f7 100644
--- a/spec/features/merge_request/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_request/user_uses_slash_commands_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Merge request > User uses quick actions', :js do
- include QuickActionsHelpers
+ include Spec::Support::Helpers::Features::NotesHelpers
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
@@ -33,7 +33,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'toggling the WIP prefix in the title from note' do
context 'when the current user can toggle the WIP prefix' do
it 'adds the WIP: prefix to the title' do
- write_note("/wip")
+ add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).to have_content 'Commands applied'
@@ -44,7 +44,7 @@ describe 'Merge request > User uses quick actions', :js do
it 'removes the WIP: prefix from the title' do
merge_request.title = merge_request.wip_title
merge_request.save
- write_note("/wip")
+ add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).to have_content 'Commands applied'
@@ -62,7 +62,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not change the WIP prefix' do
- write_note("/wip")
+ add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).not_to have_content 'Commands applied'
@@ -75,7 +75,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'merging the MR from the note' do
context 'when the current user can merge the MR' do
it 'merges the MR' do
- write_note("/merge")
+ add_note("/merge")
expect(page).to have_content 'Commands applied'
@@ -90,7 +90,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not merge the MR' do
- write_note("/merge")
+ add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
@@ -107,7 +107,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not merge the MR' do
- write_note("/merge")
+ add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
@@ -118,7 +118,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'adding a due date from note' do
it 'does not recognize the command nor create a note' do
- write_note('/due 2016-08-28')
+ add_note('/due 2016-08-28')
expect(page).not_to have_content '/due 2016-08-28'
end
@@ -162,7 +162,7 @@ describe 'Merge request > User uses quick actions', :js do
describe '/target_branch command from note' do
context 'when the current user can change target branch' do
it 'changes target branch from a note' do
- write_note("message start \n/target_branch merge-test\n message end.")
+ add_note("message start \n/target_branch merge-test\n message end.")
wait_for_requests
expect(page).not_to have_content('/target_branch')
@@ -173,7 +173,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not fail when target branch does not exists' do
- write_note('/target_branch totally_not_existing_branch')
+ add_note('/target_branch totally_not_existing_branch')
expect(page).not_to have_content('/target_branch')
@@ -190,7 +190,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not change target branch' do
- write_note('/target_branch merge-test')
+ add_note('/target_branch merge-test')
expect(page).not_to have_content '/target_branch merge-test'
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 0848857ed1e..15dcb30cbdd 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -97,9 +97,13 @@ describe 'Profile account page', :js do
end
it 'changes my username' do
- fill_in 'user_username', with: 'new-username'
+ fill_in 'username-change-input', with: 'new-username'
- click_button('Update username')
+ page.find('[data-target="#username-change-confirmation-modal"]').click
+
+ page.within('.modal') do
+ find('.js-modal-primary-action').click
+ end
expect(page).to have_content('new-username')
end
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index e8eb0d17ca4..215b658eb7b 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Profile > Account' do
+feature 'Profile > Account', :js do
given(:user) { create(:user, username: 'foo') }
before do
@@ -59,6 +59,12 @@ end
def update_username(new_username)
allow(user.namespace).to receive(:move_dir)
visit profile_account_path
- fill_in 'user_username', with: new_username
- click_button 'Update username'
+
+ fill_in 'username-change-input', with: new_username
+
+ page.find('[data-target="#username-change-confirmation-modal"]').click
+
+ page.within('.modal') do
+ find('.js-modal-primary-action').click
+ end
end
diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb
index 2693e539268..cd1cfe07998 100644
--- a/spec/features/projects/activity/rss_spec.rb
+++ b/spec/features/projects/activity/rss_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Project Activity RSS' do
- let(:user) { create(:user) }
- let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:project) { create(:project, :public) }
+ let(:user) { project.owner }
let(:path) { activity_project_path(project) }
before do
@@ -11,8 +11,7 @@ feature 'Project Activity RSS' do
context 'when signed in' do
before do
- project.add_developer(user)
- sign_in(user)
+ sign_in(project.owner)
visit path
end
diff --git a/spec/features/projects/activity/user_sees_activity_spec.rb b/spec/features/projects/activity/user_sees_activity_spec.rb
new file mode 100644
index 00000000000..644a837dc14
--- /dev/null
+++ b/spec/features/projects/activity/user_sees_activity_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+feature 'Projects > Activity > User sees activity' do
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { project.creator }
+
+ before do
+ event = create(:push_event, project: project, author: user)
+ create(:push_event_payload,
+ event: event,
+ action: :created,
+ commit_to: '6d394385cf567f80a8fd85055db1ab4c5295806f',
+ ref: 'fix',
+ commit_count: 1)
+ visit activity_project_path(project)
+ end
+
+ it 'shows the last push in the activity page', :js do
+ expect(page).to have_content "#{user.name} pushed new branch fix"
+ end
+end
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index c705e479690..0abef4bc447 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -6,7 +6,7 @@ feature 'list of badges' do
project = create(:project, :repository)
project.add_master(user)
sign_in(user)
- visit project_pipelines_settings_path(project)
+ visit project_settings_ci_cd_path(project)
end
scenario 'user wants to see build status badge' do
diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb
deleted file mode 100644
index 1d4b4d0fdca..00000000000
--- a/spec/features/projects/edit_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'rails_helper'
-
-feature 'Project edit', :js do
- let(:admin) { create(:admin) }
- let(:user) { create(:user) }
- let(:project) { create(:project) }
-
- context 'feature visibility' do
- before do
- project.add_master(user)
- sign_in(user)
-
- visit edit_project_path(project)
- end
-
- context 'merge requests select' do
- it 'hides merge requests section' do
- find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
-
- expect(page).to have_selector('.merge-requests-feature', visible: false)
- end
-
- context 'given project with merge_requests_disabled access level' do
- let(:project) { create(:project, :merge_requests_disabled) }
-
- it 'hides merge requests section' do
- expect(page).to have_selector('.merge-requests-feature', visible: false)
- end
- end
- end
-
- context 'builds select' do
- it 'hides builds select section' do
- find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click
-
- expect(page).to have_selector('.builds-feature', visible: false)
- end
-
- context 'given project with builds_disabled access level' do
- let(:project) { create(:project, :builds_disabled) }
-
- it 'hides builds select section' do
- expect(page).to have_selector('.builds-feature', visible: false)
- end
- end
- end
- end
-
- context 'LFS enabled setting' do
- before do
- sign_in(admin)
- end
-
- it 'displays the correct elements' do
- allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
- visit edit_project_path(project)
-
- expect(page).to have_content('Git Large File Storage')
- expect(page).to have_selector('input[name="project[lfs_enabled]"] + button', visible: true)
- end
- end
-end
diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb
deleted file mode 100644
index 2c38c380d9d..00000000000
--- a/spec/features/projects/files/browse_files_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'spec_helper'
-
-feature 'user browses project', :js do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
-
- before do
- project.add_master(user)
- sign_in(user)
- visit project_tree_path(project, project.default_branch)
- end
-
- scenario "can see blame of '.gitignore'" do
- click_link ".gitignore"
- click_link 'Blame'
-
- expect(page).to have_content "*.rb"
- expect(page).to have_content "Dmitriy Zaporozhets"
- expect(page).to have_content "Initial commit"
- end
-
- scenario 'can see raw content of LFS pointer with LFS disabled' do
- allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(false)
- click_link 'files'
- click_link 'lfs'
- click_link 'lfs_object.iso'
- wait_for_requests
-
- expect(page).not_to have_content 'Download (1.5 MB)'
- expect(page).to have_content 'version https://git-lfs.github.com/spec/v1'
- expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
- expect(page).to have_content 'size 1575078'
- end
-
- scenario 'can see last commit for current directory' do
- last_commit = project.repository.last_commit_for_path(project.default_branch, 'files')
-
- click_link 'files'
- wait_for_requests
-
- page.within('.blob-commit-info') do
- expect(page).to have_content last_commit.short_id
- expect(page).to have_content last_commit.author_name
- end
- end
-end
diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb
deleted file mode 100644
index 8d982636525..00000000000
--- a/spec/features/projects/files/creating_a_file_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'spec_helper'
-
-feature 'User wants to create a file' do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
-
- background do
- project.add_master(user)
- sign_in user
- visit project_new_blob_path(project, project.default_branch)
- end
-
- def submit_new_file(options)
- file_name = find('#file_name')
- file_name.set options[:file_name] || 'README.md'
-
- file_content = find('#file-content', visible: false)
- file_content.set options[:file_content] || 'Some content'
-
- click_button 'Commit changes'
- end
-
- scenario 'file name contains Chinese characters' do
- submit_new_file(file_name: '测试.md')
- expect(page).to have_content 'The file has been successfully created.'
- end
-
- scenario 'directory name contains Chinese characters' do
- submit_new_file(file_name: '中文/测试.md')
- expect(page).to have_content 'The file has been successfully created'
- end
-
- scenario 'file name contains directory traversal' do
- submit_new_file(file_name: '../README.md')
- expect(page).to have_content 'Path cannot include directory traversal'
- end
-end
diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb
index f4a39e331fd..004585f7c9e 100644
--- a/spec/features/projects/files/dockerfile_dropdown_spec.rb
+++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb
@@ -1,22 +1,15 @@
require 'spec_helper'
-require 'fileutils'
-feature 'User wants to add a Dockerfile file' do
+describe 'Projects > Files > User wants to add a Dockerfile file' do
before do
- user = create(:user)
project = create(:project, :repository)
- project.add_master(user)
-
- sign_in user
-
+ sign_in project.owner
visit project_new_blob_path(project, 'master', file_name: 'Dockerfile')
end
- scenario 'user can see Dockerfile dropdown' do
+ it 'user can pick a Dockerfile file from the dropdown', :js do
expect(page).to have_css('.dockerfile-selector')
- end
- scenario 'user can pick a Dockerfile file from the dropdown', :js do
find('.js-dockerfile-selector').click
wait_for_requests
diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb
index 2101627f324..03cb3530e2b 100644
--- a/spec/features/projects/files/download_buttons_spec.rb
+++ b/spec/features/projects/files/download_buttons_spec.rb
@@ -1,42 +1,36 @@
require 'spec_helper'
-feature 'Download buttons in files tree' do
- given(:user) { create(:user) }
- given(:role) { :developer }
- given(:status) { 'success' }
- given(:project) { create(:project, :repository) }
+describe 'Projects > Files > Download buttons in files tree' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.creator }
- given(:pipeline) do
+ let(:pipeline) do
create(:ci_pipeline,
project: project,
sha: project.commit.sha,
ref: project.default_branch,
- status: status)
+ status: 'success')
end
- given!(:build) do
+ let!(:build) do
create(:ci_build, :success, :artifacts,
pipeline: pipeline,
status: pipeline.status,
name: 'build')
end
- background do
+ before do
sign_in(user)
- project.add_role(user, role)
- end
+ project.add_developer(user)
- describe 'when files tree' do
- context 'with artifacts' do
- before do
- visit project_tree_path(project, project.default_branch)
- end
+ visit project_tree_path(project, project.default_branch)
+ end
- scenario 'shows download artifacts button' do
- href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build')
+ context 'with artifacts' do
+ it 'shows download artifacts button' do
+ href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build')
- expect(page).to have_link "Download '#{build.name}'", href: href
- end
+ expect(page).to have_link "Download '#{build.name}'", href: href
end
end
end
diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
index 8d32ada5795..41af70d8ebc 100644
--- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb
+++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
@@ -1,10 +1,9 @@
require 'spec_helper'
-feature 'User uses soft wrap whilst editing file', :js do
+describe 'Projects > Files > User uses soft wrap whilst editing file', :js do
before do
- user = create(:user)
project = create(:project, :repository)
- project.add_master(user)
+ user = project.owner
sign_in user
visit project_new_blob_path(project, 'master', file_name: 'test_file-name')
page.within('.file-editor.code') do
@@ -23,7 +22,7 @@ feature 'User uses soft wrap whilst editing file', :js do
let(:toggle_button) { find('.soft-wrap-toggle') }
- scenario 'user clicks the "Soft wrap" button and then "No wrap" button' do
+ it 'user clicks the "Soft wrap" button and then "No wrap" button' do
wrapped_content_width = get_content_width
toggle_button.click
expect(toggle_button).to have_content 'No wrap'
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
index d874cdbff8d..4074e67e2d2 100644
--- a/spec/features/projects/files/editing_a_file_spec.rb
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-feature 'User wants to edit a file' do
+describe 'Projects > Files > User wants to edit a file' do
let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let(:user) { project.owner }
let(:commit_params) do
{
start_branch: project.default_branch,
@@ -15,14 +15,13 @@ feature 'User wants to edit a file' do
}
end
- background do
- project.add_master(user)
+ before do
sign_in user
visit project_edit_blob_path(project,
File.join(project.default_branch, '.gitignore'))
end
- scenario 'file has been updated since the user opened the edit page' do
+ it 'file has been updated since the user opened the edit page' do
Files::UpdateService.new(project, user, commit_params).execute
click_button 'Commit changes'
diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
index ead9f7e9168..b6dbf76bc9b 100644
--- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
+++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
@@ -1,16 +1,15 @@
require 'spec_helper'
-feature 'User views files page' do
- let(:user) { create(:user) }
+describe 'Projects > Files > User views files page' do
let(:project) { create(:forked_project_with_submodules) }
+ let(:user) { project.owner }
before do
- project.add_master(user)
sign_in user
visit project_tree_path(project, project.repository.root_ref)
end
- scenario 'user sees folders and submodules sorted together, followed by files' do
+ it 'user sees folders and submodules sorted together, followed by files' do
rows = all('td.tree-item-file-name').map(&:text)
tree = project.repository.tree
diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb
index e9ff06c72d8..cd0235f2b9e 100644
--- a/spec/features/projects/files/find_file_keyboard_spec.rb
+++ b/spec/features/projects/files/find_file_keyboard_spec.rb
@@ -1,11 +1,10 @@
require 'spec_helper'
-feature 'Find file keyboard shortcuts', :js do
- let(:user) { create(:user) }
+describe 'Projects > Files > Find file keyboard shortcuts', :js do
let(:project) { create(:project, :repository) }
+ let(:user) { project.owner }
before do
- project.add_master(user)
sign_in user
visit project_find_file_path(project, project.repository.root_ref)
diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb
index 79f3fd09b48..9fa4c053a40 100644
--- a/spec/features/projects/files/gitignore_dropdown_spec.rb
+++ b/spec/features/projects/files/gitignore_dropdown_spec.rb
@@ -1,25 +1,24 @@
require 'spec_helper'
-feature 'User wants to add a .gitignore file' do
+describe 'Projects > Files > User wants to add a .gitignore file' do
before do
- user = create(:user)
project = create(:project, :repository)
- project.add_master(user)
- sign_in user
+ sign_in project.owner
visit project_new_blob_path(project, 'master', file_name: '.gitignore')
end
- scenario 'user can see .gitignore dropdown' do
+ it 'user can pick a .gitignore file from the dropdown', :js do
expect(page).to have_css('.gitignore-selector')
- end
- scenario 'user can pick a .gitignore file from the dropdown', :js do
find('.js-gitignore-selector').click
+
wait_for_requests
+
within '.gitignore-selector' do
find('.dropdown-input-field').set('rails')
find('.dropdown-content li', text: 'Rails').click
end
+
wait_for_requests
expect(page).to have_css('.gitignore-selector .dropdown-toggle-text', text: 'Rails')
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
index db6c67b802e..53aff183562 100644
--- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -1,25 +1,24 @@
require 'spec_helper'
-feature 'User wants to add a .gitlab-ci.yml file' do
+describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do
before do
- user = create(:user)
project = create(:project, :repository)
- project.add_master(user)
- sign_in user
+ sign_in project.owner
visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml')
end
- scenario 'user can see .gitlab-ci.yml dropdown' do
+ it 'user can pick a template from the dropdown', :js do
expect(page).to have_css('.gitlab-ci-yml-selector')
- end
- scenario 'user can pick a template from the dropdown', :js do
find('.js-gitlab-ci-yml-selector').click
+
wait_for_requests
+
within '.gitlab-ci-yml-selector' do
find('.dropdown-input-field').set('Jekyll')
find('.dropdown-content li', text: 'Jekyll').click
end
+
wait_for_requests
expect(page).to have_css('.gitlab-ci-yml-selector .dropdown-toggle-text', text: 'Jekyll')
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index 07599600876..b410199fd1f 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -1,17 +1,17 @@
require 'spec_helper'
-feature 'project owner creates a license file', :js do
- let(:project_master) { create(:user) }
+describe 'Projects > Files > Project owner creates a license file', :js do
let(:project) { create(:project, :repository) }
- background do
+ let(:project_master) { project.owner }
+
+ before do
project.repository.delete_file(project_master, 'LICENSE',
message: 'Remove LICENSE', branch_name: 'master')
- project.add_master(project_master)
sign_in(project_master)
visit project_path(project)
end
- scenario 'project master creates a license file manually from a template' do
+ it 'project master creates a license file manually from a template' do
visit project_tree_path(project, project.repository.root_ref)
find('.add-to-tree').click
click_link 'New file'
@@ -35,7 +35,7 @@ feature 'project owner creates a license file', :js do
expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
end
- scenario 'project master creates a license file from the "Add license" link' do
+ it 'project master creates a license file from the "Add license" link' do
click_link 'Add License'
expect(page).to have_content('New file')
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index 7f1d1934103..53d8ace7c94 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -1,15 +1,14 @@
require 'spec_helper'
-feature 'project owner sees a link to create a license file in empty project', :js do
- let(:project_master) { create(:user) }
+describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do
let(:project) { create(:project_empty_repo) }
+ let(:project_master) { project.owner }
- background do
- project.add_master(project_master)
+ before do
sign_in(project_master)
end
- scenario 'project master creates a license file from a template' do
+ it 'project master creates a license file from a template' do
visit project_path(project)
click_on 'Add License'
expect(page).to have_content('New file')
diff --git a/spec/features/projects/files/template_selector_menu_spec.rb b/spec/features/projects/files/template_selector_menu_spec.rb
new file mode 100644
index 00000000000..b549a69ddf3
--- /dev/null
+++ b/spec/features/projects/files/template_selector_menu_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+feature 'Template selector menu', :js do
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_master(user)
+ sign_in user
+ end
+
+ context 'editing a non-matching file' do
+ before do
+ create_and_edit_file('README.md')
+ end
+
+ scenario 'is not displayed' do
+ check_template_selector_menu_display(false)
+ end
+
+ context 'user toggles preview' do
+ before do
+ click_link 'Preview'
+ end
+
+ scenario 'template selector menu is not displayed' do
+ check_template_selector_menu_display(false)
+ click_link 'Write'
+ check_template_selector_menu_display(false)
+ end
+ end
+ end
+
+ context 'editing a matching file' do
+ before do
+ visit project_edit_blob_path(project, File.join(project.default_branch, 'LICENSE'))
+ end
+
+ scenario 'is displayed' do
+ check_template_selector_menu_display(true)
+ end
+
+ context 'user toggles preview' do
+ before do
+ click_link 'Preview'
+ end
+
+ scenario 'template selector menu is hidden and shown correctly' do
+ check_template_selector_menu_display(false)
+ click_link 'Write'
+ check_template_selector_menu_display(true)
+ end
+ end
+ end
+end
+
+def check_template_selector_menu_display(is_visible)
+ count = is_visible ? 1 : 0
+ expect(page).to have_css('.template-selectors-menu', count: count)
+end
+
+def create_and_edit_file(file_name)
+ visit project_new_blob_path(project, 'master', file_name: file_name)
+ click_button "Commit changes"
+ visit project_edit_blob_path(project, File.join(project.default_branch, file_name))
+end
diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb
index 97408a9c41e..342a93b328f 100644
--- a/spec/features/projects/files/template_type_dropdown_spec.rb
+++ b/spec/features/projects/files/template_type_dropdown_spec.rb
@@ -1,11 +1,10 @@
require 'spec_helper'
-feature 'Template type dropdown selector', :js do
+describe 'Projects > Files > Template type dropdown selector', :js do
let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let(:user) { project.owner }
before do
- project.add_master(user)
sign_in user
end
@@ -14,16 +13,16 @@ feature 'Template type dropdown selector', :js do
create_and_edit_file('.random-file.js')
end
- scenario 'not displayed' do
+ it 'not displayed' do
check_type_selector_display(false)
end
- scenario 'selects every template type correctly' do
+ it 'selects every template type correctly' do
fill_in 'file_path', with: '.gitignore'
try_selecting_all_types
end
- scenario 'updates toggle value when input matches' do
+ it 'updates toggle value when input matches' do
fill_in 'file_path', with: '.gitignore'
check_type_selector_toggle_text('.gitignore')
end
@@ -34,15 +33,15 @@ feature 'Template type dropdown selector', :js do
visit project_edit_blob_path(project, File.join(project.default_branch, 'LICENSE'))
end
- scenario 'displayed' do
+ it 'displayed' do
check_type_selector_display(true)
end
- scenario 'is displayed when input matches' do
+ it 'is displayed when input matches' do
check_type_selector_display(true)
end
- scenario 'selects every template type correctly' do
+ it 'selects every template type correctly' do
try_selecting_all_types
end
@@ -51,7 +50,7 @@ feature 'Template type dropdown selector', :js do
click_link 'Preview changes'
end
- scenario 'type selector is hidden and shown correctly' do
+ it 'type selector is hidden and shown correctly' do
check_type_selector_display(false)
click_link 'Write'
check_type_selector_display(true)
@@ -64,15 +63,15 @@ feature 'Template type dropdown selector', :js do
visit project_new_blob_path(project, 'master', file_name: '.gitignore')
end
- scenario 'is displayed' do
+ it 'is displayed' do
check_type_selector_display(true)
end
- scenario 'toggle is set to the correct value' do
+ it 'toggle is set to the correct value' do
check_type_selector_toggle_text('.gitignore')
end
- scenario 'selects every template type correctly' do
+ it 'selects every template type correctly' do
try_selecting_all_types
end
end
@@ -82,15 +81,15 @@ feature 'Template type dropdown selector', :js do
visit project_new_blob_path(project, project.default_branch)
end
- scenario 'type selector is shown' do
+ it 'type selector is shown' do
check_type_selector_display(true)
end
- scenario 'toggle is set to the proper value' do
+ it 'toggle is set to the proper value' do
check_type_selector_toggle_text('Choose type')
end
- scenario 'selects every template type correctly' do
+ it 'selects every template type correctly' do
try_selecting_all_types
end
end
diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb
index fbf35fb4e1c..5de0bc009fb 100644
--- a/spec/features/projects/files/undo_template_spec.rb
+++ b/spec/features/projects/files/undo_template_spec.rb
@@ -1,11 +1,10 @@
require 'spec_helper'
-feature 'Template Undo Button', :js do
+describe 'Projects > Files > Template Undo Button', :js do
let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let(:user) { project.owner }
before do
- project.add_master(user)
sign_in user
end
@@ -15,7 +14,7 @@ feature 'Template Undo Button', :js do
select_file_template('.js-license-selector', 'Apache License 2.0')
end
- scenario 'reverts template application' do
+ it 'reverts template application' do
try_template_undo('http://www.apache.org/licenses/', 'Apply a license template')
end
end
@@ -27,7 +26,7 @@ feature 'Template Undo Button', :js do
select_file_template('.js-license-selector', 'Apache License 2.0')
end
- scenario 'reverts template application' do
+ it 'reverts template application' do
try_template_undo('http://www.apache.org/licenses/', 'Apply a license template')
end
end
diff --git a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb
index a17e65cc5b9..2d67837763c 100644
--- a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb
+++ b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
# This is a regression test for https://gitlab.com/gitlab-org/gitlab-ce/issues/37569
-describe 'User browses a tree with a folder containing only a folder' do
+describe 'Projects > Files > User browses a tree with a folder containing only a folder' do
let(:project) { create(:project, :empty_repo) }
- let(:user) { project.creator }
+ let(:user) { project.owner }
before do
# We need to disable the tree.flat_path provided by Gitaly to reproduce the issue
diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 62e6419cc42..9c1f11f4c12 100644
--- a/spec/features/projects/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe 'User browses files' do
- include DropzoneHelper
-
+describe 'Projects > Files > User browses files' do
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
@@ -12,13 +10,24 @@ describe 'User browses files' do
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
let(:tree_path_ref_6d39438) { project_tree_path(project, '6d39438') }
let(:tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
- let(:user) { create(:user) }
+ let(:user) { project.owner }
before do
- project.add_master(user)
sign_in(user)
end
+ it 'shows last commit for current directory' do
+ visit(tree_path_root_ref)
+
+ click_link 'files'
+
+ last_commit = project.repository.last_commit_for_path(project.default_branch, 'files')
+ page.within('.blob-commit-info') do
+ expect(page).to have_content last_commit.short_id
+ expect(page).to have_content last_commit.author_name
+ end
+ end
+
context 'when browsing the master branch' do
before do
visit(tree_path_root_ref)
@@ -48,7 +57,7 @@ describe 'User browses files' do
expect(page).not_to have_link('Browse Files')
end
- it 'shows the "Browse Code" link' do
+ it 'shows the "Browse Files" link' do
click_link('History')
expect(page).to have_link('Browse Files')
@@ -121,6 +130,14 @@ describe 'User browses files' do
wait_for_requests
expect(page).to have_content('*.rbc')
end
+
+ it 'is possible to blame' do
+ click_link 'Blame'
+
+ expect(page).to have_content "*.rb"
+ expect(page).to have_content "Dmitriy Zaporozhets"
+ expect(page).to have_content "Initial commit"
+ end
end
context 'when browsing a raw file' do
@@ -133,57 +150,4 @@ describe 'User browses files' do
expect(source).to eq('') # Body is filled in by gitlab-workhorse
end
end
-
- context 'when browsing an LFS object' do
- before do
- allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true)
- visit(project_tree_path(project, 'lfs'))
- end
-
- it 'shows an LFS object' do
- click_link('files')
- click_link('lfs')
- click_link('lfs_object.iso')
-
- expect(page).to have_content('Download (1.5 MB)')
- expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1')
- expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897')
- expect(page).not_to have_content('size 1575078')
-
- page.within('.content') do
- expect(page).to have_content('Delete')
- expect(page).to have_content('History')
- expect(page).to have_content('Permalink')
- expect(page).to have_content('Replace')
- expect(page).not_to have_content('Annotate')
- expect(page).not_to have_content('Blame')
- expect(page).not_to have_content('Edit')
- expect(page).to have_link('Download')
- end
- end
- end
-
- context 'when previewing a file content' do
- before do
- visit(tree_path_root_ref)
- end
-
- it 'shows a preview of a file content', :js do
- find('.add-to-tree').click
- click_link('Upload file')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'))
-
- page.within('#modal-upload-blob') do
- fill_in(:commit_message, with: 'New commit message')
- fill_in(:branch_name, with: 'new_branch_name', visible: true)
- click_button('Upload file')
- end
-
- wait_for_all_requests
-
- visit(project_blob_path(project, 'new_branch_name/logo_sample.svg'))
-
- expect(page).to have_css('.file-content img')
- end
- end
end
diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb
new file mode 100644
index 00000000000..c559a301ca1
--- /dev/null
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -0,0 +1,57 @@
+require 'spec_helper'
+
+describe 'Projects > Files > User browses LFS files' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.owner }
+
+ before do
+ sign_in(user)
+ end
+
+ context 'when LFS is disabled', :js do
+ before do
+ allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(false)
+ visit project_tree_path(project, 'lfs')
+ end
+
+ it 'is possible to see raw content of LFS pointer' do
+ click_link 'files'
+ click_link 'lfs'
+ click_link 'lfs_object.iso'
+
+ expect(page).to have_content 'version https://git-lfs.github.com/spec/v1'
+ expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
+ expect(page).to have_content 'size 1575078'
+ expect(page).not_to have_content 'Download (1.5 MB)'
+ end
+ end
+
+ context 'when LFS is enabled' do
+ before do
+ allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true)
+ visit project_tree_path(project, 'lfs')
+ end
+
+ it 'shows an LFS object' do
+ click_link('files')
+ click_link('lfs')
+ click_link('lfs_object.iso')
+
+ expect(page).to have_content('Download (1.5 MB)')
+ expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1')
+ expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897')
+ expect(page).not_to have_content('size 1575078')
+
+ page.within('.content') do
+ expect(page).to have_content('Delete')
+ expect(page).to have_content('History')
+ expect(page).to have_content('Permalink')
+ expect(page).to have_content('Replace')
+ expect(page).not_to have_content('Annotate')
+ expect(page).not_to have_content('Blame')
+ expect(page).not_to have_content('Edit')
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb
index 00e48f6fabd..847b5f0860f 100644
--- a/spec/features/projects/user_creates_directory_spec.rb
+++ b/spec/features/projects/files/user_creates_directory_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'User creates a directory', :js do
+describe 'Projects > Files > User creates a directory', :js do
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
diff --git a/spec/features/projects/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 8993533676b..208cc8d81f7 100644
--- a/spec/features/projects/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User creates files' do
+describe 'Projects > Files > User creates files' do
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
@@ -59,6 +59,31 @@ describe 'User creates files' do
expect(page).to have_selector('.file-editor')
end
+ def submit_new_file(options)
+ file_name = find('#file_name')
+ file_name.set options[:file_name] || 'README.md'
+
+ file_content = find('#file-content', visible: false)
+ file_content.set options[:file_content] || 'Some content'
+
+ click_button 'Commit changes'
+ end
+
+ it 'allows Chinese characters in file name' do
+ submit_new_file(file_name: '测试.md')
+ expect(page).to have_content 'The file has been successfully created.'
+ end
+
+ it 'allows Chinese characters in directory name' do
+ submit_new_file(file_name: '中文/测试.md')
+ expect(page).to have_content 'The file has been successfully created'
+ end
+
+ it 'does not allow directory traversal in file name' do
+ submit_new_file(file_name: '../README.md')
+ expect(page).to have_content 'Path cannot include directory traversal'
+ end
+
it 'creates and commit a new file', :js do
find('#editor')
execute_script("ace.edit('editor').setValue('*.rbca')")
diff --git a/spec/features/projects/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb
index 9d55197e719..36d3e001a64 100644
--- a/spec/features/projects/user_deletes_files_spec.rb
+++ b/spec/features/projects/files/user_deletes_files_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User deletes files' do
+describe 'Projects > Files > User deletes files' do
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index 05c2be473da..523a9f3f4fe 100644
--- a/spec/features/projects/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User edits files' do
+describe 'Projects > Files > User edits files' do
include ProjectForksHelper
let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
diff --git a/spec/features/projects/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb
index 74872403b35..9ac3417b671 100644
--- a/spec/features/projects/user_replaces_files_spec.rb
+++ b/spec/features/projects/files/user_replaces_files_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User replaces files' do
+describe 'Projects > Files > User replaces files' do
include DropzoneHelper
let(:fork_message) do
diff --git a/spec/features/projects/files/user_searches_for_files_spec.rb b/spec/features/projects/files/user_searches_for_files_spec.rb
index a105685bca7..a90e4918fb1 100644
--- a/spec/features/projects/files/user_searches_for_files_spec.rb
+++ b/spec/features/projects/files/user_searches_for_files_spec.rb
@@ -1,8 +1,7 @@
require 'spec_helper'
-describe 'User searches for files' do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
+describe 'Projects > Files > User searches for files' do
+ let(:user) { project.owner }
before do
sign_in(user)
@@ -10,11 +9,10 @@ describe 'User searches for files' do
describe 'project main screen' do
context 'when project is empty' do
- let(:empty_project) { create(:project) }
+ let(:project) { create(:project) }
before do
- empty_project.add_developer(user)
- visit project_path(empty_project)
+ visit project_path(project)
end
it 'does not show any result' do
@@ -26,6 +24,8 @@ describe 'User searches for files' do
end
context 'when project is not empty' do
+ let(:project) { create(:project, :repository) }
+
before do
project.add_developer(user)
visit project_path(project)
@@ -38,16 +38,16 @@ describe 'User searches for files' do
end
describe 'project tree screen' do
+ let(:project) { create(:project, :repository) }
+
before do
project.add_developer(user)
visit project_tree_path(project, project.default_branch)
end
- it 'shows "Find file" button' do
+ it 'shows found files' do
expect(page).to have_selector('.tree-controls .shortcuts-find-file')
- end
- it 'shows found files' do
fill_in('search', with: 'coffee')
click_button('Go')
diff --git a/spec/features/projects/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb
index 75898afcda9..7a1e3a8bcce 100644
--- a/spec/features/projects/user_uploads_files_spec.rb
+++ b/spec/features/projects/files/user_uploads_files_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User uploads files' do
+describe 'Projects > Files > User uploads files' do
include DropzoneHelper
let(:fork_message) do
@@ -11,7 +11,7 @@ describe 'User uploads files' do
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
- let(:user) { create(:user) }
+ let(:user) { project.creator }
before do
project.add_master(user)
@@ -23,7 +23,7 @@ describe 'User uploads files' do
visit(project_tree_path_root_ref)
end
- it 'uploads and commit a new file', :js do
+ it 'uploads and commit a new text file', :js do
find('.add-to-tree').click
click_link('Upload file')
drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
@@ -46,6 +46,24 @@ describe 'User uploads files' do
expect(page).to have_content('Lorem ipsum dolor sit amet')
expect(page).to have_content('Sed ut perspiciatis unde omnis')
end
+
+ it 'uploads and commit a new image file', :js do
+ find('.add-to-tree').click
+ click_link('Upload file')
+ drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'))
+
+ page.within('#modal-upload-blob') do
+ fill_in(:commit_message, with: 'New commit message')
+ fill_in(:branch_name, with: 'new_branch_name', visible: true)
+ click_button('Upload file')
+ end
+
+ wait_for_all_requests
+
+ visit(project_blob_path(project, 'new_branch_name/logo_sample.svg'))
+
+ expect(page).to have_css('.file-content img')
+ end
end
context 'when an user does not have write access' do
diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb
deleted file mode 100644
index 199682b943c..00000000000
--- a/spec/features/projects/guest_navigation_menu_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-require 'spec_helper'
-
-describe 'Guest navigation menu' do
- let(:project) { create(:project, :private, public_builds: false) }
- let(:guest) { create(:user) }
-
- before do
- project.add_guest(guest)
-
- sign_in(guest)
- end
-
- it 'shows allowed tabs only' do
- visit project_path(project)
-
- within('.nav-sidebar') do
- expect(page).to have_content 'Overview'
- expect(page).to have_content 'Issues'
- expect(page).to have_content 'Wiki'
-
- expect(page).not_to have_content 'Repository'
- expect(page).not_to have_content 'Pipelines'
- expect(page).not_to have_content 'Merge Requests'
- end
- end
-
- it 'does not show fork button' do
- visit project_path(project)
-
- within('.count-buttons') do
- expect(page).not_to have_link 'Fork'
- end
- end
-
- it 'does not show clone path' do
- visit project_path(project)
-
- within('.project-repo-buttons') do
- expect(page).not_to have_selector '.project-clone-holder'
- end
- end
-
- describe 'project landing page' do
- before do
- project.project_feature.update!(
- issues_access_level: ProjectFeature::DISABLED,
- wiki_access_level: ProjectFeature::DISABLED
- )
- end
-
- it 'does not show the project file list landing page' do
- visit project_path(project)
-
- expect(page).not_to have_selector '.project-stats'
- expect(page).not_to have_selector '.project-last-commit'
- expect(page).not_to have_selector '.project-show-files'
- expect(page).to have_selector '.project-show-customize_workflow'
- end
-
- it 'shows the customize workflow when issues and wiki are disabled' do
- visit project_path(project)
-
- expect(page).to have_selector '.project-show-customize_workflow'
- end
-
- it 'shows the wiki when enabled' do
- project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE)
-
- visit project_path(project)
-
- expect(page).to have_selector '.project-show-wiki'
- end
-
- it 'shows the issues when enabled' do
- project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE)
-
- visit project_path(project)
-
- expect(page).to have_selector '.issues-list'
- end
- end
-end
diff --git a/spec/features/projects/issues/user_comments_on_issue_spec.rb b/spec/features/projects/issues/user_comments_on_issue_spec.rb
new file mode 100644
index 00000000000..c45fdc7642f
--- /dev/null
+++ b/spec/features/projects/issues/user_comments_on_issue_spec.rb
@@ -0,0 +1,73 @@
+require "spec_helper"
+
+describe "User comments on issue", :js do
+ include Spec::Support::Helpers::Features::NotesHelpers
+
+ let(:project) { create(:project_empty_repo, :public) }
+ let(:issue) { create(:issue, project: project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_guest(user)
+ sign_in(user)
+
+ visit(project_issue_path(project, issue))
+ end
+
+ context "when adding comments" do
+ it "adds comment" do
+ content = "XML attached"
+ target_form = ".js-main-target-form"
+
+ add_note(content)
+
+ page.within(".note") do
+ expect(page).to have_content(content)
+ end
+
+ page.within(target_form) do
+ find(".error-alert", visible: false)
+ end
+ end
+
+ it "adds comment with code block" do
+ comment = "```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```"
+
+ add_note(comment)
+
+ expect(page).to have_content(comment)
+ end
+ end
+
+ context "when editing comments" do
+ it "edits comment" do
+ add_note("# Comment with a header")
+
+ page.within(".note-body > .note-text") do
+ expect(page).to have_content("Comment with a header").and have_no_css("#comment-with-a-header")
+ end
+
+ page.within(".main-notes-list") do
+ note = find(".note")
+
+ note.hover
+ note.find(".js-note-edit").click
+ end
+
+ expect(page).to have_css(".current-note-edit-form textarea")
+
+ comment = "+1 Awesome!"
+
+ page.within(".current-note-edit-form") do
+ fill_in("note[note]", with: comment)
+ click_button("Save comment")
+ end
+
+ wait_for_requests
+
+ page.within(".note") do
+ expect(page).to have_content(comment)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/issues/user_creates_issue_spec.rb b/spec/features/projects/issues/user_creates_issue_spec.rb
new file mode 100644
index 00000000000..e76f7c5589d
--- /dev/null
+++ b/spec/features/projects/issues/user_creates_issue_spec.rb
@@ -0,0 +1,87 @@
+require "spec_helper"
+
+describe "User creates issue" do
+ let(:project) { create(:project_empty_repo, :public) }
+ let(:user) { create(:user) }
+
+ context "when signed in as guest" do
+ before do
+ project.add_guest(user)
+ sign_in(user)
+
+ visit(new_project_issue_path(project))
+ end
+
+ it "creates issue" do
+ page.within(".issue-form") do
+ expect(page).to have_no_content("Assign to")
+ .and have_no_content("Labels")
+ .and have_no_content("Milestone")
+ end
+
+ issue_title = "500 error on profile"
+
+ fill_in("Title", with: issue_title)
+ click_button("Submit issue")
+
+ expect(page).to have_content(issue_title)
+ .and have_content(user.name)
+ .and have_content(project.name)
+ end
+ end
+
+ context "when signed in as developer", :js do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(new_project_issue_path(project))
+ end
+
+ context "when previewing" do
+ it "previews content" do
+ form = first(".gfm-form")
+ textarea = first(".gfm-form textarea")
+
+ page.within(form) do
+ click_link("Preview")
+
+ preview = find(".js-md-preview") # this element is findable only when the "Preview" link is clicked.
+
+ expect(preview).to have_content("Nothing to preview.")
+
+ click_link("Write")
+ fill_in("Description", with: "Bug fixed :smile:")
+ click_link("Preview")
+
+ expect(preview).to have_css("gl-emoji")
+ expect(textarea).not_to be_visible
+ end
+ end
+ end
+
+ context "with labels" do
+ LABEL_TITLES = %w(bug feature enhancement).freeze
+
+ before do
+ LABEL_TITLES.each do |title|
+ create(:label, project: project, title: title)
+ end
+ end
+
+ it "creates issue" do
+ issue_title = "500 error on profile"
+
+ fill_in("Title", with: issue_title)
+ click_button("Label")
+ click_link(LABEL_TITLES.first)
+ click_button("Submit issue")
+
+ expect(page).to have_content(issue_title)
+ .and have_content(user.name)
+ .and have_content(project.name)
+ .and have_content(LABEL_TITLES.first)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/issues/user_edits_issue_spec.rb b/spec/features/projects/issues/user_edits_issue_spec.rb
new file mode 100644
index 00000000000..1d9c3abc20f
--- /dev/null
+++ b/spec/features/projects/issues/user_edits_issue_spec.rb
@@ -0,0 +1,25 @@
+require "spec_helper"
+
+describe "User edits issue", :js do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+ set(:issue) { create(:issue, project: project, author: user) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(edit_project_issue_path(project, issue))
+ end
+
+ it "previews content" do
+ form = first(".gfm-form")
+
+ page.within(form) do
+ fill_in("Description", with: "Bug fixed :smile:")
+ click_link("Preview")
+ end
+
+ expect(form).to have_link("Write")
+ end
+end
diff --git a/spec/features/projects/issues/user_sorts_issues_spec.rb b/spec/features/projects/issues/user_sorts_issues_spec.rb
new file mode 100644
index 00000000000..c3d63000dac
--- /dev/null
+++ b/spec/features/projects/issues/user_sorts_issues_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+
+describe "User sorts issues" do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:issue1) { create(:issue, project: project) }
+ set(:issue2) { create(:issue, project: project) }
+ set(:issue3) { create(:issue, project: project) }
+
+ before do
+ create_list(:award_emoji, 2, :upvote, awardable: issue1)
+ create_list(:award_emoji, 2, :downvote, awardable: issue2)
+ create(:award_emoji, :downvote, awardable: issue1)
+ create(:award_emoji, :upvote, awardable: issue2)
+
+ visit(project_issues_path(project))
+ end
+
+ it "sorts by popularity" do
+ find("button.dropdown-toggle").click
+
+ page.within(".content ul.dropdown-menu.dropdown-menu-align-right li") do
+ click_link("Popularity")
+ end
+
+ page.within(".issues-list") do
+ page.within("li.issue:nth-child(1)") do
+ expect(page).to have_content(issue1.title)
+ end
+
+ page.within("li.issue:nth-child(2)") do
+ expect(page).to have_content(issue2.title)
+ end
+
+ page.within("li.issue:nth-child(3)") do
+ expect(page).to have_content(issue3.title)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/issues/user_toggles_subscription_spec.rb b/spec/features/projects/issues/user_toggles_subscription_spec.rb
new file mode 100644
index 00000000000..117a614b980
--- /dev/null
+++ b/spec/features/projects/issues/user_toggles_subscription_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+
+describe "User toggles subscription", :js do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+ set(:issue) { create(:issue, project: project, author: user) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_issue_path(project, issue))
+ end
+
+ it "unsibscribes from issue" do
+ subscription_button = find(".js-issuable-subscribe-button")
+
+ # Check we're subscribed.
+ expect(subscription_button).to have_css("button.is-checked")
+
+ # Toggle subscription.
+ find(".js-issuable-subscribe-button button").click
+ wait_for_requests
+
+ # Check we're unsubscribed.
+ expect(subscription_button).to have_css("button:not(.is-checked)")
+ end
+end
diff --git a/spec/features/projects/issues/user_views_issue_spec.rb b/spec/features/projects/issues/user_views_issue_spec.rb
new file mode 100644
index 00000000000..f7f2cde3d64
--- /dev/null
+++ b/spec/features/projects/issues/user_views_issue_spec.rb
@@ -0,0 +1,16 @@
+require "spec_helper"
+
+describe "User views issue" do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+ set(:issue) { create(:issue, project: project, description: "# Description header", author: user) }
+
+ before do
+ project.add_guest(user)
+ sign_in(user)
+
+ visit(project_issue_path(project, issue))
+ end
+
+ it { expect(page).to have_header_with_correct_id_and_link(1, "Description header", "description-header") }
+end
diff --git a/spec/features/projects/issues/user_views_issues_spec.rb b/spec/features/projects/issues/user_views_issues_spec.rb
index d35009b8974..58afb4efb86 100644
--- a/spec/features/projects/issues/user_views_issues_spec.rb
+++ b/spec/features/projects/issues/user_views_issues_spec.rb
@@ -1,56 +1,116 @@
-require 'spec_helper'
+require "spec_helper"
-describe 'User views issues' do
+describe "User views issues" do
+ let!(:closed_issue) { create(:closed_issue, project: project) }
+ let!(:open_issue1) { create(:issue, project: project) }
+ let!(:open_issue2) { create(:issue, project: project) }
set(:user) { create(:user) }
- shared_examples_for 'shows issues' do
- it 'shows issues' do
- expect(page).to have_content(project.name)
- .and have_content(issue1.title)
- .and have_content(issue2.title)
- .and have_no_selector('.js-new-board-list')
+ shared_examples "opens issue from list" do
+ it "opens issue" do
+ click_link(issue.title)
+
+ expect(page).to have_content(issue.title)
end
end
- context 'when project is public' do
- set(:project) { create(:project_empty_repo, :public) }
- set(:issue1) { create(:issue, project: project) }
- set(:issue2) { create(:issue, project: project) }
+ shared_examples "open issues" do
+ context "open issues" do
+ let(:label) { create(:label, project: project, title: "bug") }
- context 'when signed in' do
before do
- project.add_developer(user)
- sign_in(user)
+ open_issue1.labels << label
+
+ visit(project_issues_path(project, state: :opened))
+ end
- visit(project_issues_path(project))
+ it "shows open issues" do
+ expect(page).to have_content(project.name)
+ .and have_content(open_issue1.title)
+ .and have_content(open_issue2.title)
+ .and have_no_content(closed_issue.title)
+ .and have_no_selector(".js-new-board-list")
end
- include_examples 'shows issues'
+ it "opens issues by label" do
+ page.within(".issues-list") do
+ click_link(label.title)
+ end
+
+ expect(page).to have_content(open_issue1.title)
+ .and have_no_content(open_issue2.title)
+ .and have_no_content(closed_issue.title)
+ end
+
+ include_examples "opens issue from list" do
+ let(:issue) { open_issue1 }
+ end
end
+ end
- context 'when not signed in' do
+ shared_examples "closed issues" do
+ context "closed issues" do
before do
- visit(project_issues_path(project))
+ visit(project_issues_path(project, state: :closed))
+ end
+
+ it "shows closed issues" do
+ expect(page).to have_content(project.name)
+ .and have_content(closed_issue.title)
+ .and have_no_content(open_issue1.title)
+ .and have_no_content(open_issue2.title)
+ .and have_no_selector(".js-new-board-list")
end
- include_examples 'shows issues'
+ include_examples "opens issue from list" do
+ let(:issue) { closed_issue }
+ end
end
end
- context 'when project is internal' do
- set(:project) { create(:project_empty_repo, :internal) }
- set(:issue1) { create(:issue, project: project) }
- set(:issue2) { create(:issue, project: project) }
-
- context 'when signed in' do
+ shared_examples "all issues" do
+ context "all issues" do
before do
- project.add_developer(user)
- sign_in(user)
+ visit(project_issues_path(project, state: :all))
+ end
- visit(project_issues_path(project))
+ it "shows all issues" do
+ expect(page).to have_content(project.name)
+ .and have_content(closed_issue.title)
+ .and have_content(open_issue1.title)
+ .and have_content(open_issue2.title)
+ .and have_no_selector(".js-new-board-list")
end
- include_examples 'shows issues'
+ include_examples "opens issue from list" do
+ let(:issue) { closed_issue }
+ end
+ end
+ end
+
+ %w[internal public].each do |visibility|
+ shared_examples "#{visibility} project" do
+ context "when project is #{visibility}" do
+ let(:project) { create(:project_empty_repo, :"#{visibility}") }
+
+ include_examples "open issues"
+ include_examples "closed issues"
+ include_examples "all issues"
+ end
end
end
+
+ context "when signed in as developer" do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ include_examples "public project"
+ include_examples "internal project"
+ end
+
+ context "when not signed in" do
+ include_examples "public project"
+ end
end
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 4c49cff30d4..bff5bbe99af 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -1,16 +1,15 @@
require 'spec_helper'
describe 'User browses a job', :js do
- let!(:build) { create(:ci_build, :running, :coverage, pipeline: pipeline) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
- let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:user) { create(:user) }
+ let(:user_access_level) { :developer }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let!(:build) { create(:ci_build, :success, :trace_artifact, :coverage, pipeline: pipeline) }
before do
project.add_master(user)
project.enable_ci
- build.success
- build.trace.set('job trace')
sign_in(user)
@@ -21,7 +20,9 @@ describe 'User browses a job', :js do
expect(page).to have_content("Job ##{build.id}")
expect(page).to have_css('#build-trace')
- accept_confirm { click_link('Erase') }
+ # scroll to the top of the page first
+ execute_script "window.scrollTo(0,0)"
+ accept_confirm { find('.js-erase-link').click }
expect(page).to have_no_css('.artifacts')
expect(build).not_to have_trace
@@ -34,4 +35,26 @@ describe 'User browses a job', :js do
expect(build.project.running_or_pending_build_count).to eq(build.project.builds.running_or_pending.count(:all))
end
+
+ context 'with a failed job' do
+ let!(:build) { create(:ci_build, :failed, :trace_artifact, pipeline: pipeline) }
+
+ it 'displays the failure reason' do
+ within('.builds-container') do
+ build_link = first('.build-job > a')
+ expect(build_link['data-title']).to eq('test - failed <br> (unknown failure)')
+ end
+ end
+ end
+
+ context 'when a failed job has been retried' do
+ let!(:build) { create(:ci_build, :failed, :retried, :trace_artifact, pipeline: pipeline) }
+
+ it 'displays the failure reason and retried label' do
+ within('.builds-container') do
+ build_link = first('.build-job > a')
+ expect(build_link['data-title']).to eq('test - failed <br> (unknown failure) (retried)')
+ end
+ end
+ end
end
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index 767777f3bf9..36ebbeadd4a 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -29,4 +29,15 @@ describe 'User browses jobs' do
expect(ci_lint_tool_link[:href]).to end_with(ci_lint_path)
end
end
+
+ context 'with a failed job' do
+ let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) }
+
+ it 'displays a tooltip with the failure reason' do
+ page.within('.ci-table') do
+ failed_job_link = page.find('.ci-failed')
+ expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)')
+ end
+ end
+ end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 5d311f2dde3..749a1b81872 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -113,7 +113,7 @@ feature 'Jobs' do
describe "GET /:project/jobs/:id" do
context "Job from project" do
- let(:job) { create(:ci_build, :success, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline) }
before do
visit project_job_path(project, job)
@@ -136,7 +136,7 @@ feature 'Jobs' do
end
context 'when job is not running', :js do
- let(:job) { create(:ci_build, :success, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, :trace_artifact, pipeline: pipeline) }
before do
visit project_job_path(project, job)
@@ -153,7 +153,7 @@ feature 'Jobs' do
end
context 'if job failed' do
- let(:job) { create(:ci_build, :failed, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :failed, :trace_artifact, pipeline: pipeline) }
before do
visit project_job_path(project, job)
@@ -339,7 +339,7 @@ feature 'Jobs' do
context 'job is successfull and has deployment' do
let(:deployment) { create(:deployment) }
- let(:job) { create(:ci_build, :success, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
it 'shows a link for the job' do
visit project_job_path(project, job)
@@ -349,7 +349,7 @@ feature 'Jobs' do
end
context 'job is complete and not successful' do
- let(:job) { create(:ci_build, :failed, environment: environment.name, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) }
it 'shows a link for the job' do
visit project_job_path(project, job)
@@ -360,7 +360,7 @@ feature 'Jobs' do
context 'job creates a new deployment' do
let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) }
- let(:job) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, pipeline: pipeline) }
it 'shows a link to latest deployment' do
visit project_job_path(project, job)
@@ -379,6 +379,7 @@ feature 'Jobs' do
end
it 'shows manual action empty state' do
+ expect(page).to have_content(job.detailed_status(user).illustration[:title])
expect(page).to have_content('This job requires a manual action')
expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments')
expect(page).to have_link('Trigger this manual action')
@@ -402,6 +403,7 @@ feature 'Jobs' do
end
it 'shows empty state' do
+ expect(page).to have_content(job.detailed_status(user).illustration[:title])
expect(page).to have_content('This job has not been triggered yet')
expect(page).to have_content('This job depends on upstream jobs that need to succeed in order for this job to be triggered')
end
@@ -415,10 +417,53 @@ feature 'Jobs' do
end
it 'shows pending empty state' do
+ expect(page).to have_content(job.detailed_status(user).illustration[:title])
expect(page).to have_content('This job has not started yet')
expect(page).to have_content('This job is in pending state and is waiting to be picked by a runner')
end
end
+
+ context 'Canceled job' do
+ context 'with log' do
+ let(:job) { create(:ci_build, :canceled, :trace_artifact, pipeline: pipeline) }
+
+ before do
+ visit project_job_path(project, job)
+ end
+
+ it 'renders job log' do
+ expect(page).to have_selector('.js-build-output')
+ end
+ end
+
+ context 'without log' do
+ let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
+
+ before do
+ visit project_job_path(project, job)
+ end
+
+ it 'renders empty state' do
+ expect(page).to have_content(job.detailed_status(user).illustration[:title])
+ expect(page).not_to have_selector('.js-build-output')
+ expect(page).to have_content('This job has been canceled')
+ end
+ end
+ end
+
+ context 'Skipped job' do
+ let(:job) { create(:ci_build, :skipped, pipeline: pipeline) }
+
+ before do
+ visit project_job_path(project, job)
+ end
+
+ it 'renders empty state' do
+ expect(page).to have_content(job.detailed_status(user).illustration[:title])
+ expect(page).not_to have_selector('.js-build-output')
+ expect(page).to have_content('This job has been skipped')
+ end
+ end
end
describe "POST /:project/jobs/:id/cancel", :js do
diff --git a/spec/features/projects/labels/user_creates_labels_spec.rb b/spec/features/projects/labels/user_creates_labels_spec.rb
new file mode 100644
index 00000000000..9fd7f3ee775
--- /dev/null
+++ b/spec/features/projects/labels/user_creates_labels_spec.rb
@@ -0,0 +1,88 @@
+require "spec_helper"
+
+describe "User creates labels" do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+
+ shared_examples_for "label creation" do
+ it "creates new label" do
+ title = "bug"
+
+ create_label(title)
+
+ page.within(".other-labels .manage-labels-list") do
+ expect(page).to have_content(title)
+ end
+ end
+ end
+
+ context "in project" do
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ visit(new_project_label_path(project))
+ end
+
+ context "when data is valid" do
+ include_examples "label creation"
+ end
+
+ context "when data is invalid" do
+ context "when title is invalid" do
+ it "shows error message" do
+ create_label("")
+
+ page.within(".label-form") do
+ expect(page).to have_content("Title can't be blank")
+ end
+ end
+ end
+
+ context "when color is invalid" do
+ it "shows error message" do
+ create_label("feature", "#12")
+
+ page.within(".label-form") do
+ expect(page).to have_content("Color must be a valid color code")
+ end
+ end
+ end
+ end
+
+ context "when label already exists" do
+ let!(:label) { create(:label, project: project) }
+
+ it "shows error message" do
+ create_label(label.title)
+
+ page.within(".label-form") do
+ expect(page).to have_content("Title has already been taken")
+ end
+ end
+ end
+ end
+
+ context "in another project" do
+ set(:another_project) { create(:project_empty_repo, :public) }
+
+ before do
+ create(:label, project: project, title: "bug") # Create label for `project` (not `another_project`) project.
+
+ another_project.add_master(user)
+ sign_in(user)
+
+ visit(new_project_label_path(another_project))
+ end
+
+ include_examples "label creation"
+ end
+
+ private
+
+ def create_label(title, color = "#F95610")
+ fill_in("Title", with: title)
+ fill_in("Background color", with: color)
+ click_button("Create label")
+ end
+end
diff --git a/spec/features/projects/labels/user_edits_labels_spec.rb b/spec/features/projects/labels/user_edits_labels_spec.rb
new file mode 100644
index 00000000000..d1041ff5c1e
--- /dev/null
+++ b/spec/features/projects/labels/user_edits_labels_spec.rb
@@ -0,0 +1,25 @@
+require "spec_helper"
+
+describe "User edits labels" do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:label) { create(:label, project: project) }
+ set(:user) { create(:user) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ visit(edit_project_label_path(project, label))
+ end
+
+ it "updates label's title" do
+ new_title = "fix"
+
+ fill_in("Title", with: new_title)
+ click_button("Save changes")
+
+ page.within(".other-labels .manage-labels-list") do
+ expect(page).to have_content(new_title).and have_no_content(label.title)
+ end
+ end
+end
diff --git a/spec/features/projects/labels/user_removes_labels_spec.rb b/spec/features/projects/labels/user_removes_labels_spec.rb
new file mode 100644
index 00000000000..f4fda6de465
--- /dev/null
+++ b/spec/features/projects/labels/user_removes_labels_spec.rb
@@ -0,0 +1,52 @@
+require "spec_helper"
+
+describe "User removes labels" do
+ let(:project) { create(:project_empty_repo, :public) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+ end
+
+ context "when one label" do
+ let!(:label) { create(:label, project: project) }
+
+ before do
+ visit(project_labels_path(project))
+ end
+
+ it "removes label" do
+ page.within(".labels") do
+ page.first(".label-list-item") do
+ first(".remove-row").click
+ first(:link, "Delete label").click
+ end
+ end
+
+ expect(page).to have_content("Label was removed").and have_no_content(label.title)
+ end
+ end
+
+ context "when many labels", :js do
+ before do
+ create_list(:label, 3, project: project)
+
+ visit(project_labels_path(project))
+ end
+
+ it "removes all labels" do
+ page.within(".labels") do
+ loop do
+ li = page.first(".label-list-item")
+ break unless li
+
+ li.click_link("Delete")
+ click_link("Delete label")
+ end
+
+ expect(page).to have_content("Generate a default set of labels").and have_content("New label")
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/labels/user_views_labels_spec.rb b/spec/features/projects/labels/user_views_labels_spec.rb
new file mode 100644
index 00000000000..0cbeca4e392
--- /dev/null
+++ b/spec/features/projects/labels/user_views_labels_spec.rb
@@ -0,0 +1,23 @@
+require "spec_helper"
+
+describe "User views labels" do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+
+ LABEL_TITLES = %w[bug enhancement feature].freeze
+
+ before do
+ LABEL_TITLES.each { |title| create(:label, project: project, title: title) }
+
+ project.add_guest(user)
+ sign_in(user)
+
+ visit(project_labels_path(project))
+ end
+
+ it "shows all labels" do
+ page.within('.other-labels .manage-labels-list') do
+ LABEL_TITLES.each { |title| expect(page).to have_content(title) }
+ end
+ end
+end
diff --git a/spec/features/projects/milestones/milestones_sorting_spec.rb b/spec/features/projects/milestones/milestones_sorting_spec.rb
index c531b81e04d..b64786d4eec 100644
--- a/spec/features/projects/milestones/milestones_sorting_spec.rb
+++ b/spec/features/projects/milestones/milestones_sorting_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'
feature 'Milestones sorting', :js do
- include SortingHelper
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 266ef693d0b..990e5c4d9df 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -115,6 +115,13 @@ describe 'Pipeline', :js do
expect(page).not_to have_content('Retry job')
end
+
+ it 'should include the failure reason' do
+ page.within('#ci-badge-test') do
+ build_link = page.find('.js-pipeline-graph-job-link')
+ expect(build_link['data-original-title']).to eq('test - failed <br> (unknown failure)')
+ end
+ end
end
context 'when pipeline has manual jobs' do
@@ -289,6 +296,15 @@ describe 'Pipeline', :js do
it { expect(build_manual.reload).to be_pending }
end
+
+ context 'failed jobs' do
+ it 'displays a tooltip with the failure reason' do
+ page.within('.ci-table') do
+ failed_job_link = page.find('.ci-failed')
+ expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)')
+ end
+ end
+ end
end
describe 'GET /:project/pipelines/:id/failures' do
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 0e81c6c629a..6e63e0f0b49 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -394,6 +394,23 @@ describe 'Pipelines', :js do
expect(build.reload).to be_canceled
end
end
+
+ context 'for a failed pipeline' do
+ let!(:build) do
+ create(:ci_build, :failed, pipeline: pipeline,
+ stage: 'build',
+ name: 'build')
+ end
+
+ it 'should display the failure reason' do
+ find('.js-builds-dropdown-button').click
+
+ within('.js-builds-dropdown-list') do
+ build_element = page.find('.mini-pipeline-graph-dropdown-item')
+ expect(build_element['data-title']).to eq('build - failed <br> (unknown failure)')
+ end
+ end
+ end
end
context 'with pagination' do
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
deleted file mode 100644
index a3ea778d401..00000000000
--- a/spec/features/projects/project_settings_spec.rb
+++ /dev/null
@@ -1,205 +0,0 @@
-require 'spec_helper'
-
-describe 'Edit Project Settings' do
- include Select2Helper
-
- let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
-
- before do
- sign_in(user)
- end
-
- describe 'Project settings section', :js do
- it 'shows errors for invalid project name' do
- visit edit_project_path(project)
- fill_in 'project_name_edit', with: 'foo&bar'
- page.within('.general-settings') do
- click_button 'Save changes'
- end
- expect(page).to have_field 'project_name_edit', with: 'foo&bar'
- expect(page).to have_content "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'."
- expect(page).to have_button 'Save changes'
- end
-
- it 'shows a successful notice when the project is updated' do
- visit edit_project_path(project)
- fill_in 'project_name_edit', with: 'hello world'
- page.within('.general-settings') do
- click_button 'Save changes'
- end
- expect(page).to have_content "Project 'hello world' was successfully updated."
- end
- end
-
- describe 'Merge request settings section' do
- it 'shows "Merge commit" strategy' do
- visit edit_project_path(project)
-
- page.within '.merge-requests-feature' do
- expect(page).to have_content 'Merge commit'
- end
- end
-
- it 'shows "Merge commit with semi-linear history " strategy' do
- visit edit_project_path(project)
-
- page.within '.merge-requests-feature' do
- expect(page).to have_content 'Merge commit with semi-linear history'
- end
- end
-
- it 'shows "Fast-forward merge" strategy' do
- visit edit_project_path(project)
-
- page.within '.merge-requests-feature' do
- expect(page).to have_content 'Fast-forward merge'
- end
- end
- end
-
- describe 'Rename repository section' do
- context 'with invalid characters' do
- it 'shows errors for invalid project path/name' do
- rename_project(project, name: 'foo&bar', path: 'foo&bar')
- expect(page).to have_field 'Project name', with: 'foo&bar'
- expect(page).to have_field 'Path', with: 'foo&bar'
- expect(page).to have_content "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'."
- expect(page).to have_content "Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'"
- end
- end
-
- context 'when changing project name' do
- it 'renames the repository' do
- rename_project(project, name: 'bar')
- expect(find('.breadcrumbs')).to have_content(project.name)
- end
-
- context 'with emojis' do
- it 'shows error for invalid project name' do
- rename_project(project, name: '🚀 foo bar ☁️')
- expect(page).to have_field 'Project name', with: '🚀 foo bar ☁️'
- expect(page).not_to have_content "Name can contain only letters, digits, emojis '_', '.', dash and space. It must start with letter, digit, emoji or '_'."
- end
- end
- end
-
- context 'when changing project path' do
- let(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') }
-
- before(:context) do
- TestEnv.clean_test_path
- end
-
- after do
- TestEnv.clean_test_path
- end
-
- specify 'the project is accessible via the new path' do
- rename_project(project, path: 'bar')
- new_path = namespace_project_path(project.namespace, 'bar')
- visit new_path
- expect(current_path).to eq(new_path)
- expect(find('.breadcrumbs')).to have_content(project.name)
- end
-
- specify 'the project is accessible via a redirect from the old path' do
- old_path = project_path(project)
- rename_project(project, path: 'bar')
- new_path = namespace_project_path(project.namespace, 'bar')
- visit old_path
- expect(current_path).to eq(new_path)
- expect(find('.breadcrumbs')).to have_content(project.name)
- end
-
- context 'and a new project is added with the same path' do
- it 'overrides the redirect' do
- old_path = project_path(project)
- rename_project(project, path: 'bar')
- new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
- visit old_path
- expect(current_path).to eq(old_path)
- expect(find('.breadcrumbs')).to have_content(new_project.name)
- end
- end
- end
- end
-
- describe 'Transfer project section', :js do
- let!(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') }
- let!(:group) { create(:group) }
-
- before(:context) do
- TestEnv.clean_test_path
- end
-
- before do
- group.add_owner(user)
- end
-
- after do
- TestEnv.clean_test_path
- end
-
- specify 'the project is accessible via the new path' do
- transfer_project(project, group)
- new_path = namespace_project_path(group, project)
-
- visit new_path
- wait_for_requests
-
- expect(current_path).to eq(new_path)
- expect(find('.breadcrumbs')).to have_content(project.name)
- end
-
- specify 'the project is accessible via a redirect from the old path' do
- old_path = project_path(project)
- transfer_project(project, group)
- new_path = namespace_project_path(group, project)
-
- visit old_path
- wait_for_requests
-
- expect(current_path).to eq(new_path)
- expect(find('.breadcrumbs')).to have_content(project.name)
- end
-
- context 'and a new project is added with the same path' do
- it 'overrides the redirect' do
- old_path = project_path(project)
- transfer_project(project, group)
- new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
- visit old_path
- expect(current_path).to eq(old_path)
- expect(find('.breadcrumbs')).to have_content(new_project.name)
- end
- end
- end
-end
-
-def rename_project(project, name: nil, path: nil)
- visit edit_project_path(project)
- fill_in('project_name', with: name) if name
- fill_in('Path', with: path) if path
- click_button('Rename project')
- wait_for_edit_project_page_reload
- project.reload
-end
-
-def transfer_project(project, namespace)
- visit edit_project_path(project)
- select2(namespace.id, from: '#new_namespace_id')
- click_button('Transfer project')
- confirm_transfer_modal
- wait_for_edit_project_page_reload
- project.reload
-end
-
-def confirm_transfer_modal
- fill_in('confirm_name_input', with: project.path)
- click_button 'Confirm'
-end
-
-def wait_for_edit_project_page_reload
- expect(find('.project-edit-container')).to have_content('Rename repository')
-end
diff --git a/spec/features/projects/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb
index 28954a4fb40..a4d1b78b83b 100644
--- a/spec/features/projects/settings/forked_project_settings_spec.rb
+++ b/spec/features/projects/settings/forked_project_settings_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Settings for a forked project', :js do
+describe 'Projects > Settings > For a forked project', :js do
include ProjectForksHelper
let(:user) { create(:user) }
let(:original_project) { create(:project) }
diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb
index f6a1a46df11..5178d63050e 100644
--- a/spec/features/projects/settings/integration_settings_spec.rb
+++ b/spec/features/projects/settings/integration_settings_spec.rb
@@ -1,20 +1,20 @@
require 'spec_helper'
-feature 'Integration settings' do
+describe 'Projects > Settings > Integration settings' do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
let(:integrations_path) { project_settings_integrations_path(project) }
- background do
+ before do
sign_in(user)
project.add_role(user, role)
end
context 'for developer' do
- given(:role) { :developer }
+ let(:role) { :developer }
- scenario 'to be disallowed to view' do
+ it 'to be disallowed to view' do
visit integrations_path
expect(page.status_code).to eq(404)
@@ -22,13 +22,13 @@ feature 'Integration settings' do
end
context 'for master' do
- given(:role) { :master }
+ let(:role) { :master }
context 'Webhooks' do
let(:hook) { create(:project_hook, :all_events_enabled, enable_ssl_verification: true, project: project) }
let(:url) { generate(:url) }
- scenario 'show list of webhooks' do
+ it 'show list of webhooks' do
hook
visit integrations_path
@@ -46,7 +46,7 @@ feature 'Integration settings' do
expect(page).to have_content('Wiki page events')
end
- scenario 'create webhook' do
+ it 'create webhook' do
visit integrations_path
fill_in 'hook_url', with: url
@@ -63,7 +63,7 @@ feature 'Integration settings' do
expect(page).to have_content('Job events')
end
- scenario 'edit existing webhook' do
+ it 'edit existing webhook' do
hook
visit integrations_path
@@ -76,7 +76,7 @@ feature 'Integration settings' do
expect(page).to have_content(url)
end
- scenario 'test existing webhook', :js do
+ it 'test existing webhook', :js do
WebMock.stub_request(:post, hook.url)
visit integrations_path
@@ -87,14 +87,14 @@ feature 'Integration settings' do
end
context 'remove existing webhook' do
- scenario 'from webhooks list page' do
+ it 'from webhooks list page' do
hook
visit integrations_path
expect { click_link 'Remove' }.to change(ProjectHook, :count).by(-1)
end
- scenario 'from webhook edit page' do
+ it 'from webhook edit page' do
hook
visit integrations_path
click_link 'Edit'
@@ -108,7 +108,7 @@ feature 'Integration settings' do
let(:hook) { create(:project_hook, project: project) }
let(:hook_log) { create(:web_hook_log, web_hook: hook, internal_error_message: 'some error') }
- scenario 'show list of hook logs' do
+ it 'show list of hook logs' do
hook_log
visit edit_project_hook_path(project, hook)
@@ -116,7 +116,7 @@ feature 'Integration settings' do
expect(page).to have_content(hook_log.url)
end
- scenario 'show hook log details' do
+ it 'show hook log details' do
hook_log
visit edit_project_hook_path(project, hook)
click_link 'View details'
@@ -126,7 +126,7 @@ feature 'Integration settings' do
expect(page).to have_content('Resend Request')
end
- scenario 'retry hook log' do
+ it 'retry hook log' do
WebMock.stub_request(:post, hook.url)
hook_log
diff --git a/spec/features/projects/settings/lfs_settings_spec.rb b/spec/features/projects/settings/lfs_settings_spec.rb
new file mode 100644
index 00000000000..0fd28a5681c
--- /dev/null
+++ b/spec/features/projects/settings/lfs_settings_spec.rb
@@ -0,0 +1,21 @@
+require 'rails_helper'
+
+describe 'Projects > Settings > LFS settings' do
+ let(:admin) { create(:admin) }
+ let(:project) { create(:project) }
+
+ context 'LFS enabled setting' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+
+ sign_in(admin)
+ end
+
+ it 'displays the correct elements', :js do
+ visit edit_project_path(project)
+
+ expect(page).to have_content('Git Large File Storage')
+ expect(page).to have_selector('input[name="project[lfs_enabled]"] + button', visible: true)
+ end
+ end
+end
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index d0720855564..d9020333f28 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -1,19 +1,19 @@
require 'spec_helper'
-feature "Pipelines settings" do
+describe "Projects > Settings > Pipelines settings" do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
- background do
+ before do
sign_in(user)
project.add_role(user, role)
end
context 'for developer' do
- given(:role) { :developer }
+ let(:role) { :developer }
- scenario 'to be disallowed to view' do
+ it 'to be disallowed to view' do
visit project_settings_ci_cd_path(project)
expect(page.status_code).to eq(404)
@@ -21,9 +21,9 @@ feature "Pipelines settings" do
end
context 'for master' do
- given(:role) { :master }
+ let(:role) { :master }
- scenario 'be allowed to change' do
+ it 'be allowed to change' do
visit project_settings_ci_cd_path(project)
fill_in('Test coverage parsing', with: 'coverage_regex')
@@ -34,7 +34,7 @@ feature "Pipelines settings" do
expect(page).to have_field('Test coverage parsing', with: 'coverage_regex')
end
- scenario 'updates auto_cancel_pending_pipelines' do
+ it 'updates auto_cancel_pending_pipelines' do
visit project_settings_ci_cd_path(project)
page.check('Auto-cancel redundant, pending pipelines')
diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb
new file mode 100644
index 00000000000..cc3551a4c21
--- /dev/null
+++ b/spec/features/projects/settings/project_badges_spec.rb
@@ -0,0 +1,125 @@
+require 'spec_helper'
+
+feature 'Project Badges' do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, namespace: group) }
+ let(:badge_link_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/commits/master'}
+ let(:badge_image_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/badges/master/build.svg'}
+ let!(:project_badge) { create(:project_badge, project: project) }
+ let!(:group_badge) { create(:group_badge, group: group) }
+
+ before do
+ group.add_master(user)
+ sign_in(user)
+
+ visit(project_settings_badges_path(project))
+ end
+
+ it 'shows a list of badges', :js do
+ page.within '.badge-settings' do
+ wait_for_requests
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ expect(rows[0]).to have_content group_badge.link_url
+ expect(rows[1]).to have_content project_badge.link_url
+ end
+ end
+
+ context 'adding a badge', :js do
+ it 'user can preview a badge' do
+ page.within '.badge-settings form' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+ within '#badge-preview' do
+ expect(find('a')[:href]).to eq badge_link_url
+ expect(find('a img')[:src]).to eq badge_image_url
+ end
+ end
+ end
+
+ it do
+ page.within '.badge-settings' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+
+ click_button 'Add badge'
+ wait_for_requests
+
+ within '.panel-body' do
+ expect(find('a')[:href]).to eq badge_link_url
+ expect(find('a img')[:src]).to eq badge_image_url
+ end
+ end
+ end
+ end
+
+ context 'editing a badge', :js do
+ it 'form is shown when clicking edit button in list' do
+ page.within '.badge-settings' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ rows[1].find('[aria-label="Edit"]').click
+
+ within 'form' do
+ expect(find('#badge-link-url').value).to eq project_badge.link_url
+ expect(find('#badge-image-url').value).to eq project_badge.image_url
+ end
+ end
+ end
+
+ it 'updates a badge when submitting the edit form' do
+ page.within '.badge-settings' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ rows[1].find('[aria-label="Edit"]').click
+ within 'form' do
+ fill_in 'badge-link-url', with: badge_link_url
+ fill_in 'badge-image-url', with: badge_image_url
+
+ click_button 'Save changes'
+ wait_for_requests
+ end
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ expect(rows[1]).to have_content badge_link_url
+ end
+ end
+ end
+
+ context 'deleting a badge', :js do
+ def click_delete_button(badge_row)
+ badge_row.find('[aria-label="Delete"]').click
+ end
+
+ it 'shows a modal when deleting a badge' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+
+ click_delete_button(rows[1])
+
+ expect(find('.modal .modal-title')).to have_content 'Delete badge?'
+ end
+
+ it 'deletes a badge when confirming the modal' do
+ wait_for_requests
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 2
+ click_delete_button(rows[1])
+
+ find('.modal .btn-danger').click
+ wait_for_requests
+
+ rows = all('.panel-body > div')
+ expect(rows.length).to eq 1
+ expect(rows[0]).to have_content group_badge.link_url
+ end
+ end
+end
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index 14670e91006..e1dfe617691 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -1,19 +1,19 @@
require 'spec_helper'
-feature 'Repository settings' do
+describe 'Projects > Settings > Repository settings' do
let(:project) { create(:project_empty_repo) }
let(:user) { create(:user) }
let(:role) { :developer }
- background do
+ before do
project.add_role(user, role)
sign_in(user)
end
context 'for developer' do
- given(:role) { :developer }
+ let(:role) { :developer }
- scenario 'is not allowed to view' do
+ it 'is not allowed to view' do
visit project_settings_repository_path(project)
expect(page.status_code).to eq(404)
@@ -21,14 +21,14 @@ feature 'Repository settings' do
end
context 'for master' do
- given(:role) { :master }
+ let(:role) { :master }
context 'Deploy Keys', :js do
let(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
let(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
let(:new_ssh_key) { attributes_for(:key)[:key] }
- scenario 'get list of keys' do
+ it 'get list of keys' do
project.deploy_keys << private_deploy_key
project.deploy_keys << public_deploy_key
@@ -38,7 +38,7 @@ feature 'Repository settings' do
expect(page).to have_content('public_deploy_key')
end
- scenario 'add a new deploy key' do
+ it 'add a new deploy key' do
visit project_settings_repository_path(project)
fill_in 'deploy_key_title', with: 'new_deploy_key'
@@ -50,7 +50,7 @@ feature 'Repository settings' do
expect(page).to have_content('Write access allowed')
end
- scenario 'edit an existing deploy key' do
+ it 'edit an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_repository_path(project)
@@ -64,7 +64,7 @@ feature 'Repository settings' do
expect(page).to have_content('Write access allowed')
end
- scenario 'edit a deploy key from projects user has access to' do
+ it 'edit a deploy key from projects user has access to' do
project2 = create(:project_empty_repo)
project2.add_role(user, role)
project2.deploy_keys << private_deploy_key
@@ -79,7 +79,7 @@ feature 'Repository settings' do
expect(page).to have_content('updated_deploy_key')
end
- scenario 'remove an existing deploy key' do
+ it 'remove an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_repository_path(project)
@@ -88,5 +88,32 @@ feature 'Repository settings' do
expect(page).not_to have_content(private_deploy_key.title)
end
end
+
+ context 'Deploy tokens' do
+ let!(:deploy_token) { create(:deploy_token, projects: [project]) }
+
+ before do
+ stub_container_registry_config(enabled: true)
+ visit project_settings_repository_path(project)
+ end
+
+ scenario 'view deploy tokens' do
+ within('.deploy-tokens') do
+ expect(page).to have_content(deploy_token.name)
+ expect(page).to have_content('read_repository')
+ expect(page).to have_content('read_registry')
+ end
+ end
+
+ scenario 'add a new deploy token' do
+ fill_in 'deploy_token_name', with: 'new_deploy_key'
+ fill_in 'deploy_token_expires_at', with: (Date.today + 1.month).to_s
+ check 'deploy_token_read_repository'
+ check 'deploy_token_read_registry'
+ click_button 'Create deploy token'
+
+ expect(page).to have_content('Your new project deploy token has been created')
+ end
+ end
end
end
diff --git a/spec/features/projects/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb
index 72063d13c2a..38c8a8c2468 100644
--- a/spec/features/projects/user_archives_project_spec.rb
+++ b/spec/features/projects/settings/user_archives_project_spec.rb
@@ -1,21 +1,19 @@
require 'spec_helper'
-describe 'User archives a project' do
+describe 'Projects > Settings > User archives a project' do
let(:user) { create(:user) }
before do
project.add_master(user)
sign_in(user)
+
+ visit edit_project_path(project)
end
context 'when a project is archived' do
let(:project) { create(:project, :archived, namespace: user.namespace) }
- before do
- visit(edit_project_path(project))
- end
-
it 'unarchives a project' do
expect(page).to have_content('Unarchive project')
@@ -28,10 +26,6 @@ describe 'User archives a project' do
context 'when a project is unarchived' do
let(:project) { create(:project, :repository, namespace: user.namespace) }
- before do
- visit(edit_project_path(project))
- end
-
it 'archives a project' do
expect(page).to have_content('Archive project')
diff --git a/spec/features/projects/settings/user_changes_avatar_spec.rb b/spec/features/projects/settings/user_changes_avatar_spec.rb
new file mode 100644
index 00000000000..2dcc79d8a12
--- /dev/null
+++ b/spec/features/projects/settings/user_changes_avatar_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe 'Projects > Settings > User changes avatar' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.creator }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+ end
+
+ it 'saves the new avatar' do
+ expect(project.reload.avatar.url).to be_nil
+
+ save_avatar(project)
+
+ expect(project.reload.avatar.url).to eq "/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif"
+ end
+
+ context 'with an avatar already set' do
+ before do
+ save_avatar(project)
+ end
+
+ it 'is possible to remove the avatar' do
+ click_link 'Remove avatar'
+
+ expect(page).not_to have_link('Remove avatar')
+
+ expect(project.reload.avatar.url).to be_nil
+ end
+ end
+
+ def save_avatar(project)
+ visit edit_project_path(project)
+ attach_file(
+ :project_avatar,
+ File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')
+ )
+ page.within '.general-settings' do
+ click_button 'Save changes'
+ end
+ end
+end
diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb
new file mode 100644
index 00000000000..e925539351d
--- /dev/null
+++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe 'Projects > Settings > User changes default branch' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
+
+ before do
+ sign_in(user)
+ visit edit_project_path(project)
+ end
+
+ it 'allows to change the default branch' do
+ select 'fix', from: 'project_default_branch'
+ page.within '.general-settings' do
+ click_button 'Save changes'
+ end
+
+ expect(find(:css, 'select#project_default_branch').value).to eq 'fix'
+ end
+end
diff --git a/spec/features/projects/settings/user_manages_group_links_spec.rb b/spec/features/projects/settings/user_manages_group_links_spec.rb
index 91e8059865c..fdf42797091 100644
--- a/spec/features/projects/settings/user_manages_group_links_spec.rb
+++ b/spec/features/projects/settings/user_manages_group_links_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User manages group links' do
+describe 'Projects > Settings > User manages group links' do
include Select2Helper
let(:user) { create(:user) }
diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index 015db603d33..b6e65fcbda1 100644
--- a/spec/features/projects/settings/merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -1,21 +1,35 @@
require 'spec_helper'
-feature 'Project settings > Merge Requests', :js do
- let(:project) { create(:project, :public) }
+describe 'Projects > Settings > User manages merge request settings' do
let(:user) { create(:user) }
+ let(:project) { create(:project, :public, namespace: user.namespace, path: 'gitlab', name: 'sample') }
- background do
- project.add_master(user)
+ before do
sign_in(user)
+ visit edit_project_path(project)
end
- context 'when Merge Request and Pipelines are initially enabled' do
- context 'when Pipelines are initially enabled' do
- before do
- visit edit_project_path(project)
- end
+ it 'shows "Merge commit" strategy' do
+ page.within '.merge-requests-feature' do
+ expect(page).to have_content 'Merge commit'
+ end
+ end
+
+ it 'shows "Merge commit with semi-linear history " strategy' do
+ page.within '.merge-requests-feature' do
+ expect(page).to have_content 'Merge commit with semi-linear history'
+ end
+ end
- scenario 'shows the Merge Requests settings' do
+ it 'shows "Fast-forward merge" strategy' do
+ page.within '.merge-requests-feature' do
+ expect(page).to have_content 'Fast-forward merge'
+ end
+ end
+
+ context 'when Merge Request and Pipelines are initially enabled', :js do
+ context 'when Pipelines are initially enabled' do
+ it 'shows the Merge Requests settings' do
expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -29,13 +43,13 @@ feature 'Project settings > Merge Requests', :js do
end
end
- context 'when Pipelines are initially disabled' do
+ context 'when Pipelines are initially disabled', :js do
before do
project.project_feature.update_attribute('builds_access_level', ProjectFeature::DISABLED)
visit edit_project_path(project)
end
- scenario 'shows the Merge Requests settings that do not depend on Builds feature' do
+ it 'shows the Merge Requests settings that do not depend on Builds feature' do
expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -50,13 +64,13 @@ feature 'Project settings > Merge Requests', :js do
end
end
- context 'when Merge Request are initially disabled' do
+ context 'when Merge Request are initially disabled', :js do
before do
project.project_feature.update_attribute('merge_requests_access_level', ProjectFeature::DISABLED)
visit edit_project_path(project)
end
- scenario 'does not show the Merge Requests settings' do
+ it 'does not show the Merge Requests settings' do
expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -70,17 +84,13 @@ feature 'Project settings > Merge Requests', :js do
end
end
- describe 'Checkbox to enable merge request link' do
- before do
- visit edit_project_path(project)
- end
-
- scenario 'is initially checked' do
+ describe 'Checkbox to enable merge request link', :js do
+ it 'is initially checked' do
checkbox = find_field('project_printing_merge_request_link_enabled')
expect(checkbox).to be_checked
end
- scenario 'when unchecked sets :printing_merge_request_link_enabled to false' do
+ it 'when unchecked sets :printing_merge_request_link_enabled to false' do
uncheck('project_printing_merge_request_link_enabled')
within('.merge-request-settings-form') do
click_on('Save changes')
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index 0a4f57bcd21..8af95522165 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User manages project members' do
+describe 'Projects > Settings > User manages project members' do
let(:group) { create(:group, name: 'OpenSource') }
let(:project) { create(:project) }
let(:project2) { create(:project) }
diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb
new file mode 100644
index 00000000000..64c9af4b706
--- /dev/null
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -0,0 +1,100 @@
+require 'spec_helper'
+
+describe 'Projects > Settings > User renames a project' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
+
+ before do
+ sign_in(user)
+ visit edit_project_path(project)
+ end
+
+ def rename_project(project, name: nil, path: nil)
+ fill_in('project_name', with: name) if name
+ fill_in('Path', with: path) if path
+ click_button('Rename project')
+ wait_for_edit_project_page_reload
+ project.reload
+ end
+
+ def wait_for_edit_project_page_reload
+ expect(find('.project-edit-container')).to have_content('Rename repository')
+ end
+
+ context 'with invalid characters' do
+ it 'shows errors for invalid project path/name' do
+ rename_project(project, name: 'foo&bar', path: 'foo&bar')
+ expect(page).to have_field 'Project name', with: 'foo&bar'
+ expect(page).to have_field 'Path', with: 'foo&bar'
+ expect(page).to have_content "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'."
+ expect(page).to have_content "Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'"
+ end
+ end
+
+ it 'shows a successful notice when the project is updated' do
+ fill_in 'project_name_edit', with: 'hello world'
+ page.within('.general-settings') do
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Project 'hello world' was successfully updated."
+ end
+
+ context 'when changing project name' do
+ it 'renames the repository' do
+ rename_project(project, name: 'bar')
+ expect(find('.breadcrumbs')).to have_content(project.name)
+ end
+
+ context 'with emojis' do
+ it 'shows error for invalid project name' do
+ rename_project(project, name: '🚀 foo bar ☁️')
+ expect(page).to have_field 'Project name', with: '🚀 foo bar ☁️'
+ expect(page).not_to have_content "Name can contain only letters, digits, emojis '_', '.', dash and space. It must start with letter, digit, emoji or '_'."
+ end
+ end
+ end
+
+ context 'when changing project path' do
+ let(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') }
+
+ before(:context) do
+ TestEnv.clean_test_path
+ end
+
+ after do
+ TestEnv.clean_test_path
+ end
+
+ it 'the project is accessible via the new path' do
+ rename_project(project, path: 'bar')
+ new_path = namespace_project_path(project.namespace, 'bar')
+ visit new_path
+
+ expect(current_path).to eq(new_path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
+ end
+
+ it 'the project is accessible via a redirect from the old path' do
+ old_path = project_path(project)
+ rename_project(project, path: 'bar')
+ new_path = namespace_project_path(project.namespace, 'bar')
+ visit old_path
+
+ expect(current_path).to eq(new_path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
+ end
+
+ context 'and a new project is added with the same path' do
+ it 'overrides the redirect' do
+ old_path = project_path(project)
+ rename_project(project, path: 'bar')
+ new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
+ visit old_path
+
+ expect(current_path).to eq(old_path)
+ expect(find('.breadcrumbs')).to have_content(new_project.name)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb
new file mode 100644
index 00000000000..57b4b1287fa
--- /dev/null
+++ b/spec/features/projects/settings/user_tags_project_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe 'Projects > Settings > User tags a project' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ before do
+ sign_in(user)
+ visit edit_project_path(project)
+ end
+
+ context 'when a project is archived' do
+ it 'unarchives a project' do
+ fill_in 'Tags', with: 'tag1, tag2'
+
+ page.within '.general-settings' do
+ click_button 'Save changes'
+ end
+
+ expect(find_field('Tags').value).to eq 'tag1, tag2'
+ end
+ end
+end
diff --git a/spec/features/projects/settings/user_transfers_a_project_spec.rb b/spec/features/projects/settings/user_transfers_a_project_spec.rb
new file mode 100644
index 00000000000..96b7cf1f93b
--- /dev/null
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+describe 'Projects > Settings > User transfers a project', :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
+ let(:group) { create(:group) }
+
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ def transfer_project(project, group)
+ visit edit_project_path(project)
+
+ page.within('.js-project-transfer-form') do
+ page.find('.select2-container').click
+ end
+
+ page.find("div[role='option']", text: group.full_name).click
+
+ click_button('Transfer project')
+
+ fill_in 'confirm_name_input', with: project.name
+
+ click_button 'Confirm'
+
+ wait_for_requests
+ end
+
+ it 'allows transferring a project to a group' do
+ old_path = project_path(project)
+ transfer_project(project, group)
+ new_path = namespace_project_path(group, project)
+
+ expect(project.reload.namespace).to eq(group)
+
+ visit new_path
+ wait_for_requests
+
+ expect(current_path).to eq(new_path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
+
+ visit old_path
+ wait_for_requests
+
+ expect(current_path).to eq(new_path)
+ expect(find('.breadcrumbs')).to have_content(project.name)
+ end
+
+ context 'and a new project is added with the same path' do
+ it 'overrides the redirect' do
+ old_path = project_path(project)
+ project_path = project.path
+ transfer_project(project, group)
+ new_project = create(:project, namespace: user.namespace, path: project_path)
+ visit old_path
+
+ expect(current_path).to eq(old_path)
+ expect(find('.breadcrumbs')).to have_content(new_project.name)
+ end
+ end
+
+ context 'when nested groups are available', :nested_groups do
+ it 'allows transferring a project to a subgroup' do
+ subgroup = create(:group, parent: group)
+
+ transfer_project(project, subgroup)
+
+ expect(project.reload.namespace).to eq(subgroup)
+ end
+ end
+end
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index 06f6702670b..2ec6990313f 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Visibility settings', :js do
+describe 'Projects > Settings > Visibility settings', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) }
@@ -10,14 +10,14 @@ feature 'Visibility settings', :js do
visit edit_project_path(project)
end
- scenario 'project visibility select is available' do
+ it 'project visibility select is available' do
visibility_select_container = find('.project-visibility-setting')
expect(visibility_select_container.find('select').value).to eq project.visibility_level.to_s
expect(visibility_select_container).to have_content 'The project can be accessed by anyone, regardless of authentication.'
end
- scenario 'project visibility description updates on change' do
+ it 'project visibility description updates on change' do
visibility_select_container = find('.project-visibility-setting')
visibility_select = visibility_select_container.find('select')
visibility_select.select('Private')
@@ -25,6 +25,38 @@ feature 'Visibility settings', :js do
expect(visibility_select.value).to eq '0'
expect(visibility_select_container).to have_content 'Access must be granted explicitly to each user.'
end
+
+ context 'merge requests select' do
+ it 'hides merge requests section' do
+ find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
+
+ expect(page).to have_selector('.merge-requests-feature', visible: false)
+ end
+
+ context 'given project with merge_requests_disabled access level' do
+ let(:project) { create(:project, :merge_requests_disabled, namespace: user.namespace) }
+
+ it 'hides merge requests section' do
+ expect(page).to have_selector('.merge-requests-feature', visible: false)
+ end
+ end
+ end
+
+ context 'builds select' do
+ it 'hides builds select section' do
+ find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click
+
+ expect(page).to have_selector('.builds-feature', visible: false)
+ end
+
+ context 'given project with builds_disabled access level' do
+ let(:project) { create(:project, :builds_disabled, namespace: user.namespace) }
+
+ it 'hides builds select section' do
+ expect(page).to have_selector('.builds-feature', visible: false)
+ end
+ end
+ end
end
context 'as master' do
@@ -36,7 +68,7 @@ feature 'Visibility settings', :js do
visit edit_project_path(project)
end
- scenario 'project visibility is locked' do
+ it 'project visibility is locked' do
visibility_select_container = find('.project-visibility-setting')
expect(visibility_select_container).to have_selector 'select[name="project[visibility_level]"]:disabled'
diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
index bf55917bf4c..8803b5222be 100644
--- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb
+++ b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Developer views empty project instructions' do
+feature 'Projects > Show > Developer views empty project instructions' do
let(:project) { create(:project, :empty_repo) }
let(:developer) { create(:user) }
diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/show/download_buttons_spec.rb
index 81f08e44cf3..254affd4a94 100644
--- a/spec/features/projects/main/download_buttons_spec.rb
+++ b/spec/features/projects/show/download_buttons_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Download buttons in project main page' do
+feature 'Projects > Show > Download buttons' do
given(:user) { create(:user) }
given(:role) { :developer }
given(:status) { 'success' }
diff --git a/spec/features/projects/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb
index b3b3212556c..b3b3212556c 100644
--- a/spec/features/projects/no_password_spec.rb
+++ b/spec/features/projects/show/no_password_spec.rb
diff --git a/spec/features/projects/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index d1d8ca07035..8d41c547d77 100644
--- a/spec/features/projects/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Project redirects' do
+describe 'Projects > Show > Redirects' do
let(:user) { create :user }
let(:public_project) { create :project, :public }
let(:private_project) { create :project, :private }
diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/show/rss_spec.rb
index 3c98c11b490..d02eaf34533 100644
--- a/spec/features/projects/main/rss_spec.rb
+++ b/spec/features/projects/show/rss_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Project RSS' do
+feature 'Projects > Show > RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_path(project) }
diff --git a/spec/features/projects/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb
index d9d2e0ab171..ba28c0e1b8a 100644
--- a/spec/features/projects/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User interacts with project stars' do
+describe 'Projects > Show > User interacts with project stars' do
let(:project) { create(:project, :public, :repository) }
context 'when user is signed in', :js do
diff --git a/spec/features/projects/show/user_manages_notifications_spec.rb b/spec/features/projects/show/user_manages_notifications_spec.rb
new file mode 100644
index 00000000000..31b105229be
--- /dev/null
+++ b/spec/features/projects/show/user_manages_notifications_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe 'Projects > Show > User manages notifications', :js do
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ sign_in(project.owner)
+ visit project_path(project)
+ end
+
+ it 'changes the notification setting' do
+ first('.notifications-btn').click
+ click_link 'On mention'
+
+ page.within '#notifications-button' do
+ expect(page).to have_content 'On mention'
+ end
+ end
+end
diff --git a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
new file mode 100644
index 00000000000..aa23bef6fd8
--- /dev/null
+++ b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe 'Projects > Show > User sees a deletion failure message' do
+ let(:project) { create(:project, :empty_repo, pending_delete: true) }
+
+ before do
+ sign_in(project.owner)
+ end
+
+ it 'shows error message if deletion for project fails' do
+ project.update_attributes(delete_error: "Something went wrong", pending_delete: false)
+
+ visit project_path(project)
+
+ expect(page).to have_selector('.project-deletion-failed-message')
+ expect(page).to have_content("This project was scheduled for deletion, but failed with the following message: #{project.delete_error}")
+ end
+end
diff --git a/spec/features/projects/user_views_details_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index ffc063654cd..9a82fee1b5d 100644
--- a/spec/features/projects/user_views_details_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User views details' do
+describe 'Projects > Show > User sees Git instructions' do
set(:user) { create(:user) }
shared_examples_for 'redirects to the sign in page' do
@@ -9,6 +9,16 @@ describe 'User views details' do
end
end
+ shared_examples_for 'shows details of empty project with no repo' do
+ it 'shows Git command line instructions' do
+ click_link 'Create empty repository'
+
+ page.within '.empty_wrapper' do
+ expect(page).to have_content('Command line instructions')
+ end
+ end
+ end
+
shared_examples_for 'shows details of empty project' do
let(:user_has_ssh_key) { false }
@@ -36,6 +46,17 @@ describe 'User views details' do
end
context 'when project is public' do
+ context 'when project has no repo' do
+ set(:project) { create(:project, :public) }
+
+ before do
+ sign_in(project.owner)
+ visit project_path(project)
+ end
+
+ include_examples 'shows details of empty project with no repo'
+ end
+
context 'when project is empty' do
set(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
new file mode 100644
index 00000000000..e277bfb8011
--- /dev/null
+++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+describe 'Projects > Show > User sees last commit CI status' do
+ set(:project) { create(:project, :repository, :public) }
+
+ it 'shows the project README', :js do
+ project.enable_ci
+ pipeline = create(:ci_pipeline, project: project, sha: project.commit.sha, ref: 'master')
+ pipeline.skip
+
+ visit project_path(project)
+
+ page.within '.blob-commit-info' do
+ expect(page).to have_content(project.commit.sha[0..6])
+ expect(page).to have_link('Commit: skipped')
+ end
+ end
+end
diff --git a/spec/features/projects/show/user_sees_readme_spec.rb b/spec/features/projects/show/user_sees_readme_spec.rb
new file mode 100644
index 00000000000..d80606c1c23
--- /dev/null
+++ b/spec/features/projects/show/user_sees_readme_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe 'Projects > Show > User sees README' do
+ set(:user) { create(:user) }
+
+ set(:project) { create(:project, :repository, :public) }
+
+ it 'shows the project README', :js do
+ visit project_path(project)
+ wait_for_requests
+
+ page.within('.readme-holder') do
+ expect(page).to have_content 'testme'
+ end
+ end
+end
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
new file mode 100644
index 00000000000..a906fa20233
--- /dev/null
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -0,0 +1,318 @@
+require 'spec_helper'
+
+describe 'Projects > Show > User sees setup shortcut buttons' do
+ # For "New file", "Add License" functionality,
+ # see spec/features/projects/files/project_owner_creates_license_file_spec.rb
+ # see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+
+ let(:user) { create(:user) }
+
+ describe 'empty project' do
+ let(:project) { create(:project, :public, :empty_repo) }
+ let(:presenter) { project.present(current_user: user) }
+
+ describe 'as a normal user' do
+ before do
+ sign_in(user)
+
+ visit project_path(project)
+ end
+
+ it 'no Auto DevOps button if can not manage pipelines' do
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
+ end
+
+ it '"Auto DevOps enabled" button not linked' do
+ project.create_auto_devops!(enabled: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_text('Auto DevOps enabled')
+ end
+ end
+ end
+
+ describe 'as a master' do
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ visit project_path(project)
+ end
+
+ it '"New file" button linked to new file page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master'))
+ end
+ end
+
+ it '"Add Readme" button linked to new file populated for a readme' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Add Readme', href: presenter.add_readme_path)
+ end
+ end
+
+ it '"Add License" button linked to new file populated for a license' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Add License', href: presenter.add_license_path)
+ end
+ end
+
+ describe 'Auto DevOps button' do
+ it '"Enable Auto DevOps" button linked to settings page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
+ end
+ end
+
+ it '"Auto DevOps enabled" anchor linked to settings page' do
+ project.create_auto_devops!(enabled: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
+ end
+ end
+ end
+
+ describe 'Kubernetes cluster button' do
+ it '"Add Kubernetes cluster" button linked to clusters page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
+ end
+ end
+
+ it '"Kubernetes cluster" anchor linked to cluster page' do
+ cluster = create(:cluster, :provided_by_gcp, projects: [project])
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
+ end
+ end
+ end
+ end
+ end
+
+ describe 'populated project' do
+ let(:project) { create(:project, :public, :repository) }
+ let(:presenter) { project.present(current_user: user) }
+
+ describe 'as a normal user' do
+ before do
+ sign_in(user)
+
+ visit project_path(project)
+ end
+
+ it 'no Auto DevOps button if can not manage pipelines' do
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
+ end
+
+ it '"Auto DevOps enabled" button not linked' do
+ project.create_auto_devops!(enabled: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_text('Auto DevOps enabled')
+ end
+ end
+
+ it 'no Kubernetes cluster button if can not manage clusters' do
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Add Kubernetes cluster')
+ expect(page).not_to have_link('Kubernetes configured')
+ end
+ end
+ end
+
+ describe 'as a master' do
+ before do
+ allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(false)
+ project.add_master(user)
+ sign_in(user)
+
+ visit project_path(project)
+ end
+
+ it 'no "Add Changelog" button if the project already has a changelog' do
+ expect(project.repository.changelog).not_to be_nil
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Add Changelog')
+ end
+ end
+
+ it 'no "Add License" button if the project already has a license' do
+ expect(project.repository.license_blob).not_to be_nil
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Add License')
+ end
+ end
+
+ it 'no "Add Contribution guide" button if the project already has a contribution guide' do
+ expect(project.repository.contribution_guide).not_to be_nil
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Add Contribution guide')
+ end
+ end
+
+ describe 'GitLab CI configuration button' do
+ it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do
+ expect(project.repository.gitlab_ci_yml).to be_nil
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
+ end
+ end
+
+ it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ expect(project.repository.gitlab_ci_yml).not_to be_nil
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up CI/CD')
+ end
+ end
+
+ it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
+ project.create_auto_devops!(enabled: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up CI/CD')
+ end
+ end
+ end
+
+ describe 'Auto DevOps button' do
+ it '"Enable Auto DevOps" button linked to settings page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
+ end
+ end
+
+ it '"Enable Auto DevOps" button linked to settings page' do
+ project.create_auto_devops!(enabled: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
+ end
+ end
+
+ it 'no Auto DevOps button if Auto DevOps callout is shown' do
+ allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true)
+
+ visit project_path(project)
+
+ expect(page).to have_selector('.js-autodevops-banner')
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
+ end
+
+ it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ expect(project.repository.gitlab_ci_yml).not_to be_nil
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
+ end
+ end
+
+ describe 'Kubernetes cluster button' do
+ it '"Add Kubernetes cluster" button linked to clusters page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
+ end
+ end
+
+ it '"Kubernetes cluster" button linked to cluster page' do
+ cluster = create(:cluster, :provided_by_gcp, projects: [project])
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
+ end
+ end
+ end
+
+ describe '"Set up Koding" button' do
+ it 'no "Set up Koding" button if Koding disabled' do
+ stub_application_setting(koding_enabled?: false)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up Koding')
+ end
+ end
+
+ it 'no "Set up Koding" button if the project already has a .koding.yml' do
+ stub_application_setting(koding_enabled?: true)
+ allow(Gitlab::CurrentSettings.current_application_settings).to receive(:koding_url).and_return('http://koding.example.com')
+ expect(project.repository.changelog).not_to be_nil
+ allow_any_instance_of(Repository).to receive(:koding_yml).and_return(project.repository.changelog)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up Koding')
+ end
+ end
+
+ it '"Set up Koding" button linked to new file populated for a .koding.yml' do
+ stub_application_setting(koding_enabled?: true)
+
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Set up Koding', href: presenter.add_koding_stack_path)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/show_project_spec.rb b/spec/features/projects/show_project_spec.rb
deleted file mode 100644
index e4f13e6cab7..00000000000
--- a/spec/features/projects/show_project_spec.rb
+++ /dev/null
@@ -1,359 +0,0 @@
-require 'spec_helper'
-
-describe 'Project show page', :feature do
- include DropzoneHelper
-
- context 'when project pending delete' do
- let(:project) { create(:project, :empty_repo, pending_delete: true) }
-
- before do
- sign_in(project.owner)
- end
-
- it 'shows error message if deletion for project fails' do
- project.update_attributes(delete_error: "Something went wrong", pending_delete: false)
-
- visit project_path(project)
-
- expect(page).to have_selector('.project-deletion-failed-message')
- expect(page).to have_content("This project was scheduled for deletion, but failed with the following message: #{project.delete_error}")
- end
- end
-
- describe 'stat button existence' do
- # For "New file", "Add License" functionality,
- # see spec/features/projects/files/project_owner_creates_license_file_spec.rb
- # see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
-
- let(:user) { create(:user) }
-
- describe 'empty project' do
- let(:project) { create(:project, :public, :empty_repo) }
- let(:presenter) { project.present(current_user: user) }
-
- describe 'as a normal user' do
- before do
- sign_in(user)
-
- visit project_path(project)
- end
-
- it 'no Auto DevOps button if can not manage pipelines' do
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
- end
- end
-
- it '"Auto DevOps enabled" button not linked' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_text('Auto DevOps enabled')
- end
- end
- end
-
- describe 'as a master' do
- before do
- project.add_master(user)
- sign_in(user)
-
- visit project_path(project)
- end
-
- it '"New file" button linked to new file page' do
- page.within('.project-stats') do
- expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master'))
- end
- end
-
- it '"Add Readme" button linked to new file populated for a readme' do
- page.within('.project-stats') do
- expect(page).to have_link('Add Readme', href: presenter.add_readme_path)
- end
- end
-
- it '"Add License" button linked to new file populated for a license' do
- page.within('.project-stats') do
- expect(page).to have_link('Add License', href: presenter.add_license_path)
- end
- end
-
- describe 'Auto DevOps button' do
- it '"Enable Auto DevOps" button linked to settings page' do
- page.within('.project-stats') do
- expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
- end
- end
-
- it '"Auto DevOps enabled" anchor linked to settings page' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
- end
- end
- end
-
- describe 'Kubernetes cluster button' do
- it '"Add Kubernetes cluster" button linked to clusters page' do
- page.within('.project-stats') do
- expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
- end
- end
-
- it '"Kubernetes cluster" anchor linked to cluster page' do
- cluster = create(:cluster, :provided_by_gcp, projects: [project])
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
- end
- end
- end
- end
- end
-
- describe 'populated project' do
- let(:project) { create(:project, :public, :repository) }
- let(:presenter) { project.present(current_user: user) }
-
- describe 'as a normal user' do
- before do
- sign_in(user)
-
- visit project_path(project)
- end
-
- it 'no Auto DevOps button if can not manage pipelines' do
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
- end
- end
-
- it '"Auto DevOps enabled" button not linked' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_text('Auto DevOps enabled')
- end
- end
-
- it 'no Kubernetes cluster button if can not manage clusters' do
- page.within('.project-stats') do
- expect(page).not_to have_link('Add Kubernetes cluster')
- expect(page).not_to have_link('Kubernetes configured')
- end
- end
- end
-
- describe 'as a master' do
- before do
- allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(false)
- project.add_master(user)
- sign_in(user)
-
- visit project_path(project)
- end
-
- it 'no "Add Changelog" button if the project already has a changelog' do
- expect(project.repository.changelog).not_to be_nil
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Add Changelog')
- end
- end
-
- it 'no "Add License" button if the project already has a license' do
- expect(project.repository.license_blob).not_to be_nil
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Add License')
- end
- end
-
- it 'no "Add Contribution guide" button if the project already has a contribution guide' do
- expect(project.repository.contribution_guide).not_to be_nil
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Add Contribution guide')
- end
- end
-
- describe 'GitLab CI configuration button' do
- it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do
- expect(project.repository.gitlab_ci_yml).to be_nil
-
- page.within('.project-stats') do
- expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
- end
- end
-
- it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
-
- expect(project.repository.gitlab_ci_yml).not_to be_nil
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up CI/CD')
- end
- end
-
- it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up CI/CD')
- end
- end
- end
-
- describe 'Auto DevOps button' do
- it '"Enable Auto DevOps" button linked to settings page' do
- page.within('.project-stats') do
- expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
- end
- end
-
- it '"Enable Auto DevOps" button linked to settings page' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings'))
- end
- end
-
- it 'no Auto DevOps button if Auto DevOps callout is shown' do
- allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true)
-
- visit project_path(project)
-
- expect(page).to have_selector('.js-autodevops-banner')
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
- end
- end
-
- it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
-
- expect(project.repository.gitlab_ci_yml).not_to be_nil
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
- end
- end
- end
-
- describe 'Kubernetes cluster button' do
- it '"Add Kubernetes cluster" button linked to clusters page' do
- page.within('.project-stats') do
- expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
- end
- end
-
- it '"Kubernetes cluster" button linked to cluster page' do
- cluster = create(:cluster, :provided_by_gcp, projects: [project])
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
- end
- end
- end
-
- describe '"Set up Koding" button' do
- it 'no "Set up Koding" button if Koding disabled' do
- stub_application_setting(koding_enabled?: false)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up Koding')
- end
- end
-
- it 'no "Set up Koding" button if the project already has a .koding.yml' do
- stub_application_setting(koding_enabled?: true)
- allow(Gitlab::CurrentSettings.current_application_settings).to receive(:koding_url).and_return('http://koding.example.com')
- expect(project.repository.changelog).not_to be_nil
- allow_any_instance_of(Repository).to receive(:koding_yml).and_return(project.repository.changelog)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up Koding')
- end
- end
-
- it '"Set up Koding" button linked to new file populated for a .koding.yml' do
- stub_application_setting(koding_enabled?: true)
-
- visit project_path(project)
-
- page.within('.project-stats') do
- expect(page).to have_link('Set up Koding', href: presenter.add_koding_stack_path)
- end
- end
- end
- end
- end
- end
-
- describe 'dropzone', :js do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
-
- before do
- project.add_master(user)
- sign_in(user)
-
- visit project_path(project)
- end
-
- it 'can upload files' do
- find('.add-to-tree').click
- click_link 'Upload file'
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
-
- expect(find('.dz-filename')).to have_content('doc_sample.txt')
- end
- end
-end
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 3466a3dfb77..2388feeb980 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Create Snippet', :js do
+describe 'Projects > Snippets > Create Snippet', :js do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb
index 216f2af7c88..004ac55b656 100644
--- a/spec/features/projects/snippets/show_spec.rb
+++ b/spec/features/projects/snippets/show_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Project snippet', :js do
+describe 'Projects > Snippets > Project snippet', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) }
diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
index 1bd2098af6d..01cf9740d1f 100644
--- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User comments on a snippet', :js do
+describe 'Projects > Snippets > User comments on a snippet', :js do
let(:project) { create(:project) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
let(:user) { create(:user) }
@@ -22,4 +22,16 @@ describe 'User comments on a snippet', :js do
expect(page).to have_content('Good snippet!')
end
+
+ it 'should have autocomplete' do
+ find('#note_note').native.send_keys('')
+ fill_in 'note[note]', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
+
+ it 'should have zen mode' do
+ find('.js-zen-enter').click()
+ expect(page).to have_selector('.fullscreen')
+ end
end
diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
index ca5f7981c33..e64837ad59e 100644
--- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User deletes a snippet' do
+describe 'Projects > Snippets > User deletes a snippet' do
let(:project) { create(:project) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb
index 09a390443cf..eaedbbf32b6 100644
--- a/spec/features/projects/snippets/user_updates_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'User updates a snippet' do
+describe 'Projects > Snippets > User updates a snippet' do
let(:project) { create(:project) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/user_views_snippets_spec.rb b/spec/features/projects/snippets/user_views_snippets_spec.rb
index e9992e00ca8..376b76e0001 100644
--- a/spec/features/projects/snippets/user_views_snippets_spec.rb
+++ b/spec/features/projects/snippets/user_views_snippets_spec.rb
@@ -1,9 +1,10 @@
require 'spec_helper'
-describe 'User views snippets' do
+describe 'Projects > Snippets > User views snippets' do
let(:project) { create(:project) }
let!(:project_snippet) { create(:project_snippet, project: project, author: user) }
let!(:snippet) { create(:snippet, author: user) }
+ let(:snippets) { [project_snippet, snippet] } # Used by the shared examples
let(:user) { create(:user) }
before do
@@ -13,6 +14,17 @@ describe 'User views snippets' do
visit(project_snippets_path(project))
end
+ context 'pagination' do
+ before do
+ create(:project_snippet, project: project, author: user)
+ allow(Snippet).to receive(:default_per_page).and_return(1)
+
+ visit project_snippets_path(project)
+ end
+
+ it_behaves_like 'paginated snippets'
+ end
+
it 'shows snippets' do
expect(page).to have_content(project_snippet.title)
expect(page).not_to have_content(snippet.title)
diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb
deleted file mode 100644
index 0fa7ca9afd4..00000000000
--- a/spec/features/projects/snippets_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'spec_helper'
-
-describe 'Project snippets', :js do
- context 'when the project has snippets' do
- let(:project) { create(:project, :public) }
- let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
- let!(:other_snippet) { create(:project_snippet) }
-
- context 'pagination' do
- before do
- allow(Snippet).to receive(:default_per_page).and_return(1)
-
- visit project_snippets_path(project)
- end
-
- it_behaves_like 'paginated snippets'
- end
-
- context 'list content' do
- it 'contains all project snippets' do
- visit project_snippets_path(project)
-
- expect(page).to have_selector('.snippet-row', count: 2)
-
- expect(page).to have_content(snippets[0].title)
- expect(page).to have_content(snippets[1].title)
- end
- end
-
- context 'when submitting a note' do
- before do
- sign_in(create(:admin))
- visit project_snippet_path(project, snippets[0])
- end
-
- it 'should have autocomplete' do
- find('#note_note').native.send_keys('')
- fill_in 'note[note]', with: '@'
-
- expect(page).to have_selector('.atwho-view')
- end
-
- it 'should have zen mode' do
- find('.js-zen-enter').click()
- expect(page).to have_selector('.fullscreen')
- end
- end
- end
-end
diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb
new file mode 100644
index 00000000000..cf80517b934
--- /dev/null
+++ b/spec/features/projects/user_sees_sidebar_spec.rb
@@ -0,0 +1,106 @@
+require 'spec_helper'
+
+describe 'Projects > User sees sidebar' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) }
+
+ context 'as owner' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when snippets are disabled' do
+ before do
+ project.project_feature.update_attribute('snippets_access_level', ProjectFeature::DISABLED)
+ end
+
+ it 'does not display a "Snippets" link' do
+ visit project_path(project)
+
+ within('.nav-sidebar') do
+ expect(page).not_to have_content 'Snippets'
+ end
+ end
+ end
+ end
+
+ context 'as guest' do
+ let(:guest) { create(:user) }
+
+ before do
+ project.add_guest(guest)
+
+ sign_in(guest)
+ end
+
+ it 'shows allowed tabs only' do
+ visit project_path(project)
+
+ within('.nav-sidebar') do
+ expect(page).to have_content 'Overview'
+ expect(page).to have_content 'Issues'
+ expect(page).to have_content 'Wiki'
+
+ expect(page).not_to have_content 'Repository'
+ expect(page).not_to have_content 'CI / CD'
+ expect(page).not_to have_content 'Merge Requests'
+ end
+ end
+
+ it 'does not show fork button' do
+ visit project_path(project)
+
+ within('.count-buttons') do
+ expect(page).not_to have_link 'Fork'
+ end
+ end
+
+ it 'does not show clone path' do
+ visit project_path(project)
+
+ within('.project-repo-buttons') do
+ expect(page).not_to have_selector '.project-clone-holder'
+ end
+ end
+
+ describe 'project landing page' do
+ before do
+ project.project_feature.update!(
+ issues_access_level: ProjectFeature::DISABLED,
+ wiki_access_level: ProjectFeature::DISABLED
+ )
+ end
+
+ it 'does not show the project file list landing page' do
+ visit project_path(project)
+
+ expect(page).not_to have_selector '.project-stats'
+ expect(page).not_to have_selector '.project-last-commit'
+ expect(page).not_to have_selector '.project-show-files'
+ expect(page).to have_selector '.project-show-customize_workflow'
+ end
+
+ it 'shows the customize workflow when issues and wiki are disabled' do
+ visit project_path(project)
+
+ expect(page).to have_selector '.project-show-customize_workflow'
+ end
+
+ it 'shows the wiki when enabled' do
+ project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE)
+
+ visit project_path(project)
+
+ expect(page).to have_selector '.project-show-wiki'
+ end
+
+ it 'shows the issues when enabled' do
+ project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE)
+
+ visit project_path(project)
+
+ expect(page).to have_selector '.issues-list'
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/user_transfers_a_project_spec.rb b/spec/features/projects/user_transfers_a_project_spec.rb
deleted file mode 100644
index 78f72b644ff..00000000000
--- a/spec/features/projects/user_transfers_a_project_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'spec_helper'
-
-feature 'User transfers a project', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository, namespace: user.namespace) }
-
- before do
- sign_in user
- end
-
- def transfer_project(project, group)
- visit edit_project_path(project)
-
- page.within('.js-project-transfer-form') do
- page.find('.select2-container').click
- end
-
- page.find("div[role='option']", text: group.full_name).click
-
- click_button('Transfer project')
-
- fill_in 'confirm_name_input', with: project.name
-
- click_button 'Confirm'
-
- wait_for_requests
- end
-
- it 'allows transferring a project to a subgroup of a namespace' do
- group = create(:group)
- group.add_owner(user)
-
- transfer_project(project, group)
-
- expect(project.reload.namespace).to eq(group)
- end
-
- context 'when nested groups are available', :nested_groups do
- it 'allows transferring a project to a subgroup' do
- parent = create(:group)
- parent.add_owner(user)
- subgroup = create(:group, parent: parent)
-
- transfer_project(project, subgroup)
-
- expect(project.reload.namespace).to eq(subgroup)
- end
- end
-end
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index a4084818284..43cabd3b9f2 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -142,7 +142,10 @@ feature 'Protected Branches', :js do
set_protected_branch_name('*-stable')
click_on "Protect"
- within(".protected-branches-list") { expect(page).to have_content("2 matching branches") }
+ within(".protected-branches-list") do
+ expect(page).to have_content("Protected branch (2)")
+ expect(page).to have_content("2 matching branches")
+ end
end
it "displays all the branches matching the wildcard" do
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 8cc6f17b8d9..efccaeaff6c 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -65,7 +65,10 @@ feature 'Protected Tags', :js do
set_protected_tag_name('*-stable')
click_on "Protect"
- within(".protected-tags-list") { expect(page).to have_content("2 matching tags") }
+ within(".protected-tags-list") do
+ expect(page).to have_content("Protected tag (2)")
+ expect(page).to have_content("2 matching tags")
+ end
end
it "displays all the tags matching the wildcard" do
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 5ddea36add5..a9128104b87 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -9,49 +9,25 @@ describe 'User uses header search field' do
before do
project.add_reporter(user)
sign_in(user)
-
- visit(project_path(project))
- end
-
- it 'starts searching by pressing the enter key', :js do
- fill_in('search', with: 'gitlab')
- find('#search').native.send_keys(:enter)
-
- page.within('.breadcrumbs-sub-title') do
- expect(page).to have_content('Search')
- end
end
- it 'contains location badge' do
- expect(page).to have_selector('.has-location-badge')
- end
-
- context 'when clicking the search field', :js do
+ context 'when user is in a global scope', :js do
before do
+ visit(root_path)
page.find('#search').click
end
- it 'shows category search dropdown' do
- expect(page).to have_selector('.dropdown-header', text: /#{project.name}/i)
- end
-
context 'when clicking issues' do
- let!(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
-
it 'shows assigned issues' do
- find('.dropdown-menu').click_link('Issues assigned to me')
+ find('.search-input-container .dropdown-menu').click_link('Issues assigned to me')
- expect(page).to have_selector('.filtered-search')
- expect_tokens([assignee_token(user.name)])
- expect_filtered_search_input_empty
+ expect(find('.js-assignee-search')).to have_content(user.name)
end
it 'shows created issues' do
- find('.dropdown-menu').click_link("Issues I've created")
+ find('.search-input-container .dropdown-menu').click_link("Issues I've created")
- expect(page).to have_selector('.filtered-search')
- expect_tokens([author_token(user.name)])
- expect_filtered_search_input_empty
+ expect(find('.js-author-search')).to have_content(user.name)
end
end
@@ -59,32 +35,97 @@ describe 'User uses header search field' do
let!(:merge_request) { create(:merge_request, source_project: project, author: user, assignee: user) }
it 'shows assigned merge requests' do
- find('.dropdown-menu').click_link('Merge requests assigned to me')
+ find('.search-input-container .dropdown-menu').click_link('Merge requests assigned to me')
- expect(page).to have_selector('.merge-requests-holder')
- expect_tokens([assignee_token(user.name)])
- expect_filtered_search_input_empty
+ expect(find('.js-assignee-search')).to have_content(user.name)
end
it 'shows created merge requests' do
- find('.dropdown-menu').click_link("Merge requests I've created")
+ find('.search-input-container .dropdown-menu').click_link("Merge requests I've created")
- expect(page).to have_selector('.merge-requests-holder')
- expect_tokens([author_token(user.name)])
- expect_filtered_search_input_empty
+ expect(find('.js-author-search')).to have_content(user.name)
end
end
end
- context 'when entering text into the search field', :js do
+ context 'when user is in a project scope' do
before do
- page.within('.search-input-wrap') do
- fill_in('search', with: project.name[0..3])
+ visit(project_path(project))
+ end
+
+ it 'starts searching by pressing the enter key', :js do
+ fill_in('search', with: 'gitlab')
+ find('#search').native.send_keys(:enter)
+
+ page.within('.breadcrumbs-sub-title') do
+ expect(page).to have_content('Search')
end
end
- it 'does not display the category search dropdown' do
- expect(page).not_to have_selector('.dropdown-header', text: /#{project.name}/i)
+ it 'contains location badge' do
+ expect(page).to have_selector('.has-location-badge')
+ end
+
+ context 'when clicking the search field', :js do
+ before do
+ page.find('#search').click
+ end
+
+ it 'shows category search dropdown' do
+ expect(page).to have_selector('.dropdown-header', text: /#{project.name}/i)
+ end
+
+ context 'when clicking issues' do
+ let!(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
+
+ it 'shows assigned issues' do
+ find('.dropdown-menu').click_link('Issues assigned to me')
+
+ expect(page).to have_selector('.filtered-search')
+ expect_tokens([assignee_token(user.name)])
+ expect_filtered_search_input_empty
+ end
+
+ it 'shows created issues' do
+ find('.dropdown-menu').click_link("Issues I've created")
+
+ expect(page).to have_selector('.filtered-search')
+ expect_tokens([author_token(user.name)])
+ expect_filtered_search_input_empty
+ end
+ end
+
+ context 'when clicking merge requests' do
+ let!(:merge_request) { create(:merge_request, source_project: project, author: user, assignee: user) }
+
+ it 'shows assigned merge requests' do
+ find('.dropdown-menu').click_link('Merge requests assigned to me')
+
+ expect(page).to have_selector('.merge-requests-holder')
+ expect_tokens([assignee_token(user.name)])
+ expect_filtered_search_input_empty
+ end
+
+ it 'shows created merge requests' do
+ find('.dropdown-menu').click_link("Merge requests I've created")
+
+ expect(page).to have_selector('.merge-requests-holder')
+ expect_tokens([author_token(user.name)])
+ expect_filtered_search_input_empty
+ end
+ end
+ end
+
+ context 'when entering text into the search field', :js do
+ before do
+ page.within('.search-input-wrap') do
+ fill_in('search', with: project.name[0..3])
+ end
+ end
+
+ it 'does not display the category search dropdown' do
+ expect(page).not_to have_selector('.dropdown-header', text: /#{project.name}/i)
+ end
end
end
end
diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb
new file mode 100644
index 00000000000..69ebdddaeec
--- /dev/null
+++ b/spec/features/user_sorts_things_spec.rb
@@ -0,0 +1,57 @@
+require "spec_helper"
+
+# The main goal of this spec is not to check whether the sorting UI works, but
+# to check if the sorting option set by user is being kept persisted while going through pages.
+# The `it`s are named here by convention `starting point -> some pages -> final point`.
+# All those specs are moved out to this spec intentionally to keep them all in one place.
+describe "User sorts things" do
+ include Spec::Support::Helpers::Features::SortingHelpers
+ include Helpers::DashboardHelper
+
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:current_user) { create(:user) } # Using `current_user` instead of just `user` because of the hardoced call in `assigned_mrs_dashboard_path` which is used below.
+ set(:issue) { create(:issue, project: project, author: current_user) }
+ set(:merge_request) { create(:merge_request, target_project: project, source_project: project, author: current_user) }
+
+ before do
+ project.add_developer(current_user)
+ sign_in(current_user)
+ end
+
+ it "issues -> project home page -> issues" do
+ sort_option = "Last updated"
+
+ visit(project_issues_path(project))
+
+ sort_by(sort_option)
+
+ visit(project_path(project))
+ visit(project_issues_path(project))
+
+ expect(find(".issues-filters")).to have_content(sort_option)
+ end
+
+ it "issues -> merge requests" do
+ sort_option = "Last updated"
+
+ visit(project_issues_path(project))
+
+ sort_by(sort_option)
+
+ visit(project_merge_requests_path(project))
+
+ expect(find(".issues-filters")).to have_content(sort_option)
+ end
+
+ it "merge requests -> dashboard merge requests" do
+ sort_option = "Last updated"
+
+ visit(project_merge_requests_path(project))
+
+ sort_by(sort_option)
+
+ visit(assigned_mrs_dashboard_path)
+
+ expect(find(".issues-filters")).to have_content(sort_option)
+ end
+end