Commit ea468c0ec1b11947fb88092e9b92659bbb0dd956

Authored by Victor Costa
2 parents 135c10f9 a1f85f37

Merge branch 'block-admin-mail' into production

Conflicts:
	app/models/event.rb
	app/models/profile.rb
	po/fr/noosfero.po
Showing 73 changed files with 616 additions and 428 deletions   Show diff stats
.gitlab-ci.yml 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +before_script:
  2 + - mkdir -p tmp/pids log
  3 + - bundle check || bundle install
  4 + - script/noosfero-plugins disableall
  5 + - rm -f tmp/makemo.stamp && rake makemo &>/dev/null
  6 +# database
  7 + - cp config/database.yml.gitlab-ci config/database.yml
  8 + - createdb gitlab_ci_test || true
  9 + - bundle exec rake db:schema:load &>/dev/null
  10 + - bundle exec rake db:migrate &>/dev/null
  11 +
  12 +units:
  13 + script: bundle exec rake test:units
  14 +functionals:
  15 + script: bundle exec rake test:functionals
  16 +integration:
  17 + script: bundle exec rake test:integration
  18 +cucumber:
  19 + script: bundle exec rake cucumber
  20 +selenium:
  21 + script: bundle exec rake selenium
  22 +plugins:
  23 + script: bundle exec rake test:noosfero_plugins
  24 +
.travis.yml 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +language: ruby
  2 +rvm:
  3 +# for 2.2 support we need to upgrade the pg gem
  4 + - 2.1.6
  5 +
  6 +before_install:
  7 +# dependencies
  8 + - sudo apt-get update
  9 + - sudo apt-get -y install po4a iso-codes tango-icon-theme pidgin-data default-jre
  10 + - sudo apt-get -y install libmagickwand-dev libpq-dev libreadline-dev libsqlite3-dev libxslt1-dev
  11 +# selenium support
  12 + - export DISPLAY=:99.0
  13 + - sh -e /etc/init.d/xvfb start
  14 +
  15 +before_script:
  16 + - mkdir -p tmp/pids log
  17 + - bundle check || bundle install
  18 + - script/noosfero-plugins disableall
  19 + - rake makemo
  20 +# database
  21 + - cp config/database.yml.travis config/database.yml
  22 + - psql -c 'create database myapp_test;' -U postgres
  23 + - bundle exec rake db:schema:load
  24 + - bundle exec rake db:migrate
  25 +
  26 +env:
  27 + - TASK=test:units
  28 + - TASK=test:functionals
  29 + - TASK=test:integration
  30 + - TASK=cucumber
  31 + - TASK=selenium
  32 + - TASK=test:noosfero_plugins
  33 +
  34 +script:
  35 + - bundle exec rake $TASK
  36 +
1 source "https://rubygems.org" 1 source "https://rubygems.org"
2 -gem 'rails', '~> 3.2.21' 2 +gem 'rails', '~> 3.2.22'
3 gem 'minitest', '~> 3.2.0' 3 gem 'minitest', '~> 3.2.0'
4 gem 'fast_gettext', '~> 0.6.8' 4 gem 'fast_gettext', '~> 0.6.8'
5 gem 'acts-as-taggable-on', '~> 3.4.2' 5 gem 'acts-as-taggable-on', '~> 3.4.2'
@@ -40,6 +40,7 @@ group :test do @@ -40,6 +40,7 @@ group :test do
40 gem 'rspec', '~> 2.14.0' 40 gem 'rspec', '~> 2.14.0'
41 gem 'rspec-rails', '~> 2.14.1' 41 gem 'rspec-rails', '~> 2.14.1'
42 gem 'mocha', '~> 1.1.0', :require => false 42 gem 'mocha', '~> 1.1.0', :require => false
  43 + gem 'test-unit' if RUBY_VERSION >= '2.2.0'
43 end 44 end
44 45
45 group :cucumber do 46 group :cucumber do
app/controllers/application_controller.rb
@@ -77,8 +77,8 @@ class ApplicationController < ActionController::Base @@ -77,8 +77,8 @@ class ApplicationController < ActionController::Base
77 FastGettext.available_locales = environment.available_locales 77 FastGettext.available_locales = environment.available_locales
78 FastGettext.default_locale = environment.default_locale 78 FastGettext.default_locale = environment.default_locale
79 FastGettext.locale = (params[:lang] || session[:lang] || environment.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') 79 FastGettext.locale = (params[:lang] || session[:lang] || environment.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
80 - I18n.locale = FastGettext.locale  
81 - I18n.default_locale = FastGettext.default_locale 80 + I18n.locale = FastGettext.locale.to_s.gsub '_', '-'
  81 + I18n.default_locale = FastGettext.default_locale.to_s.gsub '_', '-'
82 if params[:lang] 82 if params[:lang]
83 session[:lang] = params[:lang] 83 session[:lang] = params[:lang]
84 end 84 end
app/controllers/my_profile/cms_controller.rb
@@ -6,7 +6,7 @@ class CmsController < MyProfileController @@ -6,7 +6,7 @@ class CmsController < MyProfileController
6 6
7 def search_tags 7 def search_tags
8 arg = params[:term].downcase 8 arg = params[:term].downcase
9 - result = ActsAsTaggableOn::Tag.find(:all, :conditions => ['LOWER(name) LIKE ?', "%#{arg}%"]) 9 + result = ActsAsTaggableOn::Tag.where('name ILIKE ?', "%#{arg}%").limit(10)
10 render :text => prepare_to_token_input_by_label(result).to_json, :content_type => 'application/json' 10 render :text => prepare_to_token_input_by_label(result).to_json, :content_type => 'application/json'
11 end 11 end
12 12
@@ -94,6 +94,11 @@ class CmsController < MyProfileController @@ -94,6 +94,11 @@ class CmsController < MyProfileController
94 record_coming 94 record_coming
95 if request.post? 95 if request.post?
96 @article.image = nil if params[:remove_image] == 'true' 96 @article.image = nil if params[:remove_image] == 'true'
  97 + if @article.image.present? && params[:article][:image_builder] &&
  98 + params[:article][:image_builder][:label]
  99 + @article.image.label = params[:article][:image_builder][:label]
  100 + @article.image.save!
  101 + end
97 @article.last_changed_by = user 102 @article.last_changed_by = user
98 if @article.update_attributes(params[:article]) 103 if @article.update_attributes(params[:article])
99 if !continue 104 if !continue
app/helpers/application_helper.rb
@@ -1185,7 +1185,7 @@ module ApplicationHelper @@ -1185,7 +1185,7 @@ module ApplicationHelper
1185 pending_tasks_count = link_to("<i class=\"icon-menu-tasks\"></i><span class=\"task-count\">#{count}</span>", user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) 1185 pending_tasks_count = link_to("<i class=\"icon-menu-tasks\"></i><span class=\"task-count\">#{count}</span>", user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
1186 end 1186 end
1187 1187
1188 - (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))) + 1188 + (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) +
1189 render_environment_features(:usermenu) + 1189 render_environment_features(:usermenu) +
1190 admin_link + 1190 admin_link +
1191 manage_enterprises + 1191 manage_enterprises +
@@ -1234,7 +1234,7 @@ module ApplicationHelper @@ -1234,7 +1234,7 @@ module ApplicationHelper
1234 1234
1235 def task_information(task) 1235 def task_information(task)
1236 values = {} 1236 values = {}
1237 - values.merge!({:requestor => link_to(task.requestor.name, task.requestor.public_profile_url)}) if task.requestor 1237 + values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor
1238 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject 1238 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
1239 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject 1239 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject
1240 values.merge!(task.information[:variables]) if task.information[:variables] 1240 values.merge!(task.information[:variables]) if task.information[:variables]
app/helpers/comment_helper.rb
@@ -16,7 +16,7 @@ module CommentHelper @@ -16,7 +16,7 @@ module CommentHelper
16 content_tag('span', show_date(article.published_at), :class => 'date') + 16 content_tag('span', show_date(article.published_at), :class => 'date') +
17 content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') + 17 content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') +
18 content_tag('span', comments, :class => 'comments'), 18 content_tag('span', comments, :class => 'comments'),
19 - :class => 'created-at' 19 + :class => 'publishing-info'
20 ) 20 )
21 end 21 end
22 title 22 title
app/helpers/content_viewer_helper.rb
@@ -30,7 +30,7 @@ module ContentViewerHelper @@ -30,7 +30,7 @@ module ContentViewerHelper
30 date_format + 30 date_format +
31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + 31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
32 content_tag('span', comments, :class => 'comments'), 32 content_tag('span', comments, :class => 'comments'),
33 - :class => 'created-at' 33 + :class => 'publishing-info'
34 ) 34 )
35 end 35 end
36 title 36 title
app/models/article.rb
@@ -145,7 +145,7 @@ class Article &lt; ActiveRecord::Base @@ -145,7 +145,7 @@ class Article &lt; ActiveRecord::Base
145 145
146 scope :by_range, lambda { |range| { 146 scope :by_range, lambda { |range| {
147 :conditions => [ 147 :conditions => [
148 - 'published_at BETWEEN :start_date AND :end_date', { :start_date => range.first, :end_date => range.last } 148 + 'articles.published_at BETWEEN :start_date AND :end_date', { :start_date => range.first, :end_date => range.last }
149 ] 149 ]
150 }} 150 }}
151 151
@@ -748,8 +748,9 @@ class Article &lt; ActiveRecord::Base @@ -748,8 +748,9 @@ class Article &lt; ActiveRecord::Base
748 paragraphs.empty? ? '' : paragraphs.first.to_html 748 paragraphs.empty? ? '' : paragraphs.first.to_html
749 end 749 end
750 750
751 - def lead  
752 - abstract.blank? ? first_paragraph.html_safe : abstract.html_safe 751 + def lead(length = nil)
  752 + content = abstract.blank? ? first_paragraph.html_safe : abstract.html_safe
  753 + length.present? ? content.truncate(length) : content
753 end 754 end
754 755
755 def short_lead 756 def short_lead
app/models/event.rb
@@ -99,47 +99,19 @@ class Event &lt; Article @@ -99,47 +99,19 @@ class Event &lt; Article
99 start_date..(end_date||start_date) 99 start_date..(end_date||start_date)
100 end 100 end
101 101
102 - # FIXME this shouldn't be needed  
103 - include ActionView::Helpers::TagHelper  
104 - include ActionView::Helpers::UrlHelper  
105 - include DatesHelper 102 + def first_paragraph
  103 + paragraphs = Nokogiri::HTML.fragment(self.body).css('p')
  104 + paragraphs.empty? ? '' : paragraphs.first.to_html
  105 + end
