Commit 4e34a473f90b72953141d94b9887a81cfe82e2e7

Authored by Caio Almeida
2 parents 0d62704c 2cd9bf00

Merge branch 'master' of gitorious.org:noosfero/noosfero

Showing 40 changed files with 208 additions and 52 deletions   Show diff stats
INSTALL
... ... @@ -237,6 +237,10 @@ Create the database structure:
237 237  
238 238 $ RAILS_ENV=production rake db:schema:load
239 239  
  240 +Compile the translations:
  241 +
  242 +$ RAILS_ENV=production rake noosfero:translations:compile
  243 +
240 244 Now we have to create some initial data. To create your default environment
241 245 (the first one), run the command below:
242 246  
... ... @@ -258,10 +262,6 @@ $ RAILS_ENV=production ./script/runner "User.create(:login => 'adminuser', :emai
258 262 (replace "adminuser", "admin@example.com", "admin" with the login, email
259 263 and password of your environment admin)
260 264  
261   -Compile the translations:
262   -
263   -$ RAILS_ENV=production rake noosfero:translations:compile
264   -
265 265 To start the Noosfero application servers:
266 266  
267 267 $ ./script/production start
... ...
app/helpers/application_helper.rb
... ... @@ -1154,7 +1154,7 @@ module ApplicationHelper
1154 1154 def render_environment_features(folder)
1155 1155 result = ''
1156 1156 environment.enabled_features.keys.each do |feature|
1157   - file = File.join(@controller.view_paths, 'shared', folder.to_s, "#{feature}.rhtml")
  1157 + file = File.join(@controller.view_paths.last, 'shared', folder.to_s, "#{feature}.rhtml")
1158 1158 if File.exists?(file)
1159 1159 result << render(:file => file, :use_full_path => false)
1160 1160 end
... ...
app/models/feed_reader_block.rb
... ... @@ -13,6 +13,7 @@ class FeedReaderBlock &lt; Block
13 13 old_address = address
14 14 orig_set_address(new_address)
15 15 self.enabled = (new_address && new_address != old_address) || (new_address && self.enabled) || false
  16 + self.fetched_at = nil
16 17 end
17 18  
18 19 settings_items :limit, :type => :integer
... ... @@ -71,6 +72,7 @@ class FeedReaderBlock &lt; Block
71 72 self.feed_title = nil
72 73 self.error_message = nil
73 74 end
  75 +
74 76 def finish_fetch
75 77 self.fetched_at = Time.now
76 78 self.save!
... ...
app/models/person.rb
... ... @@ -403,7 +403,7 @@ class Person &lt; Profile
403 403 end
404 404  
405 405 def control_panel_settings_button
406   - {:title => _('Profile Info and settings'), :icon => 'edit-profile'}
  406 + {:title => _('Edit Profile'), :icon => 'edit-profile'}
407 407 end
408 408  
409 409 def disable
... ...
app/models/product.rb
... ... @@ -184,7 +184,7 @@ class Product &lt; ActiveRecord::Base
184 184 end
185 185  
186 186 def price_described?
187   - return false if price.nil?
  187 + return false if price.blank? or price == 0
188 188 (price - total_production_cost).zero?
189 189 end
190 190  
... ...
app/models/profile.rb
... ... @@ -810,7 +810,7 @@ private :generate_url, :url_options
810 810 end
811 811  
812 812 def control_panel_settings_button
813   - {:title => _('Profile Info and settings'), :icon => 'edit-profile'}
  813 + {:title => _('Edit Profile'), :icon => 'edit-profile'}
814 814 end
815 815  
816 816 def self.identification
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -63,7 +63,7 @@
63 63 <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
64 64 </div>
65 65 </span>
66   - <form action="/search" class="search_form" method="get" class="clean">
  66 + <form action="/search" class="search_form clean" method="get" id="top-search">
