redmineup 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/Gemfile +4 -0
  4. data/README.md +204 -0
  5. data/Rakefile +11 -0
  6. data/app/controllers/redmineup_controller.rb +26 -0
  7. data/app/views/redmine_crm/redmineup_calendar/_calendar.html.erb +34 -0
  8. data/app/views/redmineup/_money.html.erb +44 -0
  9. data/app/views/redmineup/settings.html.erb +10 -0
  10. data/bitbucket-pipelines.yml +50 -0
  11. data/config/currency_iso.json +2544 -0
  12. data/config/locales/cs.yml +13 -0
  13. data/config/locales/de.yml +13 -0
  14. data/config/locales/en.yml +13 -0
  15. data/config/locales/es.yml +13 -0
  16. data/config/locales/ru.yml +13 -0
  17. data/config/routes.rb +5 -0
  18. data/doc/CHANGELOG +14 -0
  19. data/doc/LICENSE.txt +339 -0
  20. data/lib/redmineup/acts_as_draftable/draft.rb +40 -0
  21. data/lib/redmineup/acts_as_draftable/up_acts_as_draftable.rb +172 -0
  22. data/lib/redmineup/acts_as_list/list.rb +282 -0
  23. data/lib/redmineup/acts_as_priceable/up_acts_as_priceable.rb +33 -0
  24. data/lib/redmineup/acts_as_taggable/tag.rb +81 -0
  25. data/lib/redmineup/acts_as_taggable/tag_list.rb +111 -0
  26. data/lib/redmineup/acts_as_taggable/tagging.rb +16 -0
  27. data/lib/redmineup/acts_as_taggable/up_acts_as_taggable.rb +357 -0
  28. data/lib/redmineup/acts_as_viewed/up_acts_as_viewed.rb +274 -0
  29. data/lib/redmineup/acts_as_votable/up_acts_as_votable.rb +80 -0
  30. data/lib/redmineup/acts_as_votable/up_acts_as_voter.rb +20 -0
  31. data/lib/redmineup/acts_as_votable/votable.rb +323 -0
  32. data/lib/redmineup/acts_as_votable/vote.rb +28 -0
  33. data/lib/redmineup/acts_as_votable/voter.rb +131 -0
  34. data/lib/redmineup/assets_manager.rb +43 -0
  35. data/lib/redmineup/colors_helper.rb +192 -0
  36. data/lib/redmineup/compatibility/application_controller_patch.rb +33 -0
  37. data/lib/redmineup/compatibility/routing_mapper_patch.rb +25 -0
  38. data/lib/redmineup/currency/formatting.rb +224 -0
  39. data/lib/redmineup/currency/heuristics.rb +151 -0
  40. data/lib/redmineup/currency/loader.rb +23 -0
  41. data/lib/redmineup/currency.rb +450 -0
  42. data/lib/redmineup/engine.rb +4 -0
  43. data/lib/redmineup/helpers/external_assets_helper.rb +20 -0
  44. data/lib/redmineup/helpers/form_tag_helper.rb +88 -0
  45. data/lib/redmineup/helpers/rup_calendar_helper.rb +146 -0
  46. data/lib/redmineup/helpers/tags_helper.rb +13 -0
  47. data/lib/redmineup/helpers/vote_helper.rb +35 -0
  48. data/lib/redmineup/hooks/views_layouts_hook.rb +11 -0
  49. data/lib/redmineup/liquid/drops/attachment_drop.rb +47 -0
  50. data/lib/redmineup/liquid/drops/issue_relations_drop.rb +41 -0
  51. data/lib/redmineup/liquid/drops/issues_drop.rb +217 -0
  52. data/lib/redmineup/liquid/drops/news_drop.rb +54 -0
  53. data/lib/redmineup/liquid/drops/projects_drop.rb +86 -0
  54. data/lib/redmineup/liquid/drops/time_entries_drop.rb +65 -0
  55. data/lib/redmineup/liquid/drops/users_drop.rb +68 -0
  56. data/lib/redmineup/liquid/filters/arrays.rb +254 -0
  57. data/lib/redmineup/liquid/filters/base.rb +249 -0
  58. data/lib/redmineup/liquid/filters/colors.rb +31 -0
  59. data/lib/redmineup/money_helper.rb +66 -0
  60. data/lib/redmineup/patches/liquid_patch.rb +33 -0
  61. data/lib/redmineup/settings/money.rb +46 -0
  62. data/lib/redmineup/settings.rb +53 -0
  63. data/lib/redmineup/version.rb +3 -0
  64. data/lib/redmineup.rb +108 -0
  65. data/redmineup.gemspec +29 -0
  66. data/test/acts_as_draftable/draft_test.rb +29 -0
  67. data/test/acts_as_draftable/rup_acts_as_draftable_test.rb +178 -0
  68. data/test/acts_as_taggable/rup_acts_as_taggable_test.rb +350 -0
  69. data/test/acts_as_taggable/tag_list_test.rb +34 -0
  70. data/test/acts_as_taggable/tag_test.rb +72 -0
  71. data/test/acts_as_taggable/tagging_test.rb +15 -0
  72. data/test/acts_as_viewed/rup_acts_as_viewed_test.rb +47 -0
  73. data/test/acts_as_votable/rup_acts_as_votable_test.rb +19 -0
  74. data/test/acts_as_votable/rup_acts_as_voter_test.rb +14 -0
  75. data/test/acts_as_votable/votable_test.rb +507 -0
  76. data/test/acts_as_votable/voter_test.rb +296 -0
  77. data/test/currency_test.rb +292 -0
  78. data/test/database.yml +17 -0
  79. data/test/fixtures/attachments.yml +14 -0
  80. data/test/fixtures/issues.yml +24 -0
  81. data/test/fixtures/news.yml +8 -0
  82. data/test/fixtures/projects.yml +10 -0
  83. data/test/fixtures/taggings.yml +32 -0
  84. data/test/fixtures/tags.yml +11 -0
  85. data/test/fixtures/users.yml +9 -0
  86. data/test/fixtures/votable_caches.yml +2 -0
  87. data/test/fixtures/votables.yml +4 -0
  88. data/test/fixtures/voters.yml +6 -0
  89. data/test/liquid/drops/attachment_drop_test.rb +15 -0
  90. data/test/liquid/drops/issue_relations_drop_test.rb +24 -0
  91. data/test/liquid/drops/issues_drop_test.rb +38 -0
  92. data/test/liquid/drops/news_drop_test.rb +38 -0
  93. data/test/liquid/drops/projects_drop_test.rb +44 -0
  94. data/test/liquid/drops/uses_drop_test.rb +36 -0
  95. data/test/liquid/filters/arrays_filter_test.rb +31 -0
  96. data/test/liquid/filters/base_filter_test.rb +67 -0
  97. data/test/liquid/filters/colors_filter_test.rb +33 -0
  98. data/test/liquid/liquid_helper.rb +34 -0
  99. data/test/models/attachment.rb +3 -0
  100. data/test/models/issue.rb +21 -0
  101. data/test/models/issue_relation.rb +10 -0
  102. data/test/models/news.rb +3 -0
  103. data/test/models/project.rb +8 -0
  104. data/test/models/user.rb +11 -0
  105. data/test/models/vote_classes.rb +33 -0
  106. data/test/money_helper_test.rb +12 -0
  107. data/test/schema.rb +144 -0
  108. data/test/tags_helper_test.rb +29 -0
  109. data/test/test_helper.rb +66 -0
  110. data/test/vote_helper_test.rb +28 -0
  111. data/vendor/assets/images/money.png +0 -0
  112. data/vendor/assets/images/vcard.png +0 -0
  113. data/vendor/assets/javascripts/Chart.bundle.min.js +16 -0
  114. data/vendor/assets/javascripts/select2.js +2 -0
  115. data/vendor/assets/javascripts/select2_helpers.js +192 -0
  116. data/vendor/assets/stylesheets/money.css +96 -0
  117. data/vendor/assets/stylesheets/select2.css +424 -0
  118. metadata +295 -0
