]> source.dussan.org Git - redmine.git/commitdiff
Merged r6098 from trunk.
authorJean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Mon, 20 Jun 2011 19:39:59 +0000 (19:39 +0000)
committerJean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Mon, 20 Jun 2011 19:39:59 +0000 (19:39 +0000)
Added Project#enable_module! and Project#disable_module!

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.2-stable@6104 e93f8b46-1217-0410-a6f0-8f06a7374b81

18 files changed:
app/models/attachment.rb
app/models/project.rb
app/models/setting.rb
lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb
lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb
lib/redmine/i18n.rb
lib/redmine/plugin.rb
lib/redmine/scm/adapters/abstract_adapter.rb
lib/redmine/version.rb
lib/redmine/views/my_page/block.rb
lib/tasks/extract_fixtures.rake
lib/tasks/initializers.rake
test/fixtures/repositories.yml
test/functional/application_controller_test.rb
test/functional/attachments_controller_test.rb
test/test_helper.rb
test/unit/lib/redmine/hook_test.rb
test/unit/project_test.rb

index ff434d8f21363b2c789cd3c48c57f06f30ffc0d9..92eb9157a45ed742f17cadbb3ed5dcc8e2ac07fd 100644 (file)
@@ -43,7 +43,7 @@ class Attachment < ActiveRecord::Base
                                                         "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
 
   cattr_accessor :storage_path
-  @@storage_path = Redmine::Configuration['attachments_storage_path'] || "#{RAILS_ROOT}/files"
+  @@storage_path = Redmine::Configuration['attachments_storage_path'] || "#{Rails.root}/files"
 
   def validate
     if self.filesize > Setting.attachment_max_size.to_i.kilobytes
index ab345be4fd7393415b92f9f2cbda9ce8d663fbdd..c9d00e9b78eed7d9001fe450bfc750a69c21ecf5 100644 (file)
@@ -544,7 +544,27 @@ class Project < ActiveRecord::Base
   def enabled_module_names
     enabled_modules.collect(&:name)
   end
-  
+
+  # Enable a specific module
+  #
+  # Examples:
+  #   project.enable_module!(:issue_tracking)
+  #   project.enable_module!("issue_tracking")
+  def enable_module!(name)
+    enabled_modules << EnabledModule.new(:name => name.to_s) unless module_enabled?(name)
+  end
+
+  # Disable a module if it exists
+  #
+  # Examples:
+  #   project.disable_module!(:issue_tracking)
+  #   project.disable_module!("issue_tracking")
+  #   project.disable_module!(project.enabled_modules.first)
+  def disable_module!(target)
+    target = enabled_modules.detect{|mod| target.to_s == mod.name} unless enabled_modules.include?(target)
+    target.destroy unless target.blank?
+  end
+
   safe_attributes 'name',
     'description',
     'homepage',
index 80e084e9c6b3a6be990e1b8045c500f95103a399..12b186fe84be17a63c10653cbd637157b1a07adf 100644 (file)
@@ -75,7 +75,7 @@ class Setting < ActiveRecord::Base
                   TIS-620)
 
   cattr_accessor :available_settings
-  @@available_settings = YAML::load(File.open("#{RAILS_ROOT}/config/settings.yml"))
+  @@available_settings = YAML::load(File.open("#{Rails.root}/config/settings.yml"))
   Redmine::Plugin.all.each do |plugin|
     next unless plugin.settings
     @@available_settings["plugin_#{plugin.id}"] = {'default' => plugin.settings[:default], 'serialized' => true}
index 7f3f3f68e164a1e144197602151ad3f033b00e18..24d3af8e422f986bd10919866d9d85e6cf91c185 100644 (file)
@@ -14,7 +14,7 @@ class RedminePluginControllerGenerator < ControllerGenerator
   end
   
   def destination_root
-    File.join(RAILS_ROOT, plugin_path)
+    File.join(Rails.root, plugin_path)
   end
   
   def manifest
index 1c34439aac30ecd77657132e20a0e0f58e002744..be231a91c7238c2c5f1a83215df3c9666ce06a80 100644 (file)
@@ -14,7 +14,7 @@ class RedminePluginModelGenerator < ModelGenerator
   end
   
   def destination_root
-    File.join(RAILS_ROOT, plugin_path)
+    File.join(Rails.root, plugin_path)
   end
   
   def manifest
index f0cc529b04c7e785bead0778a49a3603172be92b..29ff3281b32374652e479b87bf1f1f7399dffbb9 100644 (file)
@@ -56,11 +56,11 @@ module Redmine
     def month_name(month)
       ::I18n.t('date.month_names')[month]
     end
