Commit 51e4c39124d740b667d172de125ea02ab193f751

Authored by Joenio Costa
2 parents 16848cc8 909c8e7f

Merge branch 'master' into rails-2.3.5

Conflicts:
	test/unit/image_gallery_test.rb
Showing 159 changed files with 4983 additions and 3835 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 159 files displayed.

app/controllers/my_profile/cms_controller.rb
... ... @@ -40,6 +40,9 @@ class CmsController < MyProfileController
40 40 if profile.enterprise?
41 41 articles << EnterpriseHomepage
42 42 end
  43 + if @parent && @parent.blog?
  44 + articles -= Article.folder_types.map(&:constantize)
  45 + end
43 46 articles
44 47 end
45 48  
... ... @@ -100,6 +103,7 @@ class CmsController &lt; MyProfileController
100 103  
101 104 # user must choose an article type first
102 105  
  106 + @parent = profile.articles.find(params[:parent_id]) if params && params[:parent_id]
103 107 record_coming
104 108 @type = params[:type]
105 109 if @type.blank?
... ... @@ -156,7 +160,7 @@ class CmsController &lt; MyProfileController
156 160 profile.home_page = @article
157 161 profile.save(false)
158 162 session[:notice] = _('"%s" configured as home page.') % @article.name
159   - redirect_to :action => 'view', :id => @article.id
  163 + redirect_to (request.referer || profile.url)
160 164 end
161 165  
162 166 def upload_files
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -22,11 +22,12 @@ class ProfileEditorController &lt; MyProfileController
22 22 end
23 23 end
24 24 end
25   - rescue
  25 + rescue Exception => ex
26 26 if profile.identifier.blank?
27 27 profile.identifier = params[:profile]
28 28 end
29 29 session[:notice] = _('Cannot update profile')
  30 + logger.error ex.to_s
30 31 end
31 32 end
32 33 end
... ...
app/controllers/my_profile/tasks_controller.rb
... ... @@ -16,16 +16,18 @@ class TasksController &lt; MyProfileController
16 16 def close
17 17 failed = {}
18 18  
19   - params[:tasks].each do |id, value|
20   - decision = value[:decision]
21   - if request.post? && VALID_DECISIONS.include?(decision) && id && decision != 'skip'
22   - task = profile.find_in_all_tasks(id)
23   - task.update_attributes!(value[:task])
24   - begin
25   - task.send(decision)
26   - rescue Exception => ex
27   - message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
28   - failed[ex.clean_message] ? failed[ex.clean_message] << message : failed[ex.clean_message] = [message]
  19 + if params[:tasks]
  20 + params[:tasks].each do |id, value|
  21 + decision = value[:decision]
  22 + if request.post? && VALID_DECISIONS.include?(decision) && id && decision != 'skip'
  23 + task = profile.find_in_all_tasks(id)
  24 + begin
  25 + task.update_attributes(value[:task])
  26 + task.send(decision)
  27 + rescue Exception => ex
  28 + message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
  29 + failed[ex.clean_message] ? failed[ex.clean_message] << message : failed[ex.clean_message] = [message]
  30 + end
29 31 end
30 32 end
31 33 end
... ...
app/controllers/public/browse_controller.rb
... ... @@ -8,17 +8,20 @@ class BrowseController &lt; PublicController
8 8 more_popular
9 9 )
10 10  
  11 + def per_page
  12 + 27
  13 + end
  14 +
11 15 def people
12 16 @filter = filter
13 17 @title = self.filter_description(params[:action] + '_' + @filter )
14 18  
15 19 @results = @environment.people.visible.send(@filter)
16 20  
17   - if params[:query].blank?
18   - @results = @results.paginate(:per_page => 27, :page => params[:page])
19   - else
20   - @results = @results.find_by_contents(params[:query]).paginate(:per_page => 27, :page => params[:page])
  21 + if !params[:query].blank?
  22 + @results = @results.find_by_contents(params[:query])
21 23 end
  24 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
22 25 end
23 26  
24 27 def communities
... ... @@ -27,11 +30,10 @@ class BrowseController &lt; PublicController
27 30  
28 31 @results = @environment.communities.visible.send(@filter)
29 32  
30   - if params[:query].blank?
31   - @results = @results.paginate(:per_page => 27, :page => params[:page])
32   - else
33   - @results = @results.find_by_contents(params[:query]).paginate(:per_page => 27, :page => params[:page])
  33 + if !params[:query].blank?
  34 + @results = @results.find_by_contents(params[:query])
34 35 end
  36 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
35 37 end
36 38  
37 39 protected
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -43,6 +43,11 @@ class ContentViewerController &lt; ApplicationController
43 43 return
44 44 end
45 45  
  46 + if request.xhr? && params[:toolbar]
  47 + render :partial => 'article_toolbar'
  48 + return
  49 + end
  50 +
46 51 redirect_to_translation
47 52  
48 53 # At this point the page will be showed
... ... @@ -79,11 +84,11 @@ class ContentViewerController &lt; ApplicationController
79 84 @page.posts
80 85 end
81 86  
82   - posts = posts.native_translations if @page.blog? && @page.display_posts_in_current_language?
  87 + if @page.blog? && @page.display_posts_in_current_language?
  88 + posts = posts.native_translations.all(Article.display_filter(user, profile)).map{ |p| p.get_translation_to(FastGettext.locale) }.compact
  89 + end
83 90  
84 91 @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile)))
85   -
86   - @posts.map!{ |p| p.get_translation_to(FastGettext.locale) } if @page.blog? && @page.display_posts_in_current_language?
87 92 end
88 93  
89 94 if @page.folder? && @page.gallery?
... ...
app/controllers/public/profile_controller.rb
... ... @@ -105,6 +105,8 @@ class ProfileController &lt; PublicController
105 105 end
106 106 if request.xhr?
107 107 render :layout => false
  108 + else
  109 + redirect_to profile.url
108 110 end
109 111 end
110 112 end
... ... @@ -213,6 +215,14 @@ class ProfileController &lt; PublicController
213 215 end
214 216 end
215 217  
  218 + def profile_info
  219 + begin
  220 + @block = profile.blocks.find(params[:block_id])
  221 + rescue
  222 + render :text => _('Profile information could not be loaded')
  223 + end
  224 + end
  225 +
216 226 protected
217 227  
218 228 def check_access_to_profile
... ...
app/helpers/application_helper.rb
... ... @@ -1190,16 +1190,18 @@ module ApplicationHelper
1190 1190 stylesheet_link_tag('fancybox') +
1191 1191 javascript_include_tag('jquery.fancybox-1.3.4.pack') +
1192 1192 javascript_tag("jQuery(function($) {
1193   - $('#article .article-body img').each( function(index) {
1194   - var original = original_image_dimensions($(this).attr('src'));
1195   - if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1196   - $(this).wrap('<div class=\"zoomable-image\" />');
1197   - $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));
1198   - $(this).attr('style', '');
1199   - $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');
1200   - }
  1193 + $(window).load( function() {
  1194 + $('#article .article-body img').each( function(index) {
  1195 + var original = original_image_dimensions($(this).attr('src'));
  1196 + if ($(this).width() < original['width'] || $(this).height() < original['height']) {
  1197 + $(this).wrap('<div class=\"zoomable-image\" />');
  1198 + $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));
  1199 + $(this).attr('style', '');
  1200 + $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');
  1201 + }
  1202 + });
  1203 + $('.zoomify-image').fancybox();
1201 1204 });
1202   - $('.zoomify-image').fancybox();
1203 1205 });" % _('Zoom in'))
1204 1206 end
1205 1207 end
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -20,19 +20,18 @@ module ContentViewerHelper
20 20 unless args[:no_link]
21 21 title = content_tag('h1', link_to(article.name, article.url), :class => 'title')
22 22 end
23   - comments = args[:no_comments] ? '' : (("- %s") % link_to_comments(article))
  23 + comments = ''
  24 + unless args[:no_comments] || !article.accept_comments
  25 + comments = ("- %s") % link_to_comments(article)
  26 + end
24 27 title << content_tag('span', _("%s, by %s %s") % [show_date(article.published_at), link_to(article.author_name, article.author.url), comments], :class => 'created-at')
25 28 end
26 29 title
27 30 end
28 31  
29 32 def link_to_comments(article, args = {})
30   - link_to( number_of_comments(article), article.url.merge(:anchor => 'comments_list') )
31   - end
32   -
33   - def image_label(image)
34   - text = image.abstract || image.title
35   - text && (text.first(40) + (text.size > 40 ? '…' : ''))
  33 + return '' unless article.accept_comments?
  34 + link_to(number_of_comments(article), article.url.merge(:anchor => 'comments_list') )
36 35 end
37 36  
38 37 def article_translations(article)
... ...
app/helpers/lightbox_helper.rb
... ... @@ -32,4 +32,8 @@ module LightboxHelper
32 32 request.xhr?
33 33 end
34 34  
  35 + def lightbox_remote_button(type, label, url, options = {})
  36 + button(type, label, url, lightbox_options(options, 'remote-lbOn'))
  37 + end
  38 +
35 39 end
... ...
app/helpers/manage_products_helper.rb
... ... @@ -217,10 +217,10 @@ module ManageProductsHelper
217 217 end
218 218  
219 219 def qualifiers_for_select
220   - [[_('Select...'), nil]] + environment.qualifiers.map{ |c| [c.name, c.id] }
  220 + [[_('Select...'), nil]] + environment.qualifiers.sort.map{ |c| [c.name, c.id] }
221 221 end
222 222 def certifiers_for_select(qualifier)
223   - [[_('Self declared'), nil]] + qualifier.certifiers.map{ |c| [c.name, c.id] }
  223 + [[_('Self declared'), nil]] + qualifier.certifiers.sort.map{ |c| [c.name, c.id] }
224 224 end
225 225 def select_qualifiers(product, selected = nil)
226 226 select_tag('selected_qualifier', options_for_select(qualifiers_for_select, selected),
... ... @@ -242,8 +242,7 @@ module ManageProductsHelper
242 242 end
243 243  
244 244 def select_unit(object)
245   - selected = object.unit.nil? ? '' : object.unit
246   - select(object.class.name.downcase, 'unit', Product::UNITS.map{|unit| [_(unit[0]), unit[0]]}, {:selected => selected, :include_blank => _('Select the unit')})
  245 + collection_select(object.class.name.downcase, :unit_id, environment.units, :id, :singular, {:include_blank => _('Select the unit')})
247 246 end
248 247  
249 248 def input_icon(input)
... ... @@ -263,14 +262,13 @@ module ManageProductsHelper
263 262 if product_unit.blank?
264 263 _('Amount used in this product or service')
265 264 else
266   - _('Amount used by %s of this product or service') % _(product_unit)
  265 + _('Amount used by %s of this product or service') % product_unit.singular.downcase
267 266 end
268 267 end
269 268  
270 269 def display_unit(input)
271 270 input_amount_used = content_tag('span', input.formatted_amount, :class => 'input-amount-used')
272 271 return input_amount_used if input.unit.blank?
273   - units = Product::UNITS.find {|unit| unit[0] == input.unit}
274   - n_('1 %{singular_unit}', '%{num} %{plural_unit}', input.amount_used.to_f) % { :num => input_amount_used, :singular_unit => content_tag('span', units[0], :class => 'input-unit'), :plural_unit => content_tag('span', units[1], :class => 'input-unit') }
  272 + n_('1 %{singular_unit}', '%{num} %{plural_unit}', input.amount_used.to_f) % { :num => input_amount_used, :singular_unit => content_tag('span', input.unit.singular, :class => 'input-unit'), :plural_unit => content_tag('span', input.unit.plural, :class => 'input-unit') }
275 273 end
276 274 end
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -18,7 +18,7 @@ module ProfileEditorHelper
18 18 N_('Science Politics'),
19 19 N_('Accounting and Actuarial Science'),
20 20 N_('Morphologic Sciences'),
21   - N_('Computation'),
  21 + N_('Computer Science'),
22 22 N_('Rural Development'),
23 23 N_('Law'),
24 24 N_('Ecology'),
... ...
app/helpers/search_helper.rb
... ... @@ -65,7 +65,7 @@ module SearchHelper
65 65 data << content_tag('strong', _('Address: ')) + profile.address + '<br/>'
66 66 end
67 67 unless profile.products.empty?
68   - data << content_tag('strong', _('Products/Services: ')) + profile.products.map{|i| link_to(i.name, :controller => 'catalog', :profile => profile.identifier, :action => 'show', :id => i)}.join(', ') + '<br/>'
  68 + data << content_tag('strong', _('Products/Services: ')) + profile.products.map{|i| link_to(i.name, :controller => 'manage_products', :profile => profile.identifier, :action => 'show', :id => i.id)}.join(', ') + '<br/>'
69 69 end
70 70 if profile.respond_to?(:distance) and !profile.distance.nil?
71 71 data << content_tag('strong', _('Distance: ')) + "%.2f%" % profile.distance + '<br/>'
... ...
app/models/article.rb
... ... @@ -319,12 +319,12 @@ class Article &lt; ActiveRecord::Base
319 319 end
320 320  
321 321 def get_translation_to(locale)
322   - if self.language.nil? || self.language == locale
  322 + if self.language.nil? || self.language.blank? || self.language == locale
323 323 self
324 324 elsif self.native_translation.language == locale
325 325 self.native_translation
326 326 else
327   - self.native_translation.translations.first(:conditions => { :language => locale }) || self
  327 + self.native_translation.translations.first(:conditions => { :language => locale })
328 328 end
329 329 end
330 330  
... ... @@ -339,8 +339,13 @@ class Article &lt; ActiveRecord::Base
339 339 end
340 340 end
341 341  
  342 + def self.folder_types
  343 + ['Folder', 'Blog', 'Forum', 'Gallery']
  344 + end
  345 +
342 346 named_scope :published, :conditions => { :published => true }
343   - named_scope :folders, :conditions => { :type => ['Folder', 'Blog', 'Forum', 'Gallery'] }
  347 + named_scope :folders, :conditions => { :type => folder_types}
  348 + named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types]
344 349 named_scope :galleries, :conditions => { :type => 'Gallery' }
345 350 named_scope :images, :conditions => { :is_image => true }
346 351  
... ... @@ -412,6 +417,7 @@ class Article &lt; ActiveRecord::Base
412 417 :profile_id,
413 418 :parent_id,
414 419 :path,
  420 + :slug,
415 421 :updated_at,
416 422 :created_at,
417 423 :last_changed_by_id,
... ... @@ -499,6 +505,10 @@ class Article &lt; ActiveRecord::Base
499 505 false
500 506 end
501 507  
  508 + def accept_uploads?
  509 + self.parent && self.parent.accept_uploads?
  510 + end
  511 +
502 512 private
503 513  
504 514 def sanitize_tag_list
... ...
app/models/blog.rb
... ... @@ -2,6 +2,13 @@ class Blog &lt; Folder
2 2  
3 3 acts_as_having_posts
4 4  
  5 + #FIXME This should be used until there is a migration to fix all blogs that
  6 + # already have folders inside them
  7 + def posts_with_no_folders
  8 + posts_without_no_folders.no_folders
  9 + end
  10 + alias_method_chain :posts, :no_folders
  11 +