@@ -0,0 +1,66 @@
1
+ require 'action_view'
2
+ require 'redmineup/settings/money'
3
+
4
+ module Redmineup
5
+ module MoneyHelper
6
+ def object_price(obj, price_field = :price, options = {})
7
+ options.merge!({:symbol => true})
8
+ price_to_currency(obj.try(price_field), obj.currency, options).to_s if obj.respond_to?(:currency)
9
+ end
10
+
11
+ def prices_collection_by_currency(prices_collection, options = {})
12
+ return [] if prices_collection.blank? || prices_collection == 0
13
+ prices = prices_collection
14
+ prices.reject!{|k, v| v.to_i == 0} if options[:hide_zeros]
15
+ prices.collect{|k, v| content_tag(:span, price_to_currency(v, k, :symbol => true), :style => "white-space: nowrap;")}.compact
16
+ end
17
+
18
+ def deal_currency_icon(currency)
19
+ case currency.to_s.upcase
20
+ when 'EUR'
21
+ 'icon-money-euro'
22
+ when 'GBP'
23
+ 'icon-money-pound'
24
+ when 'JPY'
25
+ 'icon-money-yen'
26
+ else
27
+ 'icon-money-dollar'
28
+ end
29
+ end
30
+
31
+ def collection_for_currencies_select(default_currency = Redmineup::Settings::Money.default_currency, major_currencies = Redmineup::Settings::Money.major_currencies)
32
+ currencies = []
33
+ currencies << default_currency.to_s unless default_currency.blank?
34
+ currencies |= major_currencies
35
+ currencies.map do |c|
36
+ currency = Redmineup::Currency.find(c)
37
+ ["#{currency.iso_code} (#{currency.symbol})", currency.iso_code] if currency
38
+ end.compact.uniq
39
+ end
40
+
41
+ def all_currencies
42
+ Currency.table.inject([]) do |array, (_, attributes)|
43
+ array ||= []
44
+ array << [attributes[:name].to_s + (attributes[:symbol].blank? ? '' : " (#{attributes[:symbol]})"), attributes[:iso_code]]
45
+ array
46
+ end.sort{|x, y| x[0] <=> y[0]}
47
+ end
48
+
49
+ def price_to_currency(price, currency = Redmineup::Settings::Money.default_currency, options = {})
50
+ return '' if price.blank?
51
+
52
+ currency = 'USD' unless currency.is_a?(String)
53
+ default_options = {
54
+ decimal_mark: Redmineup::Settings::Money.decimal_separator,
55
+ thousands_separator: Redmineup::Settings::Money.thousands_delimiter
56
+ }.reject { |_k, v| v.nil? }
57
+
58
+ currency = Redmineup::Currency.find(currency)
59
+ Redmineup::Currency.format(price.to_f, currency, default_options.merge(options))
60
+ end
61
+ end
62
+ end
63
+
64
+ unless ActionView::Base.included_modules.include?(Redmineup::MoneyHelper)
65
+ ActionView::Base.send(:include, Redmineup::MoneyHelper)
66
+ end
@@ -0,0 +1,33 @@
1
+ module Redmineup
2
+ module Patches
3
+ module LiquidPatch
4
+ module StandardFilters
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+
9
+ private
10
+
11
+ def to_number(obj)
12
+ case obj
13
+ when Float
14
+ BigDecimal(obj.to_s)
15
+ when Numeric
16
+ obj
17
+ when String
18
+ (obj.strip =~ /^\d+\.\d+$/) ? BigDecimal(obj) : obj.to_i
19
+ else
20
+ 0
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ unless Liquid::StandardFilters.included_modules.include?(Redmineup::Patches::LiquidPatch::StandardFilters)
32
+ Liquid::StandardFilters.send(:include, Redmineup::Patches::LiquidPatch::StandardFilters)
33
+ end
@@ -0,0 +1,46 @@
1
+ require 'redmineup/settings'
2
+
3
+ module Redmineup
4
+ class Settings
5
+ class Money
6
+ TAX_TYPE_EXCLUSIVE = 1
7
+ TAX_TYPE_INCLUSIVE = 2
8
+
9
+ class << self
10
+ def default_currency
11
+ Redmineup::Settings['default_currency'] || 'USD'
12
+ end
13
+
14
+ def major_currencies
15
+ currencies = Redmineup::Settings['major_currencies'].to_s.split(',').select { |c| !c.blank? }.map(&:strip)
16
+ currencies = %w[USD EUR GBP RUB CHF] if currencies.blank?
17
+ currencies.compact.uniq
18
+ end
19
+
20
+ def default_tax
21
+ Redmineup::Settings['default_tax'].to_f
22
+ end
23
+
24
+ def tax_type
25
+ ((['1', '2'] & [Redmineup::Settings['tax_type'].to_s]).first || TAX_TYPE_EXCLUSIVE).to_i
26
+ end
27
+
28
+ def tax_exclusive?
29
+ tax_type == TAX_TYPE_EXCLUSIVE
30
+ end
31
+
32
+ def thousands_delimiter
33
+ ([' ', ',', '.'] & [Redmineup::Settings['thousands_delimiter']]).first
34
+ end
35
+
36
+ def decimal_separator
37
+ ([',', '.'] & [Redmineup::Settings['decimal_separator']]).first
38
+ end
39
+
40
+ def disable_taxes?
41
+ Redmineup::Settings['disable_taxes'].to_i > 0
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ module Redmineup
2
+ class Settings
3
+ SECTIONS = {
4
+ 'money' => { id: :money, label: :label_redmineup_money, partial: 'money' }
5
+ }.freeze
6
+
7
+ class << self
8
+ def initialize_gem_settings
9
+ return if !Object.const_defined?('Setting') || Setting.respond_to?(:plugin_redmineup)
10
+
11
+ if Setting.respond_to?(:define_setting)
12
+ Setting.send(:define_setting, 'plugin_redmineup', 'default' => default_settings, 'serialized' => true)
13
+ elsif Setting.respond_to?(:available_settings)
14
+ Setting.available_settings['plugin_redmineup'] = { 'default' => default_settings, 'serialized' => true }
15
+ Setting.class.send(:define_method, 'plugin_redmineup', -> { Setting['plugin_redmineup'] })
16
+ Setting.class.send(:define_method, 'plugin_redmineup=', lambda do |val|
17
+ setting = find_or_default('plugin_redmineup')
18
+ setting.value = val || ''
19
+ @cached_settings['plugin_redmineup'] = nil
20
+ setting.save(validate: false)
21
+ setting.value
22
+ end)
23
+ end
24
+ @settings_initialized
25
+ end
26
+
27
+ # Use apply instead attrs assign because it can rewrite other attributes
28
+ def apply=(values)
29
+ initialize_gem_settings unless @settings_initialized
30
+
31
+ Setting.plugin_redmineup = Setting.plugin_redmineup.merge(values)
32
+ end
33
+
34
+ def values
35
+ initialize_gem_settings unless @settings_initialized
36
+ Object.const_defined?('Setting') ? Setting.plugin_redmineup : {}
37
+ end
38
+
39
+ def [](value)
40
+ initialize_gem_settings unless @settings_initialized
41
+ return Setting.plugin_redmineup[value] if Object.const_defined?('Setting')
42
+
43
+ nil
44
+ end
45
+
46
+ private
47
+
48
+ def default_settings
49
+ {}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module Redmineup
2
+ VERSION = '1.0.2'
3
+ end
data/lib/redmineup.rb ADDED
@@ -0,0 +1,108 @@
1
+ require 'active_record'
2
+ require 'action_view'
3
+
4
+ require 'redmineup/version'
5
+ require 'redmineup/engine'
6
+
7
+ require 'redmineup/settings'
8
+ require 'redmineup/settings/money'
9
+
10
+ require 'redmineup/acts_as_list/list'
11
+ require 'redmineup/acts_as_taggable/tag'
12
+ require 'redmineup/acts_as_taggable/tag_list'
13
+ require 'redmineup/acts_as_taggable/tagging'
14
+ require 'redmineup/acts_as_taggable/up_acts_as_taggable'
15
+ require 'redmineup/acts_as_viewed/up_acts_as_viewed'
16
+ require 'redmineup/acts_as_votable/up_acts_as_votable'
17
+ require 'redmineup/acts_as_votable/up_acts_as_voter'
18
+ require 'redmineup/acts_as_votable/vote'
19
+ require 'redmineup/acts_as_votable/voter'
20
+ require 'redmineup/acts_as_draftable/up_acts_as_draftable'
21
+ require 'redmineup/acts_as_draftable/draft'
22
+ require 'redmineup/acts_as_priceable/up_acts_as_priceable'
23
+
24
+ require 'redmineup/currency'
25
+ require 'redmineup/helpers/tags_helper'
26
+ require 'redmineup/money_helper'
27
+ require 'redmineup/colors_helper'
28
+
29
+ require 'liquid'
30
+ require 'redmineup/liquid/filters/base'
31
+ require 'redmineup/liquid/filters/arrays'
32
+ require 'redmineup/liquid/filters/colors'
33
+ require 'redmineup/liquid/drops/issues_drop'
34
+ require 'redmineup/liquid/drops/news_drop'
35
+ require 'redmineup/liquid/drops/projects_drop'
36
+ require 'redmineup/liquid/drops/users_drop'
37
+ require 'redmineup/liquid/drops/time_entries_drop'
38
+ require 'redmineup/liquid/drops/attachment_drop'
39
+ require 'redmineup/liquid/drops/issue_relations_drop'
40
+
41
+ require 'redmineup/helpers/external_assets_helper'
42
+ require 'redmineup/helpers/form_tag_helper'
43
+ require 'redmineup/helpers/rup_calendar_helper'
44
+ require 'redmineup/assets_manager'
45
+
46
+ require 'redmineup/compatibility/application_controller_patch'
47
+ require 'redmineup/compatibility/routing_mapper_patch'
48
+ require 'redmineup/patches/liquid_patch' unless BigDecimal.respond_to?(:new)
49
+
50
+ module Redmineup
51
+ GEM_NAME = 'redmineup'.freeze
52
+ end
53
+
54
+ if defined?(ActiveRecord::Base)
55
+ ActiveRecord::Base.send :include, Redmineup::ActsAsList::List
56
+ ActiveRecord::Base.extend(Redmineup::ActsAsVotable::Voter)
57
+ ActiveRecord::Base.extend(Redmineup::ActsAsVotable::Votable)
58
+ end
59
+
60
+ Redmineup::AssetsManager.install_assets
61
+
62
+ if defined?(ActionView::Base)
63
+ ActionView::Base.send :include, Redmineup::ExternalAssetsHelper
64
+ ActionView::Base.send :include, Redmineup::FormTagHelper
65
+ end
66
+
67
+ def requires_redmineup(arg)
68
+ def compare_versions(requirement, current)
69
+ raise ArgumentError.new('wrong version format') unless check_version_format(requirement)
70
+
71
+ requirement = requirement.split('.').collect(&:to_i)
72
+ requirement <=> current.slice(0, requirement.size)
73
+ end
74
+
75
+ def check_version_format(version)
76
+ version =~ /^\d+.?\d*.?\d*$/m
77
+ end
78
+
79
+ arg = { version_or_higher: arg } unless arg.is_a?(Hash)
80
+ arg.assert_valid_keys(:version, :version_or_higher)
81
+
82
+ current = Redmineup::VERSION.split('.').map { |x| x.to_i }
83
+ arg.each do |k, req|
84
+ case k
85
+ when :version_or_higher
86
+ raise ArgumentError.new(':version_or_higher accepts a version string only') unless req.is_a?(String)
87
+
88
+ unless compare_versions(req, current) <= 0
89
+ Rails.logger.error "\033[31m[ERROR]\033[0m Redmine requires redmineup gem version #{req} or higher (you're using #{Redmineup::VERSION}).\n\033[31m[ERROR]\033[0m Please update with 'bundle update redmineup'." if Rails.logger
90
+ abort "\033[31mRedmine requires redmineup gem version #{req} or higher (you're using #{Redmineup::VERSION}).\nPlease update with 'bundle update redmineup'.\033[0m"
91
+ end
92
+ when :version
93
+ req = [req] if req.is_a?(String)
94
+ if req.is_a?(Array)
95
+ unless req.detect { |ver| compare_versions(ver, current) == 0 }
96
+ abort "\033[31mRedmine requires redmineup gem version #{req} (you're using #{Redmineup::VERSION}).\nPlease update with 'bundle update redmineup'.\033[0m"
97
+ end
98
+ elsif req.is_a?(Range)
99
+ unless compare_versions(req.first, current) <= 0 && compare_versions(req.last, current) >= 0
100
+ abort "\033[31mRedmine requires redmineup gem version between #{req.first} and #{req.last} (you're using #{Redmineup::VERSION}).\nPlease update with 'bundle update redmineup'.\033[0m"
101
+ end
102
+ else
103
+ raise ArgumentError.new(':version option accepts a version string, an array or a range of versions')
104
+ end
105
+ end
106
+ end
107
+ true
108
+ end
data/redmineup.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'redmineup/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "redmineup"
8
+ spec.version = Redmineup::VERSION
9
+ spec.authors = ["RedmineUP"]
10
+ spec.email = ["support@redmineup.com"]
11
+ spec.summary = %q{Common libraries for RedmineUP plugins for Redmine}
12
+ spec.description = %q{Common libraries for RedmineUP plugins (www.redmineup.com) for Redmine. Required Redmine from http://redmine.org}
13
+ spec.homepage = "https://www.redmineup.com"
14
+ spec.license = "GPL-2.0"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.required_ruby_version = ">= 2.0.0"
21
+
22
+ spec.add_runtime_dependency 'rails'
23
+ spec.add_runtime_dependency 'liquid', '> 4.0', '< 5.0'
24
+ spec.add_runtime_dependency 'rubyzip'
25
+
26
+ spec.add_development_dependency 'sqlite3'
27
+ spec.add_development_dependency 'mysql2'
28
+ spec.add_development_dependency 'pg'
29
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class DraftTest < ActiveSupport::TestCase
4
+ def test_restore
5
+ issue = Issue.new(subject: 'some subject', description: 'some description')
6
+
7
+ issue.save_draft
8
+ restored_issue = Redmineup::ActsAsDraftable::Draft.find(issue.draft_id).restore
9
+
10
+ assert_equal issue.subject, restored_issue.subject
11
+ assert_equal issue.description, restored_issue.description
12
+ end
13
+
14
+ def test_restore_all
15
+ first_issue = Issue.new(subject: 'first subject')
16
+ first_issue.save_draft
17
+ second_issue = Issue.new(subject: 'second subject')
18
+ second_issue.save_draft
19
+
20
+ restored_issues = Redmineup::ActsAsDraftable::Draft.restore_all
21
+ assert_equal [first_issue.subject, second_issue.subject], restored_issues.map(&:subject).sort
22
+ end
23
+
24
+ private
25
+
26
+ def current_user
27
+ users(:sam)
28
+ end
29
+ end
@@ -0,0 +1,178 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class RupActsAsDraftableTest < ActiveSupport::TestCase
4
+ def test_up_acts_as_draftable_without_arguments
5
+ assert_nothing_raised do
6
+ Project.up_acts_as_draftable
7
+ end
8
+ end
9
+
10
+ def test_up_acts_as_draftable_with_parent
11
+ assert_nothing_raised do
12
+ News.up_acts_as_draftable(parent: :author)
13
+ end
14
+ assert User.new.respond_to?(:drafts)
15
+ end
16
+
17
+ def test_up_acts_as_draftable_with_non_existing_parent
18
+ assert_raises do
19
+ Issue.up_acts_as_draftable(parent: :foo)
20
+ end
21
+ end
22
+
23
+ def test_up_acts_as_draftable_with_non_hash_argument
24
+ assert_raises do
25
+ Issue.up_acts_as_draftable('bar')
26
+ end
27
+ end
28
+
29
+ def test_up_acts_as_draftable_with_invalid_hash_key
30
+ assert_raises do
31
+ Issue.up_acts_as_draftable(baz: 'qux')
32
+ end
33
+ end
34
+
35
+ def test_drafts
36
+ Issue.up_acts_as_draftable parent: :project
37
+ issue = Issue.new
38
+ issue.save_draft
39
+
40
+ assert_equal 1, Issue.drafts(current_user).count
41
+ assert_equal Redmineup::ActsAsDraftable::Draft, Issue.drafts(current_user).first.class
42
+ end
43
+
44
+ def test_from_draft
45
+ Issue.up_acts_as_draftable parent: :project
46
+ issue = Issue.new(subject: 'subject')
47
+ issue.save_draft
48
+
49
+ issue_from_draft = Issue.from_draft(issue.draft_id)
50
+
51
+ assert_equal Issue, issue_from_draft.class
52
+ assert_equal true, issue_from_draft.new_record?
53
+ assert_equal issue.draft_id, issue_from_draft.draft_id
54
+
55
+ assert_equal issue.subject, issue_from_draft.subject
56
+ end
57
+
58
+ def test_draft_deleted_after_save
59
+ issue = Issue.new(subject: 'subject')
60
+ issue.save_draft
61
+
62
+ issue_from_draft = Issue.from_draft(issue.draft_id)
63
+
64
+ assert_difference 'Issue.count' do
65
+ assert_difference 'Redmineup::ActsAsDraftable::Draft.count', -1 do
66
+ issue_from_draft.save!
67
+ end
68
+ end
69
+ assert_nil issue_from_draft.draft_id
70
+ end
71
+
72
+ def test_from_draft_with_non_existing_draft_id
73
+ assert_raises do
74
+ Issue.from_draft(999)
75
+ end
76
+ end
77
+
78
+ def test_from_draft_with_wrong_type
79
+ Project.up_acts_as_draftable
80
+
81
+ project = Project.new
82
+ project.save_draft
83
+
84
+ assert_raises do
85
+ Issue.from_draft(project.draft_id)
86
+ end
87
+ end
88
+
89
+ def test_dump_to_draft
90
+ assert_equal String, Issue.new.dump_to_draft.class
91
+ end
92
+
93
+ def test_load_from_draft
94
+ attributes = {subject: 'subject', description: 'description'}
95
+ draft = Issue.new(attributes).dump_to_draft
96
+
97
+ issue = Issue.new
98
+ issue.load_from_draft(draft)
99
+
100
+ assert_equal attributes[:subject], issue.subject
101
+ assert_equal attributes[:description], issue.description
102
+ end
103
+
104
+ def test_save_draft
105
+ Issue.up_acts_as_draftable parent: :project
106
+ attributes = { subject: 'subject' }
107
+ issue = Issue.new(attributes)
108
+
109
+ assert_no_difference 'Issue.count' do
110
+ assert_difference 'Redmineup::ActsAsDraftable::Draft.count' do
111
+ result = issue.save_draft
112
+ assert_equal true, result
113
+ end
114
+ end
115
+ assert_not_nil issue.draft_id
116
+
117
+ draft = Redmineup::ActsAsDraftable::Draft.find(issue.draft_id)
118
+ assert_equal 'Issue', draft.target_type
119
+ assert_equal current_user.id, draft.user_id
120
+ assert_equal attributes[:subject], draft.restore.subject
121
+ end
122
+
123
+ def test_save_draft_with_associations
124
+ Issue.up_acts_as_draftable parent: :project
125
+ issue = Issue.new(project: projects(:second_project))
126
+ issue.save_draft
127
+
128
+ draft = Redmineup::ActsAsDraftable::Draft.find(issue.draft_id)
129
+ assert_equal issue.project.name, draft.restore.project.name
130
+ end
131
+
132
+ def test_save_draft_updates_existing_draft
133
+ Issue.up_acts_as_draftable parent: :project
134
+ issue = Issue.new
135
+ issue.save_draft
136
+
137
+ issue.subject = 'changed subject'
138
+ assert_no_difference 'Issue.count' do
139
+ assert_no_difference 'Redmineup::ActsAsDraftable::Draft.count' do
140
+ issue.save_draft
141
+ end
142
+ end
143
+
144
+ draft = Redmineup::ActsAsDraftable::Draft.find(issue.draft_id)
145
+ assert_equal issue.subject, draft.restore.subject
146
+ end
147
+
148
+ def test_save_draft_does_not_save_persisted_object
149
+ issue = issues(:second_issue)
150
+ assert_equal false, issue.save_draft
151
+ end
152
+
153
+ def test_save_draft_saves_persisted_but_changed_object
154
+ issue = issues(:second_issue)
155
+ issue.subject = 'changed subject'
156
+ assert_equal true, issue.save_draft
157
+ end
158
+
159
+ def test_update_draft
160
+ issue = Issue.new(subject: 'subject')
161
+ issue.save_draft
162
+
163
+ assert_no_difference 'Issue.count' do
164
+ assert_no_difference 'Redmineup::ActsAsDraftable::Draft.count' do
165
+ issue.update_draft(subject: 'updated_subject')
166
+ end
167
+ end
168
+
169
+ draft = Redmineup::ActsAsDraftable::Draft.find(issue.draft_id)
170
+ assert_equal issue.subject, draft.restore.subject
171
+ end
172
+
173
+ private
174
+
175
+ def current_user
176
+ users(:sam)
177
+ end
178
+ end