106 106
107 def to_html(options = {}) 107 def to_html(options = {})
  108 + event = self
  109 + format = options[:format]
108 110
109 - result = ''  
110 - html = ::Builder::XmlMarkup.new(:target => result)  
111 -  
112 - html.div(:class => 'event-info' ) {  
113 - html.ul(:class => 'event-data' ) {  
114 - html.li(:class => 'event-dates' ) {  
115 - html.span _('When:')  
116 - html.text! show_period(start_date, end_date)  
117 - } if start_date.present? || end_date.present?  
118 - html.li {  
119 - html.span _('URL:')  
120 - html.a(self.link || "", 'href' => self.link || "")  
121 - } if self.link.present?  
122 - html.li {  
123 - html.span _('Address:')  
124 - html.text! self.address || ""  
125 - } if self.address.present?  
126 - }  
127 -  
128 - # TODO: some good soul, please clean this ugly hack:  
129 - if self.body  
130 - html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')  
131 - end  
132 - }  
133 -  
134 - if self.body  
135 - #if options[:format] == 'short'  
136 - # result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))  
137 - #else  
138 - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)  
139 - #end 111 + proc do
  112 + render :file => 'content_viewer/event_page', :locals => { :event => event,
  113 + :format => format }
140 end 114 end
141 -  
142 - result  
143 end 115 end
144 116
145 def duration 117 def duration
app/models/image.rb
@@ -23,7 +23,7 @@ class Image &lt; ActiveRecord::Base @@ -23,7 +23,7 @@ class Image &lt; ActiveRecord::Base
23 23
24 postgresql_attachment_fu 24 postgresql_attachment_fu
25 25
26 - attr_accessible :uploaded_data 26 + attr_accessible :uploaded_data, :label
27 27
28 def current_data 28 def current_data
29 File.file?(full_filename) ? File.read(full_filename) : nil 29 File.file?(full_filename) ? File.read(full_filename) : nil
app/models/organization.rb
@@ -154,6 +154,12 @@ class Organization &lt; Profile @@ -154,6 +154,12 @@ class Organization &lt; Profile
154 ] 154 ]
155 end 155 end
156 156
  157 + def short_name chars = 40
  158 + s = self.display_name
  159 + s = super(chars) if s.blank?
  160 + s
  161 + end
  162 +
157 def notification_emails 163 def notification_emails
158 emails = [contact_email].select(&:present?) + admins.map(&:email) 164 emails = [contact_email].select(&:present?) + admins.map(&:email)
159 if emails.empty? 165 if emails.empty?
app/models/profile.rb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 # which by default is the one returned by Environment:default. 3 # which by default is the one returned by Environment:default.
4 class Profile < ActiveRecord::Base 4 class Profile < ActiveRecord::Base
5 5
6 - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :custom_fields 6 + attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :custom_fields, :administrator_mail_notification
7 7
8 # use for internationalizable human type names in search facets 8 # use for internationalizable human type names in search facets
9 # reimplement on subclasses 9 # reimplement on subclasses
@@ -219,6 +219,7 @@ class Profile &lt; ActiveRecord::Base @@ -219,6 +219,7 @@ class Profile &lt; ActiveRecord::Base
219 settings_items :description 219 settings_items :description
220 settings_items :fields_privacy, :type => :hash, :default => {} 220 settings_items :fields_privacy, :type => :hash, :default => {}
221 settings_items :email_suggestions, :type => :boolean, :default => false 221 settings_items :email_suggestions, :type => :boolean, :default => false
  222 + settings_items :administrator_mail_notification, :type => :boolean, :default => true
222 223
223 validates_length_of :description, :maximum => 550, :allow_nil => true 224 validates_length_of :description, :maximum => 550, :allow_nil => true
224 225
app/models/task.rb
@@ -70,7 +70,9 @@ class Task &lt; ActiveRecord::Base @@ -70,7 +70,9 @@ class Task &lt; ActiveRecord::Base
70 begin 70 begin
71 target_msg = task.target_notification_message 71 target_msg = task.target_notification_message
72 if target_msg && task.target && !task.target.notification_emails.empty? 72 if target_msg && task.target && !task.target.notification_emails.empty?
73 - TaskMailer.target_notification(task, target_msg).deliver 73 + if target_profile_accepts_notification?(task)
  74 + TaskMailer.target_notification(task, target_msg).deliver
  75 + end
74 end 76 end
75 rescue Exception => ex 77 rescue Exception => ex
76 Rails.logger.info ex.to_s 78 Rails.logger.info ex.to_s
@@ -78,6 +80,18 @@ class Task &lt; ActiveRecord::Base @@ -78,6 +80,18 @@ class Task &lt; ActiveRecord::Base
78 end 80 end
79 end 81 end
80 82
  83 + def target_profile_accepts_notification?(task)
  84 + if target_is_profile?(task)
  85 + return task.target.administrator_mail_notification
  86 + else
  87 + true
  88 + end
  89 + end
  90 +
  91 + def target_is_profile?(task)
  92 + task.target.kind_of? Profile
  93 + end
  94 +
