redmineup 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|