Chris@1115: # encoding: utf-8 Chris@1115: # Chris@0: # Redmine - project management software Chris@1494: # Copyright (C) 2006-2014 Jean-Philippe Lang Chris@0: # Chris@0: # This program is free software; you can redistribute it and/or Chris@0: # modify it under the terms of the GNU General Public License Chris@0: # as published by the Free Software Foundation; either version 2 Chris@0: # of the License, or (at your option) any later version. Chris@441: # Chris@0: # This program is distributed in the hope that it will be useful, Chris@0: # but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: # GNU General Public License for more details. Chris@441: # Chris@0: # You should have received a copy of the GNU General Public License Chris@0: # along with this program; if not, write to the Free Software Chris@0: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Chris@0: Chris@119: require File.expand_path('../../../test_helper', __FILE__) Chris@0: chris@22: class ApplicationHelperTest < ActionView::TestCase Chris@1464: include Redmine::I18n Chris@1115: include ERB::Util Chris@1464: include Rails.application.routes.url_helpers Chris@1115: Chris@0: fixtures :projects, :roles, :enabled_modules, :users, Chris@909: :repositories, :changesets, Chris@909: :trackers, :issue_statuses, :issues, :versions, :documents, Chris@909: :wikis, :wiki_pages, :wiki_contents, Chris@909: :boards, :messages, :news, Chris@909: :attachments, :enumerations Chris@0: Chris@0: def setup Chris@0: super Chris@909: set_tmp_attachments_directory Chris@1464: @russian_test = "\xd1\x82\xd0\xb5\xd1\x81\xd1\x82" Chris@1464: if @russian_test.respond_to?(:force_encoding) Chris@1464: @russian_test.force_encoding('UTF-8') Chris@1464: end Chris@0: end chris@22: Chris@1464: test "#link_to_if_authorized for authorized user should allow using the :controller and :action for the target link" do Chris@1464: User.current = User.find_by_login('admin') Chris@441: Chris@1464: @project = Issue.first.project # Used by helper Chris@1464: response = link_to_if_authorized('By controller/actionr', Chris@1464: {:controller => 'issues', :action => 'edit', :id => Issue.first.id}) Chris@1464: assert_match /href/, response Chris@1464: end Chris@441: Chris@1464: test "#link_to_if_authorized for unauthorized user should display nothing if user isn't authorized" do Chris@1464: User.current = User.find_by_login('dlopper') Chris@1464: @project = Project.find('private-child') Chris@1464: issue = @project.issues.first Chris@1464: assert !issue.visible? chris@22: Chris@1464: response = link_to_if_authorized('Never displayed', Chris@1464: {:controller => 'issues', :action => 'show', :id => issue}) Chris@1464: assert_nil response chris@22: end Chris@441: Chris@0: def test_auto_links Chris@0: to_test = { Chris@0: 'http://foo.bar' => 'http://foo.bar', Chris@0: 'http://foo.bar/~user' => 'http://foo.bar/~user', Chris@0: 'http://foo.bar.' => 'http://foo.bar.', Chris@0: 'https://foo.bar.' => 'https://foo.bar.', Chris@0: 'This is a link: http://foo.bar.' => 'This is a link: http://foo.bar.', Chris@0: 'A link (eg. http://foo.bar).' => 'A link (eg. http://foo.bar).', Chris@0: 'http://foo.bar/foo.bar#foo.bar.' => 'http://foo.bar/foo.bar#foo.bar.', Chris@0: 'http://www.foo.bar/Test_(foobar)' => 'http://www.foo.bar/Test_(foobar)', Chris@0: '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : http://www.foo.bar/Test_(foobar))', Chris@0: '(see inline link : http://www.foo.bar/Test)' => '(see inline link : http://www.foo.bar/Test)', Chris@0: '(see inline link : http://www.foo.bar/Test).' => '(see inline link : http://www.foo.bar/Test).', Chris@0: '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see inline link)', Chris@0: '(see "inline link":http://www.foo.bar/Test)' => '(see inline link)', Chris@0: '(see "inline link":http://www.foo.bar/Test).' => '(see inline link).', Chris@0: 'www.foo.bar' => 'www.foo.bar', Chris@0: 'http://foo.bar/page?p=1&t=z&s=' => 'http://foo.bar/page?p=1&t=z&s=', Chris@0: 'http://foo.bar/page#125' => 'http://foo.bar/page#125', Chris@0: 'http://foo@www.bar.com' => 'http://foo@www.bar.com', Chris@0: 'http://foo:bar@www.bar.com' => 'http://foo:bar@www.bar.com', Chris@0: 'ftp://foo.bar' => 'ftp://foo.bar', Chris@0: 'ftps://foo.bar' => 'ftps://foo.bar', Chris@0: 'sftp://foo.bar' => 'sftp://foo.bar', Chris@0: # two exclamation marks Chris@0: 'http://example.net/path!602815048C7B5C20!302.html' => 'http://example.net/path!602815048C7B5C20!302.html', Chris@0: # escaping Chris@1115: 'http://foo"bar' => 'http://foo"bar', chris@37: # wrap in angle brackets Chris@1464: '' => '<http://foo.bar>', Chris@1464: # invalid urls Chris@1464: 'http://' => 'http://', Chris@1464: 'www.' => 'www.', Chris@1464: 'test-www.bar.com' => 'test-www.bar.com', Chris@0: } Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@0: end Chris@441: Chris@1115: if 'ruby'.respond_to?(:encoding) Chris@1115: def test_auto_links_with_non_ascii_characters Chris@1115: to_test = { Chris@1464: "http://foo.bar/#{@russian_test}" => Chris@1464: %|http://foo.bar/#{@russian_test}| Chris@1115: } Chris@1115: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@1115: end Chris@1115: else Chris@1115: puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version' Chris@1115: end Chris@1115: Chris@0: def test_auto_mailto Chris@1464: to_test = { Chris@1464: 'test@foo.bar' => 'test@foo.bar', Chris@1464: 'test@www.foo.bar' => 'test@www.foo.bar', Chris@1464: } Chris@1464: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@0: end Chris@441: Chris@0: def test_inline_images Chris@0: to_test = { Chris@0: '!http://foo.bar/image.jpg!' => '', Chris@0: 'floating !>http://foo.bar/image.jpg!' => 'floating
', Chris@0: 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class ', Chris@1115: 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style ', Chris@0: 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title This is a title', Chris@0: 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title This is a double-quoted "title"', Chris@0: } Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@0: end Chris@441: Chris@0: def test_inline_images_inside_tags Chris@0: raw = <<-RAW Chris@0: h1. !foo.png! Heading Chris@0: Chris@0: Centered image: Chris@0: Chris@0: p=. !bar.gif! Chris@0: RAW Chris@0: Chris@0: assert textilizable(raw).include?('') Chris@0: assert textilizable(raw).include?('') Chris@0: end Chris@441: Chris@0: def test_attached_images Chris@0: to_test = { Chris@1464: 'Inline image: !logo.gif!' => 'Inline image: This is a logo', Chris@1464: 'Inline image: !logo.GIF!' => 'Inline image: This is a logo', Chris@0: 'No match: !ogo.gif!' => 'No match: ', Chris@0: 'No match: !ogo.GIF!' => 'No match: ', Chris@0: # link image Chris@1464: '!logo.gif!:http://foo.bar/' => 'This is a logo', Chris@0: } Chris@1464: attachments = Attachment.all Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text, :attachments => attachments) } Chris@0: end Chris@441: Chris@909: def test_attached_images_filename_extension Chris@909: set_tmp_attachments_directory Chris@909: a1 = Attachment.new( Chris@909: :container => Issue.find(1), Chris@909: :file => mock_file_with_options({:original_filename => "testtest.JPG"}), Chris@909: :author => User.find(1)) Chris@909: assert a1.save Chris@909: assert_equal "testtest.JPG", a1.filename Chris@909: assert_equal "image/jpeg", a1.content_type Chris@909: assert a1.image? Chris@909: Chris@909: a2 = Attachment.new( Chris@909: :container => Issue.find(1), Chris@909: :file => mock_file_with_options({:original_filename => "testtest.jpeg"}), Chris@909: :author => User.find(1)) Chris@909: assert a2.save Chris@909: assert_equal "testtest.jpeg", a2.filename Chris@909: assert_equal "image/jpeg", a2.content_type Chris@909: assert a2.image? Chris@909: Chris@909: a3 = Attachment.new( Chris@909: :container => Issue.find(1), Chris@909: :file => mock_file_with_options({:original_filename => "testtest.JPE"}), Chris@909: :author => User.find(1)) Chris@909: assert a3.save Chris@909: assert_equal "testtest.JPE", a3.filename Chris@909: assert_equal "image/jpeg", a3.content_type Chris@909: assert a3.image? Chris@909: Chris@909: a4 = Attachment.new( Chris@909: :container => Issue.find(1), Chris@909: :file => mock_file_with_options({:original_filename => "Testtest.BMP"}), Chris@909: :author => User.find(1)) Chris@909: assert a4.save Chris@909: assert_equal "Testtest.BMP", a4.filename Chris@909: assert_equal "image/x-ms-bmp", a4.content_type Chris@909: assert a4.image? Chris@909: Chris@909: to_test = { Chris@909: 'Inline image: !testtest.jpg!' => Chris@1464: 'Inline image: ', Chris@909: 'Inline image: !testtest.jpeg!' => Chris@1464: 'Inline image: ', Chris@909: 'Inline image: !testtest.jpe!' => Chris@1464: 'Inline image: ', Chris@909: 'Inline image: !testtest.bmp!' => Chris@1464: 'Inline image: ', Chris@909: } Chris@909: Chris@909: attachments = [a1, a2, a3, a4] Chris@909: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text, :attachments => attachments) } Chris@909: end Chris@909: Chris@909: def test_attached_images_should_read_later Chris@1115: set_fixtures_attachments_directory Chris@909: a1 = Attachment.find(16) Chris@909: assert_equal "testfile.png", a1.filename Chris@909: assert a1.readable? Chris@909: assert (! a1.visible?(User.anonymous)) Chris@909: assert a1.visible?(User.find(2)) Chris@909: a2 = Attachment.find(17) Chris@909: assert_equal "testfile.PNG", a2.filename Chris@909: assert a2.readable? Chris@909: assert (! a2.visible?(User.anonymous)) Chris@909: assert a2.visible?(User.find(2)) Chris@909: assert a1.created_on < a2.created_on Chris@909: Chris@909: to_test = { Chris@909: 'Inline image: !testfile.png!' => Chris@1464: 'Inline image: ', Chris@909: 'Inline image: !Testfile.PNG!' => Chris@1464: 'Inline image: ', Chris@909: } Chris@909: attachments = [a1, a2] Chris@909: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text, :attachments => attachments) } Chris@909: set_tmp_attachments_directory Chris@909: end Chris@909: Chris@0: def test_textile_external_links Chris@0: to_test = { Chris@0: 'This is a "link":http://foo.bar' => 'This is a link', Chris@0: 'This is an intern "link":/foo/bar' => 'This is an intern link', Chris@0: '"link (Link title)":http://foo.bar' => 'link', Chris@0: '"link (Link title with "double-quotes")":http://foo.bar' => 'link', Chris@0: "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":

