Commit d3b8064fb95349a37aea58f43727aac204462b6f

Authored by Rodrigo Souto
2 parents 0eba5453 a499eda4

Merge branch 'master' into api

Showing 67 changed files with 661 additions and 274 deletions   Show diff stats
.gitlab-ci.yml 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +before_script:
  2 + - mkdir -p tmp/pids log
  3 + - script/noosfero-plugins disableall
  4 + - bundle check || bundle install
  5 +# database
  6 + - cp config/database.yml.gitlab-ci config/database.yml
  7 + - createdb gitlab_ci_test || true
  8 + - bundle exec rake db:schema:load
  9 + - bundle exec rake db:migrate
  10 +
  11 +units:
  12 + script: 'bundle exec rake test:units'
  13 +functionals:
  14 + script: 'bundle exec rake test:functionals'
  15 +integration:
  16 + script: 'bundle exec rake test:integration'
  17 +cucumber:
  18 + script: 'bundle exec rake cucumber'
  19 +selenium:
  20 + script: 'bundle exec rake selenium'
  21 +plugins:
  22 + script: 'bundle exec rake test:noosfero_plugins'
  23 +
.travis.yml 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  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 openjdk-6-jre curl wget
  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 + - script/noosfero-plugins disableall
  18 + - bundle check || bundle install
  19 +# database
  20 + - cp config/database.yml.travis config/database.yml
  21 + - psql -c 'create database myapp_test;' -U postgres
  22 + - bundle exec rake db:schema:load
  23 + - bundle exec rake db:migrate
  24 +
  25 +env:
  26 + - TASK=test:units
  27 + - TASK=test:functionals
  28 + - TASK=test:integration
  29 + - TASK=cucumber
  30 + - TASK=selenium
  31 + - TASK=test:noosfero_plugins
  32 +
  33 +script:
  34 + - bundle exec rake $TASK
  35 +
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'
@@ -44,6 +44,7 @@ group :test do @@ -44,6 +44,7 @@ group :test do
44 gem 'rspec', '~> 2.14.0' 44 gem 'rspec', '~> 2.14.0'
45 gem 'rspec-rails', '~> 2.14.1' 45 gem 'rspec-rails', '~> 2.14.1'
46 gem 'mocha', '~> 1.1.0', :require => false 46 gem 'mocha', '~> 1.1.0', :require => false
  47 + gem 'test-unit' if RUBY_VERSION >= '2.2.0'
47 end 48 end
48 49
49 group :cucumber do 50 group :cucumber do
app/controllers/my_profile/cms_controller.rb
@@ -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/controllers/my_profile/manage_products_controller.rb
@@ -35,7 +35,7 @@ class ManageProductsController < ApplicationController @@ -35,7 +35,7 @@ class ManageProductsController < ApplicationController
35 end 35 end
36 36
37 def categories_for_selection 37 def categories_for_selection
38 - @category = Category.find(params[:category_id]) if params[:category_id] 38 + @category = environment.categories.find_by_id params[:category_id]
39 @object_name = params[:object_name] 39 @object_name = params[:object_name]
40 if @category 40 if @category
41 @categories = @category.children 41 @categories = @category.children
@@ -95,6 +95,20 @@ class ManageProductsController < ApplicationController @@ -95,6 +95,20 @@ class ManageProductsController < ApplicationController
95 end 95 end
96 end 96 end
97 97
  98 + def show_category_tree
  99 + @category = environment.categories.find params[:category_id]
  100 + render :partial => 'selected_category_tree'
  101 + end
  102 +
  103 + def search_categories
  104 + @term = params[:term].downcase
  105 + conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"]
  106 + @categories = ProductCategory.all :conditions => conditions, :limit => 10
  107 + render :json => (@categories.map do |category|
  108 + {:label => category.name, :value => category.id}
  109 + end)
  110 + end
  111 +
98 def add_input 112 def add_input
99 @product = @profile.products.find(params[:id]) 113 @product = @profile.products.find(params[:id])
100 @input = @product.inputs.build 114 @input = @product.inputs.build
app/controllers/my_profile/maps_controller.rb
@@ -16,6 +16,7 @@ class MapsController < MyProfileController @@ -16,6 +16,7 @@ class MapsController < MyProfileController
16 16
17 Profile.transaction do 17 Profile.transaction do
18 if profile.update_attributes!(params[:profile_data]) 18 if profile.update_attributes!(params[:profile_data])
  19 + BlockSweeper.expire_blocks profile.blocks.select{ |b| b.class == LocationBlock }
