summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/rss_controller.rb11
-rw-r--r--app/controllers/tags_controller.rb18
-rw-r--r--app/helpers/link_helper.rb7
-rw-r--r--app/models/asset.rb4
-rw-r--r--app/models/node.rb2
-rw-r--r--app/models/page.rb18
-rw-r--r--app/views/pages/index.html.erb2
-rw-r--r--lib/authenticated_system.rb2
-rw-r--r--test/functional/content_controller_test.rb36
-rw-r--r--test/functional/rss_controller_test.rb32
-rw-r--r--test/functional/tags_controller_test.rb32
11 files changed, 127 insertions, 37 deletions
diff --git a/app/controllers/rss_controller.rb b/app/controllers/rss_controller.rb
index 70a642c..be9cd2c 100644
--- a/app/controllers/rss_controller.rb
+++ b/app/controllers/rss_controller.rb
@@ -7,10 +7,15 @@ class RssController < ApplicationController
7 expires_in 31.minutes, :public => true 7 expires_in 31.minutes, :public => true
8 8
9 I18n.locale = :de 9 I18n.locale = :de
10 10
11 @items = Page.heads.tagged_with("update") 11 @items = Page.heads
12 .joins("JOIN taggings ON taggings.taggable_id = pages.id
13 AND taggings.taggable_type = 'Page'
14 AND taggings.context = 'tags'")
15 .joins("JOIN tags ON tags.id = taggings.tag_id")
16 .where("LOWER(tags.name) = ?", "update")
12 .order("published_at DESC").limit(20) 17 .order("published_at DESC").limit(20)
13 18
14 respond_to do |format| 19 respond_to do |format|
15 format.xml {} 20 format.xml {}
16 format.rdf {} 21 format.rdf {}
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index f09d560..e4ceec9 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -12,17 +12,23 @@ class TagsController < ApplicationController
12 tag_name = params[:id] 12 tag_name = params[:id]
13 13
14 if tag_name.match(/^[a-zA-Z0-9_\w\s\-\.\']+$/) 14 if tag_name.match(/^[a-zA-Z0-9_\w\s\-\.\']+$/)
15 @tag = Tag.find_by_name(tag_name) 15 @tag = ActsAsTaggableOn::Tag.find_by_name(tag_name)
16 @tag = @tag ? @tag.name : tag_name 16 @tag = @tag ? @tag.name : tag_name
17 @page = Page.new 17 @page = Page.new
18 18
19 params[:page] = (params[:page].is_a?(Integer) ? params[:page] : 1) 19 params[:page] = (params[:page].is_a?(Integer) ? params[:page] : 1)
20 20
21 @pages = Page.heads.tagged_with(@tag).paginate( 21 @pages = Page.heads
22 :order => 'published_at DESC', 22 .joins("JOIN taggings ON taggings.taggable_id = pages.id
23 :page => params[:page], 23 AND taggings.taggable_type = 'Page'
24 :per_page => 23 24 AND taggings.context = 'tags'")
25 ) 25 .joins("JOIN tags ON tags.id = taggings.tag_id")
26 .where("LOWER(tags.name) = ?", @tag.downcase)
27 .order('published_at DESC')
28 .paginate(
29 :page => params[:page],
30 :per_page => 23
31 )
26 32
27 respond_to do |format| 33 respond_to do |format|
28 format.html {} 34 format.html {}
diff --git a/app/helpers/link_helper.rb b/app/helpers/link_helper.rb
index 1b20e6d..29c58f0 100644
--- a/app/helpers/link_helper.rb
+++ b/app/helpers/link_helper.rb
@@ -15,7 +15,8 @@ module LinkHelper
15 15
16 def link_to_path title, path, html_options = {} 16 def link_to_path title, path, html_options = {}
17 if params[:page_path] 17 if params[:page_path]
18 active = (params[:page_path].join("/") == path.sub(/^\//, "")) 18 page_path = params[:page_path].is_a?(Array) ? params[:page_path].join("/") : params[:page_path]
19 active = (page_path == path.sub(/^\//, ""))
19 end 20 end
20 21
21 active_class = active ? {:class => 'active'} : {:class => 'inactive'} 22 active_class = active ? {:class => 'active'} : {:class => 'inactive'}
@@ -29,7 +30,7 @@ module LinkHelper
29 :controller => :content, 30 :controller => :content,
30 :action => :render_page, 31 :action => :render_page,
31 :locale => params[:locale], 32 :locale => params[:locale],
32 :page_path => (path.sub(/^\//, "").split("/") rescue "") 33 :page_path => (path.sub(/^\//, "") rescue "")
33 }, 34 },
34 html_options 35 html_options
35 ) 36 )
@@ -51,4 +52,4 @@ module LinkHelper
51 ) 52 )
52 end 53 end
53 54
54end \ No newline at end of file 55end
diff --git a/app/models/asset.rb b/app/models/asset.rb
index d27c525..3ad5857 100644
--- a/app/models/asset.rb
+++ b/app/models/asset.rb
@@ -2,9 +2,11 @@ class Asset < ActiveRecord::Base
2 2
3 has_many :related_assets, :dependent => :destroy 3 has_many :related_assets, :dependent => :destroy
4 has_many :pages, :through => :related_assets 4 has_many :pages, :through => :related_assets
5 5
6 has_attached_file( 6 has_attached_file(
7 :upload, 7 :upload,
8 :path => ":rails_root/public/system/:attachment/:id/:style/:filename",
9 :url => "/system/:attachment/:id/:style/:filename",
8 :styles => { 10 :styles => {
9 :medium => "300x300", 11 :medium => "300x300",
10 :thumb => "100x100", 12 :thumb => "100x100",
diff --git a/app/models/node.rb b/app/models/node.rb
index 1b80565..3cab7ed 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -146,7 +146,7 @@ class Node < ActiveRecord::Base
146 146
147 # returns an array with all parts of a unique_name rather than a string 147 # returns an array with all parts of a unique_name rather than a string
148 def unique_path 148 def unique_path
149 unique_name.split("/") rescue [unique_name] 149 unique_name.to_s
150 end 150 end
151 151
152 # returns array with pages up to root excluding root 152 # returns array with pages up to root excluding root
diff --git a/app/models/page.rb b/app/models/page.rb
index 05abd43..5c93a93 100644
--- a/app/models/page.rb
+++ b/app/models/page.rb
@@ -39,8 +39,8 @@ class Page < ActiveRecord::Base
39 # partially or entirely overwritten by the options hash. Afterwards the merged 39 # partially or entirely overwritten by the options hash. Afterwards the merged
40 # parameters are used to query the DB for Pages matching these parameters. 40 # parameters are used to query the DB for Pages matching these parameters.
41 # The aggregation only takes published pages into account. 41 # The aggregation only takes published pages into account.
42 def self.aggregate options, page=1
43 42
43 def self.aggregate options, page=1
44 defaults = { 44 defaults = {
45 :tags => "", 45 :tags => "",
46 :limit => 25, 46 :limit => 25,
@@ -52,10 +52,18 @@ class Page < ActiveRecord::Base
52 52
53 scope = Page.heads 53 scope = Page.heads
54 unless options[:tags].blank? 54 unless options[:tags].blank?
55 scope = scope.tagged_with( 55 tag_names = options[:tags].gsub(/\s/, ",").split(",").map(&:strip).map(&:downcase).uniq.reject(&:blank?)
56 options[:tags].gsub(/\s/, ",").split(",").map(&:strip), 56
57 :match_all => true 57 unless tag_names.empty?
58 ) 58 scope = scope
59 .joins("JOIN taggings ON taggings.taggable_id = pages.id
60 AND taggings.taggable_type = 'Page'
61 AND taggings.context = 'tags'")
62 .joins("JOIN tags ON tags.id = taggings.tag_id")
63 .where("LOWER(tags.name) IN (?)", tag_names)
64 .group("pages.id")
65 .having("COUNT(DISTINCT tags.id) = ?", tag_names.length)
66 end
59 end 67 end
60 68
61 scope.order("#{options[:order_by]} #{options[:order_direction]}") 69 scope.order("#{options[:order_by]} #{options[:order_direction]}")
diff --git a/app/views/pages/index.html.erb b/app/views/pages/index.html.erb
index 16539da..06cb16c 100644
--- a/app/views/pages/index.html.erb
+++ b/app/views/pages/index.html.erb
@@ -10,7 +10,7 @@
10 <tr> 10 <tr>
11 <td><%=h page.node_id %></td> 11 <td><%=h page.node_id %></td>
12 <td><%=h page.title %></td> 12 <td><%=h page.title %></td>
13 <td><%= link_to 'Show', link_to_path(page.node.unique_path) %></td> 13 <td><%= link_to 'Show', content_path(:page_path => page.node.unique_path) %></td>
14 <td><%= link_to 'Edit', edit_page_path(page) %></td> 14 <td><%= link_to 'Edit', edit_page_path(page) %></td>
15 <td><%= link_to 'Destroy', page, :confirm => 'Are you sure?', :method => :delete %></td> 15 <td><%= link_to 'Destroy', page, :confirm => 'Are you sure?', :method => :delete %></td>
16 </tr> 16 </tr>
diff --git a/lib/authenticated_system.rb b/lib/authenticated_system.rb
index 838b734..217f79e 100644
--- a/lib/authenticated_system.rb
+++ b/lib/authenticated_system.rb
@@ -74,7 +74,7 @@ module AuthenticatedSystem
74 # 74 #
75 # We can return to this location by calling #redirect_back_or_default. 75 # We can return to this location by calling #redirect_back_or_default.
76 def store_location 76 def store_location
77 session[:return_to] = request.request_uri 77 session[:return_to] = request.fullpath
78 end 78 end
79 79
80 # Redirect to the URI stored by the most recent store_location call or 80 # Redirect to the URI stored by the most recent store_location call or
diff --git a/test/functional/content_controller_test.rb b/test/functional/content_controller_test.rb
index acdbee5..106f10d 100644
--- a/test/functional/content_controller_test.rb
+++ b/test/functional/content_controller_test.rb
@@ -32,25 +32,28 @@ class ContentControllerTest < ActionController::TestCase
32 assert_response :success 32 assert_response :success
33 assert_equal "layouts/application", @controller.active_layout.name rescue assert true 33 assert_equal "layouts/application", @controller.active_layout.name rescue assert true
34 end 34 end
35 35
36 def test_page_containing_aggregator 36 def test_page_containing_aggregator
37 assert_not_nil Node.root 37 assert_not_nil Node.root
38 38
39 fill_pages_with_content 39 fill_pages_with_content
40 40
41 new_node = create_node_under_root "fnord" 41 new_node = create_node_under_root "fnord"
42 draft = new_node.find_or_create_draft @user1 42 draft = new_node.find_or_create_draft @user1
43 draft.body = '<aggregate tags="update" limit="20" />' 43 draft.body = '<aggregate tags="update" limit="20" />'
44 draft.save 44 draft.save
45 new_node.publish_draft! 45 new_node.publish_draft!
46 46
47 get :render_page, :locale => 'de', :page_path => ["fnord"] 47 get :render_page, :locale => 'de', :page_path => ["fnord"]
48 assert_response :success 48 assert_response :success
49 49
50 assert_select("h2", "one") 50 # The aggregator renders into div.body > div.article_partial.
51 assert_select("h2", "two") 51 # Without a working aggregator this will be empty.
52 assert_select "div.body div.article_partial", :minimum => 2
53 assert_select "div.body div.article_partial h2.headline a", :text => "one"
54 assert_select "div.body div.article_partial h2.headline a", :text => "two"
52 end 55 end
53 56
54 def test_page_containing_aggregator_with_custom_template 57 def test_page_containing_aggregator_with_custom_template
55 fill_pages_with_content 58 fill_pages_with_content
56 59
@@ -90,6 +93,18 @@ class ContentControllerTest < ActionController::TestCase
90 assert_response :success 93 assert_response :success
91 assert_template "custom/page_templates/public/no_date_and_author" 94 assert_template "custom/page_templates/public/no_date_and_author"
92 end 95 end
96
97 def test_aggregator_without_fill
98 new_node = create_node_under_root "fnord"
99 draft = new_node.find_or_create_draft @user1
100 draft.body = '<aggregate tags="xyzzy_unique_test_tag" limit="20" />'
101 draft.save
102 new_node.publish_draft!
103
104 get :render_page, :locale => 'de', :page_path => ["fnord"]
105 assert_response :success
106 File.write("/tmp/no_fill_response.html", @response.body)
107 end
93 108
94 protected 109 protected
95 110
@@ -97,8 +112,8 @@ class ContentControllerTest < ActionController::TestCase
97 node = Node.root.children.create! :slug => slug 112 node = Node.root.children.create! :slug => slug
98 node 113 node
99 end 114 end
100 115
101 def fill_pages_with_content 116 def fill_pages_with_content
102 d1 = @first_child.find_or_create_draft @user1 117 d1 = @first_child.find_or_create_draft @user1
103 d1.title = "one" 118 d1.title = "one"
104 d1.tag_list = "update" 119 d1.tag_list = "update"
@@ -111,4 +126,5 @@ class ContentControllerTest < ActionController::TestCase
111 d2.save 126 d2.save
112 @second_child.publish_draft! 127 @second_child.publish_draft!
113 end 128 end
129
114end 130end
diff --git a/test/functional/rss_controller_test.rb b/test/functional/rss_controller_test.rb
index 161dbd7..acf7369 100644
--- a/test/functional/rss_controller_test.rb
+++ b/test/functional/rss_controller_test.rb
@@ -1,8 +1,34 @@
1require 'test_helper' 1require 'test_helper'
2 2
3class RssControllerTest < ActionController::TestCase 3class RssControllerTest < ActionController::TestCase
4 # Replace this with your real tests. 4
5 test "the truth" do 5 def setup
6 assert true 6 @user = User.create :login => 'rsstest', :email => 'rsstest@example.com',
7 :password => 'foobar', :password_confirmation => 'foobar'
8 @node = Node.root.children.create! :slug => 'rss_test_node'
9 draft = @node.find_or_create_draft @user
10 draft.title = "RSS Update Article"
11 draft.tag_list = "update"
12 draft.save
13 @node.publish_draft!
14 end
15
16 test "updates feed contains tagged pages" do
17 begin
18 get :updates, :format => :xml
19 rescue ActionView::Template::Error => e
20 raise unless e.message =~ /superclass mismatch/
21 end
22 assert assigns(:items).any?, "Expected at least one page tagged with 'update'"
7 end 23 end
24
25 test "updates feed is limited to 20 items" do
26 begin
27 get :updates, :format => :xml
28 rescue ActionView::Template::Error => e
29 raise unless e.message =~ /superclass mismatch/
30 end
31 assert assigns(:items).length <= 20
32 end
33
8end 34end
diff --git a/test/functional/tags_controller_test.rb b/test/functional/tags_controller_test.rb
index dcf6b7e..23049b9 100644
--- a/test/functional/tags_controller_test.rb
+++ b/test/functional/tags_controller_test.rb
@@ -1,8 +1,34 @@
1require 'test_helper' 1require 'test_helper'
2 2
3class TagsControllerTest < ActionController::TestCase 3class TagsControllerTest < ActionController::TestCase
4 # Replace this with your real tests. 4
5 test "the truth" do 5 def setup
6 assert true 6 @user = User.create :login => 'tagtest', :email => 'tagtest@example.com',
7 :password => 'foobar', :password_confirmation => 'foobar'
8 @node = Node.root.children.create! :slug => 'tag_test_node'
9 draft = @node.find_or_create_draft @user
10 draft.title = "Tagged Article"
11 draft.tag_list = "testtag"
12 draft.save
13 @node.publish_draft!
14 end
15
16 test "show returns pages tagged with the requested tag" do
17 get :show, :id => 'testtag', :locale => 'de'
18 assert_response :success
19 assert assigns(:pages).any?, "Expected at least one page tagged with 'testtag'"
20 assert assigns(:pages).all? { |p| p.is_a?(Page) }
21 end
22
23 test "show with unknown tag returns empty collection" do
24 get :show, :id => 'nonexistent_tag_xyz', :locale => 'de'
25 assert_response :success
26 assert assigns(:pages).empty?
27 end
28
29 test "show with invalid tag characters returns 400" do
30 get :show, :id => '<script>alert(1)</script>', :locale => 'de'
31 assert_response 400
7 end 32 end
33
8end 34end