2019-03-28 06:17:58 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-08-18 08:59:09 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-06-24 05:08:32 -04:00
|
|
|
RSpec.describe IssuablesHelper do
|
2016-08-18 08:59:09 -04:00
|
|
|
let(:label) { build_stubbed(:label) }
|
|
|
|
let(:label2) { build_stubbed(:label) }
|
|
|
|
|
2017-05-04 08:11:15 -04:00
|
|
|
describe '#users_dropdown_label' do
|
2019-01-16 07:09:29 -05:00
|
|
|
let(:user) { build_stubbed(:user) }
|
|
|
|
let(:user2) { build_stubbed(:user) }
|
2017-05-04 08:11:15 -04:00
|
|
|
|
|
|
|
it 'returns unassigned' do
|
|
|
|
expect(users_dropdown_label([])).to eq('Unassigned')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns selected user\'s name' do
|
|
|
|
expect(users_dropdown_label([user])).to eq(user.name)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns selected user\'s name and counter' do
|
|
|
|
expect(users_dropdown_label([user, user2])).to eq("#{user.name} + 1 more")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-07-16 09:35:19 -04:00
|
|
|
describe '#group_dropdown_label' do
|
2019-01-16 07:09:29 -05:00
|
|
|
let(:group) { create(:group) }
|
2018-07-16 09:35:19 -04:00
|
|
|
let(:default) { 'default label' }
|
|
|
|
|
|
|
|
it 'returns default group label when group_id is nil' do
|
|
|
|
expect(group_dropdown_label(nil, default)).to eq('default label')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "any group" when group_id is 0' do
|
|
|
|
expect(group_dropdown_label('0', default)).to eq('Any group')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns group full path when a group was found for the provided id' do
|
|
|
|
expect(group_dropdown_label(group.id, default)).to eq(group.full_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns default label when a group was not found for the provided id' do
|
2020-04-01 11:07:45 -04:00
|
|
|
expect(group_dropdown_label(non_existing_record_id, default)).to eq('default label')
|
2018-07-16 09:35:19 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-26 13:12:16 -04:00
|
|
|
describe '#issuable_labels_tooltip' do
|
2018-11-29 23:03:35 -05:00
|
|
|
let(:label_entity) { LabelEntity.represent(label).as_json }
|
|
|
|
let(:label2_entity) { LabelEntity.represent(label2).as_json }
|
2018-11-27 11:53:16 -05:00
|
|
|
|
2018-04-19 10:43:20 -04:00
|
|
|
it 'returns label text with no labels' do
|
2019-12-12 07:07:33 -05:00
|
|
|
expect(issuable_labels_tooltip([])).to eq(_('Labels'))
|
2018-04-19 10:43:20 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns label text with labels within max limit' do
|
2018-11-27 11:53:16 -05:00
|
|
|
expect(issuable_labels_tooltip([label_entity])).to eq(label[:title])
|
2016-08-18 08:59:09 -04:00
|
|
|
end
|
|
|
|
|
2018-04-19 10:43:20 -04:00
|
|
|
it 'returns label text with labels exceeding max limit' do
|
2018-11-27 11:53:16 -05:00
|
|
|
expect(issuable_labels_tooltip([label_entity, label2_entity], limit: 1)).to eq("#{label[:title]}, and 1 more")
|
2016-08-18 08:59:09 -04:00
|
|
|
end
|
|
|
|
end
|
2016-09-26 13:12:16 -04:00
|
|
|
|
|
|
|
describe '#issuables_state_counter_text' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
|
|
describe 'state text' do
|
|
|
|
before do
|
|
|
|
allow(helper).to receive(:issuables_count_for_state).and_return(42)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "Open" when state is :opened' do
|
2018-03-27 11:29:13 -04:00
|
|
|
expect(helper.issuables_state_counter_text(:issues, :opened, true))
|
2018-04-16 16:18:18 -04:00
|
|
|
.to eq('<span>Open</span> <span class="badge badge-pill">42</span>')
|
2016-09-26 13:12:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "Closed" when state is :closed' do
|
2018-03-27 11:29:13 -04:00
|
|
|
expect(helper.issuables_state_counter_text(:issues, :closed, true))
|
2018-04-16 16:18:18 -04:00
|
|
|
.to eq('<span>Closed</span> <span class="badge badge-pill">42</span>')
|
2016-09-26 13:12:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "Merged" when state is :merged' do
|
2018-03-27 11:29:13 -04:00
|
|
|
expect(helper.issuables_state_counter_text(:merge_requests, :merged, true))
|
2018-04-16 16:18:18 -04:00
|
|
|
.to eq('<span>Merged</span> <span class="badge badge-pill">42</span>')
|
2016-09-26 13:12:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "All" when state is :all' do
|
2018-03-27 11:29:13 -04:00
|
|
|
expect(helper.issuables_state_counter_text(:merge_requests, :all, true))
|
2018-04-16 16:18:18 -04:00
|
|
|
.to eq('<span>All</span> <span class="badge badge-pill">42</span>')
|
2016-09-26 13:12:16 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-11-27 12:35:44 -05:00
|
|
|
|
2017-01-12 07:28:37 -05:00
|
|
|
describe '#issuable_reference' do
|
|
|
|
context 'when show_full_reference truthy' do
|
|
|
|
it 'display issuable full reference' do
|
|
|
|
assign(:show_full_reference, true)
|
|
|
|
issue = build_stubbed(:issue)
|
|
|
|
|
|
|
|
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(full: true))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when show_full_reference falsey' do
|
|
|
|
context 'when @group present' do
|
|
|
|
it 'display issuable reference to @group' do
|
2017-08-02 15:55:11 -04:00
|
|
|
project = build_stubbed(:project)
|
2017-01-12 07:28:37 -05:00
|
|
|
|
|
|
|
assign(:show_full_reference, nil)
|
|
|
|
assign(:group, project.namespace)
|
|
|
|
|
|
|
|
issue = build_stubbed(:issue)
|
|
|
|
|
|
|
|
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project.namespace))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when @project present' do
|
|
|
|
it 'display issuable reference to @project' do
|
2017-08-02 15:55:11 -04:00
|
|
|
project = build_stubbed(:project)
|
2017-01-12 07:28:37 -05:00
|
|
|
|
|
|
|
assign(:show_full_reference, nil)
|
|
|
|
assign(:group, nil)
|
|
|
|
assign(:project, project)
|
|
|
|
|
|
|
|
issue = build_stubbed(:issue)
|
|
|
|
|
|
|
|
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-05-31 06:10:33 -04:00
|
|
|
describe '#updated_at_by' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:unedited_issuable) { create(:issue) }
|
2018-01-11 11:22:00 -05:00
|
|
|
let(:edited_issuable) { create(:issue, last_edited_by: user, created_at: 3.days.ago, updated_at: 1.day.ago, last_edited_at: 2.days.ago) }
|
2017-05-31 06:10:33 -04:00
|
|
|
let(:edited_updated_at_by) do
|
|
|
|
{
|
2018-01-11 11:22:00 -05:00
|
|
|
updatedAt: edited_issuable.last_edited_at.to_time.iso8601,
|
2017-06-02 12:17:54 -04:00
|
|
|
updatedBy: {
|
2017-05-31 06:10:33 -04:00
|
|
|
name: user.name,
|
|
|
|
path: user_path(user)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(helper.updated_at_by(unedited_issuable)).to eq({}) }
|
|
|
|
it { expect(helper.updated_at_by(edited_issuable)).to eq(edited_updated_at_by) }
|
2017-07-17 10:38:43 -04:00
|
|
|
|
|
|
|
context 'when updated by a deleted user' do
|
|
|
|
let(:edited_updated_at_by) do
|
|
|
|
{
|
2018-01-11 11:22:00 -05:00
|
|
|
updatedAt: edited_issuable.last_edited_at.to_time.iso8601,
|
2017-07-17 10:38:43 -04:00
|
|
|
updatedBy: {
|
|
|
|
name: User.ghost.name,
|
|
|
|
path: user_path(User.ghost)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
user.destroy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns "Ghost user" as edited_by' do
|
|
|
|
expect(helper.updated_at_by(edited_issuable.reload)).to eq(edited_updated_at_by)
|
|
|
|
end
|
|
|
|
end
|
2017-05-31 06:10:33 -04:00
|
|
|
end
|
2017-11-01 13:35:14 -04:00
|
|
|
|
|
|
|
describe '#issuable_initial_data' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(helper).to receive(:current_user).and_return(user)
|
|
|
|
allow(helper).to receive(:can?).and_return(true)
|
2019-01-11 19:31:00 -05:00
|
|
|
stub_commonmark_sourcepos_disabled
|
2017-11-01 13:35:14 -04:00
|
|
|
end
|
|
|
|
|
2019-03-28 06:17:58 -04:00
|
|
|
it 'returns the correct data for an issue' do
|
2017-11-01 13:35:14 -04:00
|
|
|
issue = create(:issue, author: user, description: 'issue text')
|
|
|
|
@project = issue.project
|
|
|
|
|
|
|
|
expected_data = {
|
2020-03-02 10:08:01 -05:00
|
|
|
endpoint: "/#{@project.full_path}/-/issues/#{issue.iid}",
|
|
|
|
updateEndpoint: "/#{@project.full_path}/-/issues/#{issue.iid}.json",
|
2018-02-23 09:45:32 -05:00
|
|
|
canUpdate: true,
|
|
|
|
canDestroy: true,
|
|
|
|
issuableRef: "##{issue.iid}",
|
|
|
|
markdownPreviewPath: "/#{@project.full_path}/preview_markdown",
|
|
|
|
markdownDocsPath: '/help/user/markdown',
|
2018-12-20 19:19:41 -05:00
|
|
|
lockVersion: issue.lock_version,
|
2018-02-23 09:45:32 -05:00
|
|
|
projectPath: @project.path,
|
|
|
|
projectNamespace: @project.namespace.path,
|
|
|
|
initialTitleHtml: issue.title,
|
|
|
|
initialTitleText: issue.title,
|
|
|
|
initialDescriptionHtml: '<p dir="auto">issue text</p>',
|
|
|
|
initialDescriptionText: 'issue text',
|
|
|
|
initialTaskStatus: '0 of 0 tasks completed'
|
2017-11-01 13:35:14 -04:00
|
|
|
}
|
2019-03-28 06:17:58 -04:00
|
|
|
expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data))
|
2017-11-01 13:35:14 -04:00
|
|
|
end
|
2019-07-17 02:41:26 -04:00
|
|
|
|
2019-12-10 16:08:01 -05:00
|
|
|
describe '#sentryIssueIdentifier' do
|
|
|
|
let(:issue) { create(:issue, author: user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
assign(:project, issue.project)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets sentryIssueIdentifier to nil with no sentry issue ' do
|
|
|
|
expect(helper.issuable_initial_data(issue)[:sentryIssueIdentifier])
|
|
|
|
.to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets sentryIssueIdentifier to sentry_issue_identifier' do
|
|
|
|
sentry_issue = create(:sentry_issue, issue: issue)
|
|
|
|
|
|
|
|
expect(helper.issuable_initial_data(issue)[:sentryIssueIdentifier])
|
|
|
|
.to eq(sentry_issue.sentry_issue_identifier)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-07-17 02:41:26 -04:00
|
|
|
describe '#zoomMeetingUrl in issue' do
|
2019-10-28 14:06:15 -04:00
|
|
|
let(:issue) { create(:issue, author: user) }
|
2019-07-17 02:41:26 -04:00
|
|
|
|
|
|
|
before do
|
|
|
|
assign(:project, issue.project)
|
|
|
|
end
|
|
|
|
|
2019-10-28 14:06:15 -04:00
|
|
|
shared_examples 'sets zoomMeetingUrl to nil' do
|
|
|
|
specify do
|
|
|
|
expect(helper.issuable_initial_data(issue)[:zoomMeetingUrl])
|
|
|
|
.to be_nil
|
2019-07-17 02:41:26 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-10-28 14:06:15 -04:00
|
|
|
context 'with no "added" zoom mettings' do
|
|
|
|
it_behaves_like 'sets zoomMeetingUrl to nil'
|
|
|
|
|
|
|
|
context 'with multiple removed meetings' do
|
|
|
|
before do
|
|
|
|
create(:zoom_meeting, issue: issue, issue_status: :removed)
|
|
|
|
create(:zoom_meeting, issue: issue, issue_status: :removed)
|
|
|
|
end
|
2019-07-17 02:41:26 -04:00
|
|
|
|
2019-10-28 14:06:15 -04:00
|
|
|
it_behaves_like 'sets zoomMeetingUrl to nil'
|
2019-07-17 02:41:26 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-10-28 14:06:15 -04:00
|
|
|
context 'with "added" zoom meeting' do
|
|
|
|
before do
|
|
|
|
create(:zoom_meeting, issue: issue)
|
2019-07-17 02:41:26 -04:00
|
|
|
end
|
|
|
|
|
2019-10-28 14:06:15 -04:00
|
|
|
shared_examples 'sets zoomMeetingUrl to canonical meeting url' do
|
|
|
|
specify do
|
|
|
|
expect(helper.issuable_initial_data(issue))
|
|
|
|
.to include(zoomMeetingUrl: 'https://zoom.us/j/123456789')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'sets zoomMeetingUrl to canonical meeting url'
|
|
|
|
|
|
|
|
context 'with muliple "removed" zoom meetings' do
|
|
|
|
before do
|
|
|
|
create(:zoom_meeting, issue: issue, issue_status: :removed)
|
|
|
|
create(:zoom_meeting, issue: issue, issue_status: :removed)
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'sets zoomMeetingUrl to canonical meeting url'
|
2019-07-17 02:41:26 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-11-01 13:35:14 -04:00
|
|
|
end
|
2019-09-24 14:06:05 -04:00
|
|
|
|
|
|
|
describe '#assignee_sidebar_data' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:merge_request) { nil }
|
2019-12-17 13:07:48 -05:00
|
|
|
|
2019-09-24 14:06:05 -04:00
|
|
|
subject { helper.assignee_sidebar_data(user, merge_request: merge_request) }
|
|
|
|
|
|
|
|
it 'returns hash of assignee data' do
|
|
|
|
is_expected.to eql({
|
|
|
|
avatar_url: user.avatar_url,
|
|
|
|
name: user.name,
|
|
|
|
username: user.username
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with merge_request' do
|
|
|
|
let(:merge_request) { build_stubbed(:merge_request) }
|
|
|
|
|
|
|
|
where(can_merge: [true, false])
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
allow(merge_request).to receive(:can_be_merged_by?).and_return(can_merge)
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.to include({ can_merge: can_merge })}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-07-06 02:09:59 -04:00
|
|
|
|
|
|
|
describe '#issuable_squash_option?' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
where(:issuable_persisted, :squash, :squash_enabled_by_default, :expectation) do
|
|
|
|
true | true | true | true
|
|
|
|
true | false | true | false
|
|
|
|
false | false | false | false
|
|
|
|
false | false | true | true
|
|
|
|
false | true | false | false
|
|
|
|
false | true | true | true
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
it 'returns the correct value' do
|
|
|
|
project = double(
|
|
|
|
squash_enabled_by_default?: squash_enabled_by_default
|
|
|
|
)
|
|
|
|
issuable = double(persisted?: issuable_persisted, squash: squash)
|
|
|
|
|
|
|
|
expect(helper.issuable_squash_option?(issuable, project)).to eq(expectation)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-08-18 08:59:09 -04:00
|
|
|
end
|