kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
8.3 KiB
229 lines
8.3 KiB
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) 2012-2021 the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# See docs/COPYRIGHT.rdoc for more details.
|
|
#++
|
|
|
|
require 'spec_helper'
|
|
|
|
describe ApplicationHelper, type: :helper do
|
|
include ApplicationHelper
|
|
include WorkPackagesHelper
|
|
|
|
describe 'format_activity_description' do
|
|
it 'truncates given text' do
|
|
text = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore'
|
|
expect(format_activity_description(text).size).to eq(120)
|
|
end
|
|
|
|
it 'replaces escaped line breaks with html line breaks and should be html_safe' do
|
|
text = "Lorem ipsum dolor sit \namet, consetetur sadipscing elitr, sed diam nonumy eirmod\r tempor invidunt"
|
|
text_html = 'Lorem ipsum dolor sit <br />amet, consetetur sadipscing elitr, sed diam nonumy eirmod<br /> tempor invidunt'
|
|
expect(format_activity_description(text)).to be_html_eql(text_html)
|
|
expect(format_activity_description(text).html_safe?).to be_truthy
|
|
end
|
|
|
|
it 'escapes potentially harmful code' do
|
|
text = "Lorem ipsum dolor <script>alert('pwnd');</script> tempor invidunt"
|
|
expect(format_activity_description(text).include?('<script>alert('pwnd');</script>')).to be_truthy
|
|
end
|
|
end
|
|
|
|
describe 'footer_content' do
|
|
context 'no additional footer content' do
|
|
before do
|
|
OpenProject::Footer.content = nil
|
|
end
|
|
|
|
it { expect(footer_content).to eq(I18n.t(:text_powered_by, link: link_to(OpenProject::Info.app_name, OpenProject::Info.url))) }
|
|
end
|
|
|
|
context 'string as additional footer content' do
|
|
before do
|
|
OpenProject::Footer.content = nil
|
|
OpenProject::Footer.add_content('openproject', 'footer')
|
|
end
|
|
|
|
it { expect(footer_content.include?(I18n.t(:text_powered_by, link: link_to(OpenProject::Info.app_name, OpenProject::Info.url)))).to be_truthy }
|
|
it { expect(footer_content.include?("<span class=\"footer_openproject\">footer</span>")).to be_truthy }
|
|
end
|
|
|
|
context 'proc as additional footer content' do
|
|
before do
|
|
OpenProject::Footer.content = nil
|
|
OpenProject::Footer.add_content('openproject', Proc.new { Date.parse(Time.now.to_s) })
|
|
end
|
|
|
|
it { expect(footer_content.include?("<span class=\"footer_openproject\">#{Date.parse(Time.now.to_s)}</span>")).to be_truthy }
|
|
end
|
|
|
|
context 'proc which returns nothing' do
|
|
before do
|
|
OpenProject::Footer.content = nil
|
|
OpenProject::Footer.add_content('openproject', Proc.new { 'footer' if false })
|
|
end
|
|
|
|
it { expect(footer_content.include?("<span class=\"footer_openproject\">")).to be_falsey }
|
|
end
|
|
end
|
|
|
|
describe '.link_to_if_authorized' do
|
|
let(:project) { FactoryBot.create :valid_project }
|
|
let(:project_member) {
|
|
FactoryBot.create :user,
|
|
member_in_project: project,
|
|
member_through_role: FactoryBot.create(:role,
|
|
permissions: [:view_work_packages, :edit_work_packages,
|
|
:browse_repository, :view_changesets, :view_wiki_pages])
|
|
}
|
|
let(:issue) {
|
|
FactoryBot.create :work_package,
|
|
project: project,
|
|
author: project_member,
|
|
type: project.types.first
|
|
}
|
|
|
|
context 'if user is authorized' do
|
|
before do
|
|
expect(self).to receive(:authorize_for).and_return(true)
|
|
@response = link_to_if_authorized('link_content', {
|
|
controller: 'work_packages',
|
|
action: 'show',
|
|
id: issue },
|
|
class: 'fancy_css_class')
|
|
end
|
|
|
|
subject { @response }
|
|
|
|
it { is_expected.to match /href/ }
|
|
|
|
it { is_expected.to match /fancy_css_class/ }
|
|
end
|
|
|
|
context 'if user is unauthorized' do
|
|
before do
|
|
expect(self).to receive(:authorize_for).and_return(false)
|
|
@response = link_to_if_authorized('link_content', {
|
|
controller: 'work_packages',
|
|
action: 'show',
|
|
id: issue },
|
|
class: 'fancy_css_class')
|
|
end
|
|
|
|
subject { @response }
|
|
|
|
it { is_expected.to be_nil }
|
|
end
|
|
|
|
context 'allow using the :controller and :action for the target link' do
|
|
before do
|
|
expect(self).to receive(:authorize_for).and_return(true)
|
|
@response = link_to_if_authorized('By controller/action',
|
|
controller: 'work_packages',
|
|
action: 'show',
|
|
id: issue.id)
|
|
end
|
|
|
|
subject { @response }
|
|
|
|
it { is_expected.to match /href/ }
|
|
end
|
|
end
|
|
|
|
describe 'other_formats_links' do
|
|
context 'link given' do
|
|
before do
|
|
@links = other_formats_links { |f| f.link_to 'Atom', url: { controller: :projects, action: :index } }
|
|
end
|
|
it { expect(@links).to be_html_eql("<p class=\"other-formats\">Also available in:<span><a class=\"icon icon-atom\" href=\"/projects.atom\" rel=\"nofollow\">Atom</a></span></p>") }
|
|
end
|
|
|
|
context 'link given but disabled' do
|
|
before do
|
|
allow(Setting).to receive(:feeds_enabled?).and_return(false)
|
|
@links = other_formats_links { |f| f.link_to 'Atom', url: { controller: :projects, action: :index } }
|
|
end
|
|
it { expect(@links).to be_nil }
|
|
end
|
|
end
|
|
|
|
describe 'time_tag' do
|
|
around do |example|
|
|
I18n.with_locale(:en) { example.run }
|
|
end
|
|
|
|
subject { time_tag(time) }
|
|
|
|
context 'with project' do
|
|
before do
|
|
@project = FactoryBot.build(:project)
|
|
end
|
|
|
|
context 'right now' do
|
|
let(:time) { Time.now }
|
|
|
|
it { is_expected.to match /^\<a/ }
|
|
it { is_expected.to match /less than a minute/ }
|
|
it { is_expected.to be_html_safe }
|
|
end
|
|
|
|
context 'some time ago' do
|
|
let(:time) {
|
|
Timecop.travel(2.weeks.ago) do
|
|
Time.now
|
|
end
|
|
}
|
|
|
|
it { is_expected.to match /^\<a/ }
|
|
it { is_expected.to match /14 days/ }
|
|
it { is_expected.to be_html_safe }
|
|
end
|
|
end
|
|
|
|
context 'without project' do
|
|
context 'right now' do
|
|
let(:time) { Time.now }
|
|
|
|
it { is_expected.to match /^\<time/ }
|
|
it { is_expected.to match /datetime=\"#{Regexp.escape(time.xmlschema)}\"/ }
|
|
it { is_expected.to match /less than a minute/ }
|
|
it { is_expected.to be_html_safe }
|
|
end
|
|
|
|
context 'some time ago' do
|
|
let(:time) {
|
|
Timecop.travel(1.week.ago) do
|
|
Time.now
|
|
end
|
|
}
|
|
|
|
it { is_expected.to match /^\<time/ }
|
|
it { is_expected.to match /datetime=\"#{Regexp.escape(time.xmlschema)}\"/ }
|
|
it { is_expected.to match /7 days/ }
|
|
it { is_expected.to be_html_safe }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|