Commit 1bbebba9a9451135d0421c4dfcf958447373059e

Authored by AntonioTerceiro
1 parent 02ec23ee

ActionItem485: listing upcoming events

plus filtering events by month and year in calendar view

git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@2166 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/public/search_controller.rb
... ... @@ -89,24 +89,28 @@ class SearchController < ApplicationController
89 89 def load_product_categories_menu(asset)
90 90 @results[asset].uniq!
91 91 @categories_menu = ProductCategory.menu_categories(@product_category, environment).map do |cat|
92   - hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, cat, @region, params[:radius]))
  92 + hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, cat, @region, params[:radius], nil, nil))
93 93 childs = []
94 94 # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop
95 95 childs = cat.children.map do |child|
96   - child_hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, child, @region, params[:radius]))
  96 + child_hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, child, @region, params[:radius], nil, nil))
97 97 [child, child_hits]
98 98 end.select{|child, child_hits| child_hits > 0 }
99 99 [cat, hits, childs]
100 100 end.select{|cat, hits| hits > 0 }
101 101 end
102 102  
103   - def calculate_find_options(asset, limit, page, product_category, region, radius)
  103 + def calculate_find_options(asset, limit, page, product_category, region, radius, year, month)
104 104  
105 105 result = { :product_category => product_category, :per_page => limit, :page => page }
106 106 if [:enterprises, :people].include?(asset) && region
107 107 result.merge!(:within => radius, :region => region.id)
108 108 end
109 109  
  110 + if month || year
  111 + result[:date_range] = Event.date_range(year, month)
  112 + end
  113 +
110 114 result
111 115 end
112 116  
... ... @@ -154,7 +158,7 @@ class SearchController < ApplicationController
154 158  
155 159 SEARCH_IN.select { |key,description| @searching[key] }.each do |key, description|
156 160 @order << key
157   - @results[key] = @finder.find(key, @filtered_query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius]))
  161 + @results[key] = @finder.find(key, @filtered_query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius], params[:year], params[:month]))
158 162 @names[key] = gettext(description)
159 163 end
160 164  
... ... @@ -184,7 +188,7 @@ class SearchController &lt; ApplicationController
184 188 [ :people, _('Newer people'), @finder.recent('people', limit) ],
185 189 [ :enterprises, _('Newer enterprises'), @finder.recent('enterprises', limit) ],
186 190 [ :products, ('Newer products'), @finder.recent('products', limit) ],
187   - [ :events, _('Near events TODO'), @finder.current_events(params[:year], params[:month], {:per_page => limit}) ],
  191 + [ :events, _('Upcoming events'), @finder.upcoming_events({:per_page => limit}) ],
188 192 [ :communities, _('Newer communities'), @finder.recent('communities', limit) ],
189 193 [ :articles, _('Newer articles'), @finder.recent('articles', limit) ],
190 194 [ :most_commented_articles, _('Most commented articles'), @finder.most_commented_articles(limit) ]
... ...
app/models/category_finder.rb
... ... @@ -15,12 +15,14 @@ class CategoryFinder
15 15 options.delete(:within)
16 16 end
17 17  
  18 + date_range = options.delete(:date_range)
  19 +
18 20 options = {:page => 1, :per_page => options.delete(:limit)}.merge(options)
19 21 if query.blank?
20   - asset_class(asset).paginate(:all, options_for_find(asset_class(asset), {:order => "created_at desc, #{asset_table(asset)}.id desc"}.merge(options)))
  22 + asset_class(asset).paginate(:all, options_for_find(asset_class(asset), {:order => "created_at desc, #{asset_table(asset)}.id desc"}.merge(options), date_range))
21 23 else
22 24 ferret_options = {:page => options.delete(:page), :per_page => options.delete(:per_page)}
23   - asset_class(asset).find_by_contents(query, ferret_options, options_for_find(asset_class(asset), options))
  25 + asset_class(asset).find_by_contents(query, ferret_options, options_for_find(asset_class(asset), options, date_range))
24 26 end
25 27 end
26 28  
... ... @@ -46,9 +48,15 @@ class CategoryFinder
46 48 Event.paginate(:all, {:include => :categories, :conditions => { 'categories.id' => category_id, :start_date => range }}.merge(options))
47 49 end
48 50  
  51 + def upcoming_events(options = {})
  52 + options = { :page => 1}.merge(options)
  53 +
  54 + Event.paginate(:all, {:include => :categories, :conditions => [ 'categories.id = ? and start_date >= ?', category_id, Date.today ], :order => :start_date }.merge(options))
  55 + end
  56 +
49 57 protected
50 58  
51   - def options_for_find(klass, options={})
  59 + def options_for_find(klass, options={}, date_range = nil)
