Commit 4b48bec4b1b4be3a525c99a751b36303833a8708

Authored by Joenio Costa
Committed by Antonio Terceiro
1 parent 4182e506

Each community has its own agenda

 - New UI for calendar
 - New routes to /profile/:profile/events

(ActionItem1255)
app/controllers/public/events_controller.rb 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +class EventsController < PublicController
  2 +
  3 + needs_profile
  4 + no_design_blocks
  5 +
  6 + def events
  7 + @selected_day = nil
  8 + @events_of_the_day = []
  9 + date = build_date(params[:year], params[:month], params[:day])
  10 +
  11 + if params[:day] || !params[:year] && !params[:month]
  12 + @selected_day = date
  13 + @events_of_the_day = profile.events.by_day(@selected_day)
  14 + end
  15 +
  16 + events = profile.events.by_range(Event.first_day_of_month(date - 1.month)..Event.last_day_of_month(date + 1.month))
  17 +
  18 + @calendar = populate_calendar(date, events)
  19 + @previous_calendar = populate_calendar(date - 1.month, events)
  20 + @next_calendar = populate_calendar(date + 1.month, events)
  21 + end
  22 +
  23 + def events_by_day
  24 + @selected_day = build_date(params[:year], params[:month], params[:day])
  25 + @events_of_the_day = profile.events.by_day(@selected_day)
  26 + render :partial => 'events_by_day'
  27 + end
  28 +
  29 + protected
  30 +
  31 + include EventsHelper
  32 +
  33 +end
... ...
app/controllers/public/search_controller.rb
... ... @@ -43,30 +43,26 @@ class SearchController &lt; PublicController
43 43 end
44 44  
45 45 def events
46   - @events = @results[:events]
47   - @calendar = Event.date_range(params[:year], params[:month]).map do |date|
48   - [
49   - # the day itself
50   - date,
51   - # list of events of that day
52   - @events.select do |event|
53   - event.date_range.include?(date)
54   - end,
55   - # is this date in the current month?
56   - true
57   - ]
58   - end
59   -
60   - # pad with days before
61   - while @calendar.first.first.wday != 0
62   - @calendar.unshift([@calendar.first.first - 1.day, [], false])
  46 + @category_id = @category ? @category.id : nil
  47 +
  48 + @selected_day = nil
  49 + @events_of_the_day = []
  50 + date = build_date(params[:year], params[:month], params[:day])
  51 +
  52 + if params[:day] || !params[:year] && !params[:month]
  53 + @selected_day = date
  54 + if @category_id and Category.exists?(@category_id)
  55 + @events_of_the_day = environment.events.by_day(@selected_day).in_category(Category.find(@category_id))
  56 + else
  57 + @events_of_the_day = environment.events.by_day(@selected_day)
  58 + end
63 59 end
64 60  
65   - # pad with days after (until Saturday)
66   - while @calendar.last.first.wday != 6
67   - @calendar << [@calendar.last.first + 1.day, [], false]
68   - end
  61 + events = @results[:events]
69 62  
  63 + @calendar = populate_calendar(date, events)
  64 + @previous_calendar = populate_calendar(date - 1.month, events)
  65 + @next_calendar = populate_calendar(date + 1.month, events)
70 66 end
71 67  
72 68 def people
... ... @@ -105,7 +101,8 @@ class SearchController &lt; PublicController
105 101 end
106 102  
107 103 if month || year
108   - result[:date_range] = Event.date_range(year, month)
  104 + date = Date.new(year.to_i, month.to_i, 1)
  105 + result[:date_range] = (date - 1.month)..Event.last_day_of_month(date + 1.month)
109 106 end
110 107  
111 108 result
... ... @@ -240,4 +237,14 @@ class SearchController &lt; PublicController
240 237 render :action => 'popup', :layout => false
241 238 end
242 239  
  240 + def events_by_day
  241 + @selected_day = build_date(params[:year], params[:month], params[:day])
  242 + if params[:category_id] and Category.exists?(params[:category_id])
  243 + @events_of_the_day = environment.events.by_day(@selected_day).in_category(Category.find(params[:category_id]))
  244 + else
  245 + @events_of_the_day = environment.events.by_day(@selected_day)
  246 + end
  247 + render :partial => 'events/events_by_day'
  248 + end
  249 +
243 250 end
... ...
app/helpers/application_helper.rb
... ... @@ -908,4 +908,8 @@ module ApplicationHelper
908 908 javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")')
909 909 end
910 910  
  911 + def stylesheet(*args)
  912 + content_for(:head) { stylesheet_link_tag(*args) }
  913 + end
  914 +
911 915 end
... ...
app/helpers/dates_helper.rb
... ... @@ -2,6 +2,7 @@ module DatesHelper
2 2  
3 3 include GetText
4 4  
  5 + # FIXME Date#strftime should translate this for us !!!!