67 67 <input name="query" size="15" value="<%=_('Search...')%>"
68 68 onfocus="this.form.className='focused';
69 69 if(this.value=='<%=_('Search...')%>'){this.value=''}"
... ...
app/views/profile_editor/edit.rhtml
... ... @@ -73,8 +73,6 @@
73 73 </table>
74 74 <% end %>
75 75  
76   - <%= select_categories(:profile_data, _('Select the categories of your interest'), 2) %>
77   -
78 76 <h2><%= _('Translations') %></h2>
79 77 <%= labelled_check_box(
80 78 _('Automatic redirect the visitor to the translated article of him language'),
... ... @@ -87,11 +85,7 @@
87 85 end.join("\n")
88 86 %>
89 87  
90   - <%=
91   - @plugins.map(:profile_editor_extras).each do |content|
92   - content.respond_to?(:call) ? content.call : content
93   - end.join("\n")
94   - %>
  88 + <%= select_categories(:profile_data, _('Select the categories of your interest'), 2) %>
95 89  
96 90 <% button_bar do %>
97 91 <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %>
... ...
features/browse_catalogs.feature
... ... @@ -73,6 +73,19 @@ Feature: browse catalogs
73 73 And I should not see "qualifiers"
74 74 And I should not see "price composition"
75 75  
  76 + Scenario: don't display the price when it's not defined
  77 + Given the following products
  78 + | owner | category | name |
  79 + | artebonito | categ1 | Produto1 |
  80 + And I am on /catalog/artebonito
  81 + Then I should see "Produto1" within "li.product-link"
  82 + And I should not see "0.00"
  83 + And I should see "No image" within ".no-image"
  84 + And I should not see "product unavailable"
  85 + And I should not see "description"
  86 + And I should not see "qualifiers"
  87 + And I should not see "price composition"
  88 +
76 89 Scenario: product name links to product page
77 90 Given the following products
78 91 | owner | category | name | price |
... ...
features/delete_profile.feature
... ... @@ -16,7 +16,7 @@ Feature: delete profile
16 16 Scenario: deleting profile
17 17 Given I am logged in as "joaosilva"
18 18 And I am on Joao Silva's control panel
19   - And I follow "Profile Info and settings"
  19 + And I follow "Edit Profile"
20 20 And I follow "Delete profile"
21 21 Then I should see "Are you sure you want to delete this profile?"
22 22 When I follow "Yes, I am sure"
... ... @@ -32,7 +32,7 @@ Feature: delete profile
32 32 Scenario: giving up of deleting profile
33 33 Given I am logged in as "joaosilva"
34 34 And I am on Joao Silva's control panel
35   - And I follow "Profile Info and settings"
  35 + And I follow "Edit Profile"
36 36 And I follow "Delete profile"
37 37 Then I should see "Are you sure you want to delete this profile?"
38 38 When I follow "No, I gave up"
... ... @@ -108,7 +108,7 @@ Feature: delete profile
108 108 Scenario: environment admin deletes profile
109 109 Given I am logged in as admin
110 110 And I am on Joao Silva's control panel
111   - And I follow "Profile Info and settings"
  111 + And I follow "Edit Profile"
112 112 And I follow "Delete profile"
113 113 Then I should see "Are you sure you want to delete this profile?"
114 114 When I follow "Yes, I am sure"
... ...
features/edit_article.feature
... ... @@ -91,7 +91,7 @@ Feature: edit article
91 91 Given I am on Joao Silva's sitemap
92 92 When I follow "Save the whales" and wait
93 93 And I follow "Edit" and wait
94   - And I follow "Cancel" within ".main-block" and wait
  94 + And I follow "Cancel" and wait
95 95 Then I should be on /joaosilva/save-the-whales
96 96  
97 97 @selenium
... ...
features/edit_profile.feature
... ... @@ -11,7 +11,7 @@ Feature: edit profile
11 11 | display_name |
12 12 | birth_date |
13 13 When I go to joao's control panel
14   - And I follow "Profile Info and settings"
  14 + And I follow "Edit Profile"
15 15 And I select "November"
16 16 And I select "15"
17 17 And I press "Save"
... ... @@ -23,7 +23,7 @@ Feature: edit profile
23 23 | display_name |
24 24 | birth_date |
25 25 When I go to joao's control panel
26   - And I follow "Profile Info and settings"
  26 + And I follow "Edit Profile"
27 27 And I select "November"
28 28 And I select "15"
29 29 And I press "Save"
... ... @@ -35,7 +35,7 @@ Feature: edit profile
35 35 | display_name |
36 36 | birth_date |
37 37 When I go to joao's control panel
38   - And I follow "Profile Info and settings"
  38 + And I follow "Edit Profile"
39 39 And I select "November"
40 40 And I select "15"
41 41 And I select "1980"
... ... @@ -48,7 +48,7 @@ Feature: edit profile
48 48 | display_name |
49 49 | birth_date |
50 50 When I go to joao's control panel
51   - And I follow "Profile Info and settings"
  51 + And I follow "Edit Profile"
52 52 And I select "November"
53 53 And I select "15"
54 54 And I select "1980"
... ...
features/manage_product_price_details.feature
... ... @@ -80,7 +80,7 @@ Feature: manage product price details
80 80 And I should not see "Taxes" within "#display-price-details"
81 81 And I should see "Energy" within "#display-price-details"
82 82  
83   - Scenario: not display product detail button if product does not have input
  83 + Scenario: not display price composition if product does not have input
84 84 Given the following product
85 85 | owner | category | name |
86 86 | redemoinho | rock | Yellow Submarine |
... ... @@ -89,13 +89,12 @@ Feature: manage product price details
89 89 | mariasouza | Maria Souza |
90 90 And I am logged in as "mariasouza"
91 91 When I go to Rede Moinho's page of product Yellow Submarine
92   - And I follow "Price composition"
93   - Then I should not see "Describe here the cost of production"
  92 + Then I should not see "Price composition"
94 93  
95   - Scenario: not display price details if price is not fully described
  94 + Scenario: not display price composition if price is not fully described
96 95 Given I am not logged in
97 96 And I go to Rede Moinho's page of product Abbey Road
98   - Then I should not see "60.0"
  97 + Then I should not see "Price composition"
99 98  
100 99 @selenium
101 100 Scenario: display price details if price is fully described
... ...
features/signup.feature
... ... @@ -53,7 +53,7 @@ Feature: signup
53 53 | joaosilva | Joao Silva |
54 54 Given I am logged in as "joaosilva"
55 55 And I am on Joao Silva's control panel
56   - And I follow "Profile Info and settings"
  56 + And I follow "Edit Profile"
57 57 And I fill in "Name" with ""
58 58 When I press "Save"
59 59 Then I should see "Name can't be blank"
... ...
lib/noosfero/plugin.rb
... ... @@ -7,6 +7,10 @@ class Noosfero::Plugin
7 7  
8 8 class << self
9 9  
  10 + def klass(dir)
  11 + (dir.to_s.camelize + 'Plugin').constantize # load the plugin
  12 + end
  13 +
10 14 def init_system
11 15 Dir.glob(File.join(Rails.root, 'config', 'plugins', '*')).select do |entry|
12 16 File.directory?(entry)
... ... @@ -18,8 +22,7 @@ class Noosfero::Plugin
18 22 path << File.join(dir, 'lib')
19 23 end
20 24  
21   - plugin_name = File.basename(dir).camelize + 'Plugin'
22   - plugin_name.constantize # load the plugin
  25 + klass(File.basename(dir))
23 26 end
24 27 end
25 28  
... ...
lib/noosfero/plugin/manager.rb
... ... @@ -22,4 +22,11 @@ class Noosfero::Plugin::Manager
22 22 end
23 23 end
24 24  
  25 + def [](name)
  26 + klass = Noosfero::Plugin.klass(name)
  27 + enabled_plugins.select do |plugin|
  28 + plugin.kind_of?(klass)
  29 + end.first
  30 + end
  31 +
25 32 end
... ...
lib/tasks/doc.rake
... ... @@ -13,7 +13,7 @@ namespace :noosfero do
13 13 [File.join(RAILS_ROOT, 'doc/noosfero/plugins/index.textile')]
14 14 end
15 15 input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"}
16   - topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }
  16 + topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq
