diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml index e039a73cd3bcc9c39c6cd76acc2f2c608da9d79d..62437f5fc9d5e9db8bc4394722b352b6a91d9800 100644 --- a/app/views/shared/empty_states/_issues.html.haml +++ b/app/views/shared/empty_states/_issues.html.haml @@ -8,16 +8,17 @@ = image_tag 'illustrations/issues.svg' .col-xs-12 .text-content - - if has_button && current_user + - if current_user %h4 = _("The Issue Tracker is the place to add things that need to be improved or solved in a project") %p = _("Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.") - .text-center - - if project_select_button - = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues - - else - = link_to 'New issue', button_path, class: 'btn btn-success', title: 'New issue', id: 'new_issue_link' + - if has_button + .text-center + - if project_select_button + = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues + - else + = link_to 'New issue', button_path, class: 'btn btn-success', title: 'New issue', id: 'new_issue_link' - else %h4.text-center= _("There are no issues to show") %p diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 852d9e368aa100e4354d6bb04c6a15e6b26595c1..d1ff057a0c6c87a8fb857f91c3e7ee5e162dcabc 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -8,729 +8,753 @@ describe 'Issues' do let(:user) { create(:user) } let(:project) { create(:project, :public) } - before do - sign_in(user) - user2 = create(:user) - - project.team << [[user, user2], :developer] - end + describe 'while user is signed out' do + describe 'empty state' do + it 'user sees empty state' do + visit project_issues_path(project) - describe 'Edit issue' do - let!(:issue) do - create(:issue, - author: user, - assignees: [user], - project: 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 end + end + describe 'while user is signed in' do before do - visit edit_project_issue_path(project, issue) - find('.js-zen-enter').click - end - - it 'opens new issue popup' do - expect(page).to have_content("Issue ##{issue.iid}") - end - end + sign_in(user) + user2 = create(:user) - describe 'Editing issue assignee' do - let!(:issue) do - create(:issue, - author: user, - assignees: [user], - project: project) + project.team << [[user, user2], :developer] end - it 'allows user to select unassigned', :js do - visit edit_project_issue_path(project, issue) - - expect(page).to have_content "Assignee #{user.name}" + describe 'empty state' do + it 'user sees empty state' do + visit project_issues_path(project) - first('.js-user-search').click - click_link 'Unassigned' + 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 + end - click_button 'Save changes' + describe 'Edit issue' do + let!(:issue) do + create(:issue, + author: user, + assignees: [user], + project: project) + end - page.within('.assignee') do - expect(page).to have_content 'No assignee - assign yourself' + before do + visit edit_project_issue_path(project, issue) + find('.js-zen-enter').click end - expect(issue.reload.assignees).to be_empty + it 'opens new issue popup' do + expect(page).to have_content("Issue ##{issue.iid}") + end end - end - describe 'due date', :js do - context 'on new form' do - before do - visit new_project_issue_path(project) + describe 'Editing issue assignee' do + let!(:issue) do + create(:issue, + author: user, + assignees: [user], + project: project) end - 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 + it 'allows user to select unassigned', :js do + visit edit_project_issue_path(project, issue) - page.within '.pika-single' do - click_button date.day - end + expect(page).to have_content "Assignee #{user.name}" - expect(find('#issuable-due-date').value).to eq date.to_s + first('.js-user-search').click + click_link 'Unassigned' - click_button 'Submit issue' + click_button 'Save changes' - page.within '.issuable-sidebar' do - expect(page).to have_content date.to_s(:medium) + page.within('.assignee') do + expect(page).to have_content 'No assignee - assign yourself' end + + expect(issue.reload.assignees).to be_empty end end - context 'on edit form' do - let(:issue) { create(:issue, author: user, project: project, due_date: Date.today.at_beginning_of_month.to_s) } + describe 'due date', :js do + context 'on new form' do + before do + visit new_project_issue_path(project) + end - before do - visit edit_project_issue_path(project, issue) - end + it 'saves with due date' do + date = Date.today.at_beginning_of_month - 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 - expect(find('#issuable-due-date').value).to eq date.to_s + page.within '.pika-single' do + click_button date.day + end - date = date.tomorrow + expect(find('#issuable-due-date').value).to eq date.to_s - fill_in 'issue_title', with: 'bug 345' - fill_in 'issue_description', with: 'bug description' - find('#issuable-due-date').click + click_button 'Submit issue' - page.within '.pika-single' do - click_button date.day + page.within '.issuable-sidebar' do + expect(page).to have_content date.to_s(:medium) + end end + end - expect(find('#issuable-due-date').value).to eq date.to_s + context 'on edit form' do + let(:issue) { create(:issue, author: user, project: project, due_date: Date.today.at_beginning_of_month.to_s) } - click_button 'Save changes' - - page.within '.issuable-sidebar' do - expect(page).to have_content date.to_s(:medium) + before do + visit edit_project_issue_path(project, issue) end - end - it 'warns about version conflict' do - issue.update(title: "New title") + 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' + expect(find('#issuable-due-date').value).to eq date.to_s - click_button 'Save changes' + date = date.tomorrow - expect(page).to have_content 'Someone edited the issue the same time you did' - end - end - end + 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 - describe 'Issue info' do - it 'links to current issue in breadcrubs' do - issue = create(:issue, project: project) + expect(find('#issuable-due-date').value).to eq date.to_s - visit project_issue_path(project, issue) + click_button 'Save changes' - expect(find('.breadcrumbs-sub-title a')[:href]).to end_with(issue_path(issue)) - end + page.within '.issuable-sidebar' do + expect(page).to have_content date.to_s(:medium) + end + 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) + it 'warns about version conflict' do + issue.update(title: "New title") - visit project_issues_path(project, assignee_id: user.id) + fill_in 'issue_title', with: 'bug 345' + fill_in 'issue_description', with: 'bug description' - expect(page).to have_content 'foobar' - expect(page.all('.no-comments').first.text).to eq "0" - end - end + click_button 'Save changes' - describe 'Filter issue' do - before do - %w(foobar barbaz gitlab).each do |title| - create(:issue, - author: user, - assignees: [user], - project: project, - title: title) + expect(page).to have_content 'Someone edited the issue the same time you did' + end end - - @issue = Issue.find_by(title: 'foobar') - @issue.milestone = create(:milestone, project: project) - @issue.assignees = [] - @issue.save end - let(:issue) { @issue } + describe 'Issue info' do + it 'links to current issue in breadcrubs' do + issue = create(:issue, project: project) - it 'allows filtering by issues with no specified assignee' do - visit project_issues_path(project, assignee_id: IssuableFinder::NONE) + visit project_issue_path(project, issue) - expect(page).to have_content 'foobar' - expect(page).not_to have_content 'barbaz' - expect(page).not_to have_content 'gitlab' - end + expect(find('.breadcrumbs-sub-title a')[:href]).to end_with(issue_path(issue)) + end - it 'allows filtering by a specified assignee' do - visit project_issues_path(project, assignee_id: user.id) + it 'excludes award_emoji from comment count' do + issue = create(:issue, author: user, assignees: [user], project: project, title: 'foobar') + create(:award_emoji, awardable: issue) - expect(page).not_to have_content 'foobar' - expect(page).to have_content 'barbaz' - expect(page).to have_content 'gitlab' - end - end + visit project_issues_path(project, assignee_id: user.id) - describe 'filter issue' do - titles = %w[foo bar baz] - titles.each_with_index do |title, index| - let!(title.to_sym) do - create(:issue, title: title, - project: project, - created_at: Time.now - (index * 60)) + expect(page).to have_content 'foobar' + expect(page.all('.no-comments').first.text).to eq "0" end end - let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') } - let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') } - it 'sorts by newest' do - visit project_issues_path(project, sort: sort_value_created_date) + describe 'Filter issue' do + before do + %w(foobar barbaz gitlab).each do |title| + create(:issue, + author: user, + assignees: [user], + project: project, + title: title) + end - expect(first_issue).to include('foo') - expect(last_issue).to include('baz') - end + @issue = Issue.find_by(title: 'foobar') + @issue.milestone = create(:milestone, project: project) + @issue.assignees = [] + @issue.save + end - it 'sorts by most recently updated' do - baz.updated_at = Time.now + 100 - baz.save - visit project_issues_path(project, sort: sort_value_recently_updated) + let(:issue) { @issue } - expect(first_issue).to include('baz') - end + it 'allows filtering by issues with no specified assignee' do + visit project_issues_path(project, assignee_id: IssuableFinder::NONE) - describe 'sorting by due date' do - before do - foo.update(due_date: 1.day.from_now) - bar.update(due_date: 6.days.from_now) + expect(page).to have_content 'foobar' + expect(page).not_to have_content 'barbaz' + expect(page).not_to have_content 'gitlab' end - it 'sorts by due date' do - visit project_issues_path(project, sort: sort_value_due_date) + it 'allows filtering by a specified assignee' do + visit project_issues_path(project, assignee_id: user.id) - expect(first_issue).to include('foo') + expect(page).not_to have_content 'foobar' + expect(page).to have_content 'barbaz' + expect(page).to have_content 'gitlab' end + end - it 'sorts by due date by excluding nil due dates' do - bar.update(due_date: nil) + describe 'filter issue' do + titles = %w[foo bar baz] + titles.each_with_index do |title, index| + let!(title.to_sym) do + create(:issue, title: title, + project: project, + created_at: Time.now - (index * 60)) + end + end + let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') } + let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') } - visit project_issues_path(project, sort: sort_value_due_date) + 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 - context 'with a filter on labels' do - let(:label) { create(:label, project: project) } + it 'sorts by most recently updated' do + baz.updated_at = Time.now + 100 + baz.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 - create(:label_link, label: label, target: foo) + foo.update(due_date: 1.day.from_now) + bar.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 least recently due date by excluding nil due dates' do + it 'sorts by due date by excluding nil due dates' do bar.update(due_date: nil) - visit project_issues_path(project, label_names: [label.name], sort: sort_value_due_date_later) + visit project_issues_path(project, sort: sort_value_due_date) expect(first_issue).to include('foo') end - end - end - describe 'filtering by due date' do - before do - foo.update(due_date: 1.day.from_now) - bar.update(due_date: 6.days.from_now) - end + context 'with a filter on labels' do + let(:label) { create(:label, project: project) } + + before do + create(:label_link, label: label, target: foo) + end + + it 'sorts by least recently due date by excluding nil due dates' do + bar.update(due_date: nil) - it 'filters by none' do - visit project_issues_path(project, due_date: Issue::NoDueDate.name) + visit project_issues_path(project, label_names: [label.name], sort: sort_value_due_date_later) - 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') + expect(first_issue).to include('foo') + end end end - it 'filters by any' do - visit project_issues_path(project, due_date: Issue::AnyDueDate.name) + describe 'filtering by due date' do + before do + foo.update(due_date: 1.day.from_now) + bar.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).to have_content('foo') - expect(page).to have_content('bar') - expect(page).to have_content('baz') + 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 - end - it 'filters by due this week' do - foo.update(due_date: Date.today.beginning_of_week + 2.days) - bar.update(due_date: Date.today.end_of_week) - baz.update(due_date: Date.today - 8.days) + it 'filters by due this week' do + foo.update(due_date: Date.today.beginning_of_week + 2.days) + bar.update(due_date: Date.today.end_of_week) + baz.update(due_date: Date.today - 8.days) - visit project_issues_path(project, due_date: Issue::DueThisWeek.name) + 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') + 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 - end - it 'filters by due this month' do - foo.update(due_date: Date.today.beginning_of_month + 2.days) - bar.update(due_date: Date.today.end_of_month) - baz.update(due_date: Date.today - 50.days) + it 'filters by due this month' do + foo.update(due_date: Date.today.beginning_of_month + 2.days) + bar.update(due_date: Date.today.end_of_month) + baz.update(due_date: Date.today - 50.days) - visit project_issues_path(project, due_date: Issue::DueThisMonth.name) + 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') + 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 - end - it 'filters by overdue' do - foo.update(due_date: Date.today + 2.days) - bar.update(due_date: Date.today + 20.days) - baz.update(due_date: Date.yesterday) + it 'filters by overdue' do + foo.update(due_date: Date.today + 2.days) + bar.update(due_date: Date.today + 20.days) + baz.update(due_date: Date.yesterday) - visit project_issues_path(project, due_date: Issue::Overdue.name) + 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') + 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 - end - describe 'sorting by milestone' do - before do - foo.milestone = newer_due_milestone - foo.save - bar.milestone = later_due_milestone - bar.save - end + describe 'sorting by milestone' do + before do + foo.milestone = newer_due_milestone + foo.save + bar.milestone = later_due_milestone + bar.save + end - it 'sorts by milestone' do - visit project_issues_path(project, sort: sort_value_milestone) + 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') + expect(first_issue).to include('foo') + expect(last_issue).to include('baz') + end end - end - describe 'combine filter and sort' do - let(:user2) { create(:user) } + describe 'combine filter and sort' do + let(:user2) { create(:user) } - before do - foo.assignees << user2 - foo.save - bar.assignees << user2 - bar.save - end + before do + foo.assignees << user2 + foo.save + bar.assignees << user2 + bar.save + end - it 'sorts with a filter applied' do - visit project_issues_path(project, sort: sort_value_created_date, assignee_id: user2.id) + 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') + expect(first_issue).to include('foo') + expect(last_issue).to include('bar') + expect(page).not_to have_content('baz') + end end 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) } + 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 - stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") - project1.team << [user, :master] - visit namespace_project_issues_path(user.namespace, project1) - end + before do + stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") + project1.team << [user, :master] + visit namespace_project_issues_path(user.namespace, project1) + 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 + 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 + wait_for_requests - expect(page).to have_no_field('issuable_email', with: previous_token) - new_token = project1.new_issuable_address(user.reload, 'issue') - expect(page).to have_field( - 'issuable_email', - with: new_token - ) + expect(page).to have_no_field('issuable_email', with: previous_token) + new_token = project1.new_issuable_address(user.reload, 'issue') + expect(page).to have_field( + 'issuable_email', + with: new_token + ) + end end - end - describe 'update labels from issue#show', :js do - let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } - let!(:label) { create(:label, project: project) } + describe 'update labels from issue#show', :js do + let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } + let!(:label) { create(:label, project: project) } - before do - visit project_issue_path(project, issue) - end + before do + visit project_issue_path(project, issue) + end - it 'will not send ajax request when no data is changed' do - page.within '.labels' do - click_link 'Edit' + it 'will not send ajax request when no data is changed' do + page.within '.labels' do + click_link 'Edit' - find('.dropdown-menu-close', match: :first).click + find('.dropdown-menu-close', match: :first).click - expect(page).not_to have_selector('.block-loading') + expect(page).not_to have_selector('.block-loading') + end end end - end - describe 'update assignee from issue#show' do - let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } + describe 'update assignee from issue#show' do + let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } - context 'by authorized user' do - it 'allows user to select unassigned', :js do - visit project_issue_path(project, issue) + context 'by authorized user' do + it 'allows user to select unassigned', :js do + visit project_issue_path(project, issue) - page.within('.assignee') do - expect(page).to have_content "#{user.name}" + 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 'No assignee' - end + click_link 'Edit' + click_link 'Unassigned' + first('.title').click + expect(page).to have_content 'No assignee' + end - # wait_for_requests does not work with vue-resource at the moment - sleep 1 + # wait_for_requests does not work with vue-resource at the moment + sleep 1 - expect(issue.reload.assignees).to be_empty - end + expect(issue.reload.assignees).to be_empty + end - it 'allows user to select an assignee', :js do - issue2 = create(:issue, project: project, author: user) - visit project_issue_path(project, issue2) + it 'allows user to select an assignee', :js do + issue2 = create(:issue, project: project, author: user) + visit project_issue_path(project, issue2) - page.within('.assignee') do - expect(page).to have_content "No assignee" - end + page.within('.assignee') do + expect(page).to have_content "No assignee" + end - page.within '.assignee' do - click_link 'Edit' - end + page.within '.assignee' do + click_link 'Edit' + end - page.within '.dropdown-menu-user' do - click_link user.name - end + page.within '.dropdown-menu-user' do + click_link user.name + end - page.within('.assignee') do - expect(page).to have_content user.name + page.within('.assignee') do + expect(page).to have_content user.name + end end - end - it 'allows user to unselect themselves', :js do - issue2 = create(:issue, project: project, author: user) - visit project_issue_path(project, issue2) + it 'allows user to unselect themselves', :js 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 + page.within '.assignee' do + click_link 'Edit' + click_link user.name - page.within '.value .author' do - expect(page).to have_content user.name - end + page.within '.value .author' do + expect(page).to have_content user.name + end - click_link 'Edit' - click_link user.name + click_link 'Edit' + click_link user.name - page.within '.value .assign-yourself' do - expect(page).to have_content "No assignee" + page.within '.value .assign-yourself' do + expect(page).to have_content "No assignee" + end end end end - end - context 'by unauthorized user' do - let(:guest) { create(:user) } + context 'by unauthorized user' do + let(:guest) { create(:user) } - before do - project.team << [[guest], :guest] - end + before do + project.team << [[guest], :guest] + end - it 'shows assignee text', :js do - sign_out(:user) - sign_in(guest) + it 'shows assignee text', :js do + sign_out(:user) + sign_in(guest) - visit project_issue_path(project, issue) - expect(page).to have_content issue.assignees.first.name + visit project_issue_path(project, issue) + expect(page).to have_content issue.assignees.first.name + end end end - end - describe 'update milestone from issue#show' do - let!(:issue) { create(:issue, project: project, author: user) } - let!(:milestone) { create(:milestone, project: project) } + describe 'update milestone from issue#show' do + let!(:issue) { create(:issue, project: project, author: user) } + let!(:milestone) { create(:milestone, project: project) } - context 'by authorized user' do - it 'allows user to select unassigned', :js do - visit project_issue_path(project, issue) + context 'by authorized user' do + it 'allows user to select unassigned', :js do + visit project_issue_path(project, issue) - page.within('.milestone') do - expect(page).to have_content "None" - end + 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' + 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 + + expect(issue.reload.milestone).to be_nil end - expect(issue.reload.milestone).to be_nil - end + it 'allows user to de-select milestone', :js do + visit project_issue_path(project, issue) - it 'allows user to de-select milestone', :js do - visit project_issue_path(project, issue) + page.within('.milestone') do + click_link 'Edit' + click_link milestone.title - page.within('.milestone') do - click_link 'Edit' - click_link milestone.title - - page.within '.value' do - expect(page).to have_content milestone.title - end + page.within '.value' do + expect(page).to have_content milestone.title + end - click_link 'Edit' - click_link milestone.title + click_link 'Edit' + click_link milestone.title - page.within '.value' do - expect(page).to have_content 'None' + page.within '.value' do + expect(page).to have_content 'None' + end end end end - end - context 'by unauthorized user' do - let(:guest) { create(:user) } + context 'by unauthorized user' do + let(:guest) { create(:user) } - before do - project.team << [guest, :guest] - issue.milestone = milestone - issue.save - end + before do + project.team << [guest, :guest] + issue.milestone = milestone + issue.save + end - it 'shows milestone text', :js do - sign_out(:user) - sign_in(guest) + it 'shows milestone text', :js do + sign_out(:user) + sign_in(guest) - visit project_issue_path(project, issue) - expect(page).to have_content milestone.title + visit project_issue_path(project, issue) + expect(page).to have_content milestone.title + end end end - end - describe 'new issue' do - let!(:issue) { create(:issue, project: project) } + describe 'new issue' do + let!(:issue) { create(:issue, project: project) } - context 'by unauthenticated user' do - before do - sign_out(:user) - end + context 'by unauthenticated user' do + before do + sign_out(:user) + end - it 'redirects to signin then back to new issue after signin' do - visit project_issues_path(project) + it 'redirects to signin then back to new issue after signin' do + visit project_issues_path(project) - page.within '.nav-controls' do - click_link 'New issue' - end + page.within '.nav-controls' do + click_link 'New issue' + end - expect(current_path).to eq new_user_session_path + expect(current_path).to eq new_user_session_path - gitlab_sign_in(create(:user)) + gitlab_sign_in(create(:user)) - expect(current_path).to eq new_project_issue_path(project) + expect(current_path).to eq new_project_issue_path(project) + end end - end - context 'dropzone upload file', :js do - before do - visit new_project_issue_path(project) - 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') + 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 + 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') + 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 + 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) + 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 + 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) + 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 - end - context 'form filled by URL parameters' do - let(:project) { create(:project, :public, :repository) } + 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 + 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') + it 'fills in template' do + expect(find('.js-issuable-selector .dropdown-toggle-text')).to have_content('bug') + end end end - end - describe 'new issue by email' do - shared_examples 'show the email in the modal' do - let(:issue) { create(:issue, project: project) } + 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") + 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 + 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') + 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}']") + expect(page).to have_selector("input[value='#{email}']") + end end end - end - context 'with existing issues' do - let!(:issue) { create(:issue, project: project, author: user) } + context 'with existing issues' do + let!(:issue) { create(:issue, project: project, author: user) } - it_behaves_like 'show the email in the modal' - end + it_behaves_like 'show the email in the modal' + end - context 'without existing issues' do - it_behaves_like 'show the email in the modal' + context 'without existing issues' do + it_behaves_like 'show the email in the modal' + end end - end - describe 'due date' do - context 'update due on issue#show', :js do - let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } + describe 'due date' do + context 'update due on issue#show', :js do + let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } - before do - visit project_issue_path(project, issue) - end + before do + visit project_issue_path(project, issue) + end - it 'adds due date to issue' do - date = Date.today.at_beginning_of_month + 2.days + 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 '.due_date' do + click_link 'Edit' - page.within '.pika-single' do - click_button date.day - end + page.within '.pika-single' do + click_button date.day + end - wait_for_requests + wait_for_requests - expect(find('.value').text).to have_content date.strftime('%b %-d, %Y') + expect(find('.value').text).to have_content date.strftime('%b %-d, %Y') + end end - end - it 'removes due date from issue' do - date = Date.today.at_beginning_of_month + 2.days + 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 '.due_date' do + click_link 'Edit' - page.within '.pika-single' do - click_button date.day - end + page.within '.pika-single' do + click_button date.day + end - wait_for_requests + wait_for_requests - expect(page).to have_no_content 'No due date' + expect(page).to have_no_content 'No due date' - click_link 'remove due date' - expect(page).to have_content 'No due date' + click_link 'remove due date' + expect(page).to have_content 'No due date' + end end end end - end - describe 'title issue#show', :js do - it 'updates the title', :js do - issue = create(:issue, author: user, assignees: [user], project: project, title: 'new title') + describe 'title issue#show', :js do + it 'updates the title', :js do + issue = create(:issue, author: user, assignees: [user], project: project, title: 'new title') - visit project_issue_path(project, issue) + visit project_issue_path(project, issue) - expect(page).to have_text("new title") + expect(page).to have_text("new title") - issue.update(title: "updated title") + issue.update(title: "updated title") - wait_for_requests - expect(page).to have_text("updated title") + wait_for_requests + expect(page).to have_text("updated title") + end end - end - describe 'confidential issue#show', :js do - it 'shows confidential sibebar information as confidential and can be turned off' do - issue = create(:issue, :confidential, project: project) + describe 'confidential issue#show', :js 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) + 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') + 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') + find('.confidential-edit').click + expect(page).to have_css('.sidebar-item-warning-message') - within('.sidebar-item-warning-message') do - find('.btn-close').click - end + within('.sidebar-item-warning-message') do + find('.btn-close').click + end - wait_for_requests + wait_for_requests - visit project_issue_path(project, issue) + visit project_issue_path(project, issue) - expect(page).not_to have_css('.is-active') + expect(page).not_to have_css('.is-active') + end end end end