5 6 MONTHS = [
6 7 N_('January'),
7 8 N_('February'),
... ... @@ -49,43 +50,66 @@ module DatesHelper
49 50 end
50 51 end
51 52  
52   - def show_day_of_week(date)
53   - # FIXME Date#strftime should translate this for us !!!!
54   - _([
55   - N_('Sunday'),
56   - N_('Monday'),
57   - N_('Tuesday'),
58   - N_('Wednesday'),
59   - N_('Thursday'),
60   - N_('Friday'),
61   - N_('Saturday'),
62   - ][date.wday])
  53 + def show_day_of_week(date, abbreviated = false)
  54 + # FIXME Date#strftime should translate this for us !!!!
  55 + N_('Sun'); N_('Mon'); N_('Tue'); N_('Wed'); N_('Thu'); N_('Fri'); N_('Sat');
  56 + if abbreviated
  57 + _(date.strftime("%a"))
  58 + else
  59 + # FIXME Date#strftime should translate this for us !!!!
  60 + _([
  61 + N_('Sunday'),
  62 + N_('Monday'),
  63 + N_('Tuesday'),
  64 + N_('Wednesday'),
  65 + N_('Thursday'),
  66 + N_('Friday'),
  67 + N_('Saturday'),
  68 + ][date.wday])
  69 + end
63 70 end
64 71  
65   - def show_month(year, month)
66   -
67   - if year.blank?
68   - year = Date.today.year
69   - end
70   - if month.blank?
71   - month = Date.today.month
  72 + def show_month(year, month, opts = {})
  73 + date = build_date(year, month)
  74 + if opts[:next]
  75 + date = date >> 1
  76 + elsif opts[:previous]
  77 + date = date << 1
72 78 end
  79 + _('%{month} %{year}') % { :year => date.year, :month => month_name(date.month.to_i) }
  80 + end
73 81  
74   - _('%{month} %{year}') % { :year => year, :month => month_name(month.to_i) }
  82 + def build_date(year, month, day = 1)
  83 + if year.blank? and month.blank? and day.blank?
  84 + Date.today
  85 + else
  86 + if year.blank?
  87 + year = Date.today.year
  88 + end
  89 + if month.blank?
  90 + month = Date.today.month
  91 + end
  92 + if day.blank?
  93 + day = 1
  94 + end
  95 + Date.new(year.to_i, month.to_i, day.to_i)
  96 + end
75 97 end
76 98  
77   - def link_to_previous_month(year, month)
78   - date = (year.blank? || month.blank?) ? Date.today : Date.new(year.to_i, month.to_i, 1)
  99 + def link_to_previous_month(year, month, label = nil)
  100 + date = build_date(year, month)
79 101 previous_month_date = date - 1.month
80 102  
81   - link_to '&larr; ' + show_month(previous_month_date.year, previous_month_date.month), :year => previous_month_date.year, :month => previous_month_date.month
  103 + label ||= show_month(previous_month_date.year, previous_month_date.month)
  104 + link_to label, :year => previous_month_date.year, :month => previous_month_date.month
82 105 end
83 106  
84   - def link_to_next_month(year, month)
85   - date = (year.blank? || month.blank?) ? Date.today : Date.new(year.to_i, month.to_i, 1)
  107 + def link_to_next_month(year, month, label = nil)
  108 + date = build_date(year, month)
86 109 next_month_date = date + 1.month
87 110  
88   - link_to show_month(next_month_date.year, next_month_date.month) + ' &rarr;', :year => next_month_date.year, :month => next_month_date.month
  111 + label ||= show_month(next_month_date.year, next_month_date.month)
  112 + link_to label, :year => next_month_date.year, :month => next_month_date.month
89 113 end
90 114  
91 115 def pick_date(object, method, options = {}, html_options = {})
... ...
app/helpers/events_helper.rb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +module EventsHelper
  2 +
  3 + def list_events(date, events)
  4 + return content_tag('em', _("Select a day on the left to display it's events here"), :class => 'no-events') unless date
  5 + title = _('Events for %s') % show_date(date)
  6 + content_tag('h2', title) +
  7 + content_tag('div',
  8 + (events.any? ?
  9 + content_tag('table', events.select { |item| item.public? }.map {|item| display_event_in_listing(item)}.join('')) :
  10 + content_tag('em', _('No events for this date'))
  11 + ), :id => 'agenda-items'
  12 + )
  13 + end
  14 +
  15 + def display_event_in_listing(article)
  16 + content_tag(
  17 + 'tr',
  18 + content_tag('td', link_to(image_tag(icon_for_article(article)) + article.name, article.url)),
  19 + :class => 'agenda-item'
  20 + )
  21 + end
  22 +
  23 + def populate_calendar(selected_date, events)
  24 + calendar = Event.date_range(selected_date.year, selected_date.month).map do |date|
  25 + [
  26 + # the day itself
  27 + date,
  28 + # is there any events in this date?
  29 + events.any? do |event|
  30 + event.date_range.include?(date)
  31 + end,
  32 + # is this date in the current month?
  33 + true
  34 + ]
  35 + end
  36 + # pad with days before
  37 + while calendar.first.first.wday != 0
  38 + calendar.unshift([calendar.first.first - 1.day, false, false])
  39 + end
  40 +
  41 + # pad with days after (until Saturday)
  42 + while calendar.last.first.wday != 6
  43 + calendar << [calendar.last.first + 1.day, false, false]
  44 + end
  45 + calendar
  46 + end
  47 +
  48 +end
... ...
app/helpers/search_helper.rb
1 1 module SearchHelper
2 2  
  3 + # FIXME remove it after search_controler refactored
  4 + include EventsHelper
  5 +
3 6 STOP_WORDS = {
4 7 'pt_BR' => Ferret::Analysis::FULL_PORTUGUESE_STOP_WORDS,
5 8 'en' => Ferret::Analysis::FULL_ENGLISH_STOP_WORDS,
... ...
app/models/article.rb
... ... @@ -28,6 +28,10 @@ class Article &lt; ActiveRecord::Base
28 28  
29 29 xss_terminate :only => [ :name ]
30 30  
  31 + named_scope :in_category, lambda { |category|
  32 + {:include => 'categories', :conditions => { 'categories.id' => category.id }}
  33 + }
  34 +
31 35 def self.human_attribute_name(attrib)
32 36 case attrib.to_sym
33 37 when :name
... ...
app/models/category_finder.rb
... ... @@ -104,7 +104,7 @@ class CategoryFinder
104 104 when 'Event'
105 105 conditions =
106 106 if date_range
107   - ['articles_categories.category_id = (?) and start_date between ? and ?', category_id, date_range.first, date_range.last]
  107 + ['articles_categories.category_id = (:category_id) and (start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day)', {:category_id => category_id, :start_day => date_range.first, :end_day => date_range.last} ]
108 108 else
109 109 ['articles_categories.category_id = (?) ', category_id ]
110 110 end
... ...
app/models/environment_finder.rb
... ... @@ -32,7 +32,10 @@ class EnvironmentFinder
32 32 @environment.send(asset).send(finder_method, :all, options.merge( :order => 'profiles.name', :joins => 'inner join products on (products.enterprise_id = profiles.id) inner join product_categorizations on (product_categorizations.product_id = products.id)', :conditions => ['product_categorizations.category_id = (?)', product_category.id]))
33 33 else
34 34 if (asset == :events) && date_range
35   - @environment.send(asset).send(finder_method, :all, options.merge(:conditions => { :start_date => date_range}))
  35 + @environment.send(asset).send(finder_method, :all, options.merge(:conditions => [
  36 + 'start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day',
  37 + {:start_day => date_range.first, :end_day => date_range.last}
  38 + ]))
36 39 else
37 40 @environment.send(asset).send(finder_method, :all, options)
38 41 end
... ...
app/models/event.rb
... ... @@ -16,6 +16,10 @@ class Event &lt; Article
16 16 end
17 17 end
18 18  
  19 + named_scope :by_day, lambda { |date|
  20 + {:conditions => ['start_date = :date AND end_date IS NULL OR (start_date <= :date AND end_date >= :date)', {:date => date}]}
  21 + }
  22 +
19 23 def self.description
20 24 _('A calendar event')
21 25 end
... ... @@ -28,9 +32,12 @@ class Event &lt; Article
28 32 'event'
29 33 end
30 34  
31   - def self.by_month(year = nil, month = nil)
32   - self.find(:all, :conditions => { :start_date => date_range(year, month) })
33   - end
  35 + named_scope :by_range, lambda { |range| {
  36 + :conditions => [
  37 + 'start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day',
  38 + { :start_day => range.first, :end_day => range.last }
  39 + ]
  40 + }}
34 41  
35 42 def self.date_range(year, month)
36 43 if year.nil? || month.nil?
... ... @@ -43,11 +50,22 @@ class Event &lt; Article
43 50 end
44 51  
45 52 first_day = Date.new(year, month, 1)
46   - last_day = Date.new(year, month, 1) + 1.month - 1.day
  53 + last_day = first_day + 1.month - 1.day
47 54  
48 55 first_day..last_day
49 56 end
50 57  
  58 + def self.first_day_of_month(date)
  59 + date ||= Date.today
  60 + Date.new(date.year, date.month, 1)
  61 + end
  62 +
  63 + def self.last_day_of_month(date)
  64 + date ||= Date.today
  65 + date >>= 1
  66 + Date.new(date.year, date.month, 1) - 1.day
  67 + end
  68 +
51 69 def date_range
52 70 start_date..(end_date||start_date)
53 71 end
... ...
app/models/profile.rb
... ... @@ -115,6 +115,8 @@ class Profile &lt; ActiveRecord::Base
115 115  
116 116 has_many :tasks, :dependent => :destroy, :as => 'target'
117 117  
  118 + has_many :events, :source => 'articles', :class_name => 'Event', :order => 'name'
  119 +
118 120 %w[ pending finished ].each do |status|
119 121 class_eval <<-CODE
120 122 def all_#{status}_tasks
... ...
app/views/events/_agenda.rhtml 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<div id='agenda'>
  2 + <div class='agenda-calendar'>
  3 + <table class='noborder current-month'>
  4 + <caption>
  5 + <h2><%= show_month(params[:year], params[:month]) %></h2>
  6 + <%= link_to_previous_month(params[:year], params[:month], '&larr; previous') %>
  7 + <%= link_to_next_month(params[:year], params[:month], 'next &rarr;') %>
  8 + </caption>
  9 + <%= render :partial => 'events/month', :locals => {:calendar => @calendar, :abbreviated => true} %>
  10 + </table>
  11 + <table class='noborder previous-month'>
  12 + <caption><h3><%= link_to_previous_month(params[:year], params[:month], show_month(params[:year], params[:month], :previous => true)) %></h3></caption>
  13 + <%= render :partial => 'events/month', :locals => {:calendar => @previous_calendar, :abbreviated => true} %>
  14 + </table>
  15 + <table class='noborder next-month'>
  16 + <caption><h3><%= link_to_next_month(params[:year], params[:month], show_month(params[:year], params[:month], :next => true)) %></h3></caption>
  17 + <%= render :partial => 'events/month', :locals => {:calendar => @next_calendar, :abbreviated => true} %>
  18 + </table>
  19 + <br clear='both'/>
  20 + </div>
  21 + <div id='events-of-the-day'>
  22 + <%= render :partial => 'events/events_by_day' %>
  23 + </div>
  24 +</div>
... ...
app/views/events/_events_by_day.rhtml 0 → 100644
... ... @@ -0,0 +1 @@
  1 +<%= list_events(@selected_day, @events_of_the_day) %>
... ...
app/views/events/_month.rhtml 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 + <tr>
  2 + <% calendar.first(7).each do |day,event| %>
  3 + <th><%= show_day_of_week(day, abbreviated) %></th>
  4 + <% end %>
  5 + </tr>
  6 + <% calendar.in_groups_of(7).each do |week| %>
  7 + <tr>
  8 + <% week.each do |date, has_events, this_month| %>
  9 + <td class='calendar-day <%= this_month || "calendar-day-out" %> <%= date == Date.today && "selected" %>'>
  10 + <span>
  11 + <%= has_events ?
  12 + link_to_remote(
  13 + date.day,
  14 + :url => {:action => 'events_by_day', :year => date.year, :month => date.month, :day => date.day, :category_id => @category_id},
  15 + :update => 'events-of-the-day',
  16 + :loading => '$("events-of-the-day").addClassName("loading")',
  17 + :complete => '$("events-of-the-day").removeClassName("loading")'
  18 + ) :
  19 + date.day
  20 + %>
  21 + </span>
  22 + </td>
  23 + <% end %>
  24 + </tr>
  25 + <% end %>
... ...
app/views/events/events.rhtml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<%= button :back, _('Back to %s') % profile.name, profile.public_profile_url %>
  2 +
  3 +<h1><%= _("%s's events") % profile.name %></h1>
  4 +
  5 +<%= render :partial => 'agenda' %>
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -18,6 +18,8 @@
18 18 theme_stylesheet_path(),
19 19 pngfix_stylesheet_path()
20 20 ) %>
  21 + <%# Add custom tags/styles/etc via content_for %>
  22 + <%= yield :head %>
21 23 </head>
22 24 <body class="<%=
23 25 # Identify the current controller and action for the CSS:
... ...
app/views/layouts/application.rhtml
... ... @@ -28,11 +28,13 @@
28 28 import_controller_stylesheets + "\n" +
29 29 import_controller_stylesheets(:themed_source => true)
30 30 %>
31   -
32 31 <%= template_stylesheet_tag %>
33 32 <%= icon_theme_stylesheet_tag %>
34 33  
35 34 <%= pngfix_stylesheet %>
  35 +
  36 + <%# Add custom tags/styles/etc via content_for %>
  37 + <%= yield :head %>
36 38 </head>
37 39  
38 40 <body class='noosfero category<%= category_color %><%=
... ...
app/views/profile/index.rhtml
... ... @@ -24,6 +24,13 @@
24 24 </tr>
25 25 <tr>
26 26 <td>
  27 + </td>
  28 + <td>
  29 + <%= link_to _('Events'), :controller => 'events', :action => 'events' %>
  30 + </td>
  31 + </tr>
  32 + <tr>
  33 + <td>
27 34 <%= _('Tags:') %>
28 35 </td>
29 36 <td>
... ...
app/views/search/events.rhtml
1 1 <h1>
2 2 <% if @category %>
3   - <%= @category.name %>:
  3 + <%= @category.name %>
4 4 <% end %>
5   - <%= show_month(params[:year], params[:month]) %>
6 5 </h1>
7 6  
8   -<div style='text-align: center; margin: 1em;'>
9   - <%= link_to_previous_month(params[:year], params[:month]) %>
10   - &nbsp;
11   - &nbsp;
12   - &nbsp;
13   - <%= link_to_next_month(params[:year], params[:month]) %>
14   -</div>
  7 +<% stylesheet 'controller_events' %>
15 8  
16   -<table align='center' class='noborder'>
17   - <tr>
18   - <% @calendar.first(7).each do |day,event| %>
19   - <th style='width: 10%;'><%= show_day_of_week(day) %></th>
20   - <% end %>
21   - </tr>
22   - <% @calendar.in_groups_of(7).each do |week| %>
23   - <tr style='height: 80px;'>
24   - <% week.each do |date, events, this_month| %>
25   - <td style='vertical-align: top; <%= ("background-color: gray;" unless this_month) %> <%= ("background-color: #ff9" if date == Date.today) %>'>
26   - <div style='text-align: center;'>
27   - <strong><%= date.day %></strong>
28   - </div>
29   -
30   - <% events.each do |event| %>
31   - <div style='border: 1px solid gray; margin: 0.25em;'>
32   - <%= link_to event.name, event.url, :style => 'display: block;' %>
33   - </div>
34   - <% end %>
35   -
36   - </td>
37   - <% end %>
38   - </tr>
39   - <% end %>
40   -</table>
  9 +<%= render :partial => 'events/agenda' %>
... ...
config/routes.rb
... ... @@ -47,6 +47,11 @@ ActionController::Routing::Routes.draw do |map|
47 47 # search
48 48 map.connect 'search/:action/*category_path', :controller => 'search'
49 49  
  50 + # events
  51 + map.events 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format}/
  52 + map.events 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format}/
  53 + map.events 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/
  54 + map.events 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/