\n\n\n\t

Another paragraph", Chris@0: # no multiline link text Chris@0: "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", Chris@0: # mailto link Chris@0: "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "system administrator", Chris@0: # two exclamation marks Chris@0: '"a link":http://example.net/path!602815048C7B5C20!302.html' => 'a link', Chris@0: # escaping Chris@0: '"test":http://foo"bar' => 'test', Chris@0: } Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@0: end Chris@119: Chris@1115: if 'ruby'.respond_to?(:encoding) Chris@1115: def test_textile_external_links_with_non_ascii_characters Chris@1115: to_test = { Chris@1464: %|This is a "link":http://foo.bar/#{@russian_test}| => Chris@1464: %|This is a link| Chris@1115: } Chris@1115: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@1115: end Chris@1115: else Chris@1115: puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version' Chris@1115: end Chris@1115: Chris@0: def test_redmine_links Chris@441: issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3}, Chris@1464: :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)') Chris@1464: note_link = link_to('#3-14', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'}, Chris@1464: :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)') Chris@1464: note_link2 = link_to('#3#note-14', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'}, Chris@1464: :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)') Chris@441: Chris@1464: revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1}, Chris@1464: :class => 'changeset', :title => 'My very first commit do not escaping #<>&') Chris@1464: revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2}, Chris@0: :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') Chris@441: Chris@1464: changeset_link2 = link_to('691322a8eb01e11fd7', Chris@1464: {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1}, Chris@1464: :class => 'changeset', :title => 'My very first commit do not escaping #<>&') Chris@1464: Chris@0: document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1}, Chris@0: :class => 'document') Chris@441: Chris@0: version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2}, Chris@0: :class => 'version') Chris@0: Chris@909: board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'} Chris@909: Chris@0: message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4} Chris@909: Chris@909: news_url = {:controller => 'news', :action => 'show', :id => 1} Chris@441: Chris@0: project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'} Chris@441: Chris@1115: source_url = '/projects/ecookbook/repository/entry/some/file' Chris@1115: source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file' Chris@1115: source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext' Chris@1115: source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext' Chris@1464: source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file' Chris@1115: Chris@1115: export_url = '/projects/ecookbook/repository/raw/some/file' Chris@1115: export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file' Chris@1115: export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext' Chris@1115: export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext' Chris@1464: export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file' Chris@441: Chris@0: to_test = { Chris@0: # tickets Chris@0: '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.", Chris@1115: # ticket notes Chris@1115: '#3-14' => note_link, Chris@1464: '#3#note-14' => note_link2, Chris@1115: # should not ignore leading zero Chris@1115: '#03' => '#03', Chris@0: # changesets Chris@1464: 'r1' => revision_link, Chris@1464: 'r1.' => "#{revision_link}.", Chris@1464: 'r1, r2' => "#{revision_link}, #{revision_link2}", Chris@1464: 'r1,r2' => "#{revision_link},#{revision_link2}", Chris@1464: 'commit:691322a8eb01e11fd7' => changeset_link2, Chris@0: # documents Chris@0: 'document#1' => document_link, Chris@0: 'document:"Test document"' => document_link, Chris@0: # versions Chris@0: 'version#2' => version_link, Chris@0: 'version:1.0' => version_link, Chris@0: 'version:"1.0"' => version_link, Chris@0: # source Chris@1115: 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'), Chris@0: 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'), Chris@0: 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".", Chris@0: 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".", Chris@0: 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".", Chris@0: 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".", Chris@0: 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",", Chris@1115: 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'), Chris@1464: 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'), Chris@1115: 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'), Chris@1115: 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'), Chris@1115: 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'), Chris@1115: 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'), Chris@1115: # export Chris@1115: 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'), Chris@1115: 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'), Chris@1115: 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'), Chris@1115: 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'), Chris@1464: 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'), Chris@909: # forum Chris@909: 'forum#2' => link_to('Discussion', board_url, :class => 'board'), Chris@909: 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'), Chris@0: # message Chris@0: 'message#4' => link_to('Post 2', message_url, :class => 'message'), Chris@210: 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'), Chris@909: # news Chris@909: 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'), Chris@909: 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'), Chris@0: # project Chris@0: 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'), Chris@0: 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'), Chris@0: 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'), Chris@0: # not found Chris@0: '#0123456789' => '#0123456789', Chris@0: # invalid expressions Chris@0: 'source:' => 'source:', Chris@0: # url hash Chris@0: "http://foo.bar/FAQ#3" => 'http://foo.bar/FAQ#3', Chris@0: } Chris@0: @project = Project.find(1) Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text), "#{text} failed" } Chris@0: end Chris@441: Chris@1294: def test_redmine_links_with_a_different_project_before_current_project Chris@1294: vp1 = Version.generate!(:project_id => 1, :name => '1.4.4') Chris@1294: vp3 = Version.generate!(:project_id => 3, :name => '1.4.4') Chris@1294: @project = Project.find(3) Chris@1517: result1 = link_to("1.4.4", "/versions/#{vp1.id}", :class => "version") Chris@1517: result2 = link_to("1.4.4", "/versions/#{vp3.id}", :class => "version") Chris@1517: assert_equal "