-    
+
     def valid_languages
-      @@valid_languages ||= Dir.glob(File.join(RAILS_ROOT, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
+      @@valid_languages ||= Dir.glob(File.join(Rails.root, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
     end
-    
+
     def find_language(lang)
       @@languages_lookup = valid_languages.inject({}) {|k, v| k[v.to_s.downcase] = v; k }
       @@languages_lookup[lang.to_s.downcase]
index f30277ad1da7b988be83f9fa61756bf3e0fb06fa..e4066a105baf2b9553f622a1a0d338bf63395dd1 100644 (file)
@@ -1,16 +1,16 @@
-# redMine - project management software
-# Copyright (C) 2006-2007  Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
 # of the License, or (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
@@ -69,7 +69,7 @@ module Redmine #:nodoc:
       p.name(id.to_s.humanize) if p.name.nil?
       # Adds plugin locales if any
       # YAML translation files should be found under <plugin>/config/locales/
-      ::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
+      ::I18n.load_path += Dir.glob(File.join(Rails.root, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
       registered_plugins[id] = p
     end
     
index bb0161152b3ed9c15a4d55cd78350feeb3ef52e0..6dc416064bb447614841d76f6cc412bf0ee8d0e0 100644 (file)
@@ -204,7 +204,7 @@ module Redmine
           end
           if Rails.env == 'development'
             # Capture stderr when running in dev environment
-            cmd = "#{cmd} 2>>#{RAILS_ROOT}/log/scm.stderr.log"
+            cmd = "#{cmd} 2>>#{Rails.root}/log/scm.stderr.log"
           end
           begin
             if RUBY_VERSION < '1.9'
index 2da94757d4357bcff38ce4e20f2affe82fda6f30..13c292f103a10a03677575ff04a18d05bb86528f 100644 (file)
@@ -14,7 +14,7 @@ module Redmine
 
     def self.revision
       revision = nil
-      entries_path = "#{RAILS_ROOT}/.svn/entries"
+      entries_path = "#{Rails.root}/.svn/entries"
       if File.readable?(entries_path)
         begin
           f = File.open(entries_path, 'r')
index b6ca29f97c348d9e56f0532664b2f6acd9aa6179..06f532ddeb61fdf2661b7e0ea672049674506b18 100644 (file)
@@ -1,16 +1,16 @@
 # Redmine - project management software
-# Copyright (C) 2006-2009  Jean-Philippe Lang
+# Copyright (C) 2006-2011  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
 # of the License, or (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
@@ -20,7 +20,7 @@ module Redmine
     module MyPage
       module Block
         def self.additional_blocks
-          @@additional_blocks ||= Dir.glob("#{RAILS_ROOT}/vendor/plugins/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
+          @@additional_blocks ||= Dir.glob("#{Rails.root}/vendor/plugins/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
             name = File.basename(file).split('.').first.gsub(/^_/, '')
             h[name] = name.to_sym
             h
index 604091ba3cdd0359e4f863f245027a7eeae6d67c..d2dbf091e6a107bda90c5bd63de79c29db4e60da 100644 (file)
@@ -7,7 +7,7 @@ task :extract_fixtures => :environment do
   ActiveRecord::Base.establish_connection\r
   (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|\r
     i = "000"\r
-    File.open("#{RAILS_ROOT}/#{table_name}.yml", 'w' ) do |file|\r
+    File.open("#{Rails.root}/#{table_name}.yml", 'w' ) do |file|\r
       data = ActiveRecord::Base.connection.select_all(sql % table_name)\r
       file.write data.inject({}) { |hash, record|\r
         # cast extracted values\r
@@ -19,4 +19,5 @@ task :extract_fixtures => :environment do
       }.to_yaml\r
     end\r
   end\r
-end\r
+end
+
index 3d4a402057c8c1ccc78b853b58e9afecb662dc32..fa20f09b5810a2a1230fecd15f90a6c42fb25f71 100644 (file)
@@ -1,7 +1,7 @@
 desc 'Generates a configuration file for cookie store sessions.'
 
 file 'config/initializers/session_store.rb' do
-  path = File.join(RAILS_ROOT, 'config', 'initializers', 'session_store.rb')
+  path = File.join(Rails.root, 'config', 'initializers', 'session_store.rb')
   secret = ActiveSupport::SecureRandom.hex(40)
   File.open(path, 'w') do |f|
     f.write <<"EOF"
index c55105897e5a9f06c043837d0b02e832ccf4022d..61930f395fbee59db045130fe61458da374cbf8a 100644 (file)
@@ -1,9 +1,9 @@
 --- 
 repositories_001: 
   project_id: 1
-  url: file:///<%= RAILS_ROOT.gsub(%r{config\/\.\.}, '') %>/tmp/test/subversion_repository
+  url: file:///<%= Rails.root %>/tmp/test/subversion_repository
   id: 10
-  root_url: file:///<%= RAILS_ROOT.gsub(%r{config\/\.\.}, '') %>/tmp/test/subversion_repository
+  root_url: file:///<%= Rails.root %>/tmp/test/subversion_repository
   password: ""
   login: ""
   type: Subversion
index 57f3e091cd25936d62c5a074da91a096dffebcf1..5cc7901f1aae04c156a21ec36e3f888e4caa6921 100644 (file)
@@ -32,7 +32,7 @@ class ApplicationControllerTest < ActionController::TestCase
 
   # check that all language files are valid
   def test_localization
-    lang_files_count = Dir["#{RAILS_ROOT}/config/locales/*.yml"].size
+    lang_files_count = Dir["#{Rails.root}/config/locales/*.yml"].size
     assert_equal lang_files_count, valid_languages.size
     valid_languages.each do |lang|
       assert set_language_if_valid(lang)
index e609299c0f7f3455aa8010cf01eecc7ff93b8b07..1f91da3b0d89314e43dfc0006b534ee2490c0862 100644 (file)
@@ -32,7 +32,7 @@ class AttachmentsControllerTest < ActionController::TestCase
     @controller = AttachmentsController.new
     @request    = ActionController::TestRequest.new
     @response   = ActionController::TestResponse.new
-    Attachment.storage_path = "#{RAILS_ROOT}/test/fixtures/files"
+    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
     User.current = nil
   end
 
index e8474de155071cd6e3dd64498063e03553c63f3f..51eaae13e3cee9418d8c9d5e610e225e712d2f3a 100644 (file)
@@ -78,11 +78,13 @@ class ActiveSupport::TestCase
 
   # Use a temporary directory for attachment related tests
   def set_tmp_attachments_directory
-    Dir.mkdir "#{RAILS_ROOT}/tmp/test" unless File.directory?("#{RAILS_ROOT}/tmp/test")
-    Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
-    Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
+    Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
+    unless File.directory?("#{Rails.root}/tmp/test/attachments")
+      Dir.mkdir "#{Rails.root}/tmp/test/attachments"
+    end
+    Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
   end
-  
+
   def with_settings(options, &block)
     saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h}
     options.each {|k, v| Setting[k] = v}
index 82f507f23a2d1a542d41af55c7327636e431fd9f..14782683a50b3b660d0c92e53c246cca419f3309 100644 (file)
@@ -1,16 +1,16 @@
-# redMine - project management software
-# Copyright (C) 2006-2008  Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
 # of the License, or (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
@@ -20,10 +20,10 @@ require File.expand_path('../../../../test_helper', __FILE__)
 class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
 
   fixtures :issues
-  
+
   # Some hooks that are manually registered in these tests
   class TestHook < Redmine::Hook::ViewListener; end
-  
+
   class TestHook1 < TestHook
     def view_layouts_base_html_head(context)
       'Test hook 1 listener.'
@@ -35,13 +35,13 @@ class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
       'Test hook 2 listener.'
     end
   end
-  
+
   class TestHook3 < TestHook
     def view_layouts_base_html_head(context)
       "Context keys: #{context.keys.collect(&:to_s).sort.join(', ')}."
     end
   end
-  
+
   class TestLinkToHook < TestHook
     def view_layouts_base_html_head(context)
       link_to('Issues', :controller => 'issues')
@@ -51,54 +51,54 @@ class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
   class TestHookHelperController < ActionController::Base
     include Redmine::Hook::Helper
   end
-  
+
   class TestHookHelperView < ActionView::Base
     include Redmine::Hook::Helper
   end
-  
+
   Redmine::Hook.clear_listeners
-  
+
   def setup
     @hook_module = Redmine::Hook
   end
-  
+
   def teardown
     @hook_module.clear_listeners
   end
-  
+
   def test_clear_listeners
     assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
     @hook_module.add_listener(TestHook1)
     @hook_module.add_listener(TestHook2)
     assert_equal 2, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-    
+
     @hook_module.clear_listeners
     assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
   end
-  
+
   def test_add_listener
     assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
     @hook_module.add_listener(TestHook1)
     assert_equal 1, @hook_module.hook_listeners(:view_layouts_base_html_head).size
   end
-  
+
   def test_call_hook
     @hook_module.add_listener(TestHook1)
     assert_equal ['Test hook 1 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
   end
-  
+
   def test_call_hook_with_context
     @hook_module.add_listener(TestHook3)
     assert_equal ['Context keys: bar, controller, foo, project, request.'],
                  hook_helper.call_hook(:view_layouts_base_html_head, :foo => 1, :bar => 'a')
   end
-  
+
   def test_call_hook_with_multiple_listeners
     @hook_module.add_listener(TestHook1)
     @hook_module.add_listener(TestHook2)
     assert_equal ['Test hook 1 listener.', 'Test hook 2 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
   end
-  
+
   # Context: Redmine::Hook::Helper.call_hook default_url
   def test_call_hook_default_url_options
     @hook_module.add_listener(TestLinkToHook)
@@ -111,27 +111,27 @@ class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
     @hook_module.add_listener(TestHook3)
     assert_match /project/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
   end
-  
+
   def test_call_hook_from_controller_with_controller_added_to_context
     @hook_module.add_listener(TestHook3)
     assert_match /controller/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
   end
-    
+
   def test_call_hook_from_controller_with_request_added_to_context
     @hook_module.add_listener(TestHook3)
     assert_match /request/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
   end
-    
+
   def test_call_hook_from_view_with_project_added_to_context
     @hook_module.add_listener(TestHook3)
     assert_match /project/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
   end
-    
+
   def test_call_hook_from_view_with_controller_added_to_context
     @hook_module.add_listener(TestHook3)
     assert_match /controller/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
   end
-    
+
   def test_call_hook_from_view_with_request_added_to_context
     @hook_module.add_listener(TestHook3)
     assert_match /request/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
@@ -146,27 +146,27 @@ class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
 
   def test_call_hook_should_not_change_the_default_url_for_email_notifications
     issue = Issue.find(1)
+
     ActionMailer::Base.deliveries.clear
     Mailer.deliver_issue_add(issue)
     mail = ActionMailer::Base.deliveries.last
+
     @hook_module.add_listener(TestLinkToHook)
     hook_helper.call_hook(:view_layouts_base_html_head)
+
     ActionMailer::Base.deliveries.clear
     Mailer.deliver_issue_add(issue)
     mail2 = ActionMailer::Base.deliveries.last
+
     assert_equal mail.body, mail2.body
   end
-  
+
   def hook_helper
     @hook_helper ||= TestHookHelperController.new
   end
 
   def view_hook_helper
-    @view_hook_helper ||= TestHookHelperView.new(RAILS_ROOT + '/app/views')
+    @view_hook_helper ||= TestHookHelperView.new(Rails.root.to_s + '/app/views')
   end
 end
 
index d307500e3bc9ce3598ea9fac9e950f170fc66ae8..1fe6f15067610444738f27fd27967b08aa9c9c34 100644 (file)
@@ -597,6 +597,54 @@ class ProjectTest < ActiveSupport::TestCase
     end
   end
 
+  context "enabled_modules" do
+    setup do
+      @project = Project.find(1)
+    end
+
+    should "define module by names and preserve ids" do
+      # Remove one module
+      modules = @project.enabled_modules.slice(0..-2)
+      assert modules.any?
+      assert_difference 'EnabledModule.count', -1 do
+        @project.enabled_module_names = modules.collect(&:name)
+      end
+      @project.reload
+      # Ids should be preserved
+      assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
+    end
+
+    should "enable a module" do
+      @project.enabled_module_names = []
+      @project.reload
+      assert_equal [], @project.enabled_module_names
+      #with string
+      @project.enable_module!("issue_tracking")
+      assert_equal ["issue_tracking"], @project.enabled_module_names
+      #with symbol
+      @project.enable_module!(:gantt)
+      assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+      #don't add a module twice
+      @project.enable_module!("issue_tracking")
+      assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+    end
+
+    should "disable a module" do
+      #with string
+      assert @project.enabled_module_names.include?("issue_tracking")
+      @project.disable_module!("issue_tracking")
+      assert ! @project.reload.enabled_module_names.include?("issue_tracking")
+      #with symbol
+      assert @project.enabled_module_names.include?("gantt")
+      @project.disable_module!(:gantt)
+      assert ! @project.reload.enabled_module_names.include?("gantt")
+      #with EnabledModule object
+      first_module = @project.enabled_modules.first
+      @project.disable_module!(first_module)
+      assert ! @project.reload.enabled_module_names.include?(first_module.name)
+    end
+  end
+
   def test_enabled_module_names_should_not_recreate_enabled_modules
     project = Project.find(1)
     # Remove one module