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.
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,11 @@
1
+ error:
2
+ name: error
3
+
4
+ feature:
5
+ name: New feature
6
+
7
+ bug:
8
+ name: bug
9
+
10
+ question:
11
+ name: question
@@ -0,0 +1,9 @@
1
+ jonathan:
2
+ name: Jonathan
3
+ language: 'EN'
4
+ sam:
5
+ name: Sam
6
+ language: 'RU'
7
+ homer:
8
+ name: Homer
9
+ language: 'CH'
@@ -0,0 +1,2 @@
1
+ votable_cache:
2
+ name: 'votiong model with cache'
@@ -0,0 +1,4 @@
1
+ votable:
2
+ name: 'a voting model'
3
+ votable2:
4
+ name: 'another voting things'
@@ -0,0 +1,6 @@
1
+ voter:
2
+ name: 'i can vote!'
3
+ voter2:
4
+ name: 'a new person'
5
+ voter3:
6
+ name: 'another person'
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+
3
+ module Redmineup
4
+ class AttachmentDropTest < ActiveSupport::TestCase
5
+ def setup
6
+ @attachment = attachments(:attachment_001)
7
+ @user = @attachment.author
8
+ @liquid_render = LiquidRender.new('attachment' => Liquid::AttachmentDrop.new(@attachment))
9
+ end
10
+
11
+ def test_author
12
+ assert_equal @user.name, @liquid_render.render('{{ attachment.author.name }}')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class IssueRelationsDropTest < ActiveSupport::TestCase
6
+ def setup
7
+ @issue_from = Issue.find_by(subject: 'Issue 3 subject')
8
+ @issue_to = Issue.find_by(subject: 'Issue 4 subject')
9
+ @relation = IssueRelation.create!(issue_from: @issue_from, issue_to: @issue_to, relation_type: 'precedes', delay: 1)
10
+ @liquid_render = LiquidRender.new(
11
+ 'issue' => Liquid::IssueDrop.new(@issue_from)
12
+ )
13
+ end
14
+
15
+ def test_relation_from_render
16
+ issues_text = @liquid_render.render('{% for relation in issue.relations_from %} {{relation.issue_from.id}}|{{relation.issue_to.id}}|{{relation.relation_type}}|{{relation.delay}} {% endfor %}')
17
+ assert_match "#{@issue_from.id}|#{@issue_to.id}|precedes|#{@relation.delay}", issues_text
18
+ end
19
+
20
+ def test_relation_size
21
+ assert_equal '1', @liquid_render.render('{{ issue.relations_from.size }}')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class IssuesDropTest < ActiveSupport::TestCase
6
+ def setup
7
+ @issue = Issue.first
8
+ @user = User.first
9
+ @liquid_render = LiquidRender.new('user' => Liquid::UserDrop.new(@user),
10
+ 'issue' => Liquid::IssueDrop.new(@issue),
11
+ 'issues' => Liquid::IssuesDrop.new(Issue.all))
12
+ end
13
+
14
+ def test_issues_all
15
+ issues_text = @liquid_render.render('{% for issue in issues.all %} {{issue.subject }} {% endfor %}')
16
+ Issue.all.map(&:subject).each do |subject|
17
+ assert_match subject, issues_text
18
+ end
19
+ end
20
+
21
+ def test_issues_size
22
+ assert_equal '4', @liquid_render.render('{{ issues.size }}')
23
+ end
24
+
25
+ def test_issue_author
26
+ assert_equal @user.name, @liquid_render.render('{{ issue.author.name }}')
27
+ end
28
+
29
+ def test_issue_delegated
30
+ assert_equal [@issue.id, @issue.subject, @issue.description].join('|'),
31
+ @liquid_render.render('{{ issue.id }}|{{ issue.subject }}|{{ issue.description }}')
32
+
33
+ assert_not_equal @issue.subject, @liquid_render.render('{% if issue.closed? %}{{issue.subject}}{% endif %}')
34
+ @issue.closed = true
35
+ assert_equal @issue.subject, @liquid_render.render('{% if issue.closed? %}{{issue.subject}}{% endif %}')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class NewsDropTest < ActiveSupport::TestCase
6
+ def setup
7
+ @news = News.first
8
+ @user = User.first
9
+ @liquid_render = LiquidRender.new('user' => Liquid::UserDrop.new(@user),
10
+ 'news' => Liquid::NewsDrop.new(@news),
11
+ 'newss' => Liquid::NewssDrop.new(News.all))
12
+ end
13
+
14
+ def test_newss_all
15
+ newss_text = @liquid_render.render('{% for news in newss.all %} {{news.title }} {% endfor %}')
16
+ News.all.map(&:title).each do |title|
17
+ assert_match title, newss_text
18
+ end
19
+ end
20
+
21
+ def test_newss_last
22
+ assert_equal News.last.title, @liquid_render.render('{{ newss.last.title }}')
23
+ end
24
+
25
+ def test_newss_size
26
+ assert_equal '2', @liquid_render.render('{{ newss.size }}')
27
+ end
28
+
29
+ def test_news_author
30
+ assert_equal @user.name, @liquid_render.render('{{ news.author.name }}')
31
+ end
32
+
33
+ def test_issue_delegated
34
+ assert_equal [@news.id, @news.title, @news.description].join('|'),
35
+ @liquid_render.render('{{ news.id }}|{{ news.title }}|{{ news.description }}')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class ProjectsDropTest < ActiveSupport::TestCase
6
+ def setup
7
+ @project = Project.first
8
+ @user = User.first
9
+ @liquid_render = LiquidRender.new('user' => Liquid::UserDrop.new(@user),
10
+ 'project' => Liquid::ProjectDrop.new(@project),
11
+ 'projects' => Liquid::ProjectsDrop.new(Project.all))
12
+ end
13
+
14
+ def test_projects_all
15
+ projects_text = @liquid_render.render('{% for project in projects.all %} {{project.identifier }} {% endfor %}')
16
+ Project.all.map(&:identifier).each do |identifier|
17
+ assert_match identifier, projects_text
18
+ end
19
+ end
20
+
21
+ def test_projects_active
22
+ projects_text = @liquid_render.render('{% for project in projects.active %} {{project.identifier }} {% endfor %}')
23
+ Project.where(:status => 1).map(&:identifier).each do |identifier|
24
+ assert_match identifier, projects_text
25
+ end
26
+ end
27
+
28
+ def test_projects_size
29
+ assert_equal '2', @liquid_render.render('{{ projects.size }}')
30
+ end
31
+
32
+ def test_project_issues
33
+ issues_text = @liquid_render.render('{% for issue in project.issues %} {{issue.subject }} {% endfor %}')
34
+ Project.first.issues.each do |issue|
35
+ assert_match issue.subject, issues_text
36
+ end
37
+ end
38
+
39
+ def test_project_delegated
40
+ assert_equal [@project.id, @project.identifier, @project.description].join('|'),
41
+ @liquid_render.render('{{ project.id }}|{{ project.identifier }}|{{ project.description }}')
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class UsersDropTest < ActiveSupport::TestCase
6
+ def setup
7
+ @user = User.first
8
+ @liquid_render = LiquidRender.new('user' => Liquid::UserDrop.new(@user),
9
+ 'users' => Liquid::UsersDrop.new(User.all))
10
+ end
11
+
12
+ def test_users_all
13
+ users_text = @liquid_render.render('{% for user in users.all %} {{user.name }} {% endfor %}')
14
+ User.all.map(&:name).each do |name|
15
+ assert_match name, users_text
16
+ end
17
+ end
18
+
19
+ def test_users_current
20
+ assert_equal User.first.name, @liquid_render.render('{{ users.current.name }}')
21
+ end
22
+
23
+ def test_users_size
24
+ assert_equal '3', @liquid_render.render('{{ users.size }}')
25
+ end
26
+
27
+ def test_user_name
28
+ assert_equal @user.name, @liquid_render.render('{{ user.name }}')
29
+ end
30
+
31
+ def test_user_delegated
32
+ assert_equal [@user.name, @user.language].join('|'),
33
+ @liquid_render.render('{{ user.name }}|{{ user.language }}')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class ArraysFilterTest < ActiveSupport::TestCase
6
+ def setup
7
+ @liquid_render = LiquidRender.new
8
+ @array = '6,7,8,9,1,2,3,4,5'
9
+ end
10
+
11
+ def test_first_filter
12
+ assert_match '1', @liquid_render.render("{{ '#{@array}' | split: ',' | first: 5 | last }}")
13
+ end
14
+
15
+ def test_sort_filter
16
+ assert_match '123456789', @liquid_render.render("{{ '#{@array}' | split: ',' | sort }}")
17
+ end
18
+
19
+ def test_where_filter
20
+ assert_match '{"name"=>"two", "value"=>5}', @liquid_render.render("{{ objects_arr | where: 'name', 'two' }}")
21
+ assert_match '{"name"=>"one", "value"=>10}', @liquid_render.render("{{ objects_arr | where: 'value', 6, '>' }}")
22
+ assert_match '{"name"=>"one", "value"=>10}', @liquid_render.render("{{ objects_arr | where: 'name', 'on', 'match' }}")
23
+ assert_match '3', @liquid_render.render("{{ objects_arr | where: 'value', '', 'any' | size }}")
24
+ assert_match '1', @liquid_render.render("{{ objects_arr | where: 'value', '', 'none' | size }}")
25
+ assert_match '2', @liquid_render.render("{{ issues.all | where: 'author.name', 'Jonathan', '==' | size }}")
26
+ assert_match '1', @liquid_render.render("{{ issues.all | where: 'author.language', 'CH', '==' | size }}")
27
+ assert_match '0', @liquid_render.render("{{ issues.all | where: 'author.name', '', 'none' | size }}")
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,67 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class BaseFilterTest < ActiveSupport::TestCase
6
+ def setup
7
+ @liquid_render = LiquidRender.new
8
+ end
9
+
10
+ def test_underscore_filter
11
+ assert_match 'some_text', @liquid_render.render("{{ 'some text' | underscore }}")
12
+ end
13
+
14
+ def test_dasherize_filter
15
+ assert_match 'some-text', @liquid_render.render("{{ 'some text' | dasherize }}")
16
+ end
17
+
18
+ def test_random_filter
19
+ assert @liquid_render.render("{{ random: 10 }}").to_i <= 10
20
+ end
21
+
22
+ def test_encode_filter
23
+ assert_equal 'http%3A%3A%2F%2Fwww.test.com%3Fkey%3Dtest+test+test',
24
+ @liquid_render.render("{{ 'http:://www.test.com?key=test test test' | encode }}")
25
+ end
26
+
27
+ def test_plus_days_filter
28
+ assert_match (Date.today + 3.days).strftime(date_format), @liquid_render.render("{{today | plus_days: 3 | date: '#{date_format}'}}")
29
+ end
30
+
31
+ def test_date_range_filter
32
+ assert_equal '10', @liquid_render.render("{{today | date_range: '#{Date.today - 10.days}'}}")
33
+ end
34
+
35
+ def test_today_filter
36
+ assert_match Date.today.strftime(date_format), @liquid_render.render('{{today}}')
37
+ end
38
+
39
+ def test_utc_filter
40
+ assert_match '2017-01-01 10:13:13 UTC', @liquid_render.render("{{'San, 01 Jan 2017 13:13:13 MSK +03:00' | utc}}")
41
+ end
42
+
43
+ def test_modulo_filter
44
+ assert_equal '3', @liquid_render.render("{{24 | modulo: 7}}")
45
+ end
46
+
47
+ def test_round_filter
48
+ assert_equal '24.12', @liquid_render.render("{{24.12345 | round: 2}}")
49
+ end
50
+
51
+ def test_ceil_filter
52
+ assert_equal '25', @liquid_render.render("{{24.11 | ceil }}")
53
+ end
54
+
55
+ def test_big_decimal_filter_patch
56
+ assert_equal '2.8571', @liquid_render.render("{{ 20 | divided_by: 7.0 | round: 4 }}")
57
+ end
58
+
59
+ def test_floor_filter
60
+ assert_equal '24', @liquid_render.render("{{24.99 | floor }}")
61
+ end
62
+
63
+ def test_currency_filter
64
+ assert_equal '99,99 ₽', @liquid_render.render("{{99.99 | currency: 'RUB' }}")
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../liquid_helper'
2
+ include LiquidHelperMethods
3
+
4
+ module Redmineup
5
+ class ColorsFilterTest < ActiveSupport::TestCase
6
+
7
+ def setup
8
+ @liquid_render = LiquidRender.new
9
+ end
10
+
11
+ def test_hex_color
12
+ assert_match '#ff0000', @liquid_render.render("{{ 'red' | hex_color }}")
13
+ end
14
+
15
+ def test_darken_color
16
+ assert_match '#000066', @liquid_render.render("{{ 'blue' | darken_color }}")
17
+ end
18
+
19
+ def test_lighten_color
20
+ assert_match '#9999ff', @liquid_render.render("{{ 'blue' | lighten_color }}")
21
+ end
22
+
23
+ def test_contrasting_text_color
24
+ assert_match '#9999ff', @liquid_render.render("{{ 'blue' | contrasting_text_color }}")
25
+ end
26
+
27
+ def test_convert_to_brightness_value
28
+ assert_match '15', @liquid_render.render("{{ 'blue' | convert_to_brightness_value }}")
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class LiquidRender
4
+
5
+ def initialize(drops = {})
6
+ @objects_hash = [
7
+ {'name' => 'one', "value" => 10},
8
+ {'name' => 'two', "value" => 5},
9
+ {'name' => 'blank', "value" => nil},
10
+ {'name' => 'three', "value" => 6}
11
+ ]
12
+ @registers = {}
13
+ @assigns = {}
14
+ @assigns['objects_arr'] = @objects_hash
15
+ @assigns['issues'] = Redmineup::Liquid::IssuesDrop.new(Issue.all)
16
+ @assigns['now'] = Time.now
17
+ @assigns['today'] = Date.today.strftime(date_format)
18
+ drops.each do |key, drop|
19
+ @assigns[key] = drop
20
+ end
21
+ end
22
+
23
+ def render(content)
24
+ ::Liquid::Template.parse(content).render(::Liquid::Context.new({}, @assigns, @registers)).html_safe
25
+ rescue => e
26
+ e.message
27
+ end
28
+ end
29
+
30
+ module LiquidHelperMethods
31
+ def date_format
32
+ '%d.%m.%Y'
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ class Attachment < ActiveRecord::Base
2
+ belongs_to :author, :class_name => "User"
3
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'project'
2
+ require_relative 'user'
3
+
4
+ class Issue < ActiveRecord::Base
5
+ belongs_to :project
6
+ belongs_to :user
7
+ belongs_to :author, class_name: 'User'
8
+
9
+ has_many :relations_from, class_name: 'IssueRelation', foreign_key: 'issue_from_id', dependent: :delete_all
10
+ has_many :relations_to, class_name: 'IssueRelation', foreign_key: 'issue_to_id', dependent: :delete_all
11
+
12
+ up_acts_as_draftable
13
+ up_acts_as_taggable
14
+ up_acts_as_viewed
15
+
16
+ scope :visible, lambda { where('1=1') }
17
+
18
+ def visible?
19
+ true
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'issue'
2
+
3
+ class IssueRelation < ActiveRecord::Base
4
+ belongs_to :issue_from, :class_name => 'Issue'
5
+ belongs_to :issue_to, :class_name => 'Issue'
6
+
7
+ def other_issue(issue)
8
+ (self.issue_from_id == issue.id) ? issue_to : issue_from
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ class News < ActiveRecord::Base
2
+ belongs_to :author, :class_name => 'User'
3
+ end
@@ -0,0 +1,8 @@
1
+ class Project < ActiveRecord::Base
2
+ STATUS_ACTIVE = 1
3
+ has_many :issues, :dependent => :destroy
4
+
5
+ def active?
6
+ status == STATUS_ACTIVE
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :issues
3
+
4
+ def self.current
5
+ User.first
6
+ end
7
+
8
+ def anonymous?
9
+ false
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ class Voter < ActiveRecord::Base
2
+ up_acts_as_voter
3
+ end
4
+
5
+ class Votable < ActiveRecord::Base
6
+ up_acts_as_votable
7
+ validates_presence_of :name
8
+ end
9
+
10
+ class VotableVoter < ActiveRecord::Base
11
+ up_acts_as_votable
12
+ up_acts_as_voter
13
+ end
14
+
15
+ class StiVotable < ActiveRecord::Base
16
+ up_acts_as_votable
17
+ end
18
+
19
+ class ChildOfStiVotable < StiVotable
20
+ end
21
+
22
+ class StiNotVotable < ActiveRecord::Base
23
+ validates_presence_of :name
24
+ end
25
+
26
+ class VotableChildOfStiNotVotable < StiNotVotable
27
+ up_acts_as_votable
28
+ end
29
+
30
+ class VotableCache < ActiveRecord::Base
31
+ up_acts_as_votable
32
+ validates_presence_of :name
33
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class MoneyHelperTest < ActiveSupport::TestCase
4
+ include Redmineup::MoneyHelper
5
+
6
+ def test_price_to_currency
7
+ assert_equal '$3,265.65', price_to_currency(3265.65, 'USD')
8
+ assert_equal '3.265,65 ₽', price_to_currency(3265.65, 'RUB')
9
+ assert_equal '3,200.0', price_to_currency(3200, '')
10
+ assert_equal '3,200.0', price_to_currency(3200, 'Foo')
11
+ end
12
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,144 @@
1
+ ActiveRecord::Schema.define version: 0 do
2
+
3
+ create_table :attachments, force: true do |t|
4
+ t.integer :container_id
5
+ t.string :container_type, limit: 30
6
+ t.string :filename, default: "", null: false
7
+ t.string :disk_filename, default: "", null: false
8
+ t.bigint :filesize, default: 0, null: false
9
+ t.string :content_type, default: ""
10
+ t.string :digest, limit: 64, default: "", null: false
11
+ t.integer :downloads, default: 0, null: false
12
+ t.integer :author_id, default: 0, null: false
13
+ t.timestamp :created_on
14
+ t.string :description
15
+ t.string :disk_directory
16
+ end
17
+
18
+ create_table :drafts, force: true do |t|
19
+ t.string :target_type
20
+ t.integer :target_id
21
+ t.references :project
22
+ t.references :user
23
+ t.references :parent, polymorphic: true
24
+ t.binary :data
25
+ t.datetime :updated_at
26
+ end
27
+
28
+ create_table "tags", :force => true do |t|
29
+ t.column "name", :string
30
+ end
31
+
32
+ create_table "taggings", :force => true do |t|
33
+ t.column "tag_id", :integer
34
+ t.column "taggable_id", :integer
35
+ t.column "taggable_type", :string
36
+ t.column "created_at", :datetime
37
+ end
38
+
39
+ create_table "users", :force => true do |t|
40
+ t.column "name", :string
41
+ t.column "language", :string
42
+ end
43
+
44
+ create_table "issue_relations", :force => true do |t|
45
+ t.column "issue_from_id", :integer
46
+ t.column "issue_to_id", :integer
47
+ t.column "relation_type", :string
48
+ t.column "delay", :integer
49
+ end
50
+
51
+ create_table "issues", :force => true do |t|
52
+ t.integer "project_id"
53
+ t.column "subject", :string
54
+ t.column "description", :string
55
+ t.column "closed", :boolean
56
+ t.column "cached_tag_list", :string
57
+ t.column "user_id", :integer
58
+ t.column "author_id", :integer
59
+ t.column "views", :integer, :default => 0
60
+ t.column "total_views", :integer, :default => 0
61
+ end
62
+
63
+ create_table "votes", :force => true do |t|
64
+ t.references "votable", :polymorphic => true
65
+ t.references "voter", :polymorphic => true
66
+
67
+ t.boolean "vote_flag"
68
+ t.string "vote_scope"
69
+ t.integer "vote_weight"
70
+ t.string "vote_ip"
71
+
72
+ t.timestamps
73
+ end
74
+
75
+ create_table "news", :force => true do |t|
76
+ t.string "title"
77
+ t.text "description"
78
+ t.integer "author_id"
79
+ end
80
+
81
+ create_table "projects", :force => true do |t|
82
+ t.string "name"
83
+ t.text "description"
84
+ t.string "identifier"
85
+ t.integer "status"
86
+ end
87
+
88
+ create_table :voters, :force => true do |t|
89
+ t.string :name
90
+ end
91
+
92
+ create_table :not_voters, :force => true do |t|
93
+ t.string :name
94
+ end
95
+
96
+ create_table :votables, :force => true do |t|
97
+ t.string :name
98
+ end
99
+
100
+ create_table :votable_voters, :force => true do |t|
101
+ t.string :name
102
+ end
103
+
104
+ create_table :sti_votables, :force => true do |t|
105
+ t.string :name
106
+ t.string :type
107
+ end
108
+
109
+ create_table :sti_not_votables, :force => true do |t|
110
+ t.string :name
111
+ t.string :type
112
+ end
113
+
114
+ create_table :not_votables, :force => true do |t|
115
+ t.string :name
116
+ end
117
+
118
+ create_table :votable_caches, :force => true do |t|
119
+ t.string :name
120
+ t.integer :cached_votes_total
121
+ t.integer :cached_votes_score
122
+ t.integer :cached_votes_up
123
+ t.integer :cached_votes_down
124
+ t.integer :cached_weighted_total
125
+ t.integer :cached_weighted_score
126
+ t.float :cached_weighted_average
127
+
128
+ t.integer :cached_scoped_test_votes_total
129
+ t.integer :cached_scoped_test_votes_score
130
+ t.integer :cached_scoped_test_votes_up
131
+ t.integer :cached_scoped_test_votes_down
132
+ t.integer :cached_scoped_weighted_total
133
+ t.integer :cached_scoped_weighted_score
134
+ t.float :cached_scoped_weighted_average
135
+ end
136
+
137
+ create_table :viewings, :force => true do |t|
138
+ t.column :viewer_id, :integer
139
+ t.column :viewed_id, :integer
140
+ t.column :viewed_type, :string
141
+ t.column :ip, :string, :limit => '24'
142
+ t.column :created_at, :datetime
143
+ end
144
+ end