#{result1} #{result2}

", Chris@1517: textilizable("ecookbook:version:1.4.4 version:1.4.4") Chris@1294: end Chris@1294: Chris@1115: def test_escaped_redmine_links_should_not_be_parsed Chris@1115: to_test = [ Chris@1115: '#3.', Chris@1115: '#3-14.', Chris@1115: '#3#-note14.', Chris@1115: 'r1', Chris@1115: 'document#1', Chris@1115: 'document:"Test document"', Chris@1115: 'version#2', Chris@1115: 'version:1.0', Chris@1115: 'version:"1.0"', Chris@1115: 'source:/some/file' Chris@1115: ] Chris@1115: @project = Project.find(1) Chris@1115: to_test.each { |text| assert_equal "

#{text}

", textilizable("!" + text), "#{text} failed" } Chris@1115: end Chris@1115: Chris@210: def test_cross_project_redmine_links Chris@1517: source_link = link_to('ecookbook:source:/some/file', Chris@1517: {:controller => 'repositories', :action => 'entry', Chris@1517: :id => 'ecookbook', :path => ['some', 'file']}, Chris@1517: :class => 'source') Chris@1517: changeset_link = link_to('ecookbook:r2', Chris@1517: {:controller => 'repositories', :action => 'revision', Chris@1517: :id => 'ecookbook', :rev => 2}, Chris@1517: :class => 'changeset', Chris@1517: :title => 'This commit fixes #1, #2 and references #1 & #3') Chris@210: to_test = { Chris@210: # documents Chris@210: 'document:"Test document"' => 'document:"Test document"', Chris@1517: 'ecookbook:document:"Test document"' => Chris@1517: link_to("Test document", "/documents/1", :class => "document"), Chris@210: 'invalid:document:"Test document"' => 'invalid:document:"Test document"', Chris@210: # versions Chris@210: 'version:"1.0"' => 'version:"1.0"', Chris@1517: 'ecookbook:version:"1.0"' => Chris@1517: link_to("1.0", "/versions/2", :class => "version"), Chris@210: 'invalid:version:"1.0"' => 'invalid:version:"1.0"', Chris@210: # changeset Chris@210: 'r2' => 'r2', Chris@210: 'ecookbook:r2' => changeset_link, Chris@210: 'invalid:r2' => 'invalid:r2', Chris@210: # source Chris@210: 'source:/some/file' => 'source:/some/file', Chris@210: 'ecookbook:source:/some/file' => source_link, Chris@210: 'invalid:source:/some/file' => 'invalid:source:/some/file', Chris@210: } Chris@210: @project = Project.find(3) Chris@1517: to_test.each do |text, result| Chris@1517: assert_equal "

