redmineup 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/Gemfile +4 -0
- data/README.md +204 -0
- data/Rakefile +11 -0
- data/app/controllers/redmineup_controller.rb +26 -0
- data/app/views/redmine_crm/redmineup_calendar/_calendar.html.erb +34 -0
- data/app/views/redmineup/_money.html.erb +44 -0
- data/app/views/redmineup/settings.html.erb +10 -0
- data/bitbucket-pipelines.yml +50 -0
- data/config/currency_iso.json +2544 -0
- data/config/locales/cs.yml +13 -0
- data/config/locales/de.yml +13 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/es.yml +13 -0
- data/config/locales/ru.yml +13 -0
- data/config/routes.rb +5 -0
- data/doc/CHANGELOG +14 -0
- data/doc/LICENSE.txt +339 -0
- data/lib/redmineup/acts_as_draftable/draft.rb +40 -0
- data/lib/redmineup/acts_as_draftable/up_acts_as_draftable.rb +172 -0
- data/lib/redmineup/acts_as_list/list.rb +282 -0
- data/lib/redmineup/acts_as_priceable/up_acts_as_priceable.rb +33 -0
- data/lib/redmineup/acts_as_taggable/tag.rb +81 -0
- data/lib/redmineup/acts_as_taggable/tag_list.rb +111 -0
- data/lib/redmineup/acts_as_taggable/tagging.rb +16 -0
- data/lib/redmineup/acts_as_taggable/up_acts_as_taggable.rb +357 -0
- data/lib/redmineup/acts_as_viewed/up_acts_as_viewed.rb +274 -0
- data/lib/redmineup/acts_as_votable/up_acts_as_votable.rb +80 -0
- data/lib/redmineup/acts_as_votable/up_acts_as_voter.rb +20 -0
- data/lib/redmineup/acts_as_votable/votable.rb +323 -0
- data/lib/redmineup/acts_as_votable/vote.rb +28 -0
- data/lib/redmineup/acts_as_votable/voter.rb +131 -0
- data/lib/redmineup/assets_manager.rb +43 -0
- data/lib/redmineup/colors_helper.rb +192 -0
- data/lib/redmineup/compatibility/application_controller_patch.rb +33 -0
- data/lib/redmineup/compatibility/routing_mapper_patch.rb +25 -0
- data/lib/redmineup/currency/formatting.rb +224 -0
- data/lib/redmineup/currency/heuristics.rb +151 -0
- data/lib/redmineup/currency/loader.rb +23 -0
- data/lib/redmineup/currency.rb +450 -0
- data/lib/redmineup/engine.rb +4 -0
- data/lib/redmineup/helpers/external_assets_helper.rb +20 -0
- data/lib/redmineup/helpers/form_tag_helper.rb +88 -0
- data/lib/redmineup/helpers/rup_calendar_helper.rb +146 -0
- data/lib/redmineup/helpers/tags_helper.rb +13 -0
- data/lib/redmineup/helpers/vote_helper.rb +35 -0
- data/lib/redmineup/hooks/views_layouts_hook.rb +11 -0
- data/lib/redmineup/liquid/drops/attachment_drop.rb +47 -0
- data/lib/redmineup/liquid/drops/issue_relations_drop.rb +41 -0
- data/lib/redmineup/liquid/drops/issues_drop.rb +217 -0
- data/lib/redmineup/liquid/drops/news_drop.rb +54 -0
- data/lib/redmineup/liquid/drops/projects_drop.rb +86 -0
- data/lib/redmineup/liquid/drops/time_entries_drop.rb +65 -0
- data/lib/redmineup/liquid/drops/users_drop.rb +68 -0
- data/lib/redmineup/liquid/filters/arrays.rb +254 -0
- data/lib/redmineup/liquid/filters/base.rb +249 -0
- data/lib/redmineup/liquid/filters/colors.rb +31 -0
- data/lib/redmineup/money_helper.rb +66 -0
- data/lib/redmineup/patches/liquid_patch.rb +33 -0
- data/lib/redmineup/settings/money.rb +46 -0
- data/lib/redmineup/settings.rb +53 -0
- data/lib/redmineup/version.rb +3 -0
- data/lib/redmineup.rb +108 -0
- data/redmineup.gemspec +29 -0
- data/test/acts_as_draftable/draft_test.rb +29 -0
- data/test/acts_as_draftable/rup_acts_as_draftable_test.rb +178 -0
- data/test/acts_as_taggable/rup_acts_as_taggable_test.rb +350 -0
- data/test/acts_as_taggable/tag_list_test.rb +34 -0
- data/test/acts_as_taggable/tag_test.rb +72 -0
- data/test/acts_as_taggable/tagging_test.rb +15 -0
- data/test/acts_as_viewed/rup_acts_as_viewed_test.rb +47 -0
- data/test/acts_as_votable/rup_acts_as_votable_test.rb +19 -0
- data/test/acts_as_votable/rup_acts_as_voter_test.rb +14 -0
- data/test/acts_as_votable/votable_test.rb +507 -0
- data/test/acts_as_votable/voter_test.rb +296 -0
- data/test/currency_test.rb +292 -0
- data/test/database.yml +17 -0
- data/test/fixtures/attachments.yml +14 -0
- data/test/fixtures/issues.yml +24 -0
- data/test/fixtures/news.yml +8 -0
- data/test/fixtures/projects.yml +10 -0
- data/test/fixtures/taggings.yml +32 -0
- data/test/fixtures/tags.yml +11 -0
- data/test/fixtures/users.yml +9 -0
- data/test/fixtures/votable_caches.yml +2 -0
- data/test/fixtures/votables.yml +4 -0
- data/test/fixtures/voters.yml +6 -0
- data/test/liquid/drops/attachment_drop_test.rb +15 -0
- data/test/liquid/drops/issue_relations_drop_test.rb +24 -0
- data/test/liquid/drops/issues_drop_test.rb +38 -0
- data/test/liquid/drops/news_drop_test.rb +38 -0
- data/test/liquid/drops/projects_drop_test.rb +44 -0
- data/test/liquid/drops/uses_drop_test.rb +36 -0
- data/test/liquid/filters/arrays_filter_test.rb +31 -0
- data/test/liquid/filters/base_filter_test.rb +67 -0
- data/test/liquid/filters/colors_filter_test.rb +33 -0
- data/test/liquid/liquid_helper.rb +34 -0
- data/test/models/attachment.rb +3 -0
- data/test/models/issue.rb +21 -0
- data/test/models/issue_relation.rb +10 -0
- data/test/models/news.rb +3 -0
- data/test/models/project.rb +8 -0
- data/test/models/user.rb +11 -0
- data/test/models/vote_classes.rb +33 -0
- data/test/money_helper_test.rb +12 -0
- data/test/schema.rb +144 -0
- data/test/tags_helper_test.rb +29 -0
- data/test/test_helper.rb +66 -0
- data/test/vote_helper_test.rb +28 -0
- data/vendor/assets/images/money.png +0 -0
- data/vendor/assets/images/vcard.png +0 -0
- data/vendor/assets/javascripts/Chart.bundle.min.js +16 -0
- data/vendor/assets/javascripts/select2.js +2 -0
- data/vendor/assets/javascripts/select2_helpers.js +192 -0
- data/vendor/assets/stylesheets/money.css +96 -0
- data/vendor/assets/stylesheets/select2.css +424 -0
- 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
|
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
|