2019-12-21 20:55:43 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
require 'spec_helper'
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
RSpec.describe TodosHelper do
|
2020-05-24 23:13:21 +05:30
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
let_it_be(:author) { create(:user) }
|
2022-08-13 15:12:31 +05:30
|
|
|
let_it_be(:project) { create(:project) }
|
|
|
|
let_it_be(:issue) { create(:issue, title: 'Issue 1', project: project) }
|
2020-05-24 23:13:21 +05:30
|
|
|
let_it_be(:design) { create(:design, issue: issue) }
|
|
|
|
let_it_be(:note) do
|
2023-06-20 00:43:36 +05:30
|
|
|
create(:note, project: issue.project, note: 'I am note, hear me roar')
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
let_it_be(:group) { create(:group, :public, name: 'Group 1') }
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
let_it_be(:design_todo) do
|
2023-06-20 00:43:36 +05:30
|
|
|
create(
|
|
|
|
:todo,
|
|
|
|
:mentioned,
|
|
|
|
user: user,
|
|
|
|
project: project,
|
|
|
|
target: design,
|
|
|
|
author: author,
|
|
|
|
note: note
|
|
|
|
)
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
let_it_be(:alert_todo) do
|
|
|
|
alert = create(:alert_management_alert, iid: 1001)
|
|
|
|
create(:todo, target: alert)
|
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2022-08-13 15:12:31 +05:30
|
|
|
let_it_be(:task_todo) do
|
|
|
|
task = create(:work_item, :task, project: project)
|
|
|
|
create(:todo, target: task, target_type: task.class.name, project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
let_it_be(:issue_todo) do
|
|
|
|
create(:todo, target: issue)
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
let_it_be(:group_todo) do
|
2023-03-17 16:20:25 +05:30
|
|
|
create(:todo, target: group, group: group, project: nil, user: user)
|
|
|
|
end
|
|
|
|
|
|
|
|
let_it_be(:project_access_request_todo) do
|
|
|
|
create(:todo, target: project, action: Todo::MEMBER_ACCESS_REQUESTED)
|
2023-03-04 22:38:38 +05:30
|
|
|
end
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
describe '#todos_count_format' do
|
|
|
|
it 'shows fuzzy count for 100 or more items' do
|
|
|
|
expect(helper.todos_count_format(100)).to eq '99+'
|
|
|
|
expect(helper.todos_count_format(1000)).to eq '99+'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'shows exact count for 99 or fewer items' do
|
|
|
|
expect(helper.todos_count_format(99)).to eq '99'
|
|
|
|
expect(helper.todos_count_format(50)).to eq '50'
|
|
|
|
expect(helper.todos_count_format(1)).to eq '1'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
describe '#todo_target_name' do
|
2020-05-24 23:13:21 +05:30
|
|
|
context 'when given a design' do
|
|
|
|
let(:todo) { design_todo }
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it 'references the filename of the design' do
|
|
|
|
name = helper.todo_target_name(todo)
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
expect(name).to eq(design.to_reference.to_s)
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe '#todo_target_title' do
|
|
|
|
context 'when the target does not exist' do
|
|
|
|
let(:todo) { double('Todo', target: nil) }
|
|
|
|
|
|
|
|
it 'returns an empty string' do
|
|
|
|
title = helper.todo_target_title(todo)
|
|
|
|
expect(title).to eq("")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given a design todo' do
|
|
|
|
let(:todo) { design_todo }
|
|
|
|
|
|
|
|
it 'returns an empty string' do
|
|
|
|
title = helper.todo_target_title(todo)
|
|
|
|
expect(title).to eq("")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given a non-design todo' do
|
|
|
|
let(:todo) do
|
2023-06-20 00:43:36 +05:30
|
|
|
build_stubbed(
|
|
|
|
:todo,
|
|
|
|
:assigned,
|
|
|
|
user: user,
|
|
|
|
project: issue.project,
|
|
|
|
target: issue,
|
|
|
|
author: author
|
|
|
|
)
|
2020-06-23 00:09:42 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the title' do
|
|
|
|
title = helper.todo_target_title(todo)
|
2023-03-04 22:38:38 +05:30
|
|
|
expect(title).to eq("Issue 1")
|
2020-06-23 00:09:42 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
describe '#todo_target_path' do
|
|
|
|
context 'when given a design' do
|
|
|
|
let(:todo) { design_todo }
|
|
|
|
|
|
|
|
it 'responds with an appropriate path' do
|
|
|
|
path = helper.todo_target_path(todo)
|
|
|
|
issue_path = Gitlab::Routing.url_helpers
|
|
|
|
.project_issue_path(issue.project, issue)
|
|
|
|
|
|
|
|
expect(path).to eq("#{issue_path}/designs/#{design.filename}##{dom_id(design_todo.note)}")
|
|
|
|
end
|
|
|
|
end
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
context 'when given an alert' do
|
|
|
|
let(:todo) { alert_todo }
|
|
|
|
|
|
|
|
it 'responds with an appropriate path' do
|
|
|
|
path = helper.todo_target_path(todo)
|
|
|
|
|
|
|
|
expect(path).to eq(
|
|
|
|
"/#{todo.project.full_path}/-/alert_management/#{todo.target.iid}/details"
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
|
|
|
context 'when given a task' do
|
|
|
|
let(:todo) { task_todo }
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
it 'responds with an appropriate path using iid' do
|
2022-08-13 15:12:31 +05:30
|
|
|
path = helper.todo_target_path(todo)
|
|
|
|
|
2023-07-09 08:55:56 +05:30
|
|
|
expect(path).to eq("/#{todo.project.full_path}/-/work_items/#{todo.target.iid}")
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given an issue with a note anchor' do
|
|
|
|
let(:todo) { create(:todo, project: issue.project, target: issue, note: note) }
|
|
|
|
|
|
|
|
it 'responds with an appropriate path' do
|
|
|
|
path = helper.todo_target_path(todo)
|
|
|
|
|
|
|
|
expect(path).to eq("/#{issue.project.full_path}/-/issues/#{issue.iid}##{dom_id(note)}")
|
|
|
|
end
|
|
|
|
end
|
2023-03-04 22:38:38 +05:30
|
|
|
|
|
|
|
context 'when a user requests access to group' do
|
|
|
|
let_it_be(:group_access_request_todo) do
|
2023-06-20 00:43:36 +05:30
|
|
|
create(
|
|
|
|
:todo,
|
|
|
|
target_id: group.id,
|
|
|
|
target_type: group.class.polymorphic_name,
|
|
|
|
group: group,
|
|
|
|
action: Todo::MEMBER_ACCESS_REQUESTED
|
|
|
|
)
|
2023-03-04 22:38:38 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'responds with access requests tab' do
|
|
|
|
path = helper.todo_target_path(group_access_request_todo)
|
|
|
|
|
2023-03-17 16:20:25 +05:30
|
|
|
access_request_path = Gitlab::Routing.url_helpers.group_group_members_path(group, tab: 'access_requests')
|
|
|
|
|
|
|
|
expect(path).to eq(access_request_path)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user requests access to project' do
|
|
|
|
it 'responds with access requests tab' do
|
|
|
|
path = helper.todo_target_path(project_access_request_todo)
|
|
|
|
|
|
|
|
access_request_path = Gitlab::Routing.url_helpers.project_project_members_path(project, tab: 'access_requests')
|
2023-03-04 22:38:38 +05:30
|
|
|
|
|
|
|
expect(path).to eq(access_request_path)
|
|
|
|
end
|
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
describe '#todo_target_aria_label' do
|
|
|
|
subject { helper.todo_target_aria_label(todo) }
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
context 'when given a design todo' do
|
|
|
|
let(:todo) { design_todo }
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it { is_expected.to eq("Design ##{todo.target.iid}[#{todo.target.title}]") }
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
context 'when given an alert todo' do
|
|
|
|
let(:todo) { alert_todo }
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it { is_expected.to eq("Alert ^alert##{todo.target.iid}") }
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given a task todo' do
|
|
|
|
let(:todo) { task_todo }
|
2020-06-23 00:09:42 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it { is_expected.to eq("Task ##{todo.target.iid}") }
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given an issue todo' do
|
|
|
|
let(:todo) { issue_todo }
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it { is_expected.to eq("Issue ##{todo.target.iid}") }
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when given a merge request todo' do
|
|
|
|
let(:todo) do
|
|
|
|
merge_request = create(:merge_request, source_project: project)
|
|
|
|
create(:todo, target: merge_request)
|
2020-06-23 00:09:42 +05:30
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it { is_expected.to eq("Merge Request !#{todo.target.iid}") }
|
2020-06-23 00:09:42 +05:30
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe '#todo_types_options' do
|
|
|
|
it 'includes a match for a design todo' do
|
|
|
|
options = helper.todo_types_options
|
|
|
|
design_option = options.find { |o| o[:id] == design_todo.target_type }
|
|
|
|
|
|
|
|
expect(design_option).to include(text: 'Design')
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
describe '#todo_target_state_pill' do
|
|
|
|
subject { helper.todo_target_state_pill(todo) }
|
|
|
|
|
|
|
|
shared_examples 'a rendered state pill' do |attr|
|
|
|
|
it 'returns expected html' do
|
|
|
|
aggregate_failures do
|
2022-07-23 23:45:48 +05:30
|
|
|
expect(subject).to have_css(attr[:css])
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(subject).to have_content(attr[:state].capitalize)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'no state pill' do
|
|
|
|
specify { expect(subject).to eq(nil) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'merge request todo' do
|
|
|
|
let(:todo) { create(:todo, target: create(:merge_request)) }
|
|
|
|
|
|
|
|
it_behaves_like 'no state pill'
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
context 'closed MR' do
|
|
|
|
before do
|
|
|
|
todo.target.update!(state: 'closed')
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it_behaves_like 'a rendered state pill', css: '.badge-danger', state: 'closed'
|
2022-07-23 23:45:48 +05:30
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
context 'merged MR' do
|
|
|
|
before do
|
|
|
|
todo.target.update!(state: 'merged')
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'merged'
|
2020-07-28 23:09:34 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'issue todo' do
|
|
|
|
let(:todo) { create(:todo, target: issue) }
|
|
|
|
|
|
|
|
it_behaves_like 'no state pill'
|
|
|
|
|
|
|
|
context 'closed issue' do
|
|
|
|
before do
|
|
|
|
todo.target.update!(state: 'closed')
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'closed'
|
2020-07-28 23:09:34 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'alert todo' do
|
|
|
|
let(:todo) { alert_todo }
|
|
|
|
|
|
|
|
it_behaves_like 'no state pill'
|
|
|
|
|
|
|
|
context 'resolved alert' do
|
|
|
|
before do
|
|
|
|
todo.target.resolve!
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'resolved'
|
2020-07-28 23:09:34 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-10-11 01:57:18 +05:30
|
|
|
describe '#no_todos_messages' do
|
2023-06-20 00:43:36 +05:30
|
|
|
context 'when getting todos messages' do
|
2022-10-11 01:57:18 +05:30
|
|
|
it 'return these sentences' do
|
|
|
|
expected_sentences = [
|
|
|
|
s_('Todos|Good job! Looks like you don\'t have anything left on your To-Do List'),
|
|
|
|
s_('Todos|Isn\'t an empty To-Do List beautiful?'),
|
|
|
|
s_('Todos|Give yourself a pat on the back!'),
|
|
|
|
s_('Todos|Nothing left to do. High five!'),
|
|
|
|
s_('Todos|Henceforth, you shall be known as "To-Do Destroyer"')
|
|
|
|
]
|
|
|
|
expect(helper.no_todos_messages).to eq(expected_sentences)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
describe '#todo_author_display?' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
subject { helper.todo_author_display?(alert_todo) }
|
|
|
|
|
|
|
|
where(:action, :result) do
|
|
|
|
Todo::BUILD_FAILED | false
|
|
|
|
Todo::UNMERGEABLE | false
|
|
|
|
Todo::ASSIGNED | true
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
alert_todo.action = action
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.to eq(result) }
|
|
|
|
end
|
|
|
|
end
|
2022-11-25 23:54:43 +05:30
|
|
|
|
|
|
|
describe '#todos_filter_params' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
where(:state, :result) do
|
|
|
|
'done' | 'done'
|
|
|
|
'pending' | 'pending'
|
|
|
|
'' | nil
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
allow(helper).to receive(:params).and_return({ state: state })
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(helper.todos_filter_params[:state]).to eq(result) }
|
|
|
|
end
|
|
|
|
end
|
2023-01-13 00:05:48 +05:30
|
|
|
|
|
|
|
describe '#todo_action_name' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
where(:action, :self_added?, :expected_action_name) do
|
|
|
|
Todo::ASSIGNED | false | s_('Todos|assigned you')
|
|
|
|
Todo::ASSIGNED | true | s_('Todos|assigned')
|
2023-03-04 22:38:38 +05:30
|
|
|
Todo::REVIEW_REQUESTED | true | s_('Todos|requested a review')
|
|
|
|
Todo::MENTIONED | true | format(s_("Todos|mentioned %{who}"), who: s_('Todos|yourself'))
|
|
|
|
Todo::MENTIONED | false | format(s_("Todos|mentioned %{who}"), who: _('you'))
|
|
|
|
Todo::DIRECTLY_ADDRESSED | true | format(s_("Todos|mentioned %{who}"), who: s_('Todos|yourself'))
|
|
|
|
Todo::DIRECTLY_ADDRESSED | false | format(s_("Todos|mentioned %{who}"), who: _('you'))
|
|
|
|
Todo::BUILD_FAILED | true | s_('Todos|The pipeline failed')
|
|
|
|
Todo::MARKED | true | s_('Todos|added a to-do item')
|
|
|
|
Todo::APPROVAL_REQUIRED | true | format(s_("Todos|set %{who} as an approver"), who: s_('Todos|yourself'))
|
|
|
|
Todo::APPROVAL_REQUIRED | false | format(s_("Todos|set %{who} as an approver"), who: _('you'))
|
2023-01-13 00:05:48 +05:30
|
|
|
Todo::UNMERGEABLE | true | s_('Todos|Could not merge')
|
2023-03-04 22:38:38 +05:30
|
|
|
Todo::MERGE_TRAIN_REMOVED | true | s_("Todos|Removed from Merge Train")
|
2023-01-13 00:05:48 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
alert_todo.action = action
|
|
|
|
alert_todo.user = self_added? ? alert_todo.author : user
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(helper.todo_action_name(alert_todo)).to eq(expected_action_name) }
|
|
|
|
end
|
2023-03-04 22:38:38 +05:30
|
|
|
|
|
|
|
context 'member access requested' do
|
2023-03-17 16:20:25 +05:30
|
|
|
context 'when target is group' do
|
2023-03-04 22:38:38 +05:30
|
|
|
it 'returns group access message' do
|
|
|
|
group_todo.action = Todo::MEMBER_ACCESS_REQUESTED
|
|
|
|
|
|
|
|
expect(helper.todo_action_name(group_todo)).to eq(
|
|
|
|
format(s_("Todos|has requested access to group %{which}"), which: _(group.name))
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2023-03-17 16:20:25 +05:30
|
|
|
|
|
|
|
context 'when target is project' do
|
|
|
|
it 'returns project access message' do
|
|
|
|
expect(helper.todo_action_name(project_access_request_todo)).to eq(
|
|
|
|
format(s_("Todos|has requested access to project %{which}"), which: _(project.name))
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2023-03-04 22:38:38 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#todo_due_date' do
|
|
|
|
subject(:result) { helper.todo_due_date(todo) }
|
|
|
|
|
|
|
|
context 'due date is today' do
|
|
|
|
let_it_be(:issue_with_today_due_date) do
|
|
|
|
create(:issue, title: 'Issue 1', project: project, due_date: Date.current)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:todo) do
|
|
|
|
create(:todo, project: issue_with_today_due_date.project, target: issue_with_today_due_date, note: note)
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(result).to match('Due today') }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'due date is not today' do
|
|
|
|
let_it_be(:issue_with_tomorrow_due_date) do
|
|
|
|
create(:issue, title: 'Issue 1', project: project, due_date: Date.tomorrow)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:todo) do
|
|
|
|
create(:todo, project: issue_with_tomorrow_due_date.project, target: issue_with_tomorrow_due_date, note: note)
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(result).to match("Due #{l(Date.tomorrow, format: Date::DATE_FORMATS[:medium])}") }
|
|
|
|
end
|
2023-01-13 00:05:48 +05:30
|
|
|
end
|
2023-03-17 16:20:25 +05:30
|
|
|
|
|
|
|
describe '#todo_parent_path' do
|
|
|
|
context 'when todo resource parent is a group' do
|
|
|
|
subject(:result) { helper.todo_parent_path(group_todo) }
|
|
|
|
|
|
|
|
it { expect(result).to eq(group_todo.group.name) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when todo resource parent is not a group' do
|
|
|
|
it 'returns project title with namespace' do
|
|
|
|
result = helper.todo_parent_path(project_access_request_todo)
|
|
|
|
|
|
|
|
expect(result).to include(project_access_request_todo.project.name)
|
|
|
|
expect(result).to include(project_access_request_todo.project.namespace.human_name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|