Commit 96ad392a655a791e6df5359fe0e059aa7b53ba36

Authored by Rodrigo Souto
2 parents c3308c85 5cafd9b6

Merge branch 'stable'

Conflicts:
	app/controllers/public/content_viewer_controller.rb
	features/manage_products.feature
Showing 45 changed files with 339 additions and 71 deletions   Show diff stats
@@ -111,6 +111,7 @@ Diego Martinez <diegoamc90@gmail.com> @@ -111,6 +111,7 @@ Diego Martinez <diegoamc90@gmail.com>
111 Diego Martinez <diego@diego-K55A.(none)> 111 Diego Martinez <diego@diego-K55A.(none)>
112 Diego + Renan <renanteruoc@gmail.com> 112 Diego + Renan <renanteruoc@gmail.com>
113 Fernanda Lopes <nanda.listas+psl@gmail.com> 113 Fernanda Lopes <nanda.listas+psl@gmail.com>
  114 +Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
114 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> 115 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
115 Grazieno Pellegrino <grazieno@gmail.com> 116 Grazieno Pellegrino <grazieno@gmail.com>
116 Isaac Canan <isaac@intelletto.com.br> 117 Isaac Canan <isaac@intelletto.com.br>
@@ -195,6 +196,7 @@ root &lt;root@debian.sdr.serpro&gt; @@ -195,6 +196,7 @@ root &lt;root@debian.sdr.serpro&gt;
195 Samuel R. C. Vale <srcvale@holoscopio.com> 196 Samuel R. C. Vale <srcvale@holoscopio.com>
196 Valessio Brito <valessio@gmail.com> 197 Valessio Brito <valessio@gmail.com>
197 vfcosta <vfcosta@gmail.com> 198 vfcosta <vfcosta@gmail.com>
  199 +Vinicius Cubas Brand <viniciuscb@gmail.com>
198 Visita <visita@debian.(none)> 200 Visita <visita@debian.(none)>
199 Yann Lugrin <yann.lugrin@liquid-concept.ch> 201 Yann Lugrin <yann.lugrin@liquid-concept.ch>
200 202
app/controllers/application_controller.rb
@@ -174,8 +174,6 @@ class ApplicationController &lt; ActionController::Base @@ -174,8 +174,6 @@ class ApplicationController &lt; ActionController::Base
174 end 174 end
175 175
176 def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={}) 176 def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={})
177 - scope = scope.send(options[:filter]) if options[:filter]  
178 -  
179 @plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) || 177 @plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options) ||
180 fallback_find_by_contents(asset, scope, query, paginate_options, options) 178 fallback_find_by_contents(asset, scope, query, paginate_options, options)
181 end 179 end
@@ -183,8 +181,9 @@ class ApplicationController &lt; ActionController::Base @@ -183,8 +181,9 @@ class ApplicationController &lt; ActionController::Base
183 private 181 private
184 182
185 def fallback_find_by_contents(asset, scope, query, paginate_options, options) 183 def fallback_find_by_contents(asset, scope, query, paginate_options, options)
186 - return {:results => scope.paginate(paginate_options)} if query.blank?  
187 - {:results => scope.like_search(query).paginate(paginate_options)} 184 + scope = scope.like_search(query) unless query.blank?
  185 + scope = scope.send(options[:filter]) unless options[:filter].blank?
  186 + {:results => scope.paginate(paginate_options)}
188 end 187 end
189 188
190 end 189 end
app/controllers/public/content_viewer_controller.rb
@@ -55,8 +55,9 @@ class ContentViewerController &lt; ApplicationController @@ -55,8 +55,9 @@ class ContentViewerController &lt; ApplicationController
55 55
56 @page = FilePresenter.for @page 56 @page = FilePresenter.for @page
57 57
58 - unless @page.mime_type == 'text/html' || params[:view] 58 + if @page.download? params[:view]
59 headers['Content-Type'] = @page.mime_type 59 headers['Content-Type'] = @page.mime_type
  60 + headers.merge! @page.download_headers
60 data = @page.data 61 data = @page.data
61 62
62 # TODO test the condition 63 # TODO test the condition
@@ -72,7 +73,7 @@ class ContentViewerController &lt; ApplicationController @@ -72,7 +73,7 @@ class ContentViewerController &lt; ApplicationController
72 73
73 #FIXME see a better way to do this. It's not need to pass this variable anymore 74 #FIXME see a better way to do this. It's not need to pass this variable anymore
74 @comment = Comment.new 75 @comment = Comment.new
75 - 76 +
76 if @page.has_posts? 77 if @page.has_posts?
77 posts = if params[:year] and params[:month] 78 posts = if params[:year] and params[:month]
78 filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01") 79 filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01")
app/helpers/application_helper.rb
@@ -730,8 +730,15 @@ module ApplicationHelper @@ -730,8 +730,15 @@ module ApplicationHelper
730 end 730 end
731 731
732 def rolename_for(profile, resource) 732 def rolename_for(profile, resource)
733 - role = profile.role_assignments.find_by_resource_id(resource.id).role  
734 - content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}") 733 + roles = profile.role_assignments.
  734 + where(:resource_id => resource.id).
  735 + sort_by{ |role_assignment| role_assignment.role_id }.
  736 + map(&:role)
  737 + names = []
  738 + roles.each do |role|
  739 + names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}")
  740 + end
  741 + names.join(', ')
735 end 742 end
736 743
737 def role_color(role, env_id) 744 def role_color(role, env_id)
app/models/article.rb
@@ -192,7 +192,7 @@ class Article &lt; ActiveRecord::Base @@ -192,7 +192,7 @@ class Article &lt; ActiveRecord::Base
192 pending_categorizations.clear 192 pending_categorizations.clear
193 end 193 end
194 194
195 - acts_as_taggable 195 + acts_as_taggable
196 N_('Tag list') 196 N_('Tag list')
197 197
198 acts_as_filesystem 198 acts_as_filesystem
@@ -272,7 +272,7 @@ class Article &lt; ActiveRecord::Base @@ -272,7 +272,7 @@ class Article &lt; ActiveRecord::Base
272 end 272 end
273 273
274 # returns the data of the article. Must be overriden in each subclass to 274 # returns the data of the article. Must be overriden in each subclass to
275 - # provide the correct content for the article. 275 + # provide the correct content for the article.
276 def data 276 def data
277 body 277 body
278 end 278 end
@@ -368,6 +368,16 @@ class Article &lt; ActiveRecord::Base @@ -368,6 +368,16 @@ class Article &lt; ActiveRecord::Base
368 false 368 false
369 end 369 end
370 370
  371 + def download? view = nil
  372 + (self.uploaded_file? and not self.image?) or
  373 + (self.image? and view.blank?) or
  374 + (not self.uploaded_file? and self.mime_type != 'text/html')
  375 + end
  376 +
  377 + def download_headers
  378 + {}
  379 + end
  380 +