17 17 sections = Dir.glob('doc/noosfero/*').select {|item| File.directory?(item) }
18 18 toc_sections = sections.map {|item| File.join(item, 'toc.en.xhtml')}
19 19 index_sections = sections.map {|item| File.join(item, 'index.en.xhtml')}
... ... @@ -104,11 +104,10 @@ namespace :noosfero do
104 104 desc "Build Noosfero online documentation"
105 105 task :build => [:link_plugins_textiles, po4a_conf] do
106 106 sh "po4a #{po4a_conf}"
107   - Rake::Task['noosfero:doc:unlink_plugins_textiles'].invoke
108 107 end
109 108  
110 109 desc "Cleans Noosfero online documentation"
111   - task :clean do
  110 + task :clean => :unlink_plugins_textiles do
112 111 sh 'rm -f doc/noosfero/*.xhtml'
113 112 sh 'rm -f doc/noosfero/*/*.xhtml'
114 113 rm_f po4a_conf
... ...
plugins/google_analytics/doc/google_analytics.textile
1 1 h1. Google Analytics
2 2  
3   -Tracking and web analytics to people and communities.
  3 +Tracking and web analytics for people and communities.
4 4  
5 5 h2. Usage
6 6  
7   -* Create a "Google Analytics":http://www.google.com/analytics/ account
8   -* Configure your Google Analytics account following these steps
  7 +Create and configure Google Analytics account following these steps:
