Commit 37e8561e4263d9f3146cf094ca14f15309d2159d

Authored by Daniela Feitosa
2 parents fa1683af 7f062d8f

Merge branch 'AI2119-EventBlockPlugin' into 'master'

Ai2119 event block plugin

Fix: https://gitlab.com/noosfero/noosfero/merge_requests/349

See merge request !400
app/helpers/dates_helper.rb
@@ -2,24 +2,14 @@ require 'noosfero/i18n' @@ -2,24 +2,14 @@ require 'noosfero/i18n'
2 2
3 module DatesHelper 3 module DatesHelper
4 4
5 - # FIXME Date#strftime should translate this for us !!!!  
6 - MONTHS = [  
7 - N_('January'),  
8 - N_('February'),  
9 - N_('March'),  
10 - N_('April'),  
11 - N_('May'),  
12 - N_('June'),  
13 - N_('July'),  
14 - N_('August'),  
15 - N_('September'),  
16 - N_('October'),  
17 - N_('November'),  
18 - N_('December')  
19 - ]  
20 -  
21 - def month_name(n)  
22 - _(MONTHS[n-1]) 5 + MONTHS = I18n.t('date.month_names')
  6 +
  7 + def month_name(n, abbreviated = false)
  8 + if abbreviated
  9 + I18n.t('date.abbr_month_names')[n]
  10 + else
  11 + MONTHS[n]
  12 + end
23 end 13 end
24 14
25 # formats a date for displaying. 15 # formats a date for displaying.
@@ -91,15 +81,7 @@ module DatesHelper @@ -91,15 +81,7 @@ module DatesHelper
91 _(date.strftime("%a")) 81 _(date.strftime("%a"))
92 else 82 else
93 # FIXME Date#strftime should translate this for us !!!! 83 # FIXME Date#strftime should translate this for us !!!!
94 - _([  
95 - N_('Sunday'),  
96 - N_('Monday'),  
97 - N_('Tuesday'),  
98 - N_('Wednesday'),  
99 - N_('Thursday'),  
100 - N_('Friday'),  
101 - N_('Saturday'),  
102 - ][date.wday]) 84 + I18n.t('date.day_names')[date.wday]
103 end 85 end
104 end 86 end
105 87
@@ -111,7 +93,7 @@ module DatesHelper @@ -111,7 +93,7 @@ module DatesHelper
111 date = date << 1 93 date = date << 1
112 end 94 end
113 if opts[:only_month] 95 if opts[:only_month]
114 - _('%{month}') % {:month => month_name(date.month.to_i) } 96 + _('%{month}') % { :month => month_name(date.month.to_i) }
115 else 97 else
116 _('%{month} %{year}') % { :year => date.year, :month => month_name(date.month.to_i) } 98 _('%{month} %{year}') % { :year => date.year, :month => month_name(date.month.to_i) }
117 end 99 end
@@ -156,7 +138,7 @@ module DatesHelper @@ -156,7 +138,7 @@ module DatesHelper
156 else 138 else
157 order = [:day, :month, :year] 139 order = [:day, :month, :year]
158 end 140 end
159 - date_select(object, method, html_options.merge(options.merge(:include_blank => true, :order => order, :use_month_names => MONTHS.map {|item| gettext(item)}))) 141 + date_select(object, method, html_options.merge(options.merge(:include_blank => true, :order => order, :use_month_names => MONTHS)))
160 end 142 end
161 143
162 end 144 end
app/models/blog_archives_block.rb
@@ -36,8 +36,7 @@ class BlogArchivesBlock &lt; Block @@ -36,8 +36,7 @@ class BlogArchivesBlock &lt; Block
36 results << content_tag('li', content_tag('strong', "#{year} (#{count})")) 36 results << content_tag('li', content_tag('strong', "#{year} (#{count})"))
37 results << "<ul class='#{year}-archive'>" 37 results << "<ul class='#{year}-archive'>"
38 posts.except(:order).count(:all, :conditions => ['EXTRACT(YEAR FROM published_at)=?', year], :group => 'EXTRACT(MONTH FROM published_at)').sort_by {|month, count| -month.to_i}.each do |month, count| 38 posts.except(:order).count(:all, :conditions => ['EXTRACT(YEAR FROM published_at)=?', year], :group => 'EXTRACT(MONTH FROM published_at)').sort_by {|month, count| -month.to_i}.each do |month, count|
39 - month_name = gettext(MONTHS[month.to_i - 1])  
40 - results << content_tag('li', link_to("#{month_name} (#{count})", owner_blog.url.merge(:year => year, :month => month))) 39 + results << content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", owner_blog.url.merge(:year => year, :month => month)))
41 end 40 end
42 results << "</ul>" 41 results << "</ul>"
43 end 42 end
app/models/event.rb
@@ -141,6 +141,10 @@ class Event &lt; Article @@ -141,6 +141,10 @@ class Event &lt; Article
141 result 141 result
142 end 142 end
143 143
  144 + def duration
  145 + ((self.end_date || self.start_date) - self.start_date).to_i
  146 + end
  147 +
