diff --git a/README.rdoc b/README.rdoc index 8634ab7..7601277 100755 --- a/README.rdoc +++ b/README.rdoc @@ -1,4 +1,6 @@ = impasse -Impasse is test management tool like Testlink. +Impasse is a test management tool like Testlink. +* {Administration guide}[http://kawasima.github.com/redmine_impasse/administration_guide.html] +* {User manual}[http://kawasima.github.com/redmine_impasse/user_manual.html] diff --git a/app/controllers/impasse_custom_fields_controller.rb b/app/controllers/impasse_custom_fields_controller.rb index 9668fb8..cb50255 100644 --- a/app/controllers/impasse_custom_fields_controller.rb +++ b/app/controllers/impasse_custom_fields_controller.rb @@ -8,7 +8,7 @@ class ImpasseCustomFieldsController < ImpasseAbstractController def index @custom_fields_by_type = CustomField.find(:all).group_by {|f| f.class.name } - @tab = params[:tab] || 'Impasse::TestCaseCustomField' + @tab = params[:tab] || 'Impasse-TestCaseCustomField' end def new @@ -22,7 +22,7 @@ def new if request.post? and @custom_field.save flash[:notice] = l(:notice_successful_create) call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field) - redirect_to :action => 'index', :tab => @custom_field.class.name + redirect_to :action => 'index', :tab => @custom_field.class.name.gsub("::","-") else @trackers = Tracker.find(:all, :order => 'position') end diff --git a/app/controllers/impasse_execution_bugs_controller.rb b/app/controllers/impasse_execution_bugs_controller.rb index 045e626..c73d9ca 100644 --- a/app/controllers/impasse_execution_bugs_controller.rb +++ b/app/controllers/impasse_execution_bugs_controller.rb @@ -27,7 +27,11 @@ class ImpasseExecutionBugsController < ImpasseAbstractController def new setting = Impasse::Setting.find_or_create_by_project_id(@project) - @issue.tracker_id = setting.bug_tracker_id unless setting.bug_tracker_id.nil? + unless setting.bug_tracker_id.nil? + unless @project.trackers.find_by_id(setting.bug_tracker_id).nil? + @issue.tracker_id = setting.bug_tracker_id + end + end respond_to do |format| format.html { render :partial => 'new' } @@ -40,7 +44,7 @@ def create if @issue.save execution_bug = Impasse::ExecutionBug.new(:execution_id => params[:execution_bug][:execution_id], :bug_id => @issue.id) execution_bug.save! - + flash[:notice] = l(:notice_successful_create) respond_to do |format| format.json { render :json => { :status => 'success', :issue_id => @issue.id } } @@ -78,6 +82,11 @@ def build_new_issue_from_params if params[:issue].is_a?(Hash) @issue.safe_attributes = params[:issue] + if Redmine::VERSION::MAJOR == 1 and Redmine::VERSION::MINOR < 4 + if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record? + @issue.watcher_user_ids = params[:issue]['watcher_user_ids'] + end + end end @issue.start_date ||= Date.today @issue.author = User.current diff --git a/app/controllers/impasse_test_case_controller.rb b/app/controllers/impasse_test_case_controller.rb index 8bf2432..09668f8 100644 --- a/app/controllers/impasse_test_case_controller.rb +++ b/app/controllers/impasse_test_case_controller.rb @@ -47,7 +47,7 @@ def new begin ActiveRecord::Base.transaction do @node.save! - save_keywords(@node, params[:node_keywords]) + @node.save_keywords!(params[:node_keywords]) @test_case.id = @node.id if @node.is_test_case? and params.include? :test_steps @test_steps = params[:test_steps].collect{|i, ts| Impasse::TestStep.new(ts) } @@ -111,8 +111,8 @@ def edit begin ActiveRecord::Base.transaction do save_node(@node) + @node.save_keywords!(params[:node_keywords]) @test_case.save! - save_keywords(@node, params[:node_keywords]) if @node.is_test_case? and params.include? :test_steps @test_steps = params[:test_steps].collect{|i, ts| Impasse::TestStep.new(ts) } @@ -244,7 +244,7 @@ def copy_to_another_project new_test_case.save! test_case.test_steps.each do |ts| attr = ts.attributes - attr[:test_case_id] = new_test_case._id + attr[:test_case_id] = new_test_case.id Impasse::TestStep.create!(attr) end end @@ -254,7 +254,8 @@ def copy_to_another_project end flash[:notice] = l(:notice_successful_create) redirect_to :action => :index, :project_id => dest_project - rescue + rescue => ex + logger.error(ex.message + "\n" + ex.backtrace.join("\n")) flash[:error] = l(:error_failed_to_update) redirect_to :action => :index, :project_id => @project end @@ -298,34 +299,6 @@ def save_node(node) node.update_child_nodes_path(old_node.path) end - def save_keywords(node, keywords = "") - project_keywords = Impasse::Keyword.find_all_by_project_id(@project) - words = keywords.split(/\s*,\s*/) - words.delete_if {|word| word =~ /^\s*$/}.uniq! - - node_keywords = node.node_keywords - keeps = [] - words.each{|word| - keyword = project_keywords.detect {|k| k.keyword == word} - if keyword - node_keyword = node_keywords.detect {|nk| nk.keyword_id == keyword.id} - if node_keyword - keeps << node_keyword.id - else - new_node_keyword = Impasse::NodeKeyword.create(:keyword_id => keyword.id, :node_id => node.id) - keeps << new_node_keyword.id - end - else - new_keyword = Impasse::Keyword.create(:keyword => word, :project_id => @project.id) - new_node_keyword = Impasse::NodeKeyword.create(:keyword_id => new_keyword.id, :node_id => node.id) - keeps << new_node_keyword.id - end - } - node_keywords.each{|node_keyword| - node_keyword.destroy unless keeps.include? node_keyword.id - } - end - def get_root_name(test_plan_id) if test_plan_id.nil? @project.name diff --git a/app/helpers/impasse_settings_helper.rb b/app/helpers/impasse_settings_helper.rb index 1b3a8b1..0e7458a 100644 --- a/app/helpers/impasse_settings_helper.rb +++ b/app/helpers/impasse_settings_helper.rb @@ -2,10 +2,10 @@ module ImpasseSettingsHelper def impasse_custom_fields_tabs [ - {:name => 'Impasse::TestCaseCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_case_plural}, - {:name => 'Impasse::TestSuiteCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_suite_plural}, - {:name => 'Impasse::TestPlanCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_plan_plural}, - {:name => 'Impasse::ExecutionCustomField', :partial => 'impasse_custom_fields/index', :label => :label_execution_plural}, + {:name => 'Impasse-TestCaseCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_case_plural}, + {:name => 'Impasse-TestSuiteCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_suite_plural}, + {:name => 'Impasse-TestPlanCustomField', :partial => 'impasse_custom_fields/index', :label => :label_test_plan_plural}, + {:name => 'Impasse-ExecutionCustomField', :partial => 'impasse_custom_fields/index', :label => :label_execution_plural}, ] end end diff --git a/app/models/impasse/node.rb b/app/models/impasse/node.rb index 8aa3692..bc5f511 100755 --- a/app/models/impasse/node.rb +++ b/app/models/impasse/node.rb @@ -294,6 +294,37 @@ def update_child_nodes_path(old_path) connection.update(sql) end + def save_keywords!(keywords = "") + root_node = Impasse::Node.find(self.path.sub(/^\.(\d+)\.[\d\.]*$/, '\1').to_i) + project = Project.find(root_node.name) + project_keywords = Impasse::Keyword.find_all_by_project_id(project) + words = keywords.split(/\s*,\s*/) + words.delete_if {|word| word =~ /^\s*$/}.uniq! + + node_keywords = self.node_keywords + keeps = [] + words.each do |word| + keyword = project_keywords.detect {|k| k.keyword == word} + if keyword + node_keyword = node_keywords.detect {|nk| nk.keyword_id == keyword.id} + if node_keyword + keeps << node_keyword.id + else + new_node_keyword = Impasse::NodeKeyword.create(:keyword_id => keyword.id, :node_id => self.id) + keeps << new_node_keyword.id + end + else + new_keyword = Impasse::Keyword.create(:keyword => word, :project_id => project.id) + new_node_keyword = Impasse::NodeKeyword.create(:keyword_id => new_keyword.id, :node_id => self.id) + keeps << new_node_keyword.id + end + end + + node_keywords.each do |node_keyword| + node_keyword.destroy unless keeps.include? node_keyword.id + end + end + private def recalculate_path if parent.nil? diff --git a/app/models/impasse/test_plan.rb b/app/models/impasse/test_plan.rb index 91dfae8..f269775 100755 --- a/app/models/impasse/test_plan.rb +++ b/app/models/impasse/test_plan.rb @@ -10,6 +10,7 @@ class TestPlan < ActiveRecord::Base validates_presence_of :name validates_length_of :name, :maximum => 100 + validates_presence_of :version acts_as_customizable diff --git a/app/views/impasse_custom_fields/_index.html.erb b/app/views/impasse_custom_fields/_index.html.erb index 5c8a257..db900d1 100644 --- a/app/views/impasse_custom_fields/_index.html.erb +++ b/app/views/impasse_custom_fields/_index.html.erb @@ -11,7 +11,7 @@
<%= link_to l(:label_custom_field_new), { :controller => :impasse_custom_fields, :action => :new, :type => tab[:name] }, :class => 'icon icon-add' %>
+<%= link_to l(:label_custom_field_new), { :controller => :impasse_custom_fields, :action => :new, :type => tab[:name].gsub("-","::") }, :class => 'icon icon-add' %>
diff --git a/app/views/impasse_execution_bugs/_form.html.erb b/app/views/impasse_execution_bugs/_form.html.erb index b351403..8aa85b5 100644 --- a/app/views/impasse_execution_bugs/_form.html.erb +++ b/app/views/impasse_execution_bugs/_form.html.erb @@ -33,3 +33,24 @@+ + <%= watchers_checkboxes(@issue, @available_watchers) %> + + + <%= link_to l(:label_search_for_watchers), + {:controller => 'watchers', :action => 'new', :project_id => @issue.project}, + :remote => true, + :method => 'get' %> + +
+<% elsif Redmine::VERSION::MAJOR == 1 and Redmine::VERSION::MINOR < 4 %> +<% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%> ++<% @issue.project.users.sort.each do |user| -%> + +<% end -%> +
+<% end %> +<% end %> \ No newline at end of file diff --git a/app/views/impasse_settings/_form.html.erb b/app/views/impasse_settings/_form.html.erb index 6827d1b..822e471 100644 --- a/app/views/impasse_settings/_form.html.erb +++ b/app/views/impasse_settings/_form.html.erb @@ -1,3 +1,4 @@ +<% self.class.send(:include, ImpasseSettingsHelper) -%> <%= error_messages_for 'setting' %><%=f.select :bug_tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %>
diff --git a/app/views/impasse_test_case/index.html.erb b/app/views/impasse_test_case/index.html.erb index 1ba1df8..5d6c487 100644 --- a/app/views/impasse_test_case/index.html.erb +++ b/app/views/impasse_test_case/index.html.erb @@ -96,14 +96,14 @@ <% if @allowed_projects.present? %><%=l(:notice_copy_cases_to_another_project)%>
<% if Rails::VERSION::MAJOR < 3 %> - <% labelled_tabular_form_for :copy_tests, @project, { :action => :copy_to_another_project } do |f| %> + <% labelled_tabular_form_for :copy_tests, @project, { :html => { :id => "edit_copy_tests" }, :url => { :action => :copy_to_another_project } } do |f| %><%= select_tag('dest_project_id', project_tree_options_for_select(@allowed_projects, :selected => @target_project)) %>
<% end %> <% else %> - <% output = labelled_tabular_form_for @project, :as => :copy_tests, :url => { :action => :copy_to_another_project } do |f| %> + <% output = labelled_form_for @project, :as => :copy_tests, :html => { :id => "edit_copy_tests" }, :url => { :action => :copy_to_another_project } do |f| %><%= select_tag('dest_project_id', project_tree_options_for_select(@allowed_projects, :selected => @target_project)) %> diff --git a/app/views/impasse_test_plans/_form.html.erb b/app/views/impasse_test_plans/_form.html.erb index aff91fc..dceffab 100644 --- a/app/views/impasse_test_plans/_form.html.erb +++ b/app/views/impasse_test_plans/_form.html.erb @@ -5,7 +5,7 @@
<%= form.text_area :notes, :rows => 10, :class => 'wiki-edit' %>
<%= wikitoolbar_for 'test_plan_notes' %> -<%= form.select :version_id, @versions.collect{|v| [v.name, v.id]}, {:include_blank => false}, :required=>true%>
+<%= form.select :version_id, @versions.collect{|v| [v.name, v.id]}, {:include_blank => false, :required => true} %>
<% @test_plan.custom_field_values.each do |value| %><%= custom_field_tag_with_label :test_plan, value %>
<% end %> diff --git a/assets/javascripts/executions.js b/assets/javascripts/executions.js index 8c881cc..ae3bdb8 100644 --- a/assets/javascripts/executions.js +++ b/assets/javascripts/executions.js @@ -8,16 +8,20 @@ jQuery(document).ready(function ($) { "test_plan_case[test_plan_id]": test_plan_id, "test_plan_case[test_case_id]": node_id }, - success: function(html) { - $("#executions-view").html($(html)); - $("span.label", $("#executions-view")) - .css({cursor:'pointer'}) - .click(function(e) { - $(this).prev().attr("checked", "checked"); - }); - $("#executions-view .screenshots").tinycarousel(); - - }, + success: function(html) { + var winHeight = $(window).height(); + var $executionsView = $("#executions-view"); + $executionsView.css({height:'', overflow:''}).html(html); + $("span.label", $executionsView) + .css({cursor:'pointer'}) + .click(function(e) { + $(this).prev().attr("checked", "checked"); + }); + $(".screenshots", $executionsView).tinycarousel(); + if ($executionsView.height() > winHeight) { + $executionsView.height(winHeight - 1).css('overflow', 'scroll'); + } + }, error: ajax_error_handler, complete: function() { $("#executions-view").unblock(); } }); diff --git a/assets/javascripts/test_case_tree.js b/assets/javascripts/test_case_tree.js index 29407af..b9e8bd3 100644 --- a/assets/javascripts/test_case_tree.js +++ b/assets/javascripts/test_case_tree.js @@ -87,10 +87,15 @@ jQuery(document).ready(function ($) { $.ajax({ url: IMPASSE.url.testCaseShow, data: { "node[id]": node_id }, - success: function(html) { - $("#test-case-view").html(html).show(); - $("#test-case-view .screenshots").tinycarousel(); - }, + success: function(html) { + var winHeight = $(window).height(); + var $testCaseView = $("#test-case-view"); + $testCaseView.css({height:'', overflow:''}).html(html).show(); + $(".screenshots", $testCaseView).tinycarousel(); + if ($testCaseView.height() > winHeight) { + $testCaseView.height(winHeight - 1).css('overflow', 'scroll'); + } + }, error: ajax_error_handler, complete: function() { $("#test-case-view").unblock(); @@ -129,6 +134,65 @@ jQuery(document).ready(function ($) { } }); } + var updateTestCase = function(data, edit_type) { + var node = $(data.rslt.obj); + var node_type = node.attr("rel"); + return function(e) { + var ajaxOptions = { + type: 'POST', + url:AJAX_URL[edit_type], + success: function(r, status, xhr) { + if (r.errors) { + var ul = $("