52 60 if defined? options[:product_category]
53 61 prod_cat = options.delete(:product_category)
54 62 # FIXME this is SLOOOOW
... ... @@ -64,8 +72,16 @@ class CategoryFinder
64 72 else
65 73 {:joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id = (?)', category_id]}.merge!(options)
66 74 end
67   - when 'Article', 'Event'
  75 + when 'Article'
68 76 {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => ['articles_categories.category_id = (?)', category_id]}.merge!(options)
  77 + when 'Event'
  78 + conditions =
  79 + if date_range
  80 + ['articles_categories.category_id = (?) and start_date between ? and ?', category_id, date_range.first, date_range.last]
  81 + else
  82 + ['articles_categories.category_id = (?) ', category_id ]
  83 + end
  84 + {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => conditions}.merge!(options)
69 85 when 'Enterprise'
70 86 if prod_cat_ids
71 87 {:joins => 'inner join categories_profiles on (categories_profiles.profile_id = profiles.id) inner join products on (products.enterprise_id = profiles.id)', :conditions => ['categories_profiles.category_id = (?) and products.product_category_id in (?)', category_id, prod_cat_ids]}.merge!(options)
... ...
app/models/environment_finder.rb
... ... @@ -15,6 +15,8 @@ class EnvironmentFinder
15 15 product_category = options.delete(:product_category)
16 16 product_category_ids = product_category.map_traversal(&:id) if product_category
17 17  
  18 + date_range = options.delete(:date_range)
  19 +
18 20 options = {:page => 1, :per_page => options.delete(:limit)}.merge(options)
19 21 if query.blank?
20 22 options = {:order => 'created_at desc, id desc'}.merge(options)
... ... @@ -23,7 +25,11 @@ class EnvironmentFinder
23 25 elsif product_category && asset == :enterprises
24 26 @environment.send(asset).paginate(:all, options.merge(:order => 'profiles.created_at desc, profiles.id desc', :include => 'products', :conditions => ['products.product_category_id in (?)', product_category_ids]))
25 27 else
26   - @environment.send(asset).paginate(:all, options)
  28 + if (asset == :events) && date_range
  29 + @environment.send(asset).paginate(:all, options.merge(:conditions => { :start_date => date_range}))
  30 + else
  31 + @environment.send(asset).paginate(:all, options)
  32 + end
27 33 end
28 34 else
29 35 ferret_options = {:page => options.delete(:page), :per_page => options.delete(:per_page)}
... ...
test/functional/search_controller_test.rb
... ... @@ -647,6 +647,50 @@ class SearchControllerTest &lt; Test::Unit::TestCase
647 647 assert_not_includes assigns(:results)[:events], ev3
648 648 end
649 649  
  650 + should 'list events for a given month' do
  651 + person = create_user('testuser').person
  652 +
  653 + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25))
  654 + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27))
  655 +
  656 + get :assets, :asset => 'events', :year => '2008', :month => '1'
  657 +
  658 + assert_equal [ 'upcoming event 1' ], assigns(:results)[:events].map(&:name)
  659 + end
  660 +
  661 + should 'list events for a given month in a specific category' do
  662 + person = create_user('testuser').person
  663 +
  664 + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25))
  665 + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27))
  666 +
  667 + get :assets, :asset => 'events', :category_path => [ 'my-category' ], :year => '2008', :month => '1'
  668 +
  669 + assert_equal [ 'upcoming event 1' ], assigns(:results)[:events].map(&:name)
  670 + end
  671 +
  672 + should 'list upcoming events in a specific category' do
  673 + person = create_user('testuser').person
  674 +
  675 + # today is January 15th, 2008
  676 + Date.expects(:today).returns(Date.new(2008,1,15)).at_least_once
  677 +
  678 + # in category, but in the past
  679 + create_event(person, :name => 'past event', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 1))
  680 +
  681 + # in category, upcoming
  682 + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25))
  683 + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 27))
  684 +
  685 + # not in category
  686 + create_event(person, :name => 'event not in category')
  687 +
  688 + get :category_index, :category_path => ['my-category']
  689 +
  690 + assert_equal [ 'upcoming event 1', 'upcoming event 2' ], assigns(:results)[:events].map(&:name)
  691 + end
  692 +
  693 +
650 694 %w[ people enterprises articles events communities products ].each do |asset|
651 695 should "render asset-specific template when searching for #{asset}" do
652 696 get :index, :find_in => [ asset ]
... ...
test/unit/category_finder_test.rb
... ... @@ -290,6 +290,34 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
290 290 assert_respond_to events, :total_entries
291 291 end
292 292  
  293 + should 'list upcoming events' do
  294 + person = create_user('testuser').person
  295 +
  296 + Date.expects(:today).returns(Date.new(2008, 1, 15)).at_least_once
  297 +
  298 + past_event = Event.create!(:name => 'past event', :profile => person, :start_date => Date.new(2008,1,1), :category_ids => [@category.id])
  299 +
  300 + # event 2 is created after, but must be listed before (since it happens before)
  301 + upcoming_event_2 = Event.create!(:name => 'upcoming event 2', :profile => person, :start_date => Date.new(2008,1,25), :category_ids => [@category.id])
  302 + upcoming_event_1 = Event.create!(:name => 'upcoming event 1', :profile => person, :start_date => Date.new(2008,1,20), :category_ids => [@category.id])
  303 + not_in_category = Event.create!(:name => 'e1', :profile => person, :start_date => Date.new(2008,1,20))
  304 +
  305 + assert_equal [upcoming_event_1, upcoming_event_2], @finder.upcoming_events
  306 + end
  307 +
  308 + should 'limit events' do
  309 + person = create_user('testuser').person
  310 +
  311 + Date.expects(:today).returns(Date.new(2008, 1, 15)).at_least_once
  312 +
  313 + past_event = Event.create!(:name => 'past event', :profile => person, :start_date => Date.new(2008,1,1), :category_ids => [@category.id])
  314 + upcoming_event_1 = Event.create!(:name => 'upcoming event 1', :profile => person, :start_date => Date.new(2008,1,20), :category_ids => [@category.id])
  315 + upcoming_event_2 = Event.create!(:name => 'upcoming event 2', :profile => person, :start_date => Date.new(2008,1,25), :category_ids => [@category.id])
  316 + not_in_category = Event.create!(:name => 'e1', :profile => person, :start_date => Date.new(2008,1,20))
  317 +
  318 + assert_equal [upcoming_event_1], @finder.upcoming_events(:per_page => 1)
  319 + end
  320 +
293 321 should 'find person and enterprise in category by radius and region even without query' do
294 322 cat = Category.create!(:name => 'test category', :environment => Environment.default)
295 323 finder = CategoryFinder.new(cat)
... ...