9 8  
  9 +# Open "Google Analytics":http://www.google.com/analytics/
10 10 !=/plugins/google_analytics/images/doc/google-analytics-setup-step1.en.png(Google Setup - Step 1)!
11   -
  11 +# Sign in to Google Analytics
12 12 !=/plugins/google_analytics/images/doc/google-analytics-setup-step2.en.png(Google Setup - Step 2)!
13   -
  13 +# Follow signup instructions
14 14 !=/plugins/google_analytics/images/doc/google-analytics-setup-step3.en.png(Google Setup - Step 3)!
15   -
  15 +# Fill in _Website's URL_ with your profile address (eg.: softwarelivre.org/joenio), _Account Name_ with your name and read and accept terms of use
16 16 !=/plugins/google_analytics/images/doc/google-analytics-setup-step4.en.png(Google Setup - Step 4)!
17   -
  17 +# Accept default options, save and take note of your _Web Property ID_ (eg.: UA-23455430-3)
18 18 !=/plugins/google_analytics/images/doc/google-analytics-setup-step5.en.png(Google Setup - Step 5)!
19   -
  19 +# Login to Noosfero, go to your control panel, follow _Profile Info and Settings_ and fill in _Google Analytics Profile ID_ with ID above
20 20 !=/plugins/google_analytics/images/doc/google-analytics-setup-step6.en.png(Google Setup - Step 6)!
21 21  
22   -* Take note of your Google Analytics Profile ID
23   -* Login to Noosfero and go to your control panel
24   -* Follow Profile Info and Settings and fill in Google Analytics Profile ID
25   -
26 22 h2. Info
27 23  
28 24 * "Google Analytics Support":http://support.google.com/analytics
... ...
plugins/google_analytics/lib/google_analytics_plugin.rb
... ... @@ -4,6 +4,8 @@ class GoogleAnalyticsPlugin &lt; Noosfero::Plugin
4 4  
5 5 include ActionView::Helpers::JavaScriptHelper
6 6 include ActionView::Helpers::FormHelper
  7 + include ActionView::Helpers::UrlHelper
  8 + include ActionView::Helpers::TagHelper
7 9 include ApplicationHelper
8 10  
9 11 def self.plugin_name
... ... @@ -15,7 +17,7 @@ class GoogleAnalyticsPlugin &lt; Noosfero::Plugin
15 17 end
16 18  
17 19 def profile_id
18   - context.profile && context.profile.data[:google_analytics_profile_id]
  20 + context.profile && context.profile.google_analytics_profile_id
19 21 end
20 22  
21 23 def head_ending
... ... @@ -25,7 +27,7 @@ class GoogleAnalyticsPlugin &lt; Noosfero::Plugin
25 27 end
26 28  
27 29 def profile_editor_extras
28   - labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => context.profile.google_analytics_profile_id))
  30 + expanded_template('profile-editor-extras.rhtml',{:profile_id => profile_id})
29 31 end
30 32  
31 33 end
... ...
plugins/google_analytics/public/images/doc/google-analytics-setup-step1.en.png

107 KB | W: | H:

106 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/public/images/doc/google-analytics-setup-step1.pt.png

116 KB

plugins/google_analytics/public/images/doc/google-analytics-setup-step2.en.png

65.5 KB | W: | H:

35.9 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/public/images/doc/google-analytics-setup-step2.pt.png

86.2 KB

plugins/google_analytics/public/images/doc/google-analytics-setup-step3.en.png