144 def lead 148 def lead
145 content_tag('div', 149 content_tag('div',
146 show_period(start_date, end_date), 150 show_period(start_date, end_date),
plugins/event/lib/event_plugin.rb 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +class EventPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + _("Event Extras")
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("Include a new block to show the environment's or profiles' events information")
  9 + end
  10 +
  11 + def self.extra_blocks
  12 + { EventPlugin::EventBlock => { :type => [Community, Person, Enterprise, Environment] } }
  13 + end
  14 +
  15 + def stylesheet?
  16 + true
  17 + end
  18 +
  19 + def js_files
  20 + 'event.js'
  21 + end
  22 +
  23 +end
plugins/event/lib/event_plugin/event_block.rb 0 → 100644
@@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
  1 +class EventPlugin::EventBlock < Block
  2 + include DatesHelper
  3 +
  4 + attr_accessible :all_env_events, :limit, :future_only, :date_distance_limit
  5 +
  6 + settings_items :all_env_events, :type => :boolean, :default => false
  7 + settings_items :limit, :type => :integer, :default => 4
  8 + settings_items :future_only, :type => :boolean, :default => false
  9 + settings_items :date_distance_limit, :type => :integer, :default => 0
  10 +
  11 + def self.description
  12 + _('Events')
  13 + end
  14 +
  15 + def help
  16 + _('Show the profile events or all environment events.')
  17 + end
  18 +
  19 + def events_source
  20 + unless all_env_events
  21 + if self.owner.kind_of? Environment
  22 + return self.owner
  23 + elsif environment.portal_community
  24 + return environment.portal_community
  25 + end
  26 + end
  27 +
  28 + environment
  29 + end
  30 +
  31 + def events(user = nil)
  32 + events = events_source.events
  33 + events = events.published.order('start_date')
  34 +
  35 + if future_only
  36 + events = events.where('start_date >= ?', Date.today)
  37 + end
  38 +
  39 + if date_distance_limit > 0
  40 + events = events.by_range([
  41 + Date.today - date_distance_limit,
  42 + Date.today + date_distance_limit
  43 + ])
  44 + end
  45 +
  46 + event_list = []
  47 + events.each do |event|
  48 + event_list << event if event.display_to? user
  49 + break if event_list.length >= limit
  50 + end
  51 +
  52 + event_list
  53 + end
  54 +
  55 + def content(args={})
  56 + block = self
  57 + proc do
  58 + render(
  59 + :file => 'blocks/event',
  60 + :locals => { :block => block }
  61 + )
  62 + end
  63 + end
  64 +
  65 + def human_time_left(days_left)
  66 + months_left = (days_left/30.0).round
  67 + if days_left <= -60
  68 + n_('Started one month ago.', 'Started %d months ago.', -months_left) % -months_left
  69 + elsif days_left < 0
  70 + n_('Started one day ago.', 'Started %d days ago.', -days_left) % -days_left
  71 + elsif days_left == 0
  72 + _("I happens today.")
  73 + elsif days_left < 60
  74 + n_('One day left to start.', '%d days left to start.', days_left) % days_left
  75 + else
  76 + n_('One month left to start.', '%d months left to start.', months_left) % months_left
  77 + end
  78 + end
  79 +
  80 + def date_to_html(date)
  81 + content_tag(:span, show_day_of_week(date, true), :class => 'week-day') +
  82 + content_tag(:span, month_name(date.month, true), :class => 'month') +
  83 + content_tag(:span, date.day.to_s, :class => 'day') +
  84 + content_tag(:span, date.year.to_s, :class => 'year')
  85 + end
  86 +
  87 +end
plugins/event/po/pt/event.po 0 → 100644
@@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
  1 +# SOME DESCRIPTIVE TITLE.
  2 +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3 +# This file is distributed under the same license as the PACKAGE package.
  4 +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5 +#
  6 +msgid ""
  7 +msgstr ""
  8 +"Project-Id-Version: 1.0\n"
  9 +"POT-Creation-Date: 2015-01-30 11:52-0000\n"
  10 +"PO-Revision-Date: 2015-01-30 00:18-0000\n"
  11 +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  12 +"Language-Team: LANGUAGE <LL@li.org>\n"
  13 +"Language: \n"
  14 +"MIME-Version: 1.0\n"
  15 +"Content-Type: text/plain; charset=UTF-8\n"
  16 +"Content-Transfer-Encoding: 8bit\n"
  17 +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
  18 +
  19 +#: plugins/event/lib/event_plugin/event_block.rb:12
  20 +msgid "Events"
  21 +msgstr "Eventos"
  22 +
  23 +#: plugins/event/lib/event_plugin/event_block.rb:16
  24 +msgid "Show the profile events or all environment events."
  25 +msgstr "Mostrar todos os eventos."
  26 +
  27 +#: plugins/event/lib/event_plugin/event_block.rb:68
  28 +msgid "Started one month ago."
  29 +msgid_plural "Started %d months ago."
  30 +msgstr[0] "Iniciou a um mês atrás."
  31 +msgstr[1] "Iniciou a %d meses atrás."
  32 +
  33 +#: plugins/event/lib/event_plugin/event_block.rb:70
  34 +msgid "Started one day ago."
  35 +msgid_plural "Started %d days ago."
  36 +msgstr[0] "Iniciou a Um dia atrás."
  37 +msgstr[1] "Iniciou a %d dias atrás."
  38 +
  39 +#: plugins/event/lib/event_plugin/event_block.rb:72
  40 +msgid "I happens today."
  41 +msgstr "Acontece hoje."
  42 +
  43 +#: plugins/event/lib/event_plugin/event_block.rb:74
  44 +msgid "One day left to start."
  45 +msgid_plural "%d days left to start."
  46 +msgstr[0] "Um dia para iniciar."
  47 +msgstr[1] "%d dias para iniciar."
  48 +
  49 +#: plugins/event/lib/event_plugin/event_block.rb:76
  50 +msgid "One month left to start."
  51 +msgid_plural "%d months left to start."
  52 +msgstr[0] "Um mês para iniciar"
  53 +msgstr[1] "% meses para iniciar"
  54 +
  55 +#: plugins/event/lib/event_plugin.rb:4
  56 +msgid "Event Extras"
  57 +msgstr "Eventos"
  58 +
  59 +#: plugins/event/lib/event_plugin.rb:8
  60 +msgid ""
  61 +"Include a new block to show the environment's or profiles' events information"
  62 +msgstr ""
  63 +"Adiciona um novo bloco para apresentar as informações de eventos do ambiente "
  64 +"ou de perfis"
  65 +
  66 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:1
  67 +msgid "Limit of items"
  68 +msgstr "Limite de itens"
  69 +
  70 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:3
  71 +msgid "Show all environment events"
  72 +msgstr "Apresentar todos os eventos do ambiente"
  73 +
  74 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:8
  75 +msgid "(Don't check to show only your events)"
  76 +msgstr "(Não marque para apresentar somente seus eventos)"
  77 +
  78 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:10
  79 +msgid "(Don't check to show only %s events)"
  80 +msgstr "(Não marque para apresentar somente os eventos de %s)"
  81 +
  82 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:13
  83 +msgid "(Don't check to show only the environment events)"
  84 +msgstr "(Não marque para apresentar somente os eventos do ambiente)"
  85 +
  86 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:18
  87 +msgid "Limit of days to display"
  88 +msgstr "Limite de dias de distância para mostrar eventos"
  89 +
  90 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:20
  91 +msgid "Only show events on this limit of days."
  92 +msgstr "Mostar somente eventos que acontecem dentro do limite de dias"
  93 +
  94 +#: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:23
  95 +msgid "Only show future events"
  96 +msgstr "Mostrar apenas eventos futuros"
  97 +
  98 +#: plugins/event/views/event_plugin/event_block_item.html.erb:6
  99 +msgid "Duration: 1 day"
  100 +msgid_plural "Duration: %s days"
  101 +msgstr[0] ""
  102 +msgstr[1] ""
  103 +
  104 +#~ msgid "1 day"
  105 +#~ msgid_plural "%s days"
  106 +#~ msgstr[0] "1 dia"
  107 +#~ msgstr[1] "%s dias"
  108 +
  109 +#~ msgid "Event Block Plugin"
  110 +#~ msgstr "Plugin de Bloco de Eventos"
plugins/event/public/event.js 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +(function(){
  2 + function change_title_size(){
  3 + jQuery(".event-plugin_event-block .event .title").each(function(num, el){
  4 + var title = jQuery(el);
  5 + console.log(title.height(), title.css("line-height"));
  6 + if (title.height() > parseInt(title.css("line-height")) * 2) {
  7 + title.addClass("toobig")
  8 + }
  9 + });
  10 + }
  11 +
  12 +
  13 + jQuery(document).ready(function(){
  14 + change_title_size();
  15 + });
  16 +})();
0 \ No newline at end of file 17 \ No newline at end of file
plugins/event/public/style.css 0 → 100644
@@ -0,0 +1,186 @@ @@ -0,0 +1,186 @@
  1 +.event-plugin_event-block {
  2 + font-size: 12px;
  3 +}
  4 +
  5 +.event-plugin_event-block .events {
  6 + margin: 0;
  7 + padding: 0;
  8 + border-bottom: 1px solid #DDD;
  9 +}
  10 +
  11 +.event-plugin_event-block .events li {
  12 + margin: 0;
  13 + padding: 1px 0;
  14 + list-style: none;
  15 + border-top: 1px solid #DDD;
  16 +}
  17 +
  18 +.event-plugin_event-block .event a {
  19 + display: block;
  20 + min-height: 60px;
  21 + overflow: hidden;
  22 + padding: 3px 0;
  23 + text-decoration: none;
  24 + color: inherit;
  25 +}
  26 +
  27 +.event-plugin_event-block .event a:hover {
  28 + background-color: #EEE;
  29 + text-decoration: none;
  30 + color: inherit;
  31 +}
  32 +
  33 +.event-plugin_event-block .event a:visited {
  34 + color: inherit;
  35 +}
  36 +
  37 +.event-plugin_event-block .event .date {
  38 + display: block;
  39 + width: 60px;
  40 + height: auto;
  41 + background-size: cover;
  42 + background-position: 50% 40%;
  43 + font-weight: bold;
  44 + text-align: center;
  45 + float: left;
  46 + margin-right: 10px;
  47 +}
  48 +
  49 +.event-plugin_event-block .event .date.no-img {
  50 + background-color: #AAA;
  51 +}
  52 +
  53 +.event-plugin_event-block .event:hover .date.no-img {
  54 + background-color: #79B;
  55 +}
  56 +
  57 +.event-plugin_event-block .event:hover .date.no-img * {
  58 + opacity: 0.8;
  59 + filter: alpha(opacity=80);
  60 +}
  61 +
  62 +.event-plugin_event-block .event .month {
  63 + display: block;
  64 + background: rgba(90,90,90,0.6);
  65 + color: #FFF;
  66 + text-shadow: 0 0 2px #000;
  67 + font-size: 20px;
  68 + line-height: 22px;
  69 +}
  70 +
  71 +.msie8 .event-plugin_event-block .event .month{
  72 + background: #797979;
  73 + width: 60px;
  74 + float: left;
  75 + text-align: center;
  76 +}
  77 +
  78 +.event-plugin_event-block .event:hover .has-img .month {
  79 + opacity: 0.9;
  80 + background: rgba(90,90,90,0.4);
  81 +}
  82 +
  83 +.msie8 .event-plugin_event-block .event:hover .has-img .month {
  84 + background: #D8D8D8;
  85 +}
  86 +
  87 +.event-plugin_event-block .event .day {
  88 + display: block;
  89 + background: rgba(255,255,255,0.5);
  90 + border: 2px solid rgba(90,90,90,0.6);
  91 + border-top: none;
  92 + color: #000;
  93 + font-size: 36px;
  94 + line-height: 36px;
  95 +}
  96 +
  97 +.msie8 .event-plugin_event-block .event .day {
  98 + display: block;
  99 + background: #D4D4D4;
  100 + border: 2px solid #797979;
  101 + width: 56px;
  102 + text-align: center;
  103 +}
  104 +
  105 +.event-plugin_event-block .event .has-img .day {
  106 + text-shadow: 0 0 5px #FFF, 0 0 5px #FFF;
  107 +}
  108 +
  109 +.event-plugin_event-block .event:hover .has-img .day {
  110 + opacity: 0.8;
  111 + background: rgba(255,255,255,0.3);
  112 +}
  113 +
  114 +.event-plugin_event-block .event:hover .has-img .day {
  115 + filter: alpha(opacity=80);
  116 +}
  117 +
  118 +.msie8 .event-plugin_event-block .event:hover .has-img .day{
  119 + background: #D4D4D4;
  120 +}
  121 +
  122 +.event-plugin_event-block .event .duration {
  123 + display: block;
  124 +}
  125 +
  126 +.event-plugin_event-block .event .duration span {
  127 + font-weight: bold;
  128 +}
  129 +
  130 +#content .event-plugin_event-block .event .title {
  131 + position: relative;
  132 + display: block;
  133 + font-size: 14px;
  134 + line-height: 16px;
  135 + margin: 0;
  136 + overflow: hidden;
  137 + max-height: 33px;
  138 +}
  139 +
  140 +.event-plugin_event-block .event .title.toobig:after {
  141 + content: "...";
  142 + position: absolute;
  143 + bottom: 0;
  144 + right: 0;
  145 + width: 5em;
  146 + padding-right: 4px;
  147 + text-align: right;
  148 + color: rgba(0, 0, 0, 0.5);
  149 + background: -webkit-gradient(linear, left top, right top,
  150 + from(rgba(255, 255, 255, 0)), to(#FFF), color-stop(80%, #FFF));
  151 + background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), #FFF 80%, #FFF);
  152 + background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), #FFF 80%, #FFF);
  153 + background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), #FFF 80%, #FFF);
  154 + background: linear-gradient(to right, rgba(255, 255, 255, 0), #FFF 80%, #FFF);
  155 +}
  156 +
  157 +.event-plugin_event-block .event:hover .title.toobig:after {
  158 + background: -webkit-gradient(linear, left top, right top,
  159 + from(rgba(238, 238, 238, 0)), to(#EEE), color-stop(80%, #EEE));
  160 + background: -moz-linear-gradient(to right, rgba(238, 238, 238, 0), #EEE 80%, #EEE);
  161 + background: -ms-linear-gradient(to right, rgba(238, 238, 238, 0), #EEE 80%, #EEE);
  162 + background: -o-linear-gradient(to right, rgba(238, 238, 238, 0), #EEE 80%, #EEE);
  163 + background: linear-gradient(to right, rgba(238, 238, 238, 0), #EEE 80%, #EEE);
  164 +}
  165 +
  166 +.event-plugin_event-block .event .address i {
  167 + display: block;
  168 + font-style: normal;
  169 + overflow: hidden;
  170 + white-space: nowrap;
  171 + text-overflow: ellipsis;
  172 +}
  173 +
  174 +.event-plugin_event-block .event .days-left {
  175 + display: block;
  176 +}
  177 +
  178 +.event-plugin_event-block .event .days-left.past {
  179 + filter: alpha(opacity=50);
  180 +}
  181 +
  182 +.msie8 #content .event-plugin_event-block .event .title,
  183 +.msie8 #content .event-plugin_event-block .event .adress i,
  184 +.msie8 #content .event-plugin_event-block .event .days-left {
  185 + float: left;
  186 +}
plugins/event/test/functional/event_block_test.rb 0 → 100644
@@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class HomeController
  5 + #append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  6 + def rescue_action(e)
  7 + raise e
  8 + end
  9 +end
  10 +
  11 +class HomeControllerTest < ActionController::TestCase
  12 +
  13 + def setup
  14 + @env = Environment.default
  15 + @env.enable_plugin('EventPlugin')
  16 +
  17 + @p1 = fast_create(Person, :environment_id => @env.id)
  18 + @e1a = fast_create(Event, :name=>'Event p1 A', :profile_id=>@p1.id)
  19 +
  20 + box = Box.create!(:owner => @env)
  21 + @block = EventPlugin::EventBlock.create!(:box => box)
  22 + end
  23 +
  24 + # Event item CSS selector
  25 + ev = '.event-plugin_event-block ul.events li.event[itemscope]' +
  26 + '[itemtype="http://data-vocabulary.org/Event"] '
  27 +
  28 + should 'see events microdata sturcture' do
  29 + get :index
  30 + assert_select '.event-plugin_event-block ul.events'
  31 + assert_select ev
  32 + assert_select ev + 'a[itemprop="url"]'
  33 + assert_select ev + 'time.date[itemprop="startDate"][datetime]'
  34 + assert_select ev + 'time.date .day'
  35 + assert_select ev + 'time.date .month'
  36 + assert_select ev + 'time.date .year'
  37 + assert_select ev + '.title[itemprop="summary"]'
  38 + assert_select ev + '.address[itemprop="location"] *[itemprop="name"]'
  39 + assert_select ev + '.days-left'
  40 + end
  41 +
  42 + should 'see event duration' do
  43 + @e1a.slug = 'event1a'
  44 + @e1a.start_date = Date.today
  45 + @e1a.end_date = Date.tomorrow
  46 + @e1a.save!
  47 + get :index
  48 + assert_select ev + 'time.duration[itemprop="endDate"]', '+1 day'
  49 +
  50 + @e1a.slug = 'event1a'
  51 + @e1a.start_date = Date.today
  52 + @e1a.end_date = Date.tomorrow+1
  53 + @e1a.save!
  54 + get :index
  55 + assert_select ev + 'time.duration[itemprop="endDate"]', '+2 days'
  56 + end
  57 +
  58 + should 'not see event duration for one day events' do
  59 + get :index
  60 + assert_select ev + 'time.duration[itemprop="endDate"]', false
  61 +
  62 + @e1a.slug = 'event1a'
  63 + @e1a.start_date = Date.today
  64 + @e1a.end_date = Date.today
  65 + @e1a.save!
  66 + get :index
  67 + assert_select ev + 'time.duration[itemprop="endDate"]', false
  68 + end
  69 +
  70 +end
plugins/event/test/unit/event_block_test.rb 0 → 100644
@@ -0,0 +1,189 @@ @@ -0,0 +1,189 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class EventPlugin::EventBlockTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @env = Environment.default
  7 + @env.enable_plugin('EventPlugin')
  8 +
  9 + @p1 = fast_create(Person, :environment_id => @env.id)
  10 + @event = fast_create(Event, :name => 'Event p1 A', :profile_id => @p1.id,
  11 + :start_date => Date.today+30)
  12 + fast_create(Event, :name => 'Event p1 B', :profile_id => @p1.id,
  13 + :start_date => Date.today+10)
  14 +
  15 + @p2 = fast_create(Community, :environment_id => @env.id)
  16 + fast_create(Event, :name => 'Event p2 A', :profile_id => @p2.id,
  17 + :start_date => Date.today-10)
  18 + fast_create(Event, :name => 'Event p2 B', :profile_id => @p2.id,
  19 + :start_date => Date.today-30)
  20 +
  21 + box = fast_create(Box, :owner_id => @p1)
  22 + @block = EventPlugin::EventBlock.new(:limit => 99, :box => box)
  23 + end
  24 +
  25 + def set_portal(env, portal)
  26 + env.portal_community = portal
  27 + env.enable('use_portal_community')
  28 + env.save!
  29 + end
  30 +
  31 + should 'select source as env, while visiting the profile' do
  32 + @block.box.owner = @p1
  33 + @block.all_env_events = true
  34 +
  35 + assert_equal @env, @block.events_source
  36 + assert_equal 4, @block.events.length
  37 +
  38 + set_portal(@env, @p2)
  39 +
  40 + assert_equal @env, @block.events_source
  41 + assert_equal 4, @block.events.length
  42 + end
  43 +
  44 + should 'select source as env, while visiting an env page' do
  45 + @block.box.owner = @env
  46 + @block.all_env_events = true
  47 +
  48 + assert_equal @env, @block.events_source
  49 + assert_equal 4, @block.events.length
  50 +
  51 + set_portal @env, @p2
  52 +
  53 + assert_equal @env, @block.events_source
  54 + assert_equal 4, @block.events.length
  55 + end
  56 +
  57 + should 'select source as portal_community, while visiting an env page' do
  58 + set_portal @env, @p2
  59 +
  60 + @block.box.owner = @env.portal_community
  61 + @block.all_env_events = false
  62 +
  63 + assert_equal @p2, @block.events_source
  64 + assert_equal 2, @block.events.length
  65 + end
  66 +
  67 + should 'select source as profile, while visiting its page' do
  68 + @block.stubs(:owner).returns(@p1)
  69 + @block.all_env_events = false
  70 +
  71 + assert_equal @p1, @block.events_source
  72 + assert_equal 2, @block.events.length
  73 +
  74 + set_portal @env, @p2
  75 +
  76 + assert_equal @p1, @block.events_source
  77 + assert_equal 2, @block.events.length
  78 + end
  79 +
  80 + should 'say human left time for an event' do
  81 + one_day = @block.human_time_left(Date.tomorrow - Date.today)
  82 +
  83 + assert_match /One day left/, one_day
  84 + assert_match /5 days left/, @block.human_time_left(5)
  85 + assert_match /30 days left/, @block.human_time_left(30)
  86 + assert_match /2 months left/, @block.human_time_left(60)
  87 + assert_match /3 months left/, @block.human_time_left(85)
  88 + end
  89 +
  90 + should 'say human past time for an event' do
  91 + one_day = @block.human_time_left(Date.yesterday - Date.today)
  92 +
  93 + assert_match /One day past/, one_day
  94 + assert_match /5 days past/, @block.human_time_left(-5)
  95 + assert_match /30 days past/, @block.human_time_left(-30)
  96 + assert_match /2 months past/, @block.human_time_left(-60)
  97 + assert_match /3 months past/, @block.human_time_left(-85)
  98 + end
  99 +
  100 + should 'write formatable data in html' do
  101 + html = '<span class="week-day">Tue</span>'+
  102 + '<span class="month">Sep</span>'+
  103 + '<span class="day">27</span>'+
  104 + '<span class="year">1983</span>'
  105 +
  106 + assert_equal html, @block.date_to_html(Date.new 1983, 9, 27)
  107 + end
  108 +
  109 + should 'show unlimited time distance events' do
  110 + @block.box.owner = @env
  111 + @block.all_env_events = true
  112 + @block.date_distance_limit = 0
  113 +
  114 + assert_equal 4, @block.events.length
  115 + end
  116 +
  117 + should 'only show 20 days distant events' do
  118 + @block.box.owner = @env
  119 + @block.all_env_events = true
  120 + @block.date_distance_limit = 20
  121 +
  122 + assert_equal 2, @block.events.length
  123 + end
  124 +
  125 + should 'show future and past events' do
  126 + @block.box.owner = @env
  127 + @block.all_env_events = true
  128 + @block.future_only = false
  129 +
  130 + assert_equal 4, @block.events.length
  131 + end
  132 +
  133 + should 'show only future events' do
  134 + @block.box.owner = @env
  135 + @block.all_env_events = true
  136 + @block.future_only = true
  137 +
  138 + assert_equal 2, @block.events.length
  139 + end
  140 +
  141 + should 'show only published events' do
  142 + @block.box.owner = @env
  143 + @block.all_env_events = true
  144 + @event.published = false
  145 + @event.save!
  146 +
  147 + assert_equal 3, @block.events.length
  148 + end
  149 +
  150 + should 'filter events from non public profiles' do
  151 + person = create_user('testuser', :environment_id => @env.id).person
  152 + person.public_profile = false
  153 + person.save!
  154 +
  155 + visibility_content_test_from_a_profile person
  156 + end
  157 +
  158 + should 'filter events from non visible profiles' do
  159 + person = create_user('testuser', :environment_id=>@env.id).person
  160 + person.visible = false
  161 + person.save!
  162 +
  163 + visibility_content_test_from_a_profile person
  164 + end
  165 +
  166 + def visibility_content_test_from_a_profile(profile)
  167 + @block.box.owner = @env
  168 + ev = fast_create Event, :name => '2 de Julho', :profile_id => profile.id
  169 + @block.all_env_events = true
  170 +
  171 + # Do not list event from private profile for non logged visitor
  172 + assert ! @block.events.include?(ev)
  173 + assert_equal 4, @block.events.length
  174 +
  175 + # Do not list event from private profile for non unprivileged user
  176 + assert ! @block.events.include?(ev)
  177 + assert_equal 4, @block.events(@p1).length
  178 +
  179 + # Must to list event from private profile for a friend
  180 + AddFriend.create!(:requestor => @p1, :target => profile).finish
  181 +
  182 + assert @block.events(@p1).include?(ev)
  183 + assert_equal 5, @block.events(@p1).length
  184 +
  185 + # Must to list event from private profile for itself
  186 + assert @block.events(profile).include?(ev)
  187 + assert_equal 5, @block.events(profile).length
  188 + end
  189 +end
plugins/event/test/unit/event_plugin_test.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class EventPluginTest < ActiveSupport::TestCase
  4 +
  5 + should 'not crash' do
  6 + EventPlugin.new
  7 + end
  8 +
  9 +end
plugins/event/views/blocks/event.html.erb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +<%= block_title(block.title) %>
  2 +
  3 +<ul class="events">
  4 + <% block.events(@user).map do |event| %>
  5 + <% days_left = ( event.start_date - Date.today ).round %>
  6 + <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Event" class="event">
  7 + <%= render(
  8 + :file => 'event_plugin/event_block_item',
  9 + :locals => {
  10 + :event => event,
  11 + :block => block,
  12 + :time_class => days_left < 0 ? 'future' : 'past',
  13 + :time_left_str => block.human_time_left(days_left)
  14 + }
  15 + )
  16 + %>
  17 + </li>
  18 + <% end %>
  19 +</ul>
plugins/event/views/environment_design 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +profile_design
0 \ No newline at end of file 2 \ No newline at end of file
plugins/event/views/event_plugin/event_block_item.html.erb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<%
  2 + # compute layout values
  3 + ev_days_tag = ''
  4 + if event.duration > 0
  5 + ev_days_tag = content_tag('time',
  6 + n_('Duration: 1 day', 'Duration: %s days', event.duration) % "<b>#{event.duration}</b>",
  7 + :itemprop => 'endDate',
  8 + :datetime => show_date(event.end_date) + 'T00:00',
  9 + :class => 'duration',
  10 + :title => show_date(event.start_date) + ' &mdash; ' + time_left_str
  11 + )
  12 + end
  13 +
  14 + img = event.image.nil? ? event.first_image : event.image.public_filename
  15 + bg = "background-image: url(#{img})" if not img.blank?
  16 + img_class = img.blank? ? 'no-img' : 'has-img'
  17 +%>
  18 +<%=
  19 + link_to([
  20 + content_tag('time',
  21 + block.date_to_html(event.start_date),
  22 + :itemprop => 'startDate',
  23 + :datetime => show_date(event.start_date),
  24 + :class => 'date ' + img_class, :style => bg,
  25 + :title => show_date(event.start_date) + ' &mdash; ' + time_left_str
  26 + ),
  27 + ev_days_tag,
  28 + content_tag('strong', h(event.name), :class => 'title',
  29 + :title => event.name, :itemprop => 'summary'),
  30 + content_tag('span', content_tag('i', event.address, :itemprop=>:name),
  31 + :title => h(event.address),
  32 + :class => 'address', :itemscope => :itemscope,
  33 + :itemtype => 'http://schema.org/Place',
  34 + :itemprop => :location),
  35 + content_tag('span', time_left_str, :class => 'days-left ' + time_class)
  36 + ].join("\n"),
  37 + (event.link.blank? ? event.url : event.link),
  38 + :class => 'ev-days-' + event.duration.to_s,
  39 + :itemprop => :url
  40 + )
  41 +%>
plugins/event/views/profile_design/event_plugin/_event_block.html.erb 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +<%= labelled_form_field _('Limit of items'), text_field(:block, :limit, :size => 4) %>
  2 +
  3 +<%= labelled_check_box(_('Show all environment events'), "block[all_env_events]", "1", @block.all_env_events) %>
  4 +<br>
  5 +<small><%=
  6 + if @profile
  7 + if @profile.person?
  8 + _("(Don't check to show only your events)")
  9 + else
  10 + _("(Don't check to show only %s events)") % @profile.name
  11 + end
  12 + elsif environment.portal_community
  13 + _("(Don't check to show only the environment events)")
  14 + end
  15 +%></small>
  16 +<br>
  17 +
  18 +<%= labelled_form_field _('Limit of days to display'),
  19 + text_field(:block, :date_distance_limit, :size => 4) %>
  20 +<small>(<%=_('Only show events on this limit of days.')%>)</small>
  21 +<br><br>
  22 +
  23 +<%= labelled_check_box(_('Only show future events'), "block[future_only]", "1", @block.future_only) %>
test/factories.rb
@@ -247,7 +247,13 @@ module Noosfero::Factory @@ -247,7 +247,13 @@ module Noosfero::Factory
247 ############################################### 247 ###############################################
248 248
249 def defaults_for_event 249 def defaults_for_event
250 - { :name => 'My event ' + factory_num_seq.to_s, :start_date => Date.today } 250 + num = factory_num_seq.to_s
  251 + {
  252 + :name => 'My event ' + num,
  253 + :slug => 'my-event-' + num,
  254 + :path => '/my-event-' + num,
  255 + :start_date => Date.today
  256 + }
251 end 257 end
252 258
253 ############################################### 259 ###############################################
test/unit/dates_helper_test.rb
@@ -5,13 +5,16 @@ class DatesHelperTest &lt; ActiveSupport::TestCase @@ -5,13 +5,16 @@ class DatesHelperTest &lt; ActiveSupport::TestCase
5 include DatesHelper 5 include DatesHelper
6 6
7 should 'translate month names' do 7 should 'translate month names' do
8 - expects(:_).with('January').returns('Janeiro')  
9 - assert_equal "Janeiro", month_name(1) 8 + assert_equal "January", month_name(1)
  9 + end
  10 +
  11 + should 'translate abbreviated month names' do
  12 + assert_equal "Sep", month_name(9, true)
10 end 13 end
11 14
12 should 'display date with translation' do 15 should 'display date with translation' do
  16 + expects(:month_name).with(1).returns('Janeiro')
13 expects(:_).with('%{month_name} %{day}, %{year}').returns('%{day} de %{month_name} de %{year}') 17 expects(:_).with('%{month_name} %{day}, %{year}').returns('%{day} de %{month_name} de %{year}')
14 - expects(:_).with('January').returns('Janeiro')  
15 assert_equal '11 de Janeiro de 2008', show_date(Date.new(2008, 1, 11)) 18 assert_equal '11 de Janeiro de 2008', show_date(Date.new(2008, 1, 11))
16 end 19 end
17 20
@@ -68,75 +71,48 @@ class DatesHelperTest &lt; ActiveSupport::TestCase @@ -68,75 +71,48 @@ class DatesHelperTest &lt; ActiveSupport::TestCase
68 end 71 end
69 72
70 should 'show day of week' do 73 should 'show day of week' do
71 - expects(:_).with("Sunday").returns("Domingo")  
72 - date = mock  
73 - date.expects(:wday).returns(0)  
74 - assert_equal "Domingo", show_day_of_week(date) 74 + assert_equal "Thursday", show_day_of_week(Date.new(2014,10,23))
75 end 75 end
76 76
77 should 'show abbreviated day of week' do 77 should 'show abbreviated day of week' do
78 - expects(:_).with("Sun").returns("Dom")  
79 date = Date.new(2009, 10, 25) 78 date = Date.new(2009, 10, 25)
80 - assert_equal "Dom", show_day_of_week(date, true) 79 + assert_equal "Sun", show_day_of_week(date, true)
81 end 80 end
82 81
83 should 'show month' do 82 should 'show month' do
84 - expects(:_).with('January').returns('January')  
85 - expects(:_).with('%{month} %{year}').returns('%{month} %{year}')  
86 assert_equal 'January 2008', show_month(2008, 1) 83 assert_equal 'January 2008', show_month(2008, 1)
87 end 84 end
88 85
89 should 'fallback to current year/month in show_month' do 86 should 'fallback to current year/month in show_month' do
90 Date.expects(:today).returns(Date.new(2008,11,1)).at_least_once 87 Date.expects(:today).returns(Date.new(2008,11,1)).at_least_once
91 -  
92 - expects(:_).with('November').returns('November').at_least_once  
93 - expects(:_).with('%{month} %{year}').returns('%{month} %{year}').at_least_once  
94 assert_equal 'November 2008', show_month(nil, nil) 88 assert_equal 'November 2008', show_month(nil, nil)
95 assert_equal 'November 2008', show_month('', '') 89 assert_equal 'November 2008', show_month('', '')
96 end 90 end
97 91
98 should 'show next month' do 92 should 'show next month' do
99 - expects(:_).with('November').returns('November').at_least_once  
100 - expects(:_).with('%{month} %{year}').returns('%{month} %{year}').at_least_once  
101 assert_equal 'November 2009', show_month(2009, 10, :next => true) 93 assert_equal 'November 2009', show_month(2009, 10, :next => true)
102 end 94 end
103 95
104 should 'show previous month' do 96 should 'show previous month' do
105 - expects(:_).with('September').returns('September').at_least_once  
106 - expects(:_).with('%{month} %{year}').returns('%{month} %{year}').at_least_once  
107 assert_equal 'September 2009', show_month(2009, 10, :previous => true) 97 assert_equal 'September 2009', show_month(2009, 10, :previous => true)
108 end 98 end
109 99
110 should 'provide an intertionalized date selector pass month names' do 100 should 'provide an intertionalized date selector pass month names' do
111 - expects(:gettext).with('January').returns('January')  
112 - expects(:gettext).with('February').returns('February')  
113 - expects(:gettext).with('March').returns('March')  
114 - expects(:gettext).with('April').returns('April')  
115 - expects(:gettext).with('May').returns('May')  
116 - expects(:gettext).with('June').returns('June')  
117 - expects(:gettext).with('July').returns('July')  
118 - expects(:gettext).with('August').returns('August')  
119 - expects(:gettext).with('September').returns('September')  
120 - expects(:gettext).with('October').returns('October')  
121 - expects(:gettext).with('November').returns('November')  
122 - expects(:gettext).with('December').returns('December')  
123 expects(:language).returns('en') 101 expects(:language).returns('en')
124 -  
125 - expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:month, :day, :year], :use_month_names => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']}).returns("KKKKKKKK")  
126 - 102 + expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:month, :day, :year], :use_month_names => MONTHS }).returns("KKKKKKKK")
127 assert_equal 'KKKKKKKK', pick_date(:object, :method) 103 assert_equal 'KKKKKKKK', pick_date(:object, :method)
128 end 104 end
129 105
130 should 'order date in english like month day year' do 106 should 'order date in english like month day year' do
131 - expects(:language).returns("en")  
132 - expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:month, :day, :year], :use_month_names => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']}).returns("KKKKKKKK") 107 + expects(:language).returns('en')
  108 + expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:month, :day, :year], :use_month_names => MONTHS }).returns("KKKKKKKK")
