">
| <%= link_to ver.version, :action => 'show', :id => @page.title, :project_id => @page.project, :version => ver.version %> |
<%= radio_button_tag('version', ver.version, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < @versions.size) %> |
<%= radio_button_tag('version_from', ver.version, (line_num==2), :id => "cbto-#{line_num}") if show_diff && (line_num > 1) %> |
- <%= format_time(ver.updated_on) %> |
- <%= link_to_user ver.author %> |
- <%=h ver.comments %> |
- <%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %> |
+ <%= format_time(ver.updated_on) %> |
+ <%= link_to_user ver.author %> |
+
+ <%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %> |
<% line_num += 1 %>
<% end %>
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 486623459..1679d83d9 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -232,6 +232,24 @@ function observeRelatedIssueField(url) {
});
}
+function setVisible(id, visible) {
+ var el = $(id);
+ if (el) {if (visible) {el.show();} else {el.hide();}}
+}
+
+function observeProjectModules() {
+ var f = function() {
+ /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
+ var c = ($('project_enabled_module_names_issue_tracking').checked == true);
+ setVisible('project_trackers', c);
+ setVisible('project_issue_custom_fields', c);
+ };
+
+ Event.observe(window, 'load', f);
+ Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
+}
+
+
/* shows and hides ajax indicator */
Ajax.Responders.register({
onCreate: function(){
diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
index feddfcb4d..a2918abe2 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -179,6 +179,8 @@ tr.user td { white-space: nowrap; }
tr.user.locked, tr.user.registered { color: #aaa; }
tr.user.locked a, tr.user.registered a { color: #aaa; }
+tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
+
tr.time-entry { text-align: center; white-space: nowrap; }
tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml
index f63203ae3..979cc3211 100644
--- a/test/fixtures/roles.yml
+++ b/test/fixtures/roles.yml
@@ -7,6 +7,7 @@ roles_001:
---
- :add_project
- :edit_project
+ - :select_project_modules
- :manage_members
- :manage_versions
- :manage_categories
diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb
index aaf6e3085..fefb8d53b 100644
--- a/test/functional/projects_controller_test.rb
+++ b/test/functional/projects_controller_test.rb
@@ -154,7 +154,8 @@ class ProjectsControllerTest < ActionController::TestCase
:custom_field_values => { '3' => 'Beta' },
:tracker_ids => ['1', '3'],
# an issue custom field that is not for all project
- :issue_custom_field_ids => ['9']
+ :issue_custom_field_ids => ['9'],
+ :enabled_module_names => ['issue_tracking', 'news', 'repository']
}
assert_redirected_to '/projects/blog/settings'
@@ -167,6 +168,7 @@ class ProjectsControllerTest < ActionController::TestCase
assert_nil project.parent
assert_equal 'Beta', project.custom_value_for(3).value
assert_equal [1, 3], project.trackers.map(&:id).sort
+ assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
assert project.issue_custom_fields.include?(IssueCustomField.find(9))
end
@@ -197,7 +199,9 @@ class ProjectsControllerTest < ActionController::TestCase
:description => "weblog",
:identifier => "blog",
:is_public => 1,
- :custom_field_values => { '3' => 'Beta' }
+ :custom_field_values => { '3' => 'Beta' },
+ :tracker_ids => ['1', '3'],
+ :enabled_module_names => ['issue_tracking', 'news', 'repository']
}
assert_redirected_to '/projects/blog/settings'
@@ -206,6 +210,8 @@ class ProjectsControllerTest < ActionController::TestCase
assert_kind_of Project, project
assert_equal 'weblog', project.description
assert_equal true, project.is_public?
+ assert_equal [1, 3], project.trackers.map(&:id).sort
+ assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
# User should be added as a project member
assert User.find(9).member_of?(project)
@@ -282,6 +288,12 @@ class ProjectsControllerTest < ActionController::TestCase
end
end
+ def test_create_should_not_accept_get
+ @request.session[:user_id] = 1
+ get :create
+ assert_response :method_not_allowed
+ end
+
def test_show_by_id
get :show, :id => 1
assert_response :success
@@ -359,6 +371,21 @@ class ProjectsControllerTest < ActionController::TestCase
project = Project.find(1)
assert_equal 'Test changed name', project.name
end
+
+ def test_modules
+ @request.session[:user_id] = 2
+ Project.find(1).enabled_module_names = ['issue_tracking', 'news']
+
+ post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
+ assert_redirected_to '/projects/ecookbook/settings/modules'
+ assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
+ end
+
+ def test_modules_should_not_allow_get
+ @request.session[:user_id] = 1
+ get :modules, :id => 1
+ assert_response :method_not_allowed
+ end
def test_get_destroy
@request.session[:user_id] = 1 # admin
diff --git a/test/integration/api_test/projects_test.rb b/test/integration/api_test/projects_test.rb
index e40d6584a..6258aae89 100644
--- a/test/integration/api_test/projects_test.rb
+++ b/test/integration/api_test/projects_test.rb
@@ -122,12 +122,35 @@ class ApiTest::ProjectsTest < ActionController::IntegrationTest
project = Project.first(:order => 'id DESC')
assert_equal 'API test', project.name
assert_equal 'api-test', project.identifier
- assert_equal ['issue_tracking', 'repository'], project.enabled_module_names
+ assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
+ assert_equal Tracker.all.size, project.trackers.size
assert_response :created
assert_equal 'application/xml', @response.content_type
assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
end
+
+ should "accept enabled_module_names attribute" do
+ @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
+
+ assert_difference('Project.count') do
+ post '/projects.xml', @parameters, :authorization => credentials('admin')
+ end
+
+ project = Project.first(:order => 'id DESC')
+ assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
+ end
+
+ should "accept tracker_ids attribute" do
+ @parameters[:project].merge!({:tracker_ids => [1, 3]})
+
+ assert_difference('Project.count') do
+ post '/projects.xml', @parameters, :authorization => credentials('admin')
+ end
+
+ project = Project.first(:order => 'id DESC')
+ assert_equal [1, 3], project.trackers.map(&:id).sort
+ end
end
end
@@ -171,6 +194,28 @@ class ApiTest::ProjectsTest < ActionController::IntegrationTest
project = Project.find(2)
assert_equal 'API update', project.name
end
+
+ should "accept enabled_module_names attribute" do
+ @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
+
+ assert_no_difference 'Project.count' do
+ put '/projects/2.xml', @parameters, :authorization => credentials('admin')
+ end
+ assert_response :ok
+ project = Project.find(2)
+ assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
+ end
+
+ should "accept tracker_ids attribute" do
+ @parameters[:project].merge!({:tracker_ids => [1, 3]})
+
+ assert_no_difference 'Project.count' do
+ put '/projects/2.xml', @parameters, :authorization => credentials('admin')
+ end
+ assert_response :ok
+ project = Project.find(2)
+ assert_equal [1, 3], project.trackers.map(&:id).sort
+ end
end
end
diff --git a/test/unit/project_nested_set_test.rb b/test/unit/project_nested_set_test.rb
index d6bc528a9..9e9666529 100644
--- a/test/unit/project_nested_set_test.rb
+++ b/test/unit/project_nested_set_test.rb
@@ -19,40 +19,100 @@ require File.expand_path('../../test_helper', __FILE__)
class ProjectNestedSetTest < ActiveSupport::TestCase
- def setup
- Project.delete_all
- end
-
- def test_destroy_root_and_chldren_should_not_mess_up_the_tree
- a = Project.create!(:name => 'Project A', :identifier => 'projecta')
- a1 = Project.create!(:name => 'Project A1', :identifier => 'projecta1')
- a2 = Project.create!(:name => 'Project A2', :identifier => 'projecta2')
- a1.set_parent!(a)
- a2.set_parent!(a)
- b = Project.create!(:name => 'Project B', :identifier => 'projectb')
- b1 = Project.create!(:name => 'Project B1', :identifier => 'projectb1')
- b1.set_parent!(b)
-
- a.reload
- a1.reload
- a2.reload
- b.reload
- b1.reload
-
- assert_equal [nil, 1, 6], [a.parent_id, a.lft, a.rgt]
- assert_equal [a.id, 2, 3], [a1.parent_id, a1.lft, a1.rgt]
- assert_equal [a.id, 4, 5], [a2.parent_id, a2.lft, a2.rgt]
- assert_equal [nil, 7, 10], [b.parent_id, b.lft, b.rgt]
- assert_equal [b.id, 8, 9], [b1.parent_id, b1.lft, b1.rgt]
-
- assert_difference 'Project.count', -3 do
- a.destroy
+ context "nested set" do
+ setup do
+ Project.delete_all
+
+ @a = Project.create!(:name => 'Project A', :identifier => 'projecta')
+ @a1 = Project.create!(:name => 'Project A1', :identifier => 'projecta1')
+ @a1.set_parent!(@a)
+ @a2 = Project.create!(:name => 'Project A2', :identifier => 'projecta2')
+ @a2.set_parent!(@a)
+
+ @b = Project.create!(:name => 'Project B', :identifier => 'projectb')
+ @b1 = Project.create!(:name => 'Project B1', :identifier => 'projectb1')
+ @b1.set_parent!(@b)
+ @b11 = Project.create!(:name => 'Project B11', :identifier => 'projectb11')
+ @b11.set_parent!(@b1)
+ @b2 = Project.create!(:name => 'Project B2', :identifier => 'projectb2')
+ @b2.set_parent!(@b)
+
+ @c = Project.create!(:name => 'Project C', :identifier => 'projectc')
+ @c1 = Project.create!(:name => 'Project C1', :identifier => 'projectc1')
+ @c1.set_parent!(@c)
+
+ [@a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1].each(&:reload)
end
- b.reload
- b1.reload
-
- assert_equal [nil, 1, 4], [b.parent_id, b.lft, b.rgt]
- assert_equal [b.id, 2, 3], [b1.parent_id, b1.lft, b1.rgt]
+ context "#create" do
+ should "build valid tree" do
+ assert_nested_set_values({
+ @a => [nil, 1, 6],
+ @a1 => [@a.id, 2, 3],
+ @a2 => [@a.id, 4, 5],
+ @b => [nil, 7, 14],
+ @b1 => [@b.id, 8, 11],
+ @b11 => [@b1.id,9, 10],
+ @b2 => [@b.id,12, 13],
+ @c => [nil, 15, 18],
+ @c1 => [@c.id,16, 17]
+ })
+ end
+ end
+
+ context "#set_parent!" do
+ should "keep valid tree" do
+ assert_no_difference 'Project.count' do
+ Project.find_by_name('Project B1').set_parent!(Project.find_by_name('Project A2'))
+ end
+ assert_nested_set_values({
+ @a => [nil, 1, 10],
+ @a2 => [@a.id, 4, 9],
+ @b1 => [@a2.id,5, 8],
+ @b11 => [@b1.id,6, 7],
+ @b => [nil, 11, 14],
+ @c => [nil, 15, 18]
+ })
+ end
+ end
+
+ context "#destroy" do
+ context "a root with children" do
+ should "not mess up the tree" do
+ assert_difference 'Project.count', -4 do
+ Project.find_by_name('Project B').destroy
+ end
+ assert_nested_set_values({
+ @a => [nil, 1, 6],
+ @a1 => [@a.id, 2, 3],
+ @a2 => [@a.id, 4, 5],
+ @c => [nil, 7, 10],
+ @c1 => [@c.id, 8, 9]
+ })
+ end
+ end
+
+ context "a child with children" do
+ should "not mess up the tree" do
+ assert_difference 'Project.count', -2 do
+ Project.find_by_name('Project B1').destroy
+ end
+ assert_nested_set_values({
+ @a => [nil, 1, 6],
+ @b => [nil, 7, 10],
+ @b2 => [@b.id, 8, 9],
+ @c => [nil, 11, 14]
+ })
+ end
+ end
+ end
end
-end
\ No newline at end of file
+
+ def assert_nested_set_values(h)
+ assert Project.valid?
+ h.each do |project, expected|
+ project.reload
+ assert_equal expected, [project.parent_id, project.lft, project.rgt], "Unexpected nested set values for #{project.name}"
+ end
+ end
+end