Commit 96ad392a655a791e6df5359fe0e059aa7b53ba36
Exists in
master
and in
29 other branches
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
AUTHORS
@@ -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 <root@debian.sdr.serpro> | @@ -195,6 +196,7 @@ root <root@debian.sdr.serpro> | ||
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 < ActionController::Base | @@ -174,8 +174,6 @@ class ApplicationController < 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 < ActionController::Base | @@ -183,8 +181,9 @@ class ApplicationController < 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 < ApplicationController | @@ -55,8 +55,9 @@ class ContentViewerController < 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 < ApplicationController | @@ -72,7 +73,7 @@ class ContentViewerController < 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 < ActiveRecord::Base | @@ -192,7 +192,7 @@ class Article < 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 < ActiveRecord::Base | @@ -272,7 +272,7 @@ class Article < 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 < ActiveRecord::Base | @@ -368,6 +368,16 @@ class Article < 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 < ActiveRecord::Base | @@ -7,13 +7,13 @@ class Category < 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 < ActiveRecord::Base | @@ -27,7 +27,7 @@ class Comment < 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 < Task | @@ -40,12 +40,12 @@ class CreateEnterprise < 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 < ActiveRecord::Base | @@ -10,14 +10,14 @@ class Domain < 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 < ActiveRecord::Base | @@ -169,7 +169,7 @@ class Environment < 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 < ActiveRecord::Base | @@ -784,13 +784,6 @@ class Environment < 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 < Article | @@ -25,7 +25,7 @@ class Event < 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 < ActiveRecord::Base | @@ -17,7 +17,7 @@ class Image < 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 < Profile | @@ -240,7 +240,7 @@ class Person < 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 < Article | @@ -54,7 +54,7 @@ class UploadedFile < 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 < Article | @@ -94,6 +94,12 @@ class UploadedFile < 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 < ActiveRecord::Base | @@ -114,7 +114,7 @@ class User < 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 } %> |
@@ -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
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
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 'fast_gettext' | @@ -3,7 +3,7 @@ require 'fast_gettext' | ||
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 'active_record' | @@ -2,8 +2,11 @@ require_dependency 'active_record' | ||
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 < Noosfero::Plugin | @@ -9,8 +9,9 @@ class PgSearchPlugin < 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 < ActiveSupport::TestCase | @@ -14,6 +14,13 @@ class PgSearchPluginTest < 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 < PublicController | @@ -94,10 +94,12 @@ class ShoppingCartPluginController < 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 < MyProfileController | @@ -63,7 +63,7 @@ class ShoppingCartPluginMyprofileController < 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 < ActionController::TestCase | @@ -187,6 +187,12 @@ class ShoppingCartPluginControllerTest < 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 < ActionController::TestCase | @@ -51,6 +51,14 @@ class ShoppingCartPluginMyprofileControllerTest < 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 < Noosfero::Plugin | @@ -18,16 +18,71 @@ class SolrPlugin < 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 |
@@ -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/functional/catalog_controller_test.rb
@@ -235,4 +235,18 @@ class CatalogControllerTest < ActionController::TestCase | @@ -235,4 +235,18 @@ class CatalogControllerTest < 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 < ActionController::TestCase | @@ -64,7 +64,20 @@ class ContentViewerControllerTest < 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 < ActionController::TestCase | @@ -1254,7 +1267,7 @@ class ContentViewerControllerTest < 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 'memberships_controller' | @@ -6,7 +6,7 @@ require 'memberships_controller' | ||
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 < ActionController::TestCase | @@ -22,7 +22,7 @@ class MembershipsControllerTest < 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 < ActionController::TestCase | @@ -245,4 +245,23 @@ class MembershipsControllerTest < 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 < ActionController::TestCase | @@ -1344,6 +1344,17 @@ class ProfileControllerTest < 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 < ActionController::TestCase | @@ -624,6 +624,7 @@ class ProfileEditorControllerTest < 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 < ActionController::TestCase | @@ -639,6 +640,7 @@ class ProfileEditorControllerTest < 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 => '<Select domain>', :attributes => { :value => '' } } | 646 | assert_tag :tag => "select", :attributes => { :name => 'profile_data[preferred_domain_id]'}, :descendant => { :tag => 'option', :content => '<Select domain>', :attributes => { :value => '' } } |
@@ -978,4 +980,13 @@ class ProfileEditorControllerTest < ActionController::TestCase | @@ -978,4 +980,13 @@ class ProfileEditorControllerTest < 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 < ActiveSupport::TestCase | @@ -143,6 +143,18 @@ class ApplicationHelperTest < 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 < ActiveSupport::TestCase | @@ -293,21 +293,6 @@ class EnvironmentTest < 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 < ActiveSupport::TestCase | @@ -1888,4 +1888,11 @@ class ProfileTest < 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 |