50 55  
51 56 # public profile information
52 57 map.profile 'profile/:profile/:action/:id', :controller => 'profile', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/
... ...
features/events.feature 0 → 100644
... ... @@ -0,0 +1,151 @@
  1 +Feature: events
  2 + As a noosfero visitor
  3 + I want to see some events
  4 +
  5 + Background:
  6 + Given the following users
  7 + | login |
  8 + | josesilva |
  9 + And the following events
  10 + | owner | name | start_date |
  11 + | josesilva | Another Conference | 2009-10-24 |
  12 +
  13 + Scenario: go to next month
  14 + Given I am on /profile/josesilva/events/2009/10
  15 + When I follow "next →"
  16 + Then I should see "November 2009" within ".current-month"
  17 +
  18 + Scenario: go to next month in global agenda
  19 + Given I am on /assets/events?year=2009&month=11
  20 + When I follow "next →"
  21 + Then I should see "December 2009" within ".current-month"
  22 +
  23 + Scenario: go to previous month
  24 + Given I am on /profile/josesilva/events/2009/10
  25 + When I follow "← previous"
  26 + Then I should see "September 2009" within ".current-month"
  27 +
  28 + Scenario: go to previous month in global agenda
  29 + Given I am on /assets/events?year=2009&month=11
  30 + When I follow "← previous"
  31 + Then I should see "October 2009" within ".current-month"
  32 +
  33 + Scenario: go to next month by clicking in month name
  34 + Given I am on /profile/josesilva/events/2009/10
  35 + When I follow "November 2009"
  36 + Then I should see "November 2009" within ".current-month"
  37 +
  38 + Scenario: go to previous month by clicking in month name
  39 + Given I am on /profile/josesilva/events/2009/10
  40 + When I follow "September 2009"
  41 + Then I should see "September 2009" within ".current-month"
  42 +
  43 + Scenario: go to specific day
  44 + Given I am on the homepage
  45 + When I am on /profile/josesilva/events/2009/01/20
  46 + Then I should see "Events for January 20, 2009"
  47 +
  48 + Scenario: go to specific day in global agenda
  49 + Given I am on the homepage
  50 + When I am on /assets/events?year=2009&month=11&day=12
  51 + Then I should see "Events for November 12, 2009"
  52 +
  53 + Scenario: list events for specific day
  54 + Given I am on /profile/josesilva/events/2009/10
  55 + And the following events
  56 + | owner | name | start_date |
  57 + | josesilva | WikiSym 2009 | 2009-10-25 |
  58 + When I am on /profile/josesilva/events/2009/10/25
  59 + Then I should see "WikiSym 2009"
  60 +
  61 + Scenario: dont list events for non-selected day
  62 + Given I am on /profile/josesilva/events/2009/10
  63 + And the following events
  64 + | owner | name | start_date |
  65 + | josesilva | WikiSym 2009 | 2009-10-25 |
  66 + When I am on /profile/josesilva/events/2009/10/20
  67 + Then I should not see "WikiSym 2009"
  68 +
  69 + Scenario: list event between a range
  70 + Given I am on /profile/josesilva/events/2009/10
  71 + And the following events
  72 + | owner | name | start_date | end_date |
  73 + | josesilva | WikiSym 2009 | 2009-10-25 | 2009-10-27 |
  74 + When I am on /profile/josesilva/events/2009/10/26
  75 + Then I should see "WikiSym 2009"
  76 +
  77 + Scenario: dont list events from other profiles
  78 + Given the following users
  79 + | login |
  80 + | josemanuel |
  81 + And the following events
  82 + | owner | name | start_date |
  83 + | josemanuel | Manuel Birthday | 2009-10-24 |
  84 + When I am on /profile/josesilva/events/2009/10/24
  85 + Then I should see "Another Conference"
  86 + And I should not see "Manuel Birthday"
  87 +
  88 + Scenario: list all events in global agenda
  89 + Given the following users
  90 + | login |
  91 + | josemanuel |
  92 + And the following events
  93 + | owner | name | start_date |
  94 + | josemanuel | Manuel Birthday | 2009-10-24 |
  95 + When I am on /assets/events?year=2009&month=10&day=24
  96 + Then I should see "Another Conference"
  97 + And I should see "Manuel Birthday"
  98 +
  99 + Scenario: ask for a day when no inform complete date
  100 + When I am on /profile/josesilva/events/2009/5
  101 + Then I should see "Select a day on the left to display it's events here"
  102 +
  103 + Scenario: ask for a day when no inform complete date in global agenda
  104 + When I am on /assets/events?year=2009&month=5
  105 + Then I should see "Select a day on the left to display it's events here"
  106 +
  107 + Scenario: provide links to days with events
  108 + Given I am on /profile/josesilva/events/2009/10
  109 + Then I should see "24" link
  110 + When I follow "next →"
  111 + Then I should see "24" link
  112 + When I follow "next →"
  113 + Then I should not see "24" link
  114 +
  115 + Scenario: provide links to all days between start and end date
  116 + Given the following users
  117 + | login |
  118 + | fudencio |
  119 + And the following events
  120 + | owner | name | start_date | end_date |
  121 + | fudencio | YAPC::Brasil 2009 | 2010-10-30 | 2010-11-01 |
  122 + And I am on /profile/fudencio/events/2010/10
  123 + Then I should not see "29" link
  124 + And I should see "30" link
  125 + And I should see "31" link
  126 + And I should see "1" link
  127 +
  128 + @selenium
  129 + Scenario: show events when i follow a specific day
  130 + Given I am on /profile/josesilva/events/2009/10
  131 + And I should not see "Another Conference"
  132 + When I follow "24"
  133 + Then I should see "Another Conference"
  134 +
  135 + @selenium
  136 + Scenario: show events in a range when i follow a specific day
  137 + Given the following events
  138 + | owner | name | start_date | end_date |
  139 + | josesilva | YAPC::Brasil 2010 | 2010-10-30 | 2010-11-01 |
  140 + And I am on /profile/josesilva/events/2010/10
  141 + And I should not see "YAPC::Brasil 2010"
  142 + When I follow "31"
  143 + Then I should see "YAPC::Brasil 2010"
  144 +
  145 + Scenario: provide button to back from profile
  146 + When I am on /profile/josesilva/events
  147 + Then I should see "Back to josesilva" link
  148 +
  149 + Scenario: warn when there is no events
  150 + When I am on /profile/josesilva/events/2020/12/1
  151 + Then I should see "No events for this date"