371 named_scope :native_translations, :conditions => { :translation_of_id => nil } 381 named_scope :native_translations, :conditions => { :translation_of_id => nil }
372 382
373 def translatable? 383 def translatable?
app/models/category.rb
@@ -7,13 +7,13 @@ class Category &lt; ActiveRecord::Base @@ -7,13 +7,13 @@ class Category &lt; ActiveRecord::Base
7 :slug => 1, 7 :slug => 1,
8 } 8 }
9 9
10 - validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n 10 + validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('{fn} cannot be like that.').fix_i18n
11 validates_presence_of :name, :environment_id 11 validates_presence_of :name, :environment_id
12 - validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n 12 + validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('{fn} is already being used by another category.').fix_i18n
13 belongs_to :environment 13 belongs_to :environment
14 14
15 validates_inclusion_of :display_color, :in => [ 1, 2, 3, 4, nil ] 15 validates_inclusion_of :display_color, :in => [ 1, 2, 3, 4, nil ]
16 - validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('%{fn} was already assigned to another category.').fix_i18n 16 + validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('{fn} was already assigned to another category.').fix_i18n
17 17
18 # Finds all top level categories for a given environment. 18 # Finds all top level categories for a given environment.
19 named_scope :top_level_for, lambda { |environment| 19 named_scope :top_level_for, lambda { |environment|
app/models/comment.rb
@@ -27,7 +27,7 @@ class Comment &lt; ActiveRecord::Base @@ -27,7 +27,7 @@ class Comment &lt; ActiveRecord::Base
27 validates_presence_of :author_id, :if => (lambda { |rec| rec.name.blank? && rec.email.blank? }) 27 validates_presence_of :author_id, :if => (lambda { |rec| rec.name.blank? && rec.email.blank? })
28 validates_each :name do |rec,attribute,value| 28 validates_each :name do |rec,attribute,value|
29 if rec.author_id && (!rec.name.blank? || !rec.email.blank?) 29 if rec.author_id && (!rec.name.blank? || !rec.email.blank?)
30 - rec.errors.add(:name, _('%{fn} can only be informed for unauthenticated authors').fix_i18n) 30 + rec.errors.add(:name, _('{fn} can only be informed for unauthenticated authors').fix_i18n)
31 end 31 end
32 end 32 end
33 33
app/models/create_enterprise.rb
@@ -40,12 +40,12 @@ class CreateEnterprise &lt; Task @@ -40,12 +40,12 @@ class CreateEnterprise &lt; Task
40 40
41 if self.region && self.target 41 if self.region && self.target
42 unless self.region.validators.include?(self.target) || self.target_type == "Environment" 42 unless self.region.validators.include?(self.target) || self.target_type == "Environment"
43 - self.errors.add(:target, _('%{fn} is not a validator for the chosen region').fix_i18n) 43 + self.errors.add(:target, _('{fn} is not a validator for the chosen region').fix_i18n)
44 end 44 end
45 end 45 end
46 46
47 if self.status != Task::Status::CANCELLED && self.identifier && Profile.exists?(:identifier => self.identifier) 47 if self.status != Task::Status::CANCELLED && self.identifier && Profile.exists?(:identifier => self.identifier)
48 - self.errors.add(:identifier, _('%{fn} is already being as identifier by another enterprise, organization or person.').fix_i18n) 48 + self.errors.add(:identifier, _('{fn} is already being as identifier by another enterprise, organization or person.').fix_i18n)
49 end 49 end
50 end 50 end
51 51
app/models/domain.rb
@@ -10,14 +10,14 @@ class Domain &lt; ActiveRecord::Base @@ -10,14 +10,14 @@ class Domain &lt; ActiveRecord::Base
10 10
11 # <tt>name</tt> must be sequences of alphanumeric characters (a to z, 11 # <tt>name</tt> must be sequences of alphanumeric characters (a to z,
12 # 0 to 9), plus '_' or '-', separated by dots. Letters must be lowercase. 12 # 0 to 9), plus '_' or '-', separated by dots. Letters must be lowercase.
13 - validates_format_of :name, :with => /^([a-z0-9_-]+\.)+[a-z0-9_-]+$/, :message => N_('%{fn} must be composed of sequences of lowercase letters (a to z), numbers (0 to 9), "_" and "-", separated by dots.').fix_i18n 13 + validates_format_of :name, :with => /^([a-z0-9_-]+\.)+[a-z0-9_-]+$/, :message => N_('{fn} must be composed of sequences of lowercase letters (a to z), numbers (0 to 9), "_" and "-", separated by dots.').fix_i18n
14 14
15 # checks validations that could not be expressed using Rails' predefined 15 # checks validations that could not be expressed using Rails' predefined
16 # validations. In particular: 16 # validations. In particular:
17 # * <tt>name</tt> must not start with 'www.' 17 # * <tt>name</tt> must not start with 'www.'
18 def validate 18 def validate
19 if self.name =~ /^www\./ 19 if self.name =~ /^www\./
20 - self.errors.add(:name, _('%{fn} must not start with www.').fix_i18n) 20 + self.errors.add(:name, _('{fn} must not start with www.').fix_i18n)
21 end 21 end
22 end 22 end
23 23
app/models/environment.rb
@@ -169,7 +169,7 @@ class Environment &lt; ActiveRecord::Base @@ -169,7 +169,7 @@ class Environment &lt; ActiveRecord::Base
169 169
170 # One Environment can be reached by many domains 170 # One Environment can be reached by many domains
171 has_many :domains, :as => :owner 171 has_many :domains, :as => :owner
172 - has_many :profiles 172 + has_many :profiles, :dependent => :destroy
173 173
174 has_many :organizations 174 has_many :organizations
175 has_many :enterprises 175 has_many :enterprises
@@ -784,13 +784,6 @@ class Environment &lt; ActiveRecord::Base @@ -784,13 +784,6 @@ class Environment &lt; ActiveRecord::Base
784 self.save! 784 self.save!
785 end 785 end
786 786
787 - after_destroy :destroy_templates  
788 - def destroy_templates  
789 - [enterprise_template, inactive_enterprise_template, community_template, person_template].compact.each do |template|  
790 - template.destroy  
791 - end  
792 - end  
793 -  
794 after_create :create_default_licenses 787 after_create :create_default_licenses
795 def create_default_licenses 788 def create_default_licenses
796 License.create!(:name => 'CC (by)', :url => 'http://creativecommons.org/licenses/by/3.0/legalcode', :environment => self) 789 License.create!(:name => 'CC (by)', :url => 'http://creativecommons.org/licenses/by/3.0/legalcode', :environment => self)
app/models/event.rb
@@ -25,7 +25,7 @@ class Event &lt; Article @@ -25,7 +25,7 @@ class Event &lt; Article
25 25
26 validates_each :start_date do |event,field,value| 26 validates_each :start_date do |event,field,value|
27 if event.end_date && event.start_date && event.start_date > event.end_date 27 if event.end_date && event.start_date && event.start_date > event.end_date
28 - event.errors.add(:start_date, _('%{fn} cannot come before end date.').fix_i18n) 28 + event.errors.add(:start_date, _('{fn} cannot come before end date.').fix_i18n)
29 end 29 end
30 end 30 end
31 31
app/models/image.rb
@@ -17,7 +17,7 @@ class Image &lt; ActiveRecord::Base @@ -17,7 +17,7 @@ class Image &lt; ActiveRecord::Base
17 :icon => '20x20!' }, 17 :icon => '20x20!' },
18 :max_size => 5.megabytes # remember to update validate message below 18 :max_size => 5.megabytes # remember to update validate message below
19 19
20 - validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n 20 + validates_attachment :size => N_("{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n
21 21
22 delay_attachment_fu_thumbnails 22 delay_attachment_fu_thumbnails
23 23
app/models/person.rb
@@ -240,7 +240,7 @@ class Person &lt; Profile @@ -240,7 +240,7 @@ class Person &lt; Profile
240 240
241 validates_each :email, :on => :update do |record,attr,value| 241 validates_each :email, :on => :update do |record,attr,value|
242 if User.find(:first, :conditions => ['email = ? and id != ? and environment_id = ?', value, record.user.id, record.environment.id]) 242 if User.find(:first, :conditions => ['email = ? and id != ? and environment_id = ?', value, record.user.id, record.environment.id])
243 - record.errors.add(attr, _('%{fn} is already used by other user').fix_i18n) 243 + record.errors.add(attr, _('{fn} is already used by other user').fix_i18n)
244 end 244 end
245 end 245 end
246 246
app/models/uploaded_file.rb
@@ -54,7 +54,7 @@ class UploadedFile &lt; Article @@ -54,7 +54,7 @@ class UploadedFile &lt; Article
54 :thumbnail_class => Thumbnail, 54 :thumbnail_class => Thumbnail,
55 :max_size => 5.megabytes # remember to update validate message below 55 :max_size => 5.megabytes # remember to update validate message below
56 56
57 - validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n 57 + validates_attachment :size => N_("{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n
58 58
59 delay_attachment_fu_thumbnails 59 delay_attachment_fu_thumbnails
60 60
@@ -94,6 +94,12 @@ class UploadedFile &lt; Article @@ -94,6 +94,12 @@ class UploadedFile &lt; Article
94 self.name = self.filename 94 self.name = self.filename
95 end 95 end
96 96
  97 + def download_headers
  98 + {
  99 + 'Content-Disposition' => "attachment; filename=\"#{self.filename}\"",
  100 + }
  101 + end
  102 +
97 def data 103 def data
98 File.read(self.full_filename) 104 File.read(self.full_filename)
99 end 105 end
app/models/user.rb
@@ -114,7 +114,7 @@ class User &lt; ActiveRecord::Base @@ -114,7 +114,7 @@ class User &lt; ActiveRecord::Base
114 before_save :encrypt_password 114 before_save :encrypt_password
115 validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?}) 115 validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?})
116 116
117 - validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.').fix_i18n 117 + validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('{fn} must be checked in order to signup.').fix_i18n
118 118
119 # Authenticates a user by their login name or email and unencrypted password. Returns the user or nil. 119 # Authenticates a user by their login name or email and unencrypted password. Returns the user or nil.
120 def self.authenticate(login, password, environment = nil) 120 def self.authenticate(login, password, environment = nil)
app/views/profile/_person_profile.rhtml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 </tr> 4 </tr>
5 <%= display_field(_('Sex:'), profile, :sex) { |gender| { 'male' => _('Male'), 'female' => _('Female') }[gender] } %> 5 <%= display_field(_('Sex:'), profile, :sex) { |gender| { 'male' => _('Male'), 'female' => _('Female') }[gender] } %>
6 <%= display_field(_('Date of birth:'), profile, :birth_date) { |date| show_date(date) }%> 6 <%= display_field(_('Date of birth:'), profile, :birth_date) { |date| show_date(date) }%>
7 - <%= display_field(_('Location:'), profile, :location, true) %> 7 + <%= display_field _('Location:'), profile, :location %>
8 8
9 <%= display_field(_('Type:'), profile, :privacy_setting, true) %> 9 <%= display_field(_('Type:'), profile, :privacy_setting, true) %>
10 10
app/views/shared/_list_groups.html.erb
@@ -12,7 +12,9 @@ @@ -12,7 +12,9 @@
12 <%= _('Members: %s') % group.members_count.to_s %> <br/> 12 <%= _('Members: %s') % group.members_count.to_s %> <br/>
13 <%= _('Created at: %s') % show_date(group.created_at) unless group.enterprise? %> <br/> 13 <%= _('Created at: %s') % show_date(group.created_at) unless group.enterprise? %> <br/>
14 <% button_bar do %> 14 <% button_bar do %>
15 - <%= button 'menu-ctrl-panel', _('Control panel of this group'), group.admin_url %> 15 + <% if user.has_permission?(:edit_profile, group) %>
  16 + <%= button 'menu-ctrl-panel', _('Control panel of this group'), group.admin_url %>
  17 + <% end %>
