From 70fa15e3f38aa7efbe517c061b6292a26f7ef69a Mon Sep 17 00:00:00 2001 From: Alexey Verkhovsky Date: Sat, 10 Sep 2005 11:07:40 +0000 Subject: [PATCH] Continue extracting URL generation logic from model classes --- app/controllers/application.rb | 12 ++- app/helpers/application_helper.rb | 7 +- app/models/page.rb | 13 --- app/models/web.rb | 22 ----- app/views/wiki/page.rhtml | 2 +- app/views/wiki/print.rhtml | 2 +- lib/page_renderer.rb | 21 +++-- lib/url_generator.rb | 128 ++++++++++++++++++++++-------- lib/wiki_content.rb | 5 +- test/test_helper.rb | 60 ++++++++++++++ test/unit/page_renderer_test.rb | 44 ---------- test/watir/e2e.rb | 2 +- 12 files changed, 191 insertions(+), 127 deletions(-) diff --git a/app/controllers/application.rb b/app/controllers/application.rb index a126f845..2208066a 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -2,8 +2,8 @@ # Likewise will all the methods added be available for all controllers. class ApplicationController < ActionController::Base - before_filter :set_utf8_http_header, :connect_to_model - after_filter :remember_location + before_filter :set_utf8_http_header, :connect_to_model, :setup_url_generator + after_filter :remember_location, :teardown_url_generator # For injecting a different wiki model implementation. Intended for use in tests def self.wiki=(the_wiki) @@ -146,6 +146,14 @@ class ApplicationController < ActionController::Base @response.headers['Content-Type'] = 'text/html; charset=UTF-8' end + def setup_url_generator + PageRenderer.setup_url_generator(UrlGenerator.new(self)) + end + + def teardown_url_generator + PageRenderer.teardown_url_generator + end + def wiki self.class.wiki end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 491fb410..f72c572d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -44,7 +44,12 @@ module ApplicationHelper # Creates a hyperlink to a Wiki page, or to a "new page" form if the page doesn't exist yet def link_to_page(page_name, web = @web, text = nil, options = {}) raise 'Web not defined' if web.nil? - web.make_link(page_name, text, options.merge(:base_url => "#{base_url}/#{web.address}")) + UrlGenerator.new(@controller).make_link(page_name, web, text, + options.merge(:base_url => "#{base_url}/#{web.address}")) + end + + def author_link(page, options = {}) + UrlGenerator.new(@controller).make_link(page.author.name, page.web, nil, options) end def base_url diff --git a/app/models/page.rb b/app/models/page.rb index 1179e9f8..7d0e8695 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -79,19 +79,6 @@ class Page < ActiveRecord::Base web.brackets_only? ? name : WikiWords.separate(name) end - # used to build chunk ids. - #def id - # @id ||= name.unpack('H*').first - #end - - def link(options = {}) - web.make_link(name, nil, options) - end - - def author_link(options = {}) - web.make_link(author, nil, options) - end - LOCKING_PERIOD = 30.minutes def lock(time, locked_by) diff --git a/app/models/web.rb b/app/models/web.rb index f3fb5534..e3b2f7d0 100644 --- a/app/models/web.rb +++ b/app/models/web.rb @@ -44,28 +44,6 @@ class Web < ActiveRecord::Base read_attribute('markup').to_sym end - # Create a link for the given page name and link text based - # on the render mode in options and whether the page exists - # in the this web. - # The links a relative, and will work only if displayed on another WikiPage. - # It should not be used in menus, templates and such - instead, use link_to_page helper - def make_link(name, text = nil, options = {}) - text = CGI.escapeHTML(text || WikiWords.separate(name)) - mode = options[:mode] || :show - base_url = options[:base_url] || '..' - link_type = options[:link_type] || :show - case link_type.to_sym - when :show - UrlGenerator.new.make_page_link(mode, name, text, base_url, has_page?(name)) - when :file - UrlGenerator.new.make_file_link(mode, name, text, base_url, has_file?(name)) - when :pic - UrlGenerator.new.make_pic_link(mode, name, text, base_url, has_file?(name)) - else - raise "Unknown link type: #{link_type}" - end - end - def remove_pages(pages_to_be_removed) pages_to_be_removed.each { |p| p.destroy } end diff --git a/app/views/wiki/page.rhtml b/app/views/wiki/page.rhtml index 57c06927..432f688b 100644 --- a/app/views/wiki/page.rhtml +++ b/app/views/wiki/page.rhtml @@ -23,7 +23,7 @@
<%= @page.revisions? ? "Revised" : "Created" %> on <%= format_date(@page.revised_at) %> - by <%= @page.author_link %> + by <%= author_link(@page) %> <%= "(#{@page.author.ip})" if @page.author.respond_to?(:ip) %> <% if @web.count_pages? %> <% total_chars = @page.content.length %> diff --git a/app/views/wiki/print.rhtml b/app/views/wiki/print.rhtml index 3bc191a8..177e92f1 100644 --- a/app/views/wiki/print.rhtml +++ b/app/views/wiki/print.rhtml @@ -10,5 +10,5 @@ diff --git a/lib/page_renderer.rb b/lib/page_renderer.rb index e516b2cf..db10730a 100644 --- a/lib/page_renderer.rb +++ b/lib/page_renderer.rb @@ -4,8 +4,17 @@ require 'diff' class PageRenderer + def self.setup_url_generator(url_generator) + @@url_generator = url_generator + end + + def self.teardown_url_generator + @@url_generator = nil + end + attr_accessor :revision + def initialize(revision = nil) @revision = revision end @@ -53,7 +62,7 @@ class PageRenderer # Ensures new version works with older snapshots. def display_content unless @display_cache && @display_cache.respond_to?(:chunks_by_type) - @display_cache = WikiContent.new(@revision) + @display_cache = WikiContent.new(@revision, @@url_generator) @display_cache.render! end @display_cache @@ -76,28 +85,28 @@ class PageRenderer def display_published unless @published_cache && @published_cache.respond_to?(:chunks_by_type) - @published_cache = WikiContent.new(@revision, {:mode => :publish}) + @published_cache = WikiContent.new(@revision, @@url_generator, {:mode => :publish}) @published_cache.render! end @published_cache end def display_content_for_export - WikiContent.new(@revision, {:mode => :export} ).render! + WikiContent.new(@revision, @@url_generator, {:mode => :export} ).render! end def force_rendering begin display_content.render! rescue => e - logger.error "Failed rendering page #{@name}" - logger.error e + ActionController::Base.logger.error "Failed rendering page #{@name}" + ActionController::Base.logger.error e message = e.message # substitute content with an error message @revision.content = <<-EOL