#{result}

", textilizable(text), "#{text} failed" Chris@1517: end Chris@1517: end Chris@1517: Chris@1517: def test_redmine_links_by_name_should_work_with_html_escaped_characters Chris@1517: v = Version.generate!(:name => "Test & Show.txt", :project_id => 1) Chris@1517: link = link_to("Test & Show.txt", "/versions/#{v.id}", :class => "version") Chris@1517: Chris@1517: @project = v.project Chris@1517: assert_equal "

#{link}

", textilizable('version:"Test & Show.txt"') Chris@1517: end Chris@1517: Chris@1517: def test_link_to_issue_subject Chris@1517: issue = Issue.generate!(:subject => "01234567890123456789") Chris@1517: str = link_to_issue(issue, :truncate => 10) Chris@1517: result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes) Chris@1517: assert_equal "#{result}: 0123456...", str Chris@1517: Chris@1517: issue = Issue.generate!(:subject => "<&>") Chris@1517: str = link_to_issue(issue) Chris@1517: result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes) Chris@1517: assert_equal "#{result}: <&>", str Chris@1517: Chris@1517: issue = Issue.generate!(:subject => "<&>0123456789012345") Chris@1517: str = link_to_issue(issue, :truncate => 10) Chris@1517: result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes) Chris@1517: assert_equal "#{result}: <&>0123...", str Chris@1517: end Chris@1517: Chris@1517: def test_link_to_issue_title Chris@1517: long_str = "0123456789" * 5 Chris@1517: Chris@1517: issue = Issue.generate!(:subject => "#{long_str}01234567890123456789") Chris@1517: str = link_to_issue(issue, :subject => false) Chris@1517: result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", Chris@1517: :class => issue.css_classes, Chris@1517: :title => "#{long_str}0123456...") Chris@1517: assert_equal result, str Chris@1517: Chris@1517: issue = Issue.generate!(:subject => "<&>#{long_str}01234567890123456789") Chris@1517: str = link_to_issue(issue, :subject => false) Chris@1517: result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", Chris@1517: :class => issue.css_classes, Chris@1517: :title => "<&>#{long_str}0123...") Chris@1517: assert_equal result, str Chris@210: end Chris@119: Chris@1115: def test_multiple_repositories_redmine_links Chris@1294: svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg') Chris@1115: Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123') Chris@1115: hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg') Chris@1115: Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd') Chris@1115: Chris@1115: changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2}, Chris@1115: :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') Chris@1294: svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123}, Chris@1115: :class => 'changeset', :title => '') Chris@1115: hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'}, Chris@1115: :class => 'changeset', :title => '') Chris@1115: Chris@1115: source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source') Chris@1115: hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source') Chris@1115: Chris@1115: to_test = { Chris@1115: 'r2' => changeset_link, Chris@1294: 'svn_repo-1|r123' => svn_changeset_link, Chris@1115: 'invalid|r123' => 'invalid|r123', Chris@1115: 'commit:hg1|abcd' => hg_changeset_link, Chris@1115: 'commit:invalid|abcd' => 'commit:invalid|abcd', Chris@1115: # source Chris@1115: 'source:some/file' => source_link, Chris@1115: 'source:hg1|some/file' => hg_source_link, Chris@1115: 'source:invalid|some/file' => 'source:invalid|some/file', Chris@1115: } Chris@1115: Chris@1115: @project = Project.find(1) Chris@1115: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text), "#{text} failed" } Chris@1115: end Chris@1115: Chris@1115: def test_cross_project_multiple_repositories_redmine_links Chris@1115: svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg') Chris@1115: Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123') Chris@1115: hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg') Chris@1115: Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd') Chris@1115: Chris@1115: changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2}, Chris@1115: :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') Chris@1115: svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123}, Chris@1115: :class => 'changeset', :title => '') Chris@1115: hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'}, Chris@1115: :class => 'changeset', :title => '') Chris@1115: Chris@1115: source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source') Chris@1115: hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source') Chris@1115: Chris@1115: to_test = { Chris@1115: 'ecookbook:r2' => changeset_link, Chris@1115: 'ecookbook:svn1|r123' => svn_changeset_link, Chris@1115: 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123', Chris@1115: 'ecookbook:commit:hg1|abcd' => hg_changeset_link, Chris@1115: 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd', Chris@1115: 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd', Chris@1115: # source Chris@1115: 'ecookbook:source:some/file' => source_link, Chris@1115: 'ecookbook:source:hg1|some/file' => hg_source_link, Chris@1115: 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file', Chris@1115: 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file', Chris@1115: } Chris@1115: Chris@1115: @project = Project.find(3) Chris@1115: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text), "#{text} failed" } Chris@1115: end Chris@1115: Chris@119: def test_redmine_links_git_commit Chris@119: changeset_link = link_to('abcd', Chris@119: { Chris@119: :controller => 'repositories', Chris@119: :action => 'revision', Chris@119: :id => 'subproject1', Chris@119: :rev => 'abcd', Chris@119: }, Chris@119: :class => 'changeset', :title => 'test commit') Chris@119: to_test = { Chris@119: 'commit:abcd' => changeset_link, Chris@119: } Chris@119: @project = Project.find(3) Chris@119: r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git') Chris@119: assert r Chris@119: c = Changeset.new(:repository => r, Chris@119: :committed_on => Time.now, Chris@119: :revision => 'abcd', Chris@119: :scmid => 'abcd', Chris@119: :comments => 'test commit') Chris@119: assert( c.save ) Chris@119: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@119: end Chris@119: Chris@119: # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'. Chris@119: def test_redmine_links_darcs_commit Chris@119: changeset_link = link_to('20080308225258-98289-abcd456efg.gz', Chris@119: { Chris@119: :controller => 'repositories', Chris@119: :action => 'revision', Chris@119: :id => 'subproject1', Chris@119: :rev => '123', Chris@119: }, Chris@119: :class => 'changeset', :title => 'test commit') Chris@119: to_test = { Chris@119: 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link, Chris@119: } Chris@119: @project = Project.find(3) Chris@245: r = Repository::Darcs.create!( Chris@245: :project => @project, :url => '/tmp/test/darcs', Chris@245: :log_encoding => 'UTF-8') Chris@119: assert r Chris@119: c = Changeset.new(:repository => r, Chris@119: :committed_on => Time.now, Chris@119: :revision => '123', Chris@119: :scmid => '20080308225258-98289-abcd456efg.gz', Chris@119: :comments => 'test commit') Chris@119: assert( c.save ) Chris@119: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@119: end Chris@119: Chris@119: def test_redmine_links_mercurial_commit Chris@119: changeset_link_rev = link_to('r123', Chris@119: { Chris@119: :controller => 'repositories', Chris@119: :action => 'revision', Chris@119: :id => 'subproject1', Chris@119: :rev => '123' , Chris@119: }, Chris@119: :class => 'changeset', :title => 'test commit') Chris@119: changeset_link_commit = link_to('abcd', Chris@119: { Chris@119: :controller => 'repositories', Chris@119: :action => 'revision', Chris@119: :id => 'subproject1', Chris@119: :rev => 'abcd' , Chris@119: }, Chris@119: :class => 'changeset', :title => 'test commit') Chris@119: to_test = { Chris@119: 'r123' => changeset_link_rev, Chris@119: 'commit:abcd' => changeset_link_commit, Chris@119: } Chris@119: @project = Project.find(3) Chris@119: r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test') Chris@119: assert r Chris@119: c = Changeset.new(:repository => r, Chris@119: :committed_on => Time.now, Chris@119: :revision => '123', Chris@119: :scmid => 'abcd', Chris@119: :comments => 'test commit') Chris@119: assert( c.save ) Chris@119: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@119: end Chris@119: Chris@0: def test_attachment_links Chris@1517: text = 'attachment:error281.txt' Chris@1517: result = link_to("error281.txt", "/attachments/download/1/error281.txt", Chris@1517: :class => "attachment") Chris@1517: assert_equal "

