summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_groups_spec.rb35
-rw-r--r--spec/features/boards/boards_spec.rb23
-rw-r--r--spec/features/boards/new_issue_spec.rb2
-rw-r--r--spec/features/commits_spec.rb23
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb44
-rw-r--r--spec/features/environment_spec.rb161
-rw-r--r--spec/features/environments_spec.rb265
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb14
-rw-r--r--spec/features/global_search_spec.rb28
-rw-r--r--spec/features/groups/issues_spec.rb8
-rw-r--r--spec/features/groups/members/owner_manages_access_requests_spec.rb2
-rw-r--r--spec/features/groups/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/groups/merge_requests_spec.rb8
-rw-r--r--spec/features/groups_spec.rb8
-rw-r--r--spec/features/issues/award_emoji_spec.rb93
-rw-r--r--spec/features/issues/filter_issues_spec.rb10
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb35
-rw-r--r--spec/features/issues/new_branch_button_spec.rb8
-rw-r--r--spec/features/issues_spec.rb28
-rw-r--r--spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb69
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb17
-rw-r--r--spec/features/merge_requests/deleted_source_branch_spec.rb30
-rw-r--r--spec/features/merge_requests/diff_notes_resolve_spec.rb4
-rw-r--r--spec/features/merge_requests/merge_request_versions_spec.rb7
-rw-r--r--spec/features/merge_requests/merge_when_build_succeeds_spec.rb4
-rw-r--r--spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb (renamed from spec/features/merge_requests/only_allow_merge_if_build_succeeds.rb)45
-rw-r--r--spec/features/merge_requests/toggle_whitespace_changes_spec.rb (renamed from spec/features/merge_requests/toggle_whitespace_changes.rb)0
-rw-r--r--spec/features/profile_spec.rb29
-rw-r--r--spec/features/profiles/chat_names_spec.rb77
-rw-r--r--spec/features/projects/builds_spec.rb195
-rw-r--r--spec/features/projects/commits/cherry_pick_spec.rb2
-rw-r--r--spec/features/projects/files/browse_files_spec.rb21
-rw-r--r--spec/features/projects/labels/subscription_spec.rb74
-rw-r--r--spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb4
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/new_project_spec.rb19
-rw-r--r--spec/features/projects/pipelines_spec.rb3
-rw-r--r--spec/features/projects/project_settings_spec.rb17
-rw-r--r--spec/features/projects/ref_switcher_spec.rb14
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb48
-rw-r--r--spec/features/projects/services/slack_service_spec.rb (renamed from spec/features/projects/slack_service/slack_service_spec.rb)0
-rw-r--r--spec/features/search_spec.rb26
-rw-r--r--spec/features/security/project/snippet/internal_access_spec.rb78
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb16
-rw-r--r--spec/features/security/project/snippet/public_access_spec.rb116
-rw-r--r--spec/features/snippets/explore_spec.rb16
-rw-r--r--spec/features/snippets/public_snippets_spec.rb19
-rw-r--r--spec/features/snippets/search_snippets_spec.rb66
-rw-r--r--spec/features/todos/todos_spec.rb6
-rw-r--r--spec/features/unsubscribe_links_spec.rb14
-rw-r--r--spec/features/users_spec.rb19
52 files changed, 1448 insertions, 408 deletions
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 a92075fec8f..4aa84fb65d9 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -380,6 +380,25 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_board_cards(1, 5)
end
+
+ it 'creates new list from a new label' do
+ click_button 'Create new list'
+
+ wait_for_ajax
+
+ click_link 'Create new label'
+
+ fill_in('new_label_name', with: 'Testing New Label')
+
+ first('.suggest-colors a').click
+
+ click_button 'Create'
+
+ wait_for_ajax
+ wait_for_vue_resource
+
+ expect(page).to have_selector('.board', count: 5)
+ end
end
end
@@ -640,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/commits_spec.rb b/spec/features/commits_spec.rb
index 338c53f08a6..44646ffc602 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -12,11 +12,15 @@ describe 'Commits' do
end
let!(:pipeline) do
- FactoryGirl.create :ci_pipeline, project: project, sha: project.commit.sha
+ create(:ci_pipeline,
+ project: project,
+ ref: project.default_branch,
+ sha: project.commit.sha,
+ status: :success)
end
context 'commit status is Generic Commit Status' do
- let!(:status) { FactoryGirl.create :generic_commit_status, pipeline: pipeline }
+ let!(:status) { create(:generic_commit_status, pipeline: pipeline) }
before do
project.team << [@user, :reporter]
@@ -39,7 +43,7 @@ describe 'Commits' do
end
context 'commit status is Ci Build' do
- let!(:build) { FactoryGirl.create :ci_build, pipeline: pipeline }
+ let!(:build) { create(:ci_build, pipeline: pipeline) }
let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
context 'when logged as developer' do
@@ -48,13 +52,22 @@ describe 'Commits' do
end
describe 'Project commits' do
+ let!(:pipeline_from_other_branch) do
+ create(:ci_pipeline,
+ project: project,
+ ref: 'fix',
+ sha: project.commit.sha,
+ status: :failed)
+ end
+
before do
visit namespace_project_commits_path(project.namespace, project, :master)
end
- it 'shows build status' do
+ it 'shows correct build status from default branch' do
page.within("//li[@id='commit-#{pipeline.short_sha}']") do
- expect(page).to have_css(".ci-status-link")
+ expect(page).to have_css('.ci-status-link')
+ expect(page).to have_css('.ci-status-icon-success')
end
end
end
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/global_search_spec.rb b/spec/features/global_search_spec.rb
new file mode 100644
index 00000000000..f6409e00f22
--- /dev/null
+++ b/spec/features/global_search_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+feature 'Global search', feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ before do
+ project.team << [user, :master]
+ login_with(user)
+ end
+
+ describe 'I search through the issues and I see pagination' do
+ before do
+ allow_any_instance_of(Gitlab::SearchResults).to receive(:per_page).and_return(1)
+ create_list(:issue, 2, project: project, title: 'initial')
+ end
+
+ it "has a pagination" do
+ visit dashboard_projects_path
+
+ fill_in "search", with: "initial"
+ click_button "Go"
+
+ select_filter("Issues")
+ expect(page).to have_selector('.gl-pagination .page', count: 2)
+ end
+ end
+end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
new file mode 100644
index 00000000000..476eca17a9d
--- /dev/null
+++ b/spec/features/groups/issues_spec.rb
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+feature 'Group issues page', feature: true do
+ let(:path) { issues_group_path(group) }
+ let(:issuable) { create(:issue, project: project, title: "this is my created issuable")}
+
+ include_examples 'project features apply to issuables', Issue
+end
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/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb
new file mode 100644
index 00000000000..a2791b57544
--- /dev/null
+++ b/spec/features/groups/merge_requests_spec.rb
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+feature 'Group merge requests page', feature: true do
+ let(:path) { merge_requests_group_path(group) }
+ let(:issuable) { create(:merge_request, source_project: project, target_project: project, title: "this is my created issuable")}
+
+ include_examples 'project features apply to issuables', MergeRequest
+end
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/new_branch_button_spec.rb b/spec/features/issues/new_branch_button_spec.rb
index fb0c4704285..ab901e74617 100644
--- a/spec/features/issues/new_branch_button_spec.rb
+++ b/spec/features/issues/new_branch_button_spec.rb
@@ -18,22 +18,24 @@ feature 'Start new branch from an issue', feature: true do
end
context "when there is a referenced merge request" do
- let(:note) do
- create(:note, :on_issue, :system, project: project,
+ let!(:note) do
+ create(:note, :on_issue, :system, project: project, noteable: issue,
note: "Mentioned in !#{referenced_mr.iid}")
end
+
let(:referenced_mr) do
create(:merge_request, :simple, source_project: project, target_project: project,
description: "Fixes ##{issue.iid}", author: user)
end
before do
- issue.notes << note
+ referenced_mr.cache_merge_request_closes_issues!(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
it "hides the new branch button", js: true do
+ expect(page).to have_css('#new-branch .unavailable')
expect(page).not_to have_css('#new-branch .available')
expect(page).to have_content /1 Related Merge Request/
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index b504329656f..5c958455604 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
describe 'Issues', feature: true do
include IssueHelpers
include SortingHelper
+ include WaitForAjax
let(:project) { create(:project) }
@@ -368,6 +369,28 @@ describe 'Issues', feature: true do
end
end
+ 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
+
+ it 'changes incoming email address token', js: true do
+ find('.issue-email-modal-btn').click
+ previous_token = find('input#issue_email').value
+
+ find('.incoming-email-token-reset').click
+ wait_for_ajax
+
+ expect(find('input#issue_email').value).not_to eq(previous_token)
+ end
+ end
+
describe 'update labels from issue#show', js: true do
let(:issue) { create(:issue, project: project, author: @user, assignee: @user) }
let!(:label) { create(:label, project: project) }
@@ -553,9 +576,12 @@ describe 'Issues', feature: true do
end
end
- xdescribe 'new issue by email' 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_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
new file mode 100644
index 00000000000..7f11db3c417
--- /dev/null
+++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
@@ -0,0 +1,69 @@
+require 'spec_helper'
+
+feature 'Check if mergeable with unresolved discussions', js: true, feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let!(:merge_request) { create(:merge_request_with_diff_notes, source_project: project, author: user) }
+
+ before do
+ login_as user
+ project.team << [user, :master]
+ end
+
+ context 'when project.only_allow_merge_if_all_discussions_are_resolved == true' do
+ before do
+ project.update_column(:only_allow_merge_if_all_discussions_are_resolved, true)
+ end
+
+ context 'with unresolved discussions' do
+ it 'does not allow to merge' do
+ visit_merge_request(merge_request)
+
+ expect(page).not_to have_button 'Accept Merge Request'
+ expect(page).to have_content('This merge request has unresolved discussions')
+ end
+ end
+
+ context 'with all discussions resolved' do
+ before do
+ merge_request.discussions.each { |d| d.resolve!(user) }
+ end
+
+ it 'allows MR to be merged' do
+ visit_merge_request(merge_request)
+
+ expect(page).to have_button 'Accept Merge Request'
+ end
+ end
+ end
+
+ context 'when project.only_allow_merge_if_all_discussions_are_resolved == false' do
+ before do
+ project.update_column(:only_allow_merge_if_all_discussions_are_resolved, false)
+ end
+
+ context 'with unresolved discussions' do
+ it 'does not allow to merge' do
+ visit_merge_request(merge_request)
+
+ expect(page).to have_button 'Accept Merge Request'
+ end
+ end
+
+ context 'with all discussions resolved' do
+ before do
+ merge_request.discussions.each { |d| d.resolve!(user) }
+ end
+
+ it 'allows MR to be merged' do
+ visit_merge_request(merge_request)
+
+ expect(page).to have_button 'Accept Merge Request'
+ end
+ end
+ end
+
+ def visit_merge_request(merge_request)
+ visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request)
+ end
+end
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/profile_spec.rb b/spec/features/profile_spec.rb
index c3d8c349ca4..7a562b5e03d 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -32,4 +32,33 @@ describe 'Profile account page', feature: true do
expect(current_path).to eq(profile_account_path)
end
end
+
+ describe 'when I reset private token' do
+ before do
+ visit profile_account_path
+ end
+
+ it 'resets private token' do
+ previous_token = find("#private-token").value
+
+ click_link('Reset private token')
+
+ expect(find('#private-token').value).not_to eq(previous_token)
+ end
+ end
+
+ describe 'when I reset incoming email token' do
+ before do
+ allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
+ visit profile_account_path
+ end
+
+ it 'resets incoming email token' do
+ previous_token = find('#incoming-email-token').value
+
+ click_link('Reset incoming email token')
+
+ expect(find('#incoming-email-token').value).not_to eq(previous_token)
+ end
+ 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/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb
new file mode 100644
index 00000000000..69295e450d0
--- /dev/null
+++ b/spec/features/projects/files/browse_files_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+feature 'user checks git blame', feature: true do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_with(user)
+ visit namespace_project_tree_path(project.namespace, project, project.default_branch)
+ end
+
+ scenario "can see blame of '.gitignore'" do
+ click_link ".gitignore"
+ click_link 'Blame'
+
+ expect(page).to have_content "*.rb"
+ expect(page).to have_content "Dmitriy Zaporozhets"
+ expect(page).to have_content "Initial commit"
+ end
+end
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/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb
index b3ba40b35af..472491188c9 100644
--- a/spec/features/projects/ref_switcher_spec.rb
+++ b/spec/features/projects/ref_switcher_spec.rb
@@ -22,8 +22,20 @@ feature 'Ref switcher', feature: true, js: true do
input.native.send_keys :down
input.native.send_keys :down
input.native.send_keys :enter
+ end
+
+ expect(page).to have_title 'expand-collapse-files'
+ end
+
+ it "user selects ref with special characters" do
+ click_button 'master'
+ wait_for_ajax
- expect(page).to have_content 'expand-collapse-files'
+ page.within '.project-refs-form' do
+ page.fill_in 'Search branches and tags', with: "'test'"
+ click_link "'test'"
end
+
+ expect(page).to have_title "'test'"
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/search_spec.rb b/spec/features/search_spec.rb
index 1806200c82c..caecd027aaa 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -100,6 +100,32 @@ describe "Search", feature: true do
expect(page).to have_link(snippet.title)
end
+
+ it 'finds a commit' do
+ visit namespace_project_path(project.namespace, project)
+
+ page.within '.search' do
+ fill_in 'search', with: 'add'
+ click_button 'Go'
+ end
+
+ click_link "Commits"
+
+ expect(page).to have_selector('.commit-row-description')
+ end
+
+ it 'finds a code' do
+ visit namespace_project_path(project.namespace, project)
+
+ page.within '.search' do
+ fill_in 'search', with: 'def'
+ click_button 'Go'
+ end
+
+ click_link "Code"
+
+ expect(page).to have_selector('.file-content .code')
+ end
end
describe 'Right header search field', feature: true do
diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb
index db53a9cec97..49deacc5c74 100644
--- a/spec/features/security/project/snippet/internal_access_spec.rb
+++ b/spec/features/security/project/snippet/internal_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Internal Project Snippets Access", feature: true do
include AccessMatchers
- let(:project) { create(:project, :internal) }
+ let(:project) { create(:empty_project, :internal) }
let(:owner) { project.owner }
let(:master) { create(:user) }
@@ -48,31 +48,63 @@ describe "Internal Project Snippets Access", feature: true do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /:project_path/snippets/:id for an internal snippet" do
- subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) }
+ describe "GET /:project_path/snippets/:id" do
+ context "for an internal snippet" do
+ subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) }
- it { is_expected.to be_allowed_for :admin }
- it { is_expected.to be_allowed_for owner }
- it { is_expected.to be_allowed_for master }
- it { is_expected.to be_allowed_for developer }
- it { is_expected.to be_allowed_for reporter }
- it { is_expected.to be_allowed_for guest }
- it { is_expected.to be_allowed_for :user }
- it { is_expected.to be_denied_for :external }
- it { is_expected.to be_denied_for :visitor }
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
+
+ context "for a private snippet" do
+ subject { namespace_project_snippet_path(project.namespace, project, private_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_denied_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
end
- describe "GET /:project_path/snippets/:id for a private snippet" do
- subject { namespace_project_snippet_path(project.namespace, project, private_snippet) }
+ describe "GET /:project_path/snippets/:id/raw" do
+ context "for an internal snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) }
- it { is_expected.to be_allowed_for :admin }
- it { is_expected.to be_allowed_for owner }
- it { is_expected.to be_allowed_for master }
- it { is_expected.to be_allowed_for developer }
- it { is_expected.to be_allowed_for reporter }
- it { is_expected.to be_allowed_for guest }
- it { is_expected.to be_denied_for :user }
- it { is_expected.to be_denied_for :external }
- it { is_expected.to be_denied_for :visitor }
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
+
+ context "for a private snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_denied_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
end
end
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index d23d645c8e5..a1bfc076d99 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Private Project Snippets Access", feature: true do
include AccessMatchers
- let(:project) { create(:project, :private) }
+ let(:project) { create(:empty_project, :private) }
let(:owner) { project.owner }
let(:master) { create(:user) }
@@ -60,4 +60,18 @@ describe "Private Project Snippets Access", feature: true do
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor }
end
+
+ describe "GET /:project_path/snippets/:id/raw for a private snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_denied_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
end
diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb
index e3665b6116a..30bcd87ef04 100644
--- a/spec/features/security/project/snippet/public_access_spec.rb
+++ b/spec/features/security/project/snippet/public_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Public Project Snippets Access", feature: true do
include AccessMatchers
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:owner) { project.owner }
let(:master) { create(:user) }
@@ -49,45 +49,91 @@ describe "Public Project Snippets Access", feature: true do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /:project_path/snippets/:id for a public snippet" do
- subject { namespace_project_snippet_path(project.namespace, project, public_snippet) }
+ describe "GET /:project_path/snippets/:id" do
+ context "for a public snippet" do
+ subject { namespace_project_snippet_path(project.namespace, project, public_snippet) }
- it { is_expected.to be_allowed_for :admin }
- it { is_expected.to be_allowed_for owner }
- it { is_expected.to be_allowed_for master }
- it { is_expected.to be_allowed_for developer }
- it { is_expected.to be_allowed_for reporter }
- it { is_expected.to be_allowed_for guest }
- it { is_expected.to be_allowed_for :user }
- it { is_expected.to be_allowed_for :external }
- it { is_expected.to be_allowed_for :visitor }
- end
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_allowed_for :external }
+ it { is_expected.to be_allowed_for :visitor }
+ end
- describe "GET /:project_path/snippets/:id for an internal snippet" do
- subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) }
+ context "for an internal snippet" do
+ subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) }
- it { is_expected.to be_allowed_for :admin }
- it { is_expected.to be_allowed_for owner }
- it { is_expected.to be_allowed_for master }
- it { is_expected.to be_allowed_for developer }
- it { is_expected.to be_allowed_for reporter }
- it { is_expected.to be_allowed_for guest }
- it { is_expected.to be_allowed_for :user }
- it { is_expected.to be_denied_for :external }
- it { is_expected.to be_denied_for :visitor }
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
+
+ context "for a private snippet" do
+ subject { namespace_project_snippet_path(project.namespace, project, private_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_denied_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
end
- describe "GET /:project_path/snippets/:id for a private snippet" do
- subject { namespace_project_snippet_path(project.namespace, project, private_snippet) }
+ describe "GET /:project_path/snippets/:id/raw" do
+ context "for a public snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, public_snippet) }
- it { is_expected.to be_allowed_for :admin }
- it { is_expected.to be_allowed_for owner }
- it { is_expected.to be_allowed_for master }
- it { is_expected.to be_allowed_for developer }
- it { is_expected.to be_allowed_for reporter }
- it { is_expected.to be_allowed_for guest }
- it { is_expected.to be_denied_for :user }
- it { is_expected.to be_denied_for :external }
- it { is_expected.to be_denied_for :visitor }
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_allowed_for :external }
+ it { is_expected.to be_allowed_for :visitor }
+ end
+
+ context "for an internal snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_allowed_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
+
+ context "for a private snippet" do
+ subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) }
+
+ it { is_expected.to be_allowed_for :admin }
+ it { is_expected.to be_allowed_for owner }
+ it { is_expected.to be_allowed_for master }
+ it { is_expected.to be_allowed_for developer }
+ it { is_expected.to be_allowed_for reporter }
+ it { is_expected.to be_allowed_for guest }
+ it { is_expected.to be_denied_for :user }
+ it { is_expected.to be_denied_for :external }
+ it { is_expected.to be_denied_for :visitor }
+ end
end
end
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/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb
new file mode 100644
index 00000000000..34300ccb940
--- /dev/null
+++ b/spec/features/snippets/public_snippets_spec.rb
@@ -0,0 +1,19 @@
+require 'rails_helper'
+
+feature 'Public Snippets', feature: true do
+ scenario 'Unauthenticated user should see public snippets' do
+ public_snippet = create(:personal_snippet, :public)
+
+ visit snippet_path(public_snippet)
+
+ expect(page).to have_content(public_snippet.content)
+ end
+
+ scenario 'Unauthenticated user should see raw public snippets' do
+ public_snippet = create(:personal_snippet, :public)
+
+ visit raw_snippet_path(public_snippet)
+
+ expect(page).to have_content(public_snippet.content)
+ 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