16 <%= button 'menu-logout', _('Leave community'), group.leave_url(true), :class => 'leave-community' %> 18 <%= button 'menu-logout', _('Leave community'), group.leave_url(true), :class => 'leave-community' %>
17 <% if (group.community? && user.has_permission?(:destroy_profile, group)) %> 19 <% if (group.community? && user.has_permission?(:destroy_profile, group)) %>
18 <%= button 'delete', _('Remove'), { :controller => 'profile_editor', :action => 'destroy_profile', :profile => group.identifier } %> 20 <%= button 'delete', _('Remove'), { :controller => 'profile_editor', :action => 'destroy_profile', :profile => group.identifier } %>
db/migrate/20131121162641_remove_orphan_profiles.rb 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +class RemoveOrphanProfiles < ActiveRecord::Migration
  2 + def self.up
  3 + profiles = Profile.joins('LEFT JOIN environments ON profiles.environment_id=environments.id').where('environments.id IS NULL')
  4 + profiles.map(&:destroy)
  5 + end
  6 +
  7 + def self.down
  8 + say 'This migration can not be reverted.'
  9 + end
  10 +end
debian/changelog
  1 +noosfero (0.44.5) unstable; urgency=low
  2 +
  3 + * Bugfix release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Tue, 26 Nov 2013 17:39:39 -0300
  6 +