133 109
134 assert_equal 'KKKKKKKK', pick_date(:object, :method) 110 assert_equal 'KKKKKKKK', pick_date(:object, :method)
135 end 111 end
136 112
137 should 'order date in other languages like day month year' do 113 should 'order date in other languages like day month year' do
138 expects(:language).returns('pt_BR') 114 expects(:language).returns('pt_BR')
139 - expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:day, :month, :year], :use_month_names => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']}).returns("KKKKKKKK") 115 + expects(:date_select).with(:object, :method, { :include_blank => true, :order => [:day, :month, :year], :use_month_names => MONTHS }).returns("KKKKKKKK")
140 116
141 assert_equal 'KKKKKKKK', pick_date(:object, :method) 117 assert_equal 'KKKKKKKK', pick_date(:object, :method)
142 end 118 end
@@ -151,9 +127,7 @@ class DatesHelperTest &lt; ActiveSupport::TestCase @@ -151,9 +127,7 @@ class DatesHelperTest &lt; ActiveSupport::TestCase
151 127
152 should 'translate time' do 128 should 'translate time' do
153 time = Time.parse('25 May 2009, 12:47') 129 time = Time.parse('25 May 2009, 12:47')
154 - expects(:_).with('%{day} %{month} %{year}, %{hour}:%{minutes}').returns('translated time')  
155 - stubs(:_).with('May').returns("Maio")  
156 - assert_equal 'translated time', show_time(time) 130 + assert_equal '25 May 2009, 12:47', show_time(time)
157 end 131 end
158 132
159 should 'handle nil time' do 133 should 'handle nil time' do