Commit 961148fb74e53842f028b9485cfb210ec5d4562f
Exists in
master
and in
22 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 | ... | ... |