38.7 KB | W: | H:

51.2 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/public/images/doc/google-analytics-setup-step3.pt.png

56 KB

plugins/google_analytics/public/images/doc/google-analytics-setup-step4.en.png

116 KB | W: | H:

68.9 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/public/images/doc/google-analytics-setup-step4.pt.png

119 KB

plugins/google_analytics/public/images/doc/google-analytics-setup-step5.en.png

75.4 KB | W: | H:

63.4 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/public/images/doc/google-analytics-setup-step5.pt.png

83.2 KB

plugins/google_analytics/public/images/doc/google-analytics-setup-step6.en.png

74.6 KB | W: | H:

51.3 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
plugins/google_analytics/views/profile-editor-extras.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2><%= _('Statistics') %></h2>
  2 +<%= labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => profile_id)) %>
  3 +<%= link_to(_('See how to configure statistics for your profile'), '/doc/plugins/google_analytics', :target => '_blank') %>
... ...
plugins/google_cse/controllers/google_cse_plugin_environment_controller.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +class GoogleCsePluginEnvironmentController < ApplicationController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 + no_design_blocks
  4 +end
... ...
plugins/google_cse/doc/google_cse.textile 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +h1. GoogleCsePlugin
  2 +
  3 +A plugin that uses the Google Custom Search as Noosfero general search engine.
  4 +
  5 +h2. Usage
  6 +
  7 +* Register a Google Custom Search ID at http://www.google.com/cse
  8 +* Set at least basic config, site list and look and fell of your Google Cse ID
  9 +* Configure Noosfero environment with this ID
  10 +** >> env = Environment.find( ... )
  11 +** >> env.settings[:google_cse_id] = '&lt;PUT ID HERE&gt;'
  12 +** >> env.save!
  13 +* That's all! The top search text-field of Noosfero will be used to make searches
... ...
plugins/google_cse/lib/google_cse_plugin.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +class GoogleCsePlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "GoogleCsePlugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that uses the Google Custom Search as Noosfero general search engine.")
  9 + end
  10 +
  11 + def google_id
  12 + context.environment.settings[:google_cse_id]
  13 + end
  14 +
  15 + def self.results_url_path
  16 + '/plugin/google_cse/results'
  17 + end
  18 +
  19 + def body_beginning
  20 + unless google_id.blank?
  21 + expanded_template('search-box.rhtml', {:selector => '#top-search, #footer-search', :plugin => self})
  22 + end
  23 + end
  24 +
  25 +end
... ...
plugins/google_cse/test/functional/google_cse_plugin_environment_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/google_cse_plugin_environment_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class GoogleCsePluginEnvironmentController; def rescue_action(e) raise e end; end
  6 +
  7 +class GoogleCsePluginEnvironmentControllerTest < Test::Unit::TestCase
  8 +
  9 + def setup
  10 + @controller = GoogleCsePluginEnvironmentController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 + end
  14 +
  15 + should 'get results page' do
  16 + get :results
  17 + assert_response :success
  18 + end
  19 +
  20 +end
... ...
plugins/google_cse/test/unit/google_cse_plugin_test.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class GoogleCsePluginTest < Test::Unit::TestCase
  4 +
  5 + def setup
  6 + @plugin = GoogleCsePlugin.new
  7 + @context = mock()
  8 + @plugin.context = @context
  9 + @env = Environment.new
  10 + @plugin.context.stubs(:environment).returns(@env)
  11 + end
  12 +
  13 + should 'get google_id from environment' do
  14 + @env.stubs(:settings).returns({:google_cse_id => 10})
  15 + assert_equal 10, @plugin.google_id
  16 + end
  17 +
  18 + should 'not use custom search if google_cse_id isnt set' do
  19 + @env.stubs(:settings).returns({})
  20 + assert_nil @plugin.body_beginning
  21 + @env.stubs(:settings).returns({:google_cse_id => 11})
  22 + assert_not_nil @plugin.body_beginning
  23 + end
  24 +
  25 +end