81 # this method finished the task. It calls #perform, which must be overriden 95 # this method finished the task. It calls #perform, which must be overriden
82 # by subclasses. At the end a message (as returned by #finish_message) is 96 # by subclasses. At the end a message (as returned by #finish_message) is
83 # sent to the requestor with #notify_requestor. 97 # sent to the requestor with #notify_requestor.
app/models/user.rb
@@ -334,6 +334,8 @@ class User &lt; ActiveRecord::Base @@ -334,6 +334,8 @@ class User &lt; ActiveRecord::Base
334 334
335 { 335 {
336 'login' => self.login, 336 'login' => self.login,
  337 + 'name' => self.person.name,
  338 + 'email' => self.email,
337 'avatar' => self.person.profile_custom_icon(gravatar_default), 339 'avatar' => self.person.profile_custom_icon(gravatar_default),
338 'is_admin' => self.person.is_admin?, 340 'is_admin' => self.person.is_admin?,
339 'since_month' => self.person.created_at.month, 341 'since_month' => self.person.created_at.month,
app/views/content_viewer/_article_title.html.erb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +<% if @page.belongs_to_blog? || @page.belongs_to_forum?%>
  2 + <h1 class="title">
  3 + <% if no_link %>
  4 + <%= h(@page.title) %>
  5 + <% else %>
  6 + <%= link_to(@page.name, @page.url) %>
  7 + <% end %>
  8 + </h1>
  9 + <%= render :partial => "publishing_info" %>
  10 + <% unless @page.abstract.blank? %>
  11 + <div class="preview">
  12 + <%= @page.lead %>
  13 + </div>
  14 + <% end %>
  15 +<% else %>
  16 + <h1 class="title">
  17 + <%= h(@page.title) %>
  18 + </h1>
  19 + <%= render :partial => "publishing_info" %>
  20 +<% end %>
app/views/content_viewer/_article_toolbar.html.erb
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 <% end %> 64 <% end %>
65 <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> 65 <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> 66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
67 - <%= article_title(@page, :no_link => true) %> 67 + <%= render :partial => 'article_title', :locals => {:no_link => true} %>
68 <%= article_translations(@page) %> 68 <%= article_translations(@page) %>
69 </div> 69 </div>
70 </div> 70 </div>
app/views/content_viewer/_display_compact_format.html.erb
@@ -16,6 +16,6 @@ @@ -16,6 +16,6 @@
16 </div> 16 </div>
17 <% end %> 17 <% end %>
18 <div class = <%= className %> > 18 <div class = <%= className %> >
19 - <%= article.abstract.truncate(400) %> 19 + <%= article.lead(400) %>
20 </div> 20 </div>
21 </div> 21 </div>
app/views/content_viewer/_publishing_info.html.erb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +<span class="publishing-info">
  2 + <span class="date">
  3 + <%= show_date(@page.published_at) %>
  4 + </span>
  5 + <span class="author">
  6 + <%= _(", by %s") % (@page.author ? link_to(@page.author_name, @page.author_url) : @page.author_name) %>
  7 + </span>
  8 +<% unless @no_comments %>
  9 + <span class="comments">
  10 + <%= (" - %s") % link_to_comments(@page)%>
  11 + </span>
  12 +<% end %>
  13 +</span>
  14 +
  15 +<% if @page.display_hits? || @page.license.present? %>
  16 + <div id='article-sub-header'>
  17 + <% if @page.display_hits? %>
  18 + <div id="article-hits">
  19 + <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %>
  20 + </div>
  21 + <% end %>
  22 +
  23 + <% if @page.license.present? %>
  24 + <div id="article-license">
  25 + <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %>
  26 + </div>
  27 + <% end %>
  28 + </div>
  29 +<% end %>
app/views/content_viewer/event_page.html.erb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<div class="event-card">
  2 + <div class="event-image">
  3 + <% if event.image %>
  4 + <%= image_tag(event.image.public_filename(:big)) %>
  5 + <% end %>
  6 + </div>
  7 + <div class="about-event">
  8 + <% if event.start_date.present? || event.end_date.present? %>
  9 + <span class="event-date">
  10 + <%= show_period(event.start_date, event.end_date) %>
  11 + </span>
  12 + <% end %>
  13 + <% if event.link.present? %>
  14 + <span class="event-link">
  15 + <%= link_to event.link, event.link %>
  16 + </span>
  17 + <% end %>
  18 + <% if event.address.present? %>
  19 + <span class="event-address">
  20 + <span>
  21 + <%= event.address %>
  22 + </span>
  23 + </span>
  24 + <% end %>
  25 + </div>
  26 +</div>
  27 +
  28 +<div class="event-body">
  29 + <% if format == 'short' %>
  30 + <%= display_short_format event, :comments_link => false, :read_more_link => false %>
  31 + <% else %>
  32 + <% unless event.abstract.blank? %>
  33 + <div class="event-lead">
  34 + <%= event.article_lead %>
  35 + </div>
  36 + <% end %>
  37 + <div class="event-content">
  38 + <%= event.body %>
  39 + </div>
  40 + <% end %>
  41 +</div>
app/views/content_viewer/view_page.html.erb
@@ -24,22 +24,6 @@ @@ -24,22 +24,6 @@
24 <%= render :partial => 'article_toolbar' %> 24 <%= render :partial => 'article_toolbar' %>
25 </div> 25 </div>
26 26
27 -<% if @page.display_hits? || @page.license.present? %>  
28 - <div id='article-sub-header'>  
29 - <% if @page.display_hits? %>  
30 - <div id="article-hits">  
31 - <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %>  
32 - </div>  
33 - <% end %>  
34 -  
35 - <% if @page.license.present? %>  
36 - <div id="article-license">  
37 - <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %>  
38 - </div>  
39 - <% end %>  
40 - </div>  
41 -<% end %>  
42 -  
43 <% if NOOSFERO_CONF['addthis_enabled'] %> 27 <% if NOOSFERO_CONF['addthis_enabled'] %>
44 <%= render :partial => 'addthis' %> 28 <%= render :partial => 'addthis' %>
45 <% end %> 29 <% end %>
@@ -47,6 +31,12 @@ @@ -47,6 +31,12 @@
47 <% cache(@page.cache_key(params, user, language)) do %> 31 <% cache(@page.cache_key(params, user, language)) do %>
48 <div class="<%="article-body article-body-" + @page.css_class_name %>"> 32 <div class="<%="article-body article-body-" + @page.css_class_name %>">
49 <% options = @page.image? ? {:gallery_view => true} : {} %> 33 <% options = @page.image? ? {:gallery_view => true} : {} %>
  34 + <% if @page.image.present? && !@page.event? %>
  35 + <div class="article-body-img">
  36 + <%= image_tag(@page.image.public_filename) %>
  37 + <p><%= @page.image.label%></p>
  38 + </div>
  39 + <% end %>
50 <%= article_to_html(@page, options) %> 40 <%= article_to_html(@page, options) %>
51 <br style="clear:both" /> 41 <br style="clear:both" />
52 </div> <!-- end class="article-body" --> 42 </div> <!-- end class="article-body" -->
app/views/layouts/application-ng.html.erb
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 27
28 <script type="text/javascript"> 28 <script type="text/javascript">
29 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>; 29 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>;
  30 + noosfero.profile = <%= (@profile.identifier if @profile).to_json %>
30 </script> 31 </script>
31 32
32 </head> 33 </head>
app/views/manage_products/_categories_autocomplete.html.erb
1 <%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %> 1 <%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>
2 2
3 <%= javascript_include_tag '/javascripts/product_categories.js' %> 3 <%= javascript_include_tag '/javascripts/product_categories.js' %>
4 -<% javascript_tag do %> 4 +<%= javascript_tag do %>
5 product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %> 5 product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %>
6 product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %> 6 product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %>
7 product_categories.autocomplete.load('#product_category_id') 7 product_categories.autocomplete.load('#product_category_id')
app/views/profile_editor/_moderation.html.erb
1 <h2><%= _('Moderation options') %></h2> 1 <h2><%= _('Moderation options') %></h2>
2 <% if profile.community? %> 2 <% if profile.community? %>
3 <div style='margin-bottom: 1em'> 3 <div style='margin-bottom: 1em'>
  4 + <h4><%= _('Email Configuration:')%></h4>
  5 + </div>
  6 + <div style='margin-bottom: 0.5em'>
  7 + <%= check_box(:profile_data, :administrator_mail_notification, :style => 'float: left') %>
  8 + <div style='margin-left: 30px'>
  9 + <%= _('Send administrator Email for every task (Default: yes)') %>
  10 + </div>
  11 + </div>
  12 +
  13 + <div style='margin-bottom: 1em'>
4 <h4><%= _('Invitation moderation:')%></h4> 14 <h4><%= _('Invitation moderation:')%></h4>
5 </div> 15 </div>
6 <div style='margin-bottom: 0.5em'> 16 <div style='margin-bottom: 0.5em'>
app/views/shared/_change_image.html.erb
1 - <%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>  
2 - <%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%> 1 +<%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>
  2 +<%= labelled_form_field(_("Image Label:"), i.text_field(:label)) %>
  3 +<%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%>
config/database.yml.gitlab-ci 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +test: &TEST
  2 + adapter: postgresql
  3 + database: gitlab_ci_test
  4 + username: gitlab_ci_runner
  5 +development:
  6 + <<: *TEST
config/database.yml.travis 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +# From http://about.travis-ci.org/docs/user/database-setup/
  2 +test:
  3 + adapter: postgresql
  4 + database: myapp_test
  5 + username: postgres
config/environments/staging.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +# inherit from production
  2 +require_relative 'production'
  3 +
  4 +Noosfero::Application.configure do
  5 +
  6 + # expose errors
  7 + config.consider_all_requests_local = true
  8 +
  9 + # ease debug
  10 + config.assets.compress = false
  11 +
  12 +end
  13 +
config/locales/de.yml
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 # contributors: 3 # contributors:
4 # - Alexander Dreher - http://github.com/alexdreher - Rails 3 update 4 # - Alexander Dreher - http://github.com/alexdreher - Rails 3 update
5 5
6 -de: 6 +de: &de
7 date: 7 date:
8 formats: 8 formats:
9 default: "%d.%m.%Y" 9 default: "%d.%m.%Y"
@@ -221,3 +221,6 @@ de: @@ -221,3 +221,6 @@ de:
221 221
222 full_messages: 222 full_messages:
223 format: "%{attribute} %{message}" 223 format: "%{attribute} %{message}"
  224 +
  225 +de-DE:
  226 + <<: *de
config/locales/en-US.yml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # 2 #
3 # Use this as the base for the locale file of your language. 3 # Use this as the base for the locale file of your language.
4 4
5 -"en-US": 5 +"en-US": &en-US
6 date: 6 date:
7 formats: 7 formats:
8 default: "%Y-%m-%d" 8 default: "%Y-%m-%d"
@@ -220,4 +220,7 @@ @@ -220,4 +220,7 @@
220 template: 220 template:
221 <<: *errors_template 221 <<: *errors_template
222 full_messages: 222 full_messages:
223 - format: "%{attribute} %{message}"  
224 \ No newline at end of file 223 \ No newline at end of file
  224 + format: "%{attribute} %{message}"
  225 +
  226 +en:
  227 + <<: *en-US
config/locales/en.yml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +en-US.yml
0 \ No newline at end of file 2 \ No newline at end of file
config/locales/es.yml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 # - Tsutomu Kuroda - http://github.com/kuroda (t-kuroda@oiax.jp) 4 # - Tsutomu Kuroda - http://github.com/kuroda (t-kuroda@oiax.jp)
5 # Corrected by Eloy Serra Labán: http://goo.gl/i9Kts, /nQ928, /XfKaX 5 # Corrected by Eloy Serra Labán: http://goo.gl/i9Kts, /nQ928, /XfKaX
6 6
7 -"es": 7 +es: &es
8 date: 8 date:
9 formats: 9 formats:
10 default: "%d/%m/%Y" 10 default: "%d/%m/%Y"
@@ -223,3 +223,6 @@ @@ -223,3 +223,6 @@
223 223
224 full_messages: 224 full_messages:
225 format: "%{attribute} %{message}" 225 format: "%{attribute} %{message}"
  226 +
  227 +es_ES:
  228 + <<: *es
config/locales/fr-FR.yml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +fr.yml
0 \ No newline at end of file 2 \ No newline at end of file
config/locales/fr.yml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 # - Bruno Michel - http://github.com/nono 5 # - Bruno Michel - http://github.com/nono
6 # - Tsutomu Kuroda - http://github.com/kuroda (t-kuroda@oiax.jp) 6 # - Tsutomu Kuroda - http://github.com/kuroda (t-kuroda@oiax.jp)
7 7
8 -fr: 8 +fr: &fr
9 date: 9 date:
10 formats: 10 formats:
11 default: "%d/%m/%Y" 11 default: "%d/%m/%Y"
@@ -222,3 +222,7 @@ fr: @@ -222,3 +222,7 @@ fr:
222 <<: *errors_template 222 <<: *errors_template
223 full_messages: 223 full_messages:
224 format: "%{attribute} %{message}" 224 format: "%{attribute} %{message}"
  225 +
  226 +fr-FR:
  227 + <<: *fr
  228 +
config/locales/hr.yml
@@ -176,4 +176,4 @@ @@ -176,4 +176,4 @@
176 template: 176 template:
177 <<: *errors_template 177 <<: *errors_template
178 full_messages: 178 full_messages:
179 - format: "%{attribute} %{message}"  
180 \ No newline at end of file 179 \ No newline at end of file
  180 + format: "%{attribute} %{message}"
config/locales/hy-AM.yml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +hy.yml
0 \ No newline at end of file 2 \ No newline at end of file
config/locales/hy.yml
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 # FIXME: This is a copy of en-US.yml. Armenian translators, please translate 3 # FIXME: This is a copy of en-US.yml. Armenian translators, please translate
4 # this into Armenian. 4 # this into Armenian.
5 5
6 -"hy": 6 +hy: &hy
7 date: 7 date:
8 formats: 8 formats:
9 default: "%Y-%m-%d" 9 default: "%Y-%m-%d"
@@ -222,3 +222,6 @@ @@ -222,3 +222,6 @@
222 <<: *errors_template 222 <<: *errors_template
223 full_messages: 223 full_messages:
224 format: "%{attribute} %{message}" 224 format: "%{attribute} %{message}"
  225 +
  226 +hy-AM:
  227 + <<: *hy
config/locales/it.yml
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 # - Simone Carletti (weppos@weppos.net) 5 # - Simone Carletti (weppos@weppos.net)
6 # - Davide Guerri (d.guerri@caspur.it) 6 # - Davide Guerri (d.guerri@caspur.it)
7 7
8 -it: 8 +it: &it
9 number: 9 number:
10 format: 10 format:
11 delimiter: "," 11 delimiter: ","
@@ -234,3 +234,6 @@ it: @@ -234,3 +234,6 @@ it:
234 234
235 full_messages: 235 full_messages:
236 format: "%{attribute} %{message}" 236 format: "%{attribute} %{message}"
  237 +
  238 +it_IT:
  239 + <<: *it
config/locales/pt-BR.yml
1 # encoding: UTF-8 1 # encoding: UTF-8
2 # pt-BR translations for Ruby on Rails 2 # pt-BR translations for Ruby on Rails
3 -"pt-BR": 3 +
  4 +"pt-BR": &pt-BR
4 # formatos de data e hora 5 # formatos de data e hora
5 date: 6 date:
6 formats: 7 formats:
@@ -231,3 +232,6 @@ @@ -231,3 +232,6 @@
231 232
232 full_messages: 233 full_messages:
233 format: "%{attribute} %{message}" 234 format: "%{attribute} %{message}"
  235 +
  236 +pt:
  237 + <<: *pt-BR
config/locales/pt.yml
@@ -1,233 +0,0 @@ @@ -1,233 +0,0 @@
1 -# encoding: UTF-8  
2 -# pt-BR translations for Ruby on Rails  
3 -"pt":  
4 - # formatos de data e hora  
5 - date:  
6 - formats:  
7 - default: "%d/%m/%Y"  
8 - short: "%d de %B"  
9 - long: "%d de %B de %Y"  
10 -  
11 - day_names:  
12 - - Domingo  
13 - - Segunda  
14 - - Terça  
15 - - Quarta  
16 - - Quinta  
17 - - Sexta  
18 - - Sábado  
19 - abbr_day_names:  
20 - - Dom  
21 - - Seg  
22 - - Ter  
23 - - Qua  
24 - - Qui  
25 - - Sex  
26 - - Sáb  
27 -  
28 - month_names:  
29 - - ~  
30 - - Janeiro  
31 - - Fevereiro  
32 - - Março  
33 - - Abril  
34 - - Maio  
35 - - Junho  
36 - - Julho  
37 - - Agosto  
38 - - Setembro  
39 - - Outubro  
40 - - Novembro  
41 - - Dezembro  
42 - abbr_month_names:  
43 - - ~  
44 - - Jan  
45 - - Fev  
46 - - Mar  
47 - - Abr  
48 - - Mai  
49 - - Jun  
50 - - Jul  
51 - - Ago  
52 - - Set  
53 - - Out  
54 - - Nov  
55 - - Dez  
56 - order:  
57 - - :day  
58 - - :month  
59 - - :year  
60 -  
61 - time:  
62 - formats:  
63 - default: "%A, %d de %B de %Y, %H:%M h"  
64 - short: "%d/%m, %H:%M h"  
65 - long: "%A, %d de %B de %Y, %H:%M h"  
66 - am: ''  
67 - pm: ''  
68 -  
69 - # Usado no Array.to_sentence  
70 - support:  
71 - array:  
72 - words_connector: ", "  
73 - two_words_connector: " e "  
74 - last_word_connector: " e "  
75 -  
76 - select:  
77 - prompt: "Por favor selecione"  
78 -  
79 - number:  
80 - format:  
81 - separator: ','  
82 - delimiter: '.'  
83 - precision: 3  
84 - significant: false  
85 - strip_insignificant_zeros: false  
86 -  
87 - currency:  
88 - format:  
89 - format: '%u %n'  
90 - unit: 'R$'  
91 - separator: ','  
92 - delimiter: '.'  
93 - precision: 2  
94 - significant: false  
95 - strip_insignificant_zeros: false  
96 -  
97 - percentage:  
98 - format:  
99 - delimiter: '.'  
100 -  
101 - precision:  
102 - format:  
103 - delimiter: '.'  
104 -  
105 - human:  
106 - format:  
107 - delimiter: '.'  
108 - precision: 2  
109 - significant: true  
110 - strip_insignificant_zeros: true  
111 - storage_units:  
112 - format: "%n %u"  
113 - units:  
114 - byte:  
115 - one: "Byte"  
116 - other: "Bytes"  
117 - kb: "KB"  
118 - mb: "MB"  
119 - gb: "GB"  
120 - tb: "TB"  
121 - # number_to_human()  
122 - # new in rails 3: please add to other locales  
123 - decimal_units:  
124 - format: "%n %u"  
125 - units:  
126 - unit: ""  
127 - thousand: "mil"  
128 - million:  
129 - one: milhão  
130 - other: milhões  
131 - billion:  
132 - one: bilhão  
133 - other: bilhões  
134 - trillion:  
135 - one: trilhão  
136 - other: trilhões  
137 - quadrillion:  
138 - one: quatrilhão  
139 - other: quatrilhões  
140 -  
141 - # distancia do tempo em palavras  
142 - datetime:  
143 - distance_in_words:  
144 - half_a_minute: 'meio minuto'  
145 - less_than_x_seconds:  
146 - one: 'menos de 1 segundo'  
147 - other: 'menos de %{count} segundos'  
148 - x_seconds:  
149 - one: '1 segundo'  
150 - other: '%{count} segundos'  
151 - less_than_x_minutes:  
152 - one: 'menos de um minuto'  
153 - other: 'menos de %{count} minutos'  
154 - x_minutes:  
155 - one: '1 minuto'  
156 - other: '%{count} minutos'  
157 - about_x_hours:  
158 - one: 'aproximadamente 1 hora'  
159 - other: 'aproximadamente %{count} horas'  
160 - x_days:  
161 - one: '1 dia'  
162 - other: '%{count} dias'  
163 - about_x_months:  
164 - one: 'aproximadamente 1 mês'  
165 - other: 'aproximadamente %{count} meses'  
166 - x_months:  
167 - one: '1 mês'  
168 - other: '%{count} meses'  
169 - about_x_years:  
170 - one: 'aproximadamente 1 ano'  
171 - other: 'aproximadamente %{count} anos'  
172 - over_x_years:  
173 - one: 'mais de 1 ano'  
174 - other: 'mais de %{count} anos'  
175 - almost_x_years:  
176 - one: 'quase 1 ano'  
177 - other: 'quase %{count} anos'  
178 - prompts:  
179 - year: "Ano"  
180 - month: "Mês"  
181 - day: "Dia"  
182 - hour: "Hora"  
183 - minute: "Minuto"  
184 - second: "Segundo"  
185 -  
186 - helpers:  
187 - select:  
188 - prompt: "Por favor selecione"  
189 -  
190 - submit:  
191 - create: 'Criar %{model}'  
192 - update: 'Atualizar %{model}'  
193 - submit: 'Salvar %{model}'  
194 -  
195 - errors:  
196 - format: "%{attribute} %{message}"  
197 - messages: &errors_messages  
198 - inclusion: "não está incluído na lista"  
199 - exclusion: "não está disponível"  
200 - invalid: "não é válido"  
201 - confirmation: "não está de acordo com a confirmação"  
202 - accepted: "deve ser aceito"  
203 - empty: "não pode ficar vazio"  
204 - blank: "não pode ficar em branco"  
205 - too_long: "é muito longo (máximo: %{count} caracteres)"  
206 - too_short: "é muito curto (mínimo: %{count} caracteres)"  
207 - wrong_length: "não possui o tamanho esperado (%{count} caracteres)"  
208 - not_a_number: "não é um número"  
209 - not_an_integer: "não é um número inteiro"  
210 - greater_than: "deve ser maior que %{count}"  
211 - greater_than_or_equal_to: "deve ser maior ou igual a %{count}"  
212 - equal_to: "deve ser igual a %{count}"  
213 - less_than: "deve ser menor que %{count}"  
214 - less_than_or_equal_to: "deve ser menor ou igual a %{count}"  
215 - odd: "deve ser ímpar"  
216 - even: "deve ser par"  
217 - taken: "já está em uso"  
218 - record_invalid: "A validação falhou: %{errors}"  
219 - template: &errors_template  
220 - header:  
221 - one: "Não foi possível gravar %{model}: 1 erro"  
222 - other: "Não foi possível gravar %{model}: %{count} erros."  
223 - body: "Por favor, verifique o(s) seguinte(s) campo(s):"  
224 -  
225 - activerecord:  
226 - errors:  
227 - messages:  
228 - <<: *errors_messages  
229 - template:  
230 - <<: *errors_template  
231 -  
232 - full_messages:  
233 - format: "%{attribute} %{message}"  
config/locales/pt.yml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +pt-BR.yml
0 \ No newline at end of file 2 \ No newline at end of file
config/locales/ru.yml
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 # (http://github.com/yaroslav/russian). Следующие данные -- выдержка их него, чтобы 10 # (http://github.com/yaroslav/russian). Следующие данные -- выдержка их него, чтобы
11 # была возможность минимальной локализации приложения на русский язык. 11 # была возможность минимальной локализации приложения на русский язык.
12 12
13 -ru: 13 +ru: &ru
14 date: 14 date:
15 formats: 15 formats:
16 default: "%d.%m.%Y" 16 default: "%d.%m.%Y"
@@ -300,3 +300,7 @@ ru: @@ -300,3 +300,7 @@ ru:
300 words_connector: ", " 300 words_connector: ", "
301 two_words_connector: " и " 301 two_words_connector: " и "
302 last_word_connector: " и " 302 last_word_connector: " и "
  303 +
  304 +ru_RU:
  305 + <<: *ru
  306 +
db/migrate/20150603182105_add_label_to_image.rb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +class AddLabelToImage < ActiveRecord::Migration
  2 + def up
  3 + add_column :images, :label, :string, :default => ""
  4 + end
  5 + def down
  6 + remove_column :images, :label
  7 + end
  8 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20150602142030) do 14 +ActiveRecord::Schema.define(:version => 20150603182105) do
15 15
16 create_table "abuse_reports", :force => true do |t| 16 create_table "abuse_reports", :force => true do |t|
17 t.integer "reporter_id" 17 t.integer "reporter_id"
@@ -377,6 +377,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150602142030) do @@ -377,6 +377,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150602142030) do
377 t.integer "width" 377 t.integer "width"
378 t.integer "height" 378 t.integer "height"
379 t.boolean "thumbnails_processed", :default => false 379 t.boolean "thumbnails_processed", :default => false
  380 + t.string "label", :default => ""