1 noosfero (0.44.4) unstable; urgency=low 7 noosfero (0.44.4) unstable; urgency=low
2 8
3 * Bugfix release 9 * Bugfix release
features/manage_products.feature
@@ -9,7 +9,7 @@ Feature: manage products @@ -9,7 +9,7 @@ Feature: manage products
9 And the following enterprises 9 And the following enterprises
10 | identifier | owner | name | enabled | 10 | identifier | owner | name | enabled |
11 | redemoinho | joaosilva | Rede Moinho | true | 11 | redemoinho | joaosilva | Rede Moinho | true |
12 - And feature "products_for_enterprises" is enabled on environment 12 + And feature "products_for_enterprises" is enabled on environment
13 13
14 Scenario: display "create new product" button 14 Scenario: display "create new product" button
15 Given I am logged in as "joaosilva" 15 Given I am logged in as "joaosilva"
gitignore.example
@@ -39,3 +39,6 @@ debian/*.debhelper @@ -39,3 +39,6 @@ debian/*.debhelper
39 debian/files 39 debian/files
40 debian/noosfero/ 40 debian/noosfero/
41 debian/noosfero-apache/ 41 debian/noosfero-apache/
  42 +features/plugins/*
  43 +plugins/solr/config/solr.yml
  44 +/solr
lib/needs_profile.rb
@@ -24,7 +24,7 @@ module NeedsProfile @@ -24,7 +24,7 @@ module NeedsProfile
24 @profile ||= environment.profiles.find_by_identifier(params[:profile]) 24 @profile ||= environment.profiles.find_by_identifier(params[:profile])
25 if @profile 25 if @profile
26 profile_hostname = @profile.hostname 26 profile_hostname = @profile.hostname
27 - if profile_hostname && request.host == @environment.default_hostname 27 + if profile_hostname && profile_hostname != request.host
28 params.delete(:profile) 28 params.delete(:profile)
29 redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname)) 29 redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname))
30 end 30 end
lib/noosfero.rb
@@ -3,7 +3,7 @@ require &#39;fast_gettext&#39; @@ -3,7 +3,7 @@ require &#39;fast_gettext&#39;
3 3
4 module Noosfero 4 module Noosfero
5 PROJECT = 'noosfero' 5 PROJECT = 'noosfero'
6 - VERSION = '0.44.4' 6 + VERSION = '0.44.5'
7 7
8 def self.pattern_for_controllers_in_directory(dir) 8 def self.pattern_for_controllers_in_directory(dir)
9 disjunction = controllers_in_directory(dir).join('|') 9 disjunction = controllers_in_directory(dir).join('|')
plugins/pg_search/lib/ext/active_record.rb
@@ -2,8 +2,11 @@ require_dependency &#39;active_record&#39; @@ -2,8 +2,11 @@ require_dependency &#39;active_record&#39;
2 2
3 class ActiveRecord::Base 3 class ActiveRecord::Base
4 def self.pg_search_plugin_search(query) 4 def self.pg_search_plugin_search(query)
  5 + query.gsub!(/\|/,' ')
  6 + formatted_query = query.split.map{|w| w += ":*"}.join('|')
  7 +
5 if defined?(self::SEARCHABLE_FIELDS) 8 if defined?(self::SEARCHABLE_FIELDS)
6 - where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{query}:*')") 9 + where("to_tsvector('simple', #{pg_search_plugin_fields}) @@ to_tsquery('#{formatted_query}')")
7 else 10 else
8 raise "No searchable fields defined for #{self.name}" 11 raise "No searchable fields defined for #{self.name}"
9 end 12 end
plugins/pg_search/lib/pg_search_plugin.rb
@@ -9,8 +9,9 @@ class PgSearchPlugin &lt; Noosfero::Plugin @@ -9,8 +9,9 @@ class PgSearchPlugin &lt; Noosfero::Plugin
9 end 9 end
10 10
11 def find_by_contents(asset, scope, query, paginate_options={}, options={}) 11 def find_by_contents(asset, scope, query, paginate_options={}, options={})
12 - return if query.blank?  
13 - {:results => scope.pg_search_plugin_search(query).paginate(paginate_options)} 12 + scope = scope.pg_search_plugin_search(query) unless query.blank?
  13 + scope = scope.send(options[:filter]) unless options[:filter]
  14 + {:results => scope.paginate(paginate_options)}
14 end 15 end
15 16
16 end 17 end
plugins/pg_search/test/unit/pg_search_plugin_test.rb
@@ -14,6 +14,13 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase @@ -14,6 +14,13 @@ class PgSearchPluginTest &lt; ActiveSupport::TestCase
14 assert_includes search(Profile, 'water'), profile 14 assert_includes search(Profile, 'water'), profile
15 end 15 end
16 16
  17 + should 'locate one or more profiles' do
  18 + profile1 = fast_create(Profile, :identifier => 'administrator')
  19 + profile2 = fast_create(Profile, :identifier => 'debugger')
  20 + assert_includes search(Profile, 'admin deb'), profile1
  21 + assert_includes search(Profile, 'admin deb'), profile2
  22 + end
  23 +
17 # TODO This feature is available only on Postgresql 9.0 24 # TODO This feature is available only on Postgresql 9.0
18 # http://www.postgresql.org/docs/9.0/static/unaccent.html 25 # http://www.postgresql.org/docs/9.0/static/unaccent.html
19 # should 'ignore accents' do 26 # should 'ignore accents' do
plugins/shopping_cart/controllers/shopping_cart_plugin_controller.rb
@@ -94,10 +94,12 @@ class ShoppingCartPluginController &lt; PublicController @@ -94,10 +94,12 @@ class ShoppingCartPluginController &lt; PublicController
94 end 94 end
95 95
96 def buy 96 def buy
97 - @cart = cart  
98 - @enterprise = environment.enterprises.find(cart[:enterprise_id])  
99 - @settings = Noosfero::Plugin::Settings.new(@enterprise, ShoppingCartPlugin)  
100 - render :layout => false 97 + if validate_cart_presence
  98 + @cart = cart
  99 + @enterprise = environment.enterprises.find(cart[:enterprise_id])
  100 + @settings = Noosfero::Plugin::Settings.new(@enterprise, ShoppingCartPlugin)
  101 + render :layout => false
  102 + end
101 end 103 end
102 104
103 def send_request 105 def send_request
plugins/shopping_cart/controllers/shopping_cart_plugin_myprofile_controller.rb
@@ -63,7 +63,7 @@ class ShoppingCartPluginMyprofileController &lt; MyProfileController @@ -63,7 +63,7 @@ class ShoppingCartPluginMyprofileController &lt; MyProfileController
63 63
64 def treat_delivery_options(params) 64 def treat_delivery_options(params)
65 result = {} 65 result = {}
66 - return result if params.nil? || params[:delivery_options].nil? 66 + return result if params.nil? || params[:options].nil?
67 params[:options].size.times do |counter| 67 params[:options].size.times do |counter|
68 if params[:options][counter].present? && params[:prices][counter].present? 68 if params[:options][counter].present? && params[:prices][counter].present?
69 result[params[:options][counter]] = params[:prices][counter] 69 result[params[:options][counter]] = params[:prices][counter]
plugins/shopping_cart/test/functional/shopping_cart_plugin_controller_test.rb
@@ -187,6 +187,12 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase @@ -187,6 +187,12 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
187 assert !cart?, "cart expected to be empty!" 187 assert !cart?, "cart expected to be empty!"
188 end 188 end
189 189
  190 + should 'not allow buy without any cart' do
  191 + get :buy
  192 + assert !json_response[:ok]
  193 + assert_equal 2, json_response['error']['code']
  194 + end
  195 +
190 private 196 private
191 197
192 def json_response 198 def json_response
plugins/shopping_cart/test/functional/shopping_cart_plugin_myprofile_controller_test.rb
@@ -51,6 +51,14 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase @@ -51,6 +51,14 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
51 assert settings.delivery_price == price 51 assert settings.delivery_price == price
52 end 52 end
53 53
  54 + should 'be able to choose delivery_options' do
  55 + delivery_options = {:options => ['car', 'bike'], :prices => ['20', '5']}
  56 + post :edit, :profile => enterprise.identifier, :settings => {:delivery_options => delivery_options}
  57 +
  58 + assert_equal '20', settings.delivery_options['car']
  59 + assert_equal '5', settings.delivery_options['bike']
  60 + end
  61 +
54 should 'filter the reports correctly' do 62 should 'filter the reports correctly' do
55 another_enterprise = fast_create(Enterprise) 63 another_enterprise = fast_create(Enterprise)
56 po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED) 64 po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
plugins/solr/lib/ext/article.rb
@@ -24,7 +24,8 @@ class Article @@ -24,7 +24,8 @@ class Article
24 {:slug => :text}, {:body => :text}, 24 {:slug => :text}, {:body => :text},
25 {:abstract => :text}, {:filename => :text}, 25 {:abstract => :text}, {:filename => :text},
26 # filtered fields 26 # filtered fields
27 - {:solr_plugin_public => :boolean}, {:environment_id => :integer}, 27 + {:solr_plugin_public => :boolean}, {:published => :boolean},
  28 + {:environment_id => :integer},
28 {:profile_id => :integer}, :language, 29 {:profile_id => :integer}, :language,
29 {:solr_plugin_category_filter => :integer}, 30 {:solr_plugin_category_filter => :integer},
30 # ordered/query-boosted fields 31 # ordered/query-boosted fields
plugins/solr/lib/ext/profile.rb
@@ -28,7 +28,7 @@ class Profile @@ -28,7 +28,7 @@ class Profile
28 {:solr_plugin_category_filter => :integer}, 28 {:solr_plugin_category_filter => :integer},
29 # ordered/query-boosted fields 29 # ordered/query-boosted fields
30 {:solr_plugin_name_sortable => :string}, {:user_id => :integer}, 30 {:solr_plugin_name_sortable => :string}, {:user_id => :integer},
31 - :enabled, :active, :validated, :public_profile, 31 + :enabled, :active, :validated, :public_profile, :visible,
32 {:lat => :float}, {:lng => :float}, 32 {:lat => :float}, {:lng => :float},
33 :updated_at, :created_at, 33 :updated_at, :created_at,
34 ], 34 ],
plugins/solr/lib/solr_plugin.rb
@@ -18,16 +18,71 @@ class SolrPlugin &lt; Noosfero::Plugin @@ -18,16 +18,71 @@ class SolrPlugin &lt; Noosfero::Plugin
18 true 18 true
19 end 19 end
20 20
  21 + def solr_search? empty_query, klass
  22 + not empty_query or klass == Product
  23 + end
  24 +
21 def find_by_contents(asset, scope, query, paginate_options={}, options={}) 25 def find_by_contents(asset, scope, query, paginate_options={}, options={})
22 klass = asset_class(asset) 26 klass = asset_class(asset)
23 - category = options.delete(:category)  
24 - filter = options.delete(:filter) 27 + category = options[:category]
  28 + empty_query = empty_query? query, category
25 29
26 - return if empty_query?(query, category) && klass != Product 30 + unless solr_search? empty_query, klass
  31 + return options[:filter] ? {:results => scope.send(options[:filter]).paginate(paginate_options)} : nil
  32 + end
27 33
28 solr_options = solr_options(class_asset(klass), category) 34 solr_options = solr_options(class_asset(klass), category)
29 - solr_options.merge!(products_options(user)) if klass == Product && empty_query?(query, category)  
30 - klass.find_by_contents(query, paginate_options, solr_options.merge(options)) 35 + solr_options[:filter_queries] ||= []
  36 + solr_options[:filter_queries] += scopes_to_solr_filters scope, klass, options
  37 + solr_options.merge! products_options(user) if klass == Product and empty_query
  38 + solr_options.merge! options.except(:category, :filter)
  39 +
  40 + scope.find_by_contents query, paginate_options, solr_options
  41 + end
  42 +
  43 + protected
  44 +
  45 + def scopes_to_solr_filters scope, klass = nil, options = {}
  46 + filter_queries = []
  47 + klass ||= scope.base_class
  48 + solr_fields = klass.configuration[:solr_fields].keys
  49 + scopes_applied = scope.scopes_applied.dup rescue [] #rescue association and class direct filtering
  50 +
  51 + scope.current_scoped_methods[:create].each do |attr, value|
  52 + next unless solr_fields.include? attr.to_sym
  53 +
  54 + # if the filter is present here, then prefer it
  55 + scopes_applied.reject!{ |name| name == attr.to_sym }
  56 +
  57 + filter_queries << "#{attr}:#{value}"
  58 + end
  59 +
  60 + scopes_applied.each do |name|
  61 + next if name.to_s == options[:filter].to_s
  62 +
  63 + has_value = name === Hash
  64 + if has_value
  65 + name, args = name.keys.first, name.values.first
  66 + value = args.first
  67 + end
  68 +
  69 + related_field = nil
  70 + related_field = name if solr_fields.include? name
  71 + related_field = "solr_plugin_#{name}" if solr_fields.include? :"solr_plugin_#{name}"
  72 +
  73 + if has_value
  74 + if related_field
  75 + filter_queries << "#{related_field}:#{value}"
  76 + else
  77 + filter_queries << klass.send("solr_filter_#{name}", *args)
  78 + end
  79 + else
  80 + raise "Undeclared solr field for scope #{name}" if related_field.nil?
  81 + filter_queries << "#{related_field}:true"
  82 + end
  83 + end
  84 +
  85 + filter_queries
31 end 86 end
32 87
33 def method_missing method, *args, &block 88 def method_missing method, *args, &block
plugins/solr/test/unit/solr_plugin/plugin_test.rb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class SolrPlugin::PluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @plugin = SolrPlugin.new
  7 + end
  8 + attr_reader :plugin
  9 +
  10 + should 'convert scopes to solr filters' do
  11 + person = create_user('test').person
  12 + result = plugin.send :scopes_to_solr_filters, person.files.public.published
  13 + assert_equal result, ["profile_id:#{person.id}", "published:'true'", "solr_plugin_public:true"]
  14 + end
  15 +
  16 +end
plugins/solr/vendor/plugins/named_scope_with_applied_names/init.rb 0 → 100644
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
  1 +require_dependency 'active_record/named_scope'
  2 +
  3 +if Rails::VERSION::STRING < "2.3.99"
  4 +
  5 + module ::ActiveRecord
  6 +
  7 + module NamedScope
  8 +
  9 + module ClassMethods
  10 +
  11 + def named_scope_with_applied_names name, options = {}, &block
  12 + named_scope_without_applied_names name, options, &block
  13 +
  14 + name = name.to_sym
  15 + scopes[name] = lambda do |parent_scope, *args|
  16 + scope = Scope.new(parent_scope, case options
  17 + when Hash
  18 + options
  19 + when Proc
  20 + if self.model_name != parent_scope.model_name
  21 + options.bind(parent_scope).call(*args)
  22 + else
  23 + options.call(*args)
  24 + end
  25 + end, &block)
  26 + scope.scope_name = name
  27 + scope
  28 + end
  29 + end
  30 + alias_method_chain :named_scope, :applied_names
  31 + end
  32 +
  33 + class Scope
  34 + attr_accessor :scope_name, :scopes_applied
  35 +
  36 + def initialize_with_applied_names proxy_scope, options, &block
  37 + initialize_without_applied_names proxy_scope, options, &block
  38 + self.scopes_applied ||= []
  39 + self.scopes_applied += proxy_scope.send :scopes_applied if Scope === proxy_scope
  40 +
  41 + # unrelated bugfix: use if instead of unless
  42 + if (Scope === proxy_scope || ActiveRecord::Associations::AssociationCollection === proxy_scope)
  43 + @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
  44 + end
  45 + end
  46 + alias_method_chain :initialize, :applied_names
  47 +
  48 + def scope_name= name
  49 + @scope_name = name
  50 + self.scopes_applied << @scope_name
  51 + end
  52 +
  53 + end
  54 +
  55 + end
  56 + end
  57 +end
test/fixtures/files/500.html 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../../public/500.html
0 \ No newline at end of file 2 \ No newline at end of file
test/functional/catalog_controller_test.rb
@@ -235,4 +235,18 @@ class CatalogControllerTest &lt; ActionController::TestCase @@ -235,4 +235,18 @@ class CatalogControllerTest &lt; ActionController::TestCase
235 assert_equal [pc2, pc1, pc4, pc3], assigns(:categories) 235 assert_equal [pc2, pc1, pc4, pc3], assigns(:categories)
236 end 236 end
237 237
  238 + should 'use price_detail name instead of production_cost name straight' do
  239 + p1 = fast_create(Product, :product_category_id => @product_category.id, :enterprise_id => @enterprise.id)
  240 + p2 = fast_create(Product, :product_category_id => @product_category.id, :enterprise_id => @enterprise.id)
  241 + Product.any_instance.stubs(:price_described?).returns(true)
  242 + production_cost = fast_create(ProductionCost)
  243 + pd1 = PriceDetail.create!(:product => p1, :production_cost => production_cost)
  244 + pd2 = PriceDetail.create!(:product => p2)
  245 +
  246 + get :index, :profile => @enterprise.identifier
  247 +
  248 + assert_tag :tag => 'div', :attributes => {:class => 'search-product-input-name'}, :content => production_cost.name
  249 + assert_tag :tag => 'div', :attributes => {:class => 'search-product-input-name'}, :content => 'Other costs'
  250 + end
  251 +
238 end 252 end
test/functional/content_viewer_controller_test.rb
@@ -64,7 +64,20 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -64,7 +64,20 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
64 assert_response :missing 64 assert_response :missing
65 end 65 end
66 66
67 - should 'produce a download-like when article is not text/html' do 67 + should 'produce a download-link when article is a uploaded file' do
  68 + profile = create_user('someone').person
  69 + html = UploadedFile.create! :uploaded_data => fixture_file_upload('/files/500.html', 'text/html'), :profile => profile
  70 + html.save!
  71 +
  72 + get :view_page, :profile => 'someone', :page => [ '500.html' ]
  73 +
  74 + assert_response :success
  75 + assert_match /^text\/html/, @response.headers['Content-Type']
  76 + assert @response.headers['Content-Disposition'].present?
  77 + assert_match /attachment/, @response.headers['Content-Disposition']
  78 + end
  79 +
  80 + should 'produce a download-link when article is not text/html' do
68 81
69 # for example, RSS feeds 82 # for example, RSS feeds
70 profile = create_user('someone').person 83 profile = create_user('someone').person
@@ -1254,7 +1267,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1254,7 +1267,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1254 1267
1255 get 'view_page', :profile => profile.identifier, :page => article.path.split('/') 1268 get 'view_page', :profile => profile.identifier, :page => article.path.split('/')
1256 assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{article.path}?comment_page=2", :rel => 'next' } 1269 assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{article.path}?comment_page=2", :rel => 'next' }
1257 - end 1270 + end
1258 1271
1259 should 'not escape acceptable HTML in list of blog posts' do 1272 should 'not escape acceptable HTML in list of blog posts' do
1260 login_as('testinguser') 1273 login_as('testinguser')
test/functional/memberships_controller_test.rb
@@ -6,7 +6,7 @@ require &#39;memberships_controller&#39; @@ -6,7 +6,7 @@ require &#39;memberships_controller&#39;
6 class MembershipsController; def rescue_action(e) raise e end; end 6 class MembershipsController; def rescue_action(e) raise e end; end
7 7
8 class MembershipsControllerTest < ActionController::TestCase 8 class MembershipsControllerTest < ActionController::TestCase
9 - 9 +
10 include ApplicationHelper 10 include ApplicationHelper
11 11
12 def setup 12 def setup
@@ -22,7 +22,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase @@ -22,7 +22,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase
22 def test_local_files_reference 22 def test_local_files_reference
23 assert_local_files_reference :get, :index, :profile => profile.identifier 23 assert_local_files_reference :get, :index, :profile => profile.identifier
24 end 24 end
25 - 25 +
26 def test_valid_xhtml 26 def test_valid_xhtml
27 assert_valid_xhtml 27 assert_valid_xhtml
28 end 28 end
@@ -245,4 +245,23 @@ class MembershipsControllerTest &lt; ActionController::TestCase @@ -245,4 +245,23 @@ class MembershipsControllerTest &lt; ActionController::TestCase
245 assert_tag :tag => 'input', :attributes => {:id => 'community_plugin2', :type => 'hidden', :value => 'Plugin 2'} 245 assert_tag :tag => 'input', :attributes => {:id => 'community_plugin2', :type => 'hidden', :value => 'Plugin 2'}
246 end 246 end
247 247
  248 + should 'only display control panel link to members with permission' do
  249 + c1 = fast_create(Community, :name => 'My own community')
  250 + c2 = fast_create(Community, :name => 'Not my community')
  251 +
  252 + owner = fast_create(Person)
  253 + c2.add_admin(owner)
  254 +
  255 + person = Person['testuser']
  256 + c1.add_admin(person)
  257 + c2.add_member(person)
  258 +
  259 + login_as('testuser')
  260 + get :index, :profile => 'testuser'
  261 +
  262 + assert_template 'index'
  263 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{c2.identifier}" }
  264 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{c1.identifier}" }
  265 + end
  266 +
248 end 267 end
test/functional/profile_controller_test.rb
@@ -1344,6 +1344,17 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1344,6 +1344,17 @@ class ProfileControllerTest &lt; ActionController::TestCase
1344 assert_tag :tag => 'span', :content => '(removed user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-removed'} 1344 assert_tag :tag => 'span', :content => '(removed user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-removed'}
1345 end 1345 end
1346 1346
  1347 + should 'not display spam comments in wall' do
  1348 + UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
  1349 + article = TinyMceArticle.create!(:profile => profile, :name => 'An article about spam\'s nutritional attributes')
  1350 + comment = Comment.create!(:author => profile, :title => 'Test Comment', :body => 'This article makes me hungry', :source_id => article.id, :source_type => 'Article')
  1351 + comment.spam!
  1352 + login_as(profile.identifier)
  1353 + get :index, :profile => profile.identifier
  1354 +
  1355 + assert !/This article makes me hungry/.match(@response.body), 'Spam comment was shown!'
  1356 + end
  1357 +
1347 should 'display comment in wall from non logged users' do 1358 should 'display comment in wall from non logged users' do
1348 UserStampSweeper.any_instance.stubs(:current_user).returns(profile) 1359 UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
1349 article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') 1360 article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
test/functional/profile_editor_controller_test.rb
@@ -624,6 +624,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -624,6 +624,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
624 624
625 profile.domains << Domain.new(:name => 'myowndomain.net') 625 profile.domains << Domain.new(:name => 'myowndomain.net')
626 profile.environment.domains << Domain.new(:name => 'myenv.net') 626 profile.environment.domains << Domain.new(:name => 'myenv.net')
  627 + ActionController::TestRequest.any_instance.stubs(:host).returns(profile.hostname)
627 628
628 get :edit, :profile => profile.identifier 629 get :edit, :profile => profile.identifier
629 assert_tag :tag => 'select', :attributes => { :name => 'profile_data[preferred_domain_id]' }, :descendant => { :tag => "option", :content => 'myowndomain.net' } 630 assert_tag :tag => 'select', :attributes => { :name => 'profile_data[preferred_domain_id]' }, :descendant => { :tag => "option", :content => 'myowndomain.net' }
@@ -639,6 +640,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -639,6 +640,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
639 640
640 profile.domains << Domain.new(:name => 'myowndomain.net') 641 profile.domains << Domain.new(:name => 'myowndomain.net')
641 profile.environment.domains << Domain.new(:name => 'myenv.net') 642 profile.environment.domains << Domain.new(:name => 'myenv.net')
  643 + ActionController::TestRequest.any_instance.stubs(:host).returns(profile.hostname)
642 644
643 get :edit, :profile => profile.identifier 645 get :edit, :profile => profile.identifier
644 assert_tag :tag => "select", :attributes => { :name => 'profile_data[preferred_domain_id]'}, :descendant => { :tag => 'option', :content => '&lt;Select domain&gt;', :attributes => { :value => '' } } 646 assert_tag :tag => "select", :attributes => { :name => 'profile_data[preferred_domain_id]'}, :descendant => { :tag => 'option', :content => '&lt;Select domain&gt;', :attributes => { :value => '' } }
@@ -978,4 +980,13 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -978,4 +980,13 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
978 assert_equal({}, person.reload.fields_privacy) 980 assert_equal({}, person.reload.fields_privacy)
979 end 981 end
980 982
  983 + should 'not redirect if the profile_hostname is the same as environment hostname' do
  984 + Person.any_instance.stubs(:hostname).returns('hostname.org')
  985 + Environment.any_instance.stubs(:default_hostname).returns('hostname.org')
  986 + ActionController::TestRequest.any_instance.stubs(:host).returns('hostname.org')
  987 + get :index, :profile => profile.identifier
  988 + assert_response :success
  989 + end
  990 +
  991 +
981 end 992 end
test/unit/application_helper_test.rb
@@ -143,6 +143,18 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -143,6 +143,18 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
143 assert_tag_in_string rolename_for(member2, community), :tag => 'span', :content => 'Profile Member' 143 assert_tag_in_string rolename_for(member2, community), :tag => 'span', :content => 'Profile Member'
144 end 144 end
145 145
  146 + should 'rolenames for a member admin' do
  147 + member1 = create_user('usertest1').person
  148 + member2 = create_user('usertest2').person
  149 + community = fast_create(Community, :name => 'new community', :identifier => 'new-community', :environment_id => Environment.default.id)
  150 + community.add_member(member1)
  151 + # member2 is both a admin and a member
  152 + community.add_member(member2)
  153 + community.add_admin(member2)
  154 + assert_tag_in_string rolename_for(member2, community), :tag => 'span', :content => 'Profile Member'
  155 + assert_tag_in_string rolename_for(member2, community), :tag => 'span', :content => 'Profile Administrator'
  156 + end
  157 +
146 should 'get theme from environment by default' do 158 should 'get theme from environment by default' do
147 @environment = mock 159 @environment = mock
148 @environment.stubs(:theme).returns('my-environment-theme') 160 @environment.stubs(:theme).returns('my-environment-theme')
test/unit/environment_test.rb
@@ -293,21 +293,6 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -293,21 +293,6 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
293 assert_equal blocks - env_blocks, Block.count 293 assert_equal blocks - env_blocks, Block.count
294 end 294 end
295 295
296 - should 'destroy templates' do  
297 - env = fast_create(Environment)  
298 - templates = [mock, mock, mock, mock]  
299 - templates.each do |item|  
300 - item.expects(:destroy)  
301 - end  
302 -  
303 - env.stubs(:person_template).returns(templates[0])  
304 - env.stubs(:community_template).returns(templates[1])  
305 - env.stubs(:enterprise_template).returns(templates[2])  
306 - env.stubs(:inactive_enterprise_template).returns(templates[3])  
307 -  
308 - env.destroy  
309 - end  
310 -  
311 should 'have boxes and blocks upon creation' do 296 should 'have boxes and blocks upon creation' do
312 Environment.any_instance.stubs(:create_templates) # avoid creating templates, it's expensive 297 Environment.any_instance.stubs(:create_templates) # avoid creating templates, it's expensive
313 environment = Environment.create!(:name => 'a test environment') 298 environment = Environment.create!(:name => 'a test environment')
test/unit/profile_test.rb
@@ -1888,4 +1888,11 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1888,4 +1888,11 @@ class ProfileTest &lt; ActiveSupport::TestCase
1888 assert !profile.may_display_location_to?(user) 1888 assert !profile.may_display_location_to?(user)
1889 end 1889 end
1890 1890
  1891 + should 'destroy profile if its environment is destroyed' do
  1892 + environment = fast_create(Environment)
  1893 + profile = fast_create(Profile, :environment_id => environment.id)
  1894 +
  1895 + environment.destroy
  1896 + assert_raise(ActiveRecord::RecordNotFound) {profile.reload}
  1897 + end
1891 end 1898 end
vendor/plugins/action_tracker_has_comments/init.rb
@@ -7,7 +7,7 @@ Rails.configuration.to_prepare do @@ -7,7 +7,7 @@ Rails.configuration.to_prepare do
7 7
8 def conditions_for_comments 8 def conditions_for_comments
9 type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) 9 type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])
10 - "source_type = '#{type}' AND source_id = '#{id}'" 10 + "source_type = '#{type}' AND source_id = '#{id}' AND spam IS NOT TRUE"
11 end 11 end
12 12
13 def comments_as_thread 13 def comments_as_thread