... ...
plugins/google_cse/views/google_cse_plugin_environment/results.rhtml 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +<% plugin = @plugins[:google_cse] %>
  2 +<div id="cse" style="width: 100%;"><%= _('Loading') %></div>
  3 +<script src="//www.google.com/jsapi" type="text/javascript"></script>
  4 +<script type="text/javascript">
  5 + function parseQueryFromUrl () {
  6 + var queryParamName = "q";
  7 + var search = window.location.search.substr(1);
  8 + var parts = search.split('&');
  9 + for (var i = 0; i < parts.length; i++) {
  10 + var keyvaluepair = parts[i].split('=');
  11 + if (decodeURIComponent(keyvaluepair[0]) == queryParamName) {
  12 + return decodeURIComponent(keyvaluepair[1].replace(/\+/g, ' '));
  13 + }
  14 + }
  15 + return '';
  16 + }
  17 + google.load('search', '1', {style : google.loader.themes.MINIMALIST});
  18 + google.setOnLoadCallback(function() {
  19 + var customSearchControl = new google.search.CustomSearchControl(
  20 + '<%= plugin && plugin.google_id %>');
  21 + customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
  22 + var options = new google.search.DrawOptions();
  23 + options.enableSearchResultsOnly();
  24 + customSearchControl.draw('cse', options);
  25 + var queryFromUrl = parseQueryFromUrl();
  26 + if (queryFromUrl) {
  27 + customSearchControl.execute(queryFromUrl);
  28 + }
  29 + }, true);
  30 +</script>
... ...
plugins/google_cse/views/search-box.rhtml 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +<script type="text/javascript">
  2 + jQuery(function($) {
  3 + $('<%= locals[:selector] %>')
  4 + .attr({class: "cse-search-box", action: "<%= GoogleCsePlugin.results_url_path %>"})
  5 + .append('<input type="hidden" name="cx" value="<%= locals[:plugin].google_id %>" /><input type="hidden" name="cof" value="FORID:10" /><input type="hidden" name="ie" value="UTF-8" /><input type="hidden" name="siteurl" value="<%= context.environment.default_hostname %>">')
  6 + .children("input[name='query']")
  7 + .attr('name', 'q')
  8 + .attr('id', 'q');
  9 + });
  10 +</script>
... ...
test/unit/application_helper_test.rb
... ... @@ -603,7 +603,7 @@ class ApplicationHelperTest &lt; Test::Unit::TestCase
603 603  
604 604 @controller = ApplicationController.new
605 605 path = File.join(RAILS_ROOT, 'app', 'views')
606   - @controller.stubs(:view_paths).returns(path)
  606 + @controller.stubs(:view_paths).returns([path])
607 607  
608 608 file = path + '/shared/usermenu/xmpp_chat.rhtml'
609 609 expects(:render).with(:file => file, :use_full_path => false).returns('Open chat')
... ...
test/unit/feed_reader_block_test.rb
... ... @@ -127,7 +127,7 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase
127 127 Time.stubs(:now).returns(now - 3.hours)
128 128 not_expired.finish_fetch
129 129  
130   - # now one block should be expired and the not the other
  130 + # now one block should be expired and not the other
131 131 Time.stubs(:now).returns(now)
132 132 expired_list = FeedReaderBlock.expired
133 133 assert_includes expired_list, expired
... ... @@ -156,6 +156,17 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase
156 156 assert_equal true, reader.enabled
157 157 end
158 158  
  159 + should 'be expired when address is updated' do
  160 + reader = build(:feed_reader_block, :address => 'http://www.example.com/feed')
  161 + reader.finish_fetch
  162 + expired_list = FeedReaderBlock.expired
  163 + assert_not_includes expired_list, reader
  164 + reader.address = "http://www.example.com/new-feed"
  165 + reader.save!
  166 + expired_list = FeedReaderBlock.expired
  167 + assert_includes expired_list, reader
  168 + end
  169 +
159 170 should 'be disabled when address is empty' do
160 171 reader = build(:feed_reader_block, :enabled => true, :address => 'http://www.example.com/feed')
161 172 reader.address = nil
... ... @@ -173,7 +184,7 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase
173 184 assert_equal true, reader.enabled, 'must enable when setting to new address'
174 185 end
175 186  
176   - should 'kepp enable when address is not changed' do
  187 + should 'keep enable when address is not changed' do
177 188 reader = build(:feed_reader_block, :address => 'http://www.example.com/feed')
178 189 reader.address = 'http://www.example.com/feed'
179 190 assert_equal true, reader.enabled
... ...