380 end 381 end
381 382
382 add_index "images", ["parent_id"], :name => "index_images_on_parent_id" 383 add_index "images", ["parent_id"], :name => "index_images_on_parent_id"
features/events.feature
@@ -160,6 +160,7 @@ Feature: events @@ -160,6 +160,7 @@ Feature: events
160 When I am on /search/events 160 When I am on /search/events
161 Then I should see "Colivre.net's Events" 161 Then I should see "Colivre.net's Events"
162 162
  163 +
163 @selenium 164 @selenium
164 Scenario: published events should be listed in the agenda too 165 Scenario: published events should be listed in the agenda too
165 Given the following community 166 Given the following community
plugins/custom_forms/po/fr/custom_forms.po
@@ -7,8 +7,8 @@ msgstr &quot;&quot; @@ -7,8 +7,8 @@ msgstr &quot;&quot;
7 "Project-Id-Version: 1.1-166-gaf47713\n" 7 "Project-Id-Version: 1.1-166-gaf47713\n"
8 "Report-Msgid-Bugs-To: \n" 8 "Report-Msgid-Bugs-To: \n"
9 "POT-Creation-Date: 2015-06-01 17:26-0300\n" 9 "POT-Creation-Date: 2015-06-01 17:26-0300\n"
10 -"PO-Revision-Date: 2015-02-23 11:38+0200\n"  
11 -"Last-Translator: Michal Čihař <michal@cihar.com>\n" 10 +"PO-Revision-Date: 2015-06-29 14:17+0200\n"
  11 +"Last-Translator: Christophe DANIEL <papaeng@gmail.com>\n"