5 12 def self.short_description
6 13 _('Blog')
7 14 end
... ...
app/models/blog_archives_block.rb
... ... @@ -17,7 +17,7 @@ class BlogArchivesBlock &lt; Block
17 17 settings_items :blog_id, Integer
18 18  
19 19 def blog
20   - blog_id ? owner.blogs.find(blog_id) : owner.blog
  20 + blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog
21 21 end
22 22  
23 23 def content
... ...
app/models/certifier.rb
... ... @@ -11,4 +11,9 @@ class Certifier &lt; ActiveRecord::Base
11 11 def link
12 12 self[:link] || ''
13 13 end
  14 +
  15 + def <=>(b)
  16 + self.name.downcase.transliterate <=> b.name.downcase.transliterate
  17 + end
  18 +
14 19 end
... ...
app/models/change_password.rb
... ... @@ -68,6 +68,10 @@ class ChangePassword &lt; Task
68 68 user.force_change_password!(self.password, self.password_confirmation)
69 69 end
70 70  
  71 + def target_notification_description
  72 + _('%{requestor} wants to change its password.') % {:requestor => requestor.name}
  73 + end
  74 +
71 75 # overriding messages
72 76  
73 77 def task_cancelled_message
... ...
app/models/enterprise_activation.rb
... ... @@ -35,4 +35,8 @@ class EnterpriseActivation &lt; Task
35 35 {:type => :profile_image, :profile => requestor, :url => requestor.url}
36 36 end
37 37  
  38 + def target_notification_description
  39 + _('%{requestor} wants to activate enterprise %{enterprise}.') % {:requestor => requestor.name, :enterprise => enterprise.name}
  40 + end
  41 +
38 42 end
... ...
app/models/environment.rb
... ... @@ -93,7 +93,6 @@ class Environment &lt; ActiveRecord::Base
93 93 'enterprise_registration' => __('Enterprise registration'),
94 94  
95 95 'enterprise_activation' => __('Enable activation of enterprises'),
96   - 'wysiwyg_editor_for_environment_home' => _('Use WYSIWYG editor to edit environment home page'),
97 96 'media_panel' => _('Media panel in WYSIWYG editor'),
98 97 'select_preferred_domain' => _('Select preferred domains per profile'),
99 98 'use_portal_community' => _('Use the portal as news source for front page'),
... ... @@ -162,6 +161,8 @@ class Environment &lt; ActiveRecord::Base
162 161  
163 162 acts_as_accessible
164 163  
  164 + has_many :units, :order => 'position'
  165 +
165 166 def superior_intances
166 167 [self, nil]
167 168 end
... ... @@ -271,7 +272,6 @@ class Environment &lt; ActiveRecord::Base
271 272 organizations_are_moderated_by_default
272 273 show_balloon_with_profile_links_when_clicked
273 274 use_portal_community
274   - wysiwyg_editor_for_environment_home
275 275 ).each do |feature|
276 276 enable(feature)
277 277 end
... ...
app/models/folder.rb
1 1 class Folder < Article
2 2  
  3 + validate :not_belong_to_blog
  4 +
  5 + def not_belong_to_blog
  6 + errors.add(:parent, "A folder should not belong to a blog.") if parent && parent.blog?
  7 + end
  8 +
3 9 acts_as_having_settings :field => :setting
4 10  
5 11 xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation'
... ... @@ -47,4 +53,9 @@ class Folder &lt; Article
47 53 :foreign_key => 'parent_id',
48 54 :order => 'articles.type, articles.name',
49 55 :conditions => ["articles.type = 'UploadedFile' and articles.content_type in (?) or articles.type in ('Folder','Gallery')", UploadedFile.content_types]
  56 +
  57 + def accept_uploads?
  58 + !self.has_posts? || self.gallery?
  59 + end
  60 +
50 61 end
... ...
app/models/image_gallery.rb
... ... @@ -1,11 +0,0 @@
1   -class ImageGallery < Article
2   -
3   - def self.short_description
4   - _('Image gallery')
5   - end
6   -
7   - def self.description
8   - _('A collection of photos, logos or other kinds of images.')
9   - end
10   -
11   -end
app/models/input.rb
... ... @@ -7,6 +7,8 @@ class Input &lt; ActiveRecord::Base
7 7  
8 8 acts_as_list :scope => :product
9 9  
  10 + belongs_to :unit
  11 +
10 12 include FloatHelper
11 13  
12 14 def price_per_unit=(value)
... ...
app/models/invite_friend.rb
... ... @@ -23,6 +23,10 @@ class InviteFriend &lt; Invitation
23 23 {:type => :profile_image, :profile => requestor, :url => requestor.url}
24 24 end
25 25  
  26 + def target_notification_description
  27 + _('%{requestor} wants to be your friend.') % {:requestor => requestor.name}
  28 + end
  29 +
26 30 def permission
27 31 :manage_friends
28 32 end
... ...
app/models/invite_member.rb
... ... @@ -35,6 +35,10 @@ class InviteMember &lt; Invitation
35 35 {:type => :profile_image, :profile => community, :url => community.url}
36 36 end
37 37  
  38 + def target_notification_description
  39 + _('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}
  40 + end
  41 +
38 42 def expanded_message
39 43 super.gsub /<community>/, community.name
40 44 end
... ...
app/models/organization.rb
... ... @@ -21,6 +21,19 @@ class Organization &lt; Profile
21 21  
22 22 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
23 23  
  24 + named_scope :more_popular,
  25 + :select => "#{Profile.qualified_column_names}, count(resource_id) as total",
  26 + :group => Profile.qualified_column_names,
  27 + :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id",
  28 + :order => "total DESC"
  29 +
  30 + named_scope :more_active,
  31 + :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",
  32 + :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id",
  33 + :group => Profile.qualified_column_names,
  34 + :order => 'total DESC',
  35 + :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago]
  36 +
24 37 def validation_methodology
25 38 self.validation_info ? self.validation_info.validation_methodology : nil
26 39 end
... ...
app/models/person.rb
... ... @@ -22,10 +22,17 @@ class Person &lt; Profile
22 22 has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy
23 23  
24 24 named_scope :more_popular,
25   - :select => "#{Profile.qualified_column_names}, count(friend_id) as total",
26   - :group => Profile.qualified_column_names,
27   - :joins => :friendships,
28   - :order => "total DESC"
  25 + :select => "#{Profile.qualified_column_names}, count(friend_id) as total",
  26 + :group => Profile.qualified_column_names,
  27 + :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id",
  28 + :order => "total DESC"
  29 +
  30 + named_scope :more_active,
  31 + :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",
  32 + :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id",
  33 + :group => Profile.qualified_column_names,
  34 + :order => 'total DESC',
  35 + :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago]
29 36  
30 37 after_destroy do |person|
31 38 Friendship.find(:all, :conditions => { :friend_id => person.id}).each { |friendship| friendship.destroy }
... ... @@ -149,7 +156,7 @@ class Person &lt; Profile
149 156 N_('Schooling status')
150 157 settings_items :schooling_status
151 158  
152   - N_('Formation'); N_('Custom formation'); N_('Custom area of study');
  159 + N_('Education'); N_('Custom education'); N_('Custom area of study');
153 160 settings_items :formation, :custom_formation, :custom_area_of_study
154 161  
155 162 N_('Contact information'); N_('City'); N_('State'); N_('Country'); N_('Sex'); N_('Zip code')
... ...
app/models/product.rb
... ... @@ -42,14 +42,9 @@ class Product &lt; ActiveRecord::Base
42 42  
43 43 acts_as_mappable
44 44  
45   - include FloatHelper
  45 + belongs_to :unit
46 46  
47   - UNITS = [
48   - [N_('unit'), _('units')],
49   - [N_('litre'), _('litres')],
50   - [N_('kilo'), _('kilos')],
51   - [N_('meter'), _('meters')],
52   - ]
  47 + include FloatHelper
53 48  
54 49 include WhiteListFilter
55 50 filter_iframes :description, :whitelist => lambda { enterprise && enterprise.environment && enterprise.environment.trusted_sites_for_iframe }
... ... @@ -151,7 +146,7 @@ class Product &lt; ActiveRecord::Base
151 146 end
152 147  
153 148 def name_with_unit
154   - unit.blank? ? name : "#{name} - #{_(unit)}"
  149 + unit.blank? ? name : "#{name} - #{unit.name.downcase}"
155 150 end
156 151  
157 152 end
... ...
app/models/profile.rb
... ... @@ -78,18 +78,11 @@ class Profile &lt; ActiveRecord::Base
78 78 end
79 79  
80 80 named_scope :visible, :conditions => { :visible => true }
  81 + # Subclasses must override these methods
  82 + named_scope :more_popular
  83 + named_scope :more_active
  84 +
81 85 named_scope :more_recent, :order => "created_at DESC"
82   - named_scope :more_popular,
83   - :select => "#{Profile.qualified_column_names}, count(resource_id) as total",
84   - :group => Profile.qualified_column_names,
85   - :joins => :role_assignments,
86   - :order => "total DESC"
87   - named_scope :more_active,
88   - :select => "#{Profile.qualified_column_names}, count(articles.id) as total, sum(articles.comments_count) as total_comments",
89   - :joins => :articles,
90   - :group => Profile.qualified_column_names,
91   - :order => "total DESC, total_comments DESC",
92   - :conditions => ["articles.created_at BETWEEN ? AND ?", 7.days.ago, DateTime.now]
93 86  
94 87 acts_as_trackable :dependent => :destroy
95 88  
... ... @@ -152,6 +145,7 @@ class Profile &lt; ActiveRecord::Base
152 145 assets
153 146 doc
154 147 chat
  148 + plugin
155 149 ]
156 150  
157 151 belongs_to :user
... ... @@ -778,18 +772,27 @@ private :generate_url, :url_options
778 772 _("Since: ")
779 773 end
780 774  
  775 + def recent_actions
  776 + tracked_actions.recent
  777 + end
  778 +
  779 + def recent_notifications
  780 + tracked_notifications.recent
  781 + end
  782 +
781 783 def more_active_label
782   - amount = self.articles.count
  784 + amount = recent_actions.count
  785 + amount += recent_notifications.count if organization?
783 786 {
784   - 0 => _('none'),
785   - 1 => _('one article')
786   - }[amount] || _("%s articles") % amount
  787 + 0 => _('no activity'),
  788 + 1 => _('one activity')
  789 + }[amount] || _("%s activities") % amount
787 790 end
788 791  
789 792 def more_popular_label
790 793 amount = self.members_count
791 794 {
792   - 0 => _('none'),
  795 + 0 => _('no members'),
793 796 1 => _('one member')
794 797 }[amount] || _("%s members") % amount
795 798 end
... ...
app/models/qualifier.rb
... ... @@ -8,4 +8,10 @@ class Qualifier &lt; ActiveRecord::Base
8 8 validates_presence_of :environment_id
9 9 validates_presence_of :name
10 10  
  11 + has_many :product_qualifiers, :dependent => :destroy
  12 +
  13 + def <=>(b)
  14 + self.name.downcase.transliterate <=> b.name.downcase.transliterate
  15 + end
  16 +
11 17 end
... ...
app/models/task_mailer.rb
... ... @@ -32,7 +32,7 @@ class TaskMailer &lt; ActionMailer::Base
32 32 recipients task.friend_email
33 33  
34 34 from self.class.generate_from(task)
35   - subject '[%s] %s' % [ task.requestor.environment.name, task.information ]
  35 + subject '[%s] %s' % [ task.requestor.environment.name, task.target_notification_description ]
36 36 body :message => msg
37 37 end
38 38  
... ... @@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base
52 52  
53 53 recipients task.requestor.notification_emails
54 54 from self.class.generate_from(task)
55   - subject '[%s] %s' % [task.requestor.environment.name, task.information]
  55 + subject '[%s] %s' % [task.requestor.environment.name, task.target_notification_description]
56 56 body :requestor => task.requestor.name,
57 57 :message => text,
58 58 :environment => task.requestor.environment.name,
... ...
app/models/unit.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +class Unit < ActiveRecord::Base
  2 +
  3 + validates_presence_of :singular
  4 + validates_presence_of :plural
  5 +
  6 + belongs_to :environment
  7 + validates_presence_of :environment_id
  8 + acts_as_list :scope => :environment
  9 +
  10 + def name
  11 + self.singular
  12 + end
  13 + def name=(value)
  14 + self.singular = value
  15 + end
  16 +
  17 +end
... ...
app/models/uploaded_file.rb
... ... @@ -9,6 +9,8 @@ class UploadedFile &lt; Article
9 9 include ShortFilename
10 10  
11 11 settings_items :title, :type => 'string'
  12 + xss_terminate :only => [ :title ]
  13 +
12 14 def title_with_default
13 15 title_without_default || short_filename(name, 60)
14 16 end
... ... @@ -28,6 +30,10 @@ class UploadedFile &lt; Article
28 30 title.blank? ? name : title
29 31 end
30 32  
  33 + def first_paragraph
  34 + ''
  35 + end
  36 +
31 37 def self.max_size
32 38 UploadedFile.attachment_options[:max_size]
33 39 end
... ... @@ -48,7 +54,7 @@ class UploadedFile &lt; Article
48 54  
49 55 def self.icon_name(article = nil)
50 56 if article
51   - article.image? ? article.public_filename(:icon) : article.mime_type.gsub(/[\/+.]/, '-')
  57 + article.image? ? article.public_filename(:icon) : (article.mime_type ? article.mime_type.gsub(/[\/+.]/, '-') : 'upload-file')
52 58 else
53 59 'upload-file'
54 60 end
... ...
app/views/admin_panel/site_info.rhtml
1 1 <h2><%= _('Site info') %></h2>
2 2  
3   -<% if @environment.enabled?('wysiwyg_editor_for_environment_home') %>
4   - <%= render :file => 'shared/tiny_mce' %>
5   -<% end %>
  3 +<%= render :file => 'shared/tiny_mce' %>
6 4  
7 5 <% labelled_form_for :environment, @environment do |f| %>
8 6  
9 7 <%= labelled_form_field(_('Site name'), text_field(:environment, :name)) %>
10 8  
11   - <%= labelled_form_field _('Homepage content'), text_area(:environment, :description, :cols => 40, :style => 'width: 90%') %>
  9 + <%= labelled_form_field _('Homepage content'), text_area(:environment, :description, :cols => 40, :style => 'width: 90%', :class => 'mceEditor') %>
12 10  
13 11 <% button_bar do %>
14 12 <%= submit_button(:save, _('Save')) %>
... ...
app/views/blocks/profile_image.rhtml
... ... @@ -14,14 +14,11 @@
14 14 <p><%= h block.owner.short_name %></p>
15 15 <% end %>
16 16  
17   -<% if !user.nil? and user.has_permission?('edit_profile', profile) %>
18   - <div style='text-align: center; font-size: 75%; clear: both'>
19   - <%= link_to _('Control panel'), :controller => 'profile_editor' %>
20   - </div>
21   -<% end %>
  17 +<div style="text-align: center; font-size: 75%; clear: both" id="profile-admin-url-<%= block.id %>"></div>
22 18  
23   -<div class="profile-info-options">
24   - <%= render :file => 'blocks/profile_info_actions/' + block.owner.class.name.underscore %>
25   -</div>
  19 +<div class="profile-info-options" id="profile-info-options-<%= block.id %>"></div>