#{result}

", Chris@1517: textilizable(text, Chris@1517: :attachments => Issue.find(3).attachments), Chris@1517: "#{text} failed" Chris@0: end Chris@441: Chris@1294: def test_attachment_link_should_link_to_latest_attachment Chris@1294: set_tmp_attachments_directory Chris@1294: a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago) Chris@1294: a2 = Attachment.generate!(:filename => "test.txt") Chris@1517: result = link_to("test.txt", "/attachments/download/#{a2.id}/test.txt", Chris@1517: :class => "attachment") Chris@1517: assert_equal "

#{result}

", Chris@1517: textilizable('attachment:test.txt', :attachments => [a1, a2]) Chris@1294: end Chris@1294: Chris@0: def test_wiki_links Chris@1464: russian_eacape = CGI.escape(@russian_test) Chris@0: to_test = { Chris@1517: '[[CookBook documentation]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page|Page]]' => Chris@1517: link_to("Page", Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page"), Chris@909: # title content should be formatted Chris@1517: '[[Another page|With _styled_ *title*]]' => Chris@1517: link_to("With styled title".html_safe, Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page|With title containing HTML entities & markups]]' => Chris@1517: link_to("With title containing <strong>HTML entities & markups</strong>".html_safe, Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page"), Chris@0: # link with anchor Chris@1517: '[[CookBook documentation#One-section]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation#One-section", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page#anchor|Page]]' => Chris@1517: link_to("Page", Chris@1517: "/projects/ecookbook/wiki/Another_page#anchor", Chris@1517: :class => "wiki-page"), Chris@1115: # UTF8 anchor Chris@1464: "[[Another_page##{@russian_test}|#{@russian_test}]]" => Chris@1517: link_to(@russian_test, Chris@1517: "/projects/ecookbook/wiki/Another_page##{russian_eacape}", Chris@1517: :class => "wiki-page"), Chris@0: # page that doesn't exist Chris@1517: '[[Unknown page]]' => Chris@1517: link_to("Unknown page", Chris@1517: "/projects/ecookbook/wiki/Unknown_page", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page|404]]' => Chris@1517: link_to("404", Chris@1517: "/projects/ecookbook/wiki/Unknown_page", Chris@1517: :class => "wiki-page new"), Chris@0: # link to another project wiki Chris@1517: '[[onlinestore:]]' => Chris@1517: link_to("onlinestore", Chris@1517: "/projects/onlinestore/wiki", Chris@1517: :class => "wiki-page"), Chris@1517: '[[onlinestore:|Wiki]]' => Chris@1517: link_to("Wiki", Chris@1517: "/projects/onlinestore/wiki", Chris@1517: :class => "wiki-page"), Chris@1517: '[[onlinestore:Start page]]' => Chris@1517: link_to("Start page", Chris@1517: "/projects/onlinestore/wiki/Start_page", Chris@1517: :class => "wiki-page"), Chris@1517: '[[onlinestore:Start page|Text]]' => Chris@1517: link_to("Text", Chris@1517: "/projects/onlinestore/wiki/Start_page", Chris@1517: :class => "wiki-page"), Chris@1517: '[[onlinestore:Unknown page]]' => Chris@1517: link_to("Unknown page", Chris@1517: "/projects/onlinestore/wiki/Unknown_page", Chris@1517: :class => "wiki-page new"), Chris@0: # striked through link Chris@1517: '-[[Another page|Page]]-' => Chris@1517: "".html_safe + Chris@1517: link_to("Page", Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page").html_safe + Chris@1517: "".html_safe, Chris@1517: '-[[Another page|Page]] link-' => Chris@1517: "".html_safe + Chris@1517: link_to("Page", Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page").html_safe + Chris@1517: " link".html_safe, Chris@0: # escaping Chris@0: '![[Another page|Page]]' => '[[Another page|Page]]', Chris@0: # project does not exist Chris@0: '[[unknowproject:Start]]' => '[[unknowproject:Start]]', Chris@0: '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]', Chris@0: } Chris@0: @project = Project.find(1) Chris@0: to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text) } Chris@0: end Chris@441: Chris@909: def test_wiki_links_within_local_file_generation_context Chris@909: to_test = { Chris@909: # link to a page Chris@1517: '[[CookBook documentation]]' => Chris@1517: link_to("CookBook documentation", "CookBook_documentation.html", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation|documentation]]' => Chris@1517: link_to("documentation", "CookBook_documentation.html", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section]]' => Chris@1517: link_to("CookBook documentation", "CookBook_documentation.html#One-section", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section|documentation]]' => Chris@1517: link_to("documentation", "CookBook_documentation.html#One-section", Chris@1517: :class => "wiki-page"), Chris@909: # page that doesn't exist Chris@1517: '[[Unknown page]]' => Chris@1517: link_to("Unknown page", "Unknown_page.html", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page|404]]' => Chris@1517: link_to("404", "Unknown_page.html", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor]]' => Chris@1517: link_to("Unknown page", "Unknown_page.html#anchor", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor|404]]' => Chris@1517: link_to("404", "Unknown_page.html#anchor", Chris@1517: :class => "wiki-page new"), Chris@909: } Chris@909: @project = Project.find(1) Chris@1517: to_test.each do |text, result| Chris@1517: assert_equal "