12 "Language-Team: French <https://hosted.weblate.org/projects/noosfero/plugin-" 12 "Language-Team: French <https://hosted.weblate.org/projects/noosfero/plugin-"
13 "custom-forms/fr/>\n" 13 "custom-forms/fr/>\n"
14 "Language: fr\n" 14 "Language: fr\n"
@@ -16,7 +16,7 @@ msgstr &quot;&quot; @@ -16,7 +16,7 @@ msgstr &quot;&quot;
16 "Content-Type: text/plain; charset=UTF-8\n" 16 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Transfer-Encoding: 8bit\n" 17 "Content-Transfer-Encoding: 8bit\n"
18 "Plural-Forms: nplurals=2; plural=n > 1;\n" 18 "Plural-Forms: nplurals=2; plural=n > 1;\n"
19 -"X-Generator: Weblate 2.3-dev\n" 19 +"X-Generator: Weblate 2.4-dev\n"
20 20
21 #: plugins/custom_forms/lib/custom_forms_plugin/form.rb:67 21 #: plugins/custom_forms/lib/custom_forms_plugin/form.rb:67
22 msgid "Invalid string format of access." 22 msgid "Invalid string format of access."
@@ -64,9 +64,8 @@ msgstr &quot;%{fn} est obligatoire&quot; @@ -64,9 +64,8 @@ msgstr &quot;%{fn} est obligatoire&quot;
64 64
65 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:14 65 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:14
66 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:47 66 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:47
67 -#, fuzzy  
68 msgid "Logged users" 67 msgid "Logged users"
69 -msgstr "Connecté en tant que %s" 68 +msgstr "Utilisateurs connectés"
70 69
71 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:19 70 #: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:19
72 #, fuzzy 71 #, fuzzy
@@ -213,7 +212,7 @@ msgstr &quot;Une entreprise&quot; @@ -213,7 +212,7 @@ msgstr &quot;Une entreprise&quot;
213 212
214 #: plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_select.html.erb:29 213 #: plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_select.html.erb:29
215 msgid "Ok" 214 msgid "Ok"
216 -msgstr "" 215 +msgstr "Ok"
217 216
218 #: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb:10 217 #: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb:10
219 #, fuzzy 218 #, fuzzy
plugins/metadata/lib/ext/product.rb
@@ -7,7 +7,7 @@ class Product @@ -7,7 +7,7 @@ class Product
7 url: proc{ |p, plugin| plugin.og_url_for p.url }, 7 url: proc{ |p, plugin| plugin.og_url_for p.url },
8 gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f }, 8 gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f },
9 gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit }, 9 gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit },
10 - title: proc{ |a, plugin| "#{p.name} - #{p.profile.name}" }, 10 + title: proc{ |p, plugin| "#{p.name} - #{p.profile.name}" if p },
11 description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description }, 11 description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description },
12 12
13 image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, 13 image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image },
@@ -17,7 +17,7 @@ class Product @@ -17,7 +17,7 @@ class Product
17 17
18 see_also: [], 18 see_also: [],
19 site_name: proc{ |p, plugin| plugin.og_url_for p.profile.url }, 19 site_name: proc{ |p, plugin| plugin.og_url_for p.profile.url },
20 - updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, 20 + updated_time: proc{ |p, plugin| p.updated_at.iso8601 if p.updated_at },
21 21
22 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, 22 'locale:locale' => proc{ |p, plugin| p.environment.default_language },
23 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, 23 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages },
plugins/metadata/test/functional/home_controller_test.rb
@@ -12,7 +12,7 @@ class HomeControllerTest &lt; ActionController::TestCase @@ -12,7 +12,7 @@ class HomeControllerTest &lt; ActionController::TestCase
12 @response = ActionController::TestResponse.new 12 @response = ActionController::TestResponse.new
13 13
14 Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name]) 14 Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name])
15 - Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new]) 15 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)])
16 end 16 end
17 17
18 should 'display meta tags for social media' do 18 should 'display meta tags for social media' do
plugins/metadata/test/functional/manage_products_controller_test.rb 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +require 'test_helper'
  2 +require 'home_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class ManageProductsController; def rescue_action(e) raise e end; end
  6 +
  7 +class ManageProductsControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @controller = ManageProductsController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 + @enterprise = fast_create(Enterprise, name: 'test', identifier: 'test_ent')
  14 + @user = create_user_with_permission('test_user', 'manage_products', @enterprise)
  15 + @environment = @enterprise.environment
  16 + @environment.enable('products_for_enterprises')
  17 + login_as :test_user
  18 +
  19 + Noosfero::Plugin.stubs(:all).returns([MetadataPlugin.name])
  20 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([MetadataPlugin.new(@controller)])
  21 + end
  22 +
  23 + should "not crash on new products" do
  24 + get :new, profile: @enterprise.identifier
  25 + end
  26 +
  27 +end
plugins/remote_user/lib/remote_user_plugin.rb
@@ -48,8 +48,11 @@ class RemoteUserPlugin &lt; Noosfero::Plugin @@ -48,8 +48,11 @@ class RemoteUserPlugin &lt; Noosfero::Plugin
48 end 48 end
49 end 49 end
50 end 50 end
51 - rescue ActiveRecord::RecordInvalid => invalid  
52 - session[:notice] = _('Could not create the remote_user.') 51 + rescue ::ActiveRecord::RecordInvalid
  52 + session[:notice] = _('Could not create the remote user.')
  53 + render_404
  54 + rescue
  55 + session[:notice] = _("Could not log in.")
53 render_404 56 render_404
54 end 57 end
55 end 58 end
plugins/remote_user/test/functional/remote_user_plugin_test.rb
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + &#39;/../../../../test/test_helper&#39; @@ -3,7 +3,7 @@ require File.dirname(__FILE__) + &#39;/../../../../test/test_helper&#39;
3 # Re-raise errors caught by the controller. 3 # Re-raise errors caught by the controller.
4 class AccountController; def rescue_action(e) raise e end; end 4 class AccountController; def rescue_action(e) raise e end; end
5 5
6 -class AccountControllerTest < ActionController::TestCase 6 +class AccountControllerTest < ActionController::TestCase
7 def setup 7 def setup
8 @environment = Environment.default 8 @environment = Environment.default
9 @environment.enabled_plugins = ['RemoteUserPlugin'] 9 @environment.enabled_plugins = ['RemoteUserPlugin']
@@ -125,10 +125,18 @@ class AccountControllerTest &lt; ActionController::TestCase @@ -125,10 +125,18 @@ class AccountControllerTest &lt; ActionController::TestCase
125 get :index 125 get :index
126 126
127 assert session[:user].blank? 127 assert session[:user].blank?
128 - 128 +
129 @request.env["HTTP_REMOTE_USER"] = "" 129 @request.env["HTTP_REMOTE_USER"] = ""
130 get :index 130 get :index
131 131
132 assert session[:user].blank? 132 assert session[:user].blank?
133 end 133 end
  134 +
  135 + should 'not create a new user if his informations is invalid' do
  136 + @request.env["HTTP_REMOTE_USER"] = "*%&invalid user name&%*"
  137 + get :index
  138 +
  139 + assert session[:user].blank?
  140 + assert_response 404
  141 + end
134 end 142 end
plugins/shopping_cart/lib/shopping_cart_plugin.rb
1 class ShoppingCartPlugin < Noosfero::Plugin 1 class ShoppingCartPlugin < Noosfero::Plugin
  2 + include ModalHelper
  3 + include ActionView::Helpers::UrlHelper
2 4
3 class << self 5 class << self
4 def plugin_name 6 def plugin_name
@@ -63,4 +65,8 @@ class ShoppingCartPlugin &lt; Noosfero::Plugin @@ -63,4 +65,8 @@ class ShoppingCartPlugin &lt; Noosfero::Plugin
63 65
64 buttons 66 buttons
65 end 67 end
  68 +
  69 + def controller
  70 + context
  71 + end
66 end 72 end
plugins/shopping_cart/lib/shopping_cart_plugin/cart_helper.rb
@@ -42,7 +42,7 @@ module ShoppingCartPlugin::CartHelper @@ -42,7 +42,7 @@ module ShoppingCartPlugin::CartHelper
42 else 42 else
43 delivery = Product.new(:name => delivery_option || _('Delivery'), :price => settings.delivery_options[delivery_option]) 43 delivery = Product.new(:name => delivery_option || _('Delivery'), :price => settings.delivery_options[delivery_option])
44 end 44 end
45 - delivery.save(false) 45 + delivery.save(validate: false)
46 items << [delivery.id, ''] 46 items << [delivery.id, '']
47 end 47 end
48 48
plugins/shopping_cart/test/unit/shopping_cart_plugin/cart_helper_test.rb
@@ -41,5 +41,19 @@ class ShoppingCartPlugin::CartHelperTest &lt; ActiveSupport::TestCase @@ -41,5 +41,19 @@ class ShoppingCartPlugin::CartHelperTest &lt; ActiveSupport::TestCase
41 assert_equal "#{environment.currency_unit}13#{environment.currency_separator}70", float_to_currency_cart(value,environment) 41 assert_equal "#{environment.currency_unit}13#{environment.currency_separator}70", float_to_currency_cart(value,environment)
42 end 42 end
43 43
44 -end 44 + should 'return a table of items' do
  45 + enterprise = Enterprise.new(name: "Test Enterprise", identifier: "test-enterprise")
  46 + enterprise.environment = Environment.default
  47 + enterprise.save!
  48 +
  49 + product_category = fast_create(ProductCategory, :name => 'Products')
  50 + product = fast_create(Product, :name => 'test product1', :product_category_id => product_category.id, :profile_id => enterprise.id)
  51 + setting = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin)
  52 + setting.delivery = true
  53 + setting.save!
  54 +
  55 + assert_match 'table id="cart-items-table"', items_table([product], enterprise)
  56 + assert_match '<td>test product1</td>', items_table([product], enterprise)
  57 + end
45 58
  59 +end