26 20  
27 21 </div><!-- end class="vcard" -->
  22 +<script type="text/javascript">
  23 + <%= remote_function :url => { :controller => 'profile', :action => 'profile_info', :block_id => block.id } %>
  24 +</script>
... ...
app/views/blocks/profile_info.rhtml
... ... @@ -14,15 +14,13 @@
14 14 </div>
15 15 </div>
16 16  
17   -<ul class="profile-info-data">
  17 +<ul class="profile-info-data" id="profile-info-data-<%= block.id %>">
18 18 <li><%= link_to __('Homepage'), block.owner.url, :class => 'url' %></li>
19 19 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li>
20 20 <% if block.owner.enterprise? && !block.owner.environment.enabled?('disable_products_for_enterprises') %>
21 21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>
22 22 <% end %>
23   - <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
24   - <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
25   - <% end %>
  23 + <li id="profile-admin-url-<%= block.id %>"></li>
26 24 <% if profile.person? %>
27 25 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
28 26 <% end %>
... ... @@ -39,8 +37,9 @@
39 37 </div>
40 38 <% end %>
41 39  
42   -<div class="profile-info-options">
43   - <%= render :file => 'blocks/profile_info_actions/' + block.owner.class.name.underscore %>
44   -</div>
  40 +<div class="profile-info-options" id="profile-info-options-<%= block.id %>"></div>
45 41  
46 42 </div><!-- end class="vcard" -->
  43 +<script type="text/javascript">
  44 + <%= remote_function :url => { :controller => 'profile', :action => 'profile_info', :block_id => block.id } %>
  45 +</script>
... ...
app/views/box_organizer/_profile_list_block.rhtml
1 1 <div id='edit-profile-list-block'>
2 2 <%= labelled_form_field _('Limit of items'), text_field(:block, :limit, :size => 3) %>
3   - <%= labelled_form_field _('Prioritize profiles with image'), check_box(:block, :prioritize_profiles_with_image) %>
  3 + <%= check_box(:block, :prioritize_profiles_with_image) %>
  4 + <label for="block_prioritize_profiles_with_image"><%= _('Prioritize profiles with image') %></label>
4 5 </div>
5 6  
... ...
app/views/catalog/index.rhtml
1 1 <%= display_products_list @profile, @products %>
2 2  
3   -<%= will_paginate @products %>
  3 +<%= pagination_links @products %>
... ...
app/views/cms/_blog.rhtml
... ... @@ -56,7 +56,7 @@
56 56  
57 57 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %>
58 58  
59   -<%= labelled_check_box(_("Try listing only translated posts"), 'article[display_posts_in_current_language]', '1', @article.display_posts_in_current_language?) %>
  59 +<%= labelled_check_box(_("List only translated posts"), 'article[display_posts_in_current_language]', '1', @article.display_posts_in_current_language?) %>
60 60  
61 61 <% f.fields_for 'feed', @article.feed do |feed| %>
62 62 <%= labelled_form_field(_('Limit of posts in RSS Feed'), feed.select(:limit, [5, 10, 20, 50])) %>
... ...
app/views/cms/_event.rhtml
... ... @@ -15,5 +15,4 @@
15 15  
16 16 <%= labelled_form_field(_('Address:'), text_field(:article, :address)) %>
17 17  
18   -<%= labelled_form_field(_('Information about the event:'), text_area(:article, :body, :cols => 64, :class => 'mceEditor')) %>
19   -
  18 +<%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :body_label => 'Information about the event:'} %>
... ...
app/views/cms/_textile_article.rhtml
... ... @@ -5,17 +5,4 @@
5 5 <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64')) %>
6 6  
7 7 <%= render :partial => 'translatable' %>
8   -
9   -<br style="clear: both;"/>
10   -<%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %>
11   -<em><%= _('Used when a short version of your text is needed.') %></em>
12   -
13   -<div id="article-lead">
14   - <%= labelled_form_field(_('Lead'), text_area(:article, 'abstract', :cols => 64, :rows => 10)) %>
15   -</div>
16   -<div style="margin-top: 10px;">
17   - <%= labelled_form_field(_('Text'), text_area(:article, 'body', :cols => 64, :rows => 30)) %>
18   -</div>
19   -
20   -<%= javascript_include_tag 'article'%>
21   -
  8 +<%= render :partial => 'shared/lead_and_body' %>
... ...
app/views/cms/_tiny_mce_article.rhtml
... ... @@ -12,18 +12,5 @@
12 12 <% end %>
13 13  
14 14 <%= render :partial => 'translatable' %>
15   -
16   - <br style="clear: both;"/>
17   - <%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %>
18   - <em><%= _('Used when a short version of your text is needed.') %></em>
19   -
20   - <div id="article-lead">
21   - <%= labelled_form_field(_('Lead'), text_area(:article, 'abstract', :style => 'width: 100%; height: 200px;', :class => 'mceEditor')) %>
22   - </div>
23   - <div style="margin-top: 10px;">
24   - <%= labelled_form_field(_('Text'), text_area(:article, 'body', :style => 'width:100%; height: 500px;', :class => 'mceEditor')) %>
25   - </div>
26   -
  15 + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true} %>
27 16 </div>
28   -
29   -<%= javascript_include_tag 'article' %>
... ...
app/views/cms/suggest_an_article.rhtml
... ... @@ -16,16 +16,7 @@
16 16  
17 17 <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %>
18 18  
19   - <br style="clear: both;"/>
20   - <%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %>
21   - <em><%= _('Used when a short version of your text is needed.') %></em>
22   -
23   - <div id="article-lead">
24   - <%= labelled_form_field(_('Lead'), text_area(:task , 'article_abstract', :style => 'width: 100%; height: 200px;', :class => 'mceEditor')) %>
25   - </div>
26   - <div style="margin-top: 10px;">
27   - <%= labelled_form_field(_('Text'), text_area(:task, 'article_body', :style => 'width:100%; height: 500px;', :class => 'mceEditor')) %>
28   - </div>
  19 + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => :task, :abstract_method => 'article_abstract', :body_method => 'article_body'} %>
29 20  
30 21 <div id="captcha">
31 22 <%= labelled_form_field(_("What is the result of '%s = ?'") % @task.captcha.task, text_field(:task, 'captcha_solution')) %>
... ... @@ -39,5 +30,3 @@
39 30 <%= button :cancel, _('Cancel'), @back_to %>
40 31 <% end %>
41 32 <% end %>
42   -
43   -<%= javascript_include_tag 'article' %>
... ...
app/views/content_viewer/_article_toolbar.rhtml 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +<div<%= " class='logged-in'" if user %>>
  2 + <% if @page.allow_post_content?(user) || @page.allow_publish_content?(user) %>
  3 + <div id="article-actions">
  4 + <% if @page.allow_post_content?(user) %>
  5 + <%= link_to content_tag( 'span', label_for_edit_article(@page) ),
  6 + profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }),
  7 + :class => 'button with-text icon-edit' %>
  8 + <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %>
  9 + <% if @page != profile.home_page && !@page.has_posts? %>
  10 + <%= link_to content_tag( 'span', _('Delete') ),
  11 + profile.admin_url.merge({ :controller => 'cms', :action => 'destroy', :id => @page }),
  12 + :class => 'button with-text icon-delete' %>
  13 + <% end %>
  14 + <% if !environment.enabled?('disable_cms') && !@page.folder? %>
  15 + <% if profile.kind_of?(Person) %>
  16 + <%= link_to content_tag( 'span', _('Spread this') ),
  17 + profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page }),
  18 + :class => 'button with-text icon-spread' %>
  19 + <% elsif profile.kind_of?(Community) && environment.portal_community %>
  20 + <%= link_to content_tag( 'span', _('Spread this') ),
  21 + profile.admin_url.merge({ :controller => 'cms', :action => 'publish_on_portal_community', :id => @page }),
  22 + :class => 'button with-text icon-spread' %>
  23 + <% end %>
  24 + <% end %>
  25 + <% end %>
  26 + <% end %>
  27 + <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %>
  28 + <% if !@page.gallery? %>
  29 + <%= link_to _('Add translation'),
  30 + profile.admin_url.merge(:controller => 'cms', :action => 'new',
  31 + :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)),
  32 + :type => @page.type, :article => { :translation_of_id => @page.native_translation.id }),
  33 + :class => 'button with-text icon-locale' if @page.translatable? && !@page.native_translation.language.blank? %>
  34 + <%= lightbox_remote_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) %>
  35 + <% end %>
  36 + <% end %>
  37 + <% if @page.accept_uploads? %>
  38 + <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) %>
  39 + <% end %>
  40 + </div>
  41 + <% elsif profile.community? && (@page.blog? || @page.parent && @page.parent.blog?) %>
  42 + <div id="article-actions">
  43 + <%= link_to content_tag( 'span', _('Suggest an article') ), profile.admin_url.merge({ :controller => 'cms', :action => 'suggest_an_article'}), :id => 'suggest-article-link', :class => 'button with-text icon-new' %>
  44 + </div>
  45 + <% end %>
  46 + <div id="article-header">
  47 + <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
  48 + <%= article_title(@page, :no_link => true) %>
  49 + <%= article_translations(@page) %>
  50 + </div>
  51 +</div>
... ...
app/views/content_viewer/_uploaded_file.rhtml
1 1 <% if uploaded_file.image? %>
2   - <%= link_to content_tag(:span, uploaded_file.display_title), uploaded_file.view_url, :class => 'image', :style => 'background-image: url(%s)'% uploaded_file.public_filename(:thumb) %>
3   - <span><%= image_label(uploaded_file) %></span>
  2 + <%= link_to '',
  3 + uploaded_file.view_url,
  4 + :class => 'image',
  5 + :style => 'background-image: url(%s)'% uploaded_file.public_filename(:thumb)
  6 + %>
  7 + <span><%=h uploaded_file.title %></span>
4 8 <% else %>
5 9 <%= render :partial => 'article', :object => uploaded_file %>
6 10 <% end %>
... ...
app/views/content_viewer/image_gallery.rhtml
... ... @@ -10,11 +10,11 @@
10 10 <% end %>
11 11 <ul>
12 12 <% @images.each do |a| %>
13   - <% content_tag('li', :title => a.abstract, :class => 'image-gallery-item' ) do %>
  13 + <% content_tag('li', :title => a.title, :class => 'image-gallery-item' ) do %>
14 14 <%= render :partial => partial_for_class(a.class), :object => a %>
15 15 <% end %>
16 16 <% end %>
17 17 </ul>
18 18 <br style="clear:both" />
19   - <%= will_paginate @images, :param_name => 'npage' %>
  19 + <%= pagination_links @images, :param_name => 'npage' %>
20 20 </div>
... ...
app/views/content_viewer/view_page.rhtml
... ... @@ -6,62 +6,11 @@
6 6  
7 7 <div id="article" class="<%= @page.css_class_name %>">
8 8  
  9 +<div id="article-toolbar"></div>
9 10  
10   -<div<%= " class='logged-in'" if user %>>
11   - <% if @page.allow_post_content?(user) || @page.allow_publish_content?(user) %>
12   - <div id="article-actions">
13   - <% if @page.allow_post_content?(user) %>
14   - <%= link_to content_tag( 'span', label_for_edit_article(@page) ),
15   - profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }),
16   - :class => 'button with-text icon-edit' %>
17   - <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %>
18   - <% if @page != profile.home_page && !@page.has_posts? %>
19   - <%= link_to content_tag( 'span', _('Delete') ),
20   - profile.admin_url.merge({ :controller => 'cms', :action => 'destroy', :id => @page }),
21   - :class => 'button with-text icon-delete' %>
22   - <% end %>
23   - <% if !environment.enabled?('disable_cms') && !@page.folder? %>
24   - <% if profile.kind_of?(Person) %>
25   - <%= link_to content_tag( 'span', _('Spread this') ),
26   - profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page }),
27   - :class => 'button with-text icon-spread' %>
28   - <% elsif profile.kind_of?(Community) && environment.portal_community %>
29   - <%= link_to content_tag( 'span', _('Spread this') ),
30   - profile.admin_url.merge({ :controller => 'cms', :action => 'publish_on_portal_community', :id => @page }),
31   - :class => 'button with-text icon-spread' %>
32   - <% end %>
33   - <% end %>
34   - <% end %>
35   - <% end %>
36   - <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %>
37   - <% if !@page.gallery? %>
38   - <%= link_to _('Add translation'),
39   - profile.admin_url.merge(:controller => 'cms', :action => 'new',
40   - :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)),
41   - :type => @page.type, :article => { :translation_of_id => @page.native_translation.id }),
42   - :class => 'button with-text icon-locale' if @page.translatable? && !@page.native_translation.language.blank? %>
43   - <%= lightbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) %>
44   - <% end %>
45   - <% if (@page.folder? && !@page.has_posts?) || (@page.parent && @page.parent.folder? && !@page.parent.has_posts?) %>
46   - <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) %>
47   - <% end %>
48   - <% end %>
49   - <% if profile.kind_of?(Enterprise) && @page.gallery? %>
50   - <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %>
51   - <% end %>
52   - </div>
53   - <% else %>
54   - <% if profile.community? && (@page.blog? || @page.parent && @page.parent.blog?) %>
55   - <%= link_to content_tag( 'span', _('Suggest an article') ), profile.admin_url.merge({ :controller => 'cms', :action => 'suggest_an_article'}), :id => 'suggest-article-link', :class => 'button with-text icon-new' %>
56   - <% end %>
57   - <% end %>
58   - <div id="article-header">
59   - <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
60   - <%= article_title(@page, :no_link => true) %>
61   - <%= article_translations(@page) %>
62   - </div>
63   -</div>
64   -
  11 +<script type="text/javascript">
  12 + <%= remote_function :update => "article-toolbar", :url => @page.url.merge({ :toolbar => true, :only_path => true }), :complete => "$$('#article-toolbar .remote-lbOn').each(function(link) { new lightbox(link); }); jQuery('#article-toolbar .simplemenu-trigger').click(function(e) { e.stopPropagation(); })" %>
  13 +</script>
65 14  
66 15 <% if !@page.tags.empty? %>
67 16 <div id="article-tags">
... ... @@ -84,6 +33,18 @@
84 33  
85 34 <%= render :partial => 'shared/disabled_enterprise' %>
86 35  
  36 +<% if NOOSFERO_CONF['addthis_enabled'] %>
  37 +<div id="addThis">
  38 +<script type="text/javascript">
  39 + addthis_brand = '<%= escape_javascript( @environment.name ) %>';
  40 + addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';
  41 + addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';
  42 + addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';
  43 +</script>
  44 +<a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><img src="/images/bt-bookmark.gif" width="53" height="16" border="0" alt="" /></a><script type="text/javascript" src="http://s7.addthis.com/js/152/addthis_widget.js"></script>
  45 +</div>
  46 +<% end %>
  47 +