... ...
features/step_definitions/webrat_steps.rb
... ... @@ -188,6 +188,10 @@ Then /^show me the page$/ do
188 188 save_and_open_page
189 189 end
190 190  
191   -Then /^the source should contain tag ([^\"]+)$/ do |tag|
192   - response_body.should have_tag(tag, {id => 10})
  191 +When /^I should see "([^\"]+)" link$/ do |link|
  192 + response.should have_selector("a", :content => link)
  193 +end
  194 +
  195 +When /^I should not see "([^\"]+)" link$/ do |link|
  196 + response.should_not have_selector("a", :content => link)
193 197 end
... ...
public/stylesheets/common.css
... ... @@ -327,17 +327,22 @@ div.pending-tasks {
327 327 margin-bottom: 20px;
328 328 }
329 329  
330   -/* sitemap */
  330 +/* sitemap and agenda */
  331 +
331 332 .sitemap-item a:link,
332   -.sitemap-item a:visited {
  333 +.agenda-item a:link,
  334 +.sitemap-item a:visited,
  335 +.agenda-item a:visited {
333 336 display: block;
334 337 border: none;
335 338 text-decoration: none;
336 339 }
337   -.sitemap-item img {
  340 +.sitemap-item img,
  341 +.agenda-item img {
338 342 border: none;
339 343 }
340   -.sitemap-item a:hover {
  344 +.sitemap-item a:hover,
  345 +.agenda-item a:hover {
341 346 background: #e0e0e0;
342 347 color: red;
343 348 text-decoration: underline;
... ... @@ -346,7 +351,6 @@ div.pending-tasks {
346 351 font-size: small;
347 352 }
348 353  
349   -
350 354 /* * * icons for product category on profile * * */
351 355  
352 356 #content .product-category-icons {
... ... @@ -593,3 +597,10 @@ div.pending-tasks {
593 597 code input {
594 598 font-family: monospace;
595 599 }
  600 +
  601 +/** LOADING... **/
  602 +
  603 +.loading {
  604 + cursor: progress;
  605 + background: transparent url(../images/loading.gif) no-repeat scroll center 50px;
  606 +}
... ...
public/stylesheets/controller_events.css 0 → 100644
... ... @@ -0,0 +1,84 @@
  1 +#agenda {
  2 + position: relative;
  3 + width: 100%;
  4 +}
  5 +
  6 +#agenda .agenda-calendar {
  7 + width: 50%;
  8 +}
  9 +
  10 +#agenda td, #agenda th {
  11 + padding: 0px;
  12 +}
  13 +
  14 +#agenda .agenda-calendar .previous-month td,
  15 +#agenda .agenda-calendar .previous-month th,
  16 +#agenda .agenda-calendar .next-month td,
  17 +#agenda .agenda-calendar .next-month th {
  18 + font-size: 10px;
  19 + color: gray;
  20 +}
  21 +#agenda .agenda-calendar .current-month td {
  22 +}
  23 +#agenda .agenda-calendar .calendar-day {
  24 +}
  25 +#agenda .agenda-calendar .calendar-day-out {
  26 + color: gray;
  27 +}
  28 +#agenda .agenda-calendar .calendar-day-out span {
  29 + display: none;
  30 +}
  31 +#agenda .agenda-calendar td {
  32 + text-align: center;
  33 + padding: 0px;
  34 +}
  35 +#agenda .agenda-calendar h3 {
  36 + font-size: 12px;
  37 +}
  38 +#agenda .agenda-calendar .current-month {
  39 + height: 250px;
  40 + border-bottom: 1px solid #BFC2BC;
  41 +}
  42 +#agenda .agenda-calendar .previous-month,
  43 +#agenda .agenda-calendar .next-month {
  44 + float: left;
  45 + width: 50%;
  46 +}
  47 +#agenda .agenda-calendar .previous-month {
  48 +}
  49 +#agenda .agenda-calendar .next-month {
  50 + border-left: 1px solid #BFC2BC;
  51 +}
  52 +#agenda .selected {
  53 + background: #ff9;
  54 + font-style: normal;
  55 +}
  56 +#agenda td {
  57 + vertical-align: middle;
  58 +}
  59 +
  60 +#agenda .agenda-calendar .current-month caption {
  61 + margin-bottom: 10px;
  62 +}
  63 +
  64 +#agenda #events-of-the-day {
  65 + position: absolute;
  66 + left: 50%;
  67 + width: 45%;
  68 + top: 0px;
  69 + height: 100%;
  70 + border-left: 1px solid #BFC2BC;
  71 + padding-left: 20px;
  72 +}
  73 +
  74 +#agenda #events-of-the-day #agenda-items {
  75 + display: block;
  76 + overflow: auto;
  77 +}
  78 +
  79 +body.noosfero #content .no-boxes a.button.icon-back {
  80 + float: left;
  81 + position: absolute;
  82 + border: none;
  83 + opacity: 0.5;
  84 +}
