2019-09-30 08:06:01 -04:00
# frozen_string_literal: true
2021-08-16 08:09:17 -04:00
require 'spec_helper'
2013-02-11 08:32:29 -05:00
2020-06-24 05:08:32 -04:00
RSpec . describe IssuesHelper do
2017-08-02 15:55:11 -04:00
let ( :project ) { create ( :project ) }
2013-02-19 08:21:59 -05:00
let ( :issue ) { create :issue , project : project }
let ( :ext_project ) { create :redmine_project }
2013-02-11 08:32:29 -05:00
2021-08-16 08:09:17 -04:00
describe '#work_item_type_icon' do
it 'returns icon of all standard base types' do
2021-12-22 07:16:22 -05:00
WorkItems :: Type . base_types . each do | type |
2021-08-16 08:09:17 -04:00
expect ( work_item_type_icon ( type [ 0 ] ) ) . to eq " issue-type- #{ type [ 0 ] . to_s . dasherize } "
end
end
it 'defaults to issue icon if type is unknown' do
expect ( work_item_type_icon ( 'invalid' ) ) . to eq 'issue-type-issue'
end
end
2016-06-19 19:06:57 -04:00
describe '#award_user_list' do
2021-08-16 08:09:17 -04:00
it 'returns a comma-separated list of the first X users' do
2016-10-06 14:00:51 -04:00
user = build_stubbed ( :user , name : 'Joe' )
awards = Array . new ( 3 , build_stubbed ( :award_emoji , user : user ) )
2016-06-19 19:06:57 -04:00
2017-02-22 17:54:59 -05:00
expect ( award_user_list ( awards , nil , limit : 3 ) )
. to eq ( 'Joe, Joe, and Joe' )
2016-06-19 19:06:57 -04:00
end
2016-07-11 14:53:07 -04:00
it " displays the current user's name as 'You' " do
2016-10-06 14:00:51 -04:00
user = build_stubbed ( :user , name : 'Joe' )
award = build_stubbed ( :award_emoji , user : user )
2016-06-19 19:06:57 -04:00
2016-10-06 14:00:51 -04:00
expect ( award_user_list ( [ award ] , user ) ) . to eq ( 'You' )
expect ( award_user_list ( [ award ] , nil ) ) . to eq 'Joe'
2016-06-21 18:22:03 -04:00
end
2021-08-16 08:09:17 -04:00
it 'truncates lists' do
2016-10-06 14:00:51 -04:00
user = build_stubbed ( :user , name : 'Jane' )
awards = Array . new ( 5 , build_stubbed ( :award_emoji , user : user ) )
2017-02-22 17:54:59 -05:00
expect ( award_user_list ( awards , nil , limit : 3 ) )
. to eq ( 'Jane, Jane, Jane, and 2 more.' )
2016-06-21 18:22:03 -04:00
end
2021-08-16 08:09:17 -04:00
it 'displays the current user in front of other users' do
2016-10-06 14:00:51 -04:00
current_user = build_stubbed ( :user )
my_award = build_stubbed ( :award_emoji , user : current_user )
award = build_stubbed ( :award_emoji , user : build_stubbed ( :user , name : 'Jane' ) )
awards = Array . new ( 5 , award ) . push ( my_award )
2017-06-21 09:48:12 -04:00
expect ( award_user_list ( awards , current_user , limit : 2 ) )
2021-08-16 08:09:17 -04:00
. to eq ( 'You, Jane, and 4 more.' )
2016-06-19 19:06:57 -04:00
end
end
2016-12-30 09:44:21 -05:00
describe '#award_state_class' do
2016-04-16 15:09:08 -04:00
let! ( :upvote ) { create ( :award_emoji ) }
2018-04-06 14:19:37 -04:00
let ( :awardable ) { upvote . awardable }
let ( :user ) { upvote . user }
before do
allow ( helper ) . to receive ( :can? ) do | * args |
Ability . allowed? ( * args )
end
end
2015-11-19 07:41:05 -05:00
2021-08-16 08:09:17 -04:00
it 'returns disabled string for unauthenticated user' do
expect ( helper . award_state_class ( awardable , AwardEmoji . all , nil ) ) . to eq ( 'disabled' )
2018-04-06 14:19:37 -04:00
end
2021-08-16 08:09:17 -04:00
it 'returns disabled for a user that does not have access to the awardable' do
expect ( helper . award_state_class ( awardable , AwardEmoji . all , build ( :user ) ) ) . to eq ( 'disabled' )
2015-11-19 07:41:05 -05:00
end
2021-08-16 08:09:17 -04:00
it 'returns active string for author' do
expect ( helper . award_state_class ( awardable , AwardEmoji . all , upvote . user ) ) . to eq ( 'active' )
2018-04-06 14:19:37 -04:00
end
2021-08-16 08:09:17 -04:00
it 'is blank for a user that has access to the awardable' do
2018-04-06 14:19:37 -04:00
user = build ( :user )
expect ( helper ) . to receive ( :can? ) . with ( user , :award_emoji , awardable ) . and_return ( true )
expect ( helper . award_state_class ( awardable , AwardEmoji . all , user ) ) . to be_blank
2015-11-19 07:41:05 -05:00
end
end
2015-12-25 05:08:53 -05:00
2021-08-16 08:09:17 -04:00
describe 'awards_sort' do
it 'sorts a hash so thumbsup and thumbsdown are always on top' do
data = { 'thumbsdown' = > 'some value' , 'lifter' = > 'some value' , 'thumbsup' = > 'some value' }
2017-02-22 12:46:57 -05:00
expect ( awards_sort ( data ) . keys ) . to eq ( %w( thumbsup thumbsdown lifter ) )
2015-12-25 05:08:53 -05:00
end
end
2016-04-06 10:02:22 -04:00
2021-08-16 08:09:17 -04:00
describe '#link_to_discussions_to_resolve' do
describe 'passing only a merge request' do
2017-03-08 10:39:20 -05:00
let ( :merge_request ) { create ( :merge_request ) }
2021-08-16 08:09:17 -04:00
it 'links just the merge request' do
2017-06-29 13:06:35 -04:00
expected_path = project_merge_request_path ( merge_request . project , merge_request )
2017-03-08 10:39:20 -05:00
expect ( link_to_discussions_to_resolve ( merge_request , nil ) ) . to include ( expected_path )
end
2021-08-16 08:09:17 -04:00
it 'contains the reference to the merge request' do
2017-03-08 10:39:20 -05:00
expect ( link_to_discussions_to_resolve ( merge_request , nil ) ) . to include ( merge_request . to_reference )
end
end
2021-08-16 08:09:17 -04:00
describe 'when passing a discussion' do
2019-01-16 07:09:29 -05:00
let ( :diff_note ) { create ( :diff_note_on_merge_request ) }
2017-03-08 10:39:20 -05:00
let ( :merge_request ) { diff_note . noteable }
2017-03-17 15:25:52 -04:00
let ( :discussion ) { diff_note . to_discussion }
2017-03-08 10:39:20 -05:00
2021-08-16 08:09:17 -04:00
it 'links to the merge request with first note if a single discussion was passed' do
2017-03-08 10:39:20 -05:00
expected_path = Gitlab :: UrlBuilder . build ( diff_note )
expect ( link_to_discussions_to_resolve ( merge_request , discussion ) ) . to include ( expected_path )
end
2021-08-16 08:09:17 -04:00
it 'contains both the reference to the merge request and a mention of the discussion' do
2017-03-08 10:39:20 -05:00
expect ( link_to_discussions_to_resolve ( merge_request , discussion ) ) . to include ( " #{ merge_request . to_reference } (discussion #{ diff_note . id } ) " )
end
end
end
2018-04-10 13:49:26 -04:00
describe '#show_new_issue_link?' do
before do
allow ( helper ) . to receive ( :current_user )
end
it 'is false when no project there is no project' do
expect ( helper . show_new_issue_link? ( nil ) ) . to be_falsey
end
it 'is true when there is a project and no logged in user' do
expect ( helper . show_new_issue_link? ( build ( :project ) ) ) . to be_truthy
end
it 'is true when the current user does not have access to the project' do
project = build ( :project )
allow ( helper ) . to receive ( :current_user ) . and_return ( project . owner )
expect ( helper ) . to receive ( :can? ) . with ( project . owner , :create_issue , project ) . and_return ( true )
expect ( helper . show_new_issue_link? ( project ) ) . to be_truthy
end
end
2019-09-13 09:26:31 -04:00
describe '#issue_closed_link' do
let ( :new_issue ) { create ( :issue , project : project ) }
let ( :guest ) { create ( :user ) }
before do
allow ( helper ) . to receive ( :can? ) do | * args |
Ability . allowed? ( * args )
end
end
shared_examples 'successfully displays link to issue and with css class' do | action |
it 'returns link' do
2020-03-02 10:08:01 -05:00
link = " <a class= \" #{ css_class } \" href= \" / #{ new_issue . project . full_path } /-/issues/ #{ new_issue . iid } \" >( #{ action } )</a> "
2019-09-13 09:26:31 -04:00
expect ( helper . issue_closed_link ( issue , user , css_class : css_class ) ) . to match ( link )
end
end
shared_examples 'does not display link' do
it 'returns nil' do
expect ( helper . issue_closed_link ( issue , user ) ) . to be_nil
end
end
context 'with linked issue' do
context 'with moved issue' do
before do
2020-07-27 08:09:50 -04:00
issue . update! ( moved_to : new_issue )
2019-09-13 09:26:31 -04:00
end
context 'when user has permission to see new issue' do
let ( :user ) { project . owner }
let ( :css_class ) { 'text-white text-underline' }
it_behaves_like 'successfully displays link to issue and with css class' , 'moved'
end
context 'when user has no permission to see new issue' do
let ( :user ) { guest }
it_behaves_like 'does not display link'
end
end
context 'with duplicated issue' do
before do
2020-07-27 08:09:50 -04:00
issue . update! ( duplicated_to : new_issue )
2019-09-13 09:26:31 -04:00
end
context 'when user has permission to see new issue' do
let ( :user ) { project . owner }
let ( :css_class ) { 'text-white text-underline' }
it_behaves_like 'successfully displays link to issue and with css class' , 'duplicated'
end
context 'when user has no permission to see new issue' do
let ( :user ) { guest }
it_behaves_like 'does not display link'
end
end
end
context 'without linked issue' do
let ( :user ) { project . owner }
before do
2020-07-27 08:09:50 -04:00
issue . update! ( moved_to : nil , duplicated_to : nil )
2019-09-13 09:26:31 -04:00
end
it_behaves_like 'does not display link'
end
end
2020-07-15 17:09:26 -04:00
describe '#show_moved_service_desk_issue_warning?' do
let ( :project1 ) { create ( :project , service_desk_enabled : true ) }
let ( :project2 ) { create ( :project , service_desk_enabled : true ) }
let! ( :old_issue ) { create ( :issue , author : User . support_bot , project : project1 ) }
let! ( :new_issue ) { create ( :issue , author : User . support_bot , project : project2 ) }
before do
allow ( Gitlab :: IncomingEmail ) . to receive ( :enabled? ) { true }
allow ( Gitlab :: IncomingEmail ) . to receive ( :supports_wildcard? ) { true }
2020-07-27 08:09:50 -04:00
old_issue . update! ( moved_to : new_issue )
2020-07-15 17:09:26 -04:00
end
it 'is true when moved issue project has service desk disabled' do
project2 . update! ( service_desk_enabled : false )
expect ( helper . show_moved_service_desk_issue_warning? ( new_issue ) ) . to be ( true )
end
it 'is false when moved issue project has service desk enabled' do
expect ( helper . show_moved_service_desk_issue_warning? ( new_issue ) ) . to be ( false )
end
end
2020-09-21 05:09:29 -04:00
2021-01-26 13:09:30 -05:00
describe '#issue_header_actions_data' do
let ( :current_user ) { create ( :user ) }
before do
allow ( helper ) . to receive ( :current_user ) . and_return ( current_user )
allow ( helper ) . to receive ( :can? ) . and_return ( true )
end
it 'returns expected result' do
expected = {
2021-08-16 08:09:17 -04:00
can_create_issue : 'true' ,
2021-12-16 07:15:41 -05:00
can_destroy_issue : 'true' ,
2021-08-16 08:09:17 -04:00
can_reopen_issue : 'true' ,
can_report_spam : 'false' ,
can_update_issue : 'true' ,
2021-01-26 13:09:30 -05:00
iid : issue . iid ,
2021-08-16 08:09:17 -04:00
is_issue_author : 'false' ,
2021-12-16 07:15:41 -05:00
issue_path : issue_path ( issue ) ,
2021-08-16 08:09:17 -04:00
issue_type : 'issue' ,
2021-08-23 17:11:23 -04:00
new_issue_path : new_project_issue_path ( project , { issue : { description : " Related to \# #{ issue . iid } . \n \n " } } ) ,
2021-01-26 13:09:30 -05:00
project_path : project . full_path ,
report_abuse_path : new_abuse_report_path ( user_id : issue . author . id , ref_url : issue_url ( issue ) ) ,
submit_as_spam_path : mark_as_spam_project_issue_path ( project , issue )
}
expect ( helper . issue_header_actions_data ( project , issue , current_user ) ) . to include ( expected )
end
end
2021-04-01 14:13:56 -04:00
shared_examples 'issues list data' do
it 'returns expected result' do
finder = double . as_null_object
allow ( helper ) . to receive ( :current_user ) . and_return ( current_user )
allow ( helper ) . to receive ( :finder ) . and_return ( finder )
allow ( helper ) . to receive ( :can? ) . and_return ( true )
2021-04-09 14:09:24 -04:00
allow ( helper ) . to receive ( :image_path ) . and_return ( '#' )
2021-04-01 14:13:56 -04:00
allow ( helper ) . to receive ( :import_csv_namespace_project_issues_path ) . and_return ( '#' )
2021-11-18 13:14:27 -05:00
allow ( helper ) . to receive ( :issue_repositioning_disabled? ) . and_return ( true )
2021-04-09 14:09:24 -04:00
allow ( helper ) . to receive ( :url_for ) . and_return ( '#' )
2021-04-01 14:13:56 -04:00
expected = {
2021-04-27 08:10:12 -04:00
autocomplete_award_emojis_path : autocomplete_award_emojis_path ,
2021-04-01 14:13:56 -04:00
calendar_path : '#' ,
can_bulk_update : 'true' ,
can_edit : 'true' ,
2021-04-09 14:09:24 -04:00
can_import_issues : 'true' ,
2021-09-16 11:12:47 -04:00
email : current_user & . notification_email_or_default ,
2021-04-28 14:10:12 -04:00
emails_help_page_path : help_page_path ( 'development/emails' , anchor : 'email-namespace' ) ,
2021-04-09 14:09:24 -04:00
empty_state_svg_path : '#' ,
2021-04-01 14:13:56 -04:00
export_csv_path : export_csv_project_issues_path ( project ) ,
2021-09-01 08:10:15 -04:00
full_path : project . full_path ,
has_any_issues : project_issues ( project ) . exists? . to_s ,
2021-04-01 14:13:56 -04:00
import_csv_issues_path : '#' ,
2021-04-28 14:10:12 -04:00
initial_email : project . new_issuable_address ( current_user , 'issue' ) ,
2022-02-03 22:15:11 -05:00
initial_sort : current_user & . user_preference & . issues_sort ,
2021-12-16 13:14:09 -05:00
is_anonymous_search_disabled : 'true' ,
2021-11-18 13:14:27 -05:00
is_issue_repositioning_disabled : 'true' ,
2021-09-15 08:11:13 -04:00
is_project : 'true' ,
2021-04-09 14:09:24 -04:00
is_signed_in : current_user . present? . to_s ,
2021-08-16 11:10:05 -04:00
jira_integration_path : help_page_url ( 'integration/jira/issues' , anchor : 'view-jira-issues' ) ,
2021-04-28 14:10:12 -04:00
markdown_help_path : help_page_path ( 'user/markdown' ) ,
2021-04-01 14:13:56 -04:00
max_attachment_size : number_to_human_size ( Gitlab :: CurrentSettings . max_attachment_size . megabytes ) ,
2021-05-26 17:10:49 -04:00
new_issue_path : new_project_issue_path ( project , issue : { milestone_id : finder . milestones . first . id } ) ,
2021-04-01 14:13:56 -04:00
project_import_jira_path : project_import_jira_path ( project ) ,
2021-04-28 14:10:12 -04:00
quick_actions_help_path : help_page_path ( 'user/project/quick_actions' ) ,
2021-10-27 08:09:41 -04:00
releases_path : project_releases_path ( project , format : :json ) ,
2021-04-28 14:10:12 -04:00
reset_path : new_issuable_address_project_path ( project , issuable_type : 'issue' ) ,
2021-04-01 14:13:56 -04:00
rss_path : '#' ,
2021-04-09 14:09:24 -04:00
show_new_issue_link : 'true' ,
sign_in_path : new_user_session_path
2021-04-01 14:13:56 -04:00
}
2021-09-15 08:11:13 -04:00
expect ( helper . project_issues_list_data ( project , current_user , finder ) ) . to include ( expected )
2021-04-01 14:13:56 -04:00
end
end
2021-09-15 08:11:13 -04:00
describe '#project_issues_list_data' do
2021-12-16 13:14:09 -05:00
before do
stub_feature_flags ( disable_anonymous_search : true )
end
2021-04-01 14:13:56 -04:00
context 'when user is signed in' do
it_behaves_like 'issues list data' do
let ( :current_user ) { double . as_null_object }
end
end
context 'when user is anonymous' do
it_behaves_like 'issues list data' do
let ( :current_user ) { nil }
end
end
2021-09-15 08:11:13 -04:00
end
describe '#group_issues_list_data' do
let ( :group ) { create ( :group ) }
let ( :current_user ) { double . as_null_object }
it 'returns expected result' do
allow ( helper ) . to receive ( :current_user ) . and_return ( current_user )
allow ( helper ) . to receive ( :can? ) . and_return ( true )
allow ( helper ) . to receive ( :image_path ) . and_return ( '#' )
allow ( helper ) . to receive ( :url_for ) . and_return ( '#' )
2022-02-02 13:15:35 -05:00
assign ( :has_issues , false )
assign ( :has_projects , true )
2021-09-15 08:11:13 -04:00
expected = {
autocomplete_award_emojis_path : autocomplete_award_emojis_path ,
calendar_path : '#' ,
empty_state_svg_path : '#' ,
full_path : group . full_path ,
2022-02-02 13:15:35 -05:00
has_any_issues : false . to_s ,
has_any_projects : true . to_s ,
2021-09-15 08:11:13 -04:00
is_signed_in : current_user . present? . to_s ,
jira_integration_path : help_page_url ( 'integration/jira/issues' , anchor : 'view-jira-issues' ) ,
rss_path : '#' ,
sign_in_path : new_user_session_path
}
2022-02-02 13:15:35 -05:00
expect ( helper . group_issues_list_data ( group , current_user ) ) . to include ( expected )
2021-09-15 08:11:13 -04:00
end
2021-04-01 14:13:56 -04:00
end
2021-05-17 14:10:42 -04:00
describe '#issue_manual_ordering_class' do
context 'when sorting by relative position' do
before do
assign ( :sort , 'relative_position' )
end
it 'returns manual ordering class' do
2021-08-16 08:09:17 -04:00
expect ( helper . issue_manual_ordering_class ) . to eq ( 'manual-ordering' )
2021-05-17 14:10:42 -04:00
end
context 'when manual sorting disabled' do
before do
allow ( helper ) . to receive ( :issue_repositioning_disabled? ) . and_return ( true )
end
it 'returns nil' do
expect ( helper . issue_manual_ordering_class ) . to eq ( nil )
end
end
end
end
describe '#issue_repositioning_disabled?' do
let_it_be ( :group ) { create ( :group ) }
let_it_be ( :project ) { create ( :project , group : group ) }
subject { helper . issue_repositioning_disabled? }
context 'for project' do
before do
assign ( :project , project )
end
it { is_expected . to eq ( false ) }
context 'when block_issue_repositioning feature flag is enabled' do
before do
stub_feature_flags ( block_issue_repositioning : group )
end
it { is_expected . to eq ( true ) }
end
end
context 'for group' do
before do
assign ( :group , group )
end
it { is_expected . to eq ( false ) }
context 'when block_issue_repositioning feature flag is enabled' do
before do
stub_feature_flags ( block_issue_repositioning : group )
end
it { is_expected . to eq ( true ) }
end
end
end
2021-08-25 05:10:52 -04:00
describe '#issue_hidden?' do
context 'when issue is hidden' do
let_it_be ( :banned_user ) { build ( :user , :banned ) }
let_it_be ( :hidden_issue ) { build ( :issue , author : banned_user ) }
context 'when `ban_user_feature_flag` feature flag is enabled' do
it 'returns `true`' do
expect ( helper . issue_hidden? ( hidden_issue ) ) . to eq ( true )
end
end
context 'when `ban_user_feature_flag` feature flag is disabled' do
before do
stub_feature_flags ( ban_user_feature_flag : false )
end
it 'returns `false`' do
expect ( helper . issue_hidden? ( hidden_issue ) ) . to eq ( false )
end
end
end
context 'when issue is not hidden' do
it 'returns `false`' do
expect ( helper . issue_hidden? ( issue ) ) . to eq ( false )
end
end
end
describe '#hidden_issue_icon' do
let_it_be ( :banned_user ) { build ( :user , :banned ) }
let_it_be ( :hidden_issue ) { build ( :issue , author : banned_user ) }
let_it_be ( :mock_svg ) { '<svg></svg>' . html_safe }
before do
allow ( helper ) . to receive ( :sprite_icon ) . and_return ( mock_svg )
end
context 'when issue is hidden' do
it 'returns icon with tooltip' do
expect ( helper . hidden_issue_icon ( hidden_issue ) ) . to eq ( " <span class= \" has-tooltip \" title= \" This issue is hidden because its author has been banned \" > #{ mock_svg } </span> " )
end
end
context 'when issue is not hidden' do
it 'returns `nil`' do
expect ( helper . hidden_issue_icon ( issue ) ) . to be_nil
end
end
end
2013-02-11 08:32:29 -05:00
end