87 48 <% cache(@page.cache_key(params, user)) do %>
88 49 <div class="<%="article-body article-body-" + @page.css_class_name %>">
89 50 <% options = @page.image? ? {:gallery_view => true} : {} %>
... ... @@ -101,18 +62,6 @@
101 62  
102 63 <%= display_source_info(@page) %>
103 64  
104   -<% if NOOSFERO_CONF['addthis_enabled'] %>
105   -<div id="addThis">
106   -<script type="text/javascript">
107   - addthis_brand = '<%= escape_javascript( @environment.name ) %>';
108   - addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';
109   - addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';
110   - addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';
111   -</script>
112   -<a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><img src="/images/bt-bookmark.gif" width="53" height="16" border="0" alt="" /></a><script type="text/javascript" src="http://s7.addthis.com/js/152/addthis_widget.js"></script>
113   -</div>
114   -<% end %>
115   -
116 65 <div class="comments" id="comments_list">
117 66 <% if @page.accept_comments? %>
118 67 <h3 <%= 'class="no-comments-yet"' if @comments.size == 0 %>>
... ...
app/views/layouts/chat.rhtml
... ... @@ -26,7 +26,7 @@
26 26 </head>
27 27 <body id='chat'>
28 28 <div id='title-bar'>
29   - <h1 class='title'><%= _("%s - Friends online (<span id='friends-online'>%d</span>)") % [h(page_title), 0] %></h1>
  29 + <h1 class='title'><%= _("%s - Friends in chat (<span id='friends-online'>%d</span>)") % [h(page_title), 0] %></h1>
30 30 </div>
31 31 <div id='buddy-list'>
32 32 <div id='environment-logo'>
... ...
app/views/manage_products/_edit_description.rhtml
... ... @@ -6,7 +6,7 @@
6 6 :url => {:controller => 'manage_products', :action => 'edit', :id => @product, :field => 'description'},
7 7 :html => {:id => 'product-description-form', :method => 'post'}) do |f| %>
8 8  
9   - <%= labelled_form_field(_('Description:'), f.text_area(:description, :rows => 15, :style => 'width: 90%;')) %>
  9 + <%= labelled_form_field(_('Description:'), f.text_area(:description, :rows => 15, :style => 'width: 90%;', :class => 'mceEditor')) %>
10 10 <% button_bar do %>
11 11 <%= submit_button :save, _('Save') %>
12 12 <%= cancel_edit_product_link(@product, 'description') %>
... ...
app/views/manage_products/_form.rhtml
... ... @@ -5,7 +5,7 @@
5 5  
6 6 <%= display_form_field( _('Name:'), f.text_field(:name) ) %>
7 7 <%= display_form_field( _('Price:'), f.text_field(:price) ) %>
8   - <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %>
  8 + <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10, :class => 'mceEditor') ) %>
9 9 <%= labelled_form_field(f.check_box(:highlighted) + _('Highlight this product'),'') %>
10 10 <% f.fields_for :image_builder, @product.image do |i| %>
11 11 <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %>
... ...
app/views/manage_products/index.rhtml
... ... @@ -22,7 +22,7 @@
22 22 <% end %>
23 23 </table>
24 24  
25   -<%= will_paginate @products %>
  25 +<%= pagination_links @products %>
26 26  
27 27 <% button_bar do %>
28 28 <%= button :add, _('New product or service'), :action => 'new' %>
... ...
app/views/profile/profile_info.rjs 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +if !user.nil? and user.has_permission?('edit_profile', profile)
  2 + page.replace_html "profile-admin-url-#{@block.id}", link_to(_('Control panel'), @block.owner.admin_url)
  3 +else
  4 + page.hide "profile-admin-url-#{@block.id}"
  5 +end
  6 +page.replace_html "profile-info-options-#{@block.id}", :file => 'blocks/profile_info_actions/' + @block.owner.class.name.underscore
... ...
app/views/profile_editor/_person_form.rhtml
... ... @@ -44,7 +44,7 @@
44 44 }
45 45 </script>
46 46  
47   -<%= optional_field(@person, 'formation', select_area(_('Formation'), 'profile_data', 'formation', {:class => 'type-select-full-line'})) %>
  47 +<%= optional_field(@person, 'formation', select_area(_('Education'), 'profile_data', 'formation', {:class => 'type-select-full-line'})) %>
48 48  
49 49 <span id='profile_data_custom_formation_span' <%= "style='display:none'" if ! ['Others', nil].include?(@person.formation) %> >
50 50 <%= optional_field(@person, 'custom_formation', f.text_field(:custom_formation)) %>
... ...
app/views/profile_editor/header_footer.rhtml
... ... @@ -21,9 +21,9 @@
21 21 </div>
22 22 <% end %>
23 23 <h2><%= _('Content for header ') %></h2>
24   - <%= text_area_tag(:custom_header, @header, :style => 'width: 100%; height: 150px;') %>
  24 + <%= text_area_tag(:custom_header, @header, :style => 'width: 100%; height: 150px;', :class => 'mceEditor') %>
25 25 <h2><%= _('Content for footer') %></h2>
26   - <%= text_area_tag(:custom_footer, @footer, :style => 'width: 100%; height: 150px;') %>
  26 + <%= text_area_tag(:custom_footer, @footer, :style => 'width: 100%; height: 150px;', :class => 'mceEditor') %>
27 27 <% button_bar do %>
28 28 <%= submit_button(:save, _('Save')) %>
29 29 <%= button(:cancel, _('Cancel'), :action => 'index') %>
... ...
app/views/profile_members/send_mail.rhtml
... ... @@ -8,7 +8,7 @@
8 8  
9 9 <% form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %>
10 10 <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %>
11   - <%= labelled_form_field(_('Body:'), f.text_area(:body)) %>
  11 + <%= labelled_form_field(_('Body:'), f.text_area(:body, :class => 'mceEditor')) %>
12 12 <%= submit_button(:send, _('Send')) %>
13 13 <%= button :cancel, _('Cancel e-mail'), :action => 'index' %>
14 14 <% end %>
... ...
app/views/search/_event.rhtml
1   -<li>
2   - <strong><%= link_to(event.title, event.url, :class => icon_for_article(event)) %></strong>
  1 +<li class="<%= icon_for_article(event) %>">
  2 + <strong><%= link_to(event.title, event.url) %></strong>
3 3 <div class="item_meta">
4 4 <%= show_period(event.start_date, event.end_date) %>
5 5 </div>
... ...
app/views/search/products.rhtml
... ... @@ -23,6 +23,6 @@
23 23 </div><!-- class="has_cat_list" -->
24 24 <% end %>
25 25  
26   -<%= will_paginate @results[:products] %>
  26 +<%= pagination_links @results[:products] %>
27 27  
28 28 <br style="clear:both" />
... ...
app/views/shared/_lead_and_body.rhtml 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +<% object ||= :article %>
  2 +<% abstract_label ||= 'Lead' %>
  3 +<% abstract_method ||= :abstract %>
  4 +<% body_label ||= 'Text' %>
  5 +<% body_method ||= :body %>
  6 +<% editor_type = defined?(tiny_mce) && tiny_mce ? 'mceEditor' : '' %>
  7 +<% lead_id ||= 0%>
  8 +<% f ||= false%>
  9 +
  10 +<br style="clear: both;"/>
  11 +<%= button :add, _("Lead"), '#', :class => "lead-button", :article_id => "#article-lead-"+lead_id.to_s, :style => "margin-left: 0px;" %>
  12 +<em><%= _('Used when a short version of your text is needed.') %></em>
  13 +
  14 +<div class='article-lead' id="article-lead-<%=lead_id.to_s%>">
  15 + <% if f %>
  16 + <%= labelled_form_field(_(abstract_label), f.text_area(abstract_method, :style => 'width: 98%; height: 200px;', :class => editor_type)) %>
  17 + <% else %>
  18 + <%= labelled_form_field(_(abstract_label), text_area(object, abstract_method, :style => 'width: 98%; height: 200px;', :class => editor_type)) %>
  19 + <% end %>
  20 +</div>
  21 +<div style="margin-top: 10px;">
  22 + <% if f %>
  23 + <%= labelled_form_field(_(body_label), f.text_area(body_method, :style => 'width: 98%; height: 400px;', :class => editor_type)) %>
  24 + <% else %>
  25 + <%= labelled_form_field(_(body_label), text_area(object, body_method, :style => 'width: 98%; height: 400px;', :class => editor_type)) %>
  26 + <% end %>
  27 +</div>
  28 +
  29 +<%= javascript_include_tag 'article'%>
... ...
app/views/shared/_organization_custom_fields.rhtml
1 1 <%= optional_field(profile, 'display_name', f.text_field(:display_name)) %>
  2 +<% if profile.enterprise? %>
  3 + <%= optional_field(profile, 'business_name', f.text_field(:business_name)) %>
  4 +<% end %>
2 5 <%= optional_field(profile, 'description', f.text_area(:description, :rows => 5)) %> <!-- , :maxlength => 10 -->
3 6 <%= optional_field(profile, 'contact_person', f.text_field(:contact_person)) %>
4 7 <%= optional_field(profile, 'contact_email', f.text_field(:contact_email)) %>
... ... @@ -18,7 +21,6 @@
18 21 <% end %>
19 22  
20 23 <% if profile.enterprise? %>
21   - <%= optional_field(profile, 'business_name', f.text_field(:business_name)) %>
22 24 <%= optional_field(profile, 'organization_website', f.text_field(:organization_website)) %>
23 25 <%= optional_field(profile, 'historic_and_current_context', f.text_area(:historic_and_current_context, :rows => 5)) %>
24 26 <%= optional_field(profile, 'activities_short_description', f.text_area(:activities_short_description, :rows => 5)) %>
... ...
app/views/shared/tiny_mce.rhtml
... ... @@ -21,7 +21,6 @@ tinyMCE.init({
21 21 theme : "advanced",
22 22 relative_urls : false,
23 23 remove_script_host : true,
24   - document_base_url : <%= environment.top_url.to_json %>,
25 24 plugins: myplugins,
26 25 theme_advanced_toolbar_location : "top",
27 26 theme_advanced_layout_manager: 'SimpleLayout',
... ...
app/views/tasks/_approve_article_accept_details.rhtml
... ... @@ -4,21 +4,8 @@
4 4 <%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task]", 'article_parent_id', task.target) %>
5 5 <%= labelled_form_field(_('Highlight this article'), f.check_box(:highlighted)) %>
6 6  
7   -<div>
8   - <% if task.article && task.article.tiny_mce? %>
9   - <%= labelled_form_field(_('Lead'), f.text_area(:abstract, :style => 'width: 482px; height: 200px;', :class => 'mceEditor')) %>
10   - <% else %>
11   - <%= labelled_form_field(_('Lead'), f.text_area(:abstract, :style => 'width: 482px; height: 200px;')) %>
12   - <% end %>
13   -</div>
14   -<em><%= _('Used when a short version your text is needed.') %></em>
  7 +<% tiny = task.article && task.article.tiny_mce? ? {:tiny_mce => true} : {} %>
  8 +<%= render :partial => 'shared/lead_and_body', :locals => {:lead_id => task.id, :f => f}.merge(tiny)%>
15 9  
16   -<div style="margin-top: 10px;">
17   - <% if task.article && task.article.tiny_mce? %>
18   - <%= labelled_form_field(_('Text'), f.text_area(:body, :style => 'width:482px; height: 500px;', :class => 'mceEditor')) %>
19   - <% else %>
20   - <%= labelled_form_field(_('Text'), f.text_area(:body, :style => 'width:482px; height: 500px;')) %>
21   - <% end %>
22   -</div>
23 10 <%= labelled_form_field _('Comment for author'), f.text_field(:closing_statment, :style => 'width: 488px;') %>
24 11  
... ...
app/views/tasks/_suggest_article_accept_details.rhtml
... ... @@ -9,11 +9,4 @@
9 9 <%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task]", 'article_parent_id', task.target) %>
10 10 <%= labelled_form_field(_('Highlight this article'), f.check_box(:highlighted)) %>
11 11  
12   -<div>
13   - <%= labelled_form_field(_('Lead'), f.text_area(:article_abstract, :style => 'width: 482px; height: 200px;', :class => 'mceEditor')) %>
14   -</div>
15   -<em><%= _('Used when a short version your text is needed.') %></em>
16   -
17   -<div style="margin-top: 10px;">
18   - <%= labelled_form_field(_('Text'), f.text_area(:article_body, :style => 'width:482px; height: 500px;', :class => 'mceEditor')) %>
19   -</div>
  12 +<%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :f => f, :abstract_method => 'article_abstract', :body_method => 'article_body', :lead_id => task.id} %>
... ...
app/views/users/send_mail.rhtml
... ... @@ -6,7 +6,7 @@
6 6  
7 7 <% form_for :mailing, :url => {:action => 'send_mail'} do |f| %>
8 8 <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %>
9   - <%= labelled_form_field(_('Body:'), f.text_area(:body)) %>
  9 + <%= labelled_form_field(_('Body:'), f.text_area(:body, :class => 'mceEditor')) %>
10 10 <%= submit_button(:send, _('Send')) %>
11 11 <%= button :cancel, _('Cancel e-mail'), :controller => 'users' %>
12 12 <% end %>
... ...
config/initializers/exception_notification.rb
1 1 unless NOOSFERO_CONF['exception_recipients'].blank?
  2 + require 'noosfero.rb'
2 3 require 'exception_notification.rb'
3 4 ExceptionNotifier.sender_address = "noreply@#{Noosfero.default_hostname}"
4 5 ExceptionNotifier.email_prefix = "[Noosfero ERROR] "
... ...
db/migrate/20110221195242_create_units_and_add_reference_to_it_at_products_and_inputs.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +class CreateUnitsAndAddReferenceToItAtProductsAndInputs < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :units do |t|
  4 + t.string :singular, :null => false
  5 + t.string :plural, :null => false
  6 + t.integer :position
  7 + t.references :environment, :null => false
  8 + end
  9 + [:products, :inputs].each do |table_name|
  10 + change_table table_name do |t|
  11 + t.remove :unit
  12 + t.references :unit
  13 + end
  14 + end
  15 + end
  16 +
  17 + def self.down
  18 + drop_table :units
  19 + [:products, :inputs].each do |table_name|
  20 + change_table table_name do |t|
  21 + t.string :unit
  22 + t.remove_references :unit
  23 + end
  24 + end
  25 + end
  26 +end
... ...
db/migrate/20110222211802_remove_action_tracker_records_with_nil_users.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class RemoveActionTrackerRecordsWithNilUsers < ActiveRecord::Migration
  2 + # This migration is a copy of 20110127174236_remove_action_tracker_record_with_nil_users.rb
  3 + def self.up
  4 + ActionTracker::Record.all.map {|record| record.destroy if record.user.nil?}
  5 + end
  6 +
  7 + def self.down
  8 + say "this migration can't be reverted"
  9 + end
  10 +end
... ...
db/migrate/20110228174632_change_certifier_description_to_text.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class ChangeCertifierDescriptionToText < ActiveRecord::Migration
  2 + def self.up
  3 + change_table :certifiers do |t|
  4 + t.change :description, :text, :limit => nil
  5 + end
  6 + end
  7 +
  8 + def self.down
  9 + change_table :certifiers do |t|
  10 + t.change :description, :string
  11 + end
  12 + end
  13 +end