... ...
public/stylesheets/controller_profile_members.css
... ... @@ -44,11 +44,6 @@
44 44 position: relative;
45 45 }
46 46  
47   -.loading {
48   - cursor: progress;
49   - background: transparent url(../images/loading.gif) no-repeat scroll center 50px;
50   -}
51   -
52 47 table {
53 48 text-align: left;
54 49 }
... ...
test/functional/events_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,58 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class EventsControllerTest < ActionController::TestCase
  4 +
  5 + def setup
  6 + @profile = create_user('testuser').person
  7 + end
  8 + attr_reader :profile
  9 +
  10 + should 'hide sideboxes when show calendar' do
  11 + get :events, :profile => profile.identifier
  12 + assert_no_tag :tag => 'div', :attributes => {:id => 'boxes'}
  13 + end
  14 +
  15 + should 'list today events by default' do
  16 + profile.events << Event.new(:name => 'Joao Birthday', :start_date => Date.today)
  17 + profile.events << Event.new(:name => 'Maria Birthday', :start_date => Date.today)
  18 +
  19 + get :events, :profile => profile.identifier
  20 +
  21 + today = Date.today.strftime("%B %d, %Y")
  22 + assert_tag :tag => 'div', :attributes => {:id => "agenda-items"},
  23 + :descendant => {:tag => 'h3', :content => "Events for #{today}"},
  24 + :descendant => {:tag => 'tr', :content => "Joao Birthday"},
  25 + :descendant => {:tag => 'tr', :content => "Maria Birthday"}
  26 + end
  27 +
  28 + should 'display calendar of current month' do
  29 + get :events, :profile => profile.identifier
  30 +
  31 + month = Date.today.strftime("%B %Y")
  32 + assert_tag :tag => 'table', :attributes => {:class => /current-month/}, :descendant => {:tag => 'caption', :content => /#{month}/}
  33 + end
  34 +
  35 + should 'display calendar of previous month' do
  36 + get :events, :profile => profile.identifier
  37 +
  38 + month = (Date.today << 1).strftime("%B %Y")
  39 + assert_tag :tag => 'table', :attributes => {:class => /previous-month/}, :descendant => {:tag => 'caption', :content => /#{month}/}
  40 + end
  41 +
  42 + should 'display calendar of next month' do
  43 + get :events, :profile => profile.identifier
  44 +
  45 + month = (Date.today >> 1).strftime("%B %Y")
  46 + assert_tag :tag => 'table', :attributes => {:class => /next-month/}, :descendant => {:tag => 'caption', :content => /#{month}/}
  47 + end
  48 +
  49 + should 'display links to previous and next month' do
  50 + get :events, :profile => profile.identifier
  51 +
  52 + prev_month = Date.today << 1
  53 + next_month = Date.today >> 1
  54 + assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{next_month.year}/#{next_month.month}"}, :content => /next/
  55 + assert_tag :tag =>'a', :attributes => {:href => "/profile/#{profile.identifier}/events/#{prev_month.year}/#{prev_month.month}"}, :content => /previous/
  56 + end
  57 +
  58 +end
... ...
test/functional/profile_controller_test.rb
... ... @@ -657,4 +657,9 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
657 657 assert_nil @request.session[:before_join]
658 658 end
659 659  
  660 + should 'show link to events in index' do
  661 + get :index, :profile => profile.identifier
  662 + assert_tag :tag => 'a', :attributes => { :href => "/profile/#{profile.identifier}/events" }
  663 + end
  664 +
660 665 end
... ...
test/functional/search_controller_test.rb
... ... @@ -682,7 +682,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
682 682 person = create_user('testuser').person
683 683  
684 684 create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25))
685   - create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27))
  685 + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 4, 27))