plugins/shopping_cart/views/cart.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean basket')%></a> 5 <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean basket')%></a>
6 <ul class="cart-items"></ul> 6 <ul class="cart-items"></ul>
7 <div class="cart-total"><%=_('Total:')%> <b></b></div> 7 <div class="cart-total"><%=_('Total:')%> <b></b></div>
8 - <a href="/plugin/shopping_cart/buy" class="cart-buy modal"><%=_('Shopping checkout')%></a> 8 + <%= modal_link_to _('Shopping checkout'), { controller: 'shopping_cart_plugin', action: 'buy' }, { class: "cart-buy modal" } %>
9 </div> 9 </div>
10 <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle"> 10 <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle">
11 <span class="str-show"><%=_('Show basket')%></span> 11 <span class="str-show"><%=_('Show basket')%></span>
plugins/shopping_cart/views/shopping_cart_plugin/buy.html.erb
@@ -24,7 +24,6 @@ @@ -24,7 +24,6 @@
24 <% end %> 24 <% end %>
25 <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %> 25 <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %>
26 <%= items_table(@cart[:items], @profile, delivery_option) %> 26 <%= items_table(@cart[:items], @profile, delivery_option) %>
27 - <%= link_to_function '', "noosfero.modal.close();", :class => 'cart-box-close icon-cancel' %>  
28 </div> 27 </div>
29 28
30 <%= javascript_include_tag '../plugins/shopping_cart/buy' %> 29 <%= javascript_include_tag '../plugins/shopping_cart/buy' %>
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
@@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
17 </div> 17 </div>
18 <% end %> 18 <% end %>
19 <%= items_table(session[:cart][:items], profile) %> 19 <%= items_table(session[:cart][:items], profile) %>
20 - <%= link_to_function '', "noosfero.modal.close();", :class => 'cart-box-close icon-cancel' %>  
21 </div> 20 </div>
22 21
23 <script type="text/javascript"> 22 <script type="text/javascript">
plugins/social_share_privacy/lib/social_share_privacy_plugin.rb
@@ -19,12 +19,14 @@ class SocialSharePrivacyPlugin &lt; Noosfero::Plugin @@ -19,12 +19,14 @@ class SocialSharePrivacyPlugin &lt; Noosfero::Plugin
19 def article_extra_contents(article) 19 def article_extra_contents(article)
20 proc do 20 proc do
21 settings = Noosfero::Plugin::Settings.new(environment, SocialSharePrivacyPlugin) 21 settings = Noosfero::Plugin::Settings.new(environment, SocialSharePrivacyPlugin)
  22 + modules = settings.get_setting(:networks).map { |service| "/plugins/social_share_privacy/socialshareprivacy/javascripts/modules/#{service}.js" }
22 locale = FastGettext.locale 23 locale = FastGettext.locale
23 - javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/socialshareprivacy.js') +  
24 - javascript_include_tag('plugins/social_share_privacy/socialshareprivacy/javascripts/localstorage.js') +  
25 - javascript_include_tag(settings.get_setting(:networks).map { |service| "plugins/social_share_privacy/socialshareprivacy/javascripts/modules/#{service}.js" }) +  
26 - (locale != 'en' ? javascript_include_tag("plugins/social_share_privacy/socialshareprivacy/javascripts/locale/jquery.socialshareprivacy.min.#{locale}.js") : '') +  
27 - javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '../../plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({info_link_target: '_blank'});});") + 24 + javascript_include_tag('/plugins/social_share_privacy/socialshareprivacy/javascripts/socialshareprivacy.js') +
  25 + javascript_include_tag('/plugins/social_share_privacy/socialshareprivacy/javascripts/localstorage.js') +
  26 + (modules.present? ? javascript_include_tag(*modules) : '') +
  27 + javascript_include_tag("/plugins/social_share_privacy/socialshareprivacy/javascripts/modules/facebook.js") +
  28 + (locale != 'en' ? javascript_include_tag("/plugins/social_share_privacy/socialshareprivacy/javascripts/locale/jquery.socialshareprivacy.min.#{locale}.js") : '') +
  29 + javascript_tag("jQuery.fn.socialSharePrivacy.settings.path_prefix = '/plugins/social_share_privacy/socialshareprivacy/'; jQuery.fn.socialSharePrivacy.settings.order = #{settings.get_setting(:networks)}; jQuery(document).ready(function () { jQuery('.social-buttons').socialSharePrivacy({info_link_target: '_blank'});});") +
28 content_tag(:div, '', :class => "social-buttons") 30 content_tag(:div, '', :class => "social-buttons")
29 end 31 end
30 end 32 end
plugins/social_share_privacy/test/functional/content_viewer_controller_test.rb
@@ -23,7 +23,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -23,7 +23,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
23 23
24 get :view_page, :profile => @profile.identifier, :page => ['test'] 24 get :view_page, :profile => @profile.identifier, :page => ['test']
25 25
26 - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/socialshareprivacy\.js\??\d*/} 26 + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/socialshareprivacy\.js\??\d*/}
27 assert_tag :tag => 'div', :attributes => {:class => "social-buttons"} 27 assert_tag :tag => 'div', :attributes => {:class => "social-buttons"}
28 end 28 end
29 29
@@ -34,8 +34,8 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -34,8 +34,8 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
34 34
35 get :view_page, :profile => @profile.identifier, :page => ['test'] 35 get :view_page, :profile => @profile.identifier, :page => ['test']
36 36
37 - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/twitter\.js\??\d*/}  
38 - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/gplus\.js\??\d*/} 37 + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/twitter\.js\??\d*/}
  38 + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/modules\/gplus\.js\??\d*/}
39 end 39 end
40 40
41 should 'add javascript with string translations if not english' do 41 should 'add javascript with string translations if not english' do
@@ -45,12 +45,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -45,12 +45,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
45 45
46 get :view_page, :profile => @profile.identifier, :page => ['test'] 46 get :view_page, :profile => @profile.identifier, :page => ['test']
47 47
48 - assert_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.pt\.js\??\d*/} 48 + assert_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.pt\.js\??\d*/}
49 49
50 FastGettext.stubs(:locale).returns('en') 50 FastGettext.stubs(:locale).returns('en')
51 51
52 get :view_page, :profile => @profile.identifier, :page => ['test'] 52 get :view_page, :profile => @profile.identifier, :page => ['test']
53 53
54 - assert_no_tag :tag => 'script', :attributes => {:src => /\/javascripts\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.en\.js\??\d*/} 54 + assert_no_tag :tag => 'script', :attributes => {:src => /\/plugins\/social_share_privacy\/socialshareprivacy\/javascripts\/locale\/jquery\.socialshareprivacy\.min\.en\.js\??\d*/}
55 end 55 end
56 end 56 end
po/fr/noosfero-doc.po
@@ -7,8 +7,8 @@ msgid &quot;&quot; @@ -7,8 +7,8 @@ msgid &quot;&quot;
7 msgstr "" 7 msgstr ""
8 "Project-Id-Version: PACKAGE VERSION\n" 8 "Project-Id-Version: PACKAGE VERSION\n"
9 "POT-Creation-Date: 2013-12-10 15:48-0300\n" 9 "POT-Creation-Date: 2013-12-10 15:48-0300\n"
10 -"PO-Revision-Date: 2015-03-23 19:30+0200\n"  
11 -"Last-Translator: Jérôme Jutteau <j.jutteau@gmail.com>\n" 10 +"PO-Revision-Date: 2015-06-29 14:38+0200\n"
  11 +"Last-Translator: Christophe DANIEL <papaeng@gmail.com>\n"
12 "Language-Team: French " 12 "Language-Team: French "
13 "<https://hosted.weblate.org/projects/noosfero/documentation/fr/>\n" 13 "<https://hosted.weblate.org/projects/noosfero/documentation/fr/>\n"
14 "Language: fr\n" 14 "Language: fr\n"
@@ -16,7 +16,7 @@ msgstr &quot;&quot; @@ -16,7 +16,7 @@ msgstr &quot;&quot;
16 "Content-Type: text/plain; charset=UTF-8\n" 16 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Transfer-Encoding: 8bit\n" 17 "Content-Transfer-Encoding: 8bit\n"
18 "Plural-Forms: nplurals=2; plural=n > 1;\n" 18 "Plural-Forms: nplurals=2; plural=n > 1;\n"
19 -"X-Generator: Weblate 2.3-dev\n" 19 +"X-Generator: Weblate 2.4-dev\n"
20 20
21 # type: Content of: <h1> 21 # type: Content of: <h1>
22 #. type: Content of: <h1> 22 #. type: Content of: <h1>
@@ -470,7 +470,7 @@ msgstr &quot;&quot; @@ -470,7 +470,7 @@ msgstr &quot;&quot;
470 #. type: Attribute 'alt' of: <p><img> 470 #. type: Attribute 'alt' of: <p><img>
471 #: doc/noosfero/plugins/shopping_cart.en.xhtml:21 471 #: doc/noosfero/plugins/shopping_cart.en.xhtml:21
472 msgid "Catalog" 472 msgid "Catalog"
473 -msgstr "" 473 +msgstr "Catalogue"
474 474
475 # type: Content of: <p> 475 # type: Content of: <p>
476 #. type: Content of: <p> 476 #. type: Content of: <p>
public/designs/themes/base/style.css
@@ -1061,15 +1061,18 @@ hr.pre-posts, hr.sep-posts { @@ -1061,15 +1061,18 @@ hr.pre-posts, hr.sep-posts {
1061 text-decoration: none; 1061 text-decoration: none;
1062 } 1062 }
1063 1063
1064 -#content .main-block .created-at { 1064 +#content .main-block .publishing-info {
1065 text-align: left; 1065 text-align: left;
1066 color: #AAA; 1066 color: #AAA;
  1067 + font-size: 11px;
  1068 + /*padding-top: 20px;*/
  1069 + margin-bottom:15px;
