2019-12-21 20:55:43 +05:30
# frozen_string_literal: true
2021-10-27 15:23:28 +05:30
require 'spec_helper'
2014-09-02 18:07:02 +05:30
2020-07-28 23:09:34 +05:30
RSpec . describe IssuesHelper do
2023-03-04 22:38:38 +05:30
let_it_be ( :project ) { create ( :project ) }
let_it_be_with_reload ( :issue ) { create ( :issue , project : project ) }
2014-09-02 18:07:02 +05:30
2021-10-27 15:23:28 +05:30
describe '#work_item_type_icon' do
it 'returns icon of all standard base types' do
2022-03-02 08:16:31 +05:30
WorkItems :: Type . base_types . each do | type |
2021-10-27 15:23:28 +05:30
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-09-29 09:46:39 +05:30
describe '#award_user_list' do
2021-10-27 15:23:28 +05:30
it 'returns a comma-separated list of the first X users' do
2016-11-03 12:29:30 +05:30
user = build_stubbed ( :user , name : 'Joe' )
awards = Array . new ( 3 , build_stubbed ( :award_emoji , user : user ) )
2016-09-29 09:46:39 +05:30
2016-11-03 12:29:30 +05:30
expect ( award_user_list ( awards , nil , limit : 3 ) )
. to eq ( 'Joe, Joe, and Joe' )
2016-09-29 09:46:39 +05:30
end
it " displays the current user's name as 'You' " do
2016-11-03 12:29:30 +05:30
user = build_stubbed ( :user , name : 'Joe' )
award = build_stubbed ( :award_emoji , user : user )
2016-09-29 09:46:39 +05:30
2016-11-03 12:29:30 +05:30
expect ( award_user_list ( [ award ] , user ) ) . to eq ( 'You' )
expect ( award_user_list ( [ award ] , nil ) ) . to eq 'Joe'
2016-09-29 09:46:39 +05:30
end
2021-10-27 15:23:28 +05:30
it 'truncates lists' do
2016-11-03 12:29:30 +05:30
user = build_stubbed ( :user , name : 'Jane' )
awards = Array . new ( 5 , build_stubbed ( :award_emoji , user : user ) )
expect ( award_user_list ( awards , nil , limit : 3 ) )
. to eq ( 'Jane, Jane, Jane, and 2 more.' )
2016-09-29 09:46:39 +05:30
end
2021-10-27 15:23:28 +05:30
it 'displays the current user in front of other users' do
2016-11-03 12:29:30 +05:30
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-09-10 17:25:29 +05:30
expect ( award_user_list ( awards , current_user , limit : 2 ) )
2021-10-27 15:23:28 +05:30
. to eq ( 'You, Jane, and 4 more.' )
2016-09-29 09:46:39 +05:30
end
end
2017-08-17 22:00:37 +05:30
describe '#award_state_class' do
2016-06-16 23:09:34 +05:30
let! ( :upvote ) { create ( :award_emoji ) }
2018-05-09 12:01:36 +05:30
let ( :awardable ) { upvote . awardable }
let ( :user ) { upvote . user }
before do
allow ( helper ) . to receive ( :can? ) do | * args |
Ability . allowed? ( * args )
end
end
2015-11-26 14:37:03 +05:30
2021-10-27 15:23:28 +05:30
it 'returns disabled string for unauthenticated user' do
expect ( helper . award_state_class ( awardable , AwardEmoji . all , nil ) ) . to eq ( 'disabled' )
2018-05-09 12:01:36 +05:30
end
2021-10-27 15:23:28 +05:30
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-26 14:37:03 +05:30
end
2022-06-21 17:19:12 +05:30
it 'returns selected class for author' do
expect ( helper . award_state_class ( awardable , AwardEmoji . all , upvote . user ) ) . to eq ( 'selected' )
2018-05-09 12:01:36 +05:30
end
2021-10-27 15:23:28 +05:30
it 'is blank for a user that has access to the awardable' do
2018-05-09 12:01:36 +05:30
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-26 14:37:03 +05:30
end
end
2016-01-14 18:37:52 +05:30
2021-10-27 15:23:28 +05:30
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-08-17 22:00:37 +05:30
expect ( awards_sort ( data ) . keys ) . to eq ( %w( thumbsup thumbsdown lifter ) )
2016-01-14 18:37:52 +05:30
end
end
2016-06-02 11:05:42 +05:30
2021-10-27 15:23:28 +05:30
describe '#link_to_discussions_to_resolve' do
describe 'passing only a merge request' do
2017-08-17 22:00:37 +05:30
let ( :merge_request ) { create ( :merge_request ) }
2021-10-27 15:23:28 +05:30
it 'links just the merge request' do
2017-09-10 17:25:29 +05:30
expected_path = project_merge_request_path ( merge_request . project , merge_request )
2017-08-17 22:00:37 +05:30
expect ( link_to_discussions_to_resolve ( merge_request , nil ) ) . to include ( expected_path )
end
2021-10-27 15:23:28 +05:30
it 'contains the reference to the merge request' do
2017-08-17 22:00:37 +05:30
expect ( link_to_discussions_to_resolve ( merge_request , nil ) ) . to include ( merge_request . to_reference )
end
end
2021-10-27 15:23:28 +05:30
describe 'when passing a discussion' do
2019-03-02 22:35:43 +05:30
let ( :diff_note ) { create ( :diff_note_on_merge_request ) }
2017-08-17 22:00:37 +05:30
let ( :merge_request ) { diff_note . noteable }
let ( :discussion ) { diff_note . to_discussion }
2021-10-27 15:23:28 +05:30
it 'links to the merge request with first note if a single discussion was passed' do
2017-08-17 22:00:37 +05:30
expected_path = Gitlab :: UrlBuilder . build ( diff_note )
expect ( link_to_discussions_to_resolve ( merge_request , discussion ) ) . to include ( expected_path )
end
2021-10-27 15:23:28 +05:30
it 'contains both the reference to the merge request and a mention of the discussion' do
2017-08-17 22:00:37 +05:30
expect ( link_to_discussions_to_resolve ( merge_request , discussion ) ) . to include ( " #{ merge_request . to_reference } (discussion #{ diff_note . id } ) " )
end
end
end
2018-05-09 12:01:36 +05:30
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-12-04 20:38:33 +05:30
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-04-08 14:13:33 +05:30
link = " <a class= \" #{ css_class } \" href= \" / #{ new_issue . project . full_path } /-/issues/ #{ new_issue . iid } \" >( #{ action } )</a> "
2019-12-04 20:38:33 +05:30
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-10-24 23:57:45 +05:30
issue . update! ( moved_to : new_issue )
2019-12-04 20:38:33 +05:30
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-10-24 23:57:45 +05:30
issue . update! ( duplicated_to : new_issue )
2019-12-04 20:38:33 +05:30
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-10-24 23:57:45 +05:30
issue . update! ( moved_to : nil , duplicated_to : nil )
2019-12-04 20:38:33 +05:30
end
it_behaves_like 'does not display link'
end
end
2020-07-28 23:09:34 +05:30
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-10-24 23:57:45 +05:30
old_issue . update! ( moved_to : new_issue )
2020-07-28 23:09:34 +05:30
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
2021-01-03 14:25:43 +05:30
2021-03-11 19:13:27 +05:30
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-10-27 15:23:28 +05:30
can_create_issue : 'true' ,
2022-01-26 12:08:38 +05:30
can_destroy_issue : 'true' ,
2021-10-27 15:23:28 +05:30
can_reopen_issue : 'true' ,
can_report_spam : 'false' ,
can_update_issue : 'true' ,
2021-03-11 19:13:27 +05:30
iid : issue . iid ,
2021-10-27 15:23:28 +05:30
is_issue_author : 'false' ,
2022-01-26 12:08:38 +05:30
issue_path : issue_path ( issue ) ,
2021-10-27 15:23:28 +05:30
issue_type : 'issue' ,
2022-05-07 20:08:51 +05:30
new_issue_path : new_project_issue_path ( project , { add_related_issue : issue . iid } ) ,
2021-03-11 19:13:27 +05:30
project_path : project . full_path ,
2023-03-17 16:20:25 +05:30
report_abuse_path : add_category_abuse_reports_path ,
reported_user_id : issue . author . id ,
reported_from_url : issue_url ( issue ) ,
2021-03-11 19:13:27 +05:30
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-29 21:17:54 +05:30
shared_examples 'issues list data' do
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 ( :import_csv_namespace_project_issues_path ) . and_return ( '#' )
2022-01-26 12:08:38 +05:30
allow ( helper ) . to receive ( :issue_repositioning_disabled? ) . and_return ( true )
2021-04-29 21:17:54 +05:30
allow ( helper ) . to receive ( :url_for ) . and_return ( '#' )
expected = {
2021-06-08 01:23:25 +05:30
autocomplete_award_emojis_path : autocomplete_award_emojis_path ,
2021-04-29 21:17:54 +05:30
calendar_path : '#' ,
can_bulk_update : 'true' ,
can_edit : 'true' ,
can_import_issues : 'true' ,
2021-11-11 11:23:49 +05:30
email : current_user & . notification_email_or_default ,
2021-06-08 01:23:25 +05:30
emails_help_page_path : help_page_path ( 'development/emails' , anchor : 'email-namespace' ) ,
2021-04-29 21:17:54 +05:30
empty_state_svg_path : '#' ,
export_csv_path : export_csv_project_issues_path ( project ) ,
2021-11-11 11:23:49 +05:30
full_path : project . full_path ,
has_any_issues : project_issues ( project ) . exists? . to_s ,
2021-04-29 21:17:54 +05:30
import_csv_issues_path : '#' ,
2021-06-08 01:23:25 +05:30
initial_email : project . new_issuable_address ( current_user , 'issue' ) ,
2022-04-04 11:22:00 +05:30
initial_sort : current_user & . user_preference & . issues_sort ,
2022-01-26 12:08:38 +05:30
is_issue_repositioning_disabled : 'true' ,
2021-11-11 11:23:49 +05:30
is_project : 'true' ,
2022-07-16 23:28:13 +05:30
is_public_visibility_restricted : Gitlab :: CurrentSettings . restricted_visibility_levels ? 'false' : '' ,
2021-04-29 21:17:54 +05:30
is_signed_in : current_user . present? . to_s ,
2021-10-27 15:23:28 +05:30
jira_integration_path : help_page_url ( 'integration/jira/issues' , anchor : 'view-jira-issues' ) ,
2021-06-08 01:23:25 +05:30
markdown_help_path : help_page_path ( 'user/markdown' ) ,
2021-04-29 21:17:54 +05:30
max_attachment_size : number_to_human_size ( Gitlab :: CurrentSettings . max_attachment_size . megabytes ) ,
2022-05-07 20:08:51 +05:30
new_issue_path : new_project_issue_path ( project ) ,
2021-04-29 21:17:54 +05:30
project_import_jira_path : project_import_jira_path ( project ) ,
2021-06-08 01:23:25 +05:30
quick_actions_help_path : help_page_path ( 'user/project/quick_actions' ) ,
2021-12-11 22:18:48 +05:30
releases_path : project_releases_path ( project , format : :json ) ,
2021-06-08 01:23:25 +05:30
reset_path : new_issuable_address_project_path ( project , issuable_type : 'issue' ) ,
2021-04-29 21:17:54 +05:30
rss_path : '#' ,
show_new_issue_link : 'true' ,
sign_in_path : new_user_session_path
}
2022-05-07 20:08:51 +05:30
expect ( helper . project_issues_list_data ( project , current_user ) ) . to include ( expected )
2021-04-29 21:17:54 +05:30
end
end
2021-11-11 11:23:49 +05:30
describe '#project_issues_list_data' do
2021-04-29 21:17:54 +05:30
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
2022-07-16 23:28:13 +05:30
context 'when restricted visibility levels is nil' do
before do
allow ( Gitlab :: CurrentSettings ) . to receive ( :restricted_visibility_levels ) . and_return ( nil )
end
it_behaves_like 'issues list data' do
let ( :current_user ) { double . as_null_object }
end
end
2021-04-29 21:17:54 +05:30
end
2021-06-08 01:23:25 +05:30
2021-11-11 11:23:49 +05:30
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-04-04 11:22:00 +05:30
assign ( :has_issues , false )
assign ( :has_projects , true )
2021-11-11 11:23:49 +05:30
expected = {
autocomplete_award_emojis_path : autocomplete_award_emojis_path ,
calendar_path : '#' ,
2022-07-23 23:45:48 +05:30
can_create_projects : 'true' ,
2021-11-11 11:23:49 +05:30
empty_state_svg_path : '#' ,
full_path : group . full_path ,
2022-04-04 11:22:00 +05:30
has_any_issues : false . to_s ,
has_any_projects : true . to_s ,
2021-11-11 11:23:49 +05:30
is_signed_in : current_user . present? . to_s ,
jira_integration_path : help_page_url ( 'integration/jira/issues' , anchor : 'view-jira-issues' ) ,
2022-07-23 23:45:48 +05:30
new_project_path : new_project_path ( namespace_id : group . id ) ,
2021-11-11 11:23:49 +05:30
rss_path : '#' ,
sign_in_path : new_user_session_path
}
2022-04-04 11:22:00 +05:30
expect ( helper . group_issues_list_data ( group , current_user ) ) . to include ( expected )
2021-11-11 11:23:49 +05:30
end
2022-06-21 17:19:12 +05:30
end
2023-03-04 22:38:38 +05:30
describe '#dashboard_issues_list_data' do
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 ( :image_path ) . and_return ( '#' )
allow ( helper ) . to receive ( :url_for ) . and_return ( '#' )
expected = {
2023-03-17 16:20:25 +05:30
autocomplete_award_emojis_path : autocomplete_award_emojis_path ,
2023-03-04 22:38:38 +05:30
calendar_path : '#' ,
2023-03-17 16:20:25 +05:30
dashboard_labels_path : dashboard_labels_path ( format : :json , include_ancestor_groups : true ) ,
dashboard_milestones_path : dashboard_milestones_path ( format : :json ) ,
empty_state_with_filter_svg_path : '#' ,
empty_state_without_filter_svg_path : '#' ,
2023-03-04 22:38:38 +05:30
initial_sort : current_user & . user_preference & . issues_sort ,
is_public_visibility_restricted : Gitlab :: CurrentSettings . restricted_visibility_levels ? 'false' : '' ,
is_signed_in : current_user . present? . to_s ,
rss_path : '#'
}
expect ( helper . dashboard_issues_list_data ( current_user ) ) . to include ( expected )
end
end
2022-06-21 17:19:12 +05:30
describe '#issues_form_data' do
it 'returns expected result' do
expected = {
new_issue_path : new_project_issue_path ( project )
}
expect ( helper . issues_form_data ( project ) ) . to include ( expected )
end
2021-11-11 11:23:49 +05:30
end
2021-06-08 01:23:25 +05:30
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-10-27 15:23:28 +05:30
expect ( helper . issue_manual_ordering_class ) . to eq ( 'manual-ordering' )
2021-06-08 01:23:25 +05:30
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-11-11 11:23:49 +05:30
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 ) }
2023-04-23 21:23:45 +05:30
it 'returns `true`' do
expect ( helper . issue_hidden? ( hidden_issue ) ) . to eq ( true )
2021-11-11 11:23:49 +05:30
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
2014-09-02 18:07:02 +05:30
end