diff options
Diffstat (limited to 'spec/features')
92 files changed, 1754 insertions, 1180 deletions
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb index 9cb351282a0..430a8d22b0f 100644 --- a/spec/features/admin/admin_broadcast_messages_spec.rb +++ b/spec/features/admin/admin_broadcast_messages_spec.rb @@ -45,7 +45,7 @@ feature 'Admin Broadcast Messages' do page.within('.broadcast-message-preview') do expect(page).to have_selector('strong', text: 'Markdown') - expect(page).to have_selector('gl-emoji[data-name="tada"]') + expect(page).to have_emoji('tada') end end end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 986f864f0b5..257a3822503 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -89,7 +89,7 @@ feature 'Dashboard Projects' do end describe 'with a pipeline', :clean_gitlab_redis_shared_state do - let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) } + let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha, ref: project.default_branch) } before do # Since the cache isn't updated when a new pipeline is created @@ -102,7 +102,7 @@ feature 'Dashboard Projects' do visit dashboard_projects_path page.within('.controls') do - expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit)}']") + expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']") expect(page).to have_css('.ci-status-link') expect(page).to have_css('.ci-status-icon-success') expect(page).to have_link('Commit: passed') diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index 4ffadbbcd35..3a0424d60f8 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -98,7 +98,7 @@ feature 'Group show page' do it 'shows the project info' do expect(page).to have_content(project.title) - expect(page).to have_selector('gl-emoji[data-name="smile"]') + expect(page).to have_emoji('smile') end end end diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb index 2f24cfbd9e3..859a4c65562 100644 --- a/spec/features/merge_request/user_awards_emoji_spec.rb +++ b/spec/features/merge_request/user_awards_emoji_spec.rb @@ -35,6 +35,14 @@ describe 'Merge request > User awards emoji', :js do expect(page).to have_selector('.emoji-menu', count: 1) end + + describe 'the project is archived' do + let(:project) { create(:project, :public, :repository, :archived) } + + it 'does not see award menu button' do + expect(page).not_to have_selector('.js-award-holder') + end + end end describe 'logged out' do diff --git a/spec/features/merge_request/user_cherry_picks_spec.rb b/spec/features/merge_request/user_cherry_picks_spec.rb index 494096b21c0..61d1bdaa95a 100644 --- a/spec/features/merge_request/user_cherry_picks_spec.rb +++ b/spec/features/merge_request/user_cherry_picks_spec.rb @@ -40,6 +40,14 @@ describe 'Merge request > User cherry-picks', :js do expect(page).to have_link 'Cherry-pick' end + + it 'hides the cherry pick button for an archived project' do + project.update!(archived: true) + + visit project_merge_request_path(project, merge_request) + + expect(page).not_to have_link 'Cherry-pick' + end end end end diff --git a/spec/features/milestones/show_spec.rb b/spec/features/milestones/show_spec.rb deleted file mode 100644 index 50c5e0bb65f..00000000000 --- a/spec/features/milestones/show_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'rails_helper' - -describe 'Milestone show' do - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:milestone) { create(:milestone, project: project) } - let(:labels) { create_list(:label, 2, project: project) } - let(:issue_params) { { project: project, assignees: [user], author: user, milestone: milestone, labels: labels } } - - before do - project.add_user(user, :developer) - sign_in(user) - end - - def visit_milestone - visit project_milestone_path(project, milestone) - end - - it 'avoids N+1 database queries' do - create(:labeled_issue, issue_params) - control = ActiveRecord::QueryRecorder.new { visit_milestone } - create_list(:labeled_issue, 10, issue_params) - - expect { visit_milestone }.not_to exceed_query_limit(control) - end -end diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb new file mode 100644 index 00000000000..8fd057d587c --- /dev/null +++ b/spec/features/milestones/user_creates_milestone_spec.rb @@ -0,0 +1,29 @@ +require "rails_helper" + +describe "User creates milestone", :js do + set(:user) { create(:user) } + set(:project) { create(:project) } + + before do + project.add_developer(user) + sign_in(user) + + visit(new_project_milestone_path(project)) + end + + it "creates milestone" do + TITLE = "v2.3".freeze + + fill_in("Title", with: TITLE) + fill_in("Description", with: "# Description header") + click_button("Create milestone") + + expect(page).to have_content(TITLE) + .and have_content("Issues") + .and have_header_with_correct_id_and_link(1, "Description header", "description-header") + + visit(activity_project_path(project)) + + expect(page).to have_content("#{user.name} opened milestone") + end +end diff --git a/spec/features/milestones/user_deletes_milestone_spec.rb b/spec/features/milestones/user_deletes_milestone_spec.rb new file mode 100644 index 00000000000..414702daba4 --- /dev/null +++ b/spec/features/milestones/user_deletes_milestone_spec.rb @@ -0,0 +1,25 @@ +require "rails_helper" + +describe "User deletes milestone", :js do + set(:user) { create(:user) } + set(:project) { create(:project) } + set(:milestone) { create(:milestone, project: project) } + + before do + project.add_developer(user) + sign_in(user) + + visit(project_milestones_path(project)) + end + + it "deletes milestone" do + click_button("Delete") + click_button("Delete milestone") + + expect(page).to have_content("No milestones to show") + + visit(activity_project_path(project)) + + expect(page).to have_content("#{user.name} destroyed milestone") + end +end diff --git a/spec/features/milestones/user_views_milestone_spec.rb b/spec/features/milestones/user_views_milestone_spec.rb new file mode 100644 index 00000000000..83d8e2ff9e9 --- /dev/null +++ b/spec/features/milestones/user_views_milestone_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +describe "User views milestone" do + set(:user) { create(:user) } + set(:project) { create(:project) } + set(:milestone) { create(:milestone, project: project) } + set(:labels) { create_list(:label, 2, project: project) } + + before do + project.add_developer(user) + sign_in(user) + end + + it "avoids N+1 database queries" do + ISSUE_PARAMS = { project: project, assignees: [user], author: user, milestone: milestone, labels: labels }.freeze + + create(:labeled_issue, ISSUE_PARAMS) + + control = ActiveRecord::QueryRecorder.new { visit_milestone } + + create(:labeled_issue, ISSUE_PARAMS) + + expect { visit_milestone }.not_to exceed_query_limit(control) + end + + private + + def visit_milestone + visit(project_milestone_path(project, milestone)) + end +end diff --git a/spec/features/milestones/user_views_milestones_spec.rb b/spec/features/milestones/user_views_milestones_spec.rb new file mode 100644 index 00000000000..bebe40f73fd --- /dev/null +++ b/spec/features/milestones/user_views_milestones_spec.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +describe "User views milestones" do + set(:user) { create(:user) } + set(:project) { create(:project) } + set(:milestone) { create(:milestone, project: project) } + + before do + project.add_developer(user) + sign_in(user) + + visit(project_milestones_path(project)) + end + + it "shows milestone" do + expect(page).to have_content(milestone.title) + .and have_content(milestone.expires_at) + .and have_content("Issues") + end + + context "with issues" do + set(:issue) { create(:issue, project: project, milestone: milestone) } + set(:closed_issue) { create(:closed_issue, project: project, milestone: milestone) } + + it "opens milestone" do + click_link(milestone.title) + + expect(current_path).to eq(project_milestone_path(project, milestone)) + expect(page).to have_content(milestone.title) + .and have_selector("#tab-issues li.issuable-row", count: 2) + .and have_content(issue.title) + .and have_content(closed_issue.title) + end + end +end diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index 2693e539268..cd1cfe07998 100644 --- a/spec/features/projects/activity/rss_spec.rb +++ b/spec/features/projects/activity/rss_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' feature 'Project Activity RSS' do - let(:user) { create(:user) } - let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:project) { create(:project, :public) } + let(:user) { project.owner } let(:path) { activity_project_path(project) } before do @@ -11,8 +11,7 @@ feature 'Project Activity RSS' do context 'when signed in' do before do - project.add_developer(user) - sign_in(user) + sign_in(project.owner) visit path end diff --git a/spec/features/projects/activity/user_sees_activity_spec.rb b/spec/features/projects/activity/user_sees_activity_spec.rb new file mode 100644 index 00000000000..644a837dc14 --- /dev/null +++ b/spec/features/projects/activity/user_sees_activity_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +feature 'Projects > Activity > User sees activity' do + let(:project) { create(:project, :repository, :public) } + let(:user) { project.creator } + + before do + event = create(:push_event, project: project, author: user) + create(:push_event_payload, + event: event, + action: :created, + commit_to: '6d394385cf567f80a8fd85055db1ab4c5295806f', + ref: 'fix', + commit_count: 1) + visit activity_project_path(project) + end + + it 'shows the last push in the activity page', :js do + expect(page).to have_content "#{user.name} pushed new branch fix" + end +end diff --git a/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb index adff0a10f0e..12e07647ecd 100644 --- a/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb +++ b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb @@ -99,6 +99,74 @@ describe 'User interacts with awards in an issue', :js do click_button('Comment') end - expect(page).to have_selector('gl-emoji[data-name="smile"]') + expect(page).to have_emoji('smile') + end + + context 'when a project is archived' do + let(:project) { create(:project, :archived) } + + it 'hides the add award button' do + page.within('.awards') do + expect(page).not_to have_css('.js-add-award') + end + end + end + + context 'awards on a note' do + let!(:note) { create(:note, noteable: issue, project: issue.project) } + let!(:award_emoji) { create(:award_emoji, awardable: note, name: '100') } + + it 'shows the award on the note' do + page.within('.note-awards') do + expect(page).to have_emoji('100') + end + end + + it 'allows adding a vote to an award' do + page.within('.note-awards') do + find('gl-emoji[data-name="100"]').click + end + wait_for_requests + + expect(note.reload.award_emoji.size).to eq(2) + end + + it 'allows adding a new emoji' do + page.within('.note-actions') do + find('a.js-add-award').click + end + page.within('.emoji-menu-content') do + find('gl-emoji[data-name="8ball"]').click + end + wait_for_requests + + page.within('.note-awards') do + expect(page).to have_emoji('8ball') + end + expect(note.reload.award_emoji.size).to eq(2) + end + + context 'when the project is archived' do + let(:project) { create(:project, :archived) } + + it 'hides the buttons for adding new emoji' do + page.within('.note-awards') do + expect(page).not_to have_css('.award-menu-holder') + end + + page.within('.note-actions') do + expect(page).not_to have_css('a.js-add-award') + end + end + + it 'does not allow toggling existing emoji' do + page.within('.note-awards') do + find('gl-emoji[data-name="100"]').click + end + wait_for_requests + + expect(note.reload.award_emoji.size).to eq(1) + end + end end end diff --git a/spec/features/projects/branches/user_creates_branch_spec.rb b/spec/features/projects/branches/user_creates_branch_spec.rb new file mode 100644 index 00000000000..b706ad64954 --- /dev/null +++ b/spec/features/projects/branches/user_creates_branch_spec.rb @@ -0,0 +1,46 @@ +require "spec_helper" + +describe "User creates branch", :js do + include Spec::Support::Helpers::Features::BranchesHelpers + + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + + before do + project.add_developer(user) + sign_in(user) + + visit(new_project_branch_path(project)) + end + + it "creates new branch" do + BRANCH_NAME = "deploy_keys".freeze + + create_branch(BRANCH_NAME) + + expect(page).to have_content(BRANCH_NAME) + end + + context "when branch name is invalid" do + it "does not create new branch" do + INVALID_BRANCH_NAME = "1.0 stable".freeze + + fill_in("branch_name", with: INVALID_BRANCH_NAME) + page.find("body").click # defocus the branch_name input + + select_branch("master") + click_button("Create branch") + + expect(page).to have_content("Branch name is invalid") + expect(page).to have_content("can't contain spaces") + end + end + + context "when branch name already exists" do + it "does not create new branch" do + create_branch("master") + + expect(page).to have_content("Branch already exists") + end + end +end diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb new file mode 100644 index 00000000000..96f215e1606 --- /dev/null +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -0,0 +1,23 @@ +require "spec_helper" + +describe "User deletes branch", :js do + set(:user) { create(:user) } + set(:project) { create(:project, :repository) } + + before do + project.add_developer(user) + sign_in(user) + + visit(project_branches_path(project)) + end + + it "deletes branch" do + fill_in("branch-search", with: "improve/awesome").native.send_keys(:enter) + + page.within(".js-branch-improve\\/awesome") do + accept_alert { find(".btn-remove").click } + end + + expect(page).to have_css(".js-branch-improve\\/awesome", visible: :hidden) + end +end diff --git a/spec/features/projects/branches/user_views_branches_spec.rb b/spec/features/projects/branches/user_views_branches_spec.rb new file mode 100644 index 00000000000..62ae793151c --- /dev/null +++ b/spec/features/projects/branches/user_views_branches_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" + +describe "User views branches" do + set(:project) { create(:project, :repository) } + set(:user) { project.owner } + + before do + sign_in(user) + end + + context "all branches" do + before do + visit(project_branches_path(project)) + end + + it "shows branches" do + expect(page).to have_content("Branches").and have_content("master") + end + end + + context "protected branches" do + set(:protected_branch) { create(:protected_branch, project: project) } + + before do + visit(project_protected_branches_path(project)) + end + + it "shows branches" do + page.within(".protected-branches-list") do + expect(page).to have_content(protected_branch.name).and have_no_content("master") + end + end + end +end diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 2a9d9e6416c..b7ce1b9993a 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -195,6 +195,26 @@ describe 'Branches' do expect(page).to have_content("Protected branches can be managed in project settings") end end + + it 'shows the merge request button' do + visit project_branches_path(project) + + page.within first('.all-branches li') do + expect(page).to have_content 'Merge request' + end + end + + context 'when the project is archived' do + let(:project) { create(:project, :public, :repository, :archived) } + + it 'does not show the merge request button when the project is archived' do + visit project_branches_path(project) + + page.within first('.all-branches li') do + expect(page).not_to have_content 'Merge request' + end + end + end end context 'logged out' do @@ -204,7 +224,7 @@ describe 'Branches' do it 'does not show merge request button' do page.within first('.all-branches li') do - expect(page).not_to have_content 'Merge Request' + expect(page).not_to have_content 'Merge request' end end end diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index c4c399e3058..1df45865d6f 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -89,4 +89,15 @@ describe 'Cherry-pick Commits' do expect(page).to have_content('The commit has been successfully cherry-picked.') end end + + context 'when the project is archived' do + let(:project) { create(:project, :repository, :archived, namespace: group) } + + it 'does not show the cherry-pick link' do + find('.header-action-buttons a.dropdown-toggle').click + + expect(page).not_to have_text("Cherry-pick") + expect(page).not_to have_css("a[href='#modal-cherry-pick-commit']") + end + end end diff --git a/spec/features/projects/commit/user_reverts_commit_spec.rb b/spec/features/projects/commit/user_reverts_commit_spec.rb index 221f1d7757e..42844a03ea6 100644 --- a/spec/features/projects/commit/user_reverts_commit_spec.rb +++ b/spec/features/projects/commit/user_reverts_commit_spec.rb @@ -10,13 +10,16 @@ describe 'User reverts a commit', :js do sign_in(user) visit(project_commit_path(project, sample_commit.id)) + end + def click_revert find('.header-action-buttons .dropdown').click find('a[href="#modal-revert-commit"]').click end context 'without creating a new merge request' do before do + click_revert page.within('#modal-revert-commit') do uncheck('create_merge_request') click_button('Revert') @@ -44,6 +47,10 @@ describe 'User reverts a commit', :js do end context 'with creating a new merge request' do + before do + click_revert + end + it 'reverts a commit' do page.within('#modal-revert-commit') do click_button('Revert') @@ -53,4 +60,14 @@ describe 'User reverts a commit', :js do expect(page).to have_content("From revert-#{Commit.truncate_sha(sample_commit.id)} into master") end end + + context 'when the project is archived' do + let(:project) { create(:project, :repository, :archived, namespace: user.namespace) } + + it 'does not show the revert link' do + find('.header-action-buttons .dropdown').click + + expect(page).not_to have_link('Revert') + end + 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..004585f7c9e 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -1,22 +1,15 @@ require 'spec_helper' -require 'fileutils' -feature 'User wants to add a Dockerfile file' do +describe 'Projects > Files > User wants to add a Dockerfile file' do before do - user = create(:user) project = create(:project, :repository) - project.add_master(user) - - sign_in user - + sign_in project.owner visit project_new_blob_path(project, 'master', file_name: 'Dockerfile') end - scenario 'user can see Dockerfile dropdown' do + it 'user can pick a Dockerfile file from the dropdown', :js do expect(page).to have_css('.dockerfile-selector') - end - scenario 'user can pick a Dockerfile file from the dropdown', :js do find('.js-dockerfile-selector').click wait_for_requests diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb index 2101627f324..03cb3530e2b 100644 --- a/spec/features/projects/files/download_buttons_spec.rb +++ b/spec/features/projects/files/download_buttons_spec.rb @@ -1,42 +1,36 @@ require 'spec_helper' -feature 'Download buttons in files tree' do - given(:user) { create(:user) } - given(:role) { :developer } - given(:status) { 'success' } - given(:project) { create(:project, :repository) } +describe 'Projects > Files > Download buttons in files tree' do + let(:project) { create(:project, :repository) } + let(:user) { project.creator } - given(:pipeline) do + let(:pipeline) do create(:ci_pipeline, project: project, sha: project.commit.sha, ref: project.default_branch, - status: status) + status: 'success') end - given!(:build) do + let!(:build) do create(:ci_build, :success, :artifacts, pipeline: pipeline, status: pipeline.status, name: 'build') end - background do + before do sign_in(user) - project.add_role(user, role) - end + project.add_developer(user) - describe 'when files tree' do - context 'with artifacts' do - before do - visit project_tree_path(project, project.default_branch) - end + visit project_tree_path(project, project.default_branch) + end - scenario 'shows download artifacts button' do - href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build') + context 'with artifacts' do + it 'shows download artifacts button' do + href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build') - expect(page).to have_link "Download '#{build.name}'", href: href - end + expect(page).to have_link "Download '#{build.name}'", href: href end end end diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index 8d32ada5795..41af70d8ebc 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -1,10 +1,9 @@ require 'spec_helper' -feature 'User uses soft wrap whilst editing file', :js do +describe 'Projects > Files > User uses soft wrap whilst editing file', :js do before do - user = create(:user) project = create(:project, :repository) - project.add_master(user) + user = project.owner sign_in user visit project_new_blob_path(project, 'master', file_name: 'test_file-name') page.within('.file-editor.code') do @@ -23,7 +22,7 @@ feature 'User uses soft wrap whilst editing file', :js do let(:toggle_button) { find('.soft-wrap-toggle') } - scenario 'user clicks the "Soft wrap" button and then "No wrap" button' do + it 'user clicks the "Soft wrap" button and then "No wrap" button' do wrapped_content_width = get_content_width toggle_button.click expect(toggle_button).to have_content 'No wrap' diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index d874cdbff8d..4074e67e2d2 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -feature 'User wants to edit a file' do +describe 'Projects > Files > User wants to edit a file' do let(:project) { create(:project, :repository) } - let(:user) { create(:user) } + let(:user) { project.owner } let(:commit_params) do { start_branch: project.default_branch, @@ -15,14 +15,13 @@ feature 'User wants to edit a file' do } end - background do - project.add_master(user) + before do sign_in user visit project_edit_blob_path(project, File.join(project.default_branch, '.gitignore')) end - scenario 'file has been updated since the user opened the edit page' do + it 'file has been updated since the user opened the edit page' do Files::UpdateService.new(project, user, commit_params).execute click_button 'Commit changes' diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb index ead9f7e9168..b6dbf76bc9b 100644 --- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb +++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb @@ -1,16 +1,15 @@ require 'spec_helper' -feature 'User views files page' do - let(:user) { create(:user) } +describe 'Projects > Files > User views files page' do let(:project) { create(:forked_project_with_submodules) } + let(:user) { project.owner } before do - project.add_master(user) sign_in user visit project_tree_path(project, project.repository.root_ref) end - scenario 'user sees folders and submodules sorted together, followed by files' do + it 'user sees folders and submodules sorted together, followed by files' do rows = all('td.tree-item-file-name').map(&:text) tree = project.repository.tree diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb index e9ff06c72d8..cd0235f2b9e 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' -feature 'Find file keyboard shortcuts', :js do - let(:user) { create(:user) } +describe 'Projects > Files > Find file keyboard shortcuts', :js do let(:project) { create(:project, :repository) } + let(:user) { project.owner } before do - project.add_master(user) sign_in user visit project_find_file_path(project, project.repository.root_ref) diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index 79f3fd09b48..9fa4c053a40 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -1,25 +1,24 @@ require 'spec_helper' -feature 'User wants to add a .gitignore file' do +describe 'Projects > Files > User wants to add a .gitignore file' do before do - user = create(:user) project = create(:project, :repository) - project.add_master(user) - sign_in user + sign_in project.owner visit project_new_blob_path(project, 'master', file_name: '.gitignore') end - scenario 'user can see .gitignore dropdown' do + it 'user can pick a .gitignore file from the dropdown', :js do expect(page).to have_css('.gitignore-selector') - end - scenario 'user can pick a .gitignore file from the dropdown', :js do find('.js-gitignore-selector').click + wait_for_requests + within '.gitignore-selector' do find('.dropdown-input-field').set('rails') find('.dropdown-content li', text: 'Rails').click end + wait_for_requests expect(page).to have_css('.gitignore-selector .dropdown-toggle-text', text: 'Rails') diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index db6c67b802e..53aff183562 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -1,25 +1,24 @@ require 'spec_helper' -feature 'User wants to add a .gitlab-ci.yml file' do +describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do before do - user = create(:user) project = create(:project, :repository) - project.add_master(user) - sign_in user + sign_in project.owner visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml') end - scenario 'user can see .gitlab-ci.yml dropdown' do + it 'user can pick a template from the dropdown', :js do expect(page).to have_css('.gitlab-ci-yml-selector') - end - scenario 'user can pick a template from the dropdown', :js do find('.js-gitlab-ci-yml-selector').click + wait_for_requests + within '.gitlab-ci-yml-selector' do find('.dropdown-input-field').set('Jekyll') find('.dropdown-content li', text: 'Jekyll').click end + wait_for_requests expect(page).to have_css('.gitlab-ci-yml-selector .dropdown-toggle-text', text: 'Jekyll') diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 07599600876..b410199fd1f 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -1,17 +1,17 @@ require 'spec_helper' -feature 'project owner creates a license file', :js do - let(:project_master) { create(:user) } +describe 'Projects > Files > Project owner creates a license file', :js do let(:project) { create(:project, :repository) } - background do + let(:project_master) { project.owner } + + before do project.repository.delete_file(project_master, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') - project.add_master(project_master) sign_in(project_master) visit project_path(project) end - scenario 'project master creates a license file manually from a template' do + it 'project master creates a license file manually from a template' do visit project_tree_path(project, project.repository.root_ref) find('.add-to-tree').click click_link 'New file' @@ -35,7 +35,7 @@ feature 'project owner creates a license file', :js do expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end - scenario 'project master creates a license file from the "Add license" link' do + it 'project master creates a license file from the "Add license" link' do click_link 'Add License' expect(page).to have_content('New file') diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index 7f1d1934103..53d8ace7c94 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -1,15 +1,14 @@ require 'spec_helper' -feature 'project owner sees a link to create a license file in empty project', :js do - let(:project_master) { create(:user) } +describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do let(:project) { create(:project_empty_repo) } + let(:project_master) { project.owner } - background do - project.add_master(project_master) + before do sign_in(project_master) end - scenario 'project master creates a license file from a template' do + it 'project master creates a license file from a template' do visit project_path(project) click_on 'Add License' expect(page).to have_content('New file') diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 97408a9c41e..342a93b328f 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' -feature 'Template type dropdown selector', :js do +describe 'Projects > Files > Template type dropdown selector', :js do let(:project) { create(:project, :repository) } - let(:user) { create(:user) } + let(:user) { project.owner } before do - project.add_master(user) sign_in user end @@ -14,16 +13,16 @@ feature 'Template type dropdown selector', :js do create_and_edit_file('.random-file.js') end - scenario 'not displayed' do + it 'not displayed' do check_type_selector_display(false) end - scenario 'selects every template type correctly' do + it 'selects every template type correctly' do fill_in 'file_path', with: '.gitignore' try_selecting_all_types end - scenario 'updates toggle value when input matches' do + it 'updates toggle value when input matches' do fill_in 'file_path', with: '.gitignore' check_type_selector_toggle_text('.gitignore') end @@ -34,15 +33,15 @@ feature 'Template type dropdown selector', :js do visit project_edit_blob_path(project, File.join(project.default_branch, 'LICENSE')) end - scenario 'displayed' do + it 'displayed' do check_type_selector_display(true) end - scenario 'is displayed when input matches' do + it 'is displayed when input matches' do check_type_selector_display(true) end - scenario 'selects every template type correctly' do + it 'selects every template type correctly' do try_selecting_all_types end @@ -51,7 +50,7 @@ feature 'Template type dropdown selector', :js do click_link 'Preview changes' end - scenario 'type selector is hidden and shown correctly' do + it 'type selector is hidden and shown correctly' do check_type_selector_display(false) click_link 'Write' check_type_selector_display(true) @@ -64,15 +63,15 @@ feature 'Template type dropdown selector', :js do visit project_new_blob_path(project, 'master', file_name: '.gitignore') end - scenario 'is displayed' do + it 'is displayed' do check_type_selector_display(true) end - scenario 'toggle is set to the correct value' do + it 'toggle is set to the correct value' do check_type_selector_toggle_text('.gitignore') end - scenario 'selects every template type correctly' do + it 'selects every template type correctly' do try_selecting_all_types end end @@ -82,15 +81,15 @@ feature 'Template type dropdown selector', :js do visit project_new_blob_path(project, project.default_branch) end - scenario 'type selector is shown' do + it 'type selector is shown' do check_type_selector_display(true) end - scenario 'toggle is set to the proper value' do + it 'toggle is set to the proper value' do check_type_selector_toggle_text('Choose type') end - scenario 'selects every template type correctly' do + it 'selects every template type correctly' do try_selecting_all_types end end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index fbf35fb4e1c..5de0bc009fb 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' -feature 'Template Undo Button', :js do +describe 'Projects > Files > Template Undo Button', :js do let(:project) { create(:project, :repository) } - let(:user) { create(:user) } + let(:user) { project.owner } before do - project.add_master(user) sign_in user end @@ -15,7 +14,7 @@ feature 'Template Undo Button', :js do select_file_template('.js-license-selector', 'Apache License 2.0') end - scenario 'reverts template application' do + it 'reverts template application' do try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end @@ -27,7 +26,7 @@ feature 'Template Undo Button', :js do select_file_template('.js-license-selector', 'Apache License 2.0') end - scenario 'reverts template application' do + it 'reverts template application' do try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end diff --git a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb index a17e65cc5b9..2d67837763c 100644 --- a/spec/features/projects/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb +++ b/spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder.rb @@ -1,9 +1,9 @@ require 'spec_helper' # This is a regression test for https://gitlab.com/gitlab-org/gitlab-ce/issues/37569 -describe 'User browses a tree with a folder containing only a folder' do +describe 'Projects > Files > User browses a tree with a folder containing only a folder' do let(:project) { create(:project, :empty_repo) } - let(:user) { project.creator } + let(:user) { project.owner } before do # We need to disable the tree.flat_path provided by Gitaly to reproduce the issue diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 62e6419cc42..9c1f11f4c12 100644 --- a/spec/features/projects/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' -describe 'User browses files' do - include DropzoneHelper - +describe 'Projects > Files > User browses files' do let(:fork_message) do "You're not allowed to make changes to this project directly. "\ "A fork of this project has been created that you can make changes in, so you can submit a merge request." @@ -12,13 +10,24 @@ describe 'User browses files' do let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } let(:tree_path_ref_6d39438) { project_tree_path(project, '6d39438') } let(:tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) } - let(:user) { create(:user) } + let(:user) { project.owner } before do - project.add_master(user) sign_in(user) end + it 'shows last commit for current directory' do + visit(tree_path_root_ref) + + click_link 'files' + + last_commit = project.repository.last_commit_for_path(project.default_branch, 'files') + page.within('.blob-commit-info') do + expect(page).to have_content last_commit.short_id + expect(page).to have_content last_commit.author_name + end + end + context 'when browsing the master branch' do before do visit(tree_path_root_ref) @@ -48,7 +57,7 @@ describe 'User browses files' do expect(page).not_to have_link('Browse Files') end - it 'shows the "Browse Code" link' do + it 'shows the "Browse Files" link' do click_link('History') expect(page).to have_link('Browse Files') @@ -121,6 +130,14 @@ describe 'User browses files' do wait_for_requests expect(page).to have_content('*.rbc') end + + it 'is possible to blame' do + click_link 'Blame' + + expect(page).to have_content "*.rb" + expect(page).to have_content "Dmitriy Zaporozhets" + expect(page).to have_content "Initial commit" + end end context 'when browsing a raw file' do @@ -133,57 +150,4 @@ describe 'User browses files' do expect(source).to eq('') # Body is filled in by gitlab-workhorse end end - - context 'when browsing an LFS object' do - before do - allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true) - visit(project_tree_path(project, 'lfs')) - end - - it 'shows an LFS object' do - click_link('files') - click_link('lfs') - click_link('lfs_object.iso') - - expect(page).to have_content('Download (1.5 MB)') - expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1') - expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897') - expect(page).not_to have_content('size 1575078') - - page.within('.content') do - expect(page).to have_content('Delete') - expect(page).to have_content('History') - expect(page).to have_content('Permalink') - expect(page).to have_content('Replace') - expect(page).not_to have_content('Annotate') - expect(page).not_to have_content('Blame') - expect(page).not_to have_content('Edit') - expect(page).to have_link('Download') - end - end - end - - context 'when previewing a file content' do - before do - visit(tree_path_root_ref) - end - - it 'shows a preview of a file content', :js do - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Upload file') - end - - wait_for_all_requests - - visit(project_blob_path(project, 'new_branch_name/logo_sample.svg')) - - expect(page).to have_css('.file-content img') - end - end end diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb new file mode 100644 index 00000000000..c559a301ca1 --- /dev/null +++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe 'Projects > Files > User browses LFS files' do + let(:project) { create(:project, :repository) } + let(:user) { project.owner } + + before do + sign_in(user) + end + + context 'when LFS is disabled', :js do + before do + allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(false) + visit project_tree_path(project, 'lfs') + end + + it 'is possible to see raw content of LFS pointer' do + click_link 'files' + click_link 'lfs' + click_link 'lfs_object.iso' + + expect(page).to have_content 'version https://git-lfs.github.com/spec/v1' + expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' + expect(page).to have_content 'size 1575078' + expect(page).not_to have_content 'Download (1.5 MB)' + end + end + + context 'when LFS is enabled' do + before do + allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true) + visit project_tree_path(project, 'lfs') + end + + it 'shows an LFS object' do + click_link('files') + click_link('lfs') + click_link('lfs_object.iso') + + expect(page).to have_content('Download (1.5 MB)') + expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1') + expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897') + expect(page).not_to have_content('size 1575078') + + page.within('.content') do + expect(page).to have_content('Delete') + expect(page).to have_content('History') + expect(page).to have_content('Permalink') + expect(page).to have_content('Replace') + expect(page).not_to have_content('Annotate') + expect(page).not_to have_content('Blame') + expect(page).not_to have_content('Edit') + expect(page).to have_link('Download') + end + end + end +end diff --git a/spec/features/projects/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb index 00e48f6fabd..847b5f0860f 100644 --- a/spec/features/projects/user_creates_directory_spec.rb +++ b/spec/features/projects/files/user_creates_directory_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'User creates a directory', :js do +describe 'Projects > Files > User creates a directory', :js do let(:fork_message) do "You're not allowed to make changes to this project directly. "\ "A fork of this project has been created that you can make changes in, so you can submit a merge request." diff --git a/spec/features/projects/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb index 8993533676b..208cc8d81f7 100644 --- a/spec/features/projects/user_creates_files_spec.rb +++ b/spec/features/projects/files/user_creates_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User creates files' do +describe 'Projects > Files > User creates files' do let(:fork_message) do "You're not allowed to make changes to this project directly. "\ "A fork of this project has been created that you can make changes in, so you can submit a merge request." @@ -59,6 +59,31 @@ describe 'User creates files' do expect(page).to have_selector('.file-editor') end + def submit_new_file(options) + file_name = find('#file_name') + file_name.set options[:file_name] || 'README.md' + + file_content = find('#file-content', visible: false) + file_content.set options[:file_content] || 'Some content' + + click_button 'Commit changes' + end + + it 'allows Chinese characters in file name' do + submit_new_file(file_name: '测试.md') + expect(page).to have_content 'The file has been successfully created.' + end + + it 'allows Chinese characters in directory name' do + submit_new_file(file_name: '中文/测试.md') + expect(page).to have_content 'The file has been successfully created' + end + + it 'does not allow directory traversal in file name' do + submit_new_file(file_name: '../README.md') + expect(page).to have_content 'Path cannot include directory traversal' + end + it 'creates and commit a new file', :js do find('#editor') execute_script("ace.edit('editor').setValue('*.rbca')") diff --git a/spec/features/projects/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb index 9d55197e719..36d3e001a64 100644 --- a/spec/features/projects/user_deletes_files_spec.rb +++ b/spec/features/projects/files/user_deletes_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User deletes files' do +describe 'Projects > Files > User deletes files' do let(:fork_message) do "You're not allowed to make changes to this project directly. "\ "A fork of this project has been created that you can make changes in, so you can submit a merge request." diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index 05c2be473da..dc6e4fd27cb 100644 --- a/spec/features/projects/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User edits files' do +describe 'Projects > Files > User edits files' do include ProjectForksHelper let(:project) { create(:project, :repository, name: 'Shop') } let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } @@ -12,6 +12,23 @@ describe 'User edits files' do sign_in(user) end + shared_examples 'unavailable for an archived project' do + it 'does not show the edit link for an archived project', :js do + project.update!(archived: true) + visit project_tree_path(project, project.repository.root_ref) + + click_link('.gitignore') + + aggregate_failures 'available edit buttons' do + expect(page).not_to have_text('Edit') + expect(page).not_to have_text('Web IDE') + + expect(page).not_to have_text('Replace') + expect(page).not_to have_text('Delete') + end + end + end + context 'when an user has write access' do before do project.add_master(user) @@ -85,6 +102,8 @@ describe 'User edits files' do expect(page).to have_css('.line_holder.new') end + + it_behaves_like 'unavailable for an archived project' end context 'when an user does not have write access' do @@ -168,6 +187,10 @@ describe 'User edits files' do expect(page).to have_content("From #{forked_project.full_path}") expect(page).to have_content("into #{project2.full_path}") end + + it_behaves_like 'unavailable for an archived project' do + let(:project) { project2 } + end end end end diff --git a/spec/features/projects/files/user_reads_pipeline_status_spec.rb b/spec/features/projects/files/user_reads_pipeline_status_spec.rb new file mode 100644 index 00000000000..2fb9da2f0a2 --- /dev/null +++ b/spec/features/projects/files/user_reads_pipeline_status_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe 'user reads pipeline status', :js do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + let(:v110_pipeline) { create_pipeline('v1.1.0', 'success') } + let(:x110_pipeline) { create_pipeline('x1.1.0', 'failed') } + + before do + project.add_master(user) + + project.repository.add_tag(user, 'x1.1.0', 'v1.1.0') + v110_pipeline + x110_pipeline + + sign_in(user) + end + + shared_examples 'visiting project tree' do + scenario 'sees the correct pipeline status' do + visit project_tree_path(project, expected_pipeline.ref) + wait_for_requests + + page.within('.blob-commit-info') do + expect(page).to have_link('', href: project_pipeline_path(project, expected_pipeline)) + expect(page).to have_selector(".ci-status-icon-#{expected_pipeline.status}") + end + end + end + + it_behaves_like 'visiting project tree' do + let(:expected_pipeline) { v110_pipeline } + end + + it_behaves_like 'visiting project tree' do + let(:expected_pipeline) { x110_pipeline } + end + + def create_pipeline(ref, status) + create(:ci_pipeline, + project: project, + ref: ref, + sha: project.commit(ref).sha, + status: status) + end +end diff --git a/spec/features/projects/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb index 74872403b35..9ac3417b671 100644 --- a/spec/features/projects/user_replaces_files_spec.rb +++ b/spec/features/projects/files/user_replaces_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User replaces files' do +describe 'Projects > Files > User replaces files' do include DropzoneHelper let(:fork_message) do diff --git a/spec/features/projects/files/user_searches_for_files_spec.rb b/spec/features/projects/files/user_searches_for_files_spec.rb index a105685bca7..a90e4918fb1 100644 --- a/spec/features/projects/files/user_searches_for_files_spec.rb +++ b/spec/features/projects/files/user_searches_for_files_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' -describe 'User searches for files' do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } +describe 'Projects > Files > User searches for files' do + let(:user) { project.owner } before do sign_in(user) @@ -10,11 +9,10 @@ describe 'User searches for files' do describe 'project main screen' do context 'when project is empty' do - let(:empty_project) { create(:project) } + let(:project) { create(:project) } before do - empty_project.add_developer(user) - visit project_path(empty_project) + visit project_path(project) end it 'does not show any result' do @@ -26,6 +24,8 @@ describe 'User searches for files' do end context 'when project is not empty' do + let(:project) { create(:project, :repository) } + before do project.add_developer(user) visit project_path(project) @@ -38,16 +38,16 @@ describe 'User searches for files' do end describe 'project tree screen' do + let(:project) { create(:project, :repository) } + before do project.add_developer(user) visit project_tree_path(project, project.default_branch) end - it 'shows "Find file" button' do + it 'shows found files' do expect(page).to have_selector('.tree-controls .shortcuts-find-file') - end - it 'shows found files' do fill_in('search', with: 'coffee') click_button('Go') diff --git a/spec/features/projects/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb index 75898afcda9..7a1e3a8bcce 100644 --- a/spec/features/projects/user_uploads_files_spec.rb +++ b/spec/features/projects/files/user_uploads_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User uploads files' do +describe 'Projects > Files > User uploads files' do include DropzoneHelper let(:fork_message) do @@ -11,7 +11,7 @@ describe 'User uploads files' do let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) } let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } - let(:user) { create(:user) } + let(:user) { project.creator } before do project.add_master(user) @@ -23,7 +23,7 @@ describe 'User uploads files' do visit(project_tree_path_root_ref) end - it 'uploads and commit a new file', :js do + it 'uploads and commit a new text file', :js do find('.add-to-tree').click click_link('Upload file') drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) @@ -46,6 +46,24 @@ describe 'User uploads files' do expect(page).to have_content('Lorem ipsum dolor sit amet') expect(page).to have_content('Sed ut perspiciatis unde omnis') end + + it 'uploads and commit a new image file', :js do + find('.add-to-tree').click + click_link('Upload file') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + fill_in(:branch_name, with: 'new_branch_name', visible: true) + click_button('Upload file') + end + + wait_for_all_requests + + visit(project_blob_path(project, 'new_branch_name/logo_sample.svg')) + + expect(page).to have_css('.file-content img') + end end context 'when an user does not have write access' do diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb deleted file mode 100644 index 199682b943c..00000000000 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'spec_helper' - -describe 'Guest navigation menu' do - let(:project) { create(:project, :private, public_builds: false) } - let(:guest) { create(:user) } - - before do - project.add_guest(guest) - - sign_in(guest) - end - - it 'shows allowed tabs only' do - visit project_path(project) - - within('.nav-sidebar') do - expect(page).to have_content 'Overview' - expect(page).to have_content 'Issues' - expect(page).to have_content 'Wiki' - - expect(page).not_to have_content 'Repository' - expect(page).not_to have_content 'Pipelines' - expect(page).not_to have_content 'Merge Requests' - end - end - - it 'does not show fork button' do - visit project_path(project) - - within('.count-buttons') do - expect(page).not_to have_link 'Fork' - end - end - - it 'does not show clone path' do - visit project_path(project) - - within('.project-repo-buttons') do - expect(page).not_to have_selector '.project-clone-holder' - end - end - - describe 'project landing page' do - before do - project.project_feature.update!( - issues_access_level: ProjectFeature::DISABLED, - wiki_access_level: ProjectFeature::DISABLED - ) - end - - it 'does not show the project file list landing page' do - visit project_path(project) - - expect(page).not_to have_selector '.project-stats' - expect(page).not_to have_selector '.project-last-commit' - expect(page).not_to have_selector '.project-show-files' - expect(page).to have_selector '.project-show-customize_workflow' - end - - it 'shows the customize workflow when issues and wiki are disabled' do - visit project_path(project) - - expect(page).to have_selector '.project-show-customize_workflow' - end - - it 'shows the wiki when enabled' do - project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE) - - visit project_path(project) - - expect(page).to have_selector '.project-show-wiki' - end - - it 'shows the issues when enabled' do - project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) - - visit project_path(project) - - expect(page).to have_selector '.issues-list' - end - end -end diff --git a/spec/features/projects/issues/user_views_issue_spec.rb b/spec/features/projects/issues/user_views_issue_spec.rb index f7f2cde3d64..4093876c289 100644 --- a/spec/features/projects/issues/user_views_issue_spec.rb +++ b/spec/features/projects/issues/user_views_issue_spec.rb @@ -6,11 +6,27 @@ describe "User views issue" do set(:issue) { create(:issue, project: project, description: "# Description header", author: user) } before do - project.add_guest(user) + project.add_developer(user) sign_in(user) visit(project_issue_path(project, issue)) end it { expect(page).to have_header_with_correct_id_and_link(1, "Description header", "description-header") } + + it 'shows the merge request and issue actions', :aggregate_failures do + expect(page).to have_link('New issue') + expect(page).to have_button('Create merge request') + expect(page).to have_link('Close issue') + end + + context 'when the project is archived' do + let(:project) { create(:project, :public, :archived) } + + it 'hides the merge request and issue actions', :aggregate_failures do + expect(page).not_to have_link('New issue') + expect(page).not_to have_button('Create merge request') + expect(page).not_to have_link('Close issue') + end + end end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 749a1b81872..a460024542c 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -464,6 +464,17 @@ feature 'Jobs' do expect(page).to have_content('This job has been skipped') end end + + context 'when job is failed but has no trace' do + let(:job) { create(:ci_build, :failed, pipeline: pipeline) } + + it 'renders empty state' do + visit project_job_path(project, job) + + expect(job).not_to have_trace + expect(page).to have_content('This job does not have a trace.') + end + end end describe "POST /:project/jobs/:id/cancel", :js do diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb index 40689964b91..b571d5a0e26 100644 --- a/spec/features/projects/merge_request_button_spec.rb +++ b/spec/features/projects/merge_request_button_spec.rb @@ -45,6 +45,18 @@ feature 'Merge Request button' do end end end + + context 'when the project is archived' do + it 'hides the link' do + project.update!(archived: true) + + visit url + + within("#content-body") do + expect(page).not_to have_link(label) + end + end + end end context 'logged in as non-member' do diff --git a/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb b/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb index a41d683dbbb..f3e97bc9eb2 100644 --- a/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb +++ b/spec/features/projects/merge_requests/user_reverts_merge_request_spec.rb @@ -56,4 +56,12 @@ describe 'User reverts a merge request', :js do expect(page).to have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.') end + + it 'cannot revert a merge requests for an archived project' do + project.update!(archived: true) + + visit(merge_request_path(merge_request)) + + expect(page).not_to have_link('Revert') + end end diff --git a/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb b/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb index bf95dbb7d09..115e548b691 100644 --- a/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb +++ b/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb @@ -94,6 +94,18 @@ describe 'User views open merge requests' do end include_examples 'shows merge requests' + + it 'shows the new merge request button' do + expect(page).to have_link('New merge request') + end + + context 'when the project is archived' do + let(:project) { create(:project, :public, :repository, :archived) } + + it 'hides the new merge request button' do + expect(page).not_to have_link('New merge request') + end + 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/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb index 28954a4fb40..a4d1b78b83b 100644 --- a/spec/features/projects/settings/forked_project_settings_spec.rb +++ b/spec/features/projects/settings/forked_project_settings_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Settings for a forked project', :js do +describe 'Projects > Settings > For a forked project', :js do include ProjectForksHelper let(:user) { create(:user) } let(:original_project) { create(:project) } diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb index f6a1a46df11..5178d63050e 100644 --- a/spec/features/projects/settings/integration_settings_spec.rb +++ b/spec/features/projects/settings/integration_settings_spec.rb @@ -1,20 +1,20 @@ require 'spec_helper' -feature 'Integration settings' do +describe 'Projects > Settings > Integration settings' do let(:project) { create(:project) } let(:user) { create(:user) } let(:role) { :developer } let(:integrations_path) { project_settings_integrations_path(project) } - background do + before do sign_in(user) project.add_role(user, role) end context 'for developer' do - given(:role) { :developer } + let(:role) { :developer } - scenario 'to be disallowed to view' do + it 'to be disallowed to view' do visit integrations_path expect(page.status_code).to eq(404) @@ -22,13 +22,13 @@ feature 'Integration settings' do end context 'for master' do - given(:role) { :master } + let(:role) { :master } context 'Webhooks' do let(:hook) { create(:project_hook, :all_events_enabled, enable_ssl_verification: true, project: project) } let(:url) { generate(:url) } - scenario 'show list of webhooks' do + it 'show list of webhooks' do hook visit integrations_path @@ -46,7 +46,7 @@ feature 'Integration settings' do expect(page).to have_content('Wiki page events') end - scenario 'create webhook' do + it 'create webhook' do visit integrations_path fill_in 'hook_url', with: url @@ -63,7 +63,7 @@ feature 'Integration settings' do expect(page).to have_content('Job events') end - scenario 'edit existing webhook' do + it 'edit existing webhook' do hook visit integrations_path @@ -76,7 +76,7 @@ feature 'Integration settings' do expect(page).to have_content(url) end - scenario 'test existing webhook', :js do + it 'test existing webhook', :js do WebMock.stub_request(:post, hook.url) visit integrations_path @@ -87,14 +87,14 @@ feature 'Integration settings' do end context 'remove existing webhook' do - scenario 'from webhooks list page' do + it 'from webhooks list page' do hook visit integrations_path expect { click_link 'Remove' }.to change(ProjectHook, :count).by(-1) end - scenario 'from webhook edit page' do + it 'from webhook edit page' do hook visit integrations_path click_link 'Edit' @@ -108,7 +108,7 @@ feature 'Integration settings' do let(:hook) { create(:project_hook, project: project) } let(:hook_log) { create(:web_hook_log, web_hook: hook, internal_error_message: 'some error') } - scenario 'show list of hook logs' do + it 'show list of hook logs' do hook_log visit edit_project_hook_path(project, hook) @@ -116,7 +116,7 @@ feature 'Integration settings' do expect(page).to have_content(hook_log.url) end - scenario 'show hook log details' do + it 'show hook log details' do hook_log visit edit_project_hook_path(project, hook) click_link 'View details' @@ -126,7 +126,7 @@ feature 'Integration settings' do expect(page).to have_content('Resend Request') end - scenario 'retry hook log' do + it 'retry hook log' do WebMock.stub_request(:post, hook.url) hook_log diff --git a/spec/features/projects/settings/lfs_settings_spec.rb b/spec/features/projects/settings/lfs_settings_spec.rb new file mode 100644 index 00000000000..0fd28a5681c --- /dev/null +++ b/spec/features/projects/settings/lfs_settings_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe 'Projects > Settings > LFS settings' do + let(:admin) { create(:admin) } + let(:project) { create(:project) } + + context 'LFS enabled setting' do + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + + sign_in(admin) + end + + it 'displays the correct elements', :js do + visit edit_project_path(project) + + expect(page).to have_content('Git Large File Storage') + expect(page).to have_selector('input[name="project[lfs_enabled]"] + button', visible: true) + end + end +end diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index d0720855564..d9020333f28 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -1,19 +1,19 @@ require 'spec_helper' -feature "Pipelines settings" do +describe "Projects > Settings > Pipelines settings" do let(:project) { create(:project) } let(:user) { create(:user) } let(:role) { :developer } - background do + before do sign_in(user) project.add_role(user, role) end context 'for developer' do - given(:role) { :developer } + let(:role) { :developer } - scenario 'to be disallowed to view' do + it 'to be disallowed to view' do visit project_settings_ci_cd_path(project) expect(page.status_code).to eq(404) @@ -21,9 +21,9 @@ feature "Pipelines settings" do end context 'for master' do - given(:role) { :master } + let(:role) { :master } - scenario 'be allowed to change' do + it 'be allowed to change' do visit project_settings_ci_cd_path(project) fill_in('Test coverage parsing', with: 'coverage_regex') @@ -34,7 +34,7 @@ feature "Pipelines settings" do expect(page).to have_field('Test coverage parsing', with: 'coverage_regex') end - scenario 'updates auto_cancel_pending_pipelines' do + it 'updates auto_cancel_pending_pipelines' do visit project_settings_ci_cd_path(project) page.check('Auto-cancel redundant, pending pipelines') diff --git a/spec/features/projects/settings/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/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb index 72063d13c2a..38c8a8c2468 100644 --- a/spec/features/projects/user_archives_project_spec.rb +++ b/spec/features/projects/settings/user_archives_project_spec.rb @@ -1,21 +1,19 @@ require 'spec_helper' -describe 'User archives a project' do +describe 'Projects > Settings > User archives a project' do let(:user) { create(:user) } before do project.add_master(user) sign_in(user) + + visit edit_project_path(project) end context 'when a project is archived' do let(:project) { create(:project, :archived, namespace: user.namespace) } - before do - visit(edit_project_path(project)) - end - it 'unarchives a project' do expect(page).to have_content('Unarchive project') @@ -28,10 +26,6 @@ describe 'User archives a project' do context 'when a project is unarchived' do let(:project) { create(:project, :repository, namespace: user.namespace) } - before do - visit(edit_project_path(project)) - end - it 'archives a project' do expect(page).to have_content('Archive project') diff --git a/spec/features/projects/settings/user_changes_avatar_spec.rb b/spec/features/projects/settings/user_changes_avatar_spec.rb new file mode 100644 index 00000000000..2dcc79d8a12 --- /dev/null +++ b/spec/features/projects/settings/user_changes_avatar_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'Projects > Settings > User changes avatar' do + let(:project) { create(:project, :repository) } + let(:user) { project.creator } + + before do + project.add_master(user) + sign_in(user) + end + + it 'saves the new avatar' do + expect(project.reload.avatar.url).to be_nil + + save_avatar(project) + + expect(project.reload.avatar.url).to eq "/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif" + end + + context 'with an avatar already set' do + before do + save_avatar(project) + end + + it 'is possible to remove the avatar' do + click_link 'Remove avatar' + + expect(page).not_to have_link('Remove avatar') + + expect(project.reload.avatar.url).to be_nil + end + end + + def save_avatar(project) + visit edit_project_path(project) + attach_file( + :project_avatar, + File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') + ) + page.within '.general-settings' do + click_button 'Save changes' + end + end +end diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb new file mode 100644 index 00000000000..e925539351d --- /dev/null +++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe 'Projects > Settings > User changes default branch' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository, namespace: user.namespace) } + + before do + sign_in(user) + visit edit_project_path(project) + end + + it 'allows to change the default branch' do + select 'fix', from: 'project_default_branch' + page.within '.general-settings' do + click_button 'Save changes' + end + + expect(find(:css, 'select#project_default_branch').value).to eq 'fix' + end +end diff --git a/spec/features/projects/settings/user_manages_group_links_spec.rb b/spec/features/projects/settings/user_manages_group_links_spec.rb index 91e8059865c..fdf42797091 100644 --- a/spec/features/projects/settings/user_manages_group_links_spec.rb +++ b/spec/features/projects/settings/user_manages_group_links_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User manages group links' do +describe 'Projects > Settings > User manages group links' do include Select2Helper let(:user) { create(:user) } diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb index 015db603d33..b6e65fcbda1 100644 --- a/spec/features/projects/settings/merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb @@ -1,21 +1,35 @@ require 'spec_helper' -feature 'Project settings > Merge Requests', :js do - let(:project) { create(:project, :public) } +describe 'Projects > Settings > User manages merge request settings' do let(:user) { create(:user) } + let(:project) { create(:project, :public, namespace: user.namespace, path: 'gitlab', name: 'sample') } - background do - project.add_master(user) + before do sign_in(user) + visit edit_project_path(project) end - context 'when Merge Request and Pipelines are initially enabled' do - context 'when Pipelines are initially enabled' do - before do - visit edit_project_path(project) - end + it 'shows "Merge commit" strategy' do + page.within '.merge-requests-feature' do + expect(page).to have_content 'Merge commit' + end + end + + it 'shows "Merge commit with semi-linear history " strategy' do + page.within '.merge-requests-feature' do + expect(page).to have_content 'Merge commit with semi-linear history' + end + end - scenario 'shows the Merge Requests settings' do + it 'shows "Fast-forward merge" strategy' do + page.within '.merge-requests-feature' do + expect(page).to have_content 'Fast-forward merge' + end + end + + context 'when Merge Request and Pipelines are initially enabled', :js do + context 'when Pipelines are initially enabled' do + it 'shows the Merge Requests settings' do expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds') expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved') @@ -29,13 +43,13 @@ feature 'Project settings > Merge Requests', :js do end end - context 'when Pipelines are initially disabled' do + context 'when Pipelines are initially disabled', :js do before do project.project_feature.update_attribute('builds_access_level', ProjectFeature::DISABLED) visit edit_project_path(project) end - scenario 'shows the Merge Requests settings that do not depend on Builds feature' do + it 'shows the Merge Requests settings that do not depend on Builds feature' do expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds') expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved') @@ -50,13 +64,13 @@ feature 'Project settings > Merge Requests', :js do end end - context 'when Merge Request are initially disabled' do + context 'when Merge Request are initially disabled', :js do before do project.project_feature.update_attribute('merge_requests_access_level', ProjectFeature::DISABLED) visit edit_project_path(project) end - scenario 'does not show the Merge Requests settings' do + it 'does not show the Merge Requests settings' do expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds') expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved') @@ -70,17 +84,13 @@ feature 'Project settings > Merge Requests', :js do end end - describe 'Checkbox to enable merge request link' do - before do - visit edit_project_path(project) - end - - scenario 'is initially checked' do + describe 'Checkbox to enable merge request link', :js do + it 'is initially checked' do checkbox = find_field('project_printing_merge_request_link_enabled') expect(checkbox).to be_checked end - scenario 'when unchecked sets :printing_merge_request_link_enabled to false' do + it 'when unchecked sets :printing_merge_request_link_enabled to false' do uncheck('project_printing_merge_request_link_enabled') within('.merge-request-settings-form') do click_on('Save changes') diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb index 0a4f57bcd21..8af95522165 100644 --- a/spec/features/projects/settings/user_manages_project_members_spec.rb +++ b/spec/features/projects/settings/user_manages_project_members_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User manages project members' do +describe 'Projects > Settings > User manages project members' do let(:group) { create(:group, name: 'OpenSource') } let(:project) { create(:project) } let(:project2) { create(:project) } diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb new file mode 100644 index 00000000000..64c9af4b706 --- /dev/null +++ b/spec/features/projects/settings/user_renames_a_project_spec.rb @@ -0,0 +1,100 @@ +require 'spec_helper' + +describe 'Projects > Settings > User renames a project' do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') } + + before do + sign_in(user) + visit edit_project_path(project) + end + + def rename_project(project, name: nil, path: nil) + fill_in('project_name', with: name) if name + fill_in('Path', with: path) if path + click_button('Rename project') + wait_for_edit_project_page_reload + project.reload + end + + def wait_for_edit_project_page_reload + expect(find('.project-edit-container')).to have_content('Rename repository') + end + + context 'with invalid characters' do + it 'shows errors for invalid project path/name' do + rename_project(project, name: 'foo&bar', path: 'foo&bar') + expect(page).to have_field 'Project name', with: 'foo&bar' + expect(page).to have_field 'Path', with: 'foo&bar' + expect(page).to have_content "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'." + expect(page).to have_content "Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'" + end + end + + it 'shows a successful notice when the project is updated' do + fill_in 'project_name_edit', with: 'hello world' + page.within('.general-settings') do + click_button 'Save changes' + end + + expect(page).to have_content "Project 'hello world' was successfully updated." + end + + context 'when changing project name' do + it 'renames the repository' do + rename_project(project, name: 'bar') + expect(find('.breadcrumbs')).to have_content(project.name) + end + + context 'with emojis' do + it 'shows error for invalid project name' do + rename_project(project, name: '🚀 foo bar ☁️') + expect(page).to have_field 'Project name', with: '🚀 foo bar ☁️' + expect(page).not_to have_content "Name can contain only letters, digits, emojis '_', '.', dash and space. It must start with letter, digit, emoji or '_'." + end + end + end + + context 'when changing project path' do + let(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') } + + before(:context) do + TestEnv.clean_test_path + end + + after do + TestEnv.clean_test_path + end + + it 'the project is accessible via the new path' do + rename_project(project, path: 'bar') + new_path = namespace_project_path(project.namespace, 'bar') + visit new_path + + expect(current_path).to eq(new_path) + expect(find('.breadcrumbs')).to have_content(project.name) + end + + it 'the project is accessible via a redirect from the old path' do + old_path = project_path(project) + rename_project(project, path: 'bar') + new_path = namespace_project_path(project.namespace, 'bar') + visit old_path + + expect(current_path).to eq(new_path) + expect(find('.breadcrumbs')).to have_content(project.name) + end + + context 'and a new project is added with the same path' do + it 'overrides the redirect' do + old_path = project_path(project) + rename_project(project, path: 'bar') + new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz') + visit old_path + + expect(current_path).to eq(old_path) + expect(find('.breadcrumbs')).to have_content(new_project.name) + end + end + end +end diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb new file mode 100644 index 00000000000..57b4b1287fa --- /dev/null +++ b/spec/features/projects/settings/user_tags_project_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'Projects > Settings > User tags a project' do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + sign_in(user) + visit edit_project_path(project) + end + + context 'when a project is archived' do + it 'unarchives a project' do + fill_in 'Tags', with: 'tag1, tag2' + + page.within '.general-settings' do + click_button 'Save changes' + end + + expect(find_field('Tags').value).to eq 'tag1, tag2' + end + end +end diff --git a/spec/features/projects/settings/user_transfers_a_project_spec.rb b/spec/features/projects/settings/user_transfers_a_project_spec.rb new file mode 100644 index 00000000000..96b7cf1f93b --- /dev/null +++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe 'Projects > Settings > User transfers a project', :js do + let(:user) { create(:user) } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:group) { create(:group) } + + before do + group.add_owner(user) + sign_in(user) + end + + def transfer_project(project, group) + visit edit_project_path(project) + + page.within('.js-project-transfer-form') do + page.find('.select2-container').click + end + + page.find("div[role='option']", text: group.full_name).click + + click_button('Transfer project') + + fill_in 'confirm_name_input', with: project.name + + click_button 'Confirm' + + wait_for_requests + end + + it 'allows transferring a project to a group' do + old_path = project_path(project) + transfer_project(project, group) + new_path = namespace_project_path(group, project) + + expect(project.reload.namespace).to eq(group) + + visit new_path + wait_for_requests + + expect(current_path).to eq(new_path) + expect(find('.breadcrumbs')).to have_content(project.name) + + visit old_path + wait_for_requests + + expect(current_path).to eq(new_path) + expect(find('.breadcrumbs')).to have_content(project.name) + end + + context 'and a new project is added with the same path' do + it 'overrides the redirect' do + old_path = project_path(project) + project_path = project.path + transfer_project(project, group) + new_project = create(:project, namespace: user.namespace, path: project_path) + visit old_path + + expect(current_path).to eq(old_path) + expect(find('.breadcrumbs')).to have_content(new_project.name) + end + end + + context 'when nested groups are available', :nested_groups do + it 'allows transferring a project to a subgroup' do + subgroup = create(:group, parent: group) + + transfer_project(project, subgroup) + + expect(project.reload.namespace).to eq(subgroup) + end + end +end diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb index 06f6702670b..2ec6990313f 100644 --- a/spec/features/projects/settings/visibility_settings_spec.rb +++ b/spec/features/projects/settings/visibility_settings_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Visibility settings', :js do +describe 'Projects > Settings > Visibility settings', :js do let(:user) { create(:user) } let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) } @@ -10,14 +10,14 @@ feature 'Visibility settings', :js do visit edit_project_path(project) end - scenario 'project visibility select is available' do + it 'project visibility select is available' do visibility_select_container = find('.project-visibility-setting') expect(visibility_select_container.find('select').value).to eq project.visibility_level.to_s expect(visibility_select_container).to have_content 'The project can be accessed by anyone, regardless of authentication.' end - scenario 'project visibility description updates on change' do + it 'project visibility description updates on change' do visibility_select_container = find('.project-visibility-setting') visibility_select = visibility_select_container.find('select') visibility_select.select('Private') @@ -25,6 +25,38 @@ feature 'Visibility settings', :js do expect(visibility_select.value).to eq '0' expect(visibility_select_container).to have_content 'Access must be granted explicitly to each user.' end + + context 'merge requests select' do + it 'hides merge requests section' do + find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click + + expect(page).to have_selector('.merge-requests-feature', visible: false) + end + + context 'given project with merge_requests_disabled access level' do + let(:project) { create(:project, :merge_requests_disabled, namespace: user.namespace) } + + it 'hides merge requests section' do + expect(page).to have_selector('.merge-requests-feature', visible: false) + end + end + end + + context 'builds select' do + it 'hides builds select section' do + find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click + + expect(page).to have_selector('.builds-feature', visible: false) + end + + context 'given project with builds_disabled access level' do + let(:project) { create(:project, :builds_disabled, namespace: user.namespace) } + + it 'hides builds select section' do + expect(page).to have_selector('.builds-feature', visible: false) + end + end + end end context 'as master' do @@ -36,7 +68,7 @@ feature 'Visibility settings', :js do visit edit_project_path(project) end - scenario 'project visibility is locked' do + it 'project visibility is locked' do visibility_select_container = find('.project-visibility-setting') expect(visibility_select_container).to have_selector 'select[name="project[visibility_level]"]:disabled' diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb index bf55917bf4c..8803b5222be 100644 --- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb +++ b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Developer views empty project instructions' do +feature 'Projects > Show > Developer views empty project instructions' do let(:project) { create(:project, :empty_repo) } let(:developer) { create(:user) } diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/show/download_buttons_spec.rb index 81f08e44cf3..254affd4a94 100644 --- a/spec/features/projects/main/download_buttons_spec.rb +++ b/spec/features/projects/show/download_buttons_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Download buttons in project main page' do +feature 'Projects > Show > Download buttons' do given(:user) { create(:user) } given(:role) { :developer } given(:status) { 'success' } diff --git a/spec/features/projects/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb index b3b3212556c..b3b3212556c 100644 --- a/spec/features/projects/no_password_spec.rb +++ b/spec/features/projects/show/no_password_spec.rb diff --git a/spec/features/projects/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb index d1d8ca07035..8d41c547d77 100644 --- a/spec/features/projects/redirects_spec.rb +++ b/spec/features/projects/show/redirects_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'Project redirects' do +describe 'Projects > Show > Redirects' do let(:user) { create :user } let(:public_project) { create :project, :public } let(:private_project) { create :project, :private } diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/show/rss_spec.rb index 3c98c11b490..d02eaf34533 100644 --- a/spec/features/projects/main/rss_spec.rb +++ b/spec/features/projects/show/rss_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Project RSS' do +feature 'Projects > Show > RSS' do let(:user) { create(:user) } let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } let(:path) { project_path(project) } diff --git a/spec/features/projects/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb index d9d2e0ab171..ba28c0e1b8a 100644 --- a/spec/features/projects/user_interacts_with_stars_spec.rb +++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User interacts with project stars' do +describe 'Projects > Show > User interacts with project stars' do let(:project) { create(:project, :public, :repository) } context 'when user is signed in', :js do diff --git a/spec/features/projects/show/user_manages_notifications_spec.rb b/spec/features/projects/show/user_manages_notifications_spec.rb new file mode 100644 index 00000000000..31b105229be --- /dev/null +++ b/spec/features/projects/show/user_manages_notifications_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe 'Projects > Show > User manages notifications', :js do + let(:project) { create(:project, :public, :repository) } + + before do + sign_in(project.owner) + visit project_path(project) + end + + it 'changes the notification setting' do + first('.notifications-btn').click + click_link 'On mention' + + page.within '#notifications-button' do + expect(page).to have_content 'On mention' + end + end +end diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb new file mode 100644 index 00000000000..7b3711531c6 --- /dev/null +++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +describe 'Projects > Show > Collaboration links' do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + + before do + project.add_developer(user) + sign_in(user) + end + + it 'shows all the expected links' do + visit project_path(project) + + # The navigation bar + page.within('.header-new') do + aggregate_failures 'dropdown links in the navigation bar' do + expect(page).to have_link('New issue') + expect(page).to have_link('New merge request') + expect(page).to have_link('New snippet', href: new_project_snippet_path(project)) + end + end + + # The project header + page.within('.project-home-panel') do + aggregate_failures 'dropdown links in the project home panel' do + expect(page).to have_link('New issue') + expect(page).to have_link('New merge request') + expect(page).to have_link('New snippet') + expect(page).to have_link('New file') + expect(page).to have_link('New branch') + expect(page).to have_link('New tag') + end + end + + # The dropdown above the tree + page.within('.repo-breadcrumb') do + aggregate_failures 'dropdown links above the repo tree' do + expect(page).to have_link('New file') + expect(page).to have_link('Upload file') + expect(page).to have_link('New directory') + expect(page).to have_link('New branch') + expect(page).to have_link('New tag') + end + end + + # The Web IDE + expect(page).to have_link('Web IDE') + end + + it 'hides the links when the project is archived' do + project.update!(archived: true) + + visit project_path(project) + + page.within('.header-new') do + aggregate_failures 'dropdown links' do + expect(page).not_to have_link('New issue') + expect(page).not_to have_link('New merge request') + expect(page).not_to have_link('New snippet', href: new_project_snippet_path(project)) + end + end + + page.within('.project-home-panel') do + aggregate_failures 'dropdown links' do + expect(page).not_to have_link('New issue') + expect(page).not_to have_link('New merge request') + expect(page).not_to have_link('New snippet') + expect(page).not_to have_link('New file') + expect(page).not_to have_link('New branch') + expect(page).not_to have_link('New tag') + end + end + + page.within('.repo-breadcrumb') do + aggregate_failures 'dropdown links' do + expect(page).not_to have_link('New file') + expect(page).not_to have_link('Upload file') + expect(page).not_to have_link('New directory') + expect(page).not_to have_link('New branch') + expect(page).not_to have_link('New tag') + end + end + + expect(page).not_to have_link('Web IDE') + end +end diff --git a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb new file mode 100644 index 00000000000..aa23bef6fd8 --- /dev/null +++ b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe 'Projects > Show > User sees a deletion failure message' do + let(:project) { create(:project, :empty_repo, pending_delete: true) } + + before do + sign_in(project.owner) + end + + it 'shows error message if deletion for project fails' do + project.update_attributes(delete_error: "Something went wrong", pending_delete: false) + + visit project_path(project) + + expect(page).to have_selector('.project-deletion-failed-message') + expect(page).to have_content("This project was scheduled for deletion, but failed with the following message: #{project.delete_error}") + end +end diff --git a/spec/features/projects/user_views_details_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb index ffc063654cd..9a82fee1b5d 100644 --- a/spec/features/projects/user_views_details_spec.rb +++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User views details' do +describe 'Projects > Show > User sees Git instructions' do set(:user) { create(:user) } shared_examples_for 'redirects to the sign in page' do @@ -9,6 +9,16 @@ describe 'User views details' do end end + shared_examples_for 'shows details of empty project with no repo' do + it 'shows Git command line instructions' do + click_link 'Create empty repository' + + page.within '.empty_wrapper' do + expect(page).to have_content('Command line instructions') + end + end + end + shared_examples_for 'shows details of empty project' do let(:user_has_ssh_key) { false } @@ -36,6 +46,17 @@ describe 'User views details' do end context 'when project is public' do + context 'when project has no repo' do + set(:project) { create(:project, :public) } + + before do + sign_in(project.owner) + visit project_path(project) + end + + include_examples 'shows details of empty project with no repo' + end + context 'when project is empty' do set(:project) { create(:project_empty_repo, :public) } diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb new file mode 100644 index 00000000000..e277bfb8011 --- /dev/null +++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe 'Projects > Show > User sees last commit CI status' do + set(:project) { create(:project, :repository, :public) } + + it 'shows the project README', :js do + project.enable_ci + pipeline = create(:ci_pipeline, project: project, sha: project.commit.sha, ref: 'master') + pipeline.skip + + visit project_path(project) + + page.within '.blob-commit-info' do + expect(page).to have_content(project.commit.sha[0..6]) + expect(page).to have_link('Commit: skipped') + end + end +end diff --git a/spec/features/projects/show/user_sees_readme_spec.rb b/spec/features/projects/show/user_sees_readme_spec.rb new file mode 100644 index 00000000000..d80606c1c23 --- /dev/null +++ b/spec/features/projects/show/user_sees_readme_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'Projects > Show > User sees README' do + set(:user) { create(:user) } + + set(:project) { create(:project, :repository, :public) } + + it 'shows the project README', :js do + visit project_path(project) + wait_for_requests + + page.within('.readme-holder') do + expect(page).to have_content 'testme' + end + end +end diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb new file mode 100644 index 00000000000..a906fa20233 --- /dev/null +++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb @@ -0,0 +1,318 @@ +require 'spec_helper' + +describe 'Projects > Show > User sees setup shortcut buttons' do + # For "New file", "Add License" functionality, + # see spec/features/projects/files/project_owner_creates_license_file_spec.rb + # see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb + + let(:user) { create(:user) } + + describe 'empty project' do + let(:project) { create(:project, :public, :empty_repo) } + let(:presenter) { project.present(current_user: user) } + + describe 'as a normal user' do + before do + sign_in(user) + + visit project_path(project) + end + + it 'no Auto DevOps button if can not manage pipelines' do + page.within('.project-stats') do + expect(page).not_to have_link('Enable Auto DevOps') + expect(page).not_to have_link('Auto DevOps enabled') + end + end + + it '"Auto DevOps enabled" button not linked' do + project.create_auto_devops!(enabled: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_text('Auto DevOps enabled') + end + end + end + + describe 'as a master' do + before do + project.add_master(user) + sign_in(user) + + visit project_path(project) + end + + it '"New file" button linked to new file page' do + page.within('.project-stats') do + expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master')) + end + end + + it '"Add Readme" button linked to new file populated for a readme' do + page.within('.project-stats') do + expect(page).to have_link('Add Readme', href: presenter.add_readme_path) + end + end + + it '"Add License" button linked to new file populated for a license' do + page.within('.project-stats') do + expect(page).to have_link('Add License', href: presenter.add_license_path) + end + end + + describe 'Auto DevOps button' do + it '"Enable Auto DevOps" button linked to settings page' do + page.within('.project-stats') do + expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) + end + end + + it '"Auto DevOps enabled" anchor linked to settings page' do + project.create_auto_devops!(enabled: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) + end + end + end + + describe 'Kubernetes cluster button' do + it '"Add Kubernetes cluster" button linked to clusters page' do + page.within('.project-stats') do + expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project)) + end + end + + it '"Kubernetes cluster" anchor linked to cluster page' do + cluster = create(:cluster, :provided_by_gcp, projects: [project]) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster)) + end + end + end + end + end + + describe 'populated project' do + let(:project) { create(:project, :public, :repository) } + let(:presenter) { project.present(current_user: user) } + + describe 'as a normal user' do + before do + sign_in(user) + + visit project_path(project) + end + + it 'no Auto DevOps button if can not manage pipelines' do + page.within('.project-stats') do + expect(page).not_to have_link('Enable Auto DevOps') + expect(page).not_to have_link('Auto DevOps enabled') + end + end + + it '"Auto DevOps enabled" button not linked' do + project.create_auto_devops!(enabled: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_text('Auto DevOps enabled') + end + end + + it 'no Kubernetes cluster button if can not manage clusters' do + page.within('.project-stats') do + expect(page).not_to have_link('Add Kubernetes cluster') + expect(page).not_to have_link('Kubernetes configured') + end + end + end + + describe 'as a master' do + before do + allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(false) + project.add_master(user) + sign_in(user) + + visit project_path(project) + end + + it 'no "Add Changelog" button if the project already has a changelog' do + expect(project.repository.changelog).not_to be_nil + + page.within('.project-stats') do + expect(page).not_to have_link('Add Changelog') + end + end + + it 'no "Add License" button if the project already has a license' do + expect(project.repository.license_blob).not_to be_nil + + page.within('.project-stats') do + expect(page).not_to have_link('Add License') + end + end + + it 'no "Add Contribution guide" button if the project already has a contribution guide' do + expect(project.repository.contribution_guide).not_to be_nil + + page.within('.project-stats') do + expect(page).not_to have_link('Add Contribution guide') + end + end + + describe 'GitLab CI configuration button' do + it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do + expect(project.repository.gitlab_ci_yml).to be_nil + + page.within('.project-stats') do + expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path) + end + end + + it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do + Files::CreateService.new( + project, + project.creator, + start_branch: 'master', + branch_name: 'master', + commit_message: "Add .gitlab-ci.yml", + file_path: '.gitlab-ci.yml', + file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) + ).execute + + expect(project.repository.gitlab_ci_yml).not_to be_nil + + visit project_path(project) + + page.within('.project-stats') do + expect(page).not_to have_link('Set up CI/CD') + end + end + + it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do + project.create_auto_devops!(enabled: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).not_to have_link('Set up CI/CD') + end + end + end + + describe 'Auto DevOps button' do + it '"Enable Auto DevOps" button linked to settings page' do + page.within('.project-stats') do + expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) + end + end + + it '"Enable Auto DevOps" button linked to settings page' do + project.create_auto_devops!(enabled: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) + end + end + + it 'no Auto DevOps button if Auto DevOps callout is shown' do + allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true) + + visit project_path(project) + + expect(page).to have_selector('.js-autodevops-banner') + + page.within('.project-stats') do + expect(page).not_to have_link('Enable Auto DevOps') + expect(page).not_to have_link('Auto DevOps enabled') + end + end + + it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do + Files::CreateService.new( + project, + project.creator, + start_branch: 'master', + branch_name: 'master', + commit_message: "Add .gitlab-ci.yml", + file_path: '.gitlab-ci.yml', + file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) + ).execute + + expect(project.repository.gitlab_ci_yml).not_to be_nil + + visit project_path(project) + + page.within('.project-stats') do + expect(page).not_to have_link('Enable Auto DevOps') + expect(page).not_to have_link('Auto DevOps enabled') + end + end + end + + describe 'Kubernetes cluster button' do + it '"Add Kubernetes cluster" button linked to clusters page' do + page.within('.project-stats') do + expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project)) + end + end + + it '"Kubernetes cluster" button linked to cluster page' do + cluster = create(:cluster, :provided_by_gcp, projects: [project]) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster)) + end + end + end + + describe '"Set up Koding" button' do + it 'no "Set up Koding" button if Koding disabled' do + stub_application_setting(koding_enabled?: false) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).not_to have_link('Set up Koding') + end + end + + it 'no "Set up Koding" button if the project already has a .koding.yml' do + stub_application_setting(koding_enabled?: true) + allow(Gitlab::CurrentSettings.current_application_settings).to receive(:koding_url).and_return('http://koding.example.com') + expect(project.repository.changelog).not_to be_nil + allow_any_instance_of(Repository).to receive(:koding_yml).and_return(project.repository.changelog) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).not_to have_link('Set up Koding') + end + end + + it '"Set up Koding" button linked to new file populated for a .koding.yml' do + stub_application_setting(koding_enabled?: true) + + visit project_path(project) + + page.within('.project-stats') do + expect(page).to have_link('Set up Koding', href: presenter.add_koding_stack_path) + end + end + end + end + end +end diff --git a/spec/features/projects/show_project_spec.rb b/spec/features/projects/show_project_spec.rb deleted file mode 100644 index e4f13e6cab7..00000000000 --- a/spec/features/projects/show_project_spec.rb +++ /dev/null @@ -1,359 +0,0 @@ -require 'spec_helper' - -describe 'Project show page', :feature do - include DropzoneHelper - - context 'when project pending delete' do - let(:project) { create(:project, :empty_repo, pending_delete: true) } - - before do - sign_in(project.owner) - end - - it 'shows error message if deletion for project fails' do - project.update_attributes(delete_error: "Something went wrong", pending_delete: false) - - visit project_path(project) - - expect(page).to have_selector('.project-deletion-failed-message') - expect(page).to have_content("This project was scheduled for deletion, but failed with the following message: #{project.delete_error}") - end - end - - describe 'stat button existence' do - # For "New file", "Add License" functionality, - # see spec/features/projects/files/project_owner_creates_license_file_spec.rb - # see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb - - let(:user) { create(:user) } - - describe 'empty project' do - let(:project) { create(:project, :public, :empty_repo) } - let(:presenter) { project.present(current_user: user) } - - describe 'as a normal user' do - before do - sign_in(user) - - visit project_path(project) - end - - it 'no Auto DevOps button if can not manage pipelines' do - page.within('.project-stats') do - expect(page).not_to have_link('Enable Auto DevOps') - expect(page).not_to have_link('Auto DevOps enabled') - end - end - - it '"Auto DevOps enabled" button not linked' do - project.create_auto_devops!(enabled: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_text('Auto DevOps enabled') - end - end - end - - describe 'as a master' do - before do - project.add_master(user) - sign_in(user) - - visit project_path(project) - end - - it '"New file" button linked to new file page' do - page.within('.project-stats') do - expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master')) - end - end - - it '"Add Readme" button linked to new file populated for a readme' do - page.within('.project-stats') do - expect(page).to have_link('Add Readme', href: presenter.add_readme_path) - end - end - - it '"Add License" button linked to new file populated for a license' do - page.within('.project-stats') do - expect(page).to have_link('Add License', href: presenter.add_license_path) - end - end - - describe 'Auto DevOps button' do - it '"Enable Auto DevOps" button linked to settings page' do - page.within('.project-stats') do - expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) - end - end - - it '"Auto DevOps enabled" anchor linked to settings page' do - project.create_auto_devops!(enabled: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) - end - end - end - - describe 'Kubernetes cluster button' do - it '"Add Kubernetes cluster" button linked to clusters page' do - page.within('.project-stats') do - expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project)) - end - end - - it '"Kubernetes cluster" anchor linked to cluster page' do - cluster = create(:cluster, :provided_by_gcp, projects: [project]) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster)) - end - end - end - end - end - - describe 'populated project' do - let(:project) { create(:project, :public, :repository) } - let(:presenter) { project.present(current_user: user) } - - describe 'as a normal user' do - before do - sign_in(user) - - visit project_path(project) - end - - it 'no Auto DevOps button if can not manage pipelines' do - page.within('.project-stats') do - expect(page).not_to have_link('Enable Auto DevOps') - expect(page).not_to have_link('Auto DevOps enabled') - end - end - - it '"Auto DevOps enabled" button not linked' do - project.create_auto_devops!(enabled: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_text('Auto DevOps enabled') - end - end - - it 'no Kubernetes cluster button if can not manage clusters' do - page.within('.project-stats') do - expect(page).not_to have_link('Add Kubernetes cluster') - expect(page).not_to have_link('Kubernetes configured') - end - end - end - - describe 'as a master' do - before do - allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(false) - project.add_master(user) - sign_in(user) - - visit project_path(project) - end - - it 'no "Add Changelog" button if the project already has a changelog' do - expect(project.repository.changelog).not_to be_nil - - page.within('.project-stats') do - expect(page).not_to have_link('Add Changelog') - end - end - - it 'no "Add License" button if the project already has a license' do - expect(project.repository.license_blob).not_to be_nil - - page.within('.project-stats') do - expect(page).not_to have_link('Add License') - end - end - - it 'no "Add Contribution guide" button if the project already has a contribution guide' do - expect(project.repository.contribution_guide).not_to be_nil - - page.within('.project-stats') do - expect(page).not_to have_link('Add Contribution guide') - end - end - - describe 'GitLab CI configuration button' do - it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do - expect(project.repository.gitlab_ci_yml).to be_nil - - page.within('.project-stats') do - expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path) - end - end - - it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do - Files::CreateService.new( - project, - project.creator, - start_branch: 'master', - branch_name: 'master', - commit_message: "Add .gitlab-ci.yml", - file_path: '.gitlab-ci.yml', - file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) - ).execute - - expect(project.repository.gitlab_ci_yml).not_to be_nil - - visit project_path(project) - - page.within('.project-stats') do - expect(page).not_to have_link('Set up CI/CD') - end - end - - it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do - project.create_auto_devops!(enabled: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).not_to have_link('Set up CI/CD') - end - end - end - - describe 'Auto DevOps button' do - it '"Enable Auto DevOps" button linked to settings page' do - page.within('.project-stats') do - expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) - end - end - - it '"Enable Auto DevOps" button linked to settings page' do - project.create_auto_devops!(enabled: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings')) - end - end - - it 'no Auto DevOps button if Auto DevOps callout is shown' do - allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true) - - visit project_path(project) - - expect(page).to have_selector('.js-autodevops-banner') - - page.within('.project-stats') do - expect(page).not_to have_link('Enable Auto DevOps') - expect(page).not_to have_link('Auto DevOps enabled') - end - end - - it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do - Files::CreateService.new( - project, - project.creator, - start_branch: 'master', - branch_name: 'master', - commit_message: "Add .gitlab-ci.yml", - file_path: '.gitlab-ci.yml', - file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) - ).execute - - expect(project.repository.gitlab_ci_yml).not_to be_nil - - visit project_path(project) - - page.within('.project-stats') do - expect(page).not_to have_link('Enable Auto DevOps') - expect(page).not_to have_link('Auto DevOps enabled') - end - end - end - - describe 'Kubernetes cluster button' do - it '"Add Kubernetes cluster" button linked to clusters page' do - page.within('.project-stats') do - expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project)) - end - end - - it '"Kubernetes cluster" button linked to cluster page' do - cluster = create(:cluster, :provided_by_gcp, projects: [project]) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster)) - end - end - end - - describe '"Set up Koding" button' do - it 'no "Set up Koding" button if Koding disabled' do - stub_application_setting(koding_enabled?: false) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).not_to have_link('Set up Koding') - end - end - - it 'no "Set up Koding" button if the project already has a .koding.yml' do - stub_application_setting(koding_enabled?: true) - allow(Gitlab::CurrentSettings.current_application_settings).to receive(:koding_url).and_return('http://koding.example.com') - expect(project.repository.changelog).not_to be_nil - allow_any_instance_of(Repository).to receive(:koding_yml).and_return(project.repository.changelog) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).not_to have_link('Set up Koding') - end - end - - it '"Set up Koding" button linked to new file populated for a .koding.yml' do - stub_application_setting(koding_enabled?: true) - - visit project_path(project) - - page.within('.project-stats') do - expect(page).to have_link('Set up Koding', href: presenter.add_koding_stack_path) - end - end - end - end - end - end - - describe 'dropzone', :js do - let(:project) { create(:project, :repository) } - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - - visit project_path(project) - end - - it 'can upload files' do - find('.add-to-tree').click - click_link 'Upload file' - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - expect(find('.dz-filename')).to have_content('doc_sample.txt') - end - end -end diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index 3466a3dfb77..2388feeb980 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Create Snippet', :js do +describe 'Projects > Snippets > Create Snippet', :js do include DropzoneHelper let(:user) { create(:user) } diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb index 216f2af7c88..004ac55b656 100644 --- a/spec/features/projects/snippets/show_spec.rb +++ b/spec/features/projects/snippets/show_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Project snippet', :js do +describe 'Projects > Snippets > Project snippet', :js do let(:user) { create(:user) } let(:project) { create(:project, :repository) } let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) } diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb index 1bd2098af6d..01cf9740d1f 100644 --- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb +++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User comments on a snippet', :js do +describe 'Projects > Snippets > User comments on a snippet', :js do let(:project) { create(:project) } let!(:snippet) { create(:project_snippet, project: project, author: user) } let(:user) { create(:user) } @@ -22,4 +22,16 @@ describe 'User comments on a snippet', :js do expect(page).to have_content('Good snippet!') end + + it 'should have autocomplete' do + find('#note_note').native.send_keys('') + fill_in 'note[note]', with: '@' + + expect(page).to have_selector('.atwho-view') + end + + it 'should have zen mode' do + find('.js-zen-enter').click() + expect(page).to have_selector('.fullscreen') + end end diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb index ca5f7981c33..e64837ad59e 100644 --- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb +++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User deletes a snippet' do +describe 'Projects > Snippets > User deletes a snippet' do let(:project) { create(:project) } let!(:snippet) { create(:project_snippet, project: project, author: user) } let(:user) { create(:user) } diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb index 09a390443cf..eaedbbf32b6 100644 --- a/spec/features/projects/snippets/user_updates_snippet_spec.rb +++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'User updates a snippet' do +describe 'Projects > Snippets > User updates a snippet' do let(:project) { create(:project) } let!(:snippet) { create(:project_snippet, project: project, author: user) } let(:user) { create(:user) } diff --git a/spec/features/projects/snippets/user_views_snippets_spec.rb b/spec/features/projects/snippets/user_views_snippets_spec.rb index e9992e00ca8..376b76e0001 100644 --- a/spec/features/projects/snippets/user_views_snippets_spec.rb +++ b/spec/features/projects/snippets/user_views_snippets_spec.rb @@ -1,9 +1,10 @@ require 'spec_helper' -describe 'User views snippets' do +describe 'Projects > Snippets > User views snippets' do let(:project) { create(:project) } let!(:project_snippet) { create(:project_snippet, project: project, author: user) } let!(:snippet) { create(:snippet, author: user) } + let(:snippets) { [project_snippet, snippet] } # Used by the shared examples let(:user) { create(:user) } before do @@ -13,6 +14,17 @@ describe 'User views snippets' do visit(project_snippets_path(project)) end + context 'pagination' do + before do + create(:project_snippet, project: project, author: user) + allow(Snippet).to receive(:default_per_page).and_return(1) + + visit project_snippets_path(project) + end + + it_behaves_like 'paginated snippets' + end + it 'shows snippets' do expect(page).to have_content(project_snippet.title) expect(page).not_to have_content(snippet.title) diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb deleted file mode 100644 index 0fa7ca9afd4..00000000000 --- a/spec/features/projects/snippets_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'spec_helper' - -describe 'Project snippets', :js do - context 'when the project has snippets' do - let(:project) { create(:project, :public) } - let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) } - let!(:other_snippet) { create(:project_snippet) } - - context 'pagination' do - before do - allow(Snippet).to receive(:default_per_page).and_return(1) - - visit project_snippets_path(project) - end - - it_behaves_like 'paginated snippets' - end - - context 'list content' do - it 'contains all project snippets' do - visit project_snippets_path(project) - - expect(page).to have_selector('.snippet-row', count: 2) - - expect(page).to have_content(snippets[0].title) - expect(page).to have_content(snippets[1].title) - end - end - - context 'when submitting a note' do - before do - sign_in(create(:admin)) - visit project_snippet_path(project, snippets[0]) - end - - it 'should have autocomplete' do - find('#note_note').native.send_keys('') - fill_in 'note[note]', with: '@' - - expect(page).to have_selector('.atwho-view') - end - - it 'should have zen mode' do - find('.js-zen-enter').click() - expect(page).to have_selector('.fullscreen') - end - end - end -end diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb new file mode 100644 index 00000000000..cf80517b934 --- /dev/null +++ b/spec/features/projects/user_sees_sidebar_spec.rb @@ -0,0 +1,106 @@ +require 'spec_helper' + +describe 'Projects > User sees sidebar' do + let(:user) { create(:user) } + let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) } + + context 'as owner' do + before do + sign_in(user) + end + + context 'when snippets are disabled' do + before do + project.project_feature.update_attribute('snippets_access_level', ProjectFeature::DISABLED) + end + + it 'does not display a "Snippets" link' do + visit project_path(project) + + within('.nav-sidebar') do + expect(page).not_to have_content 'Snippets' + end + end + end + end + + context 'as guest' do + let(:guest) { create(:user) } + + before do + project.add_guest(guest) + + sign_in(guest) + end + + it 'shows allowed tabs only' do + visit project_path(project) + + within('.nav-sidebar') do + expect(page).to have_content 'Overview' + expect(page).to have_content 'Issues' + expect(page).to have_content 'Wiki' + + expect(page).not_to have_content 'Repository' + expect(page).not_to have_content 'CI / CD' + expect(page).not_to have_content 'Merge Requests' + end + end + + it 'does not show fork button' do + visit project_path(project) + + within('.count-buttons') do + expect(page).not_to have_link 'Fork' + end + end + + it 'does not show clone path' do + visit project_path(project) + + within('.project-repo-buttons') do + expect(page).not_to have_selector '.project-clone-holder' + end + end + + describe 'project landing page' do + before do + project.project_feature.update!( + issues_access_level: ProjectFeature::DISABLED, + wiki_access_level: ProjectFeature::DISABLED + ) + end + + it 'does not show the project file list landing page' do + visit project_path(project) + + expect(page).not_to have_selector '.project-stats' + expect(page).not_to have_selector '.project-last-commit' + expect(page).not_to have_selector '.project-show-files' + expect(page).to have_selector '.project-show-customize_workflow' + end + + it 'shows the customize workflow when issues and wiki are disabled' do + visit project_path(project) + + expect(page).to have_selector '.project-show-customize_workflow' + end + + it 'shows the wiki when enabled' do + project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE) + + visit project_path(project) + + expect(page).to have_selector '.project-show-wiki' + end + + it 'shows the issues when enabled' do + project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) + + visit project_path(project) + + expect(page).to have_selector '.issues-list' + end + end + end +end diff --git a/spec/features/projects/user_transfers_a_project_spec.rb b/spec/features/projects/user_transfers_a_project_spec.rb deleted file mode 100644 index 78f72b644ff..00000000000 --- a/spec/features/projects/user_transfers_a_project_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'spec_helper' - -feature 'User transfers a project', :js do - let(:user) { create(:user) } - let(:project) { create(:project, :repository, namespace: user.namespace) } - - before do - sign_in user - end - - def transfer_project(project, group) - visit edit_project_path(project) - - page.within('.js-project-transfer-form') do - page.find('.select2-container').click - end - - page.find("div[role='option']", text: group.full_name).click - - click_button('Transfer project') - - fill_in 'confirm_name_input', with: project.name - - click_button 'Confirm' - - wait_for_requests - end - - it 'allows transferring a project to a subgroup of a namespace' do - group = create(:group) - group.add_owner(user) - - transfer_project(project, group) - - expect(project.reload.namespace).to eq(group) - end - - context 'when nested groups are available', :nested_groups do - it 'allows transferring a project to a subgroup' do - parent = create(:group) - parent.add_owner(user) - subgroup = create(:group, parent: parent) - - transfer_project(project, subgroup) - - expect(project.reload.namespace).to eq(subgroup) - end - end -end diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb index fb0d8c766fe..47c5a8161d9 100644 --- a/spec/features/projects/user_uses_shortcuts_spec.rb +++ b/spec/features/projects/user_uses_shortcuts_spec.rb @@ -11,12 +11,12 @@ describe 'User uses shortcuts', :js do visit(project_path(project)) end - context 'when navigating to the Overview pages' do + context 'when navigating to the Project pages' do it 'redirects to the details page' do find('body').native.send_key('g') find('body').native.send_key('p') - expect(page).to have_active_navigation('Overview') + expect(page).to have_active_navigation('Project') expect(page).to have_active_sub_navigation('Details') end @@ -24,7 +24,7 @@ describe 'User uses shortcuts', :js do find('body').native.send_key('g') find('body').native.send_key('e') - expect(page).to have_active_navigation('Overview') + expect(page).to have_active_navigation('Project') expect(page).to have_active_sub_navigation('Activity') end end diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index bc75dc5d19b..9e10bfb2adc 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -392,7 +392,7 @@ feature 'Login' do end def ensure_one_active_tab - expect(page).to have_selector('.nav-tabs > li.active', count: 1) + expect(page).to have_selector('ul.new-session-tabs > li.active', count: 1) end def ensure_one_active_pane |