19 session[:notice] = _('Address was updated successfully!') 20 session[:notice] = _('Address was updated successfully!')
20 redirect_to :action => 'edit_location' 21 redirect_to :action => 'edit_location'
21 end 22 end
app/helpers/application_helper.rb
@@ -1185,7 +1185,7 @@ module ApplicationHelper @@ -1185,7 +1185,7 @@ module ApplicationHelper
1185 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) 1185 pending_tasks_count = link_to(count.to_s, 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 +
@@ -1233,7 +1233,7 @@ module ApplicationHelper @@ -1233,7 +1233,7 @@ module ApplicationHelper
1233 1233
1234 def task_information(task) 1234 def task_information(task)
1235 values = {} 1235 values = {}
1236 - values.merge!({:requestor => link_to(task.requestor.name, task.requestor.public_profile_url)}) if task.requestor 1236 + values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor
1237 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject 1237 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
1238 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject 1238 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!(task.information[:variables]) if task.information[:variables] 1239 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/helpers/folder_helper.rb
1 -require 'short_filename'  
2 -  
3 module FolderHelper 1 module FolderHelper
4 2
5 - include ShortFilename  
6 include ArticleHelper 3 include ArticleHelper
7 4
8 def list_contents(configure={}) 5 def list_contents(configure={})
@@ -10,8 +7,8 @@ module FolderHelper @@ -10,8 +7,8 @@ module FolderHelper
10 configure[:list_type] ||= :folder 7 configure[:list_type] ||= :folder
11 if !configure[:contents].blank? 8 if !configure[:contents].blank?
12 configure[:contents] = configure[:contents].paginate( 9 configure[:contents] = configure[:contents].paginate(
13 - :order => "updated_at DESC",  
14 - :per_page => 10, 10 + :order => "name ASC",
  11 + :per_page => 30,
15 :page => params[:npage] 12 :page => params[:npage]
16 ) 13 )
17 14
app/helpers/manage_products_helper.rb
@@ -75,9 +75,12 @@ module ManageProductsHelper @@ -75,9 +75,12 @@ module ManageProductsHelper
75 end 75 end
76 76
77 def categories_container(categories_selection_html, hierarchy_html = '') 77 def categories_container(categories_selection_html, hierarchy_html = '')
78 - hidden_field_tag('selected_category_id') +  
79 - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +  
80 - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') 78 + content_tag 'div',
  79 + render('categories_autocomplete') +
  80 + hidden_field_tag('selected_category_id') +
  81 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
  82 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  83 + :id => 'categories-container'
81 end 84 end
82 85
83 def select_for_categories(categories, level = 0) 86 def select_for_categories(categories, level = 0)
app/models/article.rb
@@ -736,8 +736,9 @@ class Article &lt; ActiveRecord::Base @@ -736,8 +736,9 @@ class Article &lt; ActiveRecord::Base
736 paragraphs.empty? ? '' : paragraphs.first.to_html 736 paragraphs.empty? ? '' : paragraphs.first.to_html
737 end 737 end
738 738
739 - def lead  
740 - abstract.blank? ? first_paragraph.html_safe : abstract.html_safe 739 + def lead(length = nil)
  740 + content = abstract.blank? ? first_paragraph.html_safe : abstract.html_safe
  741 + length.present? ? content.truncate(length) : content
741 end 742 end
742 743
743 def short_lead 744 def short_lead
app/models/event.rb
@@ -98,47 +98,19 @@ class Event &lt; Article @@ -98,47 +98,19 @@ class Event &lt; Article
98 start_date..(end_date||start_date) 98 start_date..(end_date||start_date)
99 end 99 end
100 100
101 - # FIXME this shouldn't be needed  
102 - include ActionView::Helpers::TagHelper  
103 - include ActionView::Helpers::UrlHelper  
104 - include DatesHelper 101 + def first_paragraph
  102 + paragraphs = Nokogiri::HTML.fragment(self.body).css('p')
  103 + paragraphs.empty? ? '' : paragraphs.first.to_html
  104 + end
105 105
106 def to_html(options = {}) 106 def to_html(options = {})
  107 + event = self
  108 + format = options[:format]
107 109
108 - result = ''  
109 - html = ::Builder::XmlMarkup.new(:target => result)  
110 -  
111 - html.div(:class => 'event-info' ) {  
112 - html.ul(:class => 'event-data' ) {  
113 - html.li(:class => 'event-dates' ) {  
114 - html.span _('When:')  
115 - html.text! show_period(start_date, end_date)  
116 - } if start_date.present? || end_date.present?  
117 - html.li {  
118 - html.span _('URL:')  
119 - html.a(self.link || "", 'href' => self.link || "")  
120 - } if self.link.present?  
121 - html.li {  
122 - html.span _('Address:')  
123 - html.text! self.address || ""  
124 - } if self.address.present?  
125 - }  
126 -  
127 - # TODO: some good soul, please clean this ugly hack:  
128 - if self.body  
129 - html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')  
130 - end  
131 - }  
132 -  
133 - if self.body  
134 - if options[:format] == 'short'  
135 - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))  
136 - else  
137 - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)  
138 - end 110 + proc do
  111 + render :file => 'content_viewer/event_page', :locals => { :event => event,
  112 + :format => format }