... ...
db/migrate/20110302214607_move_data_serialized_hash_to_setting_field_for_events.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +class MoveDataSerializedHashToSettingFieldForEvents < ActiveRecord::Migration
  2 + def self.up
  3 + select_all("SELECT id FROM articles WHERE type = 'Event' AND body LIKE '%:link:%'").each do |data|
  4 + article = Event.find(data['id'])
  5 + body = ''
  6 + begin
  7 + body = YAML.load(article.body)
  8 + rescue
  9 + # do nothing
  10 + next
  11 + end
  12 + if body.kind_of?(Hash)
  13 + settings = article.setting.merge(body)
  14 + body = ActiveRecord::Base.sanitize_sql_for_assignment(:body => settings[:description])
  15 + update("UPDATE articles set %s WHERE id = %d" % [body, article.id])
  16 + setting = ActiveRecord::Base.sanitize_sql_for_assignment(:setting => settings.to_yaml)
  17 + update("UPDATE articles set %s WHERE id = %d" % [setting, article.id])
  18 + end
  19 + end
  20 + end
  21 +
  22 + def self.down
  23 + say "Nothing to undo"
  24 + end
  25 +end
... ...
db/migrate/20110316171323_change_discount_to_decimal.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class ChangeDiscountToDecimal < ActiveRecord::Migration
  2 + def self.up
  3 + change_table :products do |t|
  4 + t.change :discount, :decimal
  5 + end
  6 + end
  7 +
  8 + def self.down
  9 + change_table :products do |t|
  10 + t.change :discount, :float
  11 + end
  12 + end
  13 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20110215153624) do
  12 +ActiveRecord::Schema.define(:version => 20110316171323) do
13 13  
14 14 create_table "action_tracker", :force => true do |t|
15 15 t.integer "user_id"
... ... @@ -179,7 +179,7 @@ ActiveRecord::Schema.define(:version =&gt; 20110215153624) do
179 179  
180 180 create_table "certifiers", :force => true do |t|
181 181 t.string "name", :null => false
182   - t.string "description"
  182 + t.text "description"
183 183 t.string "link"
184 184 t.integer "environment_id"
185 185 t.datetime "created_at"
... ... @@ -289,11 +289,11 @@ ActiveRecord::Schema.define(:version =&gt; 20110215153624) do
289 289 t.datetime "created_at"
290 290 t.datetime "updated_at"
291 291 t.integer "position"
292   - t.string "unit"
293 292 t.decimal "price_per_unit"
294 293 t.decimal "amount_used"
295 294 t.boolean "relevant_to_price", :default => true
296 295 t.boolean "is_from_solidarity_economy", :default => false
  296 + t.integer "unit_id"
297 297 end
298 298  
299 299 create_table "mailing_sents", :force => true do |t|
... ... @@ -345,10 +345,10 @@ ActiveRecord::Schema.define(:version =&gt; 20110215153624) do
345 345 t.datetime "updated_at"
346 346 t.float "lat"
347 347 t.float "lng"
348   - t.string "unit"
349   - t.float "discount"
  348 + t.decimal "discount"
350 349 t.boolean "available", :default => true
351 350 t.boolean "highlighted"
  351 + t.integer "unit_id"
352 352 end
353 353  
354 354 add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id"
... ... @@ -469,6 +469,13 @@ ActiveRecord::Schema.define(:version =&gt; 20110215153624) do
469 469 t.string "thumbnail"
470 470 end
471 471  
  472 + create_table "units", :force => true do |t|
  473 + t.string "singular", :null => false
  474 + t.string "plural", :null => false
  475 + t.integer "position"
  476 + t.integer "environment_id", :null => false
  477 + end
  478 +