686 686  
687 687 get :assets, :asset => 'events', :year => '2008', :month => '1'
688 688  
... ... @@ -693,7 +693,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
693 693 person = create_user('testuser').person
694 694  
695 695 create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25))
696   - create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27))
  696 + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 4, 27))
697 697  
698 698 get :assets, :asset => 'events', :category_path => [ 'my-category' ], :year => '2008', :month => '1'
699 699  
... ... @@ -875,11 +875,11 @@ class SearchControllerTest &lt; Test::Unit::TestCase
875 875 assert_equal 0, assigns(:calendar).size % 7
876 876 end
877 877  
878   - should 'display current year/month by default' do
  878 + should 'display current year/month by default as caption of current month' do
879 879 Date.expects(:today).returns(Date.new(2008, 8, 1)).at_least_once
880 880  
881 881 get :assets, :asset => 'events'
882   - assert_tag :tag => 'h1', :content => /^\s*August 2008\s*$/
  882 + assert_tag :tag => 'table', :attributes => {:class => /current-month/}, :descendant => {:tag => 'caption', :content => /August 2008/}
883 883 end
884 884  
885 885 should 'submit search form to /search when viewing asset' do
... ... @@ -1001,6 +1001,55 @@ class SearchControllerTest &lt; Test::Unit::TestCase
1001 1001 assert_includes assigns(:results)[:products], prod
1002 1002 end
1003 1003  
  1004 + should 'show events of specific day' do
  1005 + person = create_user('anotheruser').person
  1006 + event = create_event(person, :name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28))
  1007 +
  1008 + get :events_by_day, :year => 2009, :month => 10, :day => 28
  1009 +
  1010 + assert_tag :tag => 'a', :content => /Joao Birthday/
  1011 + end
  1012 +
  1013 + should 'filter events by category' do
  1014 + person = create_user('anotheruser').person
  1015 +
  1016 + searched_category = Category.create!(:name => 'Category with events', :environment => Environment.default)
  1017 +
  1018 + event_in_searched_category = create_event(person, :name => 'Maria Birthday', :start_date => Date.today, :category_ids => [searched_category.id])
  1019 + event_in_non_searched_category = create_event(person, :name => 'Joao Birthday', :start_date => Date.today, :category_ids => [@category.id])
  1020 +
  1021 + get :assets, :asset => 'events', :category_path => ['category-with-events']
  1022 +
  1023 + assert_includes assigns(:events_of_the_day), event_in_searched_category
  1024 + assert_not_includes assigns(:events_of_the_day), event_in_non_searched_category
  1025 + end
  1026 +
  1027 + should 'filter events by category of specific day' do
  1028 + person = create_user('anotheruser').person
  1029 +
  1030 + searched_category = Category.create!(:name => 'Category with events', :environment => Environment.default)
  1031 +
  1032 + event_in_searched_category = create_event(person, :name => 'Maria Birthday', :start_date => Date.new(2009, 10, 28), :category_ids => [searched_category.id])
  1033 + event_in_non_searched_category = create_event(person, :name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28), :category_ids => [@category.id])
  1034 +
  1035 + get :events_by_day, :year => 2009, :month => 10, :day => 28, :category_id => searched_category.id
  1036 +
  1037 + assert_tag :tag => 'a', :content => /Maria Birthday/
  1038 + assert_no_tag :tag => 'a', :content => /Joao Birthday/
  1039 + end
  1040 +
  1041 + should 'ignore filter of events if category not exists' do
  1042 + person = create_user('anotheruser').person
  1043 + create_event(person, :name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28), :category_ids => [@category.id])
  1044 + create_event(person, :name => 'Maria Birthday', :start_date => Date.new(2009, 10, 28))
  1045 +
  1046 + id_of_unexistent_category = Category.last.id + 10
  1047 +
  1048 + get :events_by_day, :year => 2009, :month => 10, :day => 28, :category_id => id_of_unexistent_category
  1049 +
  1050 + assert_tag :tag => 'a', :content => /Joao Birthday/
  1051 + assert_tag :tag => 'a', :content => /Maria Birthday/
  1052 + end
1004 1053  
1005 1054 ##################################################################
1006 1055 ##################################################################
... ... @@ -1011,4 +1060,5 @@ class SearchControllerTest &lt; Test::Unit::TestCase
1011 1060 ev.save!
1012 1061 ev
1013 1062 end
  1063 +
1014 1064 end
... ...
test/unit/article_test.rb
... ... @@ -801,4 +801,17 @@ class ArticleTest &lt; Test::Unit::TestCase
801 801 assert_equal 'changed-name', article.slug
802 802 end
803 803  
  804 + should 'find articles in a specific category' do
  805 + env = Environment.default
  806 + category_with_articles = env.categories.create!(:name => "Category with articles")
  807 + category_without_articles = env.categories.create!(:name => "Category without articles")
  808 +
  809 + article_in_category = profile.articles.create!(:name => 'Article in category')
  810 +
  811 + article_in_category.add_category(category_with_articles)
  812 +
  813 + assert_includes profile.articles.in_category(category_with_articles), article_in_category
  814 + assert_not_includes profile.articles.in_category(category_without_articles), article_in_category
  815 + end
  816 +
804 817 end
... ...
test/unit/category_finder_test.rb
... ... @@ -464,4 +464,18 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
464 464 assert_not_includes list, art2
465 465 end
466 466  
  467 + should 'find events in a date range' do
  468 + person = create_user('testuser').person
  469 +
  470 + date_range = Date.new(2009, 11, 28)..Date.new(2009, 12, 3)
  471 +
  472 + event_in_range = Event.create!(:name => 'Event in range', :profile => person, :start_date => Date.new(2009, 11, 27), :end_date => date_range.last, :category_ids => [@category.id])
  473 + event_out_of_range = Event.create!(:name => 'Event out of range', :profile => person, :start_date => Date.new(2009, 12, 4), :category_ids => [@category.id])
  474 +
  475 + events_found = @finder.find(:events, '', :date_range => date_range)
  476 +
  477 + assert_includes events_found, event_in_range
  478 + assert_not_includes events_found, event_out_of_range
  479 + end
  480 +
467 481 end
... ...
test/unit/dates_helper_test.rb
... ... @@ -43,6 +43,12 @@ class DatesHelperTest &lt; Test::Unit::TestCase
43 43 assert_equal "Domingo", show_day_of_week(date)
44 44 end
45 45  
  46 + should 'show abbreviated day of week' do
  47 + expects(:_).with("Sun").returns("Dom")
  48 + date = Date.new(2009, 10, 25)
  49 + assert_equal "Dom", show_day_of_week(date, true)
  50 + end
  51 +
