From 2d54dfb25134cbdf5b4f506b69d13241130bc132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 6 Apr 2018 14:40:33 +0200 Subject: Migrate features/project/project.feature to RSpec and reorganize several Project feature specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- features/project/project.feature | 86 ----- features/steps/project/project.rb | 154 --------- features/steps/shared/project.rb | 84 ----- .../projects/activity/user_sees_activity_spec.rb | 36 +++ ...eloper_views_empty_project_instructions_spec.rb | 63 ---- spec/features/projects/edit_spec.rb | 62 ---- spec/features/projects/files/browse_files_spec.rb | 46 --- .../projects/files/creating_a_file_spec.rb | 37 --- .../projects/files/dockerfile_dropdown_spec.rb | 6 +- .../projects/files/download_buttons_spec.rb | 18 +- .../projects/files/edit_file_soft_wrap_spec.rb | 4 +- .../features/projects/files/editing_a_file_spec.rb | 6 +- .../files_sort_submodules_with_folders_spec.rb | 4 +- .../projects/files/find_file_keyboard_spec.rb | 2 +- .../projects/files/gitignore_dropdown_spec.rb | 6 +- .../projects/files/gitlab_ci_yml_dropdown_spec.rb | 6 +- .../project_owner_creates_license_file_spec.rb | 9 +- ...to_create_license_file_in_empty_project_spec.rb | 6 +- .../projects/files/template_type_dropdown_spec.rb | 28 +- spec/features/projects/files/undo_template_spec.rb | 6 +- ..._tree_with_a_folder_containing_only_a_folder.rb | 20 ++ .../projects/files/user_browses_files_spec.rb | 154 +++++++++ .../projects/files/user_browses_lfs_files_spec.rb | 58 ++++ .../projects/files/user_creates_directory_spec.rb | 87 +++++ .../projects/files/user_creates_files_spec.rb | 190 +++++++++++ .../projects/files/user_deletes_files_spec.rb | 68 ++++ .../projects/files/user_edits_files_spec.rb | 173 ++++++++++ .../projects/files/user_replaces_files_spec.rb | 87 +++++ .../projects/files/user_searches_for_files_spec.rb | 2 +- .../projects/files/user_uploads_files_spec.rb | 105 ++++++ .../projects/guest_navigation_menu_spec.rb | 82 ----- .../projects/main/download_buttons_spec.rb | 49 --- spec/features/projects/main/rss_spec.rb | 25 -- spec/features/projects/no_password_spec.rb | 69 ---- spec/features/projects/project_settings_spec.rb | 205 ------------ spec/features/projects/redirects_spec.rb | 74 ----- .../settings/forked_project_settings_spec.rb | 2 +- .../projects/settings/integration_settings_spec.rb | 28 +- .../projects/settings/lfs_settings_spec.rb | 20 ++ .../settings/merge_requests_settings_spec.rb | 97 ------ .../projects/settings/pipelines_settings_spec.rb | 14 +- .../projects/settings/repository_settings_spec.rb | 20 +- .../settings/user_archives_project_spec.rb | 37 +++ .../projects/settings/user_changes_avatar_spec.rb | 44 +++ .../settings/user_changes_default_branch_spec.rb | 20 ++ .../settings/user_manages_group_links_spec.rb | 2 +- .../user_manages_merge_requests_settings_spec.rb | 107 ++++++ .../settings/user_manages_project_members_spec.rb | 2 +- .../settings/user_renames_a_project_spec.rb | 100 ++++++ .../projects/settings/user_tags_project_spec.rb | 23 ++ .../settings/user_transfers_a_project_spec.rb | 73 +++++ .../projects/settings/visibility_settings_spec.rb | 40 ++- ...eloper_views_empty_project_instructions_spec.rb | 63 ++++ .../projects/show/download_buttons_spec.rb | 49 +++ spec/features/projects/show/no_password_spec.rb | 69 ++++ spec/features/projects/show/redirects_spec.rb | 74 +++++ spec/features/projects/show/rss_spec.rb | 25 ++ .../show/user_interacts_with_stars_spec.rb | 38 +++ .../show/user_manages_notifications_spec.rb | 23 ++ .../user_sees_deletion_failure_message_spec.rb | 18 ++ .../show/user_sees_git_instructions_spec.rb | 172 ++++++++++ .../show/user_sees_last_commit_ci_status_spec.rb | 18 ++ .../projects/show/user_sees_readme_spec.rb | 16 + .../show/user_sees_setup_shortcut_buttons_spec.rb | 318 ++++++++++++++++++ spec/features/projects/show_project_spec.rb | 359 --------------------- .../projects/snippets/create_snippet_spec.rb | 2 +- spec/features/projects/snippets/show_spec.rb | 2 +- .../snippets/user_comments_on_snippet_spec.rb | 14 +- .../projects/snippets/user_deletes_snippet_spec.rb | 2 +- .../projects/snippets/user_updates_snippet_spec.rb | 2 +- .../projects/snippets/user_views_snippets_spec.rb | 14 +- spec/features/projects/snippets_spec.rb | 49 --- .../projects/user_archives_project_spec.rb | 43 --- ..._tree_with_a_folder_containing_only_a_folder.rb | 20 -- spec/features/projects/user_browses_files_spec.rb | 189 ----------- .../projects/user_creates_directory_spec.rb | 87 ----- spec/features/projects/user_creates_files_spec.rb | 165 ---------- spec/features/projects/user_deletes_files_spec.rb | 68 ---- spec/features/projects/user_edits_files_spec.rb | 173 ---------- .../projects/user_interacts_with_stars_spec.rb | 38 --- spec/features/projects/user_replaces_files_spec.rb | 87 ----- spec/features/projects/user_sees_sidebar_spec.rb | 106 ++++++ .../projects/user_transfers_a_project_spec.rb | 49 --- spec/features/projects/user_uploads_files_spec.rb | 87 ----- spec/features/projects/user_views_details_spec.rb | 151 --------- 85 files changed, 2543 insertions(+), 2793 deletions(-) delete mode 100644 features/project/project.feature delete mode 100644 features/steps/project/project.rb create mode 100644 spec/features/projects/activity/user_sees_activity_spec.rb delete mode 100644 spec/features/projects/developer_views_empty_project_instructions_spec.rb delete mode 100644 spec/features/projects/edit_spec.rb delete mode 100644 spec/features/projects/files/browse_files_spec.rb delete mode 100644 spec/features/projects/files/creating_a_file_spec.rb create mode 100644 spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb create mode 100644 spec/features/projects/files/user_browses_files_spec.rb create mode 100644 spec/features/projects/files/user_browses_lfs_files_spec.rb create mode 100644 spec/features/projects/files/user_creates_directory_spec.rb create mode 100644 spec/features/projects/files/user_creates_files_spec.rb create mode 100644 spec/features/projects/files/user_deletes_files_spec.rb create mode 100644 spec/features/projects/files/user_edits_files_spec.rb create mode 100644 spec/features/projects/files/user_replaces_files_spec.rb create mode 100644 spec/features/projects/files/user_uploads_files_spec.rb delete mode 100644 spec/features/projects/guest_navigation_menu_spec.rb delete mode 100644 spec/features/projects/main/download_buttons_spec.rb delete mode 100644 spec/features/projects/main/rss_spec.rb delete mode 100644 spec/features/projects/no_password_spec.rb delete mode 100644 spec/features/projects/project_settings_spec.rb delete mode 100644 spec/features/projects/redirects_spec.rb create mode 100644 spec/features/projects/settings/lfs_settings_spec.rb delete mode 100644 spec/features/projects/settings/merge_requests_settings_spec.rb create mode 100644 spec/features/projects/settings/user_archives_project_spec.rb create mode 100644 spec/features/projects/settings/user_changes_avatar_spec.rb create mode 100644 spec/features/projects/settings/user_changes_default_branch_spec.rb create mode 100644 spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb create mode 100644 spec/features/projects/settings/user_renames_a_project_spec.rb create mode 100644 spec/features/projects/settings/user_tags_project_spec.rb create mode 100644 spec/features/projects/settings/user_transfers_a_project_spec.rb create mode 100644 spec/features/projects/show/developer_views_empty_project_instructions_spec.rb create mode 100644 spec/features/projects/show/download_buttons_spec.rb create mode 100644 spec/features/projects/show/no_password_spec.rb create mode 100644 spec/features/projects/show/redirects_spec.rb create mode 100644 spec/features/projects/show/rss_spec.rb create mode 100644 spec/features/projects/show/user_interacts_with_stars_spec.rb create mode 100644 spec/features/projects/show/user_manages_notifications_spec.rb create mode 100644 spec/features/projects/show/user_sees_deletion_failure_message_spec.rb create mode 100644 spec/features/projects/show/user_sees_git_instructions_spec.rb create mode 100644 spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb create mode 100644 spec/features/projects/show/user_sees_readme_spec.rb create mode 100644 spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb delete mode 100644 spec/features/projects/show_project_spec.rb delete mode 100644 spec/features/projects/snippets_spec.rb delete mode 100644 spec/features/projects/user_archives_project_spec.rb delete mode 100644 spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb delete mode 100644 spec/features/projects/user_browses_files_spec.rb delete mode 100644 spec/features/projects/user_creates_directory_spec.rb delete mode 100644 spec/features/projects/user_creates_files_spec.rb delete mode 100644 spec/features/projects/user_deletes_files_spec.rb delete mode 100644 spec/features/projects/user_edits_files_spec.rb delete mode 100644 spec/features/projects/user_interacts_with_stars_spec.rb delete mode 100644 spec/features/projects/user_replaces_files_spec.rb create mode 100644 spec/features/projects/user_sees_sidebar_spec.rb delete mode 100644 spec/features/projects/user_transfers_a_project_spec.rb delete mode 100644 spec/features/projects/user_uploads_files_spec.rb delete mode 100644 spec/features/projects/user_views_details_spec.rb diff --git a/features/project/project.feature b/features/project/project.feature deleted file mode 100644 index 23817ef3ac9..00000000000 --- a/features/project/project.feature +++ /dev/null @@ -1,86 +0,0 @@ -Feature: Project - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has push event - And I visit project "Shop" page - - Scenario: I edit the project avatar - Given I visit edit project "Shop" page - When I change the project avatar - And I should see new project avatar - And I should see the "Remove avatar" button - - Scenario: I remove the project avatar - Given I visit edit project "Shop" page - And I have an project avatar - When I remove my project avatar - Then I should see the default project avatar - And I should not see the "Remove avatar" button - - @javascript - Scenario: I should have readme on page - And I visit project "Shop" page - Then I should see project "Shop" README - - Scenario: I should see last commit with CI - Given project "Shop" has CI enabled - Given project "Shop" has CI build - And I visit project "Shop" page - And I should see last commit with CI status - - @javascript - Scenario: I should see project activity - When I visit project "Shop" activity page - Then I should see project "Shop" activity feed - - Scenario: I visit edit project - When I visit edit project "Shop" page - Then I should see project settings - - Scenario: I edit project - When I visit edit project "Shop" page - And change project settings - And I save project - Then I should see project with new settings - - Scenario: I change project path - When I visit edit project "Shop" page - And change project path settings - Then I should see project with new path settings - - Scenario: I should change project default branch - When I visit edit project "Shop" page - And change project default branch - And I save project - Then I should see project default branch changed - - Scenario: I tag a project - When I visit edit project "Shop" page - Then I should see project settings - And I add project tags - And I save project - Then I should see project tags - - Scenario: I should not see "New Issue" or "New Merge Request" buttons - Given I disable issues and merge requests in project - When I visit project "Shop" page - Then I should not see "New Issue" button - And I should not see "New Merge Request" button - - Scenario: I should not see Project snippets - Given I disable snippets in project - When I visit project "Shop" page - Then I should not see "Snippets" button - - @javascript - Scenario: I edit Project Notifications - Given I click notifications drop down button - When I choose Mention setting - Then I should see Notification saved message - - Scenario: I should see command line instructions - Given I own an empty project - And I visit my empty project page - And I create bare repo - Then I should see command line instructions diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb deleted file mode 100644 index bba30a72325..00000000000 --- a/features/steps/project/project.rb +++ /dev/null @@ -1,154 +0,0 @@ -class Spinach::Features::Project < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include WaitForRequests - - step 'change project settings' do - fill_in 'project_name_edit', with: 'NewName' - end - - step 'I save project' do - page.within '.general-settings' do - click_button 'Save changes' - end - end - - step 'I should see project with new settings' do - expect(find_field('project_name').value).to eq 'NewName' - end - - step 'change project path settings' do - fill_in 'project_path', with: 'new-path' - click_button 'Rename' - end - - step 'I should see project with new path settings' do - expect(project.path).to eq 'new-path' - end - - step 'I change the project avatar' do - attach_file( - :project_avatar, - File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') - ) - page.within '.general-settings' do - click_button 'Save changes' - end - @project.reload - end - - step 'I should see new project avatar' do - expect(@project.avatar).to be_instance_of AvatarUploader - url = @project.avatar.url - expect(url).to eq "/uploads/-/system/project/avatar/#{@project.id}/banana_sample.gif" - end - - step 'I should see the "Remove avatar" button' do - expect(page).to have_link('Remove avatar') - end - - step 'I have an project avatar' do - attach_file( - :project_avatar, - File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') - ) - page.within '.general-settings' do - click_button 'Save changes' - end - @project.reload - end - - step 'I remove my project avatar' do - click_link 'Remove avatar' - @project.reload - end - - step 'I should see the default project avatar' do - expect(@project.avatar?).to eq false - end - - step 'I should not see the "Remove avatar" button' do - expect(page).not_to have_link('Remove avatar') - end - - step 'change project default branch' do - select 'fix', from: 'project_default_branch' - page.within '.general-settings' do - click_button 'Save changes' - end - end - - step 'I should see project default branch changed' do - expect(find(:css, 'select#project_default_branch').value).to eq 'fix' - end - - step 'I select project "Forum" README tab' do - click_link 'Readme' - end - - step 'I should see project "Forum" README' do - page.within('.readme-holder') do - expect(page).to have_content 'Sample repo for testing gitlab features' - end - end - - step 'I should see project "Shop" README' do - wait_for_requests - page.within('.readme-holder') do - expect(page).to have_content 'testme' - end - end - - step 'I add project tags' do - fill_in 'Tags', with: 'tag1, tag2' - end - - step 'I should see project tags' do - expect(find_field('Tags').value).to eq 'tag1, tag2' - end - - step 'I should not see "New Issue" button' do - expect(page).not_to have_link 'New Issue' - end - - step 'I should not see "New Merge Request" button' do - expect(page).not_to have_link 'New Merge Request' - end - - step 'I should not see "Snippets" button' do - page.within '.content' do - expect(page).not_to have_link 'Snippets' - end - end - - step 'project "Shop" belongs to group' do - group = create(:group) - @project.namespace = group - @project.save! - end - - step 'I click notifications drop down button' do - first('.notifications-btn').click - end - - step 'I choose Mention setting' do - click_link 'On mention' - end - - step 'I should see Notification saved message' do - page.within '#notifications-button' do - expect(page).to have_content 'On mention' - end - end - - step 'I create bare repo' do - click_link 'Create empty repository' - end - - step 'I should see command line instructions' do - page.within ".empty_wrapper" do - expect(page).to have_content("Command line instructions") - end - end -end diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index be848ebafa0..09969a6473f 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -25,72 +25,6 @@ module SharedProject @project.add_master(@user) end - step 'I disable snippets in project' do - @project.snippets_enabled = false - @project.save - end - - step 'I disable issues and merge requests in project' do - @project.issues_enabled = false - @project.merge_requests_enabled = false - @project.save - end - - # Add another user to project "Shop" - step 'I add a user to project "Shop"' do - @project = Project.find_by(name: "Shop") - other_user = create(:user, name: 'Alpha') - @project.add_master(other_user) - end - - # Create another specific project called "Forum" - step 'I own project "Forum"' do - @project = Project.find_by(name: "Forum") - @project ||= create(:project, :repository, name: "Forum", namespace: @user.namespace, path: 'forum_project') - @project.build_project_feature - @project.project_feature.save - @project.add_master(@user) - end - - # Create an empty project without caring about the name - step 'I own an empty project' do - @project = create(:project, name: 'Empty Project', namespace: @user.namespace) - @project.add_master(@user) - end - - step 'I visit my empty project page' do - project = Project.find_by(name: 'Empty Project') - visit project_path(project) - end - - step 'I visit project "Shop" activity page' do - project = Project.find_by(name: 'Shop') - visit project_path(project) - end - - step 'project "Shop" has push event' do - @project = Project.find_by(name: "Shop") - @event = create(:push_event, project: @project, author: @user) - - create(:push_event_payload, - event: @event, - action: :created, - commit_to: '6d394385cf567f80a8fd85055db1ab4c5295806f', - ref: 'fix', - commit_count: 1) - end - - step 'I should see project "Shop" activity feed' do - project = Project.find_by(name: "Shop") - expect(page).to have_content "#{@user.name} pushed new branch fix at #{project.full_name}" - end - - step 'I should see project settings' do - expect(current_path).to eq edit_project_path(@project) - expect(page).to have_content("Project name") - expect(page).to have_content("Permissions") - end - def current_project @project ||= Project.first end @@ -206,24 +140,6 @@ module SharedProject create(:label, project: project, title: 'enhancement') end - step 'project "Shop" has CI enabled' do - project = Project.find_by(name: "Shop") - project.enable_ci - end - - step 'project "Shop" has CI build' do - project = Project.find_by(name: "Shop") - pipeline = create :ci_pipeline, project: project, sha: project.commit.sha, ref: 'master' - pipeline.skip - end - - step 'I should see last commit with CI status' do - 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 - step 'The project is internal' do @project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL) 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..a1252a13260 --- /dev/null +++ b/spec/features/projects/activity/user_sees_activity_spec.rb @@ -0,0 +1,36 @@ +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 + + shared_examples 'push appears in activity' do + it 'shows the last push in the activity page', :js do + expect(page).to have_content "#{user.name} pushed new branch fix" + end + end + + context 'when signed in' do + before do + project.add_developer(user) + sign_in(user) + end + + it_behaves_like 'push appears in activity' + end + + context 'when signed out' do + it_behaves_like 'push appears in activity' + end +end diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb deleted file mode 100644 index bf55917bf4c..00000000000 --- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'rails_helper' - -feature 'Developer views empty project instructions' do - let(:project) { create(:project, :empty_repo) } - let(:developer) { create(:user) } - - background do - project.add_developer(developer) - - sign_in(developer) - end - - context 'without an SSH key' do - scenario 'defaults to HTTP' do - visit_project - - expect_instructions_for('http') - end - - scenario 'switches to SSH', :js do - visit_project - - select_protocol('SSH') - - expect_instructions_for('ssh') - end - end - - context 'with an SSH key' do - background do - create(:personal_key, user: developer) - end - - scenario 'defaults to SSH' do - visit_project - - expect_instructions_for('ssh') - end - - scenario 'switches to HTTP', :js do - visit_project - - select_protocol('HTTP') - - expect_instructions_for('http') - end - end - - def visit_project - visit project_path(project) - end - - def select_protocol(protocol) - find('#clone-dropdown').click - find(".#{protocol.downcase}-selector").click - end - - def expect_instructions_for(protocol) - msg = :"#{protocol.downcase}_url_to_repo" - - expect(page).to have_content("git clone #{project.send(msg)}") - end -end diff --git a/spec/features/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..10376afa009 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -1,7 +1,7 @@ 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) @@ -12,11 +12,11 @@ feature 'User wants to add a Dockerfile file' do visit project_new_blob_path(project, 'master', file_name: 'Dockerfile') end - scenario 'user can see Dockerfile dropdown' do + it 'user can see Dockerfile dropdown' do expect(page).to have_css('.dockerfile-selector') end - scenario 'user can pick a Dockerfile file from the dropdown', :js do + it '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..8c9252baf15 100644 --- a/spec/features/projects/files/download_buttons_spec.rb +++ b/spec/features/projects/files/download_buttons_spec.rb @@ -1,12 +1,12 @@ 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(:user) { create(:user) } + let(:role) { :developer } + let(:status) { 'success' } + let(:project) { create(:project, :repository) } - given(:pipeline) do + let(:pipeline) do create(:ci_pipeline, project: project, sha: project.commit.sha, @@ -14,14 +14,14 @@ feature 'Download buttons in files tree' do status: status) 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 @@ -32,7 +32,7 @@ feature 'Download buttons in files tree' do visit project_tree_path(project, project.default_branch) end - scenario 'shows download artifacts button' 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 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..556a5834a6d 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -1,6 +1,6 @@ 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) @@ -23,7 +23,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..14371c423b8 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -1,6 +1,6 @@ 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(:commit_params) do @@ -15,14 +15,14 @@ feature 'User wants to edit a file' do } end - background do + before do project.add_master(user) 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..143565013b0 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,6 +1,6 @@ require 'spec_helper' -feature 'User views files page' do +describe 'Projects > Files > User views files page' do let(:user) { create(:user) } let(:project) { create(:forked_project_with_submodules) } @@ -10,7 +10,7 @@ feature 'User views files page' do 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..e925203793a 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Find file keyboard shortcuts', :js do +describe 'Projects > Files > Find file keyboard shortcuts', :js do let(:user) { create(:user) } let(:project) { create(:project, :repository) } diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index 79f3fd09b48..4351e1c8d50 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -1,6 +1,6 @@ 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) @@ -9,11 +9,11 @@ feature 'User wants to add a .gitignore file' do visit project_new_blob_path(project, 'master', file_name: '.gitignore') end - scenario 'user can see .gitignore dropdown' do + it 'user can see .gitignore dropdown' do expect(page).to have_css('.gitignore-selector') end - scenario 'user can pick a .gitignore file from the dropdown', :js do + it 'user can pick a .gitignore file from the dropdown', :js do find('.js-gitignore-selector').click wait_for_requests within '.gitignore-selector' do 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..29ed37aa14e 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -1,6 +1,6 @@ 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) @@ -9,11 +9,11 @@ feature 'User wants to add a .gitlab-ci.yml file' do 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 see .gitlab-ci.yml dropdown' do expect(page).to have_css('.gitlab-ci-yml-selector') end - scenario 'user can pick a template from the dropdown', :js do + it '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 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..edf91f9ddbf 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,9 +1,10 @@ require 'spec_helper' -feature 'project owner creates a license file', :js do +describe 'Projects > Files > Project owner creates a license file', :js do let(:project_master) { create(:user) } let(:project) { create(:project, :repository) } - background do + + before do project.repository.delete_file(project_master, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') project.add_master(project_master) @@ -11,7 +12,7 @@ feature 'project owner creates a license file', :js do 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 +36,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..7f7244cd3e3 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,15 @@ require 'spec_helper' -feature 'project owner sees a link to create a license file in empty project', :js do +describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do let(:project_master) { create(:user) } let(:project) { create(:project_empty_repo) } - background do + before do project.add_master(project_master) 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_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 97408a9c41e..43f476553b1 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -1,6 +1,6 @@ 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) } @@ -14,16 +14,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 +34,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 +51,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 +64,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 +82,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..bf8fc6d37d2 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -1,6 +1,6 @@ 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) } @@ -15,7 +15,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 +27,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/files/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 new file mode 100644 index 00000000000..8f5422d6b63 --- /dev/null +++ b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +# This is a regression test for https://gitlab.com/gitlab-org/gitlab-ce/issues/37569 +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 } + + before do + # We need to disable the tree.flat_path provided by Gitaly to reproduce the issue + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) + + project.repository.create_dir(user, 'foo/bar', branch_name: 'master', message: 'Add the foo/bar folder') + sign_in(user) + visit(project_tree_path(project, project.repository.root_ref)) + end + + it 'shows the nested folder on a single row' do + expect(page).to have_content('foo/bar') + end +end diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb new file mode 100644 index 00000000000..b8432470813 --- /dev/null +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -0,0 +1,154 @@ +require 'spec_helper' + +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." + end + let(:project) { create(:project, :repository, name: 'Shop') } + let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } + 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) { project.creator } + + 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) + end + + it 'shows files from a repository' do + expect(page).to have_content('VERSION') + expect(page).to have_content('.gitignore') + expect(page).to have_content('LICENSE') + end + + it 'shows the "Browse Directory" link' do + click_link('files') + click_link('History') + + expect(page).to have_link('Browse Directory') + expect(page).not_to have_link('Browse Code') + end + + it 'shows the "Browse File" link' do + page.within('.tree-table') do + click_link('README.md') + end + click_link('History') + + expect(page).to have_link('Browse File') + expect(page).not_to have_link('Browse Files') + end + + it 'shows the "Browse Files" link' do + click_link('History') + + expect(page).to have_link('Browse Files') + expect(page).not_to have_link('Browse Directory') + end + + it 'redirects to the permalink URL' do + click_link('.gitignore') + click_link('Permalink') + + permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore") + + expect(current_path).to eq(permalink_path) + end + end + + context 'when browsing a specific ref' do + before do + visit(tree_path_ref_6d39438) + end + + it 'shows files from a repository for "6d39438"' do + expect(current_path).to eq(tree_path_ref_6d39438) + expect(page).to have_content('.gitignore') + expect(page).to have_content('LICENSE') + end + + it 'shows files from a repository with apostroph in its name', :js do + first('.js-project-refs-dropdown').click + + page.within('.project-refs-form') do + click_link("'test'") + end + + expect(page).to have_selector('.dropdown-toggle-text', text: "'test'") + + visit(project_tree_path(project, "'test'")) + + expect(page).to have_css('.tree-commit-link', visible: true) + expect(page).not_to have_content('Loading commit data...') + end + + it 'shows the code with a leading dot in the directory', :js do + first('.js-project-refs-dropdown').click + + page.within('.project-refs-form') do + click_link('fix') + end + + visit(project_tree_path(project, 'fix/.testdir')) + + expect(page).to have_css('.tree-commit-link', visible: true) + expect(page).not_to have_content('Loading commit data...') + end + + it 'does not show the permalink link' do + click_link('.gitignore') + + expect(page).not_to have_link('permalink') + end + end + + context 'when browsing a file content' do + before do + visit(tree_path_root_ref) + click_link('.gitignore') + end + + it 'shows a file content', :js 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 + before do + visit(project_blob_path(project, File.join(RepoHelpers.sample_commit.id, RepoHelpers.sample_blob.path))) + end + + it 'shows a raw file content' do + click_link('Open raw') + expect(source).to eq('') # Body is filled in by gitlab-workhorse + 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..f321d7f322e --- /dev/null +++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe 'Projects > Files > User browses LFS files' do + let(:project) { create(:project, :repository) } + let(:user) { project.creator } + + before do + project.add_master(user) + 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/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb new file mode 100644 index 00000000000..847b5f0860f --- /dev/null +++ b/spec/features/projects/files/user_creates_directory_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +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." + end + let(:project) { create(:project, :repository) } + let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } + let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } + let(:user) { create(:user) } + + before do + project.add_developer(user) + sign_in(user) + visit project_tree_path(project, 'master') + end + + context 'with default target branch' do + before do + first('.add-to-tree').click + click_link('New directory') + end + + it 'creates the directory in the default branch' do + fill_in(:dir_name, with: 'new_directory') + click_button('Create directory') + + expect(page).to have_content('master') + expect(page).to have_content('The directory has been successfully created') + expect(page).to have_content('new_directory') + end + + it 'does not create a directory with a name of already existed directory' do + fill_in(:dir_name, with: 'files') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Create directory') + + expect(page).to have_content('A directory with this name already exists') + expect(current_path).to eq(project_tree_path(project, 'master')) + end + end + + context 'with a new target branch' do + before do + first('.add-to-tree').click + click_link('New directory') + fill_in(:dir_name, with: 'new_directory') + fill_in(:branch_name, with: 'new-feature') + click_button('Create directory') + end + + it 'creates the directory in the new branch and redirect to the merge request' do + expect(page).to have_content('new-feature') + expect(page).to have_content('The directory has been successfully created') + expect(page).to have_content('New Merge Request') + expect(page).to have_content('From new-feature into master') + expect(page).to have_content('Add new directory') + + expect(current_path).to eq(project_new_merge_request_path(project)) + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'creates a directory in a forked project' do + find('.add-to-tree').click + click_link('New directory') + + expect(page).to have_content(fork_message) + + find('.add-to-tree').click + click_link('New directory') + fill_in(:dir_name, with: 'new_directory') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Create directory') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + end + end +end diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb new file mode 100644 index 00000000000..208cc8d81f7 --- /dev/null +++ b/spec/features/projects/files/user_creates_files_spec.rb @@ -0,0 +1,190 @@ +require 'spec_helper' + +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." + end + let(:project) { create(:project, :repository, name: 'Shop') } + 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) } + + before do + project.add_master(user) + sign_in(user) + end + + context 'without commiting a new file' do + context 'when an user has write access' do + before do + visit(project_tree_path_root_ref) + end + + it 'opens new file page' do + find('.add-to-tree').click + click_link('New file') + + expect(page).to have_content('New file') + expect(page).to have_content('Commit message') + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'opens new file page on a forked project' do + find('.add-to-tree').click + click_link('New file') + + expect(page).to have_selector('.file-editor') + expect(page).to have_content(fork_message) + expect(page).to have_content('New file') + expect(page).to have_content('Commit message') + end + end + end + + context 'with commiting a new file' do + context 'when an user has write access' do + before do + visit(project_tree_path_root_ref) + + find('.add-to-tree').click + click_link('New file') + 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')") + fill_in(:file_name, with: 'not_a_file.md') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + new_file_path = project_blob_path(project, 'master/not_a_file.md') + + expect(current_path).to eq(new_file_path) + + wait_for_requests + + expect(page).to have_content('*.rbca') + end + + it 'creates and commit a new file with new lines at the end of file', :js do + find('#editor') + execute_script('ace.edit("editor").setValue("Sample\n\n\n")') + fill_in(:file_name, with: 'not_a_file.md') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + new_file_path = project_blob_path(project, 'master/not_a_file.md') + + expect(current_path).to eq(new_file_path) + + find('.js-edit-blob').click + + find('#editor') + expect(evaluate_script('ace.edit("editor").getValue()')).to eq("Sample\n\n\n") + end + + it 'creates and commit a new file with a directory name', :js do + fill_in(:file_name, with: 'foo/bar/baz.txt') + + expect(page).to have_selector('.file-editor') + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + expect(current_path).to eq(project_blob_path(project, 'master/foo/bar/baz.txt')) + + wait_for_requests + + expect(page).to have_content('*.rbca') + end + + it 'creates and commit a new file specifying a new branch', :js do + expect(page).to have_selector('.file-editor') + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:file_name, with: 'not_a_file.md') + fill_in(:commit_message, with: 'New commit message', visible: true) + fill_in(:branch_name, with: 'new_branch_name', visible: true) + click_button('Commit changes') + + expect(current_path).to eq(project_new_merge_request_path(project)) + + click_link('Changes') + + wait_for_requests + + expect(page).to have_content('*.rbca') + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + + find('.add-to-tree').click + click_link('New file') + end + + it 'shows a message saying the file will be committed in a fork' do + message = "A new branch will be created in your fork and a new merge request will be started." + + expect(page).to have_content(message) + end + + it 'creates and commit new file in forked project', :js do + expect(page).to have_selector('.file-editor') + expect(page).to have_content + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + + fill_in(:file_name, with: 'not_a_file.md') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + expect(page).to have_content('New commit message') + end + end + end +end diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb new file mode 100644 index 00000000000..36d3e001a64 --- /dev/null +++ b/spec/features/projects/files/user_deletes_files_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +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." + end + let(:project) { create(:project, :repository, name: 'Shop') } + 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) } + + before do + sign_in(user) + end + + context 'when an user has write access' do + before do + project.add_master(user) + visit(project_tree_path_root_ref) + end + + it 'deletes the file', :js do + click_link('.gitignore') + + expect(page).to have_content('.gitignore') + + click_on('Delete') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Delete file') + + expect(current_path).to eq(project_tree_path(project, 'master')) + expect(page).not_to have_content('.gitignore') + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'deletes the file in a forked project', :js do + click_link('.gitignore') + + expect(page).to have_content('.gitignore') + + click_on('Delete') + + expect(page).to have_link('Fork') + expect(page).to have_button('Cancel') + + click_link('Fork') + + expect(page).to have_content(fork_message) + + click_on('Delete') + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Delete file') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + expect(page).to have_content('New commit message') + end + end +end diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb new file mode 100644 index 00000000000..523a9f3f4fe --- /dev/null +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -0,0 +1,173 @@ +require 'spec_helper' + +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') } + 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) } + + before do + sign_in(user) + end + + context 'when an user has write access' do + before do + project.add_master(user) + visit(project_tree_path_root_ref) + end + + it 'inserts a content of a file', :js do + click_link('.gitignore') + find('.js-edit-blob').click + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + + expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + end + + it 'does not show the edit link if a file is binary' do + binary_file = File.join(project.repository.root_ref, 'files/images/logo-black.png') + visit(project_blob_path(project, binary_file)) + + page.within '.content' do + expect(page).not_to have_link('edit') + end + end + + it 'commits an edited file', :js do + click_link('.gitignore') + find('.js-edit-blob').click + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + expect(current_path).to eq(project_blob_path(project, 'master/.gitignore')) + + wait_for_requests + + expect(page).to have_content('*.rbca') + end + + it 'commits an edited file to a new branch', :js do + click_link('.gitignore') + find('.js-edit-blob').click + + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:commit_message, with: 'New commit message', visible: true) + fill_in(:branch_name, with: 'new_branch_name', visible: true) + click_button('Commit changes') + + expect(current_path).to eq(project_new_merge_request_path(project)) + + click_link('Changes') + + expect(page).to have_content('*.rbca') + end + + it 'shows the diff of an edited file', :js do + click_link('.gitignore') + find('.js-edit-blob').click + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + click_link('Preview changes') + + expect(page).to have_css('.line_holder.new') + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'inserts a content of a file in a forked project', :js do + click_link('.gitignore') + find('.js-edit-blob').click + + expect(page).to have_link('Fork') + expect(page).to have_button('Cancel') + + click_link('Fork') + + expect(page).to have_content( + "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." + ) + + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + + expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + end + + it 'commits an edited file in a forked project', :js do + click_link('.gitignore') + find('.js-edit-blob').click + + expect(page).to have_link('Fork') + expect(page).to have_button('Cancel') + + click_link('Fork') + + find('.file-editor', match: :first) + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:commit_message, with: 'New commit message', visible: true) + click_button('Commit changes') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + + wait_for_requests + + expect(page).to have_content('New commit message') + end + + context 'when the user already had a fork of the project', :js do + let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) } + before do + visit(project2_tree_path_root_ref) + end + + it 'links to the forked project for editing' do + click_link('.gitignore') + find('.js-edit-blob').click + + expect(page).not_to have_link('Fork') + expect(page).not_to have_button('Cancel') + + find('#editor') + execute_script("ace.edit('editor').setValue('*.rbca')") + fill_in(:commit_message, with: 'Another commit', visible: true) + click_button('Commit changes') + + fork = user.fork_of(project2) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + + wait_for_requests + + expect(page).to have_content('Another commit') + expect(page).to have_content("From #{forked_project.full_path}") + expect(page).to have_content("into #{project2.full_path}") + end + end + end +end diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb new file mode 100644 index 00000000000..9ac3417b671 --- /dev/null +++ b/spec/features/projects/files/user_replaces_files_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +describe 'Projects > Files > User replaces files' do + include DropzoneHelper + + 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." + end + let(:project) { create(:project, :repository, name: 'Shop') } + 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) } + + before do + sign_in(user) + end + + context 'when an user has write access' do + before do + project.add_master(user) + visit(project_tree_path_root_ref) + end + + it 'replaces an existed file with a new one', :js do + click_link('.gitignore') + + expect(page).to have_content('.gitignore') + + click_on('Replace') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'Replacement file commit message') + end + + click_button('Replace file') + + expect(page).to have_content('Lorem ipsum dolor sit amet') + expect(page).to have_content('Sed ut perspiciatis unde omnis') + expect(page).to have_content('Replacement file commit message') + end + end + + context 'when an user does not have write access' do + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'replaces an existed file with a new one in a forked project', :js do + click_link('.gitignore') + + expect(page).to have_content('.gitignore') + + click_on('Replace') + + expect(page).to have_link('Fork') + expect(page).to have_button('Cancel') + + click_link('Fork') + + expect(page).to have_content(fork_message) + + click_on('Replace') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'Replacement file commit message') + end + + click_button('Replace file') + + expect(page).to have_content('Replacement file commit message') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + + click_link('Changes') + + expect(page).to have_content('Lorem ipsum dolor sit amet') + expect(page).to have_content('Sed ut perspiciatis unde omnis') + end + end +end 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..282806567ce 100644 --- a/spec/features/projects/files/user_searches_for_files_spec.rb +++ b/spec/features/projects/files/user_searches_for_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User searches for files' do +describe 'Projects > Files > User searches for files' do let(:user) { create(:user) } let(:project) { create(:project, :repository) } diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb new file mode 100644 index 00000000000..7a1e3a8bcce --- /dev/null +++ b/spec/features/projects/files/user_uploads_files_spec.rb @@ -0,0 +1,105 @@ +require 'spec_helper' + +describe 'Projects > Files > User uploads files' do + include DropzoneHelper + + 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." + end + let(:project) { create(:project, :repository, name: 'Shop') } + 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) { project.creator } + + before do + project.add_master(user) + sign_in(user) + end + + context 'when an user has write access' do + before do + visit(project_tree_path_root_ref) + end + + 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')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + end + + fill_in(:branch_name, with: 'new_branch_name', visible: true) + click_button('Upload file') + + expect(page).to have_content('New commit message') + expect(current_path).to eq(project_new_merge_request_path(project)) + + click_link('Changes') + find("a[data-action='diffs']", text: 'Changes').click + + wait_for_requests + + 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 + before do + project2.add_reporter(user) + visit(project2_tree_path_root_ref) + end + + it 'uploads and commit a new file to a forked project', :js do + find('.add-to-tree').click + click_link('Upload file') + + expect(page).to have_content(fork_message) + + find('.add-to-tree').click + click_link('Upload file') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + end + + click_button('Upload file') + + expect(page).to have_content('New commit message') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + + find("a[data-action='diffs']", text: 'Changes').click + + wait_for_requests + + expect(page).to have_content('Lorem ipsum dolor sit amet') + expect(page).to have_content('Sed ut perspiciatis unde omnis') + end + end +end 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/main/download_buttons_spec.rb b/spec/features/projects/main/download_buttons_spec.rb deleted file mode 100644 index 81f08e44cf3..00000000000 --- a/spec/features/projects/main/download_buttons_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'spec_helper' - -feature 'Download buttons in project main page' do - given(:user) { create(:user) } - given(:role) { :developer } - given(:status) { 'success' } - given(:project) { create(:project, :repository) } - - given(:pipeline) do - create(:ci_pipeline, - project: project, - sha: project.commit.sha, - ref: project.default_branch, - status: status) - end - - given!(:build) do - create(:ci_build, :success, :artifacts, - pipeline: pipeline, - status: pipeline.status, - name: 'build') - end - - background do - sign_in(user) - project.add_role(user, role) - end - - describe 'when checking project main page' do - context 'with artifacts' do - before do - visit project_path(project) - end - - scenario '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 - - scenario 'download links have download attribute' do - expect(page).to have_selector('a', text: 'Download') - page.all('a', text: 'Download').each do |link| - expect(link[:download]).to eq '' - end - end - end - end -end diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb deleted file mode 100644 index 3c98c11b490..00000000000 --- a/spec/features/projects/main/rss_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' - -feature 'Project RSS' do - let(:user) { create(:user) } - let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { project_path(project) } - - context 'when signed in' do - before do - project.add_developer(user) - sign_in(user) - visit path - end - - it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" - end - - context 'when signed out' do - before do - visit path - end - - it_behaves_like "an autodiscoverable RSS feed without an RSS token" - end -end diff --git a/spec/features/projects/no_password_spec.rb b/spec/features/projects/no_password_spec.rb deleted file mode 100644 index b3b3212556c..00000000000 --- a/spec/features/projects/no_password_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'spec_helper' - -feature 'No Password Alert' do - let(:project) { create(:project, :repository, namespace: user.namespace) } - - context 'with internal auth enabled' do - before do - sign_in(user) - visit project_path(project) - end - - context 'when user has a password' do - let(:user) { create(:user) } - - it 'shows no alert' do - expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account" - end - end - - context 'when user has password automatically set' do - let(:user) { create(:user, password_automatically_set: true) } - - it 'shows a password alert' do - expect(page).to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account" - end - end - end - - context 'with internal auth disabled' do - let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') } - - before do - stub_application_setting(password_authentication_enabled_for_git?: false) - stub_omniauth_saml_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [mock_saml_config]) - end - - context 'when user has no personal access tokens' do - it 'has a personal access token alert' do - gitlab_sign_in_via('saml', user, 'my-uid') - visit project_path(project) - - expect(page).to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" - end - end - - context 'when user has a personal access token' do - it 'shows no alert' do - create(:personal_access_token, user: user) - gitlab_sign_in_via('saml', user, 'my-uid') - visit project_path(project) - - expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" - end - end - end - - context 'when user is ldap user' do - let(:user) { create(:omniauth_user, password_automatically_set: true) } - - before do - sign_in(user) - visit project_path(project) - end - - it 'shows no alert' do - expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you" - end - end -end 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/redirects_spec.rb b/spec/features/projects/redirects_spec.rb deleted file mode 100644 index d1d8ca07035..00000000000 --- a/spec/features/projects/redirects_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'spec_helper' - -describe 'Project redirects' do - let(:user) { create :user } - let(:public_project) { create :project, :public } - let(:private_project) { create :project, :private } - - before do - allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com') - end - - it 'shows public project page' do - visit project_path(public_project) - - page.within '.breadcrumbs .breadcrumb-item-text' do - expect(page).to have_content(public_project.name) - end - end - - it 'redirects to sign in page when project is private' do - visit project_path(private_project) - - expect(current_path).to eq(new_user_session_path) - end - - it 'redirects to sign in page when project does not exist' do - visit project_path(build(:project, :public)) - - expect(current_path).to eq(new_user_session_path) - end - - it 'redirects to public project page after signing in' do - visit project_path(public_project) - - first(:link, 'Sign in').click - - fill_in 'user_login', with: user.email - fill_in 'user_password', with: user.password - click_button 'Sign in' - - expect(status_code).to eq(200) - expect(current_path).to eq("/#{public_project.full_path}") - end - - it 'redirects to private project page after sign in' do - visit project_path(private_project) - - owner = private_project.owner - fill_in 'user_login', with: owner.email - fill_in 'user_password', with: owner.password - click_button 'Sign in' - - expect(status_code).to eq(200) - expect(current_path).to eq("/#{private_project.full_path}") - end - - context 'when signed in' do - before do - sign_in(user) - end - - it 'returns 404 status when project does not exist' do - visit project_path(build(:project, :public)) - - expect(status_code).to eq(404) - end - - it 'returns 404 when project is private' do - visit project_path(private_project) - - expect(status_code).to eq(404) - end - end -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..04d3f9e452c --- /dev/null +++ b/spec/features/projects/settings/lfs_settings_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe 'Projects > Settings > LFS settings' do + let(:admin) { create(:admin) } + let(:project) { create(:project) } + + context 'LFS enabled setting' do + before do + sign_in(admin) + end + + it 'displays the correct elements', :js 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/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb deleted file mode 100644 index 015db603d33..00000000000 --- a/spec/features/projects/settings/merge_requests_settings_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'spec_helper' - -feature 'Project settings > Merge Requests', :js do - let(:project) { create(:project, :public) } - let(:user) { create(:user) } - - background do - project.add_master(user) - sign_in(user) - 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 - - scenario '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') - - within('.sharing-permissions-form') do - find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click - find('input[value="Save changes"]').send_keys(:return) - end - - 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') - end - end - - context 'when Pipelines are initially disabled' 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 - 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') - - within('.sharing-permissions-form') do - find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click - find('input[value="Save changes"]').send_keys(:return) - end - - 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') - end - end - end - - context 'when Merge Request are initially disabled' 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 - 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') - - within('.sharing-permissions-form') do - find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click - find('input[value="Save changes"]').send_keys(:return) - end - - 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') - end - end - - describe 'Checkbox to enable merge request link' do - before do - visit edit_project_path(project) - end - - scenario '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 - uncheck('project_printing_merge_request_link_enabled') - within('.merge-request-settings-form') do - click_on('Save changes') - end - - # Wait for save to complete and page to reload - checkbox = find_field('project_printing_merge_request_link_enabled') - expect(checkbox).not_to be_checked - - project.reload - expect(project.printing_merge_request_link_enabled).to be(false) - 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/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index f2c371b7df5..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) diff --git a/spec/features/projects/settings/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb new file mode 100644 index 00000000000..38c8a8c2468 --- /dev/null +++ b/spec/features/projects/settings/user_archives_project_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +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) } + + it 'unarchives a project' do + expect(page).to have_content('Unarchive project') + + click_link('Unarchive') + + expect(page).not_to have_content('Archived project') + end + end + + context 'when a project is unarchived' do + let(:project) { create(:project, :repository, namespace: user.namespace) } + + it 'archives a project' do + expect(page).to have_content('Archive project') + + click_link('Archive') + + expect(page).to have_content('Archived') + end + end +end 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/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb new file mode 100644 index 00000000000..b6e65fcbda1 --- /dev/null +++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb @@ -0,0 +1,107 @@ +require 'spec_helper' + +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') } + + before do + sign_in(user) + 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 + + 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') + + within('.sharing-permissions-form') do + find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click + find('input[value="Save changes"]').send_keys(:return) + end + + 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') + end + end + + 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 + + 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') + + within('.sharing-permissions-form') do + find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click + find('input[value="Save changes"]').send_keys(:return) + end + + 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') + end + end + end + + 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 + + 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') + + within('.sharing-permissions-form') do + find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click + find('input[value="Save changes"]').send_keys(:return) + end + + 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') + end + end + + 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 + + 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') + end + + # Wait for save to complete and page to reload + checkbox = find_field('project_printing_merge_request_link_enabled') + expect(checkbox).not_to be_checked + + project.reload + expect(project.printing_merge_request_link_enabled).to be(false) + end + end +end 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/show/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb new file mode 100644 index 00000000000..8803b5222be --- /dev/null +++ b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +feature 'Projects > Show > Developer views empty project instructions' do + let(:project) { create(:project, :empty_repo) } + let(:developer) { create(:user) } + + background do + project.add_developer(developer) + + sign_in(developer) + end + + context 'without an SSH key' do + scenario 'defaults to HTTP' do + visit_project + + expect_instructions_for('http') + end + + scenario 'switches to SSH', :js do + visit_project + + select_protocol('SSH') + + expect_instructions_for('ssh') + end + end + + context 'with an SSH key' do + background do + create(:personal_key, user: developer) + end + + scenario 'defaults to SSH' do + visit_project + + expect_instructions_for('ssh') + end + + scenario 'switches to HTTP', :js do + visit_project + + select_protocol('HTTP') + + expect_instructions_for('http') + end + end + + def visit_project + visit project_path(project) + end + + def select_protocol(protocol) + find('#clone-dropdown').click + find(".#{protocol.downcase}-selector").click + end + + def expect_instructions_for(protocol) + msg = :"#{protocol.downcase}_url_to_repo" + + expect(page).to have_content("git clone #{project.send(msg)}") + end +end diff --git a/spec/features/projects/show/download_buttons_spec.rb b/spec/features/projects/show/download_buttons_spec.rb new file mode 100644 index 00000000000..254affd4a94 --- /dev/null +++ b/spec/features/projects/show/download_buttons_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +feature 'Projects > Show > Download buttons' do + given(:user) { create(:user) } + given(:role) { :developer } + given(:status) { 'success' } + given(:project) { create(:project, :repository) } + + given(:pipeline) do + create(:ci_pipeline, + project: project, + sha: project.commit.sha, + ref: project.default_branch, + status: status) + end + + given!(:build) do + create(:ci_build, :success, :artifacts, + pipeline: pipeline, + status: pipeline.status, + name: 'build') + end + + background do + sign_in(user) + project.add_role(user, role) + end + + describe 'when checking project main page' do + context 'with artifacts' do + before do + visit project_path(project) + end + + scenario '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 + + scenario 'download links have download attribute' do + expect(page).to have_selector('a', text: 'Download') + page.all('a', text: 'Download').each do |link| + expect(link[:download]).to eq '' + end + end + end + end +end diff --git a/spec/features/projects/show/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb new file mode 100644 index 00000000000..b3b3212556c --- /dev/null +++ b/spec/features/projects/show/no_password_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +feature 'No Password Alert' do + let(:project) { create(:project, :repository, namespace: user.namespace) } + + context 'with internal auth enabled' do + before do + sign_in(user) + visit project_path(project) + end + + context 'when user has a password' do + let(:user) { create(:user) } + + it 'shows no alert' do + expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account" + end + end + + context 'when user has password automatically set' do + let(:user) { create(:user, password_automatically_set: true) } + + it 'shows a password alert' do + expect(page).to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account" + end + end + end + + context 'with internal auth disabled' do + let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') } + + before do + stub_application_setting(password_authentication_enabled_for_git?: false) + stub_omniauth_saml_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [mock_saml_config]) + end + + context 'when user has no personal access tokens' do + it 'has a personal access token alert' do + gitlab_sign_in_via('saml', user, 'my-uid') + visit project_path(project) + + expect(page).to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" + end + end + + context 'when user has a personal access token' do + it 'shows no alert' do + create(:personal_access_token, user: user) + gitlab_sign_in_via('saml', user, 'my-uid') + visit project_path(project) + + expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" + end + end + end + + context 'when user is ldap user' do + let(:user) { create(:omniauth_user, password_automatically_set: true) } + + before do + sign_in(user) + visit project_path(project) + end + + it 'shows no alert' do + expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you" + end + end +end diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb new file mode 100644 index 00000000000..8d41c547d77 --- /dev/null +++ b/spec/features/projects/show/redirects_spec.rb @@ -0,0 +1,74 @@ +require 'spec_helper' + +describe 'Projects > Show > Redirects' do + let(:user) { create :user } + let(:public_project) { create :project, :public } + let(:private_project) { create :project, :private } + + before do + allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com') + end + + it 'shows public project page' do + visit project_path(public_project) + + page.within '.breadcrumbs .breadcrumb-item-text' do + expect(page).to have_content(public_project.name) + end + end + + it 'redirects to sign in page when project is private' do + visit project_path(private_project) + + expect(current_path).to eq(new_user_session_path) + end + + it 'redirects to sign in page when project does not exist' do + visit project_path(build(:project, :public)) + + expect(current_path).to eq(new_user_session_path) + end + + it 'redirects to public project page after signing in' do + visit project_path(public_project) + + first(:link, 'Sign in').click + + fill_in 'user_login', with: user.email + fill_in 'user_password', with: user.password + click_button 'Sign in' + + expect(status_code).to eq(200) + expect(current_path).to eq("/#{public_project.full_path}") + end + + it 'redirects to private project page after sign in' do + visit project_path(private_project) + + owner = private_project.owner + fill_in 'user_login', with: owner.email + fill_in 'user_password', with: owner.password + click_button 'Sign in' + + expect(status_code).to eq(200) + expect(current_path).to eq("/#{private_project.full_path}") + end + + context 'when signed in' do + before do + sign_in(user) + end + + it 'returns 404 status when project does not exist' do + visit project_path(build(:project, :public)) + + expect(status_code).to eq(404) + end + + it 'returns 404 when project is private' do + visit project_path(private_project) + + expect(status_code).to eq(404) + end + end +end diff --git a/spec/features/projects/show/rss_spec.rb b/spec/features/projects/show/rss_spec.rb new file mode 100644 index 00000000000..d02eaf34533 --- /dev/null +++ b/spec/features/projects/show/rss_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +feature 'Projects > Show > RSS' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { project_path(project) } + + context 'when signed in' do + before do + project.add_developer(user) + sign_in(user) + visit path + end + + it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "an autodiscoverable RSS feed without an RSS token" + end +end diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb new file mode 100644 index 00000000000..ba28c0e1b8a --- /dev/null +++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe 'Projects > Show > User interacts with project stars' do + let(:project) { create(:project, :public, :repository) } + + context 'when user is signed in', :js do + let(:user) { create(:user) } + + before do + sign_in(user) + visit(project_path(project)) + end + + it 'toggles the star' do + find('.star-btn').click + + expect(page).to have_css('.star-count', text: 1) + + find('.star-btn').click + + expect(page).to have_css('.star-count', text: 0) + end + end + + context 'when user is not signed in' do + before do + visit(project_path(project)) + end + + it 'does not allow to star a project' do + expect(page).not_to have_content('.toggle-star') + + find('.star-btn').click + + expect(current_path).to eq(new_user_session_path) + end + end +end 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..38b57fe2483 --- /dev/null +++ b/spec/features/projects/show/user_manages_notifications_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'Projects > Show > User manages notifications' do + let(:project) { create(:project, :public, :repository) } + + context 'when user is signed in', :js do + let(:user) { create(:user) } + + before do + sign_in(user) + 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 +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/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb new file mode 100644 index 00000000000..9a82fee1b5d --- /dev/null +++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb @@ -0,0 +1,172 @@ +require 'spec_helper' + +describe 'Projects > Show > User sees Git instructions' do + set(:user) { create(:user) } + + shared_examples_for 'redirects to the sign in page' do + it 'redirects to the sign in page' do + expect(current_path).to eq(new_user_session_path) + 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 } + + it 'shows details' do + expect(page).not_to have_content('Git global setup') + + page.all(:css, '.git-empty .clone').each do |element| + expect(element.text).to include(project.http_url_to_repo) + end + + expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key + end + end + + shared_examples_for 'shows details of non empty project' do + let(:user_has_ssh_key) { false } + + it 'shows details' do + page.within('.breadcrumbs .breadcrumb-item-text') do + expect(page).to have_content(project.title) + end + + expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key + end + 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) } + + context 'when not signed in' do + before do + visit(project_path(project)) + end + + include_examples 'shows details of empty project' + end + + context 'when signed in' do + before do + sign_in(user) + end + + context 'when user does not have ssh keys' do + before do + visit(project_path(project)) + end + + include_examples 'shows details of empty project' + end + + context 'when user has ssh keys' do + before do + create(:personal_key, user: user) + + visit(project_path(project)) + end + + include_examples 'shows details of empty project' do + let(:user_has_ssh_key) { true } + end + end + end + end + + context 'when project is not empty' do + set(:project) { create(:project, :public, :repository) } + + before do + visit(project_path(project)) + end + + context 'when not signed in' do + before do + allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com') + end + + include_examples 'shows details of non empty project' + end + + context 'when signed in' do + before do + sign_in(user) + end + + context 'when user does not have ssh keys' do + before do + visit(project_path(project)) + end + + include_examples 'shows details of non empty project' + end + + context 'when user has ssh keys' do + before do + create(:personal_key, user: user) + + visit(project_path(project)) + end + + include_examples 'shows details of non empty project' do + let(:user_has_ssh_key) { true } + end + end + end + end + end + + context 'when project is internal' do + set(:project) { create(:project, :internal, :repository) } + + context 'when not signed in' do + before do + visit(project_path(project)) + end + + include_examples 'redirects to the sign in page' + end + + context 'when signed in' do + before do + sign_in(user) + + visit(project_path(project)) + end + + include_examples 'shows details of non empty project' + end + end + + context 'when project is private' do + set(:project) { create(:project, :private) } + + before do + visit(project_path(project)) + end + + include_examples 'redirects to the sign in page' + end +end 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_archives_project_spec.rb b/spec/features/projects/user_archives_project_spec.rb deleted file mode 100644 index 72063d13c2a..00000000000 --- a/spec/features/projects/user_archives_project_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -describe 'User archives a project' do - let(:user) { create(:user) } - - before do - project.add_master(user) - - sign_in(user) - 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') - - click_link('Unarchive') - - expect(page).not_to have_content('Archived project') - end - end - - 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') - - click_link('Archive') - - expect(page).to have_content('Archived') - end - end -end diff --git a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb b/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb deleted file mode 100644 index a17e65cc5b9..00000000000 --- a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb +++ /dev/null @@ -1,20 +0,0 @@ -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 - let(:project) { create(:project, :empty_repo) } - let(:user) { project.creator } - - before do - # We need to disable the tree.flat_path provided by Gitaly to reproduce the issue - allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) - - project.repository.create_dir(user, 'foo/bar', branch_name: 'master', message: 'Add the foo/bar folder') - sign_in(user) - visit(project_tree_path(project, project.repository.root_ref)) - end - - it 'shows the nested folder on a single row' do - expect(page).to have_content('foo/bar') - end -end diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/user_browses_files_spec.rb deleted file mode 100644 index 62e6419cc42..00000000000 --- a/spec/features/projects/user_browses_files_spec.rb +++ /dev/null @@ -1,189 +0,0 @@ -require 'spec_helper' - -describe 'User browses files' do - include DropzoneHelper - - 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." - end - let(:project) { create(:project, :repository, name: 'Shop') } - let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } - 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) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when browsing the master branch' do - before do - visit(tree_path_root_ref) - end - - it 'shows files from a repository' do - expect(page).to have_content('VERSION') - expect(page).to have_content('.gitignore') - expect(page).to have_content('LICENSE') - end - - it 'shows the "Browse Directory" link' do - click_link('files') - click_link('History') - - expect(page).to have_link('Browse Directory') - expect(page).not_to have_link('Browse Code') - end - - it 'shows the "Browse File" link' do - page.within('.tree-table') do - click_link('README.md') - end - click_link('History') - - expect(page).to have_link('Browse File') - expect(page).not_to have_link('Browse Files') - end - - it 'shows the "Browse Code" link' do - click_link('History') - - expect(page).to have_link('Browse Files') - expect(page).not_to have_link('Browse Directory') - end - - it 'redirects to the permalink URL' do - click_link('.gitignore') - click_link('Permalink') - - permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore") - - expect(current_path).to eq(permalink_path) - end - end - - context 'when browsing a specific ref' do - before do - visit(tree_path_ref_6d39438) - end - - it 'shows files from a repository for "6d39438"' do - expect(current_path).to eq(tree_path_ref_6d39438) - expect(page).to have_content('.gitignore') - expect(page).to have_content('LICENSE') - end - - it 'shows files from a repository with apostroph in its name', :js do - first('.js-project-refs-dropdown').click - - page.within('.project-refs-form') do - click_link("'test'") - end - - expect(page).to have_selector('.dropdown-toggle-text', text: "'test'") - - visit(project_tree_path(project, "'test'")) - - expect(page).to have_css('.tree-commit-link', visible: true) - expect(page).not_to have_content('Loading commit data...') - end - - it 'shows the code with a leading dot in the directory', :js do - first('.js-project-refs-dropdown').click - - page.within('.project-refs-form') do - click_link('fix') - end - - visit(project_tree_path(project, 'fix/.testdir')) - - expect(page).to have_css('.tree-commit-link', visible: true) - expect(page).not_to have_content('Loading commit data...') - end - - it 'does not show the permalink link' do - click_link('.gitignore') - - expect(page).not_to have_link('permalink') - end - end - - context 'when browsing a file content' do - before do - visit(tree_path_root_ref) - click_link('.gitignore') - end - - it 'shows a file content', :js do - wait_for_requests - expect(page).to have_content('*.rbc') - end - end - - context 'when browsing a raw file' do - before do - visit(project_blob_path(project, File.join(RepoHelpers.sample_commit.id, RepoHelpers.sample_blob.path))) - end - - it 'shows a raw file content' do - click_link('Open raw') - 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/user_creates_directory_spec.rb b/spec/features/projects/user_creates_directory_spec.rb deleted file mode 100644 index 00e48f6fabd..00000000000 --- a/spec/features/projects/user_creates_directory_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'spec_helper' - -feature '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." - end - let(:project) { create(:project, :repository) } - let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } - let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } - let(:user) { create(:user) } - - before do - project.add_developer(user) - sign_in(user) - visit project_tree_path(project, 'master') - end - - context 'with default target branch' do - before do - first('.add-to-tree').click - click_link('New directory') - end - - it 'creates the directory in the default branch' do - fill_in(:dir_name, with: 'new_directory') - click_button('Create directory') - - expect(page).to have_content('master') - expect(page).to have_content('The directory has been successfully created') - expect(page).to have_content('new_directory') - end - - it 'does not create a directory with a name of already existed directory' do - fill_in(:dir_name, with: 'files') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Create directory') - - expect(page).to have_content('A directory with this name already exists') - expect(current_path).to eq(project_tree_path(project, 'master')) - end - end - - context 'with a new target branch' do - before do - first('.add-to-tree').click - click_link('New directory') - fill_in(:dir_name, with: 'new_directory') - fill_in(:branch_name, with: 'new-feature') - click_button('Create directory') - end - - it 'creates the directory in the new branch and redirect to the merge request' do - expect(page).to have_content('new-feature') - expect(page).to have_content('The directory has been successfully created') - expect(page).to have_content('New Merge Request') - expect(page).to have_content('From new-feature into master') - expect(page).to have_content('Add new directory') - - expect(current_path).to eq(project_new_merge_request_path(project)) - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'creates a directory in a forked project' do - find('.add-to-tree').click - click_link('New directory') - - expect(page).to have_content(fork_message) - - find('.add-to-tree').click - click_link('New directory') - fill_in(:dir_name, with: 'new_directory') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Create directory') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - end - end -end diff --git a/spec/features/projects/user_creates_files_spec.rb b/spec/features/projects/user_creates_files_spec.rb deleted file mode 100644 index 8993533676b..00000000000 --- a/spec/features/projects/user_creates_files_spec.rb +++ /dev/null @@ -1,165 +0,0 @@ -require 'spec_helper' - -describe '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." - end - let(:project) { create(:project, :repository, name: 'Shop') } - 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) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'without commiting a new file' do - context 'when an user has write access' do - before do - visit(project_tree_path_root_ref) - end - - it 'opens new file page' do - find('.add-to-tree').click - click_link('New file') - - expect(page).to have_content('New file') - expect(page).to have_content('Commit message') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'opens new file page on a forked project' do - find('.add-to-tree').click - click_link('New file') - - expect(page).to have_selector('.file-editor') - expect(page).to have_content(fork_message) - expect(page).to have_content('New file') - expect(page).to have_content('Commit message') - end - end - end - - context 'with commiting a new file' do - context 'when an user has write access' do - before do - visit(project_tree_path_root_ref) - - find('.add-to-tree').click - click_link('New file') - expect(page).to have_selector('.file-editor') - end - - it 'creates and commit a new file', :js do - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:file_name, with: 'not_a_file.md') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - new_file_path = project_blob_path(project, 'master/not_a_file.md') - - expect(current_path).to eq(new_file_path) - - wait_for_requests - - expect(page).to have_content('*.rbca') - end - - it 'creates and commit a new file with new lines at the end of file', :js do - find('#editor') - execute_script('ace.edit("editor").setValue("Sample\n\n\n")') - fill_in(:file_name, with: 'not_a_file.md') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - new_file_path = project_blob_path(project, 'master/not_a_file.md') - - expect(current_path).to eq(new_file_path) - - find('.js-edit-blob').click - - find('#editor') - expect(evaluate_script('ace.edit("editor").getValue()')).to eq("Sample\n\n\n") - end - - it 'creates and commit a new file with a directory name', :js do - fill_in(:file_name, with: 'foo/bar/baz.txt') - - expect(page).to have_selector('.file-editor') - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - expect(current_path).to eq(project_blob_path(project, 'master/foo/bar/baz.txt')) - - wait_for_requests - - expect(page).to have_content('*.rbca') - end - - it 'creates and commit a new file specifying a new branch', :js do - expect(page).to have_selector('.file-editor') - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:file_name, with: 'not_a_file.md') - fill_in(:commit_message, with: 'New commit message', visible: true) - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Commit changes') - - expect(current_path).to eq(project_new_merge_request_path(project)) - - click_link('Changes') - - wait_for_requests - - expect(page).to have_content('*.rbca') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - - find('.add-to-tree').click - click_link('New file') - end - - it 'shows a message saying the file will be committed in a fork' do - message = "A new branch will be created in your fork and a new merge request will be started." - - expect(page).to have_content(message) - end - - it 'creates and commit new file in forked project', :js do - expect(page).to have_selector('.file-editor') - expect(page).to have_content - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - - fill_in(:file_name, with: 'not_a_file.md') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - expect(page).to have_content('New commit message') - end - end - end -end diff --git a/spec/features/projects/user_deletes_files_spec.rb b/spec/features/projects/user_deletes_files_spec.rb deleted file mode 100644 index 9d55197e719..00000000000 --- a/spec/features/projects/user_deletes_files_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'spec_helper' - -describe '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." - end - let(:project) { create(:project, :repository, name: 'Shop') } - 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) } - - before do - sign_in(user) - end - - context 'when an user has write access' do - before do - project.add_master(user) - visit(project_tree_path_root_ref) - end - - it 'deletes the file', :js do - click_link('.gitignore') - - expect(page).to have_content('.gitignore') - - click_on('Delete') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Delete file') - - expect(current_path).to eq(project_tree_path(project, 'master')) - expect(page).not_to have_content('.gitignore') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'deletes the file in a forked project', :js do - click_link('.gitignore') - - expect(page).to have_content('.gitignore') - - click_on('Delete') - - expect(page).to have_link('Fork') - expect(page).to have_button('Cancel') - - click_link('Fork') - - expect(page).to have_content(fork_message) - - click_on('Delete') - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Delete file') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - expect(page).to have_content('New commit message') - end - end -end diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/user_edits_files_spec.rb deleted file mode 100644 index 05c2be473da..00000000000 --- a/spec/features/projects/user_edits_files_spec.rb +++ /dev/null @@ -1,173 +0,0 @@ -require 'spec_helper' - -describe 'User edits files' do - include ProjectForksHelper - let(:project) { create(:project, :repository, name: 'Shop') } - 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) } - - before do - sign_in(user) - end - - context 'when an user has write access' do - before do - project.add_master(user) - visit(project_tree_path_root_ref) - end - - it 'inserts a content of a file', :js do - click_link('.gitignore') - find('.js-edit-blob').click - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') - end - - it 'does not show the edit link if a file is binary' do - binary_file = File.join(project.repository.root_ref, 'files/images/logo-black.png') - visit(project_blob_path(project, binary_file)) - - page.within '.content' do - expect(page).not_to have_link('edit') - end - end - - it 'commits an edited file', :js do - click_link('.gitignore') - find('.js-edit-blob').click - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - expect(current_path).to eq(project_blob_path(project, 'master/.gitignore')) - - wait_for_requests - - expect(page).to have_content('*.rbca') - end - - it 'commits an edited file to a new branch', :js do - click_link('.gitignore') - find('.js-edit-blob').click - - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:commit_message, with: 'New commit message', visible: true) - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Commit changes') - - expect(current_path).to eq(project_new_merge_request_path(project)) - - click_link('Changes') - - expect(page).to have_content('*.rbca') - end - - it 'shows the diff of an edited file', :js do - click_link('.gitignore') - find('.js-edit-blob').click - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - click_link('Preview changes') - - expect(page).to have_css('.line_holder.new') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'inserts a content of a file in a forked project', :js do - click_link('.gitignore') - find('.js-edit-blob').click - - expect(page).to have_link('Fork') - expect(page).to have_button('Cancel') - - click_link('Fork') - - expect(page).to have_content( - "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." - ) - - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') - end - - it 'commits an edited file in a forked project', :js do - click_link('.gitignore') - find('.js-edit-blob').click - - expect(page).to have_link('Fork') - expect(page).to have_button('Cancel') - - click_link('Fork') - - find('.file-editor', match: :first) - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:commit_message, with: 'New commit message', visible: true) - click_button('Commit changes') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - - wait_for_requests - - expect(page).to have_content('New commit message') - end - - context 'when the user already had a fork of the project', :js do - let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) } - before do - visit(project2_tree_path_root_ref) - end - - it 'links to the forked project for editing' do - click_link('.gitignore') - find('.js-edit-blob').click - - expect(page).not_to have_link('Fork') - expect(page).not_to have_button('Cancel') - - find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") - fill_in(:commit_message, with: 'Another commit', visible: true) - click_button('Commit changes') - - fork = user.fork_of(project2) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - - wait_for_requests - - expect(page).to have_content('Another commit') - expect(page).to have_content("From #{forked_project.full_path}") - expect(page).to have_content("into #{project2.full_path}") - end - end - end -end diff --git a/spec/features/projects/user_interacts_with_stars_spec.rb b/spec/features/projects/user_interacts_with_stars_spec.rb deleted file mode 100644 index d9d2e0ab171..00000000000 --- a/spec/features/projects/user_interacts_with_stars_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'spec_helper' - -describe 'User interacts with project stars' do - let(:project) { create(:project, :public, :repository) } - - context 'when user is signed in', :js do - let(:user) { create(:user) } - - before do - sign_in(user) - visit(project_path(project)) - end - - it 'toggles the star' do - find('.star-btn').click - - expect(page).to have_css('.star-count', text: 1) - - find('.star-btn').click - - expect(page).to have_css('.star-count', text: 0) - end - end - - context 'when user is not signed in' do - before do - visit(project_path(project)) - end - - it 'does not allow to star a project' do - expect(page).not_to have_content('.toggle-star') - - find('.star-btn').click - - expect(current_path).to eq(new_user_session_path) - end - end -end diff --git a/spec/features/projects/user_replaces_files_spec.rb b/spec/features/projects/user_replaces_files_spec.rb deleted file mode 100644 index 74872403b35..00000000000 --- a/spec/features/projects/user_replaces_files_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'spec_helper' - -describe 'User replaces files' do - include DropzoneHelper - - 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." - end - let(:project) { create(:project, :repository, name: 'Shop') } - 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) } - - before do - sign_in(user) - end - - context 'when an user has write access' do - before do - project.add_master(user) - visit(project_tree_path_root_ref) - end - - it 'replaces an existed file with a new one', :js do - click_link('.gitignore') - - expect(page).to have_content('.gitignore') - - click_on('Replace') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'Replacement file commit message') - end - - click_button('Replace file') - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') - expect(page).to have_content('Replacement file commit message') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'replaces an existed file with a new one in a forked project', :js do - click_link('.gitignore') - - expect(page).to have_content('.gitignore') - - click_on('Replace') - - expect(page).to have_link('Fork') - expect(page).to have_button('Cancel') - - click_link('Fork') - - expect(page).to have_content(fork_message) - - click_on('Replace') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'Replacement file commit message') - end - - click_button('Replace file') - - expect(page).to have_content('Replacement file commit message') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - - click_link('Changes') - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') - 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/projects/user_uploads_files_spec.rb b/spec/features/projects/user_uploads_files_spec.rb deleted file mode 100644 index 75898afcda9..00000000000 --- a/spec/features/projects/user_uploads_files_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'spec_helper' - -describe 'User uploads files' do - include DropzoneHelper - - 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." - end - let(:project) { create(:project, :repository, name: 'Shop') } - 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) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when an user has write access' do - before do - visit(project_tree_path_root_ref) - end - - it 'uploads and commit a new file', :js do - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - end - - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Upload file') - - expect(page).to have_content('New commit message') - expect(current_path).to eq(project_new_merge_request_path(project)) - - click_link('Changes') - find("a[data-action='diffs']", text: 'Changes').click - - wait_for_requests - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') - end - end - - context 'when an user does not have write access' do - before do - project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'uploads and commit a new file to a forked project', :js do - find('.add-to-tree').click - click_link('Upload file') - - expect(page).to have_content(fork_message) - - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - end - - click_button('Upload file') - - expect(page).to have_content('New commit message') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - - find("a[data-action='diffs']", text: 'Changes').click - - wait_for_requests - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') - end - end -end diff --git a/spec/features/projects/user_views_details_spec.rb b/spec/features/projects/user_views_details_spec.rb deleted file mode 100644 index ffc063654cd..00000000000 --- a/spec/features/projects/user_views_details_spec.rb +++ /dev/null @@ -1,151 +0,0 @@ -require 'spec_helper' - -describe 'User views details' do - set(:user) { create(:user) } - - shared_examples_for 'redirects to the sign in page' do - it 'redirects to the sign in page' do - expect(current_path).to eq(new_user_session_path) - end - end - - shared_examples_for 'shows details of empty project' do - let(:user_has_ssh_key) { false } - - it 'shows details' do - expect(page).not_to have_content('Git global setup') - - page.all(:css, '.git-empty .clone').each do |element| - expect(element.text).to include(project.http_url_to_repo) - end - - expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key - end - end - - shared_examples_for 'shows details of non empty project' do - let(:user_has_ssh_key) { false } - - it 'shows details' do - page.within('.breadcrumbs .breadcrumb-item-text') do - expect(page).to have_content(project.title) - end - - expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key - end - end - - context 'when project is public' do - context 'when project is empty' do - set(:project) { create(:project_empty_repo, :public) } - - context 'when not signed in' do - before do - visit(project_path(project)) - end - - include_examples 'shows details of empty project' - end - - context 'when signed in' do - before do - sign_in(user) - end - - context 'when user does not have ssh keys' do - before do - visit(project_path(project)) - end - - include_examples 'shows details of empty project' - end - - context 'when user has ssh keys' do - before do - create(:personal_key, user: user) - - visit(project_path(project)) - end - - include_examples 'shows details of empty project' do - let(:user_has_ssh_key) { true } - end - end - end - end - - context 'when project is not empty' do - set(:project) { create(:project, :public, :repository) } - - before do - visit(project_path(project)) - end - - context 'when not signed in' do - before do - allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com') - end - - include_examples 'shows details of non empty project' - end - - context 'when signed in' do - before do - sign_in(user) - end - - context 'when user does not have ssh keys' do - before do - visit(project_path(project)) - end - - include_examples 'shows details of non empty project' - end - - context 'when user has ssh keys' do - before do - create(:personal_key, user: user) - - visit(project_path(project)) - end - - include_examples 'shows details of non empty project' do - let(:user_has_ssh_key) { true } - end - end - end - end - end - - context 'when project is internal' do - set(:project) { create(:project, :internal, :repository) } - - context 'when not signed in' do - before do - visit(project_path(project)) - end - - include_examples 'redirects to the sign in page' - end - - context 'when signed in' do - before do - sign_in(user) - - visit(project_path(project)) - end - - include_examples 'shows details of non empty project' - end - end - - context 'when project is private' do - set(:project) { create(:project, :private) } - - before do - visit(project_path(project)) - end - - include_examples 'redirects to the sign in page' - end -end -- cgit v1.2.1