1067 } 1070 }
1068 -#content .main-block .created-at a { 1071 +#content .main-block .publishing-info a {
1069 color: #AAA; 1072 color: #AAA;
1070 text-decoration: none; 1073 text-decoration: none;
1071 } 1074 }
1072 -#content .main-block .created-at a:hover { 1075 +#content .main-block .publishing-info a:hover {
1073 color: #555; 1076 color: #555;
1074 text-decoration: underline; 1077 text-decoration: underline;
1075 } 1078 }
@@ -1415,3 +1418,115 @@ table#recaptcha_table tr:hover td { @@ -1415,3 +1418,115 @@ table#recaptcha_table tr:hover td {
1415 color:#333; 1418 color:#333;
1416 } 1419 }
1417 1420
  1421 +/************************* Article Page *****************************/
  1422 +
  1423 +#article-header .preview {
  1424 + font-size: 15px;
  1425 +}
  1426 +
  1427 +.article-body-img {
  1428 + float: left;
  1429 + margin-right: 20px;
  1430 + margin-top: 5px;
  1431 +}
  1432 +
  1433 +#content #article .article-body .article-body-img img {
  1434 + height: auto;
  1435 + width: auto;
  1436 + min-height: 120px;
  1437 + max-height: 180px;
  1438 + max-width: 250px;
  1439 + background-position: center center;
  1440 + background-repeat: no-repeat;
  1441 +}
  1442 +
  1443 +#content #article .article-body .article-body-img p {
  1444 + margin-bottom: 10px;
  1445 + font-size: 10px;
  1446 + min-height: 20px;
  1447 +}
  1448 +/* Noosfero Events */
  1449 +
  1450 +.event-card {
  1451 + float: left;
  1452 + padding-top: 25px;
  1453 + width: 494px;
  1454 + height: 116px;
  1455 + background-repeat: no-repeat;
  1456 + margin-bottom: 30px;
  1457 +}
  1458 +
  1459 +.event-image {
  1460 + position: relative;
  1461 + float: left;
  1462 + padding-right: 22px;
  1463 + max-width: 130px;
  1464 + height: 130px;
  1465 +}
  1466 +
  1467 +#content #article .article-body img{
  1468 + max-height: 100%;
  1469 +}
  1470 +
  1471 +.about-event {
  1472 + position: relative;
  1473 + float: left;
  1474 + height: 160px;
  1475 + width: 300px;
  1476 + max-width: 300px;
  1477 +}
  1478 +
  1479 +.about-event > span {
  1480 + display: block;
  1481 + max-width: inherit;
  1482 + margin-left: 20px;
  1483 + padding-left: 21px;
  1484 + line-height: 13px;
  1485 + margin-right: 11px;
  1486 +}
  1487 +
  1488 +.about-event .event-date {
  1489 + margin-top: 3px;
  1490 +}
  1491 +
  1492 +.about-event .event-address {
  1493 + margin-top: 19px;
  1494 +}
  1495 +
  1496 +.about-event .event-address span {
  1497 + display: block;
  1498 + margin-left: 0px;
  1499 + margin-top: 4.4px;
  1500 + line-height: 14px;
  1501 +}
  1502 +
  1503 +.event-date {
  1504 + background: url('/images/calendar_date_select/calendar-icon.png') no-repeat left center;
  1505 + padding: 5px;
  1506 +}
  1507 +
  1508 +.event-link {
  1509 + background: url('/images/globe-icon.png') no-repeat left center;
  1510 + margin-top: 18px;
  1511 +}
  1512 +
  1513 +.event-link a {
  1514 +}
  1515 +
  1516 +.event-address {
  1517 + background: url('/images/icone_pin.png') no-repeat left top;
  1518 +}
  1519 +
  1520 +.event-body {
  1521 + float: left;
  1522 +}
  1523 +
  1524 +.event-body .event-lead {
  1525 + font-size: 15px;
  1526 +}
  1527 +
  1528 +.event-body .event-content p {
  1529 + margin-top: 20px;
  1530 + width: 494px;
  1531 + padding-left: 2px;
  1532 +}
public/images/calendar_date_select/calendar-icon.png 0 → 100644

283 Bytes

public/images/globe-icon.png 0 → 100644

464 Bytes

public/images/icone_pin.png 0 → 100644

51.9 KB

public/javascripts/application.js
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 *= require jquery.ba-bbq.min.js 14 *= require jquery.ba-bbq.min.js
15 *= require jquery.tokeninput.js 15 *= require jquery.tokeninput.js
16 *= require jquery-timepicker-addon/dist/jquery-ui-timepicker-addon.js 16 *= require jquery-timepicker-addon/dist/jquery-ui-timepicker-addon.js
  17 +*= require select-or-die/_src/selectordie