#{result}

", textilizable(text, :wiki_links => :local) Chris@1517: end Chris@909: end Chris@909: Chris@1115: def test_wiki_links_within_wiki_page_context Chris@1115: page = WikiPage.find_by_title('Another_page' ) Chris@1115: to_test = { Chris@1517: '[[CookBook documentation]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation|documentation]]' => Chris@1517: link_to("documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation#One-section", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section|documentation]]' => Chris@1517: link_to("documentation", Chris@1517: "/projects/ecookbook/wiki/CookBook_documentation#One-section", Chris@1517: :class => "wiki-page"), Chris@1115: # link to the current page Chris@1517: '[[Another page]]' => Chris@1517: link_to("Another page", Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page|Page]]' => Chris@1517: link_to("Page", Chris@1517: "/projects/ecookbook/wiki/Another_page", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page#anchor]]' => Chris@1517: link_to("Another page", Chris@1517: "#anchor", Chris@1517: :class => "wiki-page"), Chris@1517: '[[Another page#anchor|Page]]' => Chris@1517: link_to("Page", Chris@1517: "#anchor", Chris@1517: :class => "wiki-page"), Chris@1115: # page that doesn't exist Chris@1517: '[[Unknown page]]' => Chris@1517: link_to("Unknown page", Chris@1517: "/projects/ecookbook/wiki/Unknown_page?parent=Another_page", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page|404]]' => Chris@1517: link_to("404", Chris@1517: "/projects/ecookbook/wiki/Unknown_page?parent=Another_page", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor]]' => Chris@1517: link_to("Unknown page", Chris@1517: "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor|404]]' => Chris@1517: link_to("404", Chris@1517: "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor", Chris@1517: :class => "wiki-page new"), Chris@1115: } Chris@1115: @project = Project.find(1) Chris@1517: to_test.each do |text, result| Chris@1517: assert_equal "

