Commit 961148fb74e53842f028b9485cfb210ec5d4562f
Exists in
master
and in
28 other branches
Merge branch 'stable'
Conflicts: po/pt_BR/noosfero.po
Showing
34 changed files
with
266 additions
and
107 deletions
Show diff stats
app/controllers/my_profile/profile_editor_controller.rb
... | ... | @@ -64,7 +64,7 @@ class ProfileEditorController < MyProfileController |
64 | 64 | def header_footer |
65 | 65 | @no_design_blocks = true |
66 | 66 | if request.post? |
67 | - @profile.update_attributes!(:custom_footer => params[:custom_footer], :custom_header => params[:custom_header]) | |
67 | + @profile.update_header_and_footer(params[:custom_header], params[:custom_footer]) | |
68 | 68 | redirect_to :action => 'index' |
69 | 69 | else |
70 | 70 | @header = boxes_holder.custom_header | ... | ... |
app/controllers/my_profile/themes_controller.rb
... | ... | @@ -4,7 +4,7 @@ class ThemesController < MyProfileController |
4 | 4 | no_design_blocks |
5 | 5 | |
6 | 6 | def set |
7 | - profile.update_attributes!(:theme => params[:id]) | |
7 | + profile.update_theme(params[:id]) | |
8 | 8 | redirect_to :action => 'index' |
9 | 9 | end |
10 | 10 | |
... | ... | @@ -79,8 +79,7 @@ class ThemesController < MyProfileController |
79 | 79 | end |
80 | 80 | |
81 | 81 | def set_layout_template |
82 | - profile.layout_template = params[:id] | |
83 | - profile.save! | |
82 | + profile.update_layout_template(params[:id]) | |
84 | 83 | redirect_to :action => 'index' |
85 | 84 | end |
86 | 85 | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -311,22 +311,35 @@ module ApplicationHelper |
311 | 311 | end |
312 | 312 | |
313 | 313 | def current_theme |
314 | - return session[:theme] if (session[:theme]) | |
315 | - | |
316 | - # utility for developers: set the theme to 'random' in development mode and | |
317 | - # you will get a different theme every request. This is interesting for | |
318 | - # testing | |
319 | - if ENV['RAILS_ENV'] == 'development' && @environment.theme == 'random' | |
320 | - @theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand | |
321 | - return @theme | |
322 | - end | |
323 | - | |
324 | - p = profile | |
325 | - if p | |
326 | - p.theme | |
327 | - else | |
328 | - @environment.theme | |
329 | - end | |
314 | + @current_theme ||= | |
315 | + begin | |
316 | + if (session[:theme]) | |
317 | + session[:theme] | |
318 | + else | |
319 | + # utility for developers: set the theme to 'random' in development mode and | |
320 | + # you will get a different theme every request. This is interesting for | |
321 | + # testing | |
322 | + if ENV['RAILS_ENV'] == 'development' && environment.theme == 'random' | |
323 | + @random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand | |
324 | + @random_theme | |
325 | + else | |
326 | + if profile | |
327 | + profile.theme | |
328 | + elsif environment | |
329 | + environment.theme | |
330 | + else | |
331 | + if logger | |
332 | + logger.warn("No environment found. This is weird.") | |
333 | + logger.warn("Request environment: %s" % request.env.inspect) | |
334 | + logger.warn("Request parameters: %s" % params.inspect) | |
335 | + end | |
336 | + | |
337 | + # could not determine the theme, so return the default one | |
338 | + 'default' | |
339 | + end | |
340 | + end | |
341 | + end | |
342 | + end | |
330 | 343 | end |
331 | 344 | |
332 | 345 | def theme_include(template) | ... | ... |
app/helpers/sweeper_helper.rb
app/models/article.rb
... | ... | @@ -214,6 +214,13 @@ class Article < ActiveRecord::Base |
214 | 214 | end |
215 | 215 | end |
216 | 216 | |
217 | + def allow_post_content?(logged_person = nil) | |
218 | + if logged_person && logged_person.has_permission?('post_content', profile) | |
219 | + return true | |
220 | + end | |
221 | + false | |
222 | + end | |
223 | + | |
217 | 224 | def comments_updated |
218 | 225 | ferret_update |
219 | 226 | end |
... | ... | @@ -266,8 +273,10 @@ class Article < ActiveRecord::Base |
266 | 273 | profile |
267 | 274 | end |
268 | 275 | |
269 | - def cache_key(params = {}) | |
270 | - "article-id-#{id}" + | |
276 | + alias :active_record_cache_key :cache_key | |
277 | + def cache_key(params = {}, the_profile = nil) | |
278 | + active_record_cache_key + | |
279 | + (allow_post_content?(the_profile) ? "-owner" : '') + | |
271 | 280 | (params[:npage] ? "-npage-#{params[:npage]}" : '') + |
272 | 281 | (params[:year] ? "-year-#{params[:year]}" : '') + |
273 | 282 | (params[:month] ? "-month-#{params[:month]}" : '') | ... | ... |
app/models/feed_reader_block.rb
... | ... | @@ -28,7 +28,7 @@ class FeedReaderBlock < Block |
28 | 28 | |
29 | 29 | def formatted_feed_content |
30 | 30 | return "<ul>\n" + |
31 | - self.feed_items.map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n") + | |
31 | + self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n") + | |
32 | 32 | "</ul>" |
33 | 33 | end |
34 | 34 | ... | ... |
app/models/person.rb
app/models/profile.rb
... | ... | @@ -643,4 +643,18 @@ class Profile < ActiveRecord::Base |
643 | 643 | ProfileSweeper.new().after_create(profile) |
644 | 644 | end |
645 | 645 | |
646 | + def update_header_and_footer(header, footer) | |
647 | + self.custom_header = header | |
648 | + self.custom_footer = footer | |
649 | + self.save(false) | |
650 | + end | |
651 | + | |
652 | + def update_theme(theme) | |
653 | + self.update_attribute(:theme, theme) | |
654 | + end | |
655 | + | |
656 | + def update_layout_template(template) | |
657 | + self.update_attribute(:layout_template, template) | |
658 | + end | |
659 | + | |
646 | 660 | end | ... | ... |
app/sweepers/article_sweeper.rb
... | ... | @@ -13,7 +13,11 @@ class ArticleSweeper < ActiveRecord::Observer |
13 | 13 | protected |
14 | 14 | |
15 | 15 | def expire_caches(article) |
16 | - article.hierarchy.each {|a| expire_fragment(a.cache_key) } | |
16 | + article.hierarchy.each do |a| | |
17 | + if a != article | |
18 | + a.touch | |
19 | + end | |
20 | + end | |
17 | 21 | blocks = (article.profile.blocks + article.profile.environment.blocks).select{|b|[RecentDocumentsBlock, BlogArchivesBlock].any?{|c| b.kind_of?(c)}} |
18 | 22 | blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} |
19 | 23 | env = article.profile.environment | ... | ... |
app/sweepers/profile_sweeper.rb
... | ... | @@ -17,8 +17,11 @@ protected |
17 | 17 | profile.members.each do |member| |
18 | 18 | expire_communities(member) if profile.community? |
19 | 19 | expire_enterprises(member) if profile.enterprise? |
20 | + expire_profile_index(member) if profile.enterprise? | |
20 | 21 | end |
21 | 22 | |
23 | + expire_profile_index(profile) if profile.person? | |
24 | + | |
22 | 25 | profile.blocks.each do |block| |
23 | 26 | expire_timeout_fragment(block.cache_keys) |
24 | 27 | end | ... | ... |
app/views/blocks/my_network/person.rhtml
... | ... | @@ -3,8 +3,8 @@ |
3 | 3 | content_tag('b', owner.articles.count), owner.public_profile_url.merge(:action => 'sitemap') ) %></li> |
4 | 4 | <li><%= link_to(n__('One friend', '%s friends', owner.friends.count) % |
5 | 5 | content_tag('b', owner.friends.count), owner.public_profile_url.merge(:action => 'friends')) %></li> |
6 | - <li><%= link_to(n__('One community', '%s communities', owner.communities.size) % | |
7 | - content_tag('b', owner.communities.size), owner.public_profile_url.merge(:action => 'communities')) %></li> | |
6 | + <li><%= link_to(n__('One community', '%{num} communities', owner.communities.size) % | |
7 | + {:num => content_tag('b', owner.communities.size)}, owner.public_profile_url.merge(:action => 'communities')) %></li> | |
8 | 8 | <li><%= link_to(n_('One tag', '%s tags', owner.article_tags.size) % |
9 | 9 | content_tag('b', owner.article_tags.size), owner.public_profile_url.merge(:action => 'tags')) %></li> |
10 | 10 | </ul> | ... | ... |
app/views/content_viewer/view_page.rhtml
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | |
24 | 24 | <div> |
25 | 25 | <%= article_title(@page, :no_link => true) %> |
26 | - <% if logged_in? && current_user.person.has_permission?('post_content', profile) %> | |
26 | + <% if @page.allow_post_content?(user) %> | |
27 | 27 | <div id="article-actions"> |
28 | 28 | <% unless @page.blog? %> |
29 | 29 | <%= link_to content_tag( 'span', label_for_edit_article(@page) ), |
... | ... | @@ -80,7 +80,7 @@ |
80 | 80 | </div> |
81 | 81 | <% end %> |
82 | 82 | |
83 | -<% cache(@page.cache_key(params)) do %> | |
83 | +<% cache(@page.cache_key(params, user)) do %> | |
84 | 84 | <div class="<%="article-body article-body-" + @page.css_class_name %>"> |
85 | 85 | <%= article_to_html(@page) %> |
86 | 86 | <br style="clear:both" /> | ... | ... |
app/views/layouts/application-ng.rhtml
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | <%= meta_tags_for_article(@page) %> |
6 | 6 | <!--<meta http-equiv="refresh" content="1"/>--> |
7 | 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
8 | + <meta name="description" content="<%= @environment.name %>" /> | |
8 | 9 | <link rel="shortcut icon" href="<%= '/designs/themes/' + current_theme + '/imgs/favicon.ico' %>" type="image/x-icon" /> |
9 | 10 | <%= noosfero_javascript %> |
10 | 11 | <%= import_blocks_stylesheets %> | ... | ... |
app/views/layouts/application.rhtml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | <head> |
4 | 4 | <title><%= page_title %></title> |
5 | 5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
6 | - <meta name="description" content="FIXME: Descriptions of Noosfero" /> | |
6 | + <meta name="description" content="<%= @environment.name %>" /> | |
7 | 7 | <meta name="keywords" content="Noosfero, Community, Open Source" /> |
8 | 8 | <link rel="shortcut icon" href="<%= '/designs/themes/' + current_theme + '/images/favicon.ico' %>" type="image/x-icon" /> |
9 | 9 | <!-- ok --><%= meta_tags_for_article(@page) %> | ... | ... |
app/views/profile/_person.rhtml
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | <%= display_field(_('e-Mail:'), profile, :email, true) { |email| link_to_email(email) } %> |
17 | 17 | <% end %> |
18 | 18 | |
19 | -<% cache_timeout(profile.identifier + '-profile-relationships', 4.hours.from_now) do %> | |
19 | +<% cache_timeout(profile.relationships_cache_key, 4.hours.from_now) do %> | |
20 | 20 | <% if !(profile.organization.blank? && profile.organization_website.blank?) && (profile.active_fields.include?('organization') || profile.active_fields.include?('organization_website')) %> |
21 | 21 | <tr> |
22 | 22 | <th colspan='2'><%= _('Work')%></th> | ... | ... |
app/views/profile_editor/_organization.rhtml
... | ... | @@ -63,23 +63,24 @@ |
63 | 63 | <%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %> |
64 | 64 | |
65 | 65 | <h1><%= _('Moderation options') %></h1> |
66 | - <div style='margin-bottom: 1em'> | |
67 | - <%= _('New members must be approved:')%> | |
68 | - </div> | |
69 | - <div style='margin-bottom: 0.5em'> | |
70 | - <%= radio_button 'profile_data', 'closed', 'true', :style => 'float: left' %> | |
71 | - <div style='margin-left: 30px'> | |
72 | - <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).') %> | |
66 | + <% if profile.community? %> | |
67 | + <div style='margin-bottom: 1em'> | |
68 | + <%= _('New members must be approved:')%> | |
73 | 69 | </div> |
74 | - </div> | |
75 | - <div> | |
76 | - <%= radio_button 'profile_data', 'closed', 'false', :style => 'float: left' %> | |
77 | - <div style='margin-left: 30px'> | |
78 | - <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).') %> | |
70 | + <div style='margin-bottom: 0.5em'> | |
71 | + <%= radio_button 'profile_data', 'closed', 'true', :style => 'float: left' %> | |
72 | + <div style='margin-left: 30px'> | |
73 | + <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).') %> | |
74 | + </div> | |
79 | 75 | </div> |
80 | - </div> | |
81 | - | |
82 | - <br> | |
76 | + <div> | |
77 | + <%= radio_button 'profile_data', 'closed', 'false', :style => 'float: left' %> | |
78 | + <div style='margin-left: 30px'> | |
79 | + <%= _('<strong>After</strong> joining this group (a moderator can always desactivate access for users later).') %> | |
80 | + </div> | |
81 | + </div> | |
82 | + <br> | |
83 | + <% end %> | |
83 | 84 | <div style='margin-bottom: 1em'> |
84 | 85 | <%= _('New articles posted by members of this group must be approved:')%> |
85 | 86 | ... | ... |
app/views/profile_editor/_person_form.rhtml
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | <%= optional_field(@person, 'cell_phone', f.text_field(:cell_phone)) %> |
16 | 16 | <%= optional_field(@person, 'comercial_phone', f.text_field(:comercial_phone)) %> |
17 | 17 | <%= optional_field(@person, 'sex', f.radio_group(:profile_data, :sex, [ ['male',_('Male')], ['female',_('Female')] ])) %> |
18 | -<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 10)}) + '</div>')) %> | |
18 | +<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> | |
19 | 19 | <%= optional_field(@person, 'nationality', f.text_field(:nationality)) %> |
20 | 20 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> |
21 | 21 | <%= optional_field(@person, 'state', f.text_field(:state)) %> | ... | ... |
app/views/profile_editor/edit.rhtml
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <div id="profile_change_picture"> |
10 | 10 | <h2><%= _('Change picture') %></h2> |
11 | 11 | <% f.fields_for :image_builder, @profile.image do |i| %> |
12 | - <%= file_field_or_thumbnail(_('Image:'), @profile.image, i) %><%= _("(max size %s)")% Image.max_size.to_humanreadable %> | |
12 | + <%= file_field_or_thumbnail(_('Image:'), @profile.image, i) %><%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %> | |
13 | 13 | <% end %> |
14 | 14 | </div> |
15 | 15 | ... | ... |
app/views/shared/tiny_mce.rhtml
... | ... | @@ -24,7 +24,7 @@ tinyMCE.init({ |
24 | 24 | apply_source_formatting : true, |
25 | 25 | content_css: '/stylesheets/tinymce.css', |
26 | 26 | language: <%= tinymce_language.inspect %>, |
27 | - cleanup_callback : "customCleanup" | |
27 | + entity_encoding: 'raw' | |
28 | 28 | }); |
29 | 29 | |
30 | 30 | function convertWord(type, content) { |
... | ... | @@ -43,16 +43,4 @@ function convertWord(type, content) { |
43 | 43 | return content; |
44 | 44 | } |
45 | 45 | |
46 | -function customCleanup(type, value) { | |
47 | - switch (type) { | |
48 | - case "get_from_editor": | |
49 | - value = value.replace(/&amp;/g,"&"); | |
50 | - break; | |
51 | - case "insert_to_editor": | |
52 | - value = value.replace(/&amp;/g,"&"); | |
53 | - break; | |
54 | - } | |
55 | - return value; | |
56 | -} | |
57 | - | |
58 | 46 | </script> | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +class AddUpdatedAtToProfiles < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + add_column :profiles, :updated_at, :datetime | |
4 | + execute 'update profiles set updated_at = created_at' | |
5 | + end | |
6 | + | |
7 | + def self.down | |
8 | + remove_column :profiles, :updated_at | |
9 | + end | |
10 | +end | ... | ... |
db/schema.rb
... | ... | @@ -89,8 +89,8 @@ ActiveRecord::Schema.define(:version => 69) do |
89 | 89 | t.boolean "virtual", :default => false |
90 | 90 | end |
91 | 91 | |
92 | - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | |
93 | 92 | add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" |
93 | + add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | |
94 | 94 | |
95 | 95 | create_table "blocks", :force => true do |t| |
96 | 96 | t.string "title" |
... | ... | @@ -131,8 +131,8 @@ ActiveRecord::Schema.define(:version => 69) do |
131 | 131 | t.boolean "virtual", :default => false |
132 | 132 | end |
133 | 133 | |
134 | - add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" | |
135 | 134 | add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id" |
135 | + add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" | |
136 | 136 | |
137 | 137 | create_table "comments", :force => true do |t| |
138 | 138 | t.string "title" |
... | ... | @@ -211,8 +211,8 @@ ActiveRecord::Schema.define(:version => 69) do |
211 | 211 | t.datetime "updated_at" |
212 | 212 | end |
213 | 213 | |
214 | - add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" | |
215 | 214 | add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id" |
215 | + add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" | |
216 | 216 | |
217 | 217 | create_table "products", :force => true do |t| |
218 | 218 | t.integer "enterprise_id" |
... | ... | @@ -284,10 +284,6 @@ ActiveRecord::Schema.define(:version => 69) do |
284 | 284 | t.integer "environment_id" |
285 | 285 | end |
286 | 286 | |
287 | - create_table "schema_info", :id => false, :force => true do |t| | |
288 | - t.integer "version" | |
289 | - end | |
290 | - | |
291 | 287 | create_table "taggings", :force => true do |t| |
292 | 288 | t.integer "tag_id" |
293 | 289 | t.integer "taggable_id" |
... | ... | @@ -295,8 +291,8 @@ ActiveRecord::Schema.define(:version => 69) do |
295 | 291 | t.datetime "created_at" |
296 | 292 | end |
297 | 293 | |
298 | - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | |
299 | 294 | add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" |
295 | + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | |
300 | 296 | |
301 | 297 | create_table "tags", :force => true do |t| |
302 | 298 | t.string "name" | ... | ... |
lib/noosfero.rb
po/pt_BR/noosfero.po
... | ... | @@ -13,7 +13,7 @@ msgid "" |
13 | 13 | msgstr "" |
14 | 14 | "Project-Id-Version: noosfero 0.19.0\n" |
15 | 15 | "POT-Creation-Date: 2009-08-04 14:28-0300\n" |
16 | -"PO-Revision-Date: 2009-08-13 09:20-0300\n" | |
16 | +"PO-Revision-Date: 2009-08-21 20:42-0300\n" | |
17 | 17 | "Last-Translator: Joenio Costa <joenio@colivre.coop.br>\n" |
18 | 18 | "Language-Team: LANGUAGE <LL@li.org>\n" |
19 | 19 | "MIME-Version: 1.0\n" |
... | ... | @@ -6671,3 +6671,6 @@ msgstr "" |
6671 | 6671 | |
6672 | 6672 | msgid "You must type at least 3 characters" |
6673 | 6673 | msgstr "Você precisa digitar pelo menos 3 caracteres" |
6674 | + | |
6675 | +msgid "Max size: %s (.jpg, .gif, .png)" | |
6676 | +msgstr "Tamanho máximo: %s (.jpg, .gif, .png)" | ... | ... |
test/functional/application_controller_test.rb
... | ... | @@ -427,4 +427,9 @@ class ApplicationControllerTest < Test::Unit::TestCase |
427 | 427 | assert_equal false, @controller.avoid_ssl |
428 | 428 | end |
429 | 429 | |
430 | + should 'diplay name of environment in description' do | |
431 | + get :index | |
432 | + assert_tag :tag => 'meta', :attributes => { :name => 'description', :content => assigns(:environment).name } | |
433 | + end | |
434 | + | |
430 | 435 | end | ... | ... |
test/functional/profile_editor_controller_test.rb
... | ... | @@ -302,31 +302,23 @@ class ProfileEditorControllerTest < Test::Unit::TestCase |
302 | 302 | assert_not_nil assigns(:profile).image |
303 | 303 | end |
304 | 304 | |
305 | - should 'display closed attribute for enterprise when it is set' do | |
306 | - org = Enterprise.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => true, :environment => Environment.default) | |
305 | + should 'display closed attribute for communities when it is set' do | |
306 | + org = Community.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => true, :environment => Environment.default) | |
307 | 307 | get :edit, :profile => 'testorg' |
308 | 308 | |
309 | 309 | assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true', :checked => 'checked' } |
310 | 310 | assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false', :checked => 'checked' } |
311 | 311 | end |
312 | 312 | |
313 | - should 'display closed attribute for organizations when it is set' do | |
314 | - org = Organization.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => true, :environment => Environment.default) | |
315 | - get :edit, :profile => 'testorg' | |
316 | - | |
317 | - assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true', :checked => 'checked' } | |
318 | - assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false', :checked => 'checked' } | |
319 | - end | |
320 | - | |
321 | - should 'display closed attribute for organizations when it is set to false' do | |
322 | - org = Organization.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => false) | |
313 | + should 'display closed attribute for communities when it is set to false' do | |
314 | + org = Community.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => false) | |
323 | 315 | get :edit, :profile => 'testorg' |
324 | 316 | assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true', :checked => 'checked' } |
325 | 317 | assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false', :checked => 'checked' } |
326 | 318 | end |
327 | 319 | |
328 | - should 'display closed attribute for organizations when it is set to nothing at all' do | |
329 | - org = Organization.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => nil) | |
320 | + should 'display closed attribute for communities when it is set to nothing at all' do | |
321 | + org = Community.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :closed => nil) | |
330 | 322 | get :edit, :profile => 'testorg' |
331 | 323 | assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true', :checked => 'checked' } |
332 | 324 | assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false', :checked => 'checked' } |
... | ... | @@ -348,6 +340,22 @@ class ProfileEditorControllerTest < Test::Unit::TestCase |
348 | 340 | assert !org.closed |
349 | 341 | end |
350 | 342 | |
343 | + should 'not display option to close when it is enterprise' do | |
344 | + org = Enterprise.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :environment => Environment.default) | |
345 | + get :edit, :profile => 'testorg' | |
346 | + | |
347 | + assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true' } | |
348 | + assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false' } | |
349 | + end | |
350 | + | |
351 | + should 'display option to close when it is community' do | |
352 | + org = Community.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :environment => Environment.default) | |
353 | + get :edit, :profile => 'testorg' | |
354 | + | |
355 | + assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'true' } | |
356 | + assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'profile_data[closed]', :value => 'false' } | |
357 | + end | |
358 | + | |
351 | 359 | should 'display manage members options if has permission' do |
352 | 360 | profile = Profile['ze'] |
353 | 361 | community = Community.create!(:name => 'test org', :identifier => 'testorg', :contact_person => 'my contact', :environment => Environment.default) |
... | ... | @@ -526,6 +534,17 @@ class ProfileEditorControllerTest < Test::Unit::TestCase |
526 | 534 | assert_equal 'new footer', person.custom_footer |
527 | 535 | end |
528 | 536 | |
537 | + should 'save header and footer even if model is invalid' do | |
538 | + person = create_user('designtestuser').person | |
539 | + person.sex = nil; person.save! | |
540 | + person.environment.custom_person_fields = {'sex' => {'required' => 'true', 'active' => 'true'} }; person.environment.save! | |
541 | + | |
542 | + post :header_footer, :profile => 'designtestuser', :custom_header => 'new header', :custom_footer => 'new footer' | |
543 | + person = Person.find(person.id) | |
544 | + assert_equal 'new header', person.custom_header | |
545 | + assert_equal 'new footer', person.custom_footer | |
546 | + end | |
547 | + | |
529 | 548 | should 'go back to editor after saving header/footer' do |
530 | 549 | person = create_user('designtestuser').person |
531 | 550 | post :header_footer, :profile => 'designtestuser', :custom_header => 'new header', :custom_footer => 'new footer' | ... | ... |
test/functional/themes_controller_test.rb
... | ... | @@ -78,6 +78,16 @@ class ThemesControllerTest < Test::Unit::TestCase |
78 | 78 | assert_equal 'onetheme', profile.theme |
79 | 79 | end |
80 | 80 | |
81 | + should 'save selection of theme even if model is invalid' do | |
82 | + @profile.sex = nil | |
83 | + @profile.save! | |
84 | + @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save! | |
85 | + | |
86 | + get :set, :profile => 'testinguser', :id => 'onetheme' | |
87 | + profile = Profile.find(@profile.id) | |
88 | + assert_equal 'onetheme', profile.theme | |
89 | + end | |
90 | + | |
81 | 91 | should 'point back to control panel' do |
82 | 92 | get :index, :profile => 'testinguser' |
83 | 93 | assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testinguser' }, :content => 'Back' |
... | ... | @@ -258,6 +268,17 @@ class ThemesControllerTest < Test::Unit::TestCase |
258 | 268 | assert_redirected_to :action => 'index' |
259 | 269 | end |
260 | 270 | |
271 | + should 'set template even if the model is invalid' do | |
272 | + @profile.sex = nil | |
273 | + @profile.save! | |
274 | + @profile.environment.custom_person_fields = { 'sex' => {'required' => 'true', 'active' => 'true'} }; @profile.environment.save! | |
275 | + | |
276 | + post :set_layout_template, :profile => 'testinguser', :id => 'leftbar' | |
277 | + profile = Profile.find(@profile.id) | |
278 | + assert_equal 'leftbar', profile.layout_template | |
279 | + assert_redirected_to :action => 'index' | |
280 | + end | |
281 | + | |
261 | 282 | should 'not display "new theme" button when user themes are disabled' do |
262 | 283 | env.disable('user_themes') |
263 | 284 | env.save! | ... | ... |
test/unit/article_test.rb
... | ... | @@ -705,15 +705,13 @@ class ArticleTest < Test::Unit::TestCase |
705 | 705 | end |
706 | 706 | |
707 | 707 | should 'use npage to compose cache key' do |
708 | - a = Article.new | |
709 | - a.expects(:id).returns(34) | |
710 | - assert_equal 'article-id-34-npage-2', a.cache_key(:npage => 2) | |
708 | + a = Article.create!(:name => 'Published at', :profile => profile) | |
709 | + assert_match(/-npage-2/,a.cache_key(:npage => 2)) | |
711 | 710 | end |
712 | 711 | |
713 | 712 | should 'use year and month to compose cache key' do |
714 | - a = Article.new | |
715 | - a.expects(:id).returns(34) | |
716 | - assert_equal 'article-id-34-year-2009-month-04', a.cache_key(:year => '2009', :month => '04') | |
713 | + a = Article.create!(:name => 'Published at', :profile => profile) | |
714 | + assert_match(/-year-2009-month-04/, a.cache_key(:year => '2009', :month => '04')) | |
717 | 715 | end |
718 | 716 | |
719 | 717 | should 'not be highlighted by default' do |
... | ... | @@ -749,4 +747,20 @@ class ArticleTest < Test::Unit::TestCase |
749 | 747 | assert_equal [c], a.categories |
750 | 748 | end |
751 | 749 | |
750 | + should 'add owner on cache_key when has profile' do | |
751 | + a = profile.articles.create!(:name => 'a test article') | |
752 | + assert_match(/-owner/, a.cache_key({}, profile)) | |
753 | + end | |
754 | + | |
755 | + should 'not add owner on cache_key when has no profile' do | |
756 | + a = profile.articles.create!(:name => 'a test article') | |
757 | + assert_no_match(/-owner/, a.cache_key({})) | |
758 | + end | |
759 | + | |
760 | + should 'add owner on cache_key when profile is community' do | |
761 | + c = Community.create!(:name => 'new_comm') | |
762 | + a = c.articles.create!(:name => 'a test article') | |
763 | + assert_match(/-owner/, a.cache_key({}, c)) | |
764 | + end | |
765 | + | |
752 | 766 | end | ... | ... |
test/unit/blog_test.rb
... | ... | @@ -130,16 +130,6 @@ class BlogTest < ActiveSupport::TestCase |
130 | 130 | assert ! blog.valid? |
131 | 131 | end |
132 | 132 | |
133 | - should 'expires cache when update post' do | |
134 | - p = create_user('testuser').person | |
135 | - blog = Blog.create!(:name => 'Blog test', :profile => p) | |
136 | - post = Article.create!(:name => 'First post', :profile => p, :parent => blog) | |
137 | - ArticleSweeper.any_instance.expects(:expire_fragment).with(blog.cache_key) | |
138 | - ArticleSweeper.any_instance.expects(:expire_fragment).with(post.cache_key) | |
139 | - post.name = 'Edited First post' | |
140 | - assert post.save! | |
141 | - end | |
142 | - | |
143 | 133 | should 'remove external feed when removing blog' do |
144 | 134 | p = create_user('testuser').person |
145 | 135 | blog = Blog.create!(:name => 'Blog test', :profile => p, :external_feed_builder => {:enabled => true, :address => "http://bli.org/feed"}) | ... | ... |
test/unit/feed_reader_block_test.rb
... | ... | @@ -81,4 +81,16 @@ class FeedReaderBlockTest < ActiveSupport::TestCase |
81 | 81 | assert_equal %w[ last-post second-post first-post ], feed.feed_items.map{|i|i[:title]} |
82 | 82 | end |
83 | 83 | |
84 | + should 'display only limit posts' do | |
85 | + feed.limit = 1; feed.save! | |
86 | + %w[ first-post second-post ].each do |i| | |
87 | + feed.add_item(i, "http://localhost/#{i}", Date.today, "some contet for #{i}") | |
88 | + end | |
89 | + | |
90 | + assert_tag_in_string feed.formatted_feed_content, :tag => 'a', :attributes => { :href => 'http://localhost/second-post' }, :content => 'second-post' | |
91 | + assert_no_tag_in_string feed.formatted_feed_content, :tag => 'a', :attributes => { :href => 'http://localhost/first-post' }, :content => 'first-post' | |
92 | + end | |
93 | + | |
94 | + | |
95 | + | |
84 | 96 | end | ... | ... |
test/unit/tiny_mce_article_test.rb
... | ... | @@ -4,7 +4,9 @@ class TinyMceArticleTest < Test::Unit::TestCase |
4 | 4 | |
5 | 5 | def setup |
6 | 6 | Article.rebuild_index |
7 | + @profile = create_user('zezinho').person | |
7 | 8 | end |
9 | + attr_reader :profile | |
8 | 10 | |
9 | 11 | # this test can be removed when we get real tests for TinyMceArticle |
10 | 12 | should 'be an article' do |
... | ... | @@ -20,16 +22,21 @@ class TinyMceArticleTest < Test::Unit::TestCase |
20 | 22 | end |
21 | 23 | |
22 | 24 | should 'be found when searching for articles by query' do |
23 | - ze = create_user('zezinho').person | |
24 | - tma = TinyMceArticle.create!(:name => 'test tinymce article', :body => '---', :profile => ze) | |
25 | + tma = TinyMceArticle.create!(:name => 'test tinymce article', :body => '---', :profile => profile) | |
25 | 26 | assert_includes TinyMceArticle.find_by_contents('article'), tma |
26 | 27 | assert_includes Article.find_by_contents('article'), tma |
27 | 28 | end |
28 | 29 | |
29 | 30 | should 'not sanitize target attribute' do |
30 | - ze = create_user('zezinho').person | |
31 | - article = TinyMceArticle.create!(:name => 'open link in new window', :body => "open <a href='www.invalid.com' target='_blank'>link</a> in new window", :profile => ze) | |
31 | + article = TinyMceArticle.create!(:name => 'open link in new window', :body => "open <a href='www.invalid.com' target='_blank'>link</a> in new window", :profile => profile) | |
32 | 32 | assert_tag_in_string article.body, :tag => 'a', :attributes => {:target => '_blank'} |
33 | 33 | end |
34 | 34 | |
35 | + should 'not translate & to amp; over times' do | |
36 | + article = TinyMceArticle.create!(:name => 'link', :body => "<a href='www.invalid.com?param1=value¶m2=value'>link</a>", :profile => profile) | |
37 | + assert article.save | |
38 | + assert_no_match /&amp;/, article.body | |
39 | + assert_match /&/, article.body | |
40 | + end | |
41 | + | |
35 | 42 | end | ... | ... |
vendor/plugins/timed_cached_fragment/lib/timed_cache_fragment.rb
... | ... | @@ -3,14 +3,13 @@ module ActionController |
3 | 3 | module Cache |
4 | 4 | module TimedCache |
5 | 5 | #handles standard ERB fragments used in RHTML |
6 | - def cache_timeout(name={}, expire = 10.minutes.from_now, &block) | |
6 | + def cache_timeout(key={}, expire = 10.minutes.from_now, &block) | |
7 | 7 | unless perform_caching then block.call; return end |
8 | - key = fragment_cache_key(name) | |
9 | 8 | if is_cache_expired?(key,true) |
10 | 9 | expire_timeout_fragment(key) |
11 | 10 | set_timeout(key, expire) |
12 | 11 | end |
13 | - cache_erb_fragment(block,name) | |
12 | + cache_erb_fragment(block,key) | |
14 | 13 | end |
15 | 14 | #handles the expiration of timeout fragment |
16 | 15 | def expire_timeout_fragment(key) | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +if ActiveRecord::Base.instance_methods.include?("touch") && Class.const_defined?('TOUCH_LOADED') | |
2 | + puts "W: ActiveRecord already provides a touch method, which means you must be using rails 2.3.3 or later." | |
3 | + puts "W: In this case the touch plugin could probably be removed" | |
4 | +end | |
5 | +TOUCH_LOADED = true | |
6 | + | |
7 | +module Touch | |
8 | + def touch | |
9 | + update_attribute(:updated_at, Time.now) | |
10 | + end | |
11 | +end | |
12 | + | |
13 | +ActiveRecord::Base.send(:include, Touch) | ... | ... |
vendor/plugins/white_list_sanitizer_unescape_before_reescape/init.rb
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | +# monkey patch to fix WhiteListSanitizer bug | |
2 | +# http://apidock.com/rails/HTML/WhiteListSanitizer/process_attributes_for | |
3 | +# | |
4 | +# this was solved in rails 2.2.1, then remove this patch when upgrade to it | |
5 | + | |
6 | +HTML::WhiteListSanitizer.module_eval do | |
7 | + # unescape before reescape to avoid: | |
8 | + # & -> & -> &amp; -> &amp;amp; -> &amp;amp;amp; -> etc | |
9 | + protected | |
10 | + def process_attributes_for(node, options) | |
11 | + return unless node.attributes | |
12 | + node.attributes.keys.each do |attr_name| | |
13 | + value = node.attributes[attr_name].to_s | |
14 | + | |
15 | + if !options[:attributes].include?(attr_name) || contains_bad_protocols?(attr_name, value) | |
16 | + node.attributes.delete(attr_name) | |
17 | + else | |
18 | + node.attributes[attr_name] = attr_name == 'style' ? sanitize_css(value) : CGI::escapeHTML(CGI::unescapeHTML(value)) | |
19 | + end | |
20 | + end | |
21 | + end | |
22 | +end | ... | ... |