139 end 113 end
140 -  
141 - result  
142 end 114 end
143 115
144 def duration 116 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
@@ -171,6 +171,12 @@ class Organization &lt; Profile @@ -171,6 +171,12 @@ class Organization &lt; Profile
171 ] 171 ]
172 end 172 end
173 173
  174 + def short_name chars = 40
  175 + s = self.display_name
  176 + s = super(chars) if s.blank?
  177 + s
  178 + end
  179 +
174 def notification_emails 180 def notification_emails
175 emails = [contact_email].select(&:present?) + admins.map(&:email) 181 emails = [contact_email].select(&:present?) + admins.map(&:email)
176 if emails.empty? 182 if emails.empty?
app/models/uploaded_file.rb
1 -require 'short_filename'  
2 -  
3 # Article type that handles uploaded files. 1 # Article type that handles uploaded files.
4 # 2 #
5 # Limitation: only file metadata are versioned. Only the latest version 3 # Limitation: only file metadata are versioned. Only the latest version
@@ -14,8 +12,6 @@ class UploadedFile &lt; Article @@ -14,8 +12,6 @@ class UploadedFile &lt; Article
14 12
15 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent 13 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent
16 14
17 - include ShortFilename  
18 -  
19 def title 15 def title
20 if self.name.present? then self.name else self.filename end 16 if self.name.present? then self.name else self.filename end
21 end 17 end
app/models/user.rb
@@ -332,6 +332,8 @@ class User &lt; ActiveRecord::Base @@ -332,6 +332,8 @@ class User &lt; ActiveRecord::Base
332 332
333 { 333 {
334 'login' => self.login, 334 'login' => self.login,
  335 + 'name' => self.person.name,
  336 + 'email' => self.email,
335 'avatar' => self.person.profile_custom_icon(gravatar_default), 337 'avatar' => self.person.profile_custom_icon(gravatar_default),
336 'is_admin' => self.person.is_admin?, 338 'is_admin' => self.person.is_admin?,
337 'since_month' => self.person.created_at.month, 339 'since_month' => self.person.created_at.month,
app/views/cms/_view_items.html.erb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +<% @articles.each do |article| article = FilePresenter.for article %>
  2 + <tr title="<%= article.title%>" >
  3 + <td class="article-name">
  4 + <%= link_to_article(article) %>
  5 + </td>
  6 + <% short_description = article.respond_to?(:short_description) ?
  7 + article.short_description :
  8 + article.class.short_description %>
  9 + <td class="article-mime" title=<%= short_description.to_json %>>
  10 + <%= short_description %>
  11 + </td>
  12 + <td class="last-update">
  13 + <%= time_ago_in_words article.updated_at %>
  14 + </td>
  15 + <td class="article-controls">
  16 + <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
  17 + <%= button_without_text :eyes, _('Public view'), article.view_url %>
  18 + <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
  19 + <% if user.can_change_homepage? && !remove_content_button(:home, article) %>
  20 + <% if profile.home_page != article %>
  21 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  22 + <% else %>
  23 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  24 + <% end %>
  25 + <% end %>
  26 + <%= display_delete_button(article) if !remove_content_button(:delete, article) %>
  27 + </td>
  28 + </tr>
  29 +<% end %>
app/views/cms/view.html.erb
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 <tr> 37 <tr>
38 <th><%= _('Name') %></th> 38 <th><%= _('Name') %></th>
39 <th><%= _('Type') %></th> 39 <th><%= _('Type') %></th>
  40 + <th><%= _('Last update') %></th>
40 <th><%= _('Actions') %></th> 41 <th><%= _('Actions') %></th>
41 </tr> 42 </tr>
42 43
@@ -54,32 +55,7 @@ @@ -54,32 +55,7 @@
54 </tr> 55 </tr>
55 <% end %> 56 <% end %>
56 57
57 - <% @articles.each do |article| article = FilePresenter.for article %>  
58 - <tr title="<%= article.title%>" >  
59 - <td class="article-name">  
60 - <%= link_to_article(article) %>  
61 - </td>  
62 - <% short_description = article.respond_to?(:short_description) ?  
63 - article.short_description :  
64 - article.class.short_description %>  
65 - <td class="article-mime" title=<%= short_description.to_json %>>  
66 - <%= short_description %>  
67 - </td>  
68 - <td class="article-controls">  
69 - <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>  
70 - <%= button_without_text :eyes, _('Public view'), article.view_url %>  
71 - <%= display_spread_button(article) unless remove_content_button(:spread, article) %>  
72 - <% if user.can_change_homepage? && !remove_content_button(:home, article) %>  
73 - <% if profile.home_page != article %>  
74 - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>  
75 - <% else %>  
76 - <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>  
77 - <% end %>  
78 - <% end %>  
79 - <%= display_delete_button(article) if !remove_content_button(:delete, article) %>  
80 - </td>  
81 - </tr>  
82 - <% end %> 58 + <%= render 'view_items' %>
83 59
84 </table> 60 </table>
85 61
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 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>
  2 +
  3 +<%= javascript_include_tag '/javascripts/product_categories.js' %>
  4 +<%= javascript_tag do %>
  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 %>
  7 + product_categories.autocomplete.load('#product_category_id')
  8 +<% end %>
app/views/manage_products/_selected_category_tree.html.erb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +<%= categories_container selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true) %>
  2 +
app/views/manage_products/edit_category.html.erb
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 16
17 <h3><%= _('Edit category of this product:') %></h3> 17 <h3><%= _('Edit category of this product:') %></h3>
18 18
19 - <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> 19 + <%= render 'manage_products/selected_category_tree' %>
20 20
21 <div id='categories_selection_actionbar'> 21 <div id='categories_selection_actionbar'>
22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> 22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %>
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')%>
app/views/shared/_content_item.html.erb
@@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
4 <%= display_content_icon(content) %> 4 <%= display_content_icon(content) %>
5 </div> 5 </div>
6 <span class="item-description"> 6 <span class="item-description">
7 - <%= link_to(short_filename_upper_ext(content.name), content.url) %> 7 + <%= link_to(content.name, content.url) %>
8 </span> 8 </span>
9 <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span> 9 <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span>
10 </div> 10 </div>
11 -</div>  
12 \ No newline at end of file 11 \ No newline at end of file
  12 +</div>
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 +
db/migrate/20140708123314_index_role_assignments_filtered_fields.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class IndexRoleAssignmentsFilteredFields < ActiveRecord::Migration
  2 +
  3 + def self.up
  4 + add_index :role_assignments, [:accessor_id, :accessor_type]
  5 + add_index :role_assignments, [:accessor_id, :accessor_type, :role_id], name: :index_on_role_assigments_accessor_role
  6 + add_index :role_assignments, [:resource_id, :resource_type]
  7 + add_index :role_assignments, [:resource_id, :resource_type, :role_id], name: :index_on_role_assigments_resource_role
  8 + add_index :role_assignments, [:accessor_id, :accessor_type, :resource_id, :resource_type], name: :index_on_role_assigments_accessor_resource_role
  9 + add_index :profiles, [:type]
  10 + add_index :profiles, [:visible]
  11 + add_index :profiles, [:enabled]
  12 + add_index :profiles, [:validated]
  13 + end
  14 +
  15 +end
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"
@@ -376,6 +376,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150602142030) do @@ -376,6 +376,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150602142030) do
376 t.integer "width" 376 t.integer "width"
377 t.integer "height" 377 t.integer "height"
378 t.boolean "thumbnails_processed", :default => false 378 t.boolean "thumbnails_processed", :default => false
  379 + t.string "label", :default => ""
