#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
#
# Copyright (C) 2012-2013 the OpenProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# See doc/COPYRIGHT.rdoc for more details.
#++
require File.expand_path('../../../test_helper', __FILE__)
class ApplicationHelperTest < ActionView::TestCase
def setup
super
# @project variable is used by helper
@project = FactoryGirl.create :valid_project
@project.reload # reload references to indirectly created entities (e.g. wiki)
@admin = FactoryGirl.create :admin
@anonymous = FactoryGirl.create :anonymous
@non_member = FactoryGirl.create :user
@project_member = FactoryGirl.create :user,
:member_in_project => @project,
:member_through_role => FactoryGirl.create(:role,
:permissions => [:view_issues, :edit_issues, :view_documents,
:browse_repository, :view_changesets, :view_wiki_pages])
@issue = FactoryGirl.create :issue, :project => @project, :author => @project_member, :tracker => @project.trackers.first
@attachment = FactoryGirl.create :attachment,
:author => @project_member,
:content_type => 'image/gif',
:filename => 'logo.gif',
:disk_filename => '060719210727_logo.gif',
:digest => 'b91e08d0cf966d5c6ff411bd8c4cc3a2',
:container => @issue,
:filesize => 280,
:description => 'This is a logo'
User.current = @project_member
end
def request
@request ||= ActionController::TestRequest.new
end
context "#link_to_if_authorized" do
should "create a link for an authorized user" do
User.current = @project_member
response = link_to_if_authorized('link_content', {
:controller => 'issues',
:action => 'show',
:id => @issue },
:class => 'fancy_css_class')
assert_match(/href/, response)
assert_match(/fancy_css_class/, response)
end
should "shouldn't create a link for an unauthorized user" do
User.current = @non_member
response = link_to_if_authorized 'link_content', {
:controller => 'issues',
:action => 'show',
:id => @issue },
:class => 'fancy_css_class'
assert_nil response
end
should "allow using the :controller and :action for the target link" do
User.current = @admin
response = link_to_if_authorized("By controller/action",
{:controller => 'issues', :action => 'edit', :id => @issue.id})
assert_match(/href/, response)
end
end
def test_auto_links
to_test = {
'http://foo.bar' => 'http://foo.bar',
'http://foo.bar/~user' => 'http://foo.bar/~user',
'http://foo.bar.' => 'http://foo.bar.',
'https://foo.bar.' => 'https://foo.bar.',
'This is a link: http://foo.bar.' => 'This is a link: http://foo.bar.',
'A link (eg. http://foo.bar).' => 'A link (eg. http://foo.bar).',
'http://foo.bar/foo.bar#foo.bar.' => 'http://foo.bar/foo.bar#foo.bar.',
'http://www.foo.bar/Test_(foobar)' => 'http://www.foo.bar/Test_(foobar)',
'(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : http://www.foo.bar/Test_(foobar))',
'(see inline link : http://www.foo.bar/Test)' => '(see inline link : http://www.foo.bar/Test)',
'(see inline link : http://www.foo.bar/Test).' => '(see inline link : http://www.foo.bar/Test).',
'(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see inline link)',
'(see "inline link":http://www.foo.bar/Test)' => '(see inline link)',
'(see "inline link":http://www.foo.bar/Test).' => '(see inline link).',
'www.foo.bar' => 'www.foo.bar',
'http://foo.bar/page?p=1&t=z&s=' => 'http://foo.bar/page?p=1&t=z&s=',
'http://foo.bar/page#125' => 'http://foo.bar/page#125',
'http://foo@www.bar.com' => 'http://foo@www.bar.com',
'http://foo:bar@www.bar.com' => 'http://foo:bar@www.bar.com',
'ftp://foo.bar' => 'ftp://foo.bar',
'ftps://foo.bar' => 'ftps://foo.bar',
'sftp://foo.bar' => 'sftp://foo.bar',
# two exclamation marks
'http://example.net/path!602815048C7B5C20!302.html' => 'http://example.net/path!602815048C7B5C20!302.html',
# escaping
'http://foo"bar' => 'http://foo"bar',
# wrap in angle brackets
' #{result} #{result} #{result}
Another paragraph",
# no multiline link text
"This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line
and another on a second line\":test",
# mailto link
"\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "system administrator",
# two exclamation marks
'"a link":http://example.net/path!602815048C7B5C20!302.html' => 'a link',
# escaping
'"test":http://foo"bar' => 'test',
}
to_test.each { |text, result| assert_equal "
#{result}
", textilizable(text) } end def test_textile_relative_to_full_links_in_a_controller # we have a request here { # shouldn't change non-relative links 'This is a "link":http://foo.bar' => 'This is a link', 'This is an intern "link":/foo/bar' => 'This is an intern link', 'This is an intern "link":/foo/bar and an extern "link":http://foo.bar' => 'This is an intern link and an extern link', }.each { |text, result| assert_equal "#{result}
", textilizable(text, :only_path => false) } end def test_textile_relative_to_full_links_in_the_mailer # we don't a request here undef request # mimic the mailer default_url_options @controller.class.class_eval { def self.default_url_options ::UserMailer.default_url_options end } { # shouldn't change non-relative links 'This is a "link":http://foo.bar' => 'This is a link', 'This is an intern "link":/foo/bar' => 'This is an intern link', 'This is an intern "link":/foo/bar and an extern "link":http://foo.bar' => 'This is an intern link and an extern link', }.each { |text, result| assert_equal "#{result}
", textilizable(text, :only_path => false) } end def test_redmine_links document = FactoryGirl.create :document, :title => 'Test document', :project => @project version = FactoryGirl.create :version, :name => '1.0', :project => @project Setting.enabled_scm = Setting.enabled_scm << "Filesystem" unless Setting.enabled_scm.include? "Filesystem" repository = FactoryGirl.create :repository, :project => @project changeset1 = FactoryGirl.create :changeset, :repository => repository, :comments => 'My very first commit' changeset2 = FactoryGirl.create :changeset, :repository => repository, :comments => 'This commit fixes #1, #2 and references #1 & #3' board = FactoryGirl.create :board, :project => @project message1 = FactoryGirl.create :message, :board => board message2 = FactoryGirl.create :message, :board => board, :parent => message1 message1.reload subproject = FactoryGirl.create :valid_project, :parent => @project identifier = @project.identifier @project.reload issue_link = link_to("##{@issue.id}", {:controller => 'issues', :action => 'show', :id => @issue}, :class => 'issue status-3 priority-1 created-by-me', :title => "#{@issue.subject} (#{@issue.status})") changeset_link = link_to("r#{changeset1.revision}", {:controller => 'repositories', :action => 'revision', :id => identifier, :rev => changeset1.revision}, :class => 'changeset', :title => 'My very first commit') changeset_link2 = link_to("r#{changeset2.revision}", {:controller => 'repositories', :action => 'revision', :id => identifier, :rev => changeset2.revision}, :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => document.id}, :class => 'document') version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => version.id}, :class => 'version') message_url = {:controller => 'messages', :action => 'show', :board_id => board.id, :id => message1.id} project_url = {:controller => 'projects', :action => 'show', :id => subproject.identifier} source_url = {:controller => 'repositories', :action => 'entry', :id => identifier, :path => ['some', 'file']} source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => identifier, :path => ['some', 'file.ext']} to_test = { # tickets "##{@issue.id}, [##{@issue.id}], (##{@issue.id}) and ##{@issue.id}." => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.", # changesets "r#{changeset1.revision}" => changeset_link, "r#{changeset1.revision}." => "#{changeset_link}.", "r#{changeset1.revision}, r#{changeset2.revision}" => "#{changeset_link}, #{changeset_link2}", "r#{changeset1.revision},r#{changeset2.revision}" => "#{changeset_link},#{changeset_link2}", # documents "document##{document.id}" => document_link, 'document:"Test document"' => document_link, # versions "version##{version.id}" => version_link, 'version:1.0' => version_link, 'version:"1.0"' => version_link, # source 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'), 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".", 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".", 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".", 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".", 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",", 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'), 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'), 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'), 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'), 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'), 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'), # message "message##{message1.id}" => link_to(message1.subject, message_url, :class => 'message'), "message##{message2.id}" => link_to(message2.subject, message_url.merge(:anchor => "message-#{message2.id}", :r => message2.id), :class => 'message'), # project "project##{subproject.id}" => link_to(subproject.name, project_url, :class => 'project'), "project:#{subproject.identifier}" => link_to(subproject.name, project_url, :class => 'project'), "project:\"#{subproject.name}\"" => link_to(subproject.name, project_url, :class => 'project'), # escaping "!##{@issue.id}." => "##{@issue.id}.", "!r#{changeset1.id}" => "r#{changeset1.id}", "!document##{document.id}" => "document##{document.id}", '!document:"Test document"' => 'document:"Test document"', "!version##{version.id}" => "version##{version.id}", '!version:1.0' => 'version:1.0', '!version:"1.0"' => 'version:"1.0"', '!source:/some/file' => 'source:/some/file', # not found '#0123456789' => '#0123456789', # invalid expressions 'source:' => 'source:', # url hash "http://foo.bar/FAQ#3" => 'http://foo.bar/FAQ#3', } to_test.each { |text, result| assert_equal "#{result}
", textilizable(text), "#{text} failed" } end def test_cross_project_redmine_links document = FactoryGirl.create :document, :title => 'Test document', :project => @project version = FactoryGirl.create :version, :name => '1.0', :project => @project Setting.enabled_scm = Setting.enabled_scm << "Filesystem" unless Setting.enabled_scm.include? "Filesystem" repository = FactoryGirl.create :repository, :project => @project changeset = FactoryGirl.create :changeset, :repository => repository, :comments => 'This commit fixes #1, #2 and references #1 & #3' identifier = @project.identifier source_link = link_to("#{identifier}:source:/some/file", {:controller => 'repositories', :action => 'entry', :id => identifier, :path => ['some', 'file']}, :class => 'source') changeset_link = link_to("#{identifier}:r#{changeset.revision}", {:controller => 'repositories', :action => 'revision', :id => identifier, :rev => changeset.revision}, :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') # textilizable "sees" the text is parses from the_other_project (and not @project) the_other_project = FactoryGirl.create :valid_project to_test = { # documents 'document:"Test document"' => 'document:"Test document"', "#{identifier}:document##{document.id}" => "Test document", "#{identifier}:document:\"Test document\"" => "Test document", 'invalid:document:"Test document"' => 'invalid:document:"Test document"', # versions 'version:"1.0"' => 'version:"1.0"', "#{identifier}:version:\"1.0\"" => "1.0", 'invalid:version:"1.0"' => 'invalid:version:"1.0"', # changeset "r#{changeset.revision}" => "r#{changeset.revision}", "#{identifier}:r#{changeset.revision}" => changeset_link, "invalid:r#{changeset.revision}" => "invalid:r#{changeset.revision}", # source 'source:/some/file' => 'source:/some/file', "#{identifier}:source:/some/file" => source_link, 'invalid:source:/some/file' => 'invalid:source:/some/file', } to_test.each { |text, result| assert_equal "#{result}
", textilizable(text, :project => the_other_project), "#{text} failed" } end def test_redmine_links_git_commit User.current = @admin changeset_link = link_to('abcd', { :controller => 'repositories', :action => 'revision', :id => @project.identifier, :rev => 'abcd', }, :class => 'changeset', :title => 'test commit') to_test = { 'commit:abcd' => changeset_link, } r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git') assert r c = Changeset.new(:repository => r, :committed_on => Time.now, :revision => 'abcd', :scmid => 'abcd', :comments => 'test commit') assert( c.save ) @project.reload to_test.each { |text, result| assert_equal "#{result}
", textilizable(text) } end def test_attachment_links attachment_link = link_to('logo.gif', {:controller => 'attachments', :action => 'download', :id => @attachment}, :class => 'attachment') to_test = { 'attachment:logo.gif' => attachment_link } to_test.each { |text, result| assert_equal "#{result}
", textilizable(text, :attachments => [@attachment]), "#{text} failed" } end def test_wiki_links User.current = @admin @project.wiki.start_page = "CookBook documentation" @project.wiki.save! FactoryGirl.create :wiki_page_with_content, :wiki => @project.wiki, :title => "CookBook_documentation" FactoryGirl.create :wiki_page_with_content, :wiki => @project.wiki, :title => "Another page" project2 = FactoryGirl.create :valid_project, :identifier => 'onlinestore' project2.reload # reload indirectly created references (esp. the wiki) project2.wiki.start_page = "Start page" project2.wiki.save! FactoryGirl.create :wiki_page_with_content, :wiki => project2.wiki, :title => "Start_page" to_test = { '[[CookBook documentation]]' => "CookBook documentation", '[[Another page|Page]]' => "Page", # link with anchor '[[CookBook documentation#One-section]]' => "CookBook documentation", '[[Another page#anchor|Page]]' => "Page", # page that doesn't exist '[[Unknown page]]' => "Unknown page", '[[Unknown page|404]]' => "404", # link to another project wiki '[[onlinestore:]]' => "onlinestore", '[[onlinestore:|Wiki]]' => "Wiki", '[[onlinestore:Start page]]' => "Start page", '[[onlinestore:Start page|Text]]' => "Text", '[[onlinestore:Unknown page]]' => "Unknown page", # striked through link '-[[Another page|Page]]-' => "#{result}
", textilizable(text) } end def test_html_tags to_test = { "<div>content</div>
", "<div class=\"bold\">content</div>
", "" => "<script>some script;</script>
", # do not escape pre/code tags "\nline 1\nline2" => "
\nline 1\nline2", "
\nline 1\nline2
" => "\nline 1\nline2
",
"" => "content
<div>content</div>", "HTML comment: " => "
HTML comment: <!-- no comments -->
", "