17 *= require inputosaurus.js 18 *= require inputosaurus.js
18 *= require reflection.js 19 *= require reflection.js
19 *= require rails.js 20 *= require rails.js
@@ -845,7 +846,7 @@ Array.min = function(array) { @@ -845,7 +846,7 @@ Array.min = function(array) {
845 846
846 function hideAndGetUrl(link) { 847 function hideAndGetUrl(link) {
847 document.body.style.cursor = 'wait'; 848 document.body.style.cursor = 'wait';
848 - link.hide(); 849 + jQuery(link).hide();
849 url = jQuery(link).attr('href'); 850 url = jQuery(link).attr('href');
850 jQuery.get(url, function( data ) { 851 jQuery.get(url, function( data ) {
851 document.body.style.cursor = 'default'; 852 document.body.style.cursor = 'default';
public/javascripts/jquery.tokeninput.js
@@ -345,7 +345,7 @@ $.TokenList = function (input, url_or_data, options) { @@ -345,7 +345,7 @@ $.TokenList = function (input, url_or_data, options) {
345 dropdown.appendTo("body"); 345 dropdown.appendTo("body");
346 if (!settings.permanentDropdown) 346 if (!settings.permanentDropdown)
347 dropdown.appendTo("body"); 347 dropdown.appendTo("body");
348 - else 348 + else
349 $(input).after(dropdown.show()); 349 $(input).after(dropdown.show());
350 350
351 if (settings.permanentDropdown || settings.showAllResults) { 351 if (settings.permanentDropdown || settings.showAllResults) {
@@ -382,7 +382,7 @@ $.TokenList = function (input, url_or_data, options) { @@ -382,7 +382,7 @@ $.TokenList = function (input, url_or_data, options) {
382 if(li_data && li_data.length) { 382 if(li_data && li_data.length) {
383 $.each(li_data, function (index, value) { 383 $.each(li_data, function (index, value) {
384 insert_token(value); 384 insert_token(value);
385 - checkTokenLimit(); 385 + checkTokenLimit({init: true});
386 }); 386 });
387 } 387 }
388 388
@@ -425,12 +425,12 @@ $.TokenList = function (input, url_or_data, options) { @@ -425,12 +425,12 @@ $.TokenList = function (input, url_or_data, options) {
425 // Private functions 425 // Private functions
426 // 426 //
427 427
428 - function checkTokenLimit() { 428 + function checkTokenLimit(options) {
429 if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { 429 if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) {
430 input_box.hide(); 430 input_box.hide();
431 hide_dropdown(); 431 hide_dropdown();
432 return; 432 return;
433 - } else { 433 + } else if (options && !options.init) {
434 input_box.focus(); 434 input_box.focus();
435 } 435 }
436 } 436 }
@@ -618,7 +618,7 @@ $.TokenList = function (input, url_or_data, options) { @@ -618,7 +618,7 @@ $.TokenList = function (input, url_or_data, options) {
618 if (!settings.showAllResults) 618 if (!settings.showAllResults)
619 dropdown.empty(); 619 dropdown.empty();
620 selected_dropdown_item = null; 620 selected_dropdown_item = null;
621 - } 621 + }
622 if (settings.showAllResults) 622 if (settings.showAllResults)
623 show_dropdown_hint(); 623 show_dropdown_hint();
624 } 624 }
@@ -728,7 +728,7 @@ $.TokenList = function (input, url_or_data, options) { @@ -728,7 +728,7 @@ $.TokenList = function (input, url_or_data, options) {
728 item.addClass(settings.classes.selectedDropdownItem); 728 item.addClass(settings.classes.selectedDropdownItem);
729 selected_dropdown_item = item.get(0); 729 selected_dropdown_item = item.get(0);
730 730
731 - isBefore = item[0].offsetTop <= (dropdown[0].scrollTop + dropdown[0].scrollWidth); 731 + isBefore = item[0].offsetTop <= (dropdown[0].scrollTop + dropdown[0].scrollWidth);
732 isAfter = item[0].offsetTop >= dropdown[0].scrollTop; 732 isAfter = item[0].offsetTop >= dropdown[0].scrollTop;
733 visible = isBefore && isAfter; 733 visible = isBefore && isAfter;
734 if (!visible) { 734 if (!visible) {
public/stylesheets/application.css
@@ -1054,6 +1054,11 @@ code input { @@ -1054,6 +1054,11 @@ code input {
1054 margin-top: 10px; 1054 margin-top: 10px;
1055 display: none; 1055 display: none;
1056 } 1056 }
  1057 +
  1058 +#change-image {
  1059 + display: table-caption;
  1060 +}
  1061 +
1057 .zoomable-image { 1062 .zoomable-image {
1058 position: relative; 1063 position: relative;
1059 display: inline-block; 1064 display: inline-block;
@@ -1520,13 +1525,13 @@ a.comment-picture { @@ -1520,13 +1525,13 @@ a.comment-picture {
1520 text-align: right; 1525 text-align: right;
1521 color: gray; 1526 color: gray;
1522 } 1527 }
1523 -#content .created-at { 1528 +#content .publishing-info {
1524 color: gray; 1529 color: gray;
1525 font-size: 12px; 1530 font-size: 12px;
1526 display: block; 1531 display: block;
1527 text-align: right; 1532 text-align: right;
1528 } 1533 }
1529 -#content .blog-post .created-at { 1534 +#content .blog-post .publishing-info {
1530 text-align: left; 1535 text-align: left;
1531 } 1536 }
1532 #content #article .pagination .prev_page { 1537 #content #article .pagination .prev_page {
@@ -1598,7 +1603,7 @@ div.article-body p img { @@ -1598,7 +1603,7 @@ div.article-body p img {
1598 .blog-post.not-published a { 1603 .blog-post.not-published a {
1599 text-decoration: none; 1604 text-decoration: none;
1600 } 1605 }
1601 -#content .blog-post.not-published .created-at { 1606 +#content .blog-post.not-published .publishing-info {
1602 text-align: left; 1607 text-align: left;
1603 } 1608 }
1604 .blog-post.not-published .metadata { 1609 .blog-post.not-published .metadata {
script/gitlab-ci
@@ -1,56 +0,0 @@ @@ -1,56 +0,0 @@
1 -#!/usr/bin/env ruby  
2 -  
3 -# These just forward the signals to the whole process group and  
4 -# then immediately exit.  
5 -pgid = Process.getpgid Process.pid  
6 -Signal.trap(:TERM) { Process.kill(:TERM, -pgid); exit }  
7 -Signal.trap(:INT) { Process.kill(:INT, -pgid); exit }  
8 -  
9 -def run command, options = {}  
10 - command = "#{command} 2>&1 > /dev/null" if options[:output] == false  
11 - #command = "time #{command}" unless options[:runtime] == false  
12 - puts "== #{command}"  
13 - system command  
14 -end  
15 -  
16 -@id = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join  
17 -@db = "gitlab-ci-#{@id}"  
18 -  
19 -def config  
20 - require 'yaml'  
21 - db_config = {  
22 - 'adapter' => 'postgresql', 'encoding' => 'unicode',  
23 - 'database' => @db, 'username' => ENV['USER'],  
24 - }  
25 - File.write 'config/database.yml', YAML.dump('test' => db_config, 'development' => db_config)  
26 -end  
27 -  
28 -def prepare  
29 - run("createdb #{@db}") and  
30 - run('mkdir -p tmp/pids log') and  
31 - run('bundle check || bundle install') and  
32 - run('rake db:schema:load', output: false) and  
33 - run('script/noosfero-plugins disableall') and  
34 - run('rake db:migrate')  
35 -end  
36 -  
37 -def test  
38 - %w[  
39 - test:units  
40 - test:functionals  
41 - test:integration  
42 - cucumber  
43 - test:noosfero_plugins  
44 - ].each do |task|  
45 - run "rake #{task}"  
46 - end  
47 -end  
48 -  
49 -def cleanup  
50 - run "dropdb #{@db}"  
51 -end  
52 -  
53 -ret = config and prepare and test  
54 -cleanup  
55 -  
56 -exit (if ret == true then 0 else 1 end)  
script/install-dependencies/debian-wheezy.sh
@@ -80,4 +80,5 @@ packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debi @@ -80,4 +80,5 @@ packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debi
80 run sudo apt-get -y install $packages 80 run sudo apt-get -y install $packages
81 sudo apt-get -y install iceweasel || sudo apt-get -y install firefox 81 sudo apt-get -y install iceweasel || sudo apt-get -y install firefox
82 82
  83 +run rm -f Gemfile.lock
83 run bundle --local 84 run bundle --local
test/functional/cms_controller_test.rb
@@ -223,6 +223,20 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -223,6 +223,20 @@ class CmsControllerTest &lt; ActionController::TestCase
223 assert_equal profile, a.last_changed_by 223 assert_equal profile, a.last_changed_by
224 end 224 end
225 225
  226 + should 'be able to set label to article image' do
  227 + login_as(profile.identifier)
  228 + post :new, :type => TextileArticle.name, :profile => profile.identifier,
  229 + :article => {
  230 + :name => 'adding-image-label',
  231 + :image_builder => {
  232 + :uploaded_data => fixture_file_upload('/files/tux.png', 'image/png'),
  233 + :label => 'test-label'
  234 + }
  235 + }
  236 + a = Article.last
  237 + assert_equal a.image.label, 'test-label'
  238 + end
  239 +
226 should 'edit by using the correct template to display the editor depending on the mime-type' do 240 should 'edit by using the correct template to display the editor depending on the mime-type' do
227 a = profile.articles.build(:name => 'test document') 241 a = profile.articles.build(:name => 'test document')
228 a.save! 242 a.save!
@@ -318,6 +332,20 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -318,6 +332,20 @@ class CmsControllerTest &lt; ActionController::TestCase
318 end 332 end
319 end 333 end
320 334
  335 + should 'be able to edit an image label' do
  336 + image = fast_create(Image, :content_type => 'image/png', :filename => 'event-image.png', :label => 'test_label', :size => 1014)
  337 + article = fast_create(Article, :profile_id => profile.id, :name => 'test_label_article', :body => 'test_content')
  338 + article.image = image
  339 + article.save
  340 + assert_not_nil article
  341 + assert_not_nil article.image
  342 + assert_equal 'test_label', article.image.label
  343 +
  344 + post :edit, :profile => profile.identifier, :id => article.id, :article => {:image_builder => { :label => 'test_label_modified'}}
  345 + article.reload
  346 + assert_equal 'test_label_modified', article.image.label
  347 + end
  348 +
321 should 'be able to upload more than one file at once' do 349 should 'be able to upload more than one file at once' do
322 assert_difference 'UploadedFile.count', 2 do 350 assert_difference 'UploadedFile.count', 2 do
323 post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain'), fixture_file_upload('/files/rails.png', 'text/plain')] 351 post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain'), fixture_file_upload('/files/rails.png', 'text/plain')]
@@ -1863,8 +1891,8 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1863,8 +1891,8 @@ class CmsControllerTest &lt; ActionController::TestCase
1863 end 1891 end
1864 1892
1865 should 'return tags found' do 1893 should 'return tags found' do
1866 - tag = mock; tag.stubs(:name).returns('linux')  
1867 - ActsAsTaggableOn::Tag.stubs(:find).returns([tag]) 1894 + a = profile.articles.create(:name => 'blablabla')
  1895 + a.tags.create! name: 'linux'
1868 get :search_tags, :profile => profile.identifier, :term => 'linux' 1896 get :search_tags, :profile => profile.identifier, :term => 'linux'
1869 assert_equal '[{"label":"linux","value":"linux"}]', @response.body 1897 assert_equal '[{"label":"linux","value":"linux"}]', @response.body
1870 end 1898 end
test/functional/content_viewer_controller_test.rb
@@ -124,6 +124,19 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -124,6 +124,19 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
124 assert_tag :tag => 'div', :attributes => { :id => 'article-tags' }, :descendant => { :content => /This article's tags:/ } 124 assert_tag :tag => 'div', :attributes => { :id => 'article-tags' }, :descendant => { :content => /This article's tags:/ }
125 end 125 end
126 126
  127 + should "display image label on article image" do
  128 + page = TinyMceArticle.create!(
  129 + :profile => profile,
  130 + :name => 'myarticle',
  131 + :image_builder => {
  132 + :uploaded_data => fixture_file_upload('/files/tux.png', 'image/png'),
  133 + :label => 'test-label'
  134 + }
  135 + )
  136 + get :view_page, page.url
  137 + assert_match /test-label/, @response.body
  138 + end
  139 +
127 should "not display current article's tags" do 140 should "not display current article's tags" do
128 page = profile.articles.create!(:name => 'myarticle', :body => 'test article') 141 page = profile.articles.create!(:name => 'myarticle', :body => 'test article')
129 142
test/unit/event_test.rb
@@ -109,17 +109,20 @@ class EventTest &lt; ActiveSupport::TestCase @@ -109,17 +109,20 @@ class EventTest &lt; ActiveSupport::TestCase
109 end 109 end
110 110
111 should 'provide nice display format' do 111 should 'provide nice display format' do
112 - e = build(Event, :start_date => Date.new(2008,1,1), :end_date => Date.new(2008,1,1), :link => 'http://www.myevent.org', :body => 'my somewhat short description') 112 + event = build(Event, :start_date => Date.new(2008,1,1), :end_date => Date.new(2008,1,1), :link => 'http://www.myevent.org', :body => '<p>my somewhat short description</p>')
  113 + display = instance_eval(&event.to_html)
113 114
114 - assert_tag_in_string e.to_html, :content => Regexp.new("January 1, 2008")  
115 - assert_tag_in_string e.to_html, :content => 'my somewhat short description'  
116 - assert_tag_in_string e.to_html, :tag => 'a', :attributes => { :href => 'http://www.myevent.org' }, :content => 'http://www.myevent.org' 115 + assert_tag_in_string display, :content => Regexp.new("January 1, 2008")
  116 + assert_tag_in_string display, :content => Regexp.new('my somewhat short description')
  117 + assert_tag_in_string display, :content => Regexp.new('http://www.myevent.org')
117 end 118 end
118 119
119 should 'not crash when body is blank' do 120 should 'not crash when body is blank' do
120 e = Event.new 121 e = Event.new
121 assert_nil e.body 122 assert_nil e.body
122 - assert_no_match(/_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____/, e.to_html) 123 + assert_nothing_raised do
  124 + instance_eval(&e.to_html)
  125 + end
123 end 126 end
124 127
125 should 'add http:// to the link if not already present' do 128 should 'add http:// to the link if not already present' do
@@ -141,10 +144,19 @@ class EventTest &lt; ActiveSupport::TestCase @@ -141,10 +144,19 @@ class EventTest &lt; ActiveSupport::TestCase
141 assert_equal '', a.link 144 assert_equal '', a.link
142 end 145 end
143 146
  147 + should 'get the first paragraph' do
  148 + profile = create_user('testuser').person
  149 + event = create(Event, :profile => profile, :name => 'test',
  150 + :body => '<p>first paragraph </p><p>second paragraph </p>',
  151 + :link => 'www.colivre.coop.br', :start_date => Date.today)
  152 +
  153 + assert_match '<p>first paragraph </p>', event.first_paragraph
  154 + end
  155 +
144 should 'not escape HTML in body' do 156 should 'not escape HTML in body' do
145 a = build(Event, :body => '<p>a paragraph of text</p>', :link => 'www.gnu.org') 157 a = build(Event, :body => '<p>a paragraph of text</p>', :link => 'www.gnu.org')
146 158
147 - assert_match '<p>a paragraph of text</p>', a.to_html 159 + assert_match '<p>a paragraph of text</p>', instance_eval(&a.to_html)
148 end 160 end
149 161
150 should 'filter HTML in body' do 162 should 'filter HTML in body' do
@@ -324,7 +336,7 @@ class EventTest &lt; ActiveSupport::TestCase @@ -324,7 +336,7 @@ class EventTest &lt; ActiveSupport::TestCase
324 environment = fast_create(Environment) 336 environment = fast_create(Environment)
325 environment.languages = nil 337 environment.languages = nil
326 profile = fast_create(Person, :environment_id => environment.id) 338 profile = fast_create(Person, :environment_id => environment.id)
327 - 339 +
328 event = Event.new(:profile => profile) 340 event = Event.new(:profile => profile)
329 341
330 assert !event.translatable? 342 assert !event.translatable?
@@ -337,11 +349,11 @@ class EventTest &lt; ActiveSupport::TestCase @@ -337,11 +349,11 @@ class EventTest &lt; ActiveSupport::TestCase
337 event = fast_create(Event, :profile_id => profile.id) 349 event = fast_create(Event, :profile_id => profile.id)
338 350
339 assert !event.translatable? 351 assert !event.translatable?
340 - 352 +
341 353
342 environment.languages = ['en','pt','fr'] 354 environment.languages = ['en','pt','fr']
343 environment.save 355 environment.save
344 - event.reload 356 + event.reload
345 assert event.translatable? 357 assert event.translatable?
346 end 358 end
347 359
test/unit/task_test.rb
@@ -192,6 +192,32 @@ class TaskTest &lt; ActiveSupport::TestCase @@ -192,6 +192,32 @@ class TaskTest &lt; ActiveSupport::TestCase
192 task.save! 192 task.save!
193 end 193 end
194 194
  195 + should 'not send notification to target if notification is disabled in profile' do
  196 + task = Task.new
  197 + target = fast_create(Profile)
  198 + target.stubs(:notification_emails).returns(['adm@example.com'])
  199 + target.stubs(:administrator_mail_notification).returns(false)
  200 + task.target = target
  201 + task.stubs(:target_notification_message).returns('some non nil message to be sent to target')
  202 + TaskMailer.expects(:target_notification).never
  203 + task.save!
  204 + end
  205 +
  206 + should 'send notification to target if notification is enabled in profile' do
  207 + task = Task.new
  208 + target = fast_create(Profile)
  209 + target.stubs(:notification_emails).returns(['adm@example.com'])
  210 + target.stubs(:administrator_mail_notification).returns(true)
  211 + task.target = target
  212 + task.stubs(:target_notification_message).returns('some non nil message to be sent to target')
  213 +
  214 +
  215 + mailer = mock
  216 + mailer.expects(:deliver).once
  217 + TaskMailer.expects(:target_notification).returns(mailer).once
  218 + task.save!
  219 + end
  220 +
195 should 'be able to list pending tasks' do 221 should 'be able to list pending tasks' do
196 Task.delete_all 222 Task.delete_all
197 t1 = Task.create! 223 t1 = Task.create!