379 end 380 end
380 381
381 add_index "images", ["parent_id"], :name => "index_images_on_parent_id" 382 add_index "images", ["parent_id"], :name => "index_images_on_parent_id"
features/article_visualization.feature 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +Feature: article visualization
  2 + As a user
  3 + I want to change view modes
  4 + In order to see articles in fullscreen or not in fullscreen
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name |
  9 + | joaosilva | Joao Silva |
  10 + And "joaosilva" has no articles
  11 + And the following articles
  12 + | owner | name | body |
  13 + | joaosilva | Sample Article | This is an article |
  14 + And I am logged in as "joaosilva"
  15 +
  16 + @selenium
  17 + Scenario: viewing the article in fullscreen by default
  18 + Given I go to /joaosilva/sample-article?fullscreen=1
  19 + Then I should see "Exit full screen"
  20 +
  21 + @selenium
  22 + Scenario: viewing the article not in fullscreen by default
  23 + Given I go to /joaosilva/sample-article
  24 + Then I should see "Full screen"
  25 +
  26 + @selenium
  27 + Scenario: changing the view mode from not in fullscreen to fullscreen
  28 + Given I go to /joaosilva/sample-article
  29 + And I follow "Full screen"
  30 + Then I should see "Exit full screen"
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
lib/short_filename.rb
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -module ShortFilename  
2 -  
3 - def short_filename(filename, limit_chars = 43)  
4 - extname = File.extname(filename)  
5 - basename = File.basename(filename,extname)  
6 - return shrink(basename, extname, limit_chars) + extname  
7 - end  
8 -  
9 - def short_filename_upper_ext(filename, limit_chars = 43)  
10 - extname = File.extname(filename)  
11 - display_name = shrink(File.basename(filename, extname), extname, limit_chars)  
12 - return extname.present? ? (display_name + ' - ' + extname.upcase.delete(".")) : display_name  
13 - end  
14 -  
15 - def shrink(filename, extname, limit_chars)  
16 - return filename if filename.size <= limit_chars  
17 - str_complement = '(...)'  
18 - return filename[0..(limit_chars - extname.size - str_complement.size - 1)] + str_complement  
19 - end  
20 -  
21 -end  
plugins/context_content/views/blocks/context_content.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <%= instance_eval(&block.content_image(content)) if block.show_image %> 6 <%= instance_eval(&block.content_image(content)) if block.show_image %>
7 </div> 7 </div>
8 <% if block.show_name %> 8 <% if block.show_name %>
9 - <div class="name"><%= short_filename(content.name, 30) %></div> 9 + <div class="name"><%= content.name %></div>
10 <% end %> 10 <% end %>
11 </a> 11 </a>
12 </span> 12 </span>
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/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
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 }
@@ -1401,3 +1404,129 @@ table.profile th { @@ -1401,3 +1404,129 @@ table.profile th {
1401 table#recaptcha_table tr:hover td { 1404 table#recaptcha_table tr:hover td {
1402 background-color: #fff; 1405 background-color: #fff;
1403 } 1406 }
  1407 +
  1408 +/* product cateogories */
  1409 +#categories-container #product_category_id {
  1410 + font-size: 18px;
  1411 + width: 100%;
  1412 + margin-bottom: 8px;
  1413 +}
  1414 +#categories-container #product_category_id:focus {
  1415 + outline: none;
  1416 + border-color: green;
  1417 + box-shadow: 0 0 10px green;
  1418 + color:#333;
  1419 +}
  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