472 479 create_table "users", :force => true do |t|
473 480 t.string "login"
474 481 t.string "email"
... ...
debian/changelog
  1 +noosfero (0.29.5) unstable; urgency=low
  2 +
  3 + * Bugfix Version release. (Closes: AI#1961)
  4 +
  5 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 25 Mar 2011 16:45:27 -0300
  6 +
  7 +noosfero (0.29.4) unstable; urgency=low
  8 +
  9 + * Bugfixes Version release. (Closes: AI#1938 AI#1943 AI#1928 AI#1929 AI#1932 AI#1946 AI#1909 AI#1947 AI#1935 AI#1930 AI#1936 AI#1926 AI#1922)
  10 +
  11 + -- Joenio Costa <joenio@colivre.coop.br> Thu, 24 Mar 2011 10:31:35 -0300
  12 +
  13 +noosfero (0.29.3) unstable; urgency=low
  14 +
  15 + * Bugfixes Version release. (Closes: AI#1760 AI#1907 AI#1899 AI#1891 AI#1904 AI#1888 AI#1869 AI#1900 AI#1914)
  16 +
  17 + -- Joenio Costa <joenio@colivre.coop.br> Fri, 11 Mar 2011 13:12:43 -0300
  18 +
  19 +noosfero (0.29.2) unstable; urgency=low
  20 +
  21 + * Bugfixes Version release. (Closes: AI#1922)
  22 +
  23 + -- Joenio Costa <joenio@perl.org.br> Wed, 02 Mar 2011 21:24:48 -0300
  24 +
  25 +noosfero (0.29.1) unstable; urgency=low
  26 +
  27 + * Bugfixes Version release. (Closes: AI#1908)
  28 +
  29 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Tue, 01 Mar 2011 17:01:37 -0300
  30 +
  31 +noosfero (0.29.0) unstable; urgency=low
  32 +
  33 + * Features Version release.
  34 +
  35 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Mon, 28 Feb 2011 17:58:38 -0300
  36 +
  37 +noosfero (0.28.6) unstable; urgency=low
  38 +
  39 + * Bugfixes Version release. (Closes: AI#1874 AI#1890 AI#1893 AI#1871 AI#1884 AI#1892 AI#1882 AI#1883 AI#1896 AI#1875 AI#1895 AI#1879)
  40 +
  41 + -- Joenio Costa <joenio@perl.org.br> Sun, 27 Feb 2011 23:56:51 -0300
  42 +
1 43 noosfero (0.28.5) unstable; urgency=low
2 44  
3 45 * Bugfixes Version release. (Closes: AI#1867 AI#1866 AI#1870 AI#1854 AI#1851 AI#1810 AI#1889 AI#1868 AI#1855 AI#1887)
... ...
debian/noosfero.templates
1 1 Template: noosfero/initial_domain
2 2 Type: string
3   -Description: Domain name for your noosfero site:
  3 +Description: Domain name for your noosfero site
4 4 Enter the domain name that will be used for your Noosfero site. This domain
5 5 name will be automatically added to Noosfero's database. The Noosfero frontend
6 6 packages (such as noosfero-apache) will also automatically configure proper
... ... @@ -12,9 +12,10 @@ Description: Domain name for your noosfero site:
12 12 Template: noosfero/email_setup_warning
13 13 Type: note
14 14 Description: Noosfero needs a working e-mail setup
15   - To function properly, Noosfero needs a working e-mail setup. This is used to
16   - send friendship request e-mails, recovering passwords, and other things.
  15 + Noosfero needs a working e-mail setup to work properly. This is used for
  16 + example to send friendship request e-mails, password recovering e-mail and
  17 + moderation requests notifications.
17 18 .
18 19 Basically, your local MTA needs to deliver e-mail to the internet. Please
19 20 check /usr/share/doc/noosfero/README.Debian for detailed instructions on
20   - settings this up.
  21 + setting this up.
... ...
etc/init.d/noosfero
... ... @@ -48,7 +48,7 @@ FERRET_PID_FILE=$NOOSFERO_DIR/tmp/pids/ferret.production.pid
48 48 main_script() {
49 49 cd $NOOSFERO_DIR
50 50 if [ "$NOOSFERO_USER" != "$USER" ]; then
51   - su $NOOSFERO_USER -c "./script/production $1"
  51 + su $NOOSFERO_USER -l -c "./script/production $1"
52 52 else
53 53 ./script/production $1
54 54 fi
... ...
features/activate_enterprise.feature
... ... @@ -7,10 +7,10 @@ Feature: activate enterprise
7 7 Given the following users
8 8 | login | name |
9 9 | joaosilva | Joao Silva |
  10 + And I am logged in as "joaosilva"
10 11  
11 12 Scenario: added an unexistent code
12 13 Given feature "enterprise_activation" is enabled on environment
13   - And I am logged in as "joaosilva"
14 14 And I am on Joao Silva's control panel
15 15 And I fill in "Enterprise activation code" with "abcde"
16 16 When I press "Activate"
... ... @@ -21,7 +21,6 @@ Feature: activate enterprise
21 21 And the following enterprises
22 22 | identifier | name | enabled |
23 23 | products-factory | Products Factory | false |
24   - And I am logged in as "joaosilva"
25 24 And I am on Joao Silva's control panel
26 25 And enterprise "Products Factory" is enabled
27 26 And I fill in "Enterprise activation code" with code of "Products Factory"
... ... @@ -33,7 +32,6 @@ Feature: activate enterprise
33 32 And the following enterprises
34 33 | identifier | name | enabled |
35 34 | products-factory | Products Factory | false |
36   - And I am logged in as "joaosilva"
37 35 And I am on Joao Silva's control panel
38 36 And I fill in "Enterprise activation code" with code of "Products Factory"
39 37 When I press "Activate"
... ... @@ -45,7 +43,6 @@ Feature: activate enterprise
45 43 And the following enterprises
46 44 | identifier | name | enabled | foundation_year |
47 45 | services-provider | Services Provider | false | 2000 |
48   - And I am logged in as "joaosilva"
49 46 And I am on Joao Silva's control panel
50 47 And I fill in "Enterprise activation code" with code of "Services Provider"
51 48 And I press "Activate"
... ... @@ -59,7 +56,6 @@ Feature: activate enterprise
59 56 And the following enterprises
60 57 | identifier | name | enabled | cnpj |
61 58 | services-provider | Services Provider | false | 00000000000000 |
62   - And I am logged in as "joaosilva"
63 59 And I am on Joao Silva's control panel
64 60 And I fill in "Enterprise activation code" with code of "Services Provider"
65 61 And I press "Activate"
... ... @@ -74,11 +70,10 @@ Feature: activate enterprise
74 70 And the following enterprises
75 71 | identifier | name | enabled | foundation_year |
76 72 | services-provider | Services Provider | false | 2000 |
77   - And I am logged in as "joaosilva"
78   - And I am on Joao Silva's control panel
  73 + And I visit "Joao Silva's control panel" and wait
79 74 And I fill in "Enterprise activation code" with code of "Services Provider"
80   - And I press "Activate"
81   - And I fill in "enterprise-activation-answer" with "2000"
  75 + And I press "Activate" and wait
  76 + And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
82 77 And I press "Continue"
83 78 And I check "I read the terms of use and accepted them"
84 79 When I press "Continue"
... ... @@ -92,22 +87,21 @@ Feature: activate enterprise
92 87 And feature "enterprise_activation" is enabled on environment
93 88 And the following enterprises
94 89 | identifier | name | enabled | foundation_year |
95   - | services-provider | Services Provider | false | 2000 |
  90 + | services-provider-2 | Services Provider 2 | false | 2000 |
96 91 | active-template | Active Template | false | 2000 |
97 92 And "Active Template" is the active enterprise template
98   - And "Services Provider" doesnt have "Active Template" as template
99   - And I am logged in as "joaosilva"
100   - And I am on Joao Silva's control panel
101   - And I fill in "Enterprise activation code" with code of "Services Provider"
102   - And I press "Activate"
103   - And I fill in "enterprise-activation-answer" with "2000"
  93 + And "Services Provider 2" doesnt have "Active Template" as template
  94 + And I visit "Joao Silva's control panel" and wait
  95 + And I fill in "Enterprise activation code" with code of "Services Provider 2"
  96 + And I press "Activate" and wait
  97 + And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
104 98 And I press "Continue"
105 99 And I check "I read the terms of use and accepted them"
106 100 When I press "Continue"
107   - Then I should see "Services Provider was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise"
108   - And enterprise "Services Provider" should be enabled
109   - And "Joao Silva" is admin of "Services Provider"
110   - And "Services Provider" has "Active Template" as template
  101 + Then I should see "Services Provider 2 was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise"
  102 + And enterprise "Services Provider 2" should be enabled
  103 + And "Joao Silva" is admin of "Services Provider 2"
  104 + And "Services Provider 2" has "Active Template" as template
111 105  
112 106 @selenium
113 107 Scenario: not replace template after enable an enterprise
... ... @@ -115,20 +109,18 @@ Feature: activate enterprise
115 109 And feature "enterprise_activation" is enabled on environment
116 110 And the following enterprises
117 111 | identifier | name | enabled | foundation_year |
118   - | services-provider | Services Provider | false | 2000 |
  112 + | services-provider-3 | Services Provider 3 | false | 2000 |
119 113 | active-template | Active Template | false | 2000 |
120 114 And "Active Template" is the active enterprise template
121   - And "Services Provider" doesnt have "Active Template" as template
122   - And I am logged in as "joaosilva"
123   - And I am on Joao Silva's control panel
124   - And I fill in "Enterprise activation code" with code of "Services Provider"
125   - And I press "Activate"
126   - And I fill in "enterprise-activation-answer" with "2000"
  115 + And "Services Provider 3" doesnt have "Active Template" as template
  116 + When I visit "Joao Silva's control panel" and wait
  117 + And I fill in "Enterprise activation code" with code of "Services Provider 3"
  118 + And I press "Activate" and wait
  119 + And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
127 120 And I press "Continue"
128 121 And I check "I read the terms of use and accepted them"
129 122 When I press "Continue"
130   - Then I should see "Services Provider was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise"
131   - And enterprise "Services Provider" should be enabled
132   - And "Joao Silva" is admin of "Services Provider"
133   - And "Services Provider" doesnt have "Active Template" as template
134   -
  123 + Then I should see "Services Provider 3 was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise"
  124 + And enterprise "Services Provider 3" should be enabled
  125 + And "Joao Silva" is admin of "Services Provider 3"
  126 + And "Services Provider 3" doesnt have "Active Template" as template
... ...
features/admin_categories.feature
... ... @@ -14,10 +14,15 @@ Feature: manage categories
14 14 Given I am logged in as admin
15 15  
16 16 @selenium
17   - Scenario: admin user could create a category
  17 + Scenario: admin user could access new category
18 18 Given I follow "Administration"
19   - And I follow "Manage Categories"
20   - And I follow "New category"
  19 + When I follow "Manage Categories"
  20 + And I follow "New category" and wait
  21 + Then I should be on /admin/categories/new
  22 +
  23 + @selenium
  24 + Scenario: admin user could create a category
  25 + Given I visit "/admin/categories/new" and wait
21 26 When I fill in "Name" with "Category 1"
22 27 And I press "Save"
23 28 Then I should see "Categories"
... ... @@ -47,7 +52,8 @@ Feature: manage categories
47 52 Given the following category
48 53 | parent | name | display_in_menu |
49 54 | Steak | Pig | true |
50   - And I follow "Administration"
  55 + And I am on the homepage
  56 + When I follow "Administration"
51 57 And I follow "Manage Categories"
52 58 Then I should see "Food Show"
53 59 When I follow "Show"
... ...
features/approve_article.feature
... ... @@ -18,18 +18,19 @@ Feature: approve article
18 18 And "Maria Silva" is a member of "Sample Community"
19 19 And "Joao Silva" is admin of "Sample Community"
20 20  
  21 + @selenium
21 22 Scenario: edit an article before approval
22 23 Given I am logged in as "mariasilva"
23 24 And I am on Maria Silva's homepage
24   - And I follow "Spread"
  25 + When I follow "Spread" and wait
25 26 And I check "Sample Community"
26 27 And I press "Spread this"
27   - When I am logged in as "joaosilva"
  28 + And I am logged in as "joaosilva"
28 29 And I go to Sample Community's control panel
29   - And I follow "Process requests"
  30 + And I follow "Process requests" and wait
30 31 And I fill in "Text" with "This is an article edited"
31 32 And I choose "Accept"
32 33 And I press "Apply!"
33 34 And I go to Sample Community's sitemap
34   - When I follow "Sample Article"
  35 + And I follow "Sample Article"
35 36 Then I should see "This is an article edited"
... ...
features/balloon.feature
... ... @@ -2,22 +2,18 @@ Feature: balloon
2 2 I want to view a balloon when mouse clicks on profile trigger
3 3  
4 4 Background:
5   - Given I am on the homepage
6 5 Given the following users
7   - | login | name |
  6 + | login | name |
8 7 | joaosilva | Joao Silva |
9 8 And the following communities
10   - | identifier | name |
11   - | sample | Sample |
  9 + | identifier | name |
  10 + | sample | Sample |
12 11  
13 12 @selenium
14 13 Scenario: I should not see trigger if not enabled
15   - Given the following blocks
16   - | owner | type |
17   - | environment | PeopleBlock |
18   - And feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
19   - And I go to the homepage
20   - Then I should not see "Friends"
  14 + Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
  15 + When I go to /browse/people
  16 + Then I should not see "Profile links"
21 17  
22 18 @selenium
23 19 Scenario: I should not see trigger by default
... ... @@ -25,7 +21,7 @@ Feature: balloon
25 21 | owner | type |
26 22 | environment | PeopleBlock |
27 23 And feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
28   - And I go to the homepage
  24 + When I go to the homepage
29 25 Then I should not see "Friends"
30 26  
31 27 @selenium
... ... @@ -34,39 +30,33 @@ Feature: balloon
34 30 | owner | type |
35 31 | environment | PeopleBlock |
36 32 And feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
37   - And I go to the homepage
38   - When I click ".menu-submenu-trigger"
39   - Then I should see "Profile"
40   - And I should see "Friends"
  33 + When I go to the homepage
  34 + And I follow "Profile links"
  35 + Then I should see "Friends"
41 36  
42 37 @selenium
43 38 Scenario: I should see balloon when clicked on community block trigger
44   - Given the following blocks
45   - | owner | type |
46   - | environment | CommunitiesBlock |
47   - And feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
48   - And I go to the homepage
49   - When I click ".menu-submenu-trigger"
50   - Then I should see "Profile"
51   - And I should see "Members"
52   - And I should see "Agenda"
  39 + Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
  40 + When I go to /browse/communities
  41 + And I follow "Profile links"
  42 + Then I should see "Members"
53 43  
54 44 @selenium
55 45 Scenario: I should not see trigger if not enabled on page
56 46 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
57   - And I go to /assets/communities
58   - Then I should not see "Members"
  47 + When I go to /assets/people
  48 + Then I should not see "Profile links"
59 49  
60 50 @selenium
61 51 Scenario: I should not see trigger by default on page
62 52 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
63   - And I go to /assets/communities
  53 + When I go to /assets/communities
64 54 Then I should not see "Members"
65 55  
66 56 @selenium
67 57 Scenario: I should see balloon when clicked on page trigger
68 58 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
69   - And I go to /assets/communities
70   - When I click ".menu-submenu-trigger"
  59 + When I go to /assets/communities
  60 + And I follow "Profile links"
71 61 Then I should see "Members"
72 62 And I should see "Agenda"
... ...
features/blog.feature
... ... @@ -83,12 +83,13 @@ Feature: blog
83 83 When I follow "Configure blog"
84 84 Then I should be on edit "Blog One" by joaosilva
85 85  
  86 + @selenium
86 87 Scenario: configure blog when viewing it
87 88 Given the following blogs
88 89 | owner | name |
89 90 | joaosilva | Blog One |
90 91 And I go to /joaosilva/blog-one
91   - When I follow "Configure blog"
  92 + When I follow "Configure blog" and wait
92 93 Then I should be on edit "Blog One" by joaosilva
93 94  
94 95 Scenario: change address of blog
... ...
features/browse.feature
... ... @@ -39,10 +39,9 @@ Feature: browse
39 39 And I should see "Invite friends"
40 40 And I should see "My friends"
41 41  
42   - @selenium
43 42 Scenario: Browse people by query
44 43 Given I go to /browse/people
45   - When I fill in "query" with "Silva"
  44 + When I fill in "Silva" for "query"
46 45 And I press "Search"
47 46 Then I should see "Joao Silva"
48 47 And I should see "Pedro Silva"
... ... @@ -53,8 +52,8 @@ Feature: browse
53 52 @selenium
54 53 Scenario: Communities browse menu should add logged information
55 54 Given I am logged in as "joaosilva"
56   - And I am on the homepage
57   - And I should not see "More Recent"
  55 + When I go to /joaosilva
  56 + Then I should not see "More Recent"
58 57 And I should not see "More Active"
59 58 And I should not see "More Popular"
60 59 And I should not see "My communities"
... ... @@ -76,14 +75,12 @@ Feature: browse
76 75 And I should see "More Active"
77 76 And I should see "More Popular"
78 77  
79   - @selenium
80 78 Scenario: Browse communities by query
81   - Given I go to /browse/communities
82   - When I fill in "query" with "Silva"
  79 + When I go to /browse/communities
  80 + And I fill in "Silva" for "query"
83 81 And I press "Search"
84 82 Then I should see "Community Silva"
85 83 And I should not see "Joao Silva"
86 84 And I should not see "Pedro Silva"
87 85 And I should not see "Paulo Neto"
88 86 And I should not see "Community Neto"
89   -
... ...
features/categories_block.feature
... ... @@ -61,12 +61,10 @@ Feature: categories_block
61 61 And I follow "Edit" within ".categories-block"
62 62 And I check "Product"
63 63 And I press "Save"
64   - Then I should see "Food"
65   - And I should not see "Vegetarian"
66   - And I should not see "Steak"
  64 + Then I should see "Book"
  65 + And I should not see "Literature"
67 66 When I click ".category-link-expand category-root"
68   - Then I should see "Vegetarian"
69   - And I should see "Steak"
  67 + Then I should see "Literature"
70 68  
71 69 @selenium
72 70 Scenario: List just general categories
... ...
features/chat.feature
... ... @@ -43,6 +43,7 @@ Feature: chat
43 43 Given I am on Tame's homepage
44 44 Then I should not see "Open chat" link
45 45  
  46 + @selenium
46 47 Scenario: not provide the chat online users list when environment not support that
47 48 Given I am logged in as "tame"
48 49 Then I should not see "Online friends "
... ... @@ -63,7 +64,7 @@ Feature: chat
63 64 And I am logged in as "tame"
64 65 When I follow "Open chat"
65 66 And I select window "noosfero_chat"
66   - Then I should see "Chat - Colivre.net - Friends online (0)"
  67 + Then I should see "Chat - Colivre.net - Friends in chat (0)"
67 68  
68 69 @selenium
69 70 Scenario: open chat with an online user in a new window
... ... @@ -74,7 +75,7 @@ Feature: chat
74 75 When I click "#chat-online-users-title"
75 76 And I follow "Maria Silva"
76 77 And I select window "noosfero_chat"
77   - Then I should see "Chat - Colivre.net - Friends online (0)"
  78 + Then I should see "Chat - Colivre.net - Friends in chat (0)"
78 79  
79 80 @selenium
80 81 Scenario: chat starts disconnected by default
... ... @@ -98,6 +99,7 @@ Feature: chat
98 99 And the "#chat-busy" should be visible
99 100 And the "#chat-disconnect" should be visible
100 101  
  102 + @selenium
101 103 Scenario: link to open chatroom of a community
102 104 Given the following communities
103 105 | identifier | name |
... ... @@ -108,6 +110,7 @@ Feature: chat
108 110 When I go to Autoramas's profile
109 111 Then I should see "Enter chat room" link
110 112  
  113 + @selenium
111 114 Scenario: not see link to open chatroom of a community if not a member
112 115 Given the following communities
113 116 | identifier | name |
... ... @@ -117,6 +120,7 @@ Feature: chat
117 120 When I go to Autoramas's profile
118 121 Then I should not see "Enter chat room" link
119 122  
  123 + @selenium
120 124 Scenario: not see link to open chatroom of a community if xmpp_chat disabled
121 125 Given the following communities
122 126 | identifier | name |
... ... @@ -137,4 +141,4 @@ Feature: chat
137 141 When I go to Autoramas's profile
138 142 And I follow "Enter chat room"
139 143 And I select window "noosfero_chat"
140   - Then I should see "Chat - Colivre.net - Friends online (0)"
  144 + Then I should see "Chat - Colivre.net - Friends in chat (0)"
... ...
features/comment.feature
... ... @@ -18,7 +18,7 @@ Feature: comment
18 18 Scenario: not post a comment without javascript
19 19 Given I am on /booking/article-to-comment
20 20 And I fill in "Name" with "Joey Ramone"
21   - And I fill in "e-Mail" with "joey@ramones.com"
  21 + And I fill in "e-mail" with "joey@ramones.com"
22 22 And I fill in "Title" with "Hey ho, let's go!"
23 23 And I fill in "Enter your comment" with "Hey ho, let's go!"
24 24 When I press "Post comment"
... ... @@ -28,7 +28,7 @@ Feature: comment
28 28 Scenario: post a comment while not authenticated
29 29 Given I am on /booking/article-to-comment
30 30 And I fill in "Name" with "Joey Ramone"
31   - And I fill in "e-Mail" with "joey@ramones.com"
  31 + And I fill in "e-mail" with "joey@ramones.com"
32 32 And I fill in "Title" with "Hey ho, let's go!"
33 33 And I fill in "Enter your comment" with "Hey ho, let's go!"
34 34 When I press "Post comment"
... ... @@ -67,7 +67,7 @@ Feature: comment
67 67 Scenario: disable post comment button
68 68 Given I am on /booking/article-to-comment
69 69 And I fill in "Name" with "Joey Ramone"
70   - And I fill in "e-Mail" with "joey@ramones.com"
  70 + And I fill in "e-mail" with "joey@ramones.com"
71 71 And I fill in "Title" with "Hey ho, let's go!"
72 72 And I fill in "Enter your comment" with "Hey ho, let's go!"
73 73 When I press "Post comment"
... ...
features/contact.feature
... ... @@ -12,16 +12,18 @@ In order to ask questions and solve problems
12 12 | sample-community | Sample Community |
13 13 And I am logged in as "joaosilva"
14 14  
  15 + @selenium
15 16 Scenario: without states
16 17 Given I am on Sample Community's homepage
17   - When I follow "Send an e-mail"
  18 + When I follow "Send an e-mail" and wait
18 19 Then I should not see "City and state"
19 20  
  21 + @selenium
20 22 Scenario: with states
21 23 Given the following states
22 24 | name |
23 25 | Bahia |
24 26 And I am on Sample Community's homepage
25   - When I follow "Send an e-mail"
  27 + When I follow "Send an e-mail" and wait
26 28 Then I should see "City and state"
27 29  
... ...
features/edit_article.feature
... ... @@ -77,52 +77,57 @@ Feature: edit article
77 77 Then I should see "My Article"
78 78 And I should be on /joaosilva/my-article
79 79  
  80 + @selenium
80 81 Scenario: edit an article
81 82 Given I am on Joao Silva's sitemap
82   - And I follow "Save the whales"
83   - And I follow "Edit"
  83 + When I follow "Save the whales" and wait
  84 + And I follow "Edit" and wait
84 85 And I fill in "Title" with "My Article edited"
85   - When I press "Save"
  86 + And I press "Save" and wait
86 87 Then I should be on /joaosilva/my-article-edited
87 88  
  89 + @selenium
88 90 Scenario: cancel button back to article when edit
89 91 Given I am on Joao Silva's sitemap
90   - And I follow "Save the whales"
91   - And I follow "Edit"
92   - When I follow "Cancel" within ".main-block"
  92 + When I follow "Save the whales" and wait
  93 + And I follow "Edit" and wait
  94 + And I follow "Cancel" within ".main-block" and wait
93 95 Then I should be on /joaosilva/save-the-whales
94 96  
  97 + @selenium
95 98 Scenario: create an article inside a folder
96 99 Given I am on Joao Silva's control panel
97   - And I follow "Manage Content"
  100 + When I follow "Manage Content"
98 101 And I follow "New content"
99   - And I follow "Folder"
  102 + And I follow "Folder" and wait
100 103 And I fill in "Title" with "My Folder"
101   - And I press "Save"
  104 + And I press "Save" and wait
102 105 Then I should be on /joaosilva/my-folder
103 106 When I follow "New article"
104   - And I follow "Text article with visual editor"
  107 + And I follow "Text article with visual editor" and wait
105 108 And I fill in "Title" with "My Article"
106   - And I press "Save"
  109 + And I press "Save" and wait
107 110 Then I should see "My Article"
108 111 And I should be on /joaosilva/my-folder/my-article
109 112  
  113 + @selenium
110 114 Scenario: cancel button back to folder after giving up creating
111 115 Given I am on Joao Silva's control panel
112   - And I follow "Manage Content"
  116 + When I follow "Manage Content"
113 117 And I follow "New content"
114   - And I follow "Folder"
  118 + And I follow "Folder" and wait
115 119 And I fill in "Title" with "My Folder"
116   - And I press "Save"
  120 + And I press "Save" and wait
117 121 Then I should be on /joaosilva/my-folder
118 122 When I follow "New article"
119   - And I follow "Text article with visual editor"
120   - When I follow "Cancel" within ".no-boxes"
121   - And I should be on /joaosilva/my-folder
  123 + And I follow "Text article with visual editor" and wait
  124 + And I follow "Cancel" within ".no-boxes" and wait
  125 + Then I should be on /joaosilva/my-folder
122 126  
  127 + @selenium
123 128 Scenario: save and continue
124 129 Given I am on /joaosilva/save-the-whales
125   - And I follow "Edit"
  130 + And I follow "Edit" and wait
126 131 When I fill in "Text" with "new text"
127 132 And I press "Save and continue"
128 133 Then the "Text" field should contain "new text"
... ... @@ -140,31 +145,33 @@ Feature: edit article
140 145 And the "Title" field should contain "My new article"
141 146 And the "Text" field should contain "text for the new article"
142 147  
  148 + @selenium
143 149 Scenario: add a translation to an article
144 150 Given I am on Joao Silva's sitemap
145 151 And I follow "Save the whales"
146 152 Then I should not see "Add translation"
147   - And I follow "Edit"
  153 + And I follow "Edit" and wait
148 154 And I select "English" from "Language"
149   - Then I press "Save"
150   - And I follow "Add translation"
  155 + Then I press "Save" and wait
  156 + And I follow "Add translation" and wait
151 157 And I fill in "Title" with "Mi neuvo artículo"
152 158 And I select "Español" from "Language"
153   - When I press "Save"
  159 + When I press "Save" and wait
154 160 Then I should be on /joaosilva/mi-neuvo-articulo
155 161 And I should see "Translations"
156 162  
  163 + @selenium
157 164 Scenario: not add a translation without a language
158 165 Given the following articles
159 166 | owner | name | language |
160 167 | joaosilva | Article in English | en |
161 168 And I am on Joao Silva's sitemap
162   - And I follow "Article in English"
163   - And I follow "Add translation"
  169 + When I follow "Article in English" and wait
  170 + And I follow "Add translation" and wait
164 171 And I fill in "Title" with "Article in Portuguese"
165   - When I press "Save"
  172 + And I press "Save" and wait
166 173 Then I should see "Language must be choosen"
167   - And I select "Português" from "Language"
168   - When I press "Save"
  174 + When I select "Português" from "Language"
  175 + And I press "Save" and wait
169 176 Then I should not see "Language must be choosen"
170 177 And I should be on /joaosilva/article-in-portuguese
... ...
features/edit_block_of_links.feature
... ... @@ -14,9 +14,9 @@ Feature: edit_block_of_links
14 14  
15 15 @selenium
16 16 Scenario: show the icon selector
17   - And I follow "Edit sideboxes"
18   - Given I follow "Edit" within ".link-list-block"
19   - And I follow "New link"
20   - And the ".icon-selector" should not be visible
  17 + Given I follow "Edit sideboxes"
  18 + And I follow "Edit" within ".link-list-block"
  19 + When I follow "New link"
  20 + Then the "css=div.icon-selector" should not be visible
21 21 When I click ".icon"
22   - Then the ".icon-selector" should be visible
  22 + Then the "css=div.icon-selector" should be visible
... ...
features/events.feature
... ... @@ -175,15 +175,16 @@ Feature: events
175 175 When I am on /assets/events
176 176 Then I should see "Colivre.net's events"
177 177  
  178 + @selenium
178 179 Scenario: published events should be listed in the agenda too
179 180 Given the following community
180 181 | identifier | name |
181 182 | sample-community | Sample Community |
182 183 And I am logged in as "josesilva"
183 184 And "josesilva" is a member of "Sample Community"
184   - And I am on josesilva's control panel
185   - And I follow "Manage content"
186   - And I follow "Another Conference"
  185 + And I go to josesilva's control panel
  186 + And I follow "Manage Content"
  187 + And I follow "Another Conference" and wait
187 188 And I follow "Spread"
188 189 And I check "Sample Community"
189 190 And I press "Spread this"
... ... @@ -206,3 +207,26 @@ Feature: events
206 207 When I am on /profile/josesilva/events/2009/10/25
207 208 Then I should see "Unpublished event"
208 209 And I should see "25" link
  210 +
  211 + Scenario: events have lead field
  212 + Given I am logged in as "josesilva"
  213 + And I am on josesilva's Event creation
  214 + Then I should see "Lead"
  215 +
  216 + @selenium
  217 + Scenario: events lead should be shown on blogs with short format
  218 + Given I am logged in as "josesilva"
  219 + And I am on josesilva's control panel
  220 + And I follow "Configure blog" and wait
  221 + And I select "First paragraph" from "How to display posts:"
  222 + And I press "Save"
  223 + And I follow "New post"
  224 + And I follow "A calendar event" and wait
  225 + And I fill in "Title" with "Leaded event"
  226 + And I type "This is the abstract." in TinyMCE field "article_abstract"
  227 + And I type "This is the real text." in TinyMCE field "article_body"
  228 + And I press "Save"
  229 + When I am on josesilva's blog
  230 + Then I should see "Leaded event"
  231 + And I should see "This is the abstract."
  232 + And I should not see "This is the real text."
... ...
features/forum.feature
... ... @@ -10,13 +10,14 @@ Feature: forum
10 10 And "joaosilva" has no articles
11 11 And I am logged in as "joaosilva"
12 12  
  13 + @selenium
13 14 Scenario: create a forum
14   - Given I go to the Control panel
  15 + Given I am on Joao Silva's control panel
15 16 And I follow "Manage Content"
16 17 And I follow "New content"
17   - When I follow "Forum"
  18 + When I follow "Forum" and wait
18 19 And I fill in "Title" with "My Forum"
19   - And I press "Save"
  20 + And I press "Save" and wait
20 21 Then I should see "Configure forum"
21 22  
22 23 Scenario: redirect to forum after create forum from cms
... ... @@ -60,12 +61,13 @@ Feature: forum
60 61 When I follow "Cancel" within ".main-block"
61 62 Then I should be on /myprofile/joaosilva/cms
62 63  
  64 + @selenium
63 65 Scenario: configure forum when viewing it
64 66 Given the following forums
65   - | owner | name |
  67 + | owner | name |
66 68 | joaosilva | Forum One |
67   - And I go to /joaosilva/forum-one
68   - When I follow "Configure forum"
  69 + And I visit "/joaosilva/forum-one" and wait
  70 + When I follow "Configure forum" and wait
69 71 Then I should be on edit "Forum One" by joaosilva
70 72  
71 73 Scenario: last topic update by unautenticated user should not link
... ...
features/gallery_navigation.feature
... ... @@ -7,20 +7,23 @@ Feature: gallery_navigation
7 7 | login |
8 8 | marciopunk |
9 9 And the following galleries
10   - | owner | name |
11   - | marciopunk | my-gallery |
  10 + | owner | name |
  11 + | marciopunk | my-gallery |
  12 + | marciopunk | other-gallery |
12 13 And the following files
13   - | owner | file | mime | parent |
14   - | marciopunk | rails.png | image/png | my-gallery |
15   - | marciopunk | other-pic.jpg | image/jpeg | my-gallery |
  14 + | owner | file | mime | parent |
  15 + | marciopunk | rails.png | image/png | my-gallery |
  16 + | marciopunk | rails.png | image/png | other-gallery |
  17 + | marciopunk | other-pic.jpg | image/jpeg | my-gallery |
16 18  
17 19 Scenario: provide link to go to next image
18 20 Given I am on /marciopunk/my-gallery/other-pic.jpg?view=true
19 21 Then I should see "Next »"
20 22  
  23 + @selenium
21 24 Scenario: view next image when follow next link
22 25 Given I am on /marciopunk/my-gallery/other-pic.jpg?view=true
23   - When I follow "Next »"
  26 + When I follow "Next »" and wait
24 27 Then I should see "rails.png" within ".title"
25 28  
26 29 Scenario: not link to next when in last image
... ... @@ -32,9 +35,10 @@ Feature: gallery_navigation
32 35 Given I am on /marciopunk/my-gallery/other-pic.jpg?view=true
33 36 Then I should see "« Previous"
34 37  
  38 + @selenium
35 39 Scenario: view previous image when follow previous link
36 40 Given I am on /marciopunk/my-gallery/rails.png?view=true
37   - When I follow "« Previous"
  41 + When I follow "« Previous" and wait
38 42 Then I should see "other-pic.jpg" within ".title"
39 43  
40 44 Scenario: not link to previous when in first image
... ... @@ -64,11 +68,11 @@ Feature: gallery_navigation
64 68 When I follow "Go back to my-gallery"
65 69 Then I should be on /marciopunk/my-gallery
66 70  
  71 + @selenium
67 72 Scenario: image title in window title
68 73 Given I am logged in as "marciopunk"
69   - And I go to /marciopunk/my-gallery/rails.png?view=true
70   - When I follow "Edit"
  74 + When I visit "/marciopunk/other-gallery/rails.png?view=true" and wait
  75 + And I follow "Edit" and wait
71 76 And I fill in "Title" with "Rails is cool"
72   - And I press "Save"
73   - And I go to /marciopunk/my-gallery/rails.png?view=true
74   - And The page title should contain "Rails is cool"
  77 + And I press "Save" and wait
  78 + Then The page title should contain "Rails is cool"
... ...
features/manage_inputs.feature
... ... @@ -20,6 +20,10 @@ Feature: manage inputs
20 20 | owner | category | name |
21 21 | redemoinho | rock | Abbey Road |
22 22 And feature "disable_products_for_enterprises" is disabled on environment
  23 + And the following units
  24 + | singular | plural |
  25 + | Meter | Meters |
  26 + | Litre | Litres |
23 27  
24 28 @selenium
25 29 Scenario: add first input to a product
... ... @@ -53,8 +57,8 @@ Feature: manage inputs
53 57 Given I am logged in as "joaosilva"
54 58 When I go to Rede Moinho's page of product Abbey Road
55 59 And I follow "Inputs"
56   - And I follow "Add the inputs or raw material used by this product"
57   - When I follow "Cancel"
  60 + And I follow "Add the inputs or raw material used by this product" and wait until "#input-category-form" is present
  61 + And I click "css=a.cancel-add-input"
58 62 Then I should see "Abbey Road"
59 63 And I should see "Add the inputs or raw material used by this product"
60 64  
... ... @@ -110,9 +114,9 @@ Feature: manage inputs
110 114 And I am logged in as "joaosilva"
111 115 When I go to Rede Moinho's page of product Abbey Road
112 116 And I follow "Inputs"
113   - And I should see "Music"
  117 + Then I should see "Music"
114 118 When I follow "Click here to add price and the amount used"
115   - And I should see "Price ($)"
  119 + And I should see "Price"
116 120 And I fill in "Price" with "10.50"
117 121 And I press "Save"
118 122 Then I should not see "Save"
... ... @@ -126,11 +130,9 @@ Feature: manage inputs
126 130 When I go to Rede Moinho's page of product Abbey Road
127 131 And I follow "Inputs"
128 132 And I follow "Click here to add price and the amount used"
129   - Then I should see "Price ($)"
130   - And I should not see "Price by meter ($)"
131   - When I select "meter"
132   - Then I should see "Price by meter ($)"
133   - And I should not see "Price ($)"
  133 + And I should not see "Price by Meter ($)"
  134 + When I select "Meter"
  135 + Then I should see "Price by Meter ($)"
134 136  
135 137 @selenium
136 138 Scenario: Save all price details of input
... ... @@ -143,10 +145,10 @@ Feature: manage inputs
143 145 And I follow "Click here to add price and the amount used"
144 146 And I fill in "Amount used" with "2.5"
145 147 And I fill in "Price" with "11.50"
146   - And I select "meter"
  148 + And I select "Meter"
147 149 And I press "Save"
148 150 Then I should see "2.5"
149   - And I should see "meter"
  151 + And I should see "Meter"
150 152 And I should not see "$ 11.50"
151 153  
152 154 @selenium
... ... @@ -160,17 +162,17 @@ Feature: manage inputs
160 162 And I follow "Click here to add price and the amount used"
161 163 And I fill in "Amount used" with "2.5"
162 164 And I fill in "Price" with "11.50"
163   - And I select "meter"
  165 + And I select "Meter"
164 166 And I press "Save"
165 167 Then I should see "2.5"
166   - And I should see "meter"
  168 + And I should see "Meter"
167 169 When I follow "Edit" within ".input-details"
168 170 And I fill in "Amount used" with "3.0"
169 171 And I fill in "Price" with "23.31"
170   - And I select "litre"
  172 + And I select "Litre"
171 173 And I press "Save"
172 174 Then I should see "3"
173   - And I should see "litre"
  175 + And I should see "Litre"
174 176  
175 177 @selenium
176 178 Scenario: Cancel edition of a input
... ... @@ -180,19 +182,19 @@ Feature: manage inputs
180 182 And I am logged in as "joaosilva"
181 183 When I go to Rede Moinho's page of product Abbey Road
182 184 And I follow "Inputs"
183   - And I follow "Click here to add price and the amount used"
  185 + And I follow "Click here to add price and the amount used" and wait until ".input-details-form" is present
184 186 Then I should see "Cancel"
185 187 And I should see "Amount used"
186 188 And I should see "Price"
187 189 And I should see "This input or raw material inpact on the final price of the product?"
188   - When I follow "Cancel"
  190 + When I click "css=a.cancel-edit-input"
189 191 Then I should see "Click here to add price and the amount used"
190 192  
191 193 @selenium
192 194 Scenario: Cancel edition of an input then edit again
193 195 Given the following input
194 196 | product | category | price_per_unit | unit |
195   - | Abbey Road | music | 10.0 | unit |
  197 + | Abbey Road | music | 10.0 | Meter |
196 198 And I am logged in as "joaosilva"
197 199 When I go to Rede Moinho's page of product Abbey Road
198 200 And I follow "Inputs"
... ... @@ -200,7 +202,7 @@ Feature: manage inputs
200 202 And I follow "Cancel"
201 203 And I follow "Edit" within ".input-details"
202 204 Then I should see "Amount used"
203   - And I should see "Price by unit"
  205 + And I should see "Price by Meter"
204 206  
205 207 @selenium
206 208 Scenario: remove input
... ... @@ -213,6 +215,7 @@ Feature: manage inputs
213 215 Then I should see "Rock"
214 216 And I should not see "Add the inputs or raw material used by this product"
215 217 When I follow "Remove"
  218 + And I confirm
216 219 Then I should see "Add the inputs or raw material used by this product"
217 220  
218 221 @selenium
... ...
features/manage_products.feature
... ... @@ -133,7 +133,7 @@ Feature: manage products
133 133 And I am on Rede Moinho's control panel
134 134 And I follow "Manage Products and Services"
135 135 When I follow "New product or service"
136   - And I select "Toplevel Product ... »" and wait for jquery
  136 + And I select "Toplevel Product Categories »" and wait for jquery
137 137 And I select "Category Level 1" and wait for jquery
138 138 Then I should see "Toplevel Product Categories" link
139 139 And I should not see "Category Level 1" link
... ... @@ -149,14 +149,14 @@ Feature: manage products
149 149  
150 150 @selenium
151 151 Scenario: enable save button when select one category
152   - Given the following product_category
  152 + Given I am logged in as "joaosilva"
  153 + And the following product_category
153 154 | name |
154 155 | Browsers (accept categories) |
155   - Given I am logged in as "joaosilva"
156 156 And I am on Rede Moinho's control panel
157 157 And I follow "Manage Products and Services"
158 158 When I follow "New product or service"
159   - And I select "Browsers (accept ..." and wait for jquery
  159 + And I select "Browsers (accept categories)" and wait for jquery
160 160 Then the "Save and continue" button should be enabled
161 161  
162 162 @selenium
... ... @@ -290,7 +290,7 @@ Feature: manage products
290 290 And I am logged in as "joaosilva"
291 291 When I go to Rede Moinho's page of product Bike
292 292 And I follow "Edit name"
293   - And I fill in "product_name" with "Red bicycle"
  293 + And I fill in "Red bicycle" for "product_name"
294 294 And I press "Save"
295 295 Then I should see "Red bicycle"
296 296 And I should be on Rede Moinho's page of product Red bicycle
... ... @@ -453,7 +453,7 @@ Feature: manage products
453 453 | Nanonote nanotech with long long name |
454 454 And the following product_category
455 455 | name | parent |
456   - | Netbook Quantum | Super Quantum Computers |
  456 + | Netbook Quantum | Super Quantum Computers with teraflops |
457 457 And I am logged in as "joaosilva"
458 458 When I go to Rede Moinho's new product page
459 459 Then I should see "Nanonote nanotech with long lo..."
... ... @@ -467,11 +467,14 @@ Feature: manage products
467 467 And the following products
468 468 | owner | category | name |
469 469 | redemoinho | bicycle | Bike |
  470 + And the following units
  471 + | singular | plural |
  472 + | Kilo | Kilos |
470 473 And I am logged in as "joaosilva"
471 474 When I go to Rede Moinho's page of product Bike
472 475 And I follow "Edit name and unit"
473   - And I fill in "product_name" with "Red bicycle"
474   - And I select "kilo"
  476 + And I fill in "Red bicycle" for "product_name"
  477 + And I select "Kilo"
475 478 And I press "Save"
476 479 Then I should see "Red bicycle - kilo"
477 480  
... ... @@ -486,7 +489,7 @@ Feature: manage products
486 489 And I am logged in as "joaosilva"
487 490 When I go to Rede Moinho's page of product Bike
488 491 And I follow "Add price and other basic information"
489   - And I fill in "product_price" with "10"
  492 + And I fill in "10" for "product_price"
490 493 And I choose "No"
491 494 And I press "Save"
492 495 Then I should see "Product not available!"
... ...
features/my_network_block.feature
... ... @@ -13,30 +13,32 @@ Feature: my_network_block
13 13 | identifier | name | public_profile |
14 14 | public-community | Public Community | true |
15 15  
  16 + @selenium
16 17 Scenario: display how many public/private communities I am member
17   - Given the following communities
  18 + Given I am logged in as "joaosilva"
  19 + And the following communities
18 20 | identifier | name | owner | public_profile |
19 21 | other-public-community | Other Public Community | joaosilva | true |
20 22 | private-community | Private Community | joaosilva | false |
21   - And I am logged in as "joaosilva"
22 23 And I am on Joao Silva's homepage
23   - Then I should see "2 communities"
  24 + And I should see "2 communities"
24 25 When I go to Public Community's homepage
25 26 And I follow "Join"
26   - When I go to Joao Silva's homepage
  27 + And I go to Joao Silva's homepage
27 28 Then I should see "3 communities"
28 29  
  30 + @selenium
29 31 Scenario: not display how many invisible communities I am member
30   - Given the following communities
  32 + Given I am logged in as "joaosilva"
  33 + And the following communities
31 34 | identifier | name | owner | visible |
32 35 | visible-community | Visible Community | joaosilva | true |
33 36 | not-visible-community | Not Visible Community | joaosilva | false |
34   - And I am logged in as "joaosilva"
35 37 And I am on Joao Silva's homepage
36   - Then I should see "One community"
  38 + And I should see "One community"
37 39 When I go to Public Community's homepage
38 40 And I follow "Join"
39   - When I go to Joao Silva's homepage
  41 + And I go to Joao Silva's homepage
40 42 Then I should see "2 communities"
41 43  
42 44 Scenario: display how many public/private friends I have
... ...
features/publish_article.feature
... ... @@ -42,11 +42,12 @@ Feature: publish article
42 42 Then I should see "Another name"
43 43 And I should not see "Sample Article"
44 44  
  45 + @selenium
45 46 Scenario: getting an error message when publishing article with same name
46 47 Given I am logged in as "joaosilva"
47 48 And "Joao Silva" is a member of "Sample Community"
48 49 And I am on Joao Silva's control panel
49   - And I follow "Manage Content"
  50 + And I follow "Manage Content" and wait
50 51 And I follow "Spread"
51 52 And I check "Sample Community"
52 53 And I press "Spread this"
... ... @@ -56,11 +57,11 @@ Feature: publish article
56 57 And I am on Maria Silva's control panel
57 58 And I follow "Manage Content"
58 59 And I follow "New content"
59   - And I follow "Text article with Textile markup language"
  60 + And I follow "Text article with Textile markup language" and wait
60 61 And I fill in the following:
61 62 | Title | Sample Article |
62 63 | Text | this is Maria's first published article |
63   - And I press "Save"
  64 + And I press "Save" and wait
64 65 And I follow "Spread"
65 66 And I check "Sample Community"
66 67 When I press "Spread this"
... ...
features/step_definitions/custom_webrat_steps.rb
1 1 When /^I should see "([^\"]+)" link$/ do |text|
2   - response.should have_selector("a:contains('#{text}')")
  2 + if response.class.to_s == 'Webrat::SeleniumResponse'
  3 + response.selenium.is_element_present("css=a:contains('#{text}')")
  4 + else
  5 + response.should have_selector("a:contains('#{text}')")
  6 + end
3 7 end
4 8  
5 9 When /^I should not see "([^\"]+)" link$/ do |text|
... ...
features/step_definitions/noosfero_steps.rb
... ... @@ -121,7 +121,8 @@ Given /^the following inputs?$/ do |table|
121 121 data = item.dup
122 122 product = Product.find_by_name(data.delete("product"))
123 123 category = Category.find_by_slug(data.delete("category").to_slug)
124   - input = Input.create!(data.merge(:product => product, :product_category => category))
  124 + unit = Unit.find_by_singular(data.delete("unit"))
  125 + input = Input.create!(data.merge(:product => product, :product_category => category, :unit => unit))
125 126 input.update_attributes!(:position => data['position'])
126 127 end
127 128 end
... ... @@ -293,7 +294,11 @@ Given /^(.+) is disabled$/ do |enterprise_name|
293 294 end
294 295  
295 296 Then /^The page title should contain "(.*)"$/ do |text|
296   - response.should have_selector("title:contains('#{text}')")
  297 + if response.class.to_s == 'Webrat::SeleniumResponse'
  298 + response.selenium.text('css=title').should include(text)
  299 + else
  300 + response.should have_selector("title:contains('#{text}')")
  301 + end
297 302 end
298 303  
299 304 Given /^the mailbox is empty$/ do
... ... @@ -369,4 +374,8 @@ Given /^someone suggested the following article to be published$/ do |table|
369 374 end
370 375 end
371 376  
372   -
  377 +Given /^the following units?$/ do |table|
  378 + table.hashes.each do |row|
  379 + Unit.create!(row.merge(:environment_id => 1))
  380 + end
  381 +end
... ...
features/step_definitions/selenium_steps.rb
... ... @@ -85,6 +85,24 @@ Then /^&quot;([^\&quot;]*)&quot; should be (left|right) aligned$/ do |element_class, align|
85 85 response.selenium.get_xpath_count("//*[contains(@class,'#{element_class}') and contains(@style,'float: #{align}')]").to_i.should be(1)
86 86 end
87 87  
  88 +When /^I confirm$/ do
  89 + selenium.get_confirmation
  90 +end
  91 +
  92 +When /^I type "([^\"]*)" in TinyMCE field "([^\"]*)"$/ do |value, field_id|
  93 + response.selenium.type("dom=document.getElementById('#{field_id}_ifr').contentDocument.body", value)
  94 +end
  95 +
  96 +When /^I answer the captcha$/ do
  97 + question = response.selenium.get_text("//label[@for='task_captcha_solution']").match(/What is the result of '(.+) = \?'/)[1]
  98 + answer = eval(question)
  99 + response.selenium.type("id=task_captcha_solution", answer)
  100 +end
  101 +
  102 +When /^I refresh the page$/ do
  103 + response.selenium.refresh
  104 +end
  105 +
88 106 #### Noosfero specific steps ####
89 107  
90 108 Then /^the select for category "([^\"]*)" should be visible$/ do |name|
... ...
features/step_definitions/webrat_steps.rb
... ... @@ -16,20 +16,49 @@ When /^I go to (.+)$/ do |page_name|
16 16 visit path_to(page_name)
17 17 end
18 18  
  19 +When /^I visit "([^\"]*)" and wait$/ do |page_name|
  20 + visit path_to(page_name)
  21 + selenium.wait_for_page_to_load(10000)
  22 +end
  23 +
19 24 When /^I press "([^\"]*)"$/ do |button|
20 25 click_button(button)
21 26 end
22 27  
  28 +When /^I press "([^\"]*)" and wait$/ do |button|
  29 + click_button(button)
  30 + selenium.wait_for_page_to_load(10000)
  31 +end
  32 +
23 33 When /^I follow "([^\"]*)"$/ do |link|
24 34 click_link(link)
25 35 end
26 36  
  37 +When /^I follow "([^\"]*)" and wait$/ do |link|
  38 + click_link(link)
  39 + selenium.wait_for_page_to_load(10000)
  40 +end
  41 +
  42 +When /^I follow "([^\"]*)" and wait until "([^\"]*)" is present$/ do |link, element|
  43 + click_link(link)
  44 + selenium.wait_for_element(string_to_element_locator(element))
  45 +end
  46 +
27 47 When /^I follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
28 48 click_link_within(parent, link)
29 49 end
30 50  
  51 +When /^I follow "([^\"]*)" within "([^\"]*)" and wait$/ do |link, parent|
  52 + click_link_within(parent, link)
  53 + selenium.wait_for_page_to_load(10000)
  54 +end
  55 +
31 56 When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
32   - fill_in(field, :with => value)
  57 + if response.class.to_s == 'Webrat::SeleniumResponse'
  58 + response.selenium.type("//*[@id=//label[contains(., '#{field}')]/@for]", value)
  59 + else
  60 + fill_in(field, :with => value)
  61 + end
33 62 end
34 63  
35 64 When /^I fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
... ... @@ -54,7 +83,11 @@ When /^I fill in the following:$/ do |fields|
54 83 end
55 84  
56 85 When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
57   - select(value, :from => field)
  86 + if response.class.to_s == 'Webrat::SeleniumResponse'
  87 + response.selenium.select("//*[@id=//label[contains(., '#{field}')]/@for]", value)
  88 + else
  89 + select(value, :from => field)
  90 + end
58 91 end
59 92  
60 93 # Use this step in conjunction with Rail's datetime_select helper. For example:
... ... @@ -173,7 +206,11 @@ Then /^I should not see \/([^\/]*)\/ within &quot;([^\&quot;]*)&quot;$/ do |regexp, selector|
173 206 end
174 207  
175 208 Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
176   - field_labeled(field).value.should =~ /#{value}/
  209 + if response.class.to_s == 'Webrat::SeleniumResponse'
  210 + response.selenium.get_value("//*[@id=//label[contains(., '#{field}')]/@for]").should match(value)
  211 + else
  212 + field_labeled(field).value.should =~ /#{value}/
  213 + end
177 214 end
178 215  
179 216 Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
... ... @@ -189,7 +226,11 @@ Then /^the &quot;([^\&quot;]*)&quot; checkbox should not be checked$/ do |label|
189 226 end
190 227  
191 228 Then /^I should be on (.+)$/ do |page_name|
192   - URI.parse(current_url).path.should == path_to(page_name)
  229 + if response.class.to_s == 'Webrat::SeleniumResponse'
  230 + URI.parse(response.selenium.get_location).path.should == path_to(page_name)
  231 + else
  232 + URI.parse(current_url).path.should == path_to(page_name)
  233 + end
193 234 end
194 235  
195 236 Then /^show me the page$/ do
... ...
features/suggest_article.feature
... ... @@ -21,3 +21,26 @@ Feature: suggest article
21 21 And I follow "Process requests"
22 22 And I should see "suggested the publication of the article"
23 23 Then I should see "Highlight this article" within ".task_box"
  24 +
  25 + @selenium
  26 + Scenario: an article is suggested and the admin approve it
  27 + Given I am on Sample Community's blog
  28 + And I follow "Suggest an article" and wait
  29 + And I fill in "Title" with "Suggestion"
  30 + And I fill in "Your name" with "Some Guy"
  31 + And I fill in "Email" with "someguy@somewhere.com"
  32 + And I type "This is my suggestion's lead" in TinyMCE field "task_article_abstract"
  33 + And I type "I like free software" in TinyMCE field "task_article_body"
  34 + And I answer the captcha
  35 + And I press "Save"
  36 + And I am logged in as "joaosilva"
  37 + And I go to Sample Community's control panel
  38 + When I follow "Process requests" and wait
  39 + Then I should see "suggested the publication of the article: Suggestion."
  40 + When I choose "Accept"
  41 + And I select "sample-community/Blog" from "Select the folder where the article must be published"
  42 + And I press "Apply!"
  43 + And I go to Sample Community's blog
  44 + And I refresh the page
  45 + Then I should see "Suggestion"
  46 + Then I should see "I like free software"
... ...
features/support/paths.rb
... ... @@ -27,6 +27,12 @@ module NavigationHelpers
27 27 when /^(.*)'s homepage$/
28 28 '/%s' % Profile.find_by_name($1).identifier
29 29  
  30 + when /^(.*)'s blog$/
  31 + '/%s/blog' % Profile.find_by_name($1).identifier
  32 +
  33 + when /^(.*)'s (.+) creation$/
  34 + '/myprofile/%s/cms/new?type=%s' % [Profile.find_by_name($1).identifier,$2]
  35 +
30 36 when /^(.*)'s sitemap/
31 37 '/profile/%s/sitemap' % Profile.find_by_name($1).identifier
32 38  
... ...
features/support/selenium.rb
1 1 Webrat.configure do |config|
2 2 config.mode = :selenium
  3 + config.application_environment = :cucumber
  4 + config.selenium_browser_startup_timeout = 30000
3 5 end
4 6  
5 7 Cucumber::Rails::World.use_transactional_fixtures = false
... ...
features/upload_files.feature 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +Feature: upload files
  2 + As a logged user
  3 + I want to upload files
  4 +
  5 + Background:
  6 + Given the following users
  7 + | login | name |
  8 + | joaosilva | Joao Silva |
  9 + And I am logged in as "joaosilva"
  10 +
  11 + @selenium
  12 + Scenario: provile links to upload files to community's gallery
  13 + Given the following communities
  14 + | identifier | name | owner |
  15 + | sample-community | Sample Community | joaosilva |
  16 + And the following galleries
  17 + | owner | name |
  18 + | sample-community | Gallery test |
  19 + And I go to Sample Community's profile
  20 + And I follow "0 pictures"
  21 + And I should see "Upload files"
  22 +
  23 + @selenium
  24 + Scenario: provile links to upload files to enterprise's gallery
  25 + Given the following enterprises
  26 + | identifier | name | owner |
  27 + | sample-enterprise | Sample Enterprise | joaosilva |
  28 + And the following galleries
  29 + | owner | name |
  30 + | sample-enterprise | Gallery test |
  31 + And I go to Sample Enterprise's profile
  32 + And I follow "0 pictures"
  33 + And I should see "Upload files"
  34 +
  35 + Scenario: not provile links to upload files on blogs
  36 + Given the following communities
  37 + | identifier | name | owner |
  38 + | sample-community | Sample Community | joaosilva |
  39 + And the following blogs
  40 + | owner | name |
  41 + | sample-community | Blog test |
  42 + And I go to Sample Community's blog
  43 + And I should not see "Upload files"
... ...
lib/noosfero.rb
1 1 module Noosfero
2 2 PROJECT = 'noosfero'
3   - VERSION = '0.28.5'
  3 + VERSION = '0.29.5'
4 4  
5 5 def self.pattern_for_controllers_in_directory(dir)
6 6 disjunction = controllers_in_directory(dir).join('|')
... ... @@ -66,7 +66,7 @@ module Noosfero
66 66 if ENV['RAILS_ENV'] == 'development'
67 67 development_url_options
68 68 elsif ENV['RAILS_ENV'] == 'cucumber'
69   - {:host => ''}
  69 + Webrat.configuration.mode == :rails ? { :host => '' } : { :port => Webrat.configuration.application_port }
70 70 else
71 71 {}
72 72 end
... ... @@ -76,7 +76,6 @@ module Noosfero
76 76 @development_url_options || {}
77 77 end
78 78  
79   -
80 79 end
81 80  
82 81 require 'noosfero/constants'
... ...