summaryrefslogtreecommitdiff
path: root/spec/features/issues
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-16 12:08:32 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-16 12:08:32 +0000
commitc158fa8d69c704663d289341a014c44c062cda88 (patch)
treed0cac82a9ac9e9ad28bb0030266eb8d5dc91fbbc /spec/features/issues
parentb806264d29b8d52ccb78a41dcc3d67f2b040700c (diff)
downloadgitlab-ce-c158fa8d69c704663d289341a014c44c062cda88.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/features/issues')
-rw-r--r--spec/features/issues/user_creates_issue_by_email_spec.rb46
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb126
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb279
-rw-r--r--spec/features/issues/user_filters_issues_spec.rb39
-rw-r--r--spec/features/issues/user_resets_their_incoming_email_token_spec.rb32
-rw-r--r--spec/features/issues/user_sees_breadcrumb_links_spec.rb20
-rw-r--r--spec/features/issues/user_sees_empty_state_spec.rb51
-rw-r--r--spec/features/issues/user_sees_live_update_spec.rb52
-rw-r--r--spec/features/issues/user_sorts_issues_spec.rb187
9 files changed, 812 insertions, 20 deletions
diff --git a/spec/features/issues/user_creates_issue_by_email_spec.rb b/spec/features/issues/user_creates_issue_by_email_spec.rb
new file mode 100644
index 00000000000..c73a65849cc
--- /dev/null
+++ b/spec/features/issues/user_creates_issue_by_email_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Issues > User creates issue by email' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+
+ before do
+ sign_in(user)
+
+ project.add_developer(user)
+ end
+
+ 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 project_issues_path(project)
+ click_button('Email a new issue')
+ end
+
+ it 'click the button to show modal for the new email' do
+ page.within '#issuable-email-modal' do
+ email = project.new_issuable_address(user, 'issue')
+
+ expect(page).to have_selector("input[value='#{email}']")
+ end
+ end
+ end
+
+ context 'with existing issues' do
+ let!(:issue) { create(:issue, project: project, author: user) }
+
+ it_behaves_like 'show the email in the modal'
+ end
+
+ context 'without existing issues' do
+ it_behaves_like 'show the email in the modal'
+ end
+ end
+end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 39ce3415727..b0a2a734877 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -3,8 +3,32 @@
require "spec_helper"
describe "User creates issue" do
- let(:project) { create(:project_empty_repo, :public) }
- let(:user) { create(:user) }
+ include DropzoneHelper
+
+ let_it_be(:project) { create(:project_empty_repo, :public) }
+ let_it_be(:user) { create(:user) }
+
+ context "when unauthenticated" do
+ before do
+ sign_out(:user)
+ end
+
+ it "redirects to signin then back to new issue after signin" do
+ create(:issue, project: project)
+
+ visit project_issues_path(project)
+
+ page.within ".nav-controls" do
+ click_link "New issue"
+ end
+
+ expect(current_path).to eq new_user_session_path
+
+ gitlab_sign_in(create(:user))
+
+ expect(current_path).to eq new_project_issue_path(project)
+ end
+ end
context "when signed in as guest" do
before do
@@ -92,6 +116,104 @@ describe "User creates issue" do
.and have_content(label_titles.first)
end
end
+
+ context 'with due date', :js do
+ it 'saves with due date' do
+ date = Date.today.at_beginning_of_month
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+ find('#issuable-due-date').click
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ expect(find('#issuable-due-date').value).to eq date.to_s
+
+ click_button 'Submit issue'
+
+ page.within '.issuable-sidebar' do
+ expect(page).to have_content date.to_s(:medium)
+ end
+ end
+ end
+
+ context 'dropzone upload file', :js do
+ before do
+ visit new_project_issue_path(project)
+ end
+
+ it 'uploads file when dragging into textarea' do
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ expect(page.find_field("issue_description").value).to have_content 'banana_sample'
+ end
+
+ it "doesn't add double newline to end of a single attachment markdown" do
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ expect(page.find_field("issue_description").value).not_to match /\n\n$/
+ end
+
+ it "cancels a file upload correctly" do
+ slow_requests do
+ dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false)
+
+ click_button 'Cancel'
+ end
+
+ expect(page).to have_button('Attach a file')
+ expect(page).not_to have_button('Cancel')
+ expect(page).not_to have_selector('.uploading-progress-container', visible: true)
+ end
+ end
+
+ context 'form filled by URL parameters' do
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ project.repository.create_file(
+ user,
+ '.gitlab/issue_templates/bug.md',
+ 'this is a test "bug" template',
+ message: 'added issue template',
+ branch_name: 'master')
+
+ visit new_project_issue_path(project, issuable_template: 'bug')
+ end
+
+ it 'fills in template' do
+ expect(find('.js-issuable-selector .dropdown-toggle-text')).to have_content('bug')
+ end
+ end
+
+ context 'suggestions', :js do
+ it 'displays list of related issues' do
+ issue = create(:issue, project: project)
+ create(:issue, project: project, title: 'test issue')
+
+ visit new_project_issue_path(project)
+
+ fill_in 'issue_title', with: issue.title
+
+ expect(page).to have_selector('.suggestion-item', count: 1)
+ end
+ end
+
+ it 'clears local storage after creating a new issue', :js do
+ 2.times do
+ visit new_project_issue_path(project)
+ wait_for_requests
+
+ expect(page).to have_field('Title', with: '')
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+
+ click_button 'Submit issue'
+ end
+ end
end
context "when signed in as user with special characters in their name" do
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 0afc19d9519..ad984cf07e2 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -2,26 +2,283 @@
require "spec_helper"
-describe "User edits issue", :js do
- set(:project) { create(:project_empty_repo, :public) }
- set(:user) { create(:user) }
- set(:issue) { create(:issue, project: project, author: user) }
+describe "Issues > User edits issue", :js do
+ let_it_be(:project) { create(:project_empty_repo, :public) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
+ let_it_be(:label) { create(:label, project: project) }
+ let_it_be(:milestone) { create(:milestone, project: project) }
before do
project.add_developer(user)
sign_in(user)
+ end
+
+ context "from edit page" do
+ before do
+ visit edit_project_issue_path(project, issue)
+ end
+
+ it "previews content" do
+ form = first(".gfm-form")
+
+ page.within(form) do
+ fill_in("Description", with: "Bug fixed :smile:")
+ click_button("Preview")
+ end
+
+ expect(form).to have_button("Write")
+ end
+
+ it 'allows user to select unassigned' do
+ visit edit_project_issue_path(project, issue)
+
+ expect(page).to have_content "Assignee #{user.name}"
+
+ first('.js-user-search').click
+ click_link 'Unassigned'
+
+ click_button 'Save changes'
+
+ page.within('.assignee') do
+ expect(page).to have_content 'None - assign yourself'
+ end
+ end
+
+ context 'with due date' do
+ before do
+ visit edit_project_issue_path(project, issue)
+ end
+
+ it 'saves with due date' do
+ date = Date.today.at_beginning_of_month.tomorrow
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+ find('#issuable-due-date').click
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ expect(find('#issuable-due-date').value).to eq date.to_s
+
+ click_button 'Save changes'
- visit(edit_project_issue_path(project, issue))
+ page.within '.issuable-sidebar' do
+ expect(page).to have_content date.to_s(:medium)
+ end
+ end
+
+ it 'warns about version conflict' do
+ issue.update(title: "New title")
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Someone edited the issue the same time you did'
+ end
+ end
end
- it "previews content" do
- form = first(".gfm-form")
+ context "from issue#show" do
+ before do
+ visit project_issue_path(project, issue)
+ end
+
+ describe 'update labels' do
+ it 'will not send ajax request when no data is changed' do
+ page.within '.labels' do
+ click_link 'Edit'
- page.within(form) do
- fill_in("Description", with: "Bug fixed :smile:")
- click_button("Preview")
+ find('.dropdown-menu-close', match: :first).click
+
+ expect(page).not_to have_selector('.block-loading')
+ end
+ end
end
- expect(form).to have_button("Write")
+ describe 'update assignee' do
+ context 'by authorized user' do
+ def close_dropdown_menu_if_visible
+ find('.dropdown-menu-toggle', visible: :all).tap do |toggle|
+ toggle.click if toggle.visible?
+ end
+ end
+
+ it 'allows user to select unassigned' do
+ visit project_issue_path(project, issue)
+
+ page.within('.assignee') do
+ expect(page).to have_content "#{user.name}"
+
+ click_link 'Edit'
+ click_link 'Unassigned'
+ first('.title').click
+ expect(page).to have_content 'None - assign yourself'
+ end
+ end
+
+ it 'allows user to select an assignee' do
+ issue2 = create(:issue, project: project, author: user)
+ visit project_issue_path(project, issue2)
+
+ page.within('.assignee') do
+ expect(page).to have_content "None"
+ end
+
+ page.within '.assignee' do
+ click_link 'Edit'
+ end
+
+ page.within '.dropdown-menu-user' do
+ click_link user.name
+ end
+
+ page.within('.assignee') do
+ expect(page).to have_content user.name
+ end
+ end
+
+ it 'allows user to unselect themselves' do
+ issue2 = create(:issue, project: project, author: user)
+
+ visit project_issue_path(project, issue2)
+
+ page.within '.assignee' do
+ click_link 'Edit'
+ click_link user.name
+
+ close_dropdown_menu_if_visible
+
+ page.within '.value .author' do
+ expect(page).to have_content user.name
+ end
+
+ click_link 'Edit'
+ click_link user.name
+
+ close_dropdown_menu_if_visible
+
+ page.within '.value .assign-yourself' do
+ expect(page).to have_content "None"
+ end
+ end
+ end
+ end
+
+ context 'by unauthorized user' do
+ let(:guest) { create(:user) }
+
+ before do
+ project.add_guest(guest)
+ end
+
+ it 'shows assignee text' do
+ sign_out(:user)
+ sign_in(guest)
+
+ visit project_issue_path(project, issue)
+ expect(page).to have_content issue.assignees.first.name
+ end
+ end
+ end
+
+ describe 'update milestone' do
+ context 'by authorized user' do
+ it 'allows user to select unassigned' do
+ visit project_issue_path(project, issue)
+
+ page.within('.milestone') do
+ expect(page).to have_content "None"
+ end
+
+ find('.block.milestone .edit-link').click
+ sleep 2 # wait for ajax stuff to complete
+ first('.dropdown-content li').click
+ sleep 2
+ page.within('.milestone') do
+ expect(page).to have_content 'None'
+ end
+ end
+
+ it 'allows user to de-select milestone' do
+ visit project_issue_path(project, issue)
+
+ page.within('.milestone') do
+ click_link 'Edit'
+ click_link milestone.title
+
+ page.within '.value' do
+ expect(page).to have_content milestone.title
+ end
+
+ click_link 'Edit'
+ click_link milestone.title
+
+ page.within '.value' do
+ expect(page).to have_content 'None'
+ end
+ end
+ end
+ end
+
+ context 'by unauthorized user' do
+ let(:guest) { create(:user) }
+
+ before do
+ project.add_guest(guest)
+ issue.milestone = milestone
+ issue.save
+ end
+
+ it 'shows milestone text' do
+ sign_out(:user)
+ sign_in(guest)
+
+ visit project_issue_path(project, issue)
+ expect(page).to have_content milestone.title
+ end
+ end
+ end
+
+ context 'update due date' do
+ it 'adds due date to issue' do
+ date = Date.today.at_beginning_of_month + 2.days
+
+ page.within '.due_date' do
+ click_link 'Edit'
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ wait_for_requests
+
+ expect(find('.value').text).to have_content date.strftime('%b %-d, %Y')
+ end
+ end
+
+ it 'removes due date from issue' do
+ date = Date.today.at_beginning_of_month + 2.days
+
+ page.within '.due_date' do
+ click_link 'Edit'
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ wait_for_requests
+
+ expect(page).to have_no_content 'None'
+
+ click_link 'remove due date'
+ expect(page).to have_content 'None'
+ end
+ end
+ end
end
end
diff --git a/spec/features/issues/user_filters_issues_spec.rb b/spec/features/issues/user_filters_issues_spec.rb
new file mode 100644
index 00000000000..714bc972025
--- /dev/null
+++ b/spec/features/issues/user_filters_issues_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'User filters issues' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project_empty_repo, :public) }
+
+ before do
+ %w[foobar barbaz].each do |title|
+ create(:issue,
+ author: user,
+ assignees: [user],
+ project: project,
+ title: title)
+ end
+
+ @issue = Issue.find_by(title: 'foobar')
+ @issue.milestone = create(:milestone, project: project)
+ @issue.assignees = []
+ @issue.save
+ end
+
+ let(:issue) { @issue }
+
+ it 'allows filtering by issues with no specified assignee' do
+ visit project_issues_path(project, assignee_id: IssuableFinder::FILTER_NONE)
+
+ expect(page).to have_content 'foobar'
+ expect(page).not_to have_content 'barbaz'
+ end
+
+ it 'allows filtering by a specified assignee' do
+ visit project_issues_path(project, assignee_id: user.id)
+
+ expect(page).not_to have_content 'foobar'
+ expect(page).to have_content 'barbaz'
+ end
+end
diff --git a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
new file mode 100644
index 00000000000..108b6f550db
--- /dev/null
+++ b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Issues > User resets their incoming email token' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, namespace: user.namespace) }
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ before do
+ stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit namespace_project_issues_path(user.namespace, project)
+ end
+
+ it 'changes incoming email address token', :js do
+ find('.issuable-email-modal-btn').click
+ previous_token = find('input#issuable_email').value
+ find('.incoming-email-token-reset').click
+
+ wait_for_requests
+
+ expect(page).to have_no_field('issuable_email', with: previous_token)
+ new_token = project.new_issuable_address(user.reload, 'issue')
+ expect(page).to have_field(
+ 'issuable_email',
+ with: new_token
+ )
+ end
+end
diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
index f31d730c337..8a120a0a0b2 100644
--- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe 'New issue breadcrumb' do
- let(:project) { create(:project) }
+ let_it_be(:project, reload: true) { create(:project) }
let(:user) { project.creator }
before do
@@ -17,4 +17,22 @@ describe 'New issue breadcrumb' do
expect(find_link('New')[:href]).to end_with(new_project_issue_path(project))
end
end
+
+ it 'links to current issue in breadcrubs' do
+ issue = create(:issue, project: project)
+
+ visit project_issue_path(project, issue)
+
+ expect(find('.breadcrumbs-sub-title a')[:href]).to end_with(issue_path(issue))
+ end
+
+ it 'excludes award_emoji from comment count' do
+ issue = create(:issue, author: user, assignees: [user], project: project, title: 'foobar')
+ create(:award_emoji, awardable: issue)
+
+ visit project_issues_path(project, assignee_id: user.id)
+
+ expect(page).to have_content 'foobar'
+ expect(page.all('.no-comments').first.text).to eq "0"
+ end
end
diff --git a/spec/features/issues/user_sees_empty_state_spec.rb b/spec/features/issues/user_sees_empty_state_spec.rb
new file mode 100644
index 00000000000..114d119aca8
--- /dev/null
+++ b/spec/features/issues/user_sees_empty_state_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Issues > User sees empty state' do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { project.creator }
+
+ shared_examples_for 'empty state with filters' do
+ it 'user sees empty state with filters' do
+ create(:issue, author: user, project: project)
+
+ visit project_issues_path(project, milestone_title: "1.0")
+
+ expect(page).to have_content('Sorry, your filter produced no results')
+ expect(page).to have_content('To widen your search, change or remove filters above')
+ end
+ end
+
+ describe 'while user is signed out' do
+ describe 'empty state' do
+ it 'user sees empty state' do
+ visit project_issues_path(project)
+
+ expect(page).to have_content('Register / Sign In')
+ expect(page).to have_content('The Issue Tracker is the place to add things that need to be improved or solved in a project.')
+ expect(page).to have_content('You can register or sign in to create issues for this project.')
+ end
+
+ it_behaves_like 'empty state with filters'
+ end
+ end
+
+ describe 'while user is signed in' do
+ before do
+ sign_in(user)
+ end
+
+ describe 'empty state' do
+ it 'user sees empty state' do
+ visit project_issues_path(project)
+
+ expect(page).to have_content('The Issue Tracker is the place to add things that need to be improved or solved in a project')
+ expect(page).to have_content('Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.')
+ expect(page).to have_content('New issue')
+ end
+
+ it_behaves_like 'empty state with filters'
+ end
+ end
+end
diff --git a/spec/features/issues/user_sees_live_update_spec.rb b/spec/features/issues/user_sees_live_update_spec.rb
new file mode 100644
index 00000000000..98c7d289fb0
--- /dev/null
+++ b/spec/features/issues/user_sees_live_update_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Issues > User sees live update', :js do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { project.creator }
+
+ before do
+ sign_in(user)
+ end
+
+ describe 'title issue#show' do
+ it 'updates the title' do
+ issue = create(:issue, author: user, assignees: [user], project: project, title: 'new title')
+
+ visit project_issue_path(project, issue)
+
+ expect(page).to have_text("new title")
+
+ issue.update(title: "updated title")
+
+ wait_for_requests
+ expect(page).to have_text("updated title")
+ end
+ end
+
+ describe 'confidential issue#show' do
+ it 'shows confidential sibebar information as confidential and can be turned off' do
+ issue = create(:issue, :confidential, project: project)
+
+ visit project_issue_path(project, issue)
+
+ expect(page).to have_css('.issuable-note-warning')
+ expect(find('.issuable-sidebar-item.confidentiality')).to have_css('.is-active')
+ expect(find('.issuable-sidebar-item.confidentiality')).not_to have_css('.not-active')
+
+ find('.confidential-edit').click
+ expect(page).to have_css('.sidebar-item-warning-message')
+
+ within('.sidebar-item-warning-message') do
+ find('.btn-close').click
+ end
+
+ wait_for_requests
+
+ visit project_issue_path(project, issue)
+
+ expect(page).not_to have_css('.is-active')
+ end
+ end
+end
diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb
index 79938785633..66110f55435 100644
--- a/spec/features/issues/user_sorts_issues_spec.rb
+++ b/spec/features/issues/user_sorts_issues_spec.rb
@@ -3,12 +3,17 @@
require "spec_helper"
describe "User sorts issues" do
- set(:user) { create(:user) }
- set(:group) { create(:group) }
- set(:project) { create(:project_empty_repo, :public, group: group) }
- set(:issue1) { create(:issue, project: project) }
- set(:issue2) { create(:issue, project: project) }
- set(:issue3) { create(:issue, project: project) }
+ include SortingHelper
+ include IssueHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project_empty_repo, :public, group: group) }
+ let_it_be(:issue1, reload: true) { create(:issue, title: 'foo', created_at: Time.now, project: project) }
+ let_it_be(:issue2, reload: true) { create(:issue, title: 'bar', created_at: Time.now - 60, project: project) }
+ let_it_be(:issue3, reload: true) { create(:issue, title: 'baz', created_at: Time.now - 120, project: project) }
+ let_it_be(:newer_due_milestone) { create(:milestone, project: project, due_date: '2013-12-11') }
+ let_it_be(:later_due_milestone) { create(:milestone, project: project, due_date: '2013-12-12') }
before do
create_list(:award_emoji, 2, :upvote, awardable: issue1)
@@ -62,4 +67,174 @@ describe "User sorts issues" do
end
end
end
+
+ it 'sorts by newest' do
+ visit project_issues_path(project, sort: sort_value_created_date)
+
+ expect(first_issue).to include('foo')
+ expect(last_issue).to include('baz')
+ end
+
+ it 'sorts by most recently updated' do
+ issue3.updated_at = Time.now + 100
+ issue3.save
+ visit project_issues_path(project, sort: sort_value_recently_updated)
+
+ expect(first_issue).to include('baz')
+ end
+
+ describe 'sorting by due date' do
+ before do
+ issue1.update(due_date: 1.day.from_now)
+ issue2.update(due_date: 6.days.from_now)
+ end
+
+ it 'sorts by due date' do
+ visit project_issues_path(project, sort: sort_value_due_date)
+
+ expect(first_issue).to include('foo')
+ end
+
+ it 'sorts by due date by excluding nil due dates' do
+ issue2.update(due_date: nil)
+
+ visit project_issues_path(project, sort: sort_value_due_date)
+
+ expect(first_issue).to include('foo')
+ end
+
+ context 'with a filter on labels' do
+ let(:label) { create(:label, project: project) }
+
+ before do
+ create(:label_link, label: label, target: issue1)
+ end
+
+ it 'sorts by least recently due date by excluding nil due dates' do
+ issue2.update(due_date: nil)
+
+ visit project_issues_path(project, label_names: [label.name], sort: sort_value_due_date_later)
+
+ expect(first_issue).to include('foo')
+ end
+ end
+ end
+
+ describe 'filtering by due date' do
+ before do
+ issue1.update(due_date: 1.day.from_now)
+ issue2.update(due_date: 6.days.from_now)
+ end
+
+ it 'filters by none' do
+ visit project_issues_path(project, due_date: Issue::NoDueDate.name)
+
+ page.within '.issues-holder' do
+ expect(page).not_to have_content('foo')
+ expect(page).not_to have_content('bar')
+ expect(page).to have_content('baz')
+ end
+ end
+
+ it 'filters by any' do
+ visit project_issues_path(project, due_date: Issue::AnyDueDate.name)
+
+ page.within '.issues-holder' do
+ expect(page).to have_content('foo')
+ expect(page).to have_content('bar')
+ expect(page).to have_content('baz')
+ end
+ end
+
+ it 'filters by due this week' do
+ issue1.update(due_date: Date.today.beginning_of_week + 2.days)
+ issue2.update(due_date: Date.today.end_of_week)
+ issue3.update(due_date: Date.today - 8.days)
+
+ visit project_issues_path(project, due_date: Issue::DueThisWeek.name)
+
+ page.within '.issues-holder' do
+ expect(page).to have_content('foo')
+ expect(page).to have_content('bar')
+ expect(page).not_to have_content('baz')
+ end
+ end
+
+ it 'filters by due this month' do
+ issue1.update(due_date: Date.today.beginning_of_month + 2.days)
+ issue2.update(due_date: Date.today.end_of_month)
+ issue3.update(due_date: Date.today - 50.days)
+
+ visit project_issues_path(project, due_date: Issue::DueThisMonth.name)
+
+ page.within '.issues-holder' do
+ expect(page).to have_content('foo')
+ expect(page).to have_content('bar')
+ expect(page).not_to have_content('baz')
+ end
+ end
+
+ it 'filters by overdue' do
+ issue1.update(due_date: Date.today + 2.days)
+ issue2.update(due_date: Date.today + 20.days)
+ issue3.update(due_date: Date.yesterday)
+
+ visit project_issues_path(project, due_date: Issue::Overdue.name)
+
+ page.within '.issues-holder' do
+ expect(page).not_to have_content('foo')
+ expect(page).not_to have_content('bar')
+ expect(page).to have_content('baz')
+ end
+ end
+
+ it 'filters by due next month and previous two weeks' do
+ issue1.update(due_date: Date.today - 4.weeks)
+ issue2.update(due_date: (Date.today + 2.months).beginning_of_month)
+ issue3.update(due_date: Date.yesterday)
+
+ visit project_issues_path(project, due_date: Issue::DueNextMonthAndPreviousTwoWeeks.name)
+
+ page.within '.issues-holder' do
+ expect(page).not_to have_content('foo')
+ expect(page).not_to have_content('bar')
+ expect(page).to have_content('baz')
+ end
+ end
+ end
+
+ describe 'sorting by milestone' do
+ before do
+ issue1.milestone = newer_due_milestone
+ issue1.save
+ issue2.milestone = later_due_milestone
+ issue2.save
+ end
+
+ it 'sorts by milestone' do
+ visit project_issues_path(project, sort: sort_value_milestone)
+
+ expect(first_issue).to include('foo')
+ expect(last_issue).to include('baz')
+ end
+ end
+
+ describe 'combine filter and sort' do
+ let(:user2) { create(:user) }
+
+ before do
+ issue1.assignees << user2
+ issue1.save
+ issue2.assignees << user2
+ issue2.save
+ end
+
+ it 'sorts with a filter applied' do
+ visit project_issues_path(project, sort: sort_value_created_date, assignee_id: user2.id)
+
+ expect(first_issue).to include('foo')
+ expect(last_issue).to include('bar')
+ expect(page).not_to have_content('baz')
+ end
+ end
end