@@ -830,7 +831,7 @@ Array.min = function(array) { @@ -830,7 +831,7 @@ Array.min = function(array) {
830 831
831 function hideAndGetUrl(link) { 832 function hideAndGetUrl(link) {
832 document.body.style.cursor = 'wait'; 833 document.body.style.cursor = 'wait';
833 - link.hide(); 834 + jQuery(link).hide();
834 url = jQuery(link).attr('href'); 835 url = jQuery(link).attr('href');
835 jQuery.get(url, function( data ) { 836 jQuery.get(url, function( data ) {
836 document.body.style.cursor = 'default'; 837 document.body.style.cursor = 'default';
@@ -1178,7 +1179,10 @@ window.isHidden = function isHidden() { return (typeof(document.hidden) != &#39;unde @@ -1178,7 +1179,10 @@ window.isHidden = function isHidden() { return (typeof(document.hidden) != &#39;unde
1178 1179
1179 function $_GET(id){ 1180 function $_GET(id){
1180 var a = new RegExp(id+"=([^&#=]*)"); 1181 var a = new RegExp(id+"=([^&#=]*)");
1181 - return decodeURIComponent(a.exec(window.location.search)[1]); 1182 + var result_of_search = a.exec(window.location.search)
  1183 + if(result_of_search != null){
  1184 + return decodeURIComponent(result_of_search[1]);
  1185 + }
1182 } 1186 }
1183 1187
1184 var fullwidth=false; 1188 var fullwidth=false;
@@ -1206,4 +1210,3 @@ function fullscreenPageLoad(itemId){ @@ -1206,4 +1210,3 @@ function fullscreenPageLoad(itemId){
1206 } 1210 }
1207 }); 1211 });
1208 } 1212 }
1209 -  
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/javascripts/product_categories.js 0 → 100644
@@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
  1 +product_categories = {
  2 +
  3 + autocomplete: {
  4 + search_url: '',
  5 + select_url: '',
  6 +
  7 + load: function(elem) {
  8 + elem = jQuery(elem)
  9 +
  10 + elem.autocomplete({
  11 + minLength: 3,
  12 + selectFirst: true,
  13 +
  14 + //define callback to retrieve results
  15 + source: function(req, add) {
  16 + //pass request to server
  17 + //The alt attribute contains the wordpress callback action
  18 + var params = { term: req.term };
  19 + jQuery.getJSON(product_categories.autocomplete.search_url, params, function(data) {
  20 + add(data);
  21 + });
  22 + },
  23 +
  24 + focus: function( event, ui ) {
  25 + jQuery(this).val(ui.item.label);
  26 + return false;
  27 + },
  28 +
  29 + select: function(e, ui) {
  30 + jQuery('#categories-container').load(product_categories.autocomplete.select_url, {category_id: ui.item.value})
  31 +
  32 + jQuery(this).val("")
  33 + },
  34 +
  35 + });
  36 +
  37 + },
  38 + },
  39 +
  40 +};
public/stylesheets/application.scss
@@ -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')]
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/application_helper_test.rb
@@ -564,18 +564,6 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -564,18 +564,6 @@ class ApplicationHelperTest &lt; ActionView::TestCase
564 assert_equal environment.theme, current_theme 564 assert_equal environment.theme, current_theme
565 end 565 end
566 566
567 - should 'trunc to 15 chars the big filename' do  
568 - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15)  
569 - end  
570 -  
571 - should 'trunc to default limit the big filename' do  
572 - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3')  
573 - end  
574 -  
575 - should 'does not trunc short filename' do  
576 - assert_equal 'filename.mp3', short_filename('filename.mp3')  
577 - end  
578 -  
579 should 'return nil when :show_balloon_with_profile_links_when_clicked is not enabled in environment' do 567 should 'return nil when :show_balloon_with_profile_links_when_clicked is not enabled in environment' do
580 env = Environment.default 568 env = Environment.default
581 env.stubs(:enabled?).with(:show_balloon_with_profile_links_when_clicked).returns(false) 569 env.stubs(:enabled?).with(:show_balloon_with_profile_links_when_clicked).returns(false)
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/short_filename_test.rb
@@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
1 -require_relative "../test_helper"  
2 -  
3 -class NoosferoFilenamesTest < ActiveSupport::TestCase  
4 -  
5 - include ShortFilename  
6 -  
7 - should 'trunc to 15 chars the big filename' do  
8 - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15)  
9 - end  
10 -  
11 - should 'trunc to default limit the big filename' do  
12 - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3')  
13 - end  
14 -  
15 - should 'does not trunc short filename' do  
16 - assert_equal 'filename.mp3', short_filename('filename.mp3')  
17 - end  
18 -  
19 - should 'highlight the file extansion' do  
20 - assert_equal 'AGENDA(...) - MP3', short_filename_upper_ext('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15)  
21 -  
22 - assert_equal 'AGENDA - MP3', short_filename_upper_ext('AGENDA.mp3',15)  
23 - end  
24 -  
25 - should 'return the full filename if its size is smaller than the limit' do  
26 - assert_equal 'AGENDA', shrink('AGENDA', 'mp3', 15)  
27 - end  
28 -  
29 - should 'shrink the filename if its size is bigger than the limit' do  
30 - assert_equal 'AGENDA(...)', shrink('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA', 'mp3', 14)  
31 - end  
32 -  
33 -end  
34 -