Commit 3133eb48de1d1f587b01c80b8f47881f0a9eadfd
Exists in
master
and in
29 other branches
Merge branch 'stable'
Conflicts: script/quick-start test/unit/application_helper_test.rb test/unit/environment_statistics_block_test.rb test/unit/environment_test.rb
Showing
17 changed files
with
188 additions
and
101 deletions
Show diff stats
app/helpers/application_helper.rb
... | ... | @@ -1424,7 +1424,7 @@ module ApplicationHelper |
1424 | 1424 | end |
1425 | 1425 | |
1426 | 1426 | def filter_html(html, source) |
1427 | - if @plugins | |
1427 | + if @plugins && source.has_macro? | |
1428 | 1428 | html = convert_macro(html, source) |
1429 | 1429 | #TODO This parse should be done through the macro infra, but since there |
1430 | 1430 | # are old things that do not support it we are keeping this hot spot. | ... | ... |
app/helpers/boxes_helper.rb
... | ... | @@ -100,9 +100,7 @@ module BoxesHelper |
100 | 100 | options[:title] = _("This block is invisible. Your visitors will not see it.") |
101 | 101 | end |
102 | 102 | |
103 | - if @controller.send(:content_editor?) | |
104 | - result = filter_html(result, block) | |
105 | - end | |
103 | + result = filter_html(result, block) | |
106 | 104 | |
107 | 105 | box_decorator.block_target(block.box, block) + |
108 | 106 | content_tag('div', | ... | ... |
app/helpers/profile_helper.rb
1 | 1 | module ProfileHelper |
2 | 2 | |
3 | 3 | def display_field(title, profile, field, force = false) |
4 | - if (!force && !profile.active_fields.include?(field.to_s)) || | |
5 | - (profile.active_fields.include?(field.to_s) && !profile.public_fields.include?(field.to_s) && (!user || (user != profile && !user.is_a_friend?(profile)))) | |
4 | + unless force || profile.may_display_field_to?(field, user) | |
6 | 5 | return '' |
7 | 6 | end |
8 | 7 | value = profile.send(field) | ... | ... |
app/models/article.rb
app/models/block.rb
app/models/profile.rb
... | ... | @@ -226,12 +226,14 @@ class Profile < ActiveRecord::Base |
226 | 226 | |
227 | 227 | belongs_to :region |
228 | 228 | |
229 | + LOCATION_FIELDS = %w[address district city state country_name zip_code] | |
230 | + | |
229 | 231 | def location(separator = ' - ') |
230 | 232 | myregion = self.region |
231 | 233 | if myregion |
232 | 234 | myregion.hierarchy.reverse.first(2).map(&:name).join(separator) |
233 | 235 | else |
234 | - %w[address district city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
236 | + LOCATION_FIELDS.map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
235 | 237 | end |
236 | 238 | end |
237 | 239 | |
... | ... | @@ -882,6 +884,21 @@ private :generate_url, :url_options |
882 | 884 | [] |
883 | 885 | end |
884 | 886 | |
887 | + def may_display_field_to? field, user = nil | |
888 | + if not self.active_fields.include? field.to_s | |
889 | + self.send "may_display_#{field}_to?", user rescue true | |
890 | + else | |
891 | + not (!self.public_fields.include? field.to_s and (!user or (user != self and !user.is_a_friend?(self)))) | |
892 | + end | |
893 | + end | |
894 | + | |
895 | + def may_display_location_to? user = nil | |
896 | + LOCATION_FIELDS.each do |field| | |
897 | + return false if !self.may_display_field_to? field, user | |
898 | + end | |
899 | + return true | |
900 | + end | |
901 | + | |
885 | 902 | # field => privacy (e.g.: "address" => "public") |
886 | 903 | def fields_privacy |
887 | 904 | self.data[:fields_privacy] | ... | ... |
app/models/raw_html_block.rb
lib/feed_updater.rb
... | ... | @@ -20,14 +20,20 @@ end |
20 | 20 | class FeedUpdater |
21 | 21 | |
22 | 22 | class ExceptionNotification < ActionMailer::Base |
23 | - def mail error | |
23 | + def mail container, error | |
24 | 24 | environment = Environment.default |
25 | 25 | |
26 | 26 | recipients NOOSFERO_CONF['exception_recipients'] |
27 | 27 | from environment.contact_email |
28 | 28 | reply_to environment.contact_email |
29 | 29 | subject "[#{environment.name}] Feed-updater: #{error.message}" |
30 | - body render(:text => error.backtrace.join("\n")) | |
30 | + body render(:text => " | |
31 | +Container: | |
32 | +#{container.inspect} | |
33 | + | |
34 | +Backtrace: | |
35 | +#{error.backtrace.join("\n")} | |
36 | + ") | |
31 | 37 | end |
32 | 38 | end |
33 | 39 | |
... | ... | @@ -88,11 +94,13 @@ class FeedUpdater |
88 | 94 | if !running |
89 | 95 | break |
90 | 96 | end |
91 | - feed_handler.process(container) | |
97 | + begin | |
98 | + feed_handler.process(container) | |
99 | + rescue Exception => e | |
100 | + FeedUpdater::ExceptionNotification.deliver_mail container, e if NOOSFERO_CONF['exception_recipients'].present? | |
101 | + end | |
92 | 102 | end |
93 | 103 | end |
94 | - rescue Exception => e | |
95 | - FeedUpdater::ExceptionNotification.deliver_mail e if NOOSFERO_CONF['exception_recipients'].present? | |
96 | 104 | end |
97 | 105 | end |
98 | 106 | ... | ... |
test/unit/application_helper_test.rb
... | ... | @@ -591,7 +591,7 @@ class ApplicationHelperTest < ActiveSupport::TestCase |
591 | 591 | end |
592 | 592 | |
593 | 593 | should 'include item in usermenu for environment enabled features' do |
594 | - env = Environment.new | |
594 | + env = fast_create(Environment) | |
595 | 595 | env.enable('xmpp_chat', false) |
596 | 596 | stubs(:environment).returns(env) |
597 | 597 | |
... | ... | @@ -791,6 +791,29 @@ class ApplicationHelperTest < ActiveSupport::TestCase |
791 | 791 | '<br style=\'clear: left;\' /></div>', result |
792 | 792 | end |
793 | 793 | |
794 | + should 'not filter html if source does not have macros' do | |
795 | + class Plugin1 < Noosfero::Plugin | |
796 | + end | |
797 | + | |
798 | + class Plugin1::Macro1 < Noosfero::Plugin::Macro | |
799 | + def parse(params, inner_html, source) | |
800 | + 'Test1' | |
801 | + end | |
802 | + end | |
803 | + | |
804 | + environment = Environment.default | |
805 | + environment.enable_plugin(Plugin1) | |
806 | + @plugins = Noosfero::Plugin::Manager.new(environment, self) | |
807 | + macro1_name = Plugin1::Macro1.identifier | |
808 | + source = mock | |
809 | + source.stubs(:has_macro?).returns(false) | |
810 | + | |
811 | + html = "<div class='macro nonEdit' data-macro='#{macro1_name}' data-macro-param='123'></div>" | |
812 | + parsed_html = filter_html(html, source) | |
813 | + | |
814 | + assert_no_match /Test1/, parsed_html | |
815 | + end | |
816 | + | |
794 | 817 | protected |
795 | 818 | include NoosferoTestHelper |
796 | 819 | ... | ... |
test/unit/environment_statistics_block_test.rb
... | ... | @@ -84,7 +84,7 @@ class EnvironmentStatisticsBlockTest < ActiveSupport::TestCase |
84 | 84 | end |
85 | 85 | |
86 | 86 | should 'not display enterprises if disabled' do |
87 | - env = Environment.new | |
87 | + env = fast_create(Environment) | |
88 | 88 | env.enable('disable_asset_enterprises', false) |
89 | 89 | |
90 | 90 | block = EnvironmentStatisticsBlock.new | ... | ... |
test/unit/environment_test.rb
... | ... | @@ -34,7 +34,7 @@ class EnvironmentTest < ActiveSupport::TestCase |
34 | 34 | end |
35 | 35 | |
36 | 36 | def test_features |
37 | - v = Environment.new | |
37 | + v = fast_create(Environment) | |
38 | 38 | v.enable('feature1', false) |
39 | 39 | assert v.enabled?('feature1') |
40 | 40 | v.disable('feature1', false) |
... | ... | @@ -42,14 +42,14 @@ class EnvironmentTest < ActiveSupport::TestCase |
42 | 42 | end |
43 | 43 | |
44 | 44 | def test_enabled_features |
45 | - v = Environment.new | |
45 | + v = fast_create(Environment) | |
46 | 46 | v.enable('feature1', false) |
47 | 47 | v.enable('feature2', false) |
48 | 48 | assert v.enabled?('feature1') && v.enabled?('feature2') && !v.enabled?('feature3') |
49 | 49 | end |
50 | 50 | |
51 | 51 | def test_enabled_features_no_features_enabled |
52 | - v = Environment.new | |
52 | + v = fast_create(Environment) | |
53 | 53 | assert !v.enabled?('feature1') && !v.enabled?('feature2') && !v.enabled?('feature3') |
54 | 54 | end |
55 | 55 | |
... | ... | @@ -1074,7 +1074,7 @@ class EnvironmentTest < ActiveSupport::TestCase |
1074 | 1074 | end |
1075 | 1075 | |
1076 | 1076 | should 'get enabled features' do |
1077 | - env = Environment.new | |
1077 | + env = fast_create(Environment) | |
1078 | 1078 | env.enable('feature1', false) |
1079 | 1079 | env.enable('feature2', false) |
1080 | 1080 | env.disable('feature3', false) | ... | ... |
test/unit/person_test.rb
... | ... | @@ -211,7 +211,7 @@ class PersonTest < ActiveSupport::TestCase |
211 | 211 | p3 = create_user('testuser3').person |
212 | 212 | p1.add_friend(p3) |
213 | 213 | |
214 | - assert_equal [p2,p3], p1.friends(true) # force reload | |
214 | + assert_equivalent [p2,p3], p1.friends(true) # force reload | |
215 | 215 | |
216 | 216 | end |
217 | 217 | |
... | ... | @@ -1074,8 +1074,8 @@ class PersonTest < ActiveSupport::TestCase |
1074 | 1074 | person.add_friend(friend_1) |
1075 | 1075 | person.add_friend(friend_2) |
1076 | 1076 | person.add_friend(friend_3) |
1077 | - assert_equal [friend_1, friend_2, friend_3], person.friends | |
1078 | - assert_equal [friend_1], person.friends.online | |
1077 | + assert_equivalent [friend_1, friend_2, friend_3], person.friends | |
1078 | + assert_equivalent [friend_1], person.friends.online | |
1079 | 1079 | end |
1080 | 1080 | |
1081 | 1081 | should 'return url to a person wall' do | ... | ... |
test/unit/profile_helper_test.rb
... | ... | @@ -13,84 +13,48 @@ class ProfileHelperTest < ActiveSupport::TestCase |
13 | 13 | end |
14 | 14 | attr_reader :profile, :helper |
15 | 15 | |
16 | - should 'not display field if field is not active and not forced' do | |
17 | - profile.expects(:active_fields).returns([]) | |
18 | - assert_equal '', display_field('Title', profile, 'field') | |
19 | - end | |
20 | - | |
21 | - should 'display field if field is not active but is forced' do | |
22 | - profile.expects(:active_fields).returns([]) | |
16 | + should 'display field if may display it' do | |
17 | + self.stubs(:user).returns(nil) | |
18 | + profile.expects(:may_display_field_to?).returns(true) | |
23 | 19 | profile.expects(:field).returns('value') |
24 | - assert_match /Title.*value/, display_field('Title', profile, 'field', true) | |
20 | + assert_match /Title.*value/, display_field('Title', profile, 'field') | |
25 | 21 | end |
26 | 22 | |
27 | - should 'not display field if field is active but not public and not logged in' do | |
28 | - profile.stubs(:active_fields).returns(['field']) | |
29 | - profile.expects(:public_fields).returns([]) | |
30 | - @controller = mock | |
31 | - @controller.stubs(:user).returns(nil) | |
23 | + should 'not display field if may not display it and not forced' do | |
24 | + self.stubs(:user).returns(nil) | |
25 | + profile.expects(:may_display_field_to?).returns(false) | |
32 | 26 | assert_equal '', display_field('Title', profile, 'field') |
33 | 27 | end |
34 | 28 | |
35 | - should 'not display field if field is active but not public and user is not friend' do | |
36 | - profile.stubs(:active_fields).returns(['field']) | |
37 | - profile.expects(:public_fields).returns([]) | |
38 | - user = mock | |
39 | - user.expects(:is_a_friend?).with(profile).returns(false) | |
40 | - @controller = mock | |
41 | - @controller.stubs(:user).returns(user) | |
42 | - assert_equal '', display_field('Title', profile, 'field') | |
43 | - end | |
44 | - | |
45 | - should 'display field if field is active and not public but user is profile owner' do | |
46 | - profile.stubs(:active_fields).returns(['field']) | |
47 | - profile.expects(:public_fields).returns([]) | |
29 | + should 'display field if may not display it but is forced' do | |
30 | + self.stubs(:user).returns(nil) | |
31 | + profile.stubs(:may_display_field_to?).returns(false) | |
48 | 32 | profile.expects(:field).returns('value') |
49 | - @controller = mock | |
50 | - @controller.stubs(:user).returns(profile) | |
51 | 33 | assert_match /Title.*value/, display_field('Title', profile, 'field', true) |
52 | 34 | end |
53 | 35 | |
54 | - should 'display field if field is active and not public but user is a friend' do | |
55 | - profile.stubs(:active_fields).returns(['field']) | |
56 | - profile.expects(:public_fields).returns([]) | |
57 | - profile.expects(:field).returns('value') | |
58 | - user = mock | |
59 | - user.expects(:is_a_friend?).with(profile).returns(true) | |
60 | - @controller = mock | |
61 | - @controller.stubs(:user).returns(user) | |
62 | - assert_match /Title.*value/, display_field('Title', profile, 'field', true) | |
36 | + should 'display work info if at least one of the fields should be displayed' do | |
37 | + self.stubs(:user).returns(nil) | |
38 | + profile.stubs(:may_display_field_to?).with(:organization, nil).returns(true) | |
39 | + profile.stubs(:may_display_field_to?).with(:organization_website, nil).returns(false) | |
40 | + profile.expects(:organization).returns('Organization Name') | |
41 | + profile.expects(:organization_website).never | |
42 | + assert_match /Work.*Organization Name/, display_work_info(profile) | |
63 | 43 | end |
64 | 44 | |
65 | - should 'not display work info if field is active but not public and user is not friend' do | |
66 | - profile.stubs(:active_fields).returns(['organization', 'organization_website']) | |
67 | - profile.expects(:public_fields).returns([]).times(2) | |
68 | - user = mock | |
69 | - user.expects(:is_a_friend?).with(profile).returns(false).times(2) | |
70 | - @controller = mock | |
71 | - @controller.stubs(:user).returns(user) | |
45 | + should 'not display work info if none of the fields should be displayed' do | |
46 | + self.stubs(:user).returns(nil) | |
47 | + profile.stubs(:may_display_field_to?).returns(false) | |
48 | + profile.expects(:organization).never | |
49 | + profile.expects(:organization_website).never | |
72 | 50 | assert_equal '', display_work_info(profile) |
73 | 51 | end |
74 | 52 | |
75 | - should 'display work info if field is active and not public but user is profile owner' do | |
76 | - profile.stubs(:active_fields).returns(['organization', 'organization_website']) | |
77 | - profile.expects(:public_fields).returns([]).times(2) | |
78 | - profile.expects(:organization).returns('Organization Name') | |
79 | - profile.expects(:organization_website).returns('') | |
80 | - @controller = mock | |
81 | - @controller.stubs(:user).returns(profile) | |
82 | - assert_match /Work.*Organization Name/, display_work_info(profile) | |
83 | - end | |
84 | - | |
85 | - should 'display work info if field is active and not public but user is a friend' do | |
86 | - profile.stubs(:active_fields).returns(['organization', 'organization_website']) | |
87 | - profile.expects(:public_fields).returns([]).times(2) | |
53 | + should 'display work info if both fields should be displayed' do | |
54 | + self.stubs(:user).returns(nil) | |
55 | + profile.stubs(:may_display_field_to?).returns(true) | |
88 | 56 | profile.expects(:organization).returns('Organization Name') |
89 | 57 | profile.expects(:organization_website).returns('') |
90 | - user = mock | |
91 | - user.expects(:is_a_friend?).with(profile).returns(true).times(2) | |
92 | - @controller = mock | |
93 | - @controller.stubs(:user).returns(user) | |
94 | 58 | assert_match /Work.*Organization Name/, display_work_info(profile) |
95 | 59 | end |
96 | 60 | ... | ... |
test/unit/profile_list_block_test.rb
... | ... | @@ -34,6 +34,7 @@ class ProfileListBlockTest < ActiveSupport::TestCase |
34 | 34 | self.expects(:profile_image_link).with(person2, :minor).once |
35 | 35 | self.expects(:profile_image_link).with(person3, :minor).once |
36 | 36 | |
37 | + self.stubs(:tag).returns('<div></div>') | |
37 | 38 | self.expects(:content_tag).returns('<div></div>').at_least_once |
38 | 39 | self.expects(:block_title).returns('block title').at_least_once |
39 | 40 | ... | ... |
test/unit/profile_test.rb
... | ... | @@ -1833,4 +1833,59 @@ class ProfileTest < ActiveSupport::TestCase |
1833 | 1833 | assert_equal f, p.fields_privacy |
1834 | 1834 | end |
1835 | 1835 | |
1836 | + should 'not display field if field is active but not public and user not logged in' do | |
1837 | + profile = fast_create(Profile) | |
1838 | + profile.stubs(:active_fields).returns(['field']) | |
1839 | + profile.stubs(:public_fields).returns([]) | |
1840 | + assert !profile.may_display_field_to?('field', nil) | |
1841 | + end | |
1842 | + | |
1843 | + should 'not display field if field is active but not public and user is not friend' do | |
1844 | + profile = fast_create(Profile) | |
1845 | + profile.stubs(:active_fields).returns(['field']) | |
1846 | + profile.expects(:public_fields).returns([]) | |
1847 | + user = mock | |
1848 | + user.expects(:is_a_friend?).with(profile).returns(false) | |
1849 | + assert !profile.may_display_field_to?('field', user) | |
1850 | + end | |
1851 | + | |
1852 | + should 'display field if field is active and not public but user is profile owner' do | |
1853 | + user = profile = fast_create(Profile) | |
1854 | + profile.stubs(:active_fields).returns(['field']) | |
1855 | + profile.expects(:public_fields).returns([]) | |
1856 | + assert profile.may_display_field_to?('field', user) | |
1857 | + end | |
1858 | + | |
1859 | + should 'display field if field is active and not public but user is a friend' do | |
1860 | + profile = fast_create(Profile) | |
1861 | + profile.stubs(:active_fields).returns(['field']) | |
1862 | + profile.expects(:public_fields).returns([]) | |
1863 | + user = mock | |
1864 | + user.expects(:is_a_friend?).with(profile).returns(true) | |
1865 | + assert profile.may_display_field_to?('field', user) | |
1866 | + end | |
1867 | + | |
1868 | + should 'call may_display on field name if the field is not active' do | |
1869 | + user = fast_create(Person) | |
1870 | + profile = fast_create(Profile) | |
1871 | + profile.stubs(:active_fields).returns(['humble']) | |
1872 | + profile.expects(:may_display_humble_to?).never | |
1873 | + profile.expects(:may_display_bundle_to?).once | |
1874 | + | |
1875 | + profile.may_display_field_to?('humble', user) | |
1876 | + profile.may_display_field_to?('bundle', user) | |
1877 | + end | |
1878 | + | |
1879 | + # TODO Eventually we would like to specify it in a deeper granularity... | |
1880 | + should 'not display location if any field is private' do | |
1881 | + user = fast_create(Person) | |
1882 | + profile = fast_create(Profile) | |
1883 | + profile.stubs(:active_fields).returns(Profile::LOCATION_FIELDS) | |
1884 | + Profile::LOCATION_FIELDS.each { |field| profile.stubs(:may_display_field_to?).with(field, user).returns(true)} | |
1885 | + assert profile.may_display_location_to?(user) | |
1886 | + | |
1887 | + profile.stubs(:may_display_field_to?).with(Profile::LOCATION_FIELDS[0], user).returns(false) | |
1888 | + assert !profile.may_display_location_to?(user) | |
1889 | + end | |
1890 | + | |
1836 | 1891 | end | ... | ... |
vendor/plugins/action_tracker_has_comments/init.rb
1 | 1 | # monkey patch to add comments on action_tracker |
2 | 2 | |
3 | -ActionTracker::Record.module_eval do | |
3 | +Rails.configuration.to_prepare do | |
4 | + ActionTracker::Record.module_eval do | |
4 | 5 | |
5 | - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}' | |
6 | + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}' | |
6 | 7 | |
7 | - def conditions_for_comments | |
8 | - type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) | |
9 | - "source_type = '#{type}' AND source_id = '#{id}'" | |
10 | - end | |
8 | + def conditions_for_comments | |
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}'" | |
11 | + end | |
11 | 12 | |
12 | - def comments_as_thread | |
13 | - result = {} | |
14 | - root = [] | |
15 | - self.comments.each do |c| | |
16 | - c.replies = [] | |
17 | - result[c.id] ||= c | |
18 | - c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c | |
13 | + def comments_as_thread | |
14 | + result = {} | |
15 | + root = [] | |
16 | + self.comments.each do |c| | |
17 | + c.replies = [] | |
18 | + result[c.id] ||= c | |
19 | + c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c | |
20 | + end | |
21 | + root | |
19 | 22 | end |
20 | - root | |
21 | - end | |
22 | 23 | |
24 | + end | |
23 | 25 | end | ... | ... |
vendor/plugins/monkey_patches/rescue_delayed_job_crashes/init.rb
1 | 1 | Delayed::Worker.module_eval do |
2 | 2 | # based on https://groups.google.com/forum/#!topic/delayed_job/ZGMUFFppNgs |
3 | 3 | class Delayed::Worker::ExceptionNotification < ActionMailer::Base |
4 | - def mail error | |
4 | + def mail job, error | |
5 | 5 | environment = Environment.default |
6 | 6 | |
7 | 7 | recipients NOOSFERO_CONF['exception_recipients'] |
8 | 8 | from environment.contact_email |
9 | 9 | reply_to environment.contact_email |
10 | - subject "[#{environment.name}] DelayedJob: #{error.message}" | |
11 | - body render(:text => error.backtrace.join("\n")) | |
10 | + subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}" | |
11 | + body render(:text => " | |
12 | +Job: | |
13 | +#{job.inspect} | |
14 | + | |
15 | +Handler: | |
16 | +#{job.handler} | |
17 | + | |
18 | +Backtrace: | |
19 | +#{error.backtrace.join("\n")} | |
20 | + ") | |
12 | 21 | end |
13 | 22 | end |
14 | 23 | |
15 | 24 | def handle_failed_job_with_notification(job, error) |
16 | - Delayed::Worker::ExceptionNotification.deliver_mail error if NOOSFERO_CONF['exception_recipients'].present? | |
25 | + Delayed::Worker::ExceptionNotification.deliver_mail job, error if NOOSFERO_CONF['exception_recipients'].present? | |
17 | 26 | handle_failed_job_without_notification job, error |
18 | 27 | end |
19 | 28 | alias_method_chain :handle_failed_job, :notification | ... | ... |