summaryrefslogtreecommitdiff
path: root/spec/features/dashboard
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2017-08-02 16:58:28 -0700
committerStan Hu <stanhu@gmail.com>2017-08-02 16:58:28 -0700
commit408df2edcbd5f3f93ef5541bac9de2b71ba4f0ea (patch)
tree708ae61f9683b48f436f7577d1fad98f30e100fc /spec/features/dashboard
parent3f81586ef0ab20533b8da1213bd9f60e1786dbaa (diff)
parentfaa2a123911eaf84bb57163ea7af759d4632601b (diff)
downloadgitlab-ce-408df2edcbd5f3f93ef5541bac9de2b71ba4f0ea.tar.gz
Merge branch 'master' into sh-headless-chrome-support
Diffstat (limited to 'spec/features/dashboard')
-rw-r--r--spec/features/dashboard/active_tab_spec.rb4
-rw-r--r--spec/features/dashboard/activity_spec.rb161
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb6
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb8
-rw-r--r--spec/features/dashboard/group_spec.rb4
-rw-r--r--spec/features/dashboard/groups_list_spec.rb12
-rw-r--r--spec/features/dashboard/help_spec.rb4
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb4
-rw-r--r--spec/features/dashboard/issues_filter_spec.rb115
-rw-r--r--spec/features/dashboard/issues_spec.rb22
-rw-r--r--spec/features/dashboard/label_filter_spec.rb8
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb112
-rw-r--r--spec/features/dashboard/milestone_filter_spec.rb26
-rw-r--r--spec/features/dashboard/milestone_tabs_spec.rb4
-rw-r--r--spec/features/dashboard/milestones_spec.rb29
-rw-r--r--spec/features/dashboard/project_member_activity_index_spec.rb4
-rw-r--r--spec/features/dashboard/projects_spec.rb91
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb4
-rw-r--r--spec/features/dashboard/snippets_spec.rb6
-rw-r--r--spec/features/dashboard/todos/target_state_spec.rb65
-rw-r--r--spec/features/dashboard/todos/todos_filtering_spec.rb153
-rw-r--r--spec/features/dashboard/todos/todos_sorting_spec.rb99
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb338
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb8
24 files changed, 1201 insertions, 86 deletions
diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb
index f32f23faebc..ee2554cbd48 100644
--- a/spec/features/dashboard/active_tab_spec.rb
+++ b/spec/features/dashboard/active_tab_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Active Tab', js: true, feature: true do
+RSpec.describe 'Dashboard Active Tab', js: true do
before do
- gitlab_sign_in :user
+ sign_in(create(:user))
end
shared_examples 'page has active tab' do |title|
diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb
index 1e9cabe7850..a96270c9147 100644
--- a/spec/features/dashboard/activity_spec.rb
+++ b/spec/features/dashboard/activity_spec.rb
@@ -1,11 +1,162 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Activity', feature: true do
+feature 'Dashboard > Activity' do
+ let(:user) { create(:user) }
+
before do
- gitlab_sign_in(create :user)
- visit activity_dashboard_path
+ sign_in(user)
+ end
+
+ context 'rss' do
+ before do
+ visit activity_dashboard_path
+ end
+
+ it_behaves_like "it has an RSS button with current_user's RSS token"
+ it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token"
end
- it_behaves_like "it has an RSS button with current_user's RSS token"
- it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token"
+ context 'event filters', :js do
+ let(:project) { create(:empty_project) }
+
+ let(:merge_request) do
+ create(:merge_request, author: user, source_project: project, target_project: project)
+ end
+
+ let(:push_event_data) do
+ {
+ before: Gitlab::Git::BLANK_SHA,
+ after: '0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e',
+ ref: 'refs/heads/new_design',
+ user_id: user.id,
+ user_name: user.name,
+ repository: {
+ name: project.name,
+ url: 'localhost/rubinius',
+ description: '',
+ homepage: 'localhost/rubinius',
+ private: true
+ }
+ }
+ end
+
+ let(:note) { create(:note, project: project, noteable: merge_request) }
+
+ let!(:push_event) do
+ create(:event, :pushed, data: push_event_data, project: project, author: user)
+ end
+
+ let!(:merged_event) do
+ create(:event, :merged, project: project, target: merge_request, author: user)
+ end
+
+ let!(:joined_event) do
+ create(:event, :joined, project: project, author: user)
+ end
+
+ let!(:closed_event) do
+ create(:event, :closed, project: project, target: merge_request, author: user)
+ end
+
+ let!(:comments_event) do
+ create(:event, :commented, project: project, target: note, author: user)
+ end
+
+ before do
+ project.add_master(user)
+
+ visit activity_dashboard_path
+ wait_for_requests
+ end
+
+ scenario 'user should see all events' do
+ within '.content_list' do
+ expect(page).to have_content('pushed new branch')
+ expect(page).to have_content('joined')
+ expect(page).to have_content('accepted')
+ expect(page).to have_content('closed')
+ expect(page).to have_content('commented on')
+ end
+ end
+
+ scenario 'user should see only pushed events' do
+ click_link('Push events')
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).to have_content('pushed new branch')
+ expect(page).not_to have_content('joined')
+ expect(page).not_to have_content('accepted')
+ expect(page).not_to have_content('closed')
+ expect(page).not_to have_content('commented on')
+ end
+ end
+
+ scenario 'user should see only merged events' do
+ click_link('Merge events')
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).not_to have_content('pushed new branch')
+ expect(page).not_to have_content('joined')
+ expect(page).to have_content('accepted')
+ expect(page).not_to have_content('closed')
+ expect(page).not_to have_content('commented on')
+ end
+ end
+
+ scenario 'user should see only issues events' do
+ click_link('Issue events')
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).not_to have_content('pushed new branch')
+ expect(page).not_to have_content('joined')
+ expect(page).not_to have_content('accepted')
+ expect(page).to have_content('closed')
+ expect(page).not_to have_content('commented on')
+ end
+ end
+
+ scenario 'user should see only comments events' do
+ click_link('Comments')
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).not_to have_content('pushed new branch')
+ expect(page).not_to have_content('joined')
+ expect(page).not_to have_content('accepted')
+ expect(page).not_to have_content('closed')
+ expect(page).to have_content('commented on')
+ end
+ end
+
+ scenario 'user should see only joined events' do
+ click_link('Team')
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).not_to have_content('pushed new branch')
+ expect(page).to have_content('joined')
+ expect(page).not_to have_content('accepted')
+ expect(page).not_to have_content('closed')
+ expect(page).not_to have_content('commented on')
+ end
+ end
+
+ scenario 'user see selected event after page reloading' do
+ click_link('Push events')
+ wait_for_requests
+ visit activity_dashboard_path
+ wait_for_requests
+
+ within '.content_list' do
+ expect(page).to have_content('pushed new branch')
+ expect(page).not_to have_content('joined')
+ expect(page).not_to have_content('accepted')
+ expect(page).not_to have_content('closed')
+ expect(page).not_to have_content('commented on')
+ end
+ end
+ end
end
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index a5ba3e7e3cf..ceac6a0a27c 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -1,15 +1,15 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Archived Project', feature: true do
+RSpec.describe 'Dashboard Archived Project' do
let(:user) { create :user }
let(:project) { create :project}
- let(:archived_project) { create(:project, :archived) }
+ let(:archived_project) { create(:empty_project, :archived) }
before do
project.team << [user, :master]
archived_project.team << [user, :master]
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_projects_path
end
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index 6931d0a840e..05dcdd93f37 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-feature 'Tooltips on .timeago dates', feature: true, js: true do
+feature 'Tooltips on .timeago dates', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
let(:expected_format) { created_date.in_time_zone.strftime('%b %-d, %Y %l:%M%P') }
@@ -13,7 +13,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do
Event.create( project: project, author_id: user.id, action: Event::JOINED,
updated_at: created_date, created_at: created_date)
- gitlab_sign_in user
+ sign_in user
visit user_path(user)
wait_for_requests()
@@ -30,7 +30,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do
project.team << [user, :master]
create(:snippet, author: user, updated_at: created_date, created_at: created_date)
- gitlab_sign_in user
+ sign_in user
visit user_snippets_path(user)
wait_for_requests()
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 6c8958cb376..1c4699c3818 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Group', feature: true do
+RSpec.describe 'Dashboard Group' do
before do
- gitlab_sign_in(:user)
+ sign_in(create(:user))
end
it 'creates new group', js: true do
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index 1ecc27a0cca..bb4f3d9ecb4 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Dashboard Groups page', js: true, feature: true do
+feature 'Dashboard Groups page', :js do
let!(:user) { create :user }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, :nested) }
@@ -10,7 +10,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
nested_group.add_owner(user)
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_groups_path
expect(page).to have_content(group.full_name)
@@ -23,7 +23,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
nested_group.add_owner(user)
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_groups_path
end
@@ -41,7 +41,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
fill_in 'filter_groups', with: group.name
wait_for_requests
- fill_in 'filter_groups', with: ""
+ fill_in 'filter_groups', with: ''
wait_for_requests
expect(page).to have_content(group.full_name)
@@ -58,7 +58,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
subgroup.add_owner(user)
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_groups_path
end
@@ -98,7 +98,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
allow(Kaminari.config).to receive(:default_per_page).and_return(1)
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_groups_path
end
diff --git a/spec/features/dashboard/help_spec.rb b/spec/features/dashboard/help_spec.rb
index 25b0f40c9cd..68bfbf22736 100644
--- a/spec/features/dashboard/help_spec.rb
+++ b/spec/features/dashboard/help_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Help', feature: true do
+RSpec.describe 'Dashboard Help' do
before do
- gitlab_sign_in(:user)
+ sign_in(create(:user))
end
it 'renders correctly markdown' do
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index 8a8a20fd5b1..ae68b0f65d5 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Navigation bar counter', feature: true, caching: true do
+describe 'Navigation bar counter', :use_clean_rails_memory_store_caching do
let(:user) { create(:user) }
let(:project) { create(:empty_project, namespace: user.namespace) }
let(:issue) { create(:issue, project: project) }
@@ -9,7 +9,7 @@ describe 'Navigation bar counter', feature: true, caching: true do
before do
issue.assignees = [user]
merge_request.update(assignee: user)
- gitlab_sign_in(user)
+ sign_in(user)
end
it 'reflects dashboard issues count' do
diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb
new file mode 100644
index 00000000000..0ce642f32f2
--- /dev/null
+++ b/spec/features/dashboard/issues_filter_spec.rb
@@ -0,0 +1,115 @@
+require 'spec_helper'
+
+feature 'Dashboard Issues filtering', :js do
+ include SortingHelper
+
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project) }
+ let(:milestone) { create(:milestone, project: project) }
+
+ let!(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
+ let!(:issue2) { create(:issue, project: project, author: user, assignees: [user], milestone: milestone) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ visit_issues
+ end
+
+ context 'filtering by milestone' do
+ it 'shows all issues with no milestone' do
+ show_milestone_dropdown
+
+ click_link 'No Milestone'
+
+ expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
+ expect(page).to have_selector('.issue', count: 1)
+ end
+
+ it 'shows all issues with any milestone' do
+ show_milestone_dropdown
+
+ click_link 'Any Milestone'
+
+ expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2)
+ expect(page).to have_selector('.issue', count: 2)
+ end
+
+ it 'shows all issues with the selected milestone' do
+ show_milestone_dropdown
+
+ page.within '.dropdown-content' do
+ click_link milestone.title
+ end
+
+ expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1)
+ expect(page).to have_selector('.issue', count: 1)
+ end
+
+ it 'updates atom feed link' do
+ visit_issues(milestone_title: '', assignee_id: user.id)
+
+ link = find('.nav-controls a[title="Subscribe"]')
+ params = CGI.parse(URI.parse(link[:href]).query)
+ auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
+ auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
+
+ expect(params).to include('rss_token' => [user.rss_token])
+ expect(params).to include('milestone_title' => [''])
+ expect(params).to include('assignee_id' => [user.id.to_s])
+ expect(auto_discovery_params).to include('rss_token' => [user.rss_token])
+ expect(auto_discovery_params).to include('milestone_title' => [''])
+ expect(auto_discovery_params).to include('assignee_id' => [user.id.to_s])
+ end
+ end
+
+ context 'filtering by label' do
+ let(:label) { create(:label, project: project) }
+ let!(:label_link) { create(:label_link, label: label, target: issue) }
+
+ it 'shows all issues without filter' do
+ page.within 'ul.content-list' do
+ expect(page).to have_content issue.title
+ expect(page).to have_content issue2.title
+ end
+ end
+
+ it 'shows all issues with the selected label' do
+ page.within '.labels-filter' do
+ find('.dropdown').click
+ click_link label.title
+ end
+
+ page.within 'ul.content-list' do
+ expect(page).to have_content issue.title
+ expect(page).not_to have_content issue2.title
+ end
+ end
+ end
+
+ context 'sorting' do
+ it 'shows sorted issues' do
+ sorting_by('Oldest updated')
+ visit_issues
+
+ expect(find('.issues-filters')).to have_content('Oldest updated')
+ end
+
+ it 'keeps sorting issues after visiting Projects Issues page' do
+ sorting_by('Oldest updated')
+ visit project_issues_path(project)
+
+ expect(find('.issues-filters')).to have_content('Oldest updated')
+ end
+ end
+
+ def show_milestone_dropdown
+ click_button 'Milestone'
+ expect(page).to have_selector('.dropdown-content', visible: true)
+ end
+
+ def visit_issues(*args)
+ visit issues_dashboard_path(*args)
+ end
+end
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index f79fc1b5a01..a11499ba191 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -1,7 +1,8 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Issues', feature: true do
+RSpec.describe 'Dashboard Issues' do
let(:current_user) { create :user }
+ let(:user) { current_user } # Shared examples depend on this being available
let!(:public_project) { create(:empty_project, :public) }
let(:project) { create(:empty_project) }
let(:project_with_issues_disabled) { create(:empty_project, :issues_disabled) }
@@ -12,7 +13,7 @@ RSpec.describe 'Dashboard Issues', feature: true do
before do
[project, project_with_issues_disabled].each { |project| project.team << [current_user, :master] }
- gitlab_sign_in(current_user)
+ sign_in(current_user)
visit issues_dashboard_path(assignee_id: current_user.id)
end
@@ -59,6 +60,11 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).to have_content(other_issue.title)
end
+ it 'state filter tabs work' do
+ find('#state-closed').click
+ expect(page).to have_current_path(issues_dashboard_url(assignee_id: current_user.id, state: 'closed'), url: true)
+ end
+
it_behaves_like "it has an RSS button with current_user's RSS token"
it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token"
end
@@ -72,5 +78,17 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).not_to have_content(project_with_issues_disabled.name_with_namespace)
end
end
+
+ it 'shows the new issue page', :js do
+ find('.new-project-item-select-button').trigger('click')
+ wait_for_requests
+ find('.select2-results li').click
+
+ expect(page).to have_current_path("/#{project.path_with_namespace}/issues/new")
+
+ page.within('#content-body') do
+ expect(page).to have_selector('.issue-form')
+ end
+ end
end
end
diff --git a/spec/features/dashboard/label_filter_spec.rb b/spec/features/dashboard/label_filter_spec.rb
index 88bbb9e75b9..8e19fb93665 100644
--- a/spec/features/dashboard/label_filter_spec.rb
+++ b/spec/features/dashboard/label_filter_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-describe 'Dashboard > label filter', feature: true, js: true do
+describe 'Dashboard > label filter', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
- let(:project2) { create(:project, name: 'test2', path: 'test2', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project2) { create(:empty_project, name: 'test2', path: 'test2', namespace: user.namespace) }
let(:label) { create(:label, title: 'bug', color: '#ff0000') }
let(:label2) { create(:label, title: 'bug') }
@@ -11,7 +11,7 @@ describe 'Dashboard > label filter', feature: true, js: true do
project.labels << label
project2.labels << label2
- gitlab_sign_in(user)
+ sign_in(user)
visit issues_dashboard_path
end
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index e521b6ed4bc..a406cd89ead 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -1,18 +1,25 @@
require 'spec_helper'
-describe 'Dashboard Merge Requests' do
+feature 'Dashboard Merge Requests' do
+ include FilterItemSelectHelper
+ include SortingHelper
+
let(:current_user) { create :user }
let(:project) { create(:empty_project) }
- let(:project_with_merge_requests_disabled) { create(:empty_project, :merge_requests_disabled) }
- before do
- [project, project_with_merge_requests_disabled].each { |project| project.team << [current_user, :master] }
+ let(:public_project) { create(:empty_project, :public, :repository) }
+ let(:forked_project) { Projects::ForkService.new(public_project, current_user).execute }
- gitlab_sign_in(current_user)
+ before do
+ project.add_master(current_user)
+ sign_in(current_user)
end
- describe 'new merge request dropdown' do
+ context 'new merge request dropdown' do
+ let(:project_with_disabled_merge_requests) { create(:empty_project, :merge_requests_disabled) }
+
before do
+ project_with_disabled_merge_requests.add_master(current_user)
visit merge_requests_dashboard_path
end
@@ -21,26 +28,103 @@ describe 'Dashboard Merge Requests' do
page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace)
- expect(page).not_to have_content(project_with_merge_requests_disabled.name_with_namespace)
+ expect(page).not_to have_content(project_with_disabled_merge_requests.name_with_namespace)
end
end
end
- it 'should show an empty state' do
- visit merge_requests_dashboard_path(assignee_id: current_user.id)
+ context 'no merge requests exist' do
+ it 'shows an empty state' do
+ visit merge_requests_dashboard_path(assignee_id: current_user.id)
- expect(page).to have_selector('.empty-state')
+ expect(page).to have_selector('.empty-state')
+ end
end
- context 'if there are merge requests' do
+ context 'merge requests exist' do
+ let!(:assigned_merge_request) do
+ create(:merge_request, assignee: current_user, target_project: project, source_project: project)
+ end
+
+ let!(:assigned_merge_request_from_fork) do
+ create(:merge_request,
+ source_branch: 'markdown', assignee: current_user,
+ target_project: public_project, source_project: forked_project
+ )
+ end
+
+ let!(:authored_merge_request) do
+ create(:merge_request,
+ source_branch: 'markdown', author: current_user,
+ target_project: project, source_project: project
+ )
+ end
+
+ let!(:authored_merge_request_from_fork) do
+ create(:merge_request,
+ source_branch: 'feature_conflict',
+ author: current_user,
+ target_project: public_project, source_project: forked_project
+ )
+ end
+
+ let!(:other_merge_request) do
+ create(:merge_request,
+ source_branch: 'fix',
+ target_project: project, source_project: project
+ )
+ end
+
before do
- create(:merge_request, assignee: current_user, source_project: project)
+ visit merge_requests_dashboard_path(assignee_id: current_user.id)
+ end
+
+ it 'shows assigned merge requests' do
+ expect(page).to have_content(assigned_merge_request.title)
+ expect(page).to have_content(assigned_merge_request_from_fork.title)
+
+ expect(page).not_to have_content(authored_merge_request.title)
+ expect(page).not_to have_content(authored_merge_request_from_fork.title)
+ expect(page).not_to have_content(other_merge_request.title)
+ end
+
+ it 'shows authored merge requests', js: true do
+ filter_item_select('Any Assignee', '.js-assignee-search')
+ filter_item_select(current_user.to_reference, '.js-author-search')
+
+ expect(page).to have_content(authored_merge_request.title)
+ expect(page).to have_content(authored_merge_request_from_fork.title)
+
+ expect(page).not_to have_content(assigned_merge_request.title)
+ expect(page).not_to have_content(assigned_merge_request_from_fork.title)
+ expect(page).not_to have_content(other_merge_request.title)
+ end
+
+ it 'shows all merge requests', js: true do
+ filter_item_select('Any Assignee', '.js-assignee-search')
+ filter_item_select('Any Author', '.js-author-search')
+
+ expect(page).to have_content(authored_merge_request.title)
+ expect(page).to have_content(authored_merge_request_from_fork.title)
+ expect(page).to have_content(assigned_merge_request.title)
+ expect(page).to have_content(assigned_merge_request_from_fork.title)
+ expect(page).to have_content(other_merge_request.title)
+ end
+
+ it 'shows sorted merge requests' do
+ sorting_by('Oldest updated')
visit merge_requests_dashboard_path(assignee_id: current_user.id)
+
+ expect(find('.issues-filters')).to have_content('Oldest updated')
end
- it 'should not show an empty state' do
- expect(page).not_to have_selector('.empty-state')
+ it 'keeps sorting merge requests after visiting Projects MR page' do
+ sorting_by('Oldest updated')
+
+ visit project_merge_requests_path(project)
+
+ expect(find('.issues-filters')).to have_content('Oldest updated')
end
end
end
diff --git a/spec/features/dashboard/milestone_filter_spec.rb b/spec/features/dashboard/milestone_filter_spec.rb
index 295262980a6..5ebef1eb097 100644
--- a/spec/features/dashboard/milestone_filter_spec.rb
+++ b/spec/features/dashboard/milestone_filter_spec.rb
@@ -1,15 +1,17 @@
require 'spec_helper'
-describe 'Dashboard > milestone filter', :feature, :js do
+feature 'Dashboard > milestone filter', :js do
+ include FilterItemSelectHelper
+
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
- let(:milestone) { create(:milestone, title: "v1.0", project: project) }
- let(:milestone2) { create(:milestone, title: "v2.0", project: project) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:milestone) { create(:milestone, title: 'v1.0', project: project) }
+ let(:milestone2) { create(:milestone, title: 'v2.0', project: project) }
let!(:issue) { create :issue, author: user, project: project, milestone: milestone }
let!(:issue2) { create :issue, author: user, project: project, milestone: milestone2 }
before do
- gitlab_sign_in(user)
+ sign_in(user)
visit issues_dashboard_path(author_id: user.id)
end
@@ -22,17 +24,11 @@ describe 'Dashboard > milestone filter', :feature, :js do
end
context 'filtering by milestone' do
- milestone_select = '.js-milestone-select'
+ milestone_select_selector = '.js-milestone-select'
before do
- find(milestone_select).click
- wait_for_requests
-
- page.within('.dropdown-content') do
- click_link 'v1.0'
- end
-
- find(milestone_select).click
+ filter_item_select('v1.0', milestone_select_selector)
+ find(milestone_select_selector).click
wait_for_requests
end
@@ -49,7 +45,7 @@ describe 'Dashboard > milestone filter', :feature, :js do
expect(find('.milestone-filter')).not_to have_selector('.dropdown.open')
- find(milestone_select).click
+ find(milestone_select_selector).click
expect(find('.dropdown-content')).to have_selector('a.is-active', count: 1)
expect(find('.dropdown-content a.is-active')).to have_content('v1.0')
diff --git a/spec/features/dashboard/milestone_tabs_spec.rb b/spec/features/dashboard/milestone_tabs_spec.rb
index cc4193b180f..cf32d705365 100644
--- a/spec/features/dashboard/milestone_tabs_spec.rb
+++ b/spec/features/dashboard/milestone_tabs_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Dashboard milestone tabs', :js, :feature do
+describe 'Dashboard milestone tabs', :js do
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let!(:label) { create(:label, project: project) }
@@ -15,7 +15,7 @@ describe 'Dashboard milestone tabs', :js, :feature do
before do
project.add_master(user)
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_milestone_path(milestone.safe_title, title: milestone.title)
end
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
new file mode 100644
index 00000000000..488f7397c69
--- /dev/null
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+feature 'Dashboard > Milestones' do
+ describe 'as anonymous user' do
+ before do
+ visit dashboard_milestones_path
+ end
+
+ it 'is redirected to sign-in page' do
+ expect(current_path).to eq new_user_session_path
+ end
+ end
+
+ describe 'as logged-in user' do
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project, namespace: user.namespace) }
+ let!(:milestone) { create(:milestone, project: project) }
+ before do
+ project.team << [user, :master]
+ sign_in(user)
+ visit dashboard_milestones_path
+ end
+
+ it 'sees milestones' do
+ expect(current_path).to eq dashboard_milestones_path
+ expect(page).to have_content(milestone.title)
+ end
+ end
+end
diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb
index 0ba87d921d0..f3b538e490e 100644
--- a/spec/features/dashboard/project_member_activity_index_spec.rb
+++ b/spec/features/dashboard/project_member_activity_index_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Project member activity', feature: true, js: true do
+feature 'Project member activity', js: true do
let(:user) { create(:user) }
let(:project) { create(:empty_project, :public, name: 'x', namespace: user.namespace) }
@@ -10,7 +10,7 @@ feature 'Project member activity', feature: true, js: true do
def visit_activities_and_wait_with_event(event_type)
Event.create(project: project, author_id: user.id, action: event_type)
- visit activity_namespace_project_path(project.namespace, project)
+ visit activity_project_path(project)
wait_for_requests
end
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 2a8185ca669..abb9e5eef96 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -1,13 +1,19 @@
require 'spec_helper'
-RSpec.describe 'Dashboard Projects', feature: true do
+feature 'Dashboard Projects' do
let(:user) { create(:user) }
- let(:project) { create(:project, name: "awesome stuff") }
+ let(:project) { create(:project, name: 'awesome stuff') }
let(:project2) { create(:project, :public, name: 'Community project') }
before do
project.team << [user, :developer]
- gitlab_sign_in(user)
+ sign_in(user)
+ end
+
+ it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token" do
+ before do
+ visit dashboard_projects_path
+ end
end
it 'shows the project the user in a member of in the list' do
@@ -15,13 +21,33 @@ RSpec.describe 'Dashboard Projects', feature: true do
expect(page).to have_content('awesome stuff')
end
- it 'shows the last_activity_at attribute as the update date' do
- now = Time.now
- project.update_column(:last_activity_at, now)
-
+ it 'shows "New project" button' do
visit dashboard_projects_path
- expect(page).to have_xpath("//time[@datetime='#{now.getutc.iso8601}']")
+ page.within '#content-body' do
+ expect(page).to have_link('New project')
+ end
+ end
+
+ context 'when last_repository_updated_at, last_activity_at and update_at are present' do
+ it 'shows the last_repository_updated_at attribute as the update date' do
+ project.update_attributes!(last_repository_updated_at: Time.now, last_activity_at: 1.hour.ago)
+
+ visit dashboard_projects_path
+
+ expect(page).to have_xpath("//time[@datetime='#{project.last_repository_updated_at.getutc.iso8601}']")
+ end
+ end
+
+ context 'when last_repository_updated_at and last_activity_at are missing' do
+ it 'shows the updated_at attribute as the update date' do
+ project.update_attributes!(last_repository_updated_at: nil, last_activity_at: nil)
+ project.touch
+
+ visit dashboard_projects_path
+
+ expect(page).to have_xpath("//time[@datetime='#{project.updated_at.getutc.iso8601}']")
+ end
end
context 'when on Starred projects tab' do
@@ -35,8 +61,8 @@ RSpec.describe 'Dashboard Projects', feature: true do
end
end
- describe "with a pipeline", redis: true do
- let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) }
+ describe 'with a pipeline', clean_gitlab_redis_shared_state: true do
+ let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) }
before do
# Since the cache isn't updated when a new pipeline is created
@@ -48,9 +74,50 @@ RSpec.describe 'Dashboard Projects', feature: true do
it 'shows that the last pipeline passed' do
visit dashboard_projects_path
- expect(page).to have_xpath("//a[@href='#{pipelines_namespace_project_commit_path(project.namespace, project, project.commit)}']")
+ page.within('.controls') do
+ expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit)}']")
+ expect(page).to have_css('.ci-status-link')
+ expect(page).to have_css('.ci-status-icon-success')
+ expect(page).to have_link('Commit: passed')
+ end
end
end
- it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token"
+ context 'last push widget' do
+ let(:push_event_data) do
+ {
+ before: Gitlab::Git::BLANK_SHA,
+ after: '0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e',
+ ref: 'refs/heads/feature',
+ user_id: user.id,
+ user_name: user.name,
+ repository: {
+ name: project.name,
+ url: 'localhost/rubinius',
+ description: '',
+ homepage: 'localhost/rubinius',
+ private: true
+ }
+ }
+ end
+ let!(:push_event) { create(:event, :pushed, data: push_event_data, project: project, author: user) }
+
+ before do
+ visit dashboard_projects_path
+ end
+
+ scenario 'shows "Create merge request" button' do
+ expect(page).to have_content 'You pushed to feature'
+
+ within('#content-body') do
+ find_link('Create merge request', visible: false).click
+ end
+
+ expect(page).to have_selector('.merge-request-form')
+ expect(current_path).to eq project_new_merge_request_path(project)
+ expect(find('#merge_request_target_project_id').value).to eq project.id.to_s
+ expect(find('input#merge_request_source_branch').value).to eq 'feature'
+ expect(find('input#merge_request_target_branch').value).to eq 'master'
+ end
+ end
end
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 525b0e1b210..5f1f0c10339 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-feature 'Dashboard shortcuts', :feature, :js do
+feature 'Dashboard shortcuts', :js do
context 'logged in' do
before do
- gitlab_sign_in :user
+ sign_in(create(:user))
visit root_dashboard_path
end
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index 0c069ae5cf0..c29bcc7c9e9 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -1,12 +1,12 @@
require 'spec_helper'
-describe 'Dashboard snippets', feature: true do
+describe 'Dashboard snippets' do
context 'when the project has snippets' do
let(:project) { create(:empty_project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
before do
allow(Snippet).to receive(:default_per_page).and_return(1)
- gitlab_sign_in(project.owner)
+ sign_in(project.owner)
visit dashboard_snippets_path
end
@@ -25,7 +25,7 @@ describe 'Dashboard snippets', feature: true do
end
before do
- gitlab_sign_in(user)
+ sign_in(user)
visit dashboard_snippets_path
end
diff --git a/spec/features/dashboard/todos/target_state_spec.rb b/spec/features/dashboard/todos/target_state_spec.rb
new file mode 100644
index 00000000000..93da36c08fc
--- /dev/null
+++ b/spec/features/dashboard/todos/target_state_spec.rb
@@ -0,0 +1,65 @@
+require 'rails_helper'
+
+feature 'Dashboard > Todo target states' do
+ let(:user) { create(:user) }
+ let(:author) { create(:user) }
+ let(:project) { create(:empty_project, :public) }
+
+ before do
+ sign_in(user)
+ end
+
+ scenario 'on a closed issue todo has closed label' do
+ issue_closed = create(:issue, state: 'closed')
+ create_todo issue_closed
+ visit dashboard_todos_path
+
+ page.within '.todos-list' do
+ expect(page).to have_content('Closed')
+ end
+ end
+
+ scenario 'on an open issue todo does not have an open label' do
+ issue_open = create(:issue)
+ create_todo issue_open
+ visit dashboard_todos_path
+
+ page.within '.todos-list' do
+ expect(page).not_to have_content('Open')
+ end
+ end
+
+ scenario 'on a merged merge request todo has merged label' do
+ mr_merged = create(:merge_request, :simple, :merged, author: user)
+ create_todo mr_merged
+ visit dashboard_todos_path
+
+ page.within '.todos-list' do
+ expect(page).to have_content('Merged')
+ end
+ end
+
+ scenario 'on a closed merge request todo has closed label' do
+ mr_closed = create(:merge_request, :simple, :closed, author: user)
+ create_todo mr_closed
+ visit dashboard_todos_path
+
+ page.within '.todos-list' do
+ expect(page).to have_content('Closed')
+ end
+ end
+
+ scenario 'on an open merge request todo does not have an open label' do
+ mr_open = create(:merge_request, :simple, author: user)
+ create_todo mr_open
+ visit dashboard_todos_path
+
+ page.within '.todos-list' do
+ expect(page).not_to have_content('Open')
+ end
+ end
+
+ def create_todo(target)
+ create(:todo, :mentioned, user: user, project: project, target: target, author: author)
+ end
+end
diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb
new file mode 100644
index 00000000000..0a363259fe7
--- /dev/null
+++ b/spec/features/dashboard/todos/todos_filtering_spec.rb
@@ -0,0 +1,153 @@
+require 'spec_helper'
+
+feature 'Dashboard > User filters todos', js: true do
+ let(:user_1) { create(:user, username: 'user_1', name: 'user_1') }
+ let(:user_2) { create(:user, username: 'user_2', name: 'user_2') }
+
+ let(:project_1) { create(:empty_project, name: 'project_1') }
+ let(:project_2) { create(:empty_project, name: 'project_2') }
+
+ let(:issue) { create(:issue, title: 'issue', project: project_1) }
+
+ let!(:merge_request) { create(:merge_request, source_project: project_2, title: 'merge_request') }
+
+ before do
+ create(:todo, user: user_1, author: user_2, project: project_1, target: issue, action: 1)
+ create(:todo, user: user_1, author: user_1, project: project_2, target: merge_request, action: 2)
+
+ project_1.team << [user_1, :developer]
+ project_2.team << [user_1, :developer]
+ sign_in(user_1)
+ visit dashboard_todos_path
+ end
+
+ it 'filters by project' do
+ click_button 'Project'
+ within '.dropdown-menu-project' do
+ fill_in 'Search projects', with: project_1.name_with_namespace
+ click_link project_1.name_with_namespace
+ end
+
+ wait_for_requests
+
+ expect(page).to have_content project_1.name_with_namespace
+ expect(page).not_to have_content project_2.name_with_namespace
+ end
+
+ context 'Author filter' do
+ it 'filters by author' do
+ click_button 'Author'
+
+ within '.dropdown-menu-author' do
+ fill_in 'Search authors', with: user_1.name
+ click_link user_1.name
+ end
+
+ wait_for_requests
+
+ expect(find('.todos-list')).to have_content 'merge request'
+ expect(find('.todos-list')).not_to have_content 'issue'
+ end
+
+ it 'shows only authors of existing todos' do
+ click_button 'Author'
+
+ within '.dropdown-menu-author' do
+ # It should contain two users + 'Any Author'
+ expect(page).to have_selector('.dropdown-menu-user-link', count: 3)
+ expect(page).to have_content(user_1.name)
+ expect(page).to have_content(user_2.name)
+ end
+ end
+
+ it 'shows only authors of existing done todos' do
+ user_3 = create :user
+ user_4 = create :user
+ create(:todo, user: user_1, author: user_3, project: project_1, target: issue, action: 1, state: :done)
+ create(:todo, user: user_1, author: user_4, project: project_2, target: merge_request, action: 2, state: :done)
+
+ project_1.team << [user_3, :developer]
+ project_2.team << [user_4, :developer]
+
+ visit dashboard_todos_path(state: 'done')
+
+ click_button 'Author'
+
+ within '.dropdown-menu-author' do
+ # It should contain two users + 'Any Author'
+ expect(page).to have_selector('.dropdown-menu-user-link', count: 3)
+ expect(page).to have_content(user_3.name)
+ expect(page).to have_content(user_4.name)
+ expect(page).not_to have_content(user_1.name)
+ expect(page).not_to have_content(user_2.name)
+ end
+ end
+ end
+
+ it 'filters by type' do
+ click_button 'Type'
+ within '.dropdown-menu-type' do
+ click_link 'Issue'
+ end
+
+ wait_for_requests
+
+ expect(find('.todos-list')).to have_content issue.to_reference
+ expect(find('.todos-list')).not_to have_content merge_request.to_reference
+ end
+
+ describe 'filter by action' do
+ before do
+ create(:todo, :build_failed, user: user_1, author: user_2, project: project_1)
+ create(:todo, :marked, user: user_1, author: user_2, project: project_1, target: issue)
+ end
+
+ it 'filters by Assigned' do
+ filter_action('Assigned')
+
+ expect_to_see_action(:assigned)
+ end
+
+ it 'filters by Mentioned' do
+ filter_action('Mentioned')
+
+ expect_to_see_action(:mentioned)
+ end
+
+ it 'filters by Added' do
+ filter_action('Added')
+
+ expect_to_see_action(:marked)
+ end
+
+ it 'filters by Pipelines' do
+ filter_action('Pipelines')
+
+ expect_to_see_action(:build_failed)
+ end
+
+ def filter_action(name)
+ click_button 'Action'
+ within '.dropdown-menu-action' do
+ click_link name
+ end
+
+ wait_for_requests
+ end
+
+ def expect_to_see_action(action_name)
+ action_names = {
+ assigned: ' assigned you ',
+ mentioned: ' mentioned ',
+ marked: ' added a todo for ',
+ build_failed: ' build failed for '
+ }
+
+ action_name_text = action_names.delete(action_name)
+ expect(find('.todos-list')).to have_content action_name_text
+ action_names.each_value do |other_action_text|
+ expect(find('.todos-list')).not_to have_content other_action_text
+ end
+ end
+ end
+end
diff --git a/spec/features/dashboard/todos/todos_sorting_spec.rb b/spec/features/dashboard/todos/todos_sorting_spec.rb
new file mode 100644
index 00000000000..d49a78b290f
--- /dev/null
+++ b/spec/features/dashboard/todos/todos_sorting_spec.rb
@@ -0,0 +1,99 @@
+require 'spec_helper'
+
+feature 'Dashboard > User sorts todos' do
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project) }
+
+ let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
+ let(:label_2) { create(:label, title: 'label_2', project: project, priority: 2) }
+ let(:label_3) { create(:label, title: 'label_3', project: project, priority: 3) }
+
+ before do
+ project.team << [user, :developer]
+ end
+
+ context 'sort options' do
+ let(:issue_1) { create(:issue, title: 'issue_1', project: project) }
+ let(:issue_2) { create(:issue, title: 'issue_2', project: project) }
+ let(:issue_3) { create(:issue, title: 'issue_3', project: project) }
+ let(:issue_4) { create(:issue, title: 'issue_4', project: project) }
+
+ let!(:merge_request_1) { create(:merge_request, source_project: project, title: 'merge_request_1') }
+
+ before do
+ create(:todo, user: user, project: project, target: issue_4, created_at: 5.hours.ago)
+ create(:todo, user: user, project: project, target: issue_2, created_at: 4.hours.ago)
+ create(:todo, user: user, project: project, target: issue_3, created_at: 3.hours.ago)
+ create(:todo, user: user, project: project, target: issue_1, created_at: 2.hours.ago)
+ create(:todo, user: user, project: project, target: merge_request_1, created_at: 1.hour.ago)
+
+ merge_request_1.labels << label_1
+ issue_3.labels << label_1
+ issue_2.labels << label_3
+ issue_1.labels << label_2
+
+ sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'sorts with oldest created todos first' do
+ click_link 'Last created'
+
+ results_list = page.find('.todos-list')
+ expect(results_list.all('p')[0]).to have_content('merge_request_1')
+ expect(results_list.all('p')[1]).to have_content('issue_1')
+ expect(results_list.all('p')[2]).to have_content('issue_3')
+ expect(results_list.all('p')[3]).to have_content('issue_2')
+ expect(results_list.all('p')[4]).to have_content('issue_4')
+ end
+
+ it 'sorts with newest created todos first' do
+ click_link 'Oldest created'
+
+ results_list = page.find('.todos-list')
+ expect(results_list.all('p')[0]).to have_content('issue_4')
+ expect(results_list.all('p')[1]).to have_content('issue_2')
+ expect(results_list.all('p')[2]).to have_content('issue_3')
+ expect(results_list.all('p')[3]).to have_content('issue_1')
+ expect(results_list.all('p')[4]).to have_content('merge_request_1')
+ end
+
+ it 'sorts by label priority' do
+ click_link 'Label priority'
+
+ results_list = page.find('.todos-list')
+ expect(results_list.all('p')[0]).to have_content('issue_3')
+ expect(results_list.all('p')[1]).to have_content('merge_request_1')
+ expect(results_list.all('p')[2]).to have_content('issue_1')
+ expect(results_list.all('p')[3]).to have_content('issue_2')
+ expect(results_list.all('p')[4]).to have_content('issue_4')
+ end
+ end
+
+ context 'issues and merge requests' do
+ let(:issue_1) { create(:issue, id: 10000, title: 'issue_1', project: project) }
+ let(:issue_2) { create(:issue, id: 10001, title: 'issue_2', project: project) }
+ let(:merge_request_1) { create(:merge_request, id: 10000, title: 'merge_request_1', source_project: project) }
+
+ before do
+ issue_1.labels << label_1
+ issue_2.labels << label_2
+
+ create(:todo, user: user, project: project, target: issue_1)
+ create(:todo, user: user, project: project, target: issue_2)
+ create(:todo, user: user, project: project, target: merge_request_1)
+
+ sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it "doesn't mix issues and merge requests label priorities" do
+ click_link 'Label priority'
+
+ results_list = page.find('.todos-list')
+ expect(results_list.all('p')[0]).to have_content('issue_1')
+ expect(results_list.all('p')[1]).to have_content('issue_2')
+ expect(results_list.all('p')[2]).to have_content('merge_request_1')
+ end
+ end
+end
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
new file mode 100644
index 00000000000..c2a61cf5aff
--- /dev/null
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -0,0 +1,338 @@
+require 'spec_helper'
+
+feature 'Dashboard Todos' do
+ let(:user) { create(:user) }
+ let(:author) { create(:user) }
+ let(:project) { create(:empty_project, :public) }
+ let(:issue) { create(:issue, due_date: Date.today) }
+
+ context 'User does not have todos' do
+ before do
+ sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows "All done" message' do
+ expect(page).to have_content 'Todos let you see what you should do next.'
+ end
+ end
+
+ context 'User has a todo', js: true do
+ before do
+ create(:todo, :mentioned, user: user, project: project, target: issue, author: author)
+ sign_in(user)
+
+ visit dashboard_todos_path
+ end
+
+ it 'has todo present' do
+ expect(page).to have_selector('.todos-list .todo', count: 1)
+ end
+
+ it 'shows due date as today' do
+ within first('.todo') do
+ expect(page).to have_content 'Due today'
+ end
+ end
+
+ shared_examples 'deleting the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ end
+ end
+
+ it 'is marked as done-reversible in the list' do
+ expect(page).to have_selector('.todos-list .todo.todo-pending.done-reversible')
+ end
+
+ it 'shows Undo button' do
+ expect(page).to have_selector('.js-undo-todo', visible: true)
+ expect(page).to have_selector('.js-done-todo', visible: false)
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content 'Done 1'
+ end
+
+ it 'has not "All done" message' do
+ expect(page).not_to have_selector('.todos-all-done')
+ end
+ end
+
+ shared_examples 'deleting and restoring the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ wait_for_requests
+ click_link 'Undo'
+ end
+ end
+
+ it 'is marked back as pending in the list' do
+ expect(page).not_to have_selector('.todos-list .todo.todo-pending.done-reversible')
+ expect(page).to have_selector('.todos-list .todo.todo-pending')
+ end
+
+ it 'shows Done button' do
+ expect(page).to have_selector('.js-undo-todo', visible: false)
+ expect(page).to have_selector('.js-done-todo', visible: true)
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 1'
+ expect(page).to have_content 'Done 0'
+ end
+ end
+
+ it_behaves_like 'deleting the todo'
+ it_behaves_like 'deleting and restoring the todo'
+
+ context 'todo is stale on the page' do
+ before do
+ todos = TodosFinder.new(user, state: :pending).execute
+ TodoService.new.mark_todos_as_done(todos, user)
+ end
+
+ it_behaves_like 'deleting the todo'
+ it_behaves_like 'deleting and restoring the todo'
+ end
+ end
+
+ context 'User created todos for themself' do
+ before do
+ sign_in(user)
+ end
+
+ context 'issue assigned todo' do
+ before do
+ create(:todo, :assigned, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows issue assigned to yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You assigned issue #{issue.to_reference(full: true)} to yourself")
+ end
+ end
+ end
+
+ context 'marked todo' do
+ before do
+ create(:todo, :marked, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you added a todo message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You added a todo for issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'mentioned todo' do
+ before do
+ create(:todo, :mentioned, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you mentioned yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You mentioned yourself on issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'directly_addressed todo' do
+ before do
+ create(:todo, :directly_addressed, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you directly addressed yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You directly addressed yourself on issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'approval todo' do
+ let(:merge_request) { create(:merge_request) }
+
+ before do
+ create(:todo, :approval_required, user: user, project: project, target: merge_request, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you set yourself as an approver message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You set yourself as an approver for merge request #{merge_request.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+ end
+
+ context 'User has done todos', js: true do
+ before do
+ create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author)
+ sign_in(user)
+ visit dashboard_todos_path(state: :done)
+ end
+
+ it 'has the done todo present' do
+ expect(page).to have_selector('.todos-list .todo.todo-done', count: 1)
+ end
+
+ describe 'restoring the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Add todo'
+ end
+ end
+
+ it 'is removed from the list' do
+ expect(page).not_to have_selector('.todos-list .todo.todo-done')
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 1'
+ expect(page).to have_content 'Done 0'
+ end
+ end
+ end
+
+ context 'User has Todos with labels spanning multiple projects' do
+ before do
+ label1 = create(:label, project: project)
+ note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project)
+ create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id)
+
+ project2 = create(:empty_project, :public)
+ label2 = create(:label, project: project2)
+ issue2 = create(:issue, project: project2)
+ note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
+ create(:todo, :mentioned, project: project2, target: issue2, user: user, note_id: note2.id)
+
+ gitlab_sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows page with two Todos' do
+ expect(page).to have_selector('.todos-list .todo', count: 2)
+ end
+ end
+
+ context 'User has multiple pages of Todos' do
+ before do
+ allow(Todo).to receive(:default_per_page).and_return(1)
+
+ # Create just enough records to cause us to paginate
+ create_list(:todo, 2, :mentioned, user: user, project: project, target: issue, author: author)
+
+ sign_in(user)
+ end
+
+ it 'is paginated' do
+ visit dashboard_todos_path
+
+ expect(page).to have_selector('.gl-pagination')
+ end
+
+ it 'is has the right number of pages' do
+ visit dashboard_todos_path
+
+ expect(page).to have_selector('.gl-pagination .page', count: 2)
+ end
+
+ describe 'mark all as done', js: true do
+ before do
+ visit dashboard_todos_path
+ find('.js-todos-mark-all').trigger('click')
+ end
+
+ it 'shows "All done" message!' do
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content "You're all done!"
+ expect(page).not_to have_selector('.gl-pagination')
+ end
+
+ it 'shows "Undo mark all as done" button' do
+ expect(page).to have_selector('.js-todos-mark-all', visible: false)
+ expect(page).to have_selector('.js-todos-undo-all', visible: true)
+ end
+ end
+
+ describe 'undo mark all as done', js: true do
+ before do
+ visit dashboard_todos_path
+ end
+
+ it 'shows the restored todo list' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.todos-list .todo', count: 1)
+ expect(page).to have_selector('.gl-pagination')
+ expect(page).not_to have_content "You're all done!"
+ end
+
+ it 'updates todo count' do
+ mark_all_and_undo
+
+ expect(page).to have_content 'To do 2'
+ expect(page).to have_content 'Done 0'
+ end
+
+ it 'shows "Mark all as done" button' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.js-todos-mark-all', visible: true)
+ expect(page).to have_selector('.js-todos-undo-all', visible: false)
+ end
+
+ context 'User has deleted a todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ end
+ end
+
+ it 'shows the restored todo list with the deleted todo' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.todos-list .todo.todo-pending', count: 1)
+ end
+ end
+
+ def mark_all_and_undo
+ find('.js-todos-mark-all').trigger('click')
+ wait_for_requests
+ find('.js-todos-undo-all').trigger('click')
+ wait_for_requests
+ end
+ end
+ end
+
+ context 'User has a Build Failed todo' do
+ let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: author) }
+
+ before do
+ sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows the todo' do
+ expect(page).to have_content 'The build failed for merge request'
+ end
+
+ it 'links to the pipelines for the merge request' do
+ href = pipelines_project_merge_request_path(project, todo.target)
+
+ expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href
+ end
+ end
+end
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index e9f34760143..a88fe207e0e 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -1,15 +1,15 @@
require 'spec_helper'
-describe 'Dashboard > User filters projects', :feature do
+describe 'Dashboard > User filters projects' do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'Victorialand', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'Victorialand', namespace: user.namespace) }
let(:user2) { create(:user) }
- let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace) }
+ let(:project2) { create(:empty_project, name: 'Treasure', namespace: user2.namespace) }
before do
project.team << [user, :master]
- gitlab_sign_in(user)
+ sign_in(user)
end
describe 'filtering personal projects' do