Markup engine has failed to render this page, raising the following error:

#{message}

-
#{self.content}
+
#{@revision.content}
EOL clear_display_cache raise e diff --git a/lib/url_generator.rb b/lib/url_generator.rb index 4fd1ff93..fcc08312 100644 --- a/lib/url_generator.rb +++ b/lib/url_generator.rb @@ -1,61 +1,121 @@ -class UrlGenerator +class AbstractUrlGenerator - def initialize(controller = nil) - @controller = controller or ControllerStub.new + def initialize(controller) + raise 'Controller cannot be nil' if controller.nil? + @controller = controller end - def make_file_link(mode, name, text, base_url, known_file) - link = CGI.escape(name) + # Create a link for the given page (or file) name and link text based + # on the render mode in options and whether the page (file) exists + # in the web. + def make_link(name, web, text = nil, options = {}) + text = CGI.escapeHTML(text || WikiWords.separate(name)) + mode = (options[:mode] || :show).to_sym + link_type = (options[:link_type] || :show).to_sym + + if (link_type == :show) + known_page = web.has_page?(name) + else + known_page = web.has_file?(name) + end + + case link_type + when :show + page_link(mode, name, text, web.address, known_page) + when :file + file_link(mode, name, text, web.address, known_page) + when :pic + pic_link(mode, name, text, web.address, known_page) + else + raise "Unknown link type: #{link_type}" + end + end + +end + +class UrlGenerator < AbstractUrlGenerator + + private + + def file_link(mode, name, text, web_address, known_file) case mode when :export - if known_file then "#{text}" - else "#{text}" end - when :publish - if known_file then "#{text}" - else "#{text}" end - else if known_file - "#{text}" + %{#{text}} else - "#{text}?" + %{#{text}} + end + when :publish + if known_file + href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published', + :id => name + %{#{text}} + else + %{#{text}} + end + else + href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'file', + :id => name + if known_file + %{#{text}} + else + %{#{text}?} end end end - def make_page_link(mode, name, text, base_url, known_page) - link = CGI.escape(name) - case mode.to_sym + def page_link(mode, name, text, web_address, known_page) + case mode when :export - if known_page then %{#{text}} - else %{#{text}} end + if known_page + %{#{text}} + else + %{#{text}} + end when :publish - if known_page then %{#{text}} - else %{#{text}} end + if known_page + href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published', + :id => name + %{#{text}} + else + %{#{text}} + end else if known_page - %{#{text}} + href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'show', + :id => name + %{#{text}} else - %{#{text}?} + href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'new', + :id => name + %{#{text}?} end end end - def make_pic_link(mode, name, text, base_url, known_pic) - link = CGI.escape(name) - case mode.to_sym + def pic_link(mode, name, text, web_address, known_pic) + case mode when :export - if known_pic then %{#{text}} - else %{#{text}} end + if known_pic + %{#{text}} + else + %{#{text}} + end when :publish - if known_pic then %{#{text}} - else %{#{text}} end + if known_pic + %{#{text}} + else + %{#{text}} + end else - if known_pic then %{#{text}} - else %{#{text}?} end + href = @controller.url_for @controller => 'file', :web => web_address, :action => 'pic', + :id => name + if known_pic + %{#{text}} + else + %{#{text}?} + end end end end - -class ControllerStub -end \ No newline at end of file diff --git a/lib/wiki_content.rb b/lib/wiki_content.rb index 6fcc4a85..85816aba 100644 --- a/lib/wiki_content.rb +++ b/lib/wiki_content.rb @@ -126,8 +126,9 @@ class WikiContent < String # Create a new wiki content string from the given one. # The options are explained at the top of this file. - def initialize(revision, options = {}) + def initialize(revision, url_generator, options = {}) @revision = revision + @url_generator = url_generator @web = @revision.page.web @options = DEFAULT_OPTS.dup.merge(options) @@ -146,7 +147,7 @@ class WikiContent < String # Call @web.page_link using current options. def page_link(name, text, link_type) @options[:link_type] = (link_type || :show) - @web.make_link(name, text, @options) + @url_generator.make_link(name, @web, text, @options) end def build_chunks diff --git a/test/test_helper.rb b/test/test_helper.rb index f310732a..928c2e49 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,6 +11,7 @@ require 'action_controller/test_process' require 'action_web_service/test_invoke' require 'breakpoint' require 'wiki_content' +require 'url_generator' # Uncomment these and hang on, because the tests will be FAST #Test::Unit::TestCase.pre_loaded_fixtures = false @@ -43,6 +44,7 @@ class Test::Unit::TestCase end def test_renderer(revision = nil) + PageRenderer.setup_url_generator(StubUrlGenerator.new) PageRenderer.new(revision) end @@ -93,6 +95,64 @@ module ChunkMatch end end +class StubUrlGenerator < AbstractUrlGenerator + + def initialize + super(:doesnt_need_controller) + end + + def file_link(mode, name, text, web_name, known_file) + link = CGI.escape(name) + case mode + when :export + if known_file then %{#{text}} + else %{#{text}} end + when :publish + if known_file then %{#{text}} + else %{#{text}} end + else + if known_file + %{#{text}} + else + %{#{text}?} + end + end + end + + def page_link(mode, name, text, web_address, known_page) + link = CGI.escape(name) + case mode.to_sym + when :export + if known_page then %{#{text}} + else %{#{text}} end + when :publish + if known_page then %{#{text}} + else %{#{text}} end + else + if known_page + %{#{text}} + else + %{#{text}?} + end + end + end + + def pic_link(mode, name, text, web_name, known_pic) + link = CGI.escape(name) + case mode.to_sym + when :export + if known_pic then %{#{text}} + else %{#{text}} end + when :publish + if known_pic then %{#{text}} + else %{#{text}} end + else + if known_pic then %{#{text}} + else %{#{text}?} end + end + end +end + if defined? $validate_xml_in_assert_success and $validate_xml_in_assert_success == true module Test module Unit diff --git a/test/unit/page_renderer_test.rb b/test/unit/page_renderer_test.rb index b94212fb..d84a74ff 100644 --- a/test/unit/page_renderer_test.rb +++ b/test/unit/page_renderer_test.rb @@ -25,50 +25,6 @@ class PageRendererTest < Test::Unit::TestCase rendered_content(@web.page("SecondPage"))) end - def test_make_link - add_sample_pages - - existing_page_wiki_url = - 'Ever Been In Love' - existing_page_published_url = - 'Ever Been In Love' - existing_page_static_url = - 'Ever Been In Love' - new_page_wiki_url = - 'Unknown Word?' - new_page_published_url = new_page_static_url = 'Unknown Word' - - # no options - assert_equal existing_page_wiki_url, @web.make_link('EverBeenInLove') - - # :mode => :export - assert_equal existing_page_static_url, @web.make_link('EverBeenInLove', nil, :mode => :export) - - # :mode => :publish - assert_equal existing_page_published_url, - @web.make_link('EverBeenInLove', nil, :mode => :publish) - - # new page, no options - assert_equal new_page_wiki_url, @web.make_link('UnknownWord') - - # new page, :mode => :export - assert_equal new_page_static_url, @web.make_link('UnknownWord', nil, :mode => :export) - - # new page, :mode => :publish - assert_equal new_page_published_url, @web.make_link('UnknownWord', nil, :mode => :publish) - - # Escaping special characters in the name - assert_equal( - 'Smith & Wesson?', - @web.make_link('Smith & Wesson')) - - # optionally using text as the link text - assert_equal( - existing_page_published_url.sub(/>Ever Been In LoveHaven't you ever been in love?<"), - @web.make_link('EverBeenInLove', "Haven't you ever been in love?", :mode => :publish)) - - end - def test_wiki_words assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ), test_renderer(@revision).wiki_words.sort diff --git a/test/watir/e2e.rb b/test/watir/e2e.rb index cdf81554..4aeaf109 100644 --- a/test/watir/e2e.rb +++ b/test/watir/e2e.rb @@ -59,7 +59,7 @@ class E2EInstikiTest < Test::Unit::TestCase def test_00020_add_a_page # Add reference to a non-existant wiki page enter_markup('HomePage', '[[Another Wiki Page]]') - assert_equal '?', ie.link(:url, url(:show, 'Another Wiki Page')).text + assert_equal '?', ie.link(:url, url(:new, 'Another Wiki Page')).text # Edit the first revision of a page enter_markup('Another Wiki Page', 'First revision of Another Wiki Page, linked from HomePage')