Commit 4b48bec4b1b4be3a525c99a751b36303833a8708
Committed by
Antonio Terceiro
1 parent
4182e506
Exists in
master
and in
22 other branches
Each community has its own agenda
- New UI for calendar - New routes to /profile/:profile/events (ActionItem1255)
Showing
35 changed files
with
877 additions
and
131 deletions
Show diff stats
| ... | ... | @@ -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 < 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 < 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 < 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 '← ' + 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) + ' →', :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 = {}) | ... | ... |
| ... | ... | @@ -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
app/models/article.rb
| ... | ... | @@ -28,6 +28,10 @@ class Article < 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 < 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 < 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 < 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 < 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 | ... | ... |
| ... | ... | @@ -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], '← previous') %> | |
| 7 | + <%= link_to_next_month(params[:year], params[:month], 'next →') %> | |
| 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> | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +<%= list_events(@selected_day, @events_of_the_day) %> | ... | ... |
| ... | ... | @@ -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/layouts/application-ng.rhtml
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
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 | - | |
| 11 | - | |
| 12 | - | |
| 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}/ | ... | ... |
| ... | ... | @@ -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 | +} | ... | ... |
| ... | ... | @@ -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
| ... | ... | @@ -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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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('← 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('← 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 →', { :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 →', { :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 →', { :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('← 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 < 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 < 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 < 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 < 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 | ... | ... |
| ... | ... | @@ -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 < 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) | ... | ... |