diff options
Diffstat (limited to 'spec/features')
43 files changed, 1100 insertions, 353 deletions
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb new file mode 100644 index 00000000000..1e11fb756b2 --- /dev/null +++ b/spec/features/abuse_report_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +feature 'Abuse reports', feature: true do + let(:another_user) { create(:user) } + + before do + login_as :user + end + + scenario 'Report abuse' do + visit user_path(another_user) + + click_link 'Report abuse' + + fill_in 'abuse_report_message', with: 'This user send spam' + click_button 'Send report' + + expect(page).to have_content 'Thank you for your report' + + visit user_path(another_user) + + expect(page).to have_button("Already reported for abuse") + end +end diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb index c1731e6414a..7fcfe5a54c7 100644 --- a/spec/features/admin/admin_abuse_reports_spec.rb +++ b/spec/features/admin/admin_abuse_reports_spec.rb @@ -4,17 +4,21 @@ describe "Admin::AbuseReports", feature: true, js: true do let(:user) { create(:user) } context 'as an admin' do + before do + login_as :admin + end + describe 'if a user has been reported for abuse' do - before do - create(:abuse_report, user: user) - login_as :admin - end + let!(:abuse_report) { create(:abuse_report, user: user) } describe 'in the abuse report view' do - it "presents a link to the user's profile" do + it 'presents information about abuse report' do visit admin_abuse_reports_path - expect(page).to have_link user.name, href: user_path(user) + expect(page).to have_content('Abuse Reports') + expect(page).to have_content(abuse_report.message) + expect(page).to have_link(user.name, href: user_path(user)) + expect(page).to have_link('Remove user') end end diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb new file mode 100644 index 00000000000..f6d625fa7f6 --- /dev/null +++ b/spec/features/admin/admin_groups_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +feature 'Admin Groups', feature: true do + let(:internal) { Gitlab::VisibilityLevel::INTERNAL } + + before do + login_as(:admin) + + stub_application_setting(default_group_visibility: internal) + end + + describe 'create a group' do + scenario 'shows the visibility level radio populated with the default value' do + visit new_admin_group_path + + expect_selected_visibility(internal) + end + end + + describe 'group edit' do + scenario 'shows the visibility level radio populated with the group visibility_level value' do + group = create(:group, :private) + + visit edit_admin_group_path(group) + + expect_selected_visibility(group.visibility_level) + end + end + + def expect_selected_visibility(level) + selector = "#group_visibility_level_#{level}[checked=checked]" + + expect(page).to have_selector(selector, count: 1) + end +end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 6cb8753e8fc..973d5b286e9 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -158,7 +158,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'removes checkmark in new list dropdown after deleting' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within(find('.board:nth-child(2)')) do @@ -304,7 +304,7 @@ describe 'Issue Boards', feature: true, js: true do context 'new list' do it 'shows all labels in new list dropdown' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -315,7 +315,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'creates new list for label' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -328,7 +328,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'creates new list for Backlog label' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -341,7 +341,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'creates new list for Done label' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -354,7 +354,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'keeps dropdown open after adding new list' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -369,7 +369,7 @@ describe 'Issue Boards', feature: true, js: true do it 'moves issues from backlog into new list' do wait_for_board_cards(1, 6) - click_button 'Create new list' + click_button 'Add list' wait_for_ajax page.within('.dropdown-menu-issues-board-new') do @@ -382,7 +382,7 @@ describe 'Issue Boards', feature: true, js: true do end it 'creates new list from a new label' do - click_button 'Create new list' + click_button 'Add list' wait_for_ajax @@ -659,6 +659,10 @@ describe 'Issue Boards', feature: true, js: true do wait_for_vue_resource end + it 'displays lists' do + expect(page).to have_selector('.board') + end + it 'does not show create new list' do expect(page).not_to have_selector('.js-new-board-list') end diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index 760a8967123..a03cd6fbf2d 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -46,7 +46,7 @@ describe 'Issue Boards new issue', feature: true, js: true do click_button 'Cancel' - expect(page).to have_selector('.board-new-issue-form', visible: false) + expect(page).not_to have_selector('.board-new-issue-form') end end diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 7fa0c95cae2..3e0b6364e0d 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -52,6 +52,10 @@ feature 'Contributions Calendar', js: true, feature: true do Event.create(push_params) end + def get_first_cell_content + find('.user-calendar-activities').text + end + before do login_as :user visit @user.username @@ -62,6 +66,43 @@ feature 'Contributions Calendar', js: true, feature: true do expect(page).to have_css('.js-contrib-calendar') end + describe 'select calendar day', js: true do + let(:cells) { page.all('.user-contrib-cell') } + let(:first_cell_content_before) { get_first_cell_content } + + before do + cells[0].click + wait_for_ajax + first_cell_content_before + end + + it 'displays calendar day activities', js: true do + expect(get_first_cell_content).not_to eq('') + end + + describe 'select another calendar day', js: true do + before do + cells[1].click + wait_for_ajax + end + + it 'displays different calendar day activities', js: true do + expect(get_first_cell_content).not_to eq(first_cell_content_before) + end + end + + describe 'deselect calendar day', js: true do + before do + cells[0].click + wait_for_ajax + end + + it 'hides calendar day activities', js: true do + expect(get_first_cell_content).to eq('') + end + end + end + describe '1 calendar activity' do before do Issues::CreateService.new(contributed_project, @user, issue_params).execute diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb new file mode 100644 index 00000000000..41dcfe439c2 --- /dev/null +++ b/spec/features/dashboard/issuables_counter_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'Navigation bar counter', feature: true, js: true, caching: true do + let(:user) { create(:user) } + let(:project) { create(:empty_project, namespace: user.namespace) } + let(:issue) { create(:issue, project: project) } + let(:merge_request) { create(:merge_request, source_project: project) } + + before do + issue.update(assignee: user) + merge_request.update(assignee: user) + login_as(user) + end + + it 'reflects dashboard issues count' do + visit issues_dashboard_path + + expect_counters('issues', '1') + + issue.update(assignee: nil) + visit issues_dashboard_path + + expect_counters('issues', '1') + end + + it 'reflects dashboard merge requests count' do + visit merge_requests_dashboard_path + + expect_counters('merge_requests', '1') + + merge_request.update(assignee: nil) + visit merge_requests_dashboard_path + + expect_counters('merge_requests', '1') + end + + def expect_counters(issuable_type, count) + dashboard_count = find('li.active span.badge') + nav_count = find(".dashboard-shortcuts-#{issuable_type} span.count") + + expect(nav_count).to have_content(count) + expect(dashboard_count).to have_content(count) + end +end diff --git a/spec/features/environment_spec.rb b/spec/features/environment_spec.rb new file mode 100644 index 00000000000..0c1939fd885 --- /dev/null +++ b/spec/features/environment_spec.rb @@ -0,0 +1,161 @@ +require 'spec_helper' + +feature 'Environment', :feature do + given(:project) { create(:empty_project) } + given(:user) { create(:user) } + given(:role) { :developer } + + background do + login_as(user) + project.team << [user, role] + end + + feature 'environment details page' do + given!(:environment) { create(:environment, project: project) } + given!(:deployment) { } + given!(:manual) { } + + before do + visit_environment(environment) + end + + context 'without deployments' do + scenario 'does show no deployments' do + expect(page).to have_content('You don\'t have any deployments right now.') + end + end + + context 'with deployments' do + context 'when there is no related deployable' do + given(:deployment) do + create(:deployment, environment: environment, deployable: nil) + end + + scenario 'does show deployment SHA' do + expect(page).to have_link(deployment.short_sha) + end + + scenario 'does not show a re-deploy button for deployment without build' do + expect(page).not_to have_link('Re-deploy') + end + end + + context 'with related deployable present' do + given(:pipeline) { create(:ci_pipeline, project: project) } + given(:build) { create(:ci_build, pipeline: pipeline) } + + given(:deployment) do + create(:deployment, environment: environment, deployable: build) + end + + scenario 'does show build name' do + expect(page).to have_link("#{build.name} (##{build.id})") + end + + scenario 'does show re-deploy button' do + expect(page).to have_link('Re-deploy') + end + + scenario 'does not show stop button' do + expect(page).not_to have_link('Stop') + end + + context 'with manual action' do + given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production') } + + scenario 'does show a play button' do + expect(page).to have_link(manual.name.humanize) + end + + scenario 'does allow to play manual action' do + expect(manual).to be_skipped + expect{ click_link(manual.name.humanize) }.not_to change { Ci::Pipeline.count } + expect(page).to have_content(manual.name) + expect(manual.reload).to be_pending + end + + context 'with external_url' do + given(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') } + given(:build) { create(:ci_build, pipeline: pipeline) } + given(:deployment) { create(:deployment, environment: environment, deployable: build) } + + scenario 'does show an external link button' do + expect(page).to have_link(nil, href: environment.external_url) + end + end + + context 'with stop action' do + given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } + given(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') } + + scenario 'does show stop button' do + expect(page).to have_link('Stop') + end + + scenario 'does allow to stop environment' do + click_link('Stop') + + expect(page).to have_content('close_app') + end + + context 'for reporter' do + let(:role) { :reporter } + + scenario 'does not show stop button' do + expect(page).not_to have_link('Stop') + end + end + end + end + end + end + end + + feature 'auto-close environment when branch is deleted' do + given(:project) { create(:project) } + + given!(:environment) do + create(:environment, :with_review_app, project: project, + ref: 'feature') + end + + scenario 'user visits environment page' do + visit_environment(environment) + + expect(page).to have_link('Stop') + end + + scenario 'user deletes the branch with running environment' do + visit namespace_project_branches_path(project.namespace, project) + + remove_branch_with_hooks(project, user, 'feature') do + page.within('.js-branch-feature') { find('a.btn-remove').click } + end + + visit_environment(environment) + + expect(page).to have_no_link('Stop') + end + + ## + # This is a workaround for problem described in #24543 + # + def remove_branch_with_hooks(project, user, branch) + params = { + oldrev: project.commit(branch).id, + newrev: Gitlab::Git::BLANK_SHA, + ref: "refs/heads/#{branch}" + } + + yield + + GitPushService.new(project, user, params).execute + end + end + + def visit_environment(environment) + visit namespace_project_environment_path(environment.project.namespace, + environment.project, + environment) + end +end diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index b565586ee14..c7fe622c477 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -1,228 +1,147 @@ require 'spec_helper' -feature 'Environments', feature: true do +feature 'Environments page', :feature, :js do given(:project) { create(:empty_project) } given(:user) { create(:user) } given(:role) { :developer } background do - login_as(user) project.team << [user, role] + login_as(user) end - describe 'when showing environments' do - given!(:environment) { } - given!(:deployment) { } - given!(:manual) { } - - before do - visit namespace_project_environments_path(project.namespace, project) - end + given!(:environment) { } + given!(:deployment) { } + given!(:manual) { } - context 'shows two tabs' do - scenario 'shows "Available" and "Stopped" tab with links' do - expect(page).to have_link('Available') - expect(page).to have_link('Stopped') - end - end - - context 'without environments' do - scenario 'does show no environments' do - expect(page).to have_content('You don\'t have any environments right now.') - end + before do + visit_environments(project) + end - scenario 'does show 0 as counter for environments in both tabs' do - expect(page.find('.js-available-environments-count').text).to eq('0') - expect(page.find('.js-stopped-environments-count').text).to eq('0') - end + describe 'page tabs' do + scenario 'shows "Available" and "Stopped" tab with links' do + expect(page).to have_link('Available') + expect(page).to have_link('Stopped') end + end - context 'with environments' do - given(:environment) { create(:environment, project: project) } - - scenario 'does show environment name' do - expect(page).to have_link(environment.name) - end - - scenario 'does show number of available and stopped environments' do - expect(page.find('.js-available-environments-count').text).to eq('1') - expect(page.find('.js-stopped-environments-count').text).to eq('0') - end - - context 'without deployments' do - scenario 'does show no deployments' do - expect(page).to have_content('No deployments yet') - end - end - - context 'with deployments' do - given(:deployment) { create(:deployment, environment: environment) } - - scenario 'does show deployment SHA' do - expect(page).to have_link(deployment.short_sha) - end - - scenario 'does show deployment internal id' do - expect(page).to have_content(deployment.iid) - end - - context 'with build and manual actions' do - given(:pipeline) { create(:ci_pipeline, project: project) } - given(:build) { create(:ci_build, pipeline: pipeline) } - given(:deployment) { create(:deployment, environment: environment, deployable: build) } - given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production') } - - scenario 'does show a play button' do - expect(page).to have_link(manual.name.humanize) - end - - scenario 'does allow to play manual action' do - expect(manual).to be_skipped - expect{ click_link(manual.name.humanize) }.not_to change { Ci::Pipeline.count } - expect(page).to have_content(manual.name) - expect(manual.reload).to be_pending - end - - scenario 'does show build name and id' do - expect(page).to have_link("#{build.name} (##{build.id})") - end - - scenario 'does not show stop button' do - expect(page).not_to have_selector('.stop-env-link') - end - - scenario 'does not show external link button' do - expect(page).not_to have_css('external-url') - end - - context 'with external_url' do - given(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') } - given(:build) { create(:ci_build, pipeline: pipeline) } - given(:deployment) { create(:deployment, environment: environment, deployable: build) } - - scenario 'does show an external link button' do - expect(page).to have_link(nil, href: environment.external_url) - end - end - - context 'with stop action' do - given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } - given(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') } - - scenario 'does show stop button' do - expect(page).to have_selector('.stop-env-link') - end - - scenario 'starts build when stop button clicked' do - first('.stop-env-link').click - - expect(page).to have_content('close_app') - end - - context 'for reporter' do - let(:role) { :reporter } - - scenario 'does not show stop button' do - expect(page).not_to have_selector('.stop-env-link') - end - end - end - end - end + context 'without environments' do + scenario 'does show no environments' do + expect(page).to have_content('You don\'t have any environments right now.') end - scenario 'does have a New environment button' do - expect(page).to have_link('New environment') + scenario 'does show 0 as counter for environments in both tabs' do + expect(page.find('.js-available-environments-count').text).to eq('0') + expect(page.find('.js-stopped-environments-count').text).to eq('0') end end describe 'when showing the environment' do given(:environment) { create(:environment, project: project) } - given!(:deployment) { } - given!(:manual) { } - before do - visit namespace_project_environment_path(project.namespace, project, environment) + scenario 'does show environment name' do + expect(page).to have_link(environment.name) + end + + scenario 'does show number of available and stopped environments' do + expect(page.find('.js-available-environments-count').text).to eq('1') + expect(page.find('.js-stopped-environments-count').text).to eq('0') end context 'without deployments' do scenario 'does show no deployments' do - expect(page).to have_content('You don\'t have any deployments right now.') + expect(page).to have_content('No deployments yet') end end context 'with deployments' do - given(:deployment) { create(:deployment, environment: environment) } + given(:project) { create(:project) } + + given(:deployment) do + create(:deployment, environment: environment, + sha: project.commit.id) + end scenario 'does show deployment SHA' do expect(page).to have_link(deployment.short_sha) end - scenario 'does not show a re-deploy button for deployment without build' do - expect(page).not_to have_link('Re-deploy') + scenario 'does show deployment internal id' do + expect(page).to have_content(deployment.iid) end - context 'with build' do + context 'with build and manual actions' do given(:pipeline) { create(:ci_pipeline, project: project) } given(:build) { create(:ci_build, pipeline: pipeline) } - given(:deployment) { create(:deployment, environment: environment, deployable: build) } - scenario 'does show build name' do - expect(page).to have_link("#{build.name} (##{build.id})") + given(:manual) do + create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production') end - scenario 'does show re-deploy button' do - expect(page).to have_link('Re-deploy') + given(:deployment) do + create(:deployment, environment: environment, + deployable: build, + sha: project.commit.id) end - scenario 'does not show stop button' do - expect(page).not_to have_link('Stop') + scenario 'does show a play button' do + find('.dropdown-play-icon-container').click + expect(page).to have_content(manual.name.humanize) end - context 'with manual action' do - given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production') } + scenario 'does allow to play manual action', js: true do + expect(manual).to be_skipped - scenario 'does show a play button' do - expect(page).to have_link(manual.name.humanize) - end + find('.dropdown-play-icon-container').click + expect(page).to have_content(manual.name.humanize) - scenario 'does allow to play manual action' do - expect(manual).to be_skipped - expect{ click_link(manual.name.humanize) }.not_to change { Ci::Pipeline.count } - expect(page).to have_content(manual.name) - expect(manual.reload).to be_pending - end + expect { click_link(manual.name.humanize) } + .not_to change { Ci::Pipeline.count } - context 'with external_url' do - given(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') } - given(:build) { create(:ci_build, pipeline: pipeline) } - given(:deployment) { create(:deployment, environment: environment, deployable: build) } + expect(manual.reload).to be_pending + end - scenario 'does show an external link button' do - expect(page).to have_link(nil, href: environment.external_url) - end + scenario 'does show build name and id' do + expect(page).to have_link("#{build.name} ##{build.id}") + end + + scenario 'does not show stop button' do + expect(page).not_to have_selector('.stop-env-link') + end + + scenario 'does not show external link button' do + expect(page).not_to have_css('external-url') + end + + context 'with external_url' do + given(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') } + given(:build) { create(:ci_build, pipeline: pipeline) } + given(:deployment) { create(:deployment, environment: environment, deployable: build) } + + scenario 'does show an external link button' do + expect(page).to have_link(nil, href: environment.external_url) end + end - context 'with stop action' do - given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } - given(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') } + context 'with stop action' do + given(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } + given(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') } - scenario 'does show stop button' do - expect(page).to have_link('Stop') - end + scenario 'does show stop button' do + expect(page).to have_selector('.stop-env-link') + end - scenario 'does allow to stop environment' do - click_link('Stop') + scenario 'starts build when stop button clicked' do + find('.stop-env-link').click - expect(page).to have_content('close_app') - end + expect(page).to have_content('close_app') + end - context 'for reporter' do - let(:role) { :reporter } + context 'for reporter' do + let(:role) { :reporter } - scenario 'does not show stop button' do - expect(page).not_to have_link('Stop') - end + scenario 'does not show stop button' do + expect(page).not_to have_selector('.stop-env-link') end end end @@ -230,9 +149,13 @@ feature 'Environments', feature: true do end end + scenario 'does have a New environment button' do + expect(page).to have_link('New environment') + end + describe 'when creating a new environment' do before do - visit namespace_project_environments_path(project.namespace, project) + visit_environments(project) end context 'when logged as developer' do @@ -271,4 +194,8 @@ feature 'Environments', feature: true do end end end + + def visit_environments(project) + visit namespace_project_environments_path(project.namespace, project) + end end diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb index 6c938bdead8..3934c936f20 100644 --- a/spec/features/expand_collapse_diffs_spec.rb +++ b/spec/features/expand_collapse_diffs_spec.rb @@ -182,6 +182,20 @@ feature 'Expand and collapse diffs', js: true, feature: true do end end end + + context 'expanding a diff when symlink was converted to a regular file' do + let(:branch) { 'symlink-expand-diff' } + + it 'shows the content of the regular file' do + expect(page).to have_content('This diff is collapsed') + expect(page).to have_no_content('No longer a symlink') + + find('.click-to-expand').click + wait_for_ajax + + expect(page).to have_content('No longer a symlink') + end + end end context 'visiting a commit without collapsed diffs' do diff --git a/spec/features/groups/members/owner_manages_access_requests_spec.rb b/spec/features/groups/members/owner_manages_access_requests_spec.rb index d811b05b0c3..dbe150823ba 100644 --- a/spec/features/groups/members/owner_manages_access_requests_spec.rb +++ b/spec/features/groups/members/owner_manages_access_requests_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Groups > Members > Owner manages access requests', feature: true do let(:user) { create(:user) } let(:owner) { create(:user) } - let(:group) { create(:group, :public) } + let(:group) { create(:group, :public, :access_requestable) } background do group.request_access(user) diff --git a/spec/features/groups/members/user_requests_access_spec.rb b/spec/features/groups/members/user_requests_access_spec.rb index b3baa2ab57c..d8c9c487996 100644 --- a/spec/features/groups/members/user_requests_access_spec.rb +++ b/spec/features/groups/members/user_requests_access_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Groups > Members > User requests access', feature: true do let(:user) { create(:user) } let(:owner) { create(:user) } - let(:group) { create(:group, :public) } + let(:group) { create(:group, :public, :access_requestable) } let!(:project) { create(:project, :private, namespace: group) } background do diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 13bfe90302c..4b19886274e 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -80,7 +80,7 @@ feature 'Group', feature: true do visit path - expect(page).to have_css('.description > p > strong') + expect(page).to have_css('.group-home-desc > p > strong') end it 'passes through html-pipeline' do @@ -88,7 +88,7 @@ feature 'Group', feature: true do visit path - expect(page).to have_css('.description > p > img') + expect(page).to have_css('.group-home-desc > p > img') end it 'sanitizes unwanted tags' do @@ -96,7 +96,7 @@ feature 'Group', feature: true do visit path - expect(page).not_to have_css('.description h1') + expect(page).not_to have_css('.group-home-desc h1') end it 'permits `rel` attribute on links' do @@ -104,7 +104,7 @@ feature 'Group', feature: true do visit path - expect(page).to have_css('.description a[rel]') + expect(page).to have_css('.group-home-desc a[rel]') end end end diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index ef00f209998..efb53026449 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -3,72 +3,83 @@ require 'rails_helper' describe 'Awards Emoji', feature: true do include WaitForAjax - let!(:project) { create(:project) } + let!(:project) { create(:project, :public) } let!(:user) { create(:user) } - - before do - project.team << [user, :master] - login_as(user) + let(:issue) do + create(:issue, + assignee: @user, + project: project) end - describe 'Click award emoji from issue#show' do - let!(:issue) do - create(:issue, - assignee: @user, - project: project) - end - - let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") } - + context 'authorized user' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + project.team << [user, :master] + login_as(user) end - it 'increments the thumbsdown emoji', js: true do - find('[data-emoji="thumbsdown"]').click - wait_for_ajax - expect(thumbsdown_emoji).to have_text("1") - end + describe 'Click award emoji from issue#show' do + let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") } - context 'click the thumbsup emoji' do - it 'increments the thumbsup emoji', js: true do - find('[data-emoji="thumbsup"]').click - wait_for_ajax - expect(thumbsup_emoji).to have_text("1") + before do + visit namespace_project_issue_path(project.namespace, project, issue) end - it 'decrements the thumbsdown emoji', js: true do - expect(thumbsdown_emoji).to have_text("0") - end - end - - context 'click the thumbsdown emoji' do it 'increments the thumbsdown emoji', js: true do find('[data-emoji="thumbsdown"]').click wait_for_ajax expect(thumbsdown_emoji).to have_text("1") end - it 'decrements the thumbsup emoji', js: true do - expect(thumbsup_emoji).to have_text("0") + context 'click the thumbsup emoji' do + it 'increments the thumbsup emoji', js: true do + find('[data-emoji="thumbsup"]').click + wait_for_ajax + expect(thumbsup_emoji).to have_text("1") + end + + it 'decrements the thumbsdown emoji', js: true do + expect(thumbsdown_emoji).to have_text("0") + end end - end - it 'toggles the smiley emoji on a note', js: true do - toggle_smiley_emoji(true) + context 'click the thumbsdown emoji' do + it 'increments the thumbsdown emoji', js: true do + find('[data-emoji="thumbsdown"]').click + wait_for_ajax + expect(thumbsdown_emoji).to have_text("1") + end - within('.note-awards') do - expect(find(emoji_counter)).to have_text("1") + it 'decrements the thumbsup emoji', js: true do + expect(thumbsup_emoji).to have_text("0") + end end - toggle_smiley_emoji(false) + it 'toggles the smiley emoji on a note', js: true do + toggle_smiley_emoji(true) + + within('.note-awards') do + expect(find(emoji_counter)).to have_text("1") + end + + toggle_smiley_emoji(false) - within('.note-awards') do - expect(page).not_to have_selector(emoji_counter) + within('.note-awards') do + expect(page).not_to have_selector(emoji_counter) + end end end end + context 'unauthorized user', js: true do + before do + visit namespace_project_issue_path(project.namespace, project, issue) + end + + it 'has disabled emoji button' do + expect(first('.award-control')[:disabled]).to be(true) + end + end + def thumbsup_emoji page.all(emoji_counter).first end diff --git a/spec/features/issues/filter_issues_spec.rb b/spec/features/issues/filter_issues_spec.rb index 2798db92f0f..0d19563d628 100644 --- a/spec/features/issues/filter_issues_spec.rb +++ b/spec/features/issues/filter_issues_spec.rb @@ -3,8 +3,8 @@ require 'rails_helper' describe 'Filter issues', feature: true do include WaitForAjax - let!(:project) { create(:project) } let!(:group) { create(:group) } + let!(:project) { create(:project, group: group) } let!(:user) { create(:user)} let!(:milestone) { create(:milestone, project: project) } let!(:label) { create(:label, project: project) } @@ -127,7 +127,7 @@ describe 'Filter issues', feature: true do expect(page).to have_content wontfix.title end - find('body').click + find('.dropdown-menu-close-icon').click expect(find('.filtered-labels')).to have_content(wontfix.title) @@ -135,7 +135,7 @@ describe 'Filter issues', feature: true do wait_for_ajax find('.dropdown-menu-labels a', text: label.title).click - find('body').click + find('.dropdown-menu-close-icon').click expect(find('.filtered-labels')).to have_content(wontfix.title) expect(find('.filtered-labels')).to have_content(label.title) @@ -150,8 +150,8 @@ describe 'Filter issues', feature: true do it "selects and unselects `won't fix`" do find('.dropdown-menu-labels a', text: wontfix.title).click find('.dropdown-menu-labels a', text: wontfix.title).click - # Close label dropdown to load - find('body').click + + find('.dropdown-menu-close-icon').click expect(page).not_to have_css('.filtered-labels') end end diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 4b1aec8bf71..bc068b5e7e0 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -1,7 +1,9 @@ require 'rails_helper' feature 'Issue Sidebar', feature: true do - let(:project) { create(:project) } + include WaitForAjax + + let(:project) { create(:project, :public) } let(:issue) { create(:issue, project: project) } let!(:user) { create(:user)} @@ -10,6 +12,37 @@ feature 'Issue Sidebar', feature: true do login_as(user) end + context 'assignee', js: true do + let(:user2) { create(:user) } + let(:issue2) { create(:issue, project: project, author: user2) } + + before do + project.team << [user, :developer] + visit_issue(project, issue2) + + find('.block.assignee .edit-link').click + + wait_for_ajax + end + + it 'shows author in assignee dropdown' do + page.within '.dropdown-menu-user' do + expect(page).to have_content(user2.name) + end + end + + it 'shows author when filtering assignee dropdown' do + page.within '.dropdown-menu-user' do + find('.dropdown-input-field').native.send_keys user2.name + sleep 1 # Required to wait for end of input delay + + wait_for_ajax + + expect(page).to have_content(user2.name) + end + end + end + context 'as a allowed user' do before do project.team << [user, :developer] diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index cdd02a8c8e3..5c958455604 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -371,10 +371,12 @@ describe 'Issues', feature: true do describe 'when I want to reset my incoming email token' do let(:project1) { create(:project, namespace: @user.namespace) } + let(:issue) { create(:issue, project: project1) } before do allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) project1.team << [@user, :master] + project1.issues << issue visit namespace_project_issues_path(@user.namespace, project1) end @@ -576,7 +578,10 @@ describe 'Issues', feature: true do describe 'new issue by email' do shared_examples 'show the email in the modal' do + let(:issue) { create(:issue, project: project) } + before do + project.issues << issue stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") visit namespace_project_issues_path(project.namespace, project) diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb index 7f11db3c417..7f11db3c417 100644 --- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions.rb +++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index c68e1ea4af9..702869b6e8b 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -67,4 +67,21 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).to have_content('Source branch "non-exist-source" does not exist') expect(page).to have_content('Target branch "non-exist-target" does not exist') end + + context 'when a branch contains commits that both delete and add the same image' do + it 'renders the diff successfully' do + visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'deleted-image-test' }) + + click_link "Changes" + + expect(page).to have_content "6049019_460s.jpg" + end + end + + # Isolates a regression (see #24627) + it 'does not show error messages on initial form' do + visit new_namespace_project_merge_request_path(project.namespace, project) + expect(page).not_to have_selector('#error_explanation') + expect(page).not_to have_content('The form contains the following error') + end end diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb new file mode 100644 index 00000000000..778b3a90cf3 --- /dev/null +++ b/spec/features/merge_requests/deleted_source_branch_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe 'Deleted source branch', feature: true, js: true do + let(:user) { create(:user) } + let(:merge_request) { create(:merge_request) } + + before do + login_as user + merge_request.project.team << [user, :master] + merge_request.update!(source_branch: 'this-branch-does-not-exist') + visit namespace_project_merge_request_path( + merge_request.project.namespace, + merge_request.project, merge_request + ) + end + + it 'shows a message about missing source branch' do + expect(page).to have_content( + 'Source branch this-branch-does-not-exist does not exist' + ) + end + + it 'hides Discussion, Commits and Changes tabs' do + within '.merge-request-details' do + expect(page).to have_no_content('Discussion') + expect(page).to have_no_content('Commits') + expect(page).to have_no_content('Changes') + end + end +end diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 5e6d8467217..eab64bd4b54 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -69,8 +69,6 @@ feature 'Diff notes resolve', feature: true, js: true do page.within '.diff-content .note' do expect(page).to have_selector('.line-resolve-btn.is-active') - - expect(find('.line-resolve-btn')['data-original-title']).to eq("Resolved by #{user.name}") end page.within '.line-resolve-all-container' do @@ -203,7 +201,7 @@ feature 'Diff notes resolve', feature: true, js: true do expect(first('.line-resolve-btn')['data-original-title']).to eq("Resolved by #{user.name}") end - expect(page).to have_content('Last updated') + expect(page).not_to have_content('Last updated') page.within '.line-resolve-all-container' do expect(page).to have_content('0/1 discussion resolved') diff --git a/spec/features/merge_requests/merge_request_versions_spec.rb b/spec/features/merge_requests/merge_request_versions_spec.rb index 23cee891bac..09451f41de4 100644 --- a/spec/features/merge_requests/merge_request_versions_spec.rb +++ b/spec/features/merge_requests/merge_request_versions_spec.rb @@ -3,11 +3,12 @@ require 'spec_helper' feature 'Merge Request versions', js: true, feature: true do let(:merge_request) { create(:merge_request, importing: true) } let(:project) { merge_request.source_project } + let!(:merge_request_diff1) { merge_request.merge_request_diffs.create(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } + let!(:merge_request_diff2) { merge_request.merge_request_diffs.create(head_commit_sha: nil) } + let!(:merge_request_diff3) { merge_request.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') } before do login_as :admin - merge_request.merge_request_diffs.create(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') - merge_request.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) end @@ -53,7 +54,7 @@ feature 'Merge Request versions', js: true, feature: true do project.namespace, project, merge_request.iid, - diff_id: 2, + diff_id: merge_request_diff3.id, start_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' ) end diff --git a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb index c3c3ab33872..8eceaad2457 100644 --- a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb @@ -73,7 +73,7 @@ feature 'Merge When Build Succeeds', feature: true, js: true do expect(page).to have_button "Merge When Build Succeeds" visit_merge_request(merge_request) # refresh the page - expect(page).to have_content "Canceled the automatic merge" + expect(page).to have_content "canceled the automatic merge" end it "allows the user to remove the source branch" do @@ -101,7 +101,7 @@ feature 'Merge When Build Succeeds', feature: true, js: true do expect(page).not_to have_link "Merge When Build Succeeds" end end - + def visit_merge_request(merge_request) visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) end diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 80e8b8fc642..1ec3103feef 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' feature 'Only allow merge requests to be merged if the build succeeds', feature: true do - let(:project) { create(:project, :public) } - let(:merge_request) { create(:merge_request_with_diffs, source_project: project) } + let(:merge_request) { create(:merge_request_with_diffs) } + let(:project) { merge_request.target_project } before do login_as merge_request.author @@ -19,7 +19,13 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when project has CI enabled' do - let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch) } + given!(:pipeline) do + create(:ci_empty_pipeline, + project: project, + sha: merge_request.diff_head_sha, + ref: merge_request.source_branch, + status: status) + end context 'when merge requests can only be merged if the build succeeds' do before do @@ -27,7 +33,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI is running' do - before { pipeline.update_column(:status, :running) } + given(:status) { :running } it 'does not allow to merge immediately' do visit_merge_request(merge_request) @@ -38,7 +44,18 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI failed' do - before { pipeline.update_column(:status, :failed) } + given(:status) { :failed } + + it 'does not allow MR to be merged' do + visit_merge_request(merge_request) + + expect(page).not_to have_button 'Accept Merge Request' + expect(page).to have_content('Please retry the build or push a new commit to fix the failure.') + end + end + + context 'when CI canceled' do + given(:status) { :canceled } it 'does not allow MR to be merged' do visit_merge_request(merge_request) @@ -49,7 +66,17 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI succeeded' do - before { pipeline.update_column(:status, :success) } + given(:status) { :success } + + it 'allows MR to be merged' do + visit_merge_request(merge_request) + + expect(page).to have_button 'Accept Merge Request' + end + end + + context 'when CI skipped' do + given(:status) { :skipped } it 'allows MR to be merged' do visit_merge_request(merge_request) @@ -65,7 +92,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI is running' do - before { pipeline.update_column(:status, :running) } + given(:status) { :running } it 'allows MR to be merged immediately', js: true do visit_merge_request(merge_request) @@ -78,7 +105,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI failed' do - before { pipeline.update_column(:status, :failed) } + given(:status) { :failed } it 'allows MR to be merged' do visit_merge_request(merge_request) @@ -88,7 +115,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature: end context 'when CI succeeded' do - before { pipeline.update_column(:status, :success) } + given(:status) { :success } it 'allows MR to be merged' do visit_merge_request(merge_request) diff --git a/spec/features/merge_requests/toggle_whitespace_changes.rb b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb index 0f98737b700..0f98737b700 100644 --- a/spec/features/merge_requests/toggle_whitespace_changes.rb +++ b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb index b8c838bf7ab..a2e40546588 100644 --- a/spec/features/milestone_spec.rb +++ b/spec/features/milestone_spec.rb @@ -14,12 +14,17 @@ feature 'Milestone', feature: true do feature 'Create a milestone' do scenario 'shows an informative message for a new milestone' do visit new_namespace_project_milestone_path(project.namespace, project) + page.within '.milestone-form' do fill_in "milestone_title", with: '8.7' + fill_in "milestone_start_date", with: '2016-11-16' + fill_in "milestone_due_date", with: '2016-12-16' end + find('input[name="commit"]').click expect(find('.alert-success')).to have_content('Assign some issues to this milestone.') + expect(page).to have_content('Nov 16, 2016 - Dec 16, 2016') end end diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb new file mode 100644 index 00000000000..6f6f7029c0b --- /dev/null +++ b/spec/features/profiles/chat_names_spec.rb @@ -0,0 +1,77 @@ +require 'rails_helper' + +feature 'Profile > Chat', feature: true do + given(:user) { create(:user) } + given(:service) { create(:service) } + + before do + login_as(user) + end + + describe 'uses authorization link' do + given(:params) do + { team_id: 'T00', team_domain: 'my_chat_team', user_id: 'U01', user_name: 'my_chat_user' } + end + given!(:authorize_url) { ChatNames::AuthorizeUserService.new(service, params).execute } + given(:authorize_path) { URI.parse(authorize_url).request_uri } + + before do + visit authorize_path + end + + context 'clicks authorize' do + before do + click_button 'Authorize' + end + + scenario 'goes to list of chat names and see chat account' do + expect(page.current_path).to eq(profile_chat_names_path) + expect(page).to have_content('my_chat_team') + expect(page).to have_content('my_chat_user') + end + + scenario 'second use of link is denied' do + visit authorize_path + + expect(page).to have_http_status(:not_found) + end + end + + context 'clicks deny' do + before do + click_button 'Deny' + end + + scenario 'goes to list of chat names and do not see chat account' do + expect(page.current_path).to eq(profile_chat_names_path) + expect(page).not_to have_content('my_chat_team') + expect(page).not_to have_content('my_chat_user') + end + + scenario 'second use of link is denied' do + visit authorize_path + + expect(page).to have_http_status(:not_found) + end + end + end + + describe 'visits chat accounts' do + given!(:chat_name) { create(:chat_name, user: user, service: service) } + + before do + visit profile_chat_names_path + end + + scenario 'sees chat user' do + expect(page).to have_content(chat_name.team_domain) + expect(page).to have_content(chat_name.chat_name) + end + + scenario 'removes chat account' do + click_link 'Remove' + + expect(page).to have_content("You don't have any active chat names.") + end + end +end diff --git a/spec/features/projects/builds_spec.rb b/spec/features/projects/builds_spec.rb index a8022a5361f..a0ccc472d11 100644 --- a/spec/features/projects/builds_spec.rb +++ b/spec/features/projects/builds_spec.rb @@ -1,52 +1,59 @@ require 'spec_helper' require 'tempfile' -describe "Builds" do - let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') } +feature 'Builds', :feature do + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:pipeline) { create(:ci_pipeline, project: project) } + + let(:build) { create(:ci_build, :trace, pipeline: pipeline) } + let(:build2) { create(:ci_build) } + + let(:artifacts_file) do + fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') + end before do - login_as(:user) - @commit = FactoryGirl.create :ci_pipeline - @build = FactoryGirl.create :ci_build, :trace, pipeline: @commit - @build2 = FactoryGirl.create :ci_build - @project = @commit.project - @project.team << [@user, :developer] + project.team << [user, :developer] + login_as(user) end describe "GET /:project/builds" do + let!(:build) { create(:ci_build, pipeline: pipeline) } + context "Pending scope" do before do - visit namespace_project_builds_path(@project.namespace, @project, scope: :pending) + visit namespace_project_builds_path(project.namespace, project, scope: :pending) end it "shows Pending tab builds" do expect(page).to have_link 'Cancel running' expect(page).to have_selector('.nav-links li.active', text: 'Pending') - expect(page).to have_content @build.short_sha - expect(page).to have_content @build.ref - expect(page).to have_content @build.name + expect(page).to have_content build.short_sha + expect(page).to have_content build.ref + expect(page).to have_content build.name end end context "Running scope" do before do - @build.run! - visit namespace_project_builds_path(@project.namespace, @project, scope: :running) + build.run! + visit namespace_project_builds_path(project.namespace, project, scope: :running) end it "shows Running tab builds" do expect(page).to have_selector('.nav-links li.active', text: 'Running') expect(page).to have_link 'Cancel running' - expect(page).to have_content @build.short_sha - expect(page).to have_content @build.ref - expect(page).to have_content @build.name + expect(page).to have_content build.short_sha + expect(page).to have_content build.ref + expect(page).to have_content build.name end end context "Finished scope" do before do - @build.run! - visit namespace_project_builds_path(@project.namespace, @project, scope: :finished) + build.run! + visit namespace_project_builds_path(project.namespace, project, scope: :finished) end it "shows Finished tab builds" do @@ -58,15 +65,15 @@ describe "Builds" do context "All builds" do before do - @project.builds.running_or_pending.each(&:success) - visit namespace_project_builds_path(@project.namespace, @project) + project.builds.running_or_pending.each(&:success) + visit namespace_project_builds_path(project.namespace, project) end it "shows All tab builds" do expect(page).to have_selector('.nav-links li.active', text: 'All') - expect(page).to have_content @build.short_sha - expect(page).to have_content @build.ref - expect(page).to have_content @build.name + expect(page).to have_content build.short_sha + expect(page).to have_content build.ref + expect(page).to have_content build.name expect(page).not_to have_link 'Cancel running' end end @@ -74,17 +81,17 @@ describe "Builds" do describe "POST /:project/builds/:id/cancel_all" do before do - @build.run! - visit namespace_project_builds_path(@project.namespace, @project) + build.run! + visit namespace_project_builds_path(project.namespace, project) click_link "Cancel running" end it 'shows all necessary content' do expect(page).to have_selector('.nav-links li.active', text: 'All') expect(page).to have_content 'canceled' - expect(page).to have_content @build.short_sha - expect(page).to have_content @build.ref - expect(page).to have_content @build.name + expect(page).to have_content build.short_sha + expect(page).to have_content build.ref + expect(page).to have_content build.name expect(page).not_to have_link 'Cancel running' end end @@ -92,20 +99,20 @@ describe "Builds" do describe "GET /:project/builds/:id" do context "Build from project" do before do - visit namespace_project_build_path(@project.namespace, @project, @build) + visit namespace_project_build_path(project.namespace, project, build) end it 'shows commit`s data' do expect(page.status_code).to eq(200) - expect(page).to have_content @commit.sha[0..7] - expect(page).to have_content @commit.git_commit_message - expect(page).to have_content @commit.git_author_name + expect(page).to have_content pipeline.sha[0..7] + expect(page).to have_content pipeline.git_commit_message + expect(page).to have_content pipeline.git_author_name end end context "Build from other project" do before do - visit namespace_project_build_path(@project.namespace, @project, @build2) + visit namespace_project_build_path(project.namespace, project, build2) end it { expect(page.status_code).to eq(404) } @@ -113,8 +120,8 @@ describe "Builds" do context "Download artifacts" do before do - @build.update_attributes(artifacts_file: artifacts_file) - visit namespace_project_build_path(@project.namespace, @project, @build) + build.update_attributes(artifacts_file: artifacts_file) + visit namespace_project_build_path(project.namespace, project, build) end it 'has button to download artifacts' do @@ -124,8 +131,8 @@ describe "Builds" do context 'Artifacts expire date' do before do - @build.update_attributes(artifacts_file: artifacts_file, artifacts_expire_at: expire_at) - visit namespace_project_build_path(@project.namespace, @project, @build) + build.update_attributes(artifacts_file: artifacts_file, artifacts_expire_at: expire_at) + visit namespace_project_build_path(project.namespace, project, build) end context 'no expire date defined' do @@ -158,10 +165,10 @@ describe "Builds" do end end - context 'Build raw trace' do + feature 'Raw trace' do before do - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) end it do @@ -169,11 +176,43 @@ describe "Builds" do end end - describe 'Variables' do + feature 'HTML trace', :js do + before do + build.run! + + visit namespace_project_build_path(project.namespace, project, build) + end + + context 'when build has an initial trace' do + it 'loads build trace' do + expect(page).to have_content 'BUILD TRACE' + + build.append_trace(' and more trace', 11) + + expect(page).to have_content 'BUILD TRACE and more trace' + end + end + + context 'when build does not have an initial trace' do + let(:build) { create(:ci_build, pipeline: pipeline) } + + it 'loads new trace' do + build.append_trace('build trace', 0) + + expect(page).to have_content 'build trace' + end + end + end + + feature 'Variables' do + let(:trigger_request) { create(:ci_trigger_request_with_variables) } + + let(:build) do + create :ci_build, pipeline: pipeline, trigger_request: trigger_request + end + before do - @trigger_request = create :ci_trigger_request_with_variables - @build = create :ci_build, pipeline: @commit, trigger_request: @trigger_request - visit namespace_project_build_path(@project.namespace, @project, @build) + visit namespace_project_build_path(project.namespace, project, build) end it 'shows variable key and value after click', js: true do @@ -193,8 +232,8 @@ describe "Builds" do describe "POST /:project/builds/:id/cancel" do context "Build from project" do before do - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) click_link "Cancel" end @@ -207,9 +246,9 @@ describe "Builds" do context "Build from other project" do before do - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) - page.driver.post(cancel_namespace_project_build_path(@project.namespace, @project, @build2)) + build.run! + visit namespace_project_build_path(project.namespace, project, build) + page.driver.post(cancel_namespace_project_build_path(project.namespace, project, build2)) end it { expect(page.status_code).to eq(404) } @@ -219,8 +258,8 @@ describe "Builds" do describe "POST /:project/builds/:id/retry" do context "Build from project" do before do - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) click_link 'Cancel' page.within('.build-header') do click_link 'Retry build' @@ -238,10 +277,10 @@ describe "Builds" do context "Build from other project" do before do - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) click_link 'Cancel' - page.driver.post(retry_namespace_project_build_path(@project.namespace, @project, @build2)) + page.driver.post(retry_namespace_project_build_path(project.namespace, project, build2)) end it { expect(page).to have_http_status(404) } @@ -249,13 +288,13 @@ describe "Builds" do context "Build that current user is not allowed to retry" do before do - @build.run! - @build.cancel! - @project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + build.run! + build.cancel! + project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC) logout_direct login_with(create(:user)) - visit namespace_project_build_path(@project.namespace, @project, @build) + visit namespace_project_build_path(project.namespace, project, build) end it 'does not show the Retry button' do @@ -268,15 +307,15 @@ describe "Builds" do describe "GET /:project/builds/:id/download" do before do - @build.update_attributes(artifacts_file: artifacts_file) - visit namespace_project_build_path(@project.namespace, @project, @build) + build.update_attributes(artifacts_file: artifacts_file) + visit namespace_project_build_path(project.namespace, project, build) click_link 'Download' end context "Build from other project" do before do - @build2.update_attributes(artifacts_file: artifacts_file) - visit download_namespace_project_build_artifacts_path(@project.namespace, @project, @build2) + build2.update_attributes(artifacts_file: artifacts_file) + visit download_namespace_project_build_artifacts_path(project.namespace, project, build2) end it { expect(page.status_code).to eq(404) } @@ -288,23 +327,23 @@ describe "Builds" do context 'build from project' do before do Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) page.within('.js-build-sidebar') { click_link 'Raw' } end it 'sends the right headers' do expect(page.status_code).to eq(200) expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(page.response_headers['X-Sendfile']).to eq(@build.path_to_trace) + expect(page.response_headers['X-Sendfile']).to eq(build.path_to_trace) end end context 'build from other project' do before do Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - @build2.run! - visit raw_namespace_project_build_path(@project.namespace, @project, @build2) + build2.run! + visit raw_namespace_project_build_path(project.namespace, project, build2) end it 'sends the right headers' do @@ -325,8 +364,8 @@ describe "Builds" do context 'when build has trace in file' do before do Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) allow_any_instance_of(Project).to receive(:ci_id).and_return(nil) allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(existing_file) @@ -345,8 +384,8 @@ describe "Builds" do context 'when build has trace in old file' do before do Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) allow_any_instance_of(Project).to receive(:ci_id).and_return(999) allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file) @@ -365,8 +404,8 @@ describe "Builds" do context 'when build has trace in DB' do before do Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - @build.run! - visit namespace_project_build_path(@project.namespace, @project, @build) + build.run! + visit namespace_project_build_path(project.namespace, project, build) allow_any_instance_of(Project).to receive(:ci_id).and_return(nil) allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file) @@ -385,7 +424,7 @@ describe "Builds" do describe "GET /:project/builds/:id/trace.json" do context "Build from project" do before do - visit trace_namespace_project_build_path(@project.namespace, @project, @build, format: :json) + visit trace_namespace_project_build_path(project.namespace, project, build, format: :json) end it { expect(page.status_code).to eq(200) } @@ -393,7 +432,7 @@ describe "Builds" do context "Build from other project" do before do - visit trace_namespace_project_build_path(@project.namespace, @project, @build2, format: :json) + visit trace_namespace_project_build_path(project.namespace, project, build2, format: :json) end it { expect(page.status_code).to eq(404) } @@ -403,7 +442,7 @@ describe "Builds" do describe "GET /:project/builds/:id/status" do context "Build from project" do before do - visit status_namespace_project_build_path(@project.namespace, @project, @build) + visit status_namespace_project_build_path(project.namespace, project, build) end it { expect(page.status_code).to eq(200) } @@ -411,7 +450,7 @@ describe "Builds" do context "Build from other project" do before do - visit status_namespace_project_build_path(@project.namespace, @project, @build2) + visit status_namespace_project_build_path(project.namespace, project, build2) end it { expect(page.status_code).to eq(404) } diff --git a/spec/features/projects/commits/cherry_pick_spec.rb b/spec/features/projects/commits/cherry_pick_spec.rb index e45e3a36d01..d46d9e9399e 100644 --- a/spec/features/projects/commits/cherry_pick_spec.rb +++ b/spec/features/projects/commits/cherry_pick_spec.rb @@ -64,7 +64,7 @@ describe 'Cherry-pick Commits' do context "I cherry-pick a commit from a different branch", js: true do it do - find('.commit-action-buttons a.dropdown-toggle').click + find('.header-action-buttons a.dropdown-toggle').click find(:css, "a[href='#modal-cherry-pick-commit']").click page.within('#modal-cherry-pick-commit') do diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb new file mode 100644 index 00000000000..3130d87fba5 --- /dev/null +++ b/spec/features/projects/labels/subscription_spec.rb @@ -0,0 +1,74 @@ +require 'spec_helper' + +feature 'Labels subscription', feature: true do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project) { create(:empty_project, :public, namespace: group) } + let!(:bug) { create(:label, project: project, title: 'bug') } + let!(:feature) { create(:group_label, group: group, title: 'feature') } + + context 'when signed in' do + before do + project.team << [user, :developer] + login_as user + end + + scenario 'users can subscribe/unsubscribe to labels', js: true do + visit namespace_project_labels_path(project.namespace, project) + + expect(page).to have_content('bug') + expect(page).to have_content('feature') + + within "#project_label_#{bug.id}" do + expect(page).not_to have_button 'Unsubscribe' + + click_button 'Subscribe' + + expect(page).not_to have_button 'Subscribe' + expect(page).to have_button 'Unsubscribe' + + click_button 'Unsubscribe' + + expect(page).to have_button 'Subscribe' + expect(page).not_to have_button 'Unsubscribe' + end + + within "#group_label_#{feature.id}" do + expect(page).not_to have_button 'Unsubscribe' + + click_link_on_dropdown('Group level') + + expect(page).not_to have_selector('.dropdown-group-label') + expect(page).to have_button 'Unsubscribe' + + click_button 'Unsubscribe' + + expect(page).to have_selector('.dropdown-group-label') + + click_link_on_dropdown('Project level') + + expect(page).not_to have_selector('.dropdown-group-label') + expect(page).to have_button 'Unsubscribe' + end + end + end + + context 'when not signed in' do + it 'users can not subscribe/unsubscribe to labels' do + visit namespace_project_labels_path(project.namespace, project) + + expect(page).to have_content 'bug' + expect(page).to have_content 'feature' + expect(page).not_to have_button('Subscribe') + expect(page).not_to have_selector('.dropdown-group-label') + end + end + + def click_link_on_dropdown(text) + find('.dropdown-group-label').click + + page.within('.dropdown-group-label') do + find('a.js-subscribe-button', text: text).click + end + end +end diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb index c4ed92d2780..4973e0aee85 100644 --- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb +++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' feature 'Projects > Members > Group requester cannot request access to project', feature: true do let(:user) { create(:user) } let(:owner) { create(:user) } - let(:group) { create(:group, :public) } - let(:project) { create(:project, :public, namespace: group) } + let(:group) { create(:group, :public, :access_requestable) } + let(:project) { create(:project, :public, :access_requestable, namespace: group) } background do group.add_owner(owner) diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb index d15376931c3..143390b71cd 100644 --- a/spec/features/projects/members/master_manages_access_requests_spec.rb +++ b/spec/features/projects/members/master_manages_access_requests_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Projects > Members > Master manages access requests', feature: true do let(:user) { create(:user) } let(:master) { create(:user) } - let(:project) { create(:project, :public) } + let(:project) { create(:empty_project, :public, :access_requestable) } background do project.request_access(user) diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 56ede8eb5be..97c42bd7f01 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Projects > Members > User requests access', feature: true do let(:user) { create(:user) } let(:master) { create(:user) } - let(:project) { create(:project, :public) } + let(:project) { create(:project, :public, :access_requestable) } background do project.team << [master, :master] diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb new file mode 100644 index 00000000000..abfc46601fb --- /dev/null +++ b/spec/features/projects/new_project_spec.rb @@ -0,0 +1,19 @@ +require "spec_helper" + +feature "New project", feature: true do + context "Visibility level selector" do + let(:user) { create(:admin) } + + before { login_as(user) } + + Gitlab::VisibilityLevel.options.each do |key, level| + it "sets selector to #{key}" do + stub_application_setting(default_project_visibility: level) + + visit new_project_path + + expect(find_field("project_visibility_level_#{level}")).to be_checked + end + end + end +end diff --git a/spec/features/projects/pipelines_spec.rb b/spec/features/projects/pipelines_spec.rb index db56a50e058..002c6f6b359 100644 --- a/spec/features/projects/pipelines_spec.rb +++ b/spec/features/projects/pipelines_spec.rb @@ -146,7 +146,8 @@ describe "Pipelines" do end describe 'GET /:project/pipelines/:id' do - let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master') } + let(:project) { create(:project) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } before do @success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build') diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb index 3de25d7af7d..bf60cca4ea4 100644 --- a/spec/features/projects/project_settings_spec.rb +++ b/spec/features/projects/project_settings_spec.rb @@ -18,7 +18,7 @@ describe 'Edit Project Settings', feature: true do click_button 'Save changes' expect(page).to have_field 'project_name_edit', with: 'foo&bar' - expect(page).to have_content "Name can contain only letters, digits, '_', '.', dash and space. It must start with letter, digit or '_'." + 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 end @@ -34,8 +34,21 @@ describe 'Edit Project Settings', feature: true do 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, '_', '.', dash and space. It must start with letter, digit or '_'." + 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 + + describe 'Rename repository name with emojis' do + it 'shows error for invalid project name' do + visit edit_namespace_project_path(project.namespace, project) + + fill_in 'Project name', with: '🚀 foo bar ☁️' + + click_button 'Rename project' + + 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 diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb new file mode 100644 index 00000000000..f474e7e891b --- /dev/null +++ b/spec/features/projects/services/mattermost_slash_command_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +feature 'Setup Mattermost slash commands', feature: true do + include WaitForAjax + + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:service) { project.create_mattermost_slash_commands_service } + + before do + project.team << [user, :master] + login_as(user) + end + + describe 'user visites the mattermost slash command config page', js: true do + it 'shows a help message' do + visit edit_namespace_project_service_path(project.namespace, project, service) + + wait_for_ajax + + expect(page).to have_content("This service allows GitLab users to perform common") + end + end + + describe 'saving a token' do + let(:token) { ('a'..'z').to_a.join } + + it 'shows the token after saving' do + visit edit_namespace_project_service_path(project.namespace, project, service) + + fill_in 'service_token', with: token + click_on 'Save' + + value = find_field('service_token').value + + expect(value).to eq(token) + end + end + + describe 'the trigger url' do + it 'shows the correct url' do + visit edit_namespace_project_service_path(project.namespace, project, service) + + value = find_field('request_url').value + expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger") + end + end +end diff --git a/spec/features/projects/slack_service/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb index 16541f51d98..16541f51d98 100644 --- a/spec/features/projects/slack_service/slack_service_spec.rb +++ b/spec/features/projects/services/slack_service_spec.rb diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb new file mode 100644 index 00000000000..10a4597e467 --- /dev/null +++ b/spec/features/snippets/explore_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +feature 'Explore Snippets', feature: true do + scenario 'User should see snippets that are not private' do + public_snippet = create(:personal_snippet, :public) + internal_snippet = create(:personal_snippet, :internal) + private_snippet = create(:personal_snippet, :private) + + login_as create(:user) + visit explore_snippets_path + + expect(page).to have_content(public_snippet.title) + expect(page).to have_content(internal_snippet.title) + expect(page).not_to have_content(private_snippet.title) + end +end diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb new file mode 100644 index 00000000000..146cd3af848 --- /dev/null +++ b/spec/features/snippets/search_snippets_spec.rb @@ -0,0 +1,66 @@ +require 'rails_helper' + +feature 'Search Snippets', feature: true do + scenario 'User searches for snippets by title' do + public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle') + private_snippet = create(:personal_snippet, :private, title: 'Middle and End') + + login_as private_snippet.author + visit dashboard_snippets_path + + page.within '.search' do + fill_in 'search', with: 'Middle' + click_button 'Go' + end + + click_link 'Titles and Filenames' + + expect(page).to have_link(public_snippet.title) + expect(page).to have_link(private_snippet.title) + end + + scenario 'User searches for snippet contents' do + create(:personal_snippet, + :public, + title: 'Many lined snippet', + content: <<-CONTENT.strip_heredoc + |line one + |line two + |line three + |line four + |line five + |line six + |line seven + |line eight + |line nine + |line ten + |line eleven + |line twelve + |line thirteen + |line fourteen + CONTENT + ) + + login_as create(:user) + visit dashboard_snippets_path + + page.within '.search' do + fill_in 'search', with: 'line seven' + click_button 'Go' + end + + expect(page).to have_content('line seven') + + # 3 lines before the matched line should be visible + expect(page).to have_content('line six') + expect(page).to have_content('line five') + expect(page).to have_content('line four') + expect(page).not_to have_content('line three') + + # 3 lines after the matched line should be visible + expect(page).to have_content('line eight') + expect(page).to have_content('line nine') + expect(page).to have_content('line ten') + expect(page).not_to have_content('line eleven') + end +end diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index 3ae83ac082d..88eabea7e3a 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -44,7 +44,7 @@ describe 'Dashboard Todos', feature: true do end it 'shows "All done" message' do - expect(page).to have_content("Good job! Looks like you don't have any todos left.") + expect(page).to have_selector('.todos-all-done', count: 1) end end @@ -64,7 +64,7 @@ describe 'Dashboard Todos', feature: true do end it 'shows "All done" message' do - expect(page).to have_content("Good job! Looks like you don't have any todos left.") + expect(page).to have_selector('.todos-all-done', count: 1) end end end @@ -152,7 +152,7 @@ describe 'Dashboard Todos', feature: true do within('.todos-pending-count') { expect(page).to have_content '0' } expect(page).to have_content 'To do 0' expect(page).to have_content 'Done 0' - expect(page).to have_content "Good job! Looks like you don't have any todos left." + expect(page).to have_selector('.todos-all-done', count: 1) end end end diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb index 33b52d1547e..e2d9cfdd0b0 100644 --- a/spec/features/unsubscribe_links_spec.rb +++ b/spec/features/unsubscribe_links_spec.rb @@ -26,11 +26,11 @@ describe 'Unsubscribe links', feature: true do expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last) expect(page).to have_text(%(Unsubscribe from issue #{issue.title} (#{issue.to_reference}))) expect(page).to have_text(%(Are you sure you want to unsubscribe from issue #{issue.title} (#{issue.to_reference})?)) - expect(issue.subscribed?(recipient)).to be_truthy + expect(issue.subscribed?(recipient, project)).to be_truthy click_link 'Unsubscribe' - expect(issue.subscribed?(recipient)).to be_falsey + expect(issue.subscribed?(recipient, project)).to be_falsey expect(current_path).to eq new_user_session_path end @@ -38,11 +38,11 @@ describe 'Unsubscribe links', feature: true do visit body_link expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last) - expect(issue.subscribed?(recipient)).to be_truthy + expect(issue.subscribed?(recipient, project)).to be_truthy click_link 'Cancel' - expect(issue.subscribed?(recipient)).to be_truthy + expect(issue.subscribed?(recipient, project)).to be_truthy expect(current_path).to eq new_user_session_path end end @@ -51,7 +51,7 @@ describe 'Unsubscribe links', feature: true do visit header_link expect(page).to have_text('unsubscribed') - expect(issue.subscribed?(recipient)).to be_falsey + expect(issue.subscribed?(recipient, project)).to be_falsey end end @@ -62,14 +62,14 @@ describe 'Unsubscribe links', feature: true do visit body_link expect(page).to have_text('unsubscribed') - expect(issue.subscribed?(recipient)).to be_falsey + expect(issue.subscribed?(recipient, project)).to be_falsey end it 'unsubscribes from the issue when visiting the link from the header' do visit header_link expect(page).to have_text('unsubscribed') - expect(issue.subscribed?(recipient)).to be_falsey + expect(issue.subscribed?(recipient, project)).to be_falsey end end end diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index 111ca7f7a70..afa98f3f715 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -74,16 +74,29 @@ feature 'Users', feature: true, js: true do visit new_user_session_path click_link 'Register' end + + scenario 'doesn\'t show an error border if the username is available' do + fill_in username_input, with: 'new-user' + wait_for_ajax + expect(find('.username')).not_to have_css '.gl-field-error-outline' + end + + scenario 'does not show an error border if the username contains dots (.)' do + fill_in username_input, with: 'new.user.username' + wait_for_ajax + expect(find('.username')).not_to have_css '.gl-field-error-outline' + end + scenario 'shows an error border if the username already exists' do fill_in username_input, with: user.username wait_for_ajax expect(find('.username')).to have_css '.gl-field-error-outline' end - scenario 'doesn\'t show an error border if the username is available' do - fill_in username_input, with: 'new-user' + scenario 'shows an error border if the username contains special characters' do + fill_in username_input, with: 'new$user!username' wait_for_ajax - expect(find('#new_user_username')).not_to have_css '.gl-field-error-outline' + expect(find('.username')).to have_css '.gl-field-error-outline' end end |