46 52 should 'show month' do
47 53 expects(:_).with('January').returns('January')
48 54 expects(:_).with('%{month} %{year}').returns('%{month} %{year}')
... ... @@ -58,35 +64,47 @@ class DatesHelperTest &lt; Test::Unit::TestCase
58 64 assert_equal 'November 2008', show_month('', '')
59 65 end
60 66  
  67 + should 'show next month' do
  68 + expects(:_).with('November').returns('November').at_least_once
  69 + expects(:_).with('%{month} %{year}').returns('%{month} %{year}').at_least_once
  70 + assert_equal 'November 2009', show_month(2009, 10, :next => true)
  71 + end
  72 +
  73 + should 'show previous month' do
  74 + expects(:_).with('September').returns('September').at_least_once
  75 + expects(:_).with('%{month} %{year}').returns('%{month} %{year}').at_least_once
  76 + assert_equal 'September 2009', show_month(2009, 10, :previous => true)
  77 + end
  78 +
61 79 should 'provide link to previous month' do
62   - expects(:link_to).with('&larr; January 2008', { :year => 2008, :month => 1})
  80 + expects(:link_to).with('January 2008', { :year => 2008, :month => 1})
63 81 link_to_previous_month('2008', '2')
64 82 end
65 83  
66 84 should 'support last year in link to previous month' do
67   - expects(:link_to).with('&larr; December 2007', { :year => 2007, :month => 12})
  85 + expects(:link_to).with('December 2007', { :year => 2007, :month => 12})
68 86 link_to_previous_month('2008', '1')
69 87 end
70 88  
71 89 should 'provide link to next month' do
72   - expects(:link_to).with('March 2008 &rarr;', { :year => 2008, :month => 3})
  90 + expects(:link_to).with('March 2008', { :year => 2008, :month => 3})
73 91 link_to_next_month('2008', '2')
74 92 end
75 93  
76 94 should 'support next year in link to next month' do
77   - expects(:link_to).with('January 2009 &rarr;', { :year => 2009, :month => 1})
  95 + expects(:link_to).with('January 2009', { :year => 2009, :month => 1})
78 96 link_to_next_month('2008', '12')
79 97 end
80 98  
81 99 should 'get current date when year and month are not informed for next month' do
82   - Date.expects(:today).returns(Date.new(2008,1,1))
83   - expects(:link_to).with('February 2008 &rarr;', { :year => 2008, :month => 2})
  100 + Date.stubs(:today).returns(Date.new(2008,1,1))
  101 + expects(:link_to).with('February 2008', { :year => 2008, :month => 2})
84 102 link_to_next_month(nil, nil)
85 103 end
86 104  
87 105 should 'get current date when year and month are not informed for previous month' do
88   - Date.expects(:today).returns(Date.new(2008,1,1))
89   - expects(:link_to).with('&larr; December 2007', { :year => 2007, :month => 12})
  106 + Date.stubs(:today).returns(Date.new(2008,1,1))
  107 + expects(:link_to).with('December 2007', { :year => 2007, :month => 12})
90 108 link_to_previous_month(nil, nil)
91 109 end
92 110  
... ... @@ -141,4 +159,16 @@ class DatesHelperTest &lt; Test::Unit::TestCase
141 159 assert_equal '', show_time(nil)
142 160 end
143 161  
  162 + should 'build date' do
  163 + assert_equal Date.new(2009, 10, 24), build_date(2009, 10, 24)
  164 + end
  165 +
  166 + should 'build date to day 1 by default' do
  167 + assert_equal Date.new(2009, 10, 1), build_date(2009, 10)
  168 + end
  169 +
  170 + should 'build today date when year and month are blank' do
  171 + assert_equal Date.new(Date.today.year, Date.today.month, 1), build_date('', '')
  172 + end
  173 +
144 174 end
... ...
test/unit/environment_finder_test.rb
... ... @@ -323,4 +323,19 @@ class EnvironmentFinderTest &lt; ActiveSupport::TestCase
323 323 assert_equal 20, finder.find(:enterprises, 'test').total_entries
324 324 end
325 325  
  326 + should 'find events in a date range' do
  327 + finder = EnvironmentFinder.new(Environment.default)
  328 + person = create_user('testuser').person
  329 +
  330 + date_range = Date.new(2009, 11, 28)..Date.new(2009, 12, 3)
  331 +
  332 + event_in_range = Event.create!(:name => 'Event in range', :profile => person, :start_date => Date.new(2009, 11, 27), :end_date => date_range.last)
  333 + event_out_of_range = Event.create!(:name => 'Event out of range', :profile => person, :start_date => Date.new(2009, 12, 4))
  334 +
  335 + events_found = finder.find(:events, '', :date_range => date_range)
  336 +
  337 + assert_includes events_found, event_in_range
  338 + assert_not_includes events_found, event_out_of_range
  339 + end
  340 +
326 341 end
... ...
test/unit/event_test.rb
... ... @@ -76,35 +76,22 @@ class EventTest &lt; ActiveSupport::TestCase
76 76 assert !e.errors.invalid?(:start_date)
77 77 end
78 78  
79   - should 'find by year and month' do
  79 + should 'find by range of dates' do
80 80 profile = create_user('testuser').person
81 81 e1 = Event.create!(:name => 'e1', :start_date => Date.new(2008,1,1), :profile => profile)
82 82 e2 = Event.create!(:name => 'e2', :start_date => Date.new(2008,2,1), :profile => profile)
83 83 e3 = Event.create!(:name => 'e3', :start_date => Date.new(2008,3,1), :profile => profile)
84 84  
85   - found = Event.by_month(2008, 2)
  85 + found = Event.by_range(Date.new(2008, 1, 1)..Date.new(2008, 2, 28))
  86 + assert_includes found, e1
86 87 assert_includes found, e2
87   - assert_not_includes found, e1
88 88 assert_not_includes found, e3
89 89 end
90 90  
91   - should 'find when in first day of month' do
  91 + should 'filter events by range' do
92 92 profile = create_user('testuser').person
93   - e1 = Event.create!(:name => 'e1', :start_date => Date.new(2008,1,1), :profile => profile)
94   - assert_includes Event.by_month(2008, 1), e1
95   - end
96   -
97   - should 'find when in last day of month' do
98   - profile = create_user('testuser').person
99   - e1 = Event.create!(:name => 'e1', :start_date => Date.new(2008,1,31), :profile => profile)
100   - assert_includes Event.by_month(2008, 1), e1
101   - end
102   -
103   - should 'use current month by default' do
104   - profile = create_user('testuser').person
105   - e1 = Event.create!(:name => 'e1', :start_date => Date.new(2008,1,31), :profile => profile)
106   - Date.expects(:today).returns(Date.new(2008, 1, 15))
107   - assert_includes Event.by_month, e1
  93 + e1 = Event.create!(:name => 'e1', :start_date => Date.new(2008,1,15), :profile => profile)
  94 + assert_includes profile.events.by_range(Date.new(2008, 1, 10)..Date.new(2008, 1, 20)), e1
