diff options
Diffstat (limited to 'spec/features/projects/settings')
17 files changed, 772 insertions, 71 deletions
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..342be1d2a9d --- /dev/null +++ b/spec/features/projects/settings/lfs_settings_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +describe 'Projects > Settings > LFS settings' do + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:role) { :master } + + context 'LFS enabled setting' do + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + + sign_in(user) + project.add_role(user, role) + end + + context 'for master' do + let(:role) { :master } + + 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 +end diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index d0720855564..cfdae246c09 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -1,19 +1,20 @@ 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) + create(:project_auto_devops, project: project) 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,27 +22,39 @@ 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') - click_on 'Save changes' + + page.within '#js-general-pipeline-settings' do + click_on 'Save changes' + end expect(page.status_code).to eq(200) - expect(page).to have_button('Save changes', disabled: false) + + page.within '#js-general-pipeline-settings' do + expect(page).to have_button('Save changes', disabled: false) + end + 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') - click_on 'Save changes' + page.within '#js-general-pipeline-settings' do + click_on 'Save changes' + end expect(page.status_code).to eq(200) - expect(page).to have_button('Save changes', disabled: false) + + page.within '#js-general-pipeline-settings' do + expect(page).to have_button('Save changes', disabled: false) + end checkbox = find_field('project_auto_cancel_pending_pipelines') expect(checkbox).to be_checked @@ -51,13 +64,39 @@ feature "Pipelines settings" do it 'update auto devops settings' do visit project_settings_ci_cd_path(project) - fill_in('project_auto_devops_attributes_domain', with: 'test.com') - page.choose('project_auto_devops_attributes_enabled_false') - click_on 'Save changes' + page.within '#autodevops-settings' do + fill_in('project_auto_devops_attributes_domain', with: 'test.com') + page.choose('project_auto_devops_attributes_enabled_false') + click_on 'Save changes' + end expect(page.status_code).to eq(200) expect(project.auto_devops).to be_present expect(project.auto_devops).not_to be_enabled + expect(project.auto_devops.domain).to eq('test.com') + end + + context 'when there is a cluster with ingress and external_ip' do + before do + cluster = create(:cluster, projects: [project]) + cluster.create_application_ingress!(external_ip: '192.168.1.100') + end + + it 'shows the help text with the nip.io domain as an alternative to custom domain' do + visit project_settings_ci_cd_path(project) + expect(page).to have_content('192.168.1.100.nip.io can be used as an alternative to a custom domain') + end + end + + context 'when there is no ingress' do + before do + create(:cluster, projects: [project]) + end + + it 'alternative to custom domain is not shown' do + visit project_settings_ci_cd_path(project) + expect(page).not_to have_content('can be used as an alternative to a custom domain') + end end end end diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb new file mode 100644 index 00000000000..4893bef8884 --- /dev/null +++ b/spec/features/projects/settings/project_badges_spec.rb @@ -0,0 +1,125 @@ +require 'spec_helper' + +feature 'Project Badges' do + include WaitForRequests + + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project) { create(:project, namespace: group) } + let(:badge_link_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/commits/master'} + let(:badge_image_url) { 'https://gitlab.com/gitlab-org/gitlab-ee/badges/master/build.svg'} + let!(:project_badge) { create(:project_badge, project: project) } + let!(:group_badge) { create(:group_badge, group: group) } + + before do + group.add_master(user) + sign_in(user) + + visit(project_settings_badges_path(project)) + end + + it 'shows a list of badges', :js do + page.within '.badge-settings' do + wait_for_requests + + rows = all('.card-body > div') + expect(rows.length).to eq 2 + expect(rows[0]).to have_content group_badge.link_url + expect(rows[1]).to have_content project_badge.link_url + end + end + + context 'adding a badge', :js do + it 'user can preview a badge' do + page.within '.badge-settings form' do + fill_in 'badge-link-url', with: badge_link_url + fill_in 'badge-image-url', with: badge_image_url + within '#badge-preview' do + expect(find('a')[:href]).to eq badge_link_url + expect(find('a img')[:src]).to eq badge_image_url + end + end + end + + it do + page.within '.badge-settings' do + fill_in 'badge-link-url', with: badge_link_url + fill_in 'badge-image-url', with: badge_image_url + + click_button 'Add badge' + wait_for_requests + + within '.card-body' do + expect(find('a')[:href]).to eq badge_link_url + expect(find('a img')[:src]).to eq badge_image_url + end + end + end + end + + context 'editing a badge', :js do + it 'form is shown when clicking edit button in list' do + page.within '.badge-settings' do + wait_for_requests + rows = all('.card-body > div') + expect(rows.length).to eq 2 + rows[1].find('[aria-label="Edit"]').click + + within 'form' do + expect(find('#badge-link-url').value).to eq project_badge.link_url + expect(find('#badge-image-url').value).to eq project_badge.image_url + end + end + end + + it 'updates a badge when submitting the edit form' do + page.within '.badge-settings' do + wait_for_requests + rows = all('.card-body > div') + expect(rows.length).to eq 2 + rows[1].find('[aria-label="Edit"]').click + within 'form' do + fill_in 'badge-link-url', with: badge_link_url + fill_in 'badge-image-url', with: badge_image_url + + click_button 'Save changes' + wait_for_requests + end + + rows = all('.card-body > div') + expect(rows.length).to eq 2 + expect(rows[1]).to have_content badge_link_url + end + end + end + + context 'deleting a badge', :js do + def click_delete_button(badge_row) + badge_row.find('[aria-label="Delete"]').click + end + + it 'shows a modal when deleting a badge' do + wait_for_requests + rows = all('.card-body > div') + expect(rows.length).to eq 2 + + click_delete_button(rows[1]) + + expect(find('.modal .modal-title')).to have_content 'Delete badge?' + end + + it 'deletes a badge when confirming the modal' do + wait_for_requests + rows = all('.card-body > div') + expect(rows.length).to eq 2 + click_delete_button(rows[1]) + + find('.modal .btn-danger').click + wait_for_requests + + rows = all('.card-body > div') + expect(rows.length).to eq 1 + expect(rows[0]).to have_content group_badge.link_url + end + end +end diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 14670e91006..08b40653764 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,11 +50,11 @@ 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) - find('li', text: private_deploy_key.title).click_link('Edit') + find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click() fill_in 'deploy_key_title', with: 'updated_deploy_key' check 'deploy_key_deploy_keys_projects_attributes_0_can_push' @@ -64,29 +64,75 @@ 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 visit project_settings_repository_path(project) - find('li', text: private_deploy_key.title).click_link('Edit') + find('.js-deployKeys-tab-available_project_keys').click() + + find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click() fill_in 'deploy_key_title', with: 'updated_deploy_key' click_button 'Save changes' + find('.js-deployKeys-tab-available_project_keys').click() + 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) - accept_confirm { find('li', text: private_deploy_key.title).click_button('Remove') } + accept_confirm { find('.deploy-key', text: private_deploy_key.title).find('.ic-remove').click() } expect(page).not_to have_content(private_deploy_key.title) end end + + context 'Deploy tokens' do + let!(:deploy_token) { create(:deploy_token, projects: [project]) } + + before do + stub_container_registry_config(enabled: true) + visit project_settings_repository_path(project) + end + + scenario 'view deploy tokens' do + within('.deploy-tokens') do + expect(page).to have_content(deploy_token.name) + expect(page).to have_content('read_repository') + expect(page).to have_content('read_registry') + end + end + + scenario 'add a new deploy token' do + fill_in 'deploy_token_name', with: 'new_deploy_key' + fill_in 'deploy_token_expires_at', with: (Date.today + 1.month).to_s + check 'deploy_token_read_repository' + check 'deploy_token_read_registry' + click_button 'Create deploy token' + + expect(page).to have_content('Your new project deploy token has been created') + end + end + + context 'remote mirror settings' do + let(:user2) { create(:user) } + + before do + project.add_master(user2) + + visit project_settings_repository_path(project) + end + + it 'shows push mirror settings' do + expect(page).to have_selector('#project_remote_mirrors_attributes_0_enabled') + expect(page).to have_selector('#project_remote_mirrors_attributes_0_url') + end + end end end diff --git a/spec/features/projects/settings/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb new file mode 100644 index 00000000000..38c8a8c2468 --- /dev/null +++ b/spec/features/projects/settings/user_archives_project_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'Projects > Settings > User archives a project' do + let(:user) { create(:user) } + + before do + project.add_master(user) + + sign_in(user) + + visit edit_project_path(project) + end + + context 'when a project is archived' do + let(:project) { create(:project, :archived, namespace: user.namespace) } + + it 'unarchives a project' do + expect(page).to have_content('Unarchive project') + + click_link('Unarchive') + + expect(page).not_to have_content('Archived project') + end + end + + context 'when a project is unarchived' do + let(:project) { create(:project, :repository, namespace: user.namespace) } + + it 'archives a project' do + expect(page).to have_content('Archive project') + + click_link('Archive') + + expect(page).to have_content('Archived') + end + end +end diff --git a/spec/features/projects/settings/user_changes_avatar_spec.rb b/spec/features/projects/settings/user_changes_avatar_spec.rb new file mode 100644 index 00000000000..2dcc79d8a12 --- /dev/null +++ b/spec/features/projects/settings/user_changes_avatar_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'Projects > Settings > User changes avatar' do + let(:project) { create(:project, :repository) } + let(:user) { project.creator } + + before do + project.add_master(user) + sign_in(user) + end + + it 'saves the new avatar' do + expect(project.reload.avatar.url).to be_nil + + save_avatar(project) + + expect(project.reload.avatar.url).to eq "/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif" + end + + context 'with an avatar already set' do + before do + save_avatar(project) + end + + it 'is possible to remove the avatar' do + click_link 'Remove avatar' + + expect(page).not_to have_link('Remove avatar') + + expect(project.reload.avatar.url).to be_nil + end + end + + def save_avatar(project) + visit edit_project_path(project) + attach_file( + :project_avatar, + File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') + ) + page.within '.general-settings' do + click_button 'Save changes' + end + end +end diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb new file mode 100644 index 00000000000..e925539351d --- /dev/null +++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe 'Projects > Settings > User changes default branch' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository, namespace: user.namespace) } + + before do + sign_in(user) + visit edit_project_path(project) + end + + it 'allows to change the default branch' do + select 'fix', from: 'project_default_branch' + page.within '.general-settings' do + click_button 'Save changes' + end + + expect(find(:css, 'select#project_default_branch').value).to eq 'fix' + end +end diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb new file mode 100644 index 00000000000..71a077039b7 --- /dev/null +++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb @@ -0,0 +1,125 @@ +require "spec_helper" + +describe "User interacts with deploy keys", :js do + let(:project) { create(:project, :repository) } + let(:user) { project.owner } + + before do + sign_in(user) + end + + shared_examples "attaches a key" do + it "attaches key" do + visit(project_deploy_keys_path(project)) + + page.within(".deploy-keys") do + find(".badge", text: "1").click + + click_button("Enable") + + expect(page).not_to have_selector(".fa-spinner") + expect(current_path).to eq(project_settings_repository_path(project)) + + find(".js-deployKeys-tab-enabled_keys").click + + expect(page).to have_content(deploy_key.title) + end + end + end + + context "viewing deploy keys" do + let(:deploy_key) { create(:deploy_key) } + + context "when project has keys" do + before do + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + end + + it "shows deploy keys" do + visit(project_deploy_keys_path(project)) + + page.within(".deploy-keys") do + expect(page).to have_content(deploy_key.title) + end + end + end + + context "when another project has keys" do + let(:another_project) { create(:project) } + + before do + create(:deploy_keys_project, project: another_project, deploy_key: deploy_key) + + another_project.add_master(user) + end + + it "shows deploy keys" do + visit(project_deploy_keys_path(project)) + + page.within(".deploy-keys") do + find('.js-deployKeys-tab-available_project_keys').click + + expect(page).to have_content(deploy_key.title) + expect(find(".js-deployKeys-tab-available_project_keys .badge")).to have_content("1") + end + end + end + + context "when there are public deploy keys" do + let!(:deploy_key) { create(:deploy_key, public: true) } + + it "shows public deploy keys" do + visit(project_deploy_keys_path(project)) + + page.within(".deploy-keys") do + find(".js-deployKeys-tab-public_keys").click + + expect(page).to have_content(deploy_key.title) + end + end + end + end + + context "adding deploy keys" do + before do + visit(project_deploy_keys_path(project)) + end + + it "adds new key" do + DEPLOY_KEY_TITLE = attributes_for(:key)[:title] + DEPLOY_KEY_BODY = attributes_for(:key)[:key] + + fill_in("deploy_key_title", with: DEPLOY_KEY_TITLE) + fill_in("deploy_key_key", with: DEPLOY_KEY_BODY) + + click_button("Add key") + + expect(current_path).to eq(project_settings_repository_path(project)) + + page.within(".deploy-keys") do + expect(page).to have_content(DEPLOY_KEY_TITLE) + end + end + end + + context "attaching existing keys" do + context "from another project" do + let(:another_project) { create(:project) } + let(:deploy_key) { create(:deploy_key) } + + before do + create(:deploy_keys_project, project: another_project, deploy_key: deploy_key) + + another_project.add_master(user) + end + + it_behaves_like "attaches a key" + end + + context "when keys are public" do + let!(:deploy_key) { create(:deploy_key, public: true) } + + it_behaves_like "attaches a key" + end + 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..92ce2ca83c7 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) } @@ -30,7 +30,7 @@ describe 'User manages group links' do click_link('Share with group') select2(group_market.id, from: '#link_group_id') - select('Master', from: 'link_group_access') + select('Maintainer', from: 'link_group_access') click_button('Share') 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..d3003753ae6 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) } @@ -62,7 +62,7 @@ describe 'User manages project members' do page.within('.project-members-groups') do expect(page).to have_content('OpenSource') - expect(first('.group_member')).to have_content('Master') + expect(first('.group_member')).to have_content('Maintainer') end end end 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' |