#{result}

", Chris@1517: textilizable(WikiContent.new( :text => text, :page => page ), :text) Chris@1517: end Chris@1115: end Chris@1115: Chris@1115: def test_wiki_links_anchor_option_should_prepend_page_title_to_href Chris@1115: to_test = { Chris@1115: # link to a page Chris@1517: '[[CookBook documentation]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "#CookBook_documentation", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation|documentation]]' => Chris@1517: link_to("documentation", Chris@1517: "#CookBook_documentation", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section]]' => Chris@1517: link_to("CookBook documentation", Chris@1517: "#CookBook_documentation_One-section", Chris@1517: :class => "wiki-page"), Chris@1517: '[[CookBook documentation#One-section|documentation]]' => Chris@1517: link_to("documentation", Chris@1517: "#CookBook_documentation_One-section", Chris@1517: :class => "wiki-page"), Chris@1115: # page that doesn't exist Chris@1517: '[[Unknown page]]' => Chris@1517: link_to("Unknown page", Chris@1517: "#Unknown_page", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page|404]]' => Chris@1517: link_to("404", Chris@1517: "#Unknown_page", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor]]' => Chris@1517: link_to("Unknown page", Chris@1517: "#Unknown_page_anchor", Chris@1517: :class => "wiki-page new"), Chris@1517: '[[Unknown page#anchor|404]]' => Chris@1517: link_to("404", Chris@1517: "#Unknown_page_anchor", Chris@1517: :class => "wiki-page new"), Chris@1115: } Chris@1115: @project = Project.find(1) Chris@1517: to_test.each do |text, result| Chris@1517: assert_equal "

#{result}

", textilizable(text, :wiki_links => :anchor) Chris@1517: end Chris@1115: end Chris@1115: Chris@0: def test_html_tags Chris@0: to_test = { Chris@0: "
content
" => "

<div>content</div>

", Chris@0: "
content
" => "

<div class=\"bold\">content</div>

", Chris@0: "" => "

<script>some script;</script>

", Chris@0: # do not escape pre/code tags Chris@0: "
\nline 1\nline2
" => "
\nline 1\nline2
", Chris@0: "
\nline 1\nline2
" => "
\nline 1\nline2
", Chris@0: "
content
" => "
<div>content</div>
", Chris@0: "HTML comment: " => "

HTML comment: <!-- no comments -->

", Chris@0: "