108 95 end
109 96  
110 97 should 'provide period for searching in month' do
... ... @@ -184,4 +171,55 @@ class EventTest &lt; ActiveSupport::TestCase
184 171 end
185 172 end
186 173  
  174 + should 'list all events' do
  175 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  176 + event1 = Event.new(:name => 'Ze Birthday', :start_date => Date.today)
  177 + event2 = Event.new(:name => 'Mane Birthday', :start_date => Date.today >> 1)
  178 + profile.events << [event1, event2]
  179 + assert_includes profile.events, event1
  180 + assert_includes profile.events, event2
  181 + end
  182 +
  183 + should 'list events by day' do
  184 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  185 +
  186 + today = Date.today
  187 + yesterday_event = Event.new(:name => 'Joao Birthday', :start_date => today - 1.day)
  188 + today_event = Event.new(:name => 'Ze Birthday', :start_date => today)
  189 + tomorrow_event = Event.new(:name => 'Mane Birthday', :start_date => today + 1.day)
  190 +
  191 + profile.events << [yesterday_event, today_event, tomorrow_event]
  192 +
  193 + assert_equal [today_event], profile.events.by_day(today)
  194 + end
  195 +
  196 + should 'list events in a range' do
  197 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  198 +
  199 + today = Date.today
  200 + event_in_range = Event.new(:name => 'Noosfero Conference', :start_date => today - 2.day, :end_date => today + 2.day)
  201 + event_in_day = Event.new(:name => 'Ze Birthday', :start_date => today)
  202 +
  203 + profile.events << [event_in_range, event_in_day]
  204 +
  205 + assert_equal [event_in_range], profile.events.by_day(today - 1.day)
  206 + assert_equal [event_in_range], profile.events.by_day(today + 1.day)
  207 + assert_equal [event_in_range, event_in_day], profile.events.by_day(today)
  208 + end
  209 +
  210 + should 'not list events out of range' do
  211 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  212 +
  213 + today = Date.today
  214 + event_in_range1 = Event.new(:name => 'Foswiki Conference', :start_date => today - 2.day, :end_date => today + 2.day)
  215 + event_in_range2 = Event.new(:name => 'Debian Conference', :start_date => today - 2.day, :end_date => today + 3.day)
  216 + event_out_of_range = Event.new(:name => 'Ze Birthday', :start_date => today - 5.day, :end_date => today - 3.day)
  217 +
  218 + profile.events << [event_in_range1, event_in_range2, event_out_of_range]
  219 +
  220 + assert_includes profile.events.by_day(today), event_in_range1
  221 + assert_includes profile.events.by_day(today), event_in_range2
  222 + assert_not_includes profile.events.by_day(today), event_out_of_range
  223 + end
  224 +
187 225 end
... ...
test/unit/events_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class EventsHelperTest < Test::Unit::TestCase
  4 +
  5 + include EventsHelper
  6 +
  7 + should 'list events' do
  8 + expects(:show_date).returns('')
  9 + expects(:_).with('Events for %s').returns('')
  10 + event1 = mock; event1.expects(:public?).returns(true); event1.expects(:name).returns('Event 1'); event1.expects(:url).returns({})
  11 + event2 = mock; event2.expects(:public?).returns(true); event2.expects(:name).returns('Event 2'); event2.expects(:url).returns({})
  12 + result = list_events('', [event1, event2])
  13 + assert_match /Event 1/, result
  14 + assert_match /Event 2/, result
  15 + end
  16 +
  17 + protected
  18 +
  19 + def content_tag(tag, text, options = {})
  20 + "<#{tag}>#{text}</#{tag}>"
  21 + end
  22 + def icon_for_article(article)
  23 + ''
  24 + end
  25 + def image_tag(arg)
  26 + arg
  27 + end
  28 + def link_to(text, url, options = {})
  29 + "<a href='#{url.to_s}'>#{text}</a>"
  30 + end
  31 +
  32 +end
... ...
test/unit/profile_test.rb
... ... @@ -1402,6 +1402,66 @@ class ProfileTest &lt; Test::Unit::TestCase
1402 1402 assert_equal 3, p.blogs.count
1403 1403 end
1404 1404  
  1405 + should 'list all events' do
  1406 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  1407 + event1 = Event.new(:name => 'Ze Birthday', :start_date => Date.today)
  1408 + event2 = Event.new(:name => 'Mane Birthday', :start_date => Date.today >> 1)
  1409 + profile.events << [event1, event2]
  1410 + assert_includes profile.events, event1
  1411 + assert_includes profile.events, event2
  1412 + end
  1413 +
  1414 + should 'list events by day' do
  1415 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  1416 +
  1417 + today = Date.today
  1418 + yesterday_event = Event.new(:name => 'Joao Birthday', :start_date => today - 1.day)
  1419 + today_event = Event.new(:name => 'Ze Birthday', :start_date => today)
  1420 + tomorrow_event = Event.new(:name => 'Mane Birthday', :start_date => today + 1.day)
  1421 +
  1422 + profile.events << [yesterday_event, today_event, tomorrow_event]
  1423 +
  1424 + assert_equal [today_event], profile.events.by_day(today)
  1425 + end
  1426 +
  1427 + should 'list events in a range' do
  1428 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  1429 +
  1430 + today = Date.today
  1431 + event_in_range = Event.new(:name => 'Noosfero Conference', :start_date => today - 2.day, :end_date => today + 2.day)
  1432 + event_in_day = Event.new(:name => 'Ze Birthday', :start_date => today)
  1433 +
  1434 + profile.events << [event_in_range, event_in_day]
  1435 +
  1436 + assert_equal [event_in_range], profile.events.by_day(today - 1.day)
  1437 + assert_equal [event_in_range], profile.events.by_day(today + 1.day)
  1438 + assert_equal [event_in_range, event_in_day], profile.events.by_day(today)
  1439 + end
  1440 +
  1441 + should 'not list events out of range' do
  1442 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  1443 +
  1444 + today = Date.today
  1445 + event_in_range1 = Event.new(:name => 'Foswiki Conference', :start_date => today - 2.day, :end_date => today + 2.day)
  1446 + event_in_range2 = Event.new(:name => 'Debian Conference', :start_date => today - 2.day, :end_date => today + 3.day)
  1447 + event_out_of_range = Event.new(:name => 'Ze Birthday', :start_date => today - 5.day, :end_date => today - 3.day)
  1448 +
  1449 + profile.events << [event_in_range1, event_in_range2, event_out_of_range]
  1450 +
  1451 + assert_includes profile.events.by_day(today), event_in_range1
  1452 + assert_includes profile.events.by_day(today), event_in_range2
  1453 + assert_not_includes profile.events.by_day(today), event_out_of_range
  1454 + end
  1455 +
  1456 + should 'sort events by name' do
  1457 + profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile')
  1458 + event1 = Event.new(:name => 'Noosfero Hackaton', :start_date => Date.today)
  1459 + event2 = Event.new(:name => 'Debian Day', :start_date => Date.today)
  1460 + event3 = Event.new(:name => 'Fisl 10', :start_date => Date.today)
  1461 + profile.events << [event1, event2, event3]
  1462 + assert_equal [event2, event3, event1], profile.events
  1463 + end
  1464 +
1405 1465 private
1406 1466  
1407 1467 def assert_invalid_identifier(id)
... ...