diff --git a/app/views/stopwatch/_settings.html.erb b/app/views/stopwatch/_settings.html.erb new file mode 100644 index 0000000..873d442 --- /dev/null +++ b/app/views/stopwatch/_settings.html.erb @@ -0,0 +1,4 @@ +

+ + <%= select_tag 'settings[default_activity]', options_from_collection_for_select( [['always_ask', t('.label_always_ask')], ['system', t('.label_system')]] + TimeEntryActivity.system.active.to_a.pluck(:id, :name), :first, :last, Stopwatch.settings['default_activity'] ) %> +

diff --git a/init.rb b/init.rb index 7b68dd0..c634f6e 100644 --- a/init.rb +++ b/init.rb @@ -1,3 +1,4 @@ +require_dependency 'stopwatch' require 'stopwatch/hooks' Redmine::Plugin.register :stopwatch do @@ -8,6 +9,9 @@ Redmine::Plugin.register :stopwatch do version '0.1.0' requires_redmine version_or_higher: '3.4.0' + settings default: { + 'default_activity' => 'always_ask', + }, partial: 'stopwatch/settings' menu :account_menu, :stopwatch, :new_stopwatch_timer_path, diff --git a/lib/stopwatch.rb b/lib/stopwatch.rb index 0b14ec8..723e8f5 100644 --- a/lib/stopwatch.rb +++ b/lib/stopwatch.rb @@ -1,2 +1,36 @@ +# frozen_string_literal: true + module Stopwatch + def self.settings + Setting.plugin_stopwatch + end + + def self.default_activity + if id = settings['default_activity'].presence + if id.to_s =~ /^\d+$/ + TimeEntryActivity.find_by_id id + else + id + end + end + end + + def self.default_activity_for(time_entry) + default = Stopwatch.default_activity + return nil if default == 'always_ask' + + project = time_entry.project || time_entry.issue&.project + + if project.nil? + activities = TimeEntryActivity.shared.active + else + activities = project.activities + end + + if default == 'system' + activities.detect(&:is_default?) || activities.detect{|a| a.parent&.is_default?} || (activities.one? && activities[0]).presence + else + return activities.detect{ |a| a == default || a.parent == default } + end + end end diff --git a/test/unit/stopwatch_test.rb b/test/unit/stopwatch_test.rb new file mode 100644 index 0000000..78944c3 --- /dev/null +++ b/test/unit/stopwatch_test.rb @@ -0,0 +1,78 @@ +require_relative '../test_helper' + +class StopwatchTest < ActiveSupport::TestCase + fixtures :projects, :enabled_modules, :enumerations + + setup do + @project = Project.find 'ecookbook' + @te = TimeEntry.new project: @project + end + + test "default value for default_activity" do + assert_equal 'always_ask', Stopwatch.default_activity + end + + test "should find default activity" do + with_settings plugin_stopwatch: { 'default_activity' => 9} do + assert_equal 'Design', Stopwatch.default_activity.name + end + with_settings plugin_stopwatch: { 'default_activity' => '11'} do + assert_equal 'QA', Stopwatch.default_activity.name + end + end + + ### 'system' -> ask if there is no sys default / more than one availabale activity + + test "should use system default activity for te" do + with_settings plugin_stopwatch: { 'default_activity' => 'system' } do + assert_equal 'Development', Stopwatch.default_activity_for(@te).name + end + end + + test "should use single active project activity for time entry" do + with_settings plugin_stopwatch: { 'default_activity' => 'system' } do + TimeEntryActivity.create! active: false, project: @project, name: 'Development', parent_id: 10 + TimeEntryActivity.create! active: false, project: @project, name: 'QA', parent_id: 11 + assert_equal 'Design', Stopwatch.default_activity_for(@te).name + end + end + + test "should ask if more than one and no default" do + with_settings plugin_stopwatch: { 'default_activity' => 'system' } do + TimeEntryActivity.update_all is_default: false + assert_nil Stopwatch.default_activity_for(@te) + end + end + + ### always_ask (the default) + + test "should return nil if always ask is set" do + assert_nil Stopwatch.default_activity_for(@te) + + TimeEntryActivity.create! active: false, project: @project, name: 'Development' + assert_nil Stopwatch.default_activity_for(@te) + + TimeEntryActivity.where(name: 'Development').delete_all + assert_nil Stopwatch.default_activity_for(@te) + end + + ### specific activity -> ask only if this is not available in project + + test "should use configured default activity for time entry" do + with_settings plugin_stopwatch: { 'default_activity' => '9' } do + assert_equal 'Design', Stopwatch.default_activity_for(@te).name + end + end + + test "should not have default if unavailable" do + TimeEntryActivity.create! active: false, project: @project, name: 'Design', parent_id: 9 + TimeEntryActivity.create! active: false, project: @project, name: 'Development', parent_id: 11 + assert_equal [10], @project.activities.pluck(:id) + + with_settings plugin_stopwatch: { 'default_activity' => '9'} do + assert_nil Stopwatch.default_activity_for(@te) + end + end + +end +