redmine_crm 0.0.54 → 0.0.57
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bitbucket-pipelines.yml +0 -20
- data/config/locales/cs.yml +13 -0
- data/config/locales/de.yml +13 -0
- data/doc/CHANGELOG +17 -1
- data/lib/redmine_crm/acts_as_priceable/rcrm_acts_as_priceable.rb +33 -0
- data/lib/redmine_crm/acts_as_taggable/rcrm_acts_as_taggable.rb +3 -3
- data/lib/redmine_crm/acts_as_taggable/tag_list.rb +1 -1
- data/lib/redmine_crm/acts_as_votable/rcrm_acts_as_votable.rb +1 -1
- data/lib/redmine_crm/acts_as_votable/votable.rb +2 -2
- data/lib/redmine_crm/liquid/drops/attachment_drop.rb +49 -0
- data/lib/redmine_crm/liquid/drops/issue_relations_drop.rb +41 -0
- data/lib/redmine_crm/liquid/drops/issues_drop.rb +29 -25
- data/lib/redmine_crm/patches/liquid_patch.rb +33 -0
- data/lib/redmine_crm/version.rb +1 -1
- data/lib/redmine_crm.rb +8 -2
- data/redmine_crm.gemspec +1 -0
- data/test/acts_as_taggable/rcrm_acts_as_taggable_test.rb +97 -92
- data/test/liquid/drops/issue_relations_drop_test.rb +24 -0
- data/test/liquid/filters/base_filter_test.rb +4 -0
- data/test/models/issue.rb +7 -0
- data/test/models/issue_relation.rb +10 -0
- data/test/schema.rb +7 -1
- data/test/tags_helper_test.rb +4 -4
- metadata +14 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 214cac797343372370ee81fb9edd38aba5e67ce9d47ad15276952da329f6f876
|
4
|
+
data.tar.gz: d1b987d030f3c4fcd6c10c6cfdd3cb42c8b7bbd2014ce2ab1653c6adce75f3e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94df5375a9504037d560bcd3da69c76d1915539056e3da79978c3548d950364afb09e594a6c4ef478e8901aa84ee407c66426d8aecc98f882929a94e43d3ab9e
|
7
|
+
data.tar.gz: 239c0df29c90a226d5ba7c62d5838a60311b3e3a6ac6dc70bcbeb4361f5fa130b0133de2ac1d83527a5850572e37153fa394d9a64eea6301c6946853170b4a08
|
data/bitbucket-pipelines.yml
CHANGED
@@ -19,26 +19,6 @@ pipelines:
|
|
19
19
|
services:
|
20
20
|
- mysql
|
21
21
|
- postgres
|
22
|
-
- step:
|
23
|
-
name: Old ruby
|
24
|
-
image: ruby:1.9.3
|
25
|
-
script:
|
26
|
-
- sed -i "s/'rails'/'rails'\n spec.add_runtime_dependency 'rake', '~> 11.2.0'/g" redmine_crm.gemspec
|
27
|
-
- sed -i "s/'rails'/'rails'\n spec.add_runtime_dependency 'i18n', '~> 0.9.5'/g" redmine_crm.gemspec
|
28
|
-
- sed -i "s/'rails'/'rails'\n spec.add_runtime_dependency 'nokogiri', '~> 1.6.8'/g" redmine_crm.gemspec
|
29
|
-
- sed -i "s/'rails'/'rails', '~> 4.2.11'/g" redmine_crm.gemspec
|
30
|
-
- sed -i "s/'sqlite3'/'sqlite3', '~> 1.3.6'/g" redmine_crm.gemspec
|
31
|
-
- sed -i "s/'mysql2'/'mysql2', '~> 0.4.0'/g" redmine_crm.gemspec
|
32
|
-
- sed -i "s/'pg'/'pg', '~> 0.18.0'/g" redmine_crm.gemspec
|
33
|
-
- sed -i "s/^end/ spec.add_development_dependency 'minitest', '~> 5.11.3'\nend/g" redmine_crm.gemspec
|
34
|
-
- sed -i "s/^end/ spec.add_development_dependency 'sprockets', '~> 3.5.2'\nend/g" redmine_crm.gemspec
|
35
|
-
- sed -i "s/^end/ spec.add_development_dependency 'thor', '~> 0.20.3'\nend/g" redmine_crm.gemspec
|
36
|
-
- sed -i "s/'rubyzip'/'rubyzip', '~> 1.3.0'/g" redmine_crm.gemspec
|
37
|
-
- bundle install
|
38
|
-
- bundle exec rake test DB=sqlite
|
39
|
-
- bundle exec rake test DB=mysql
|
40
|
-
services:
|
41
|
-
- mysql
|
42
22
|
|
43
23
|
definitions:
|
44
24
|
services:
|
@@ -0,0 +1,13 @@
|
|
1
|
+
cs:
|
2
|
+
label_redmine_crm_settings: Peníze
|
3
|
+
label_redmine_crm_money: Peníze
|
4
|
+
|
5
|
+
label_redmine_crm_disable_taxes: Znemožnit daně
|
6
|
+
label_redmine_crm_default_tax: Výchozí hodnota daně
|
7
|
+
label_redmine_crm_tax_type: Typ daně
|
8
|
+
label_redmine_crm_tax_type_exclusive: Bez daně
|
9
|
+
label_redmine_crm_tax_type_inclusive: Včetně daně
|
10
|
+
label_redmine_crm_default_currency: Výchozí měna
|
11
|
+
label_redmine_crm_major_currencies: Hlavní měny
|
12
|
+
label_redmine_crm_thousands_delimiter: Oddělovač tisíců
|
13
|
+
label_redmine_crm_decimal_separator: Desetinný oddělovač
|
@@ -0,0 +1,13 @@
|
|
1
|
+
de:
|
2
|
+
label_redmine_crm_settings: Währungseinstellungen
|
3
|
+
label_redmine_crm_money: Währung
|
4
|
+
|
5
|
+
label_redmine_crm_disable_taxes: Steuern deaktiviert
|
6
|
+
label_redmine_crm_default_tax: Standard Steuersatz
|
7
|
+
label_redmine_crm_tax_type: Steuerart
|
8
|
+
label_redmine_crm_tax_type_exclusive: Steuer ausgeschlossen
|
9
|
+
label_redmine_crm_tax_type_inclusive: Steuer eingeschlossen
|
10
|
+
label_redmine_crm_default_currency: Standard Währung
|
11
|
+
label_redmine_crm_major_currencies: Aktive Währungen
|
12
|
+
label_redmine_crm_thousands_delimiter: Tausendertrennzeichen
|
13
|
+
label_redmine_crm_decimal_separator: Dezimaltrennzeichen
|
data/doc/CHANGELOG
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
== Redmine CRM gem changelog
|
2
2
|
|
3
3
|
Redmine crm gem - general functions for plugins (tags, vote, viewing, currency)
|
4
|
-
Copyright (C) 2011-
|
4
|
+
Copyright (C) 2011-2022 RedmineUP
|
5
5
|
https://www.redmineup.com/
|
6
6
|
|
7
|
+
== 2022-02-14 v0.0.57
|
8
|
+
|
9
|
+
* Fixed BigDecimal liquid bug for ruby > 2.6
|
10
|
+
|
11
|
+
== 2022-02-14 v0.0.56
|
12
|
+
|
13
|
+
* Added rcrm_acts_as_priceable
|
14
|
+
* Added IssueRealtions drops
|
15
|
+
|
16
|
+
== 2021-06-08 v0.0.55
|
17
|
+
|
18
|
+
* Added Attachment Liquid drop
|
19
|
+
* Added section to Checklist Liquid drop
|
20
|
+
* Added Czech locale
|
21
|
+
* Added German locale
|
22
|
+
|
7
23
|
== 2020-08-10 v0.0.54
|
8
24
|
|
9
25
|
* Fixed new JQuery select2 bug
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RedmineCrm
|
2
|
+
module ActsAsPriceable
|
3
|
+
module Base
|
4
|
+
def rcrm_acts_as_priceable(*args)
|
5
|
+
priceable_options = args
|
6
|
+
priceable_options << :price if priceable_options.empty?
|
7
|
+
priceable_methods = ""
|
8
|
+
priceable_options.each do |priceable_attr|
|
9
|
+
priceable_methods << %(
|
10
|
+
def #{priceable_attr.to_s}_to_s
|
11
|
+
object_price(
|
12
|
+
self,
|
13
|
+
:#{priceable_attr},
|
14
|
+
{
|
15
|
+
:decimal_mark => RedmineCrm::Settings::Money.decimal_separator,
|
16
|
+
:thousands_separator => RedmineCrm::Settings::Money.thousands_delimiter
|
17
|
+
}
|
18
|
+
) if self.respond_to?(:#{priceable_attr})
|
19
|
+
end
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
class_eval <<-EOV
|
24
|
+
include RedmineCrm::MoneyHelper
|
25
|
+
|
26
|
+
#{priceable_methods}
|
27
|
+
EOV
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
ActiveRecord::Base.extend RedmineCrm::ActsAsPriceable::Base
|
@@ -90,7 +90,7 @@ module RedmineCrm
|
|
90
90
|
#Return all avalible tags for a project or global
|
91
91
|
#Example: Question.available_tags(:project => @project_id )
|
92
92
|
def available_tags(options = {})
|
93
|
-
|
93
|
+
projects = [[options[:project]], options[:projects]].flatten.compact
|
94
94
|
limit = options[:limit].to_i.zero? ? 30 : options[:limit].to_i
|
95
95
|
scope = Tag.where({})
|
96
96
|
class_name = quote_string_value(base_class.name)
|
@@ -98,9 +98,9 @@ module RedmineCrm
|
|
98
98
|
join << "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id "
|
99
99
|
join << "JOIN #{table_name} ON #{table_name}.id = #{Tagging.table_name}.taggable_id
|
100
100
|
AND #{Tagging.table_name}.taggable_type = #{class_name} "
|
101
|
-
if attribute_names.include?('project_id') &&
|
101
|
+
if attribute_names.include?('project_id') && projects.any?
|
102
102
|
join << "JOIN #{Project.table_name} ON #{Project.table_name}.id = #{table_name}.project_id"
|
103
|
-
scope = scope.where("#{table_name}.project_id
|
103
|
+
scope = scope.where("#{table_name}.project_id IN (%s)", projects.map(&:id).join(','))
|
104
104
|
end
|
105
105
|
|
106
106
|
if options[:name_like]
|
@@ -233,9 +233,9 @@ module RedmineCrm
|
|
233
233
|
end
|
234
234
|
self.record_timestamps = false
|
235
235
|
if (::ActiveRecord::VERSION::MAJOR == 3) && (::ActiveRecord::VERSION::MINOR != 0)
|
236
|
-
self.
|
236
|
+
self.assign_attributes(updates, :without_protection => true) && self.save if !updates.empty?
|
237
237
|
else
|
238
|
-
self.
|
238
|
+
self.assign_attributes(updates) && self.save if !updates.empty?
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RedmineCrm
|
2
|
+
module Liquid
|
3
|
+
class AttachmentDrop < ::Liquid::Drop
|
4
|
+
delegate :id,
|
5
|
+
:filename,
|
6
|
+
:title,
|
7
|
+
:description,
|
8
|
+
:filesize,
|
9
|
+
:content_type,
|
10
|
+
:digest,
|
11
|
+
:downloads,
|
12
|
+
:created_on,
|
13
|
+
:token,
|
14
|
+
:visible?,
|
15
|
+
:image?,
|
16
|
+
:thumbnailable?,
|
17
|
+
:is_text?,
|
18
|
+
:readable?,
|
19
|
+
to: :@attachment
|
20
|
+
|
21
|
+
delegate :id, :filename, :filesize, :description, to: :@attachment
|
22
|
+
|
23
|
+
def initialize(attachment)
|
24
|
+
@attachment = attachment
|
25
|
+
end
|
26
|
+
|
27
|
+
def url(options = {})
|
28
|
+
Rails.application.routes.url_helpers.download_named_attachment_url(@attachment, { filename: filename,
|
29
|
+
host: Setting.host_name,
|
30
|
+
protocol: Setting.protocol }.merge(options))
|
31
|
+
end
|
32
|
+
|
33
|
+
def link
|
34
|
+
link_to((@attachment.description.blank? ? @attachment.filename : @attachment.description), url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def author
|
38
|
+
@author ||= UsersDrop.new @attachment.author
|
39
|
+
end
|
40
|
+
|
41
|
+
def read
|
42
|
+
@content ||= if @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
|
43
|
+
File.new(@attachment.diskfile, "rb").read
|
44
|
+
end
|
45
|
+
@content
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RedmineCrm
|
2
|
+
module Liquid
|
3
|
+
class IssueRelationsDrop < ::Liquid::Drop
|
4
|
+
def initialize(relations)
|
5
|
+
@relations = relations
|
6
|
+
end
|
7
|
+
|
8
|
+
def all
|
9
|
+
@all ||= @relations.map { |relation| IssueRelationDrop.new(relation) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def visible
|
13
|
+
@visible ||= @all.select(&:visible?)
|
14
|
+
end
|
15
|
+
|
16
|
+
def each(&block)
|
17
|
+
all.each(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def size
|
21
|
+
@relations.size
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class IssueRelationDrop < ::Liquid::Drop
|
26
|
+
delegate :relation_type, :delay, to: :@relation
|
27
|
+
|
28
|
+
def initialize(relation)
|
29
|
+
@relation = relation
|
30
|
+
end
|
31
|
+
|
32
|
+
def issue_from
|
33
|
+
@issue_from ||= IssueDrop.new(@relation.issue_from)
|
34
|
+
end
|
35
|
+
|
36
|
+
def issue_to
|
37
|
+
@issue_to ||= IssueDrop.new(@relation.issue_to)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -6,14 +6,15 @@ module RedmineCrm
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def before_method(id)
|
9
|
-
issue = @issues.where(:
|
9
|
+
issue = @issues.where(id: id).first || Issue.new
|
10
10
|
IssueDrop.new issue
|
11
11
|
end
|
12
12
|
|
13
13
|
def all
|
14
|
-
@all ||=
|
15
|
-
|
16
|
-
|
14
|
+
@all ||=
|
15
|
+
@issues.map do |issue|
|
16
|
+
IssueDrop.new issue
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def visible
|
@@ -49,14 +50,14 @@ module RedmineCrm
|
|
49
50
|
:closed_on,
|
50
51
|
:updated_on,
|
51
52
|
:created_on,
|
52
|
-
:
|
53
|
+
to: :@issue
|
53
54
|
|
54
55
|
def initialize(issue)
|
55
56
|
@issue = issue
|
56
57
|
end
|
57
58
|
|
58
59
|
def link
|
59
|
-
link_to @issue.subject,
|
60
|
+
link_to @issue.subject, url
|
60
61
|
end
|
61
62
|
|
62
63
|
def url
|
@@ -96,15 +97,23 @@ module RedmineCrm
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def parent
|
99
|
-
@parent ||= IssueDrop.new @issue.parent if @issue.parent
|
100
|
+
@parent ||= IssueDrop.new @issue.parent if @issue.parent
|
100
101
|
end
|
101
102
|
|
102
103
|
def project
|
103
|
-
@project ||= ProjectDrop.new @issue.project if @issue.project
|
104
|
+
@project ||= ProjectDrop.new @issue.project if @issue.project
|
104
105
|
end
|
105
106
|
|
106
107
|
def subtasks
|
107
|
-
@subtasks ||= IssuesDrop.new @issue.children
|
108
|
+
@subtasks ||= IssuesDrop.new @issue.children
|
109
|
+
end
|
110
|
+
|
111
|
+
def relations_from
|
112
|
+
@relations_from ||= IssueRelationsDrop.new(@issue.relations_from.select { |r| r.other_issue(@issue) && r.other_issue(@issue).visible? })
|
113
|
+
end
|
114
|
+
|
115
|
+
def relations_to
|
116
|
+
@relations_to ||= IssueRelationsDrop.new(@issue.relations_to.select { |r| r.other_issue(@issue) && r.other_issue(@issue).visible? })
|
108
117
|
end
|
109
118
|
|
110
119
|
def notes
|
@@ -126,19 +135,20 @@ module RedmineCrm
|
|
126
135
|
def color
|
127
136
|
@issue.respond_to?(:color) && @issue.color
|
128
137
|
end
|
129
|
-
|
138
|
+
|
130
139
|
def day_in_state
|
131
140
|
@issue.respond_to?(:day_in_state) && @issue.day_in_state
|
132
141
|
end
|
133
142
|
|
134
143
|
def checklists
|
135
|
-
@issue.respond_to?(:checklists) && @issue.checklists.map
|
144
|
+
@issue.respond_to?(:checklists) && @issue.checklists.map do |item|
|
145
|
+
{ 'id_done' => item.is_done, 'subject' => item.subject, 'is_section' => item.is_section }
|
146
|
+
end
|
136
147
|
end
|
137
148
|
|
138
149
|
def custom_field_values
|
139
150
|
@issue.custom_field_values
|
140
|
-
end
|
141
|
-
|
151
|
+
end
|
142
152
|
end
|
143
153
|
|
144
154
|
class JournalsDrop < ::Liquid::Drop
|
@@ -147,9 +157,10 @@ module RedmineCrm
|
|
147
157
|
end
|
148
158
|
|
149
159
|
def all
|
150
|
-
@all ||=
|
151
|
-
|
152
|
-
|
160
|
+
@all ||=
|
161
|
+
@journals.map do |journal|
|
162
|
+
JournalDrop.new journal
|
163
|
+
end
|
153
164
|
end
|
154
165
|
|
155
166
|
def visible
|
@@ -166,12 +177,7 @@ module RedmineCrm
|
|
166
177
|
end
|
167
178
|
|
168
179
|
class JournalDrop < ::Liquid::Drop
|
169
|
-
delegate :id,
|
170
|
-
:notes,
|
171
|
-
:created_on,
|
172
|
-
:private_notes,
|
173
|
-
:to => :@journal,
|
174
|
-
allow_nil: true
|
180
|
+
delegate :id, :notes, :created_on, :private_notes, to: :@journal, allow_nil: true
|
175
181
|
|
176
182
|
def initialize(journal)
|
177
183
|
@journal = journal
|
@@ -182,10 +188,8 @@ module RedmineCrm
|
|
182
188
|
end
|
183
189
|
|
184
190
|
def issue
|
185
|
-
@issue ||= IssueDrop.new @journal.issue if @journal.issue
|
191
|
+
@issue ||= IssueDrop.new @journal.issue if @journal.issue
|
186
192
|
end
|
187
|
-
|
188
193
|
end
|
189
|
-
|
190
194
|
end
|
191
195
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RedmineCrm
|
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?(RedmineCrm::Patches::LiquidPatch::StandardFilters)
|
32
|
+
Liquid::StandardFilters.send(:include, RedmineCrm::Patches::LiquidPatch::StandardFilters)
|
33
|
+
end
|
data/lib/redmine_crm/version.rb
CHANGED
data/lib/redmine_crm.rb
CHANGED
@@ -19,6 +19,7 @@ require 'redmine_crm/acts_as_votable/vote'
|
|
19
19
|
require 'redmine_crm/acts_as_votable/voter'
|
20
20
|
require 'redmine_crm/acts_as_draftable/rcrm_acts_as_draftable'
|
21
21
|
require 'redmine_crm/acts_as_draftable/draft'
|
22
|
+
require 'redmine_crm/acts_as_priceable/rcrm_acts_as_priceable'
|
22
23
|
|
23
24
|
require 'redmine_crm/currency'
|
24
25
|
require 'redmine_crm/helpers/tags_helper'
|
@@ -34,12 +35,15 @@ require 'redmine_crm/liquid/drops/news_drop'
|
|
34
35
|
require 'redmine_crm/liquid/drops/projects_drop'
|
35
36
|
require 'redmine_crm/liquid/drops/users_drop'
|
36
37
|
require 'redmine_crm/liquid/drops/time_entries_drop'
|
38
|
+
require 'redmine_crm/liquid/drops/attachment_drop'
|
39
|
+
require 'redmine_crm/liquid/drops/issue_relations_drop'
|
37
40
|
|
38
41
|
require 'redmine_crm/helpers/external_assets_helper'
|
39
42
|
require 'redmine_crm/helpers/form_tag_helper'
|
40
43
|
require 'redmine_crm/assets_manager'
|
41
44
|
|
42
45
|
require 'redmine_crm/compatibility/application_controller_patch'
|
46
|
+
require 'redmine_crm/patches/liquid_patch' unless BigDecimal.respond_to?(:new)
|
43
47
|
|
44
48
|
module RedmineCrm
|
45
49
|
GEM_NAME = 'redmine_crm'.freeze
|
@@ -61,6 +65,7 @@ end
|
|
61
65
|
def requires_redmine_crm(arg)
|
62
66
|
def compare_versions(requirement, current)
|
63
67
|
raise ArgumentError.new('wrong version format') unless check_version_format(requirement)
|
68
|
+
|
64
69
|
requirement = requirement.split('.').collect(&:to_i)
|
65
70
|
requirement <=> current.slice(0, requirement.size)
|
66
71
|
end
|
@@ -69,7 +74,7 @@ def requires_redmine_crm(arg)
|
|
69
74
|
version =~ /^\d+.?\d*.?\d*$/m
|
70
75
|
end
|
71
76
|
|
72
|
-
arg = { :
|
77
|
+
arg = { version_or_higher: arg } unless arg.is_a?(Hash)
|
73
78
|
arg.assert_valid_keys(:version, :version_or_higher)
|
74
79
|
|
75
80
|
current = RedmineCrm::VERSION.split('.').map { |x| x.to_i }
|
@@ -77,6 +82,7 @@ def requires_redmine_crm(arg)
|
|
77
82
|
case k
|
78
83
|
when :version_or_higher
|
79
84
|
raise ArgumentError.new(':version_or_higher accepts a version string only') unless req.is_a?(String)
|
85
|
+
|
80
86
|
unless compare_versions(req, current) <= 0
|
81
87
|
Rails.logger.error "\033[31m[ERROR]\033[0m Redmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\n\033[31m[ERROR]\033[0m Please update with 'bundle update redmine_crm'." if Rails.logger
|
82
88
|
abort "\033[31mRedmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
|
@@ -84,7 +90,7 @@ def requires_redmine_crm(arg)
|
|
84
90
|
when :version
|
85
91
|
req = [req] if req.is_a?(String)
|
86
92
|
if req.is_a?(Array)
|
87
|
-
unless req.detect {|ver| compare_versions(ver, current) == 0}
|
93
|
+
unless req.detect { |ver| compare_versions(ver, current) == 0 }
|
88
94
|
abort "\033[31mRedmine requires redmine_crm gem version #{req} (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
|
89
95
|
end
|
90
96
|
elsif req.is_a?(Range)
|
data/redmine_crm.gemspec
CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
|
+
spec.required_ruby_version = ">= 2.0.0"
|
20
21
|
|
21
22
|
spec.add_runtime_dependency 'rails'
|
22
23
|
spec.add_runtime_dependency 'liquid', '< 2.6.4'
|
@@ -3,76 +3,81 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|
3
3
|
class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
4
4
|
def test_available_tags
|
5
5
|
assert_equivalent [tags(:feature), tags(:bug), tags(:error), tags(:question)], Issue.available_tags(Project.first)
|
6
|
-
assert_equivalent [tags(:error), tags(:question)], Issue.available_tags(:
|
6
|
+
assert_equivalent [tags(:error), tags(:question)], Issue.available_tags(project: Project.first, limit: 2)
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_find_related_tags_with
|
10
|
-
assert_equivalent [tags(:feature), tags(:bug), tags(:question)], Issue.find_related_tags(
|
10
|
+
assert_equivalent [tags(:feature), tags(:bug), tags(:question)], Issue.find_related_tags('error')
|
11
11
|
assert_equivalent [tags(:feature), tags(:error), tags(:question)], Issue.find_related_tags(tags(:bug))
|
12
|
-
assert_equivalent [tags(:error), tags(:question)], Issue.find_related_tags([
|
12
|
+
assert_equivalent [tags(:error), tags(:question)], Issue.find_related_tags(['New feature', 'bug'])
|
13
13
|
assert_equivalent [tags(:feature), tags(:bug)], Issue.find_related_tags([tags(:error), tags(:question)])
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_find_tagged_with_include_and_order
|
17
|
-
assert_equal issues(:third_issue, :first_issue, :second_issue),
|
17
|
+
assert_equal issues(:third_issue, :first_issue, :second_issue),
|
18
|
+
Issue.find_tagged_with('question', order: 'issues.description DESC', include: :user).to_a
|
18
19
|
end
|
19
20
|
|
20
21
|
def test_find_related_tags_with_non_existent_tags
|
21
|
-
assert_equal [], Issue.find_related_tags(
|
22
|
+
assert_equal [], Issue.find_related_tags('ABCDEFG')
|
22
23
|
assert_equal [], Issue.find_related_tags(['HIJKLM'])
|
23
24
|
end
|
24
25
|
|
25
26
|
def test_find_related_tags_with_nothing
|
26
|
-
assert_equal [], Issue.find_related_tags(
|
27
|
+
assert_equal [], Issue.find_related_tags('')
|
27
28
|
assert_equal [], Issue.find_related_tags([])
|
28
29
|
end
|
29
30
|
|
30
31
|
def test_find_tagged_with
|
31
|
-
assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)],
|
32
|
+
assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)],
|
33
|
+
Issue.find_tagged_with('"error"')
|
32
34
|
assert_equal Issue.find_tagged_with('"error"'), Issue.find_tagged_with(['error'])
|
33
35
|
assert_equal Issue.find_tagged_with('"error"'), Issue.find_tagged_with([tags(:error)])
|
34
36
|
|
35
|
-
assert_equivalent [issues(:second_issue)
|
37
|
+
assert_equivalent [issues(:second_issue)], Issue.find_tagged_with('New feature')
|
36
38
|
assert_equal Issue.find_tagged_with('New feature'), Issue.find_tagged_with(['New feature'])
|
37
39
|
assert_equal Issue.find_tagged_with('New feature'), Issue.find_tagged_with([tags(:feature)])
|
38
40
|
end
|
39
41
|
|
40
42
|
def test_find_tagged_with_nothing
|
41
|
-
assert_equal [], Issue.find_tagged_with(
|
43
|
+
assert_equal [], Issue.find_tagged_with('')
|
42
44
|
assert_equal [], Issue.find_tagged_with([])
|
43
45
|
end
|
44
46
|
|
45
47
|
def test_find_tagged_with_nonexistant_tags
|
46
48
|
assert_equal [], Issue.find_tagged_with('ABCDEFG')
|
47
49
|
assert_equal [], Issue.find_tagged_with(['HIJKLM'])
|
48
|
-
assert_equal [], Issue.find_tagged_with([RedmineCrm::ActsAsTaggable::Tag.new(:
|
50
|
+
assert_equal [], Issue.find_tagged_with([RedmineCrm::ActsAsTaggable::Tag.new(name: 'unsaved tag')])
|
49
51
|
end
|
50
52
|
|
51
53
|
def test_find_tagged_with_match_all
|
52
|
-
assert_equivalent [issues(:second_issue)],
|
54
|
+
assert_equivalent [issues(:second_issue)],
|
55
|
+
Issue.find_tagged_with('error, "bug", "New feature", "question"', match_all: true)
|
53
56
|
end
|
54
57
|
|
55
58
|
def test_find_tagged_with_match_all_and_include
|
56
|
-
assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)],
|
59
|
+
assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)],
|
60
|
+
Issue.find_tagged_with(%w[error question], match_all: true, include: :tags)
|
57
61
|
end
|
58
62
|
|
59
63
|
def test_find_tagged_with_conditions
|
60
|
-
assert_equal [], Issue.find_tagged_with('"error", bug', :
|
64
|
+
assert_equal [], Issue.find_tagged_with('"error", bug', conditions: '1=0')
|
61
65
|
end
|
62
66
|
|
63
67
|
def test_find_tagged_with_duplicates_options_hash
|
64
|
-
options = { :
|
65
|
-
assert_nothing_raised { Issue.find_tagged_with(
|
68
|
+
options = { conditions: '1=1' }.freeze
|
69
|
+
assert_nothing_raised { Issue.find_tagged_with('error', options) }
|
66
70
|
end
|
67
71
|
|
68
72
|
def test_find_tagged_with_exclusions
|
69
|
-
assert_equivalent [issues(:first_issue), issues(:third_issue)], Issue.find_tagged_with(
|
70
|
-
assert_equivalent [issues(:first_issue), issues(:third_issue)],
|
73
|
+
assert_equivalent [issues(:first_issue), issues(:third_issue)], Issue.find_tagged_with('bug', exclude: true)
|
74
|
+
assert_equivalent [issues(:first_issue), issues(:third_issue)],
|
75
|
+
Issue.find_tagged_with("'bug', feature", exclude: true)
|
71
76
|
end
|
72
77
|
|
73
78
|
def test_find_options_for_find_tagged_with_no_tags_returns_empty_hash
|
74
|
-
assert_equal
|
75
|
-
assert_equal
|
79
|
+
assert_equal({}, Issue.find_options_for_find_tagged_with(''))
|
80
|
+
assert_equal({}, Issue.find_options_for_find_tagged_with([nil]))
|
76
81
|
end
|
77
82
|
|
78
83
|
def test_find_options_for_find_tagged_with_leaves_arguments_unchanged
|
@@ -82,10 +87,10 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
82
87
|
end
|
83
88
|
|
84
89
|
def test_find_options_for_find_tagged_with_respects_custom_table_name
|
85
|
-
RedmineCrm::ActsAsTaggable::Tagging.table_name =
|
86
|
-
RedmineCrm::ActsAsTaggable::Tag.table_name =
|
90
|
+
RedmineCrm::ActsAsTaggable::Tagging.table_name = 'categorisations'
|
91
|
+
RedmineCrm::ActsAsTaggable::Tag.table_name = 'categories'
|
87
92
|
|
88
|
-
options = Issue.find_options_for_find_tagged_with(
|
93
|
+
options = Issue.find_options_for_find_tagged_with('Hello')
|
89
94
|
|
90
95
|
assert_no_match(/ taggings /, options[:joins])
|
91
96
|
assert_no_match(/ tags /, options[:joins])
|
@@ -93,156 +98,156 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
93
98
|
assert_match(/ categorisations /, options[:joins])
|
94
99
|
assert_match(/ categories /, options[:joins])
|
95
100
|
ensure
|
96
|
-
RedmineCrm::ActsAsTaggable::Tagging.table_name =
|
97
|
-
RedmineCrm::ActsAsTaggable::Tag.table_name =
|
101
|
+
RedmineCrm::ActsAsTaggable::Tagging.table_name = 'taggings'
|
102
|
+
RedmineCrm::ActsAsTaggable::Tag.table_name = 'tags'
|
98
103
|
end
|
99
104
|
|
100
105
|
def test_include_tags_on_find_tagged_with
|
101
106
|
assert_nothing_raised do
|
102
|
-
Issue.find_tagged_with('error', :
|
103
|
-
Issue.find_tagged_with(
|
107
|
+
Issue.find_tagged_with('error', include: :tags)
|
108
|
+
Issue.find_tagged_with('error', include: { taggings: :tag })
|
104
109
|
end
|
105
110
|
end
|
106
111
|
|
107
112
|
def test_basic_tag_counts_on_class
|
108
|
-
assert_tag_counts Issue.tag_counts, :
|
113
|
+
assert_tag_counts Issue.tag_counts, error: 3, feature: 1, question: 3, bug: 1
|
109
114
|
end
|
110
115
|
|
111
116
|
def test_tag_counts_on_class_with_date_conditions
|
112
|
-
assert_tag_counts Issue.tag_counts(:
|
113
|
-
assert_tag_counts Issue.tag_counts(:
|
114
|
-
assert_tag_counts Issue.tag_counts(:
|
117
|
+
assert_tag_counts Issue.tag_counts(start_at: Date.new(2015, 1, 1)), error: 2, feature: 1, question: 3, bug: 1
|
118
|
+
assert_tag_counts Issue.tag_counts(end_at: Date.new(2014, 12, 31)), error: 1
|
119
|
+
assert_tag_counts Issue.tag_counts(start_at: Date.new(2015, 1, 31), end_at: Date.new(2015, 3, 1)), question: 1
|
115
120
|
end
|
116
121
|
|
117
122
|
def test_tag_counts_on_class_with_frequencies
|
118
|
-
assert_tag_counts Issue.tag_counts(:
|
119
|
-
assert_tag_counts Issue.tag_counts(:
|
123
|
+
assert_tag_counts Issue.tag_counts(at_least: 2), question: 3, error: 3
|
124
|
+
assert_tag_counts Issue.tag_counts(at_most: 2), bug: 1, feature: 1
|
120
125
|
end
|
121
126
|
|
122
127
|
def test_tag_counts_on_class_with_frequencies_and_conditions
|
123
|
-
assert_tag_counts Issue.tag_counts(:
|
128
|
+
assert_tag_counts Issue.tag_counts(at_least: 2, conditions: '1=1'), question: 3, error: 3
|
124
129
|
end
|
125
130
|
|
126
131
|
def test_tag_counts_duplicates_options_hash
|
127
|
-
options = { :
|
132
|
+
options = { at_least: 2, conditions: '1=1' }.freeze
|
128
133
|
assert_nothing_raised { Issue.tag_counts(options) }
|
129
134
|
end
|
130
135
|
|
131
136
|
def test_tag_counts_with_limit
|
132
|
-
assert_equal 2, Issue.tag_counts(:
|
133
|
-
assert_equal 2, Issue.tag_counts(:
|
137
|
+
assert_equal 2, Issue.tag_counts(limit: 2).to_a.size
|
138
|
+
assert_equal 2, Issue.tag_counts(at_least: 3, limit: 2).to_a.size
|
134
139
|
end
|
135
140
|
|
136
141
|
def test_tag_counts_with_limit_and_order
|
137
|
-
assert_equivalent RedmineCrm::ActsAsTaggable::Tag.where(:
|
142
|
+
assert_equivalent RedmineCrm::ActsAsTaggable::Tag.where(id: [tags(:error), tags(:question)]),
|
143
|
+
Issue.tag_counts(order: 'count desc', limit: 2)
|
138
144
|
end
|
139
145
|
|
140
146
|
def test_tag_counts_on_association
|
141
|
-
assert_tag_counts users(:jonathan).issues.tag_counts, :
|
142
|
-
assert_tag_counts users(:sam).issues.tag_counts, :
|
147
|
+
assert_tag_counts users(:jonathan).issues.tag_counts, error: 2, bug: 1, question: 2, feature: 1
|
148
|
+
assert_tag_counts users(:sam).issues.tag_counts, error: 1, question: 1
|
143
149
|
end
|
144
150
|
|
145
151
|
def test_tag_counts_on_association_with_options
|
146
|
-
assert_equal [], users(:jonathan).issues.tag_counts(:
|
147
|
-
assert_tag_counts users(:jonathan).issues.tag_counts(:
|
148
|
-
:feature => 1, :error => 2, :question => 2
|
152
|
+
assert_equal [], users(:jonathan).issues.tag_counts(conditions: '1=0')
|
153
|
+
assert_tag_counts users(:jonathan).issues.tag_counts(at_most: 2), bug: 1, feature: 1, error: 2, question: 2
|
149
154
|
end
|
150
155
|
|
151
156
|
def test_tag_counts_on_model_instance
|
152
|
-
assert_tag_counts issues(:third_issue).tag_counts, :
|
157
|
+
assert_tag_counts issues(:third_issue).tag_counts, error: 3, question: 3
|
153
158
|
end
|
154
159
|
|
155
160
|
def test_tag_counts_on_model_instance_merges_conditions
|
156
|
-
assert_tag_counts issues(:first_issue).tag_counts(:
|
161
|
+
assert_tag_counts issues(:first_issue).tag_counts(conditions: "tags.name = 'error'"), error: 3
|
157
162
|
end
|
158
163
|
|
159
164
|
def test_tag_counts_on_model_instance_with_no_tags
|
160
|
-
issue = Issue.create!(:
|
165
|
+
issue = Issue.create!(description: 'desc')
|
161
166
|
|
162
167
|
assert_tag_counts issue.tag_counts, {}
|
163
168
|
end
|
164
169
|
|
165
170
|
def test_tag_counts_should_sanitize_scope_conditions
|
166
|
-
Issue.send :where, {
|
167
|
-
assert_tag_counts Issue.tag_counts, :
|
171
|
+
Issue.send :where, { 'tags.id = ?' => tags(:error).id } do
|
172
|
+
assert_tag_counts Issue.tag_counts, error: 3
|
168
173
|
end
|
169
174
|
end
|
170
175
|
|
171
176
|
def test_tag_counts_respects_custom_table_names
|
172
|
-
RedmineCrm::ActsAsTaggable::Tagging.table_name =
|
173
|
-
RedmineCrm::ActsAsTaggable::Tag.table_name =
|
177
|
+
RedmineCrm::ActsAsTaggable::Tagging.table_name = 'categorisations'
|
178
|
+
RedmineCrm::ActsAsTaggable::Tag.table_name = 'categories'
|
174
179
|
|
175
|
-
options = Issue.find_options_for_tag_counts(:
|
180
|
+
options = Issue.find_options_for_tag_counts(start_at: 2.weeks.ago, end_at: Date.today)
|
176
181
|
sql = options.values.join(' ')
|
177
182
|
|
178
|
-
assert_no_match
|
179
|
-
assert_no_match
|
183
|
+
assert_no_match(/taggings/, sql)
|
184
|
+
assert_no_match(/tags/, sql)
|
180
185
|
|
181
|
-
assert_match
|
182
|
-
assert_match
|
186
|
+
assert_match(/categorisations/, sql)
|
187
|
+
assert_match(/categories/, sql)
|
183
188
|
ensure
|
184
|
-
RedmineCrm::ActsAsTaggable::Tagging.table_name =
|
185
|
-
RedmineCrm::ActsAsTaggable::Tag.table_name =
|
189
|
+
RedmineCrm::ActsAsTaggable::Tagging.table_name = 'taggings'
|
190
|
+
RedmineCrm::ActsAsTaggable::Tag.table_name = 'tags'
|
186
191
|
end
|
187
192
|
|
188
193
|
def test_tag_list_reader
|
189
|
-
assert_equivalent [
|
190
|
-
assert_equivalent [
|
194
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
195
|
+
assert_equivalent ['error', 'New feature', 'bug', 'question'], issues(:second_issue).tag_list
|
191
196
|
end
|
192
197
|
|
193
198
|
def test_reassign_tag_list
|
194
|
-
assert_equivalent [
|
199
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
195
200
|
issues(:first_issue).taggings.reload
|
196
201
|
|
197
202
|
# Only an update of the issues table should be executed, the other two queries are for savepoints
|
198
203
|
# assert_queries 3 do
|
199
|
-
# issues(:first_issue).
|
204
|
+
# issues(:first_issue).update!(:description => "new name", :tag_list => issues(:first_issue).tag_list.to_s)
|
200
205
|
# end
|
201
206
|
|
202
|
-
assert_equivalent [
|
207
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
203
208
|
end
|
204
209
|
|
205
210
|
def test_new_tags
|
206
|
-
assert_equivalent [
|
207
|
-
issues(:first_issue).
|
208
|
-
assert_equivalent [
|
211
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
212
|
+
issues(:first_issue).update!(tag_list: "#{issues(:first_issue).tag_list}, One, Two")
|
213
|
+
assert_equivalent %w[error question One Two], issues(:first_issue).tag_list
|
209
214
|
end
|
210
215
|
|
211
216
|
def test_remove_tag
|
212
|
-
assert_equivalent [
|
213
|
-
issues(:first_issue).
|
214
|
-
assert_equivalent [
|
217
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
218
|
+
issues(:first_issue).update!(tag_list: 'error')
|
219
|
+
assert_equivalent ['error'], issues(:first_issue).tag_list
|
215
220
|
end
|
216
221
|
|
217
222
|
def test_remove_and_add_tag
|
218
|
-
assert_equivalent [
|
219
|
-
issues(:first_issue).
|
220
|
-
assert_equivalent [
|
223
|
+
assert_equivalent %w[error question], issues(:first_issue).tag_list
|
224
|
+
issues(:first_issue).update!(tag_list: 'question, Beautiful')
|
225
|
+
assert_equivalent %w[question Beautiful], issues(:first_issue).tag_list
|
221
226
|
end
|
222
227
|
|
223
228
|
def test_tags_not_saved_if_validation_fails
|
224
229
|
issue = issues(:first_issue)
|
225
|
-
assert_equivalent [
|
230
|
+
assert_equivalent %w[error question], issue.tag_list
|
226
231
|
|
227
232
|
issue.stub(:valid?, false) do
|
228
|
-
assert !issue.
|
233
|
+
assert !issue.update(tag_list: 'One, Two')
|
229
234
|
end
|
230
|
-
assert_equivalent [
|
235
|
+
assert_equivalent %w[error question], Issue.find(issue.id).tag_list
|
231
236
|
end
|
232
237
|
|
233
238
|
def test_tag_list_accessors_on_new_record
|
234
|
-
p = Issue.new(:
|
239
|
+
p = Issue.new(description: 'Test')
|
235
240
|
|
236
241
|
assert p.tag_list.blank?
|
237
|
-
p.tag_list =
|
238
|
-
assert_equal
|
242
|
+
p.tag_list = 'One, Two'
|
243
|
+
assert_equal 'One, Two', p.tag_list.to_s
|
239
244
|
end
|
240
245
|
|
241
246
|
def test_clear_tag_list_with_nil
|
242
247
|
p = issues(:second_issue)
|
243
248
|
|
244
249
|
assert !p.tag_list.blank?
|
245
|
-
assert p.
|
250
|
+
assert p.update(tag_list: nil)
|
246
251
|
assert p.tag_list.blank?
|
247
252
|
|
248
253
|
assert p.reload.tag_list.blank?
|
@@ -252,7 +257,7 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
252
257
|
p = issues(:second_issue)
|
253
258
|
|
254
259
|
assert !p.tag_list.blank?
|
255
|
-
assert p.
|
260
|
+
assert p.update(tag_list: ' ')
|
256
261
|
assert p.tag_list.blank?
|
257
262
|
|
258
263
|
assert p.reload.tag_list.blank?
|
@@ -267,7 +272,7 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
267
272
|
end
|
268
273
|
|
269
274
|
def test_instance_tag_counts
|
270
|
-
assert_tag_counts issues(:first_issue).tag_counts, :
|
275
|
+
assert_tag_counts issues(:first_issue).tag_counts, error: 3, question: 3
|
271
276
|
end
|
272
277
|
|
273
278
|
def test_tag_list_populated_when_cache_nil
|
@@ -279,8 +284,8 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
279
284
|
def test_cached_tag_list_updated
|
280
285
|
assert_nil issues(:first_issue).cached_tag_list
|
281
286
|
issues(:first_issue).save!
|
282
|
-
assert_equivalent [
|
283
|
-
issues(:first_issue).
|
287
|
+
assert_equivalent %w[question error], RedmineCrm::ActsAsTaggable::TagList.from(issues(:first_issue).cached_tag_list)
|
288
|
+
issues(:first_issue).update!(tag_list: 'None')
|
284
289
|
|
285
290
|
assert_equal 'None', issues(:first_issue).cached_tag_list
|
286
291
|
assert_equal 'None', issues(:first_issue).reload.cached_tag_list
|
@@ -290,8 +295,8 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
290
295
|
# Generate the cached tag list
|
291
296
|
issues(:first_issue).save!
|
292
297
|
|
293
|
-
issues(:first_issue).
|
294
|
-
assert_equal
|
298
|
+
issues(:first_issue).update!(tag_list: '')
|
299
|
+
assert_equal '', issues(:first_issue).cached_tag_list
|
295
300
|
end
|
296
301
|
|
297
302
|
def test_find_tagged_with_using_sti
|
@@ -300,19 +305,19 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
300
305
|
end
|
301
306
|
|
302
307
|
def test_case_insensitivity
|
303
|
-
assert_difference
|
304
|
-
Issue.create!(:
|
305
|
-
Issue.create!(:
|
308
|
+
assert_difference 'RedmineCrm::ActsAsTaggable::Tag.count', 1 do
|
309
|
+
Issue.create!(description: 'Test', tag_list: 'one')
|
310
|
+
Issue.create!(description: 'Test', tag_list: 'One')
|
306
311
|
end
|
307
|
-
assert_equal Issue.find_tagged_with(
|
312
|
+
assert_equal Issue.find_tagged_with('question'), Issue.find_tagged_with('question')
|
308
313
|
end
|
309
314
|
|
310
315
|
def test_tag_not_destroyed_when_unused
|
311
|
-
issues(:first_issue).tag_list.add(
|
316
|
+
issues(:first_issue).tag_list.add('Random')
|
312
317
|
issues(:first_issue).save!
|
313
318
|
|
314
319
|
assert_no_difference 'RedmineCrm::ActsAsTaggable::Tag.count' do
|
315
|
-
issues(:first_issue).tag_list.remove(
|
320
|
+
issues(:first_issue).tag_list.remove('Random')
|
316
321
|
issues(:first_issue).save!
|
317
322
|
end
|
318
323
|
end
|
@@ -320,11 +325,11 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
320
325
|
def test_tag_destroyed_when_unused
|
321
326
|
RedmineCrm::ActsAsTaggable::Tag.destroy_unused = true
|
322
327
|
|
323
|
-
issues(:first_issue).tag_list.add(
|
328
|
+
issues(:first_issue).tag_list.add('Random')
|
324
329
|
issues(:first_issue).save!
|
325
330
|
|
326
331
|
assert_difference 'RedmineCrm::ActsAsTaggable::Tag.count', -1 do
|
327
|
-
issues(:first_issue).tag_list.remove(
|
332
|
+
issues(:first_issue).tag_list.remove('Random')
|
328
333
|
issues(:first_issue).save!
|
329
334
|
end
|
330
335
|
ensure
|
@@ -340,6 +345,6 @@ class RcrmActsAsTaggableTest < ActiveSupport::TestCase
|
|
340
345
|
issues(:first_issue).tag_list.remove('error')
|
341
346
|
issues(:first_issue).tag_list.add('new')
|
342
347
|
issues(:first_issue).save!
|
343
|
-
assert_equal %w
|
348
|
+
assert_equal %w[question new], issues(:first_issue).reload.all_tags_list
|
344
349
|
end
|
345
350
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../liquid_helper'
|
2
|
+
include LiquidHelperMethods
|
3
|
+
|
4
|
+
module RedmineCrm
|
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
|
@@ -52,6 +52,10 @@ module RedmineCrm
|
|
52
52
|
assert_equal '25', @liquid_render.render("{{24.11 | ceil }}")
|
53
53
|
end
|
54
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
|
+
|
55
59
|
def test_floor_filter
|
56
60
|
assert_equal '24', @liquid_render.render("{{24.99 | floor }}")
|
57
61
|
end
|
data/test/models/issue.rb
CHANGED
@@ -6,9 +6,16 @@ class Issue < ActiveRecord::Base
|
|
6
6
|
belongs_to :user
|
7
7
|
belongs_to :author, class_name: 'User'
|
8
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
|
+
|
9
12
|
rcrm_acts_as_draftable
|
10
13
|
rcrm_acts_as_taggable
|
11
14
|
rcrm_acts_as_viewed
|
12
15
|
|
13
16
|
scope :visible, lambda { where('1=1') }
|
17
|
+
|
18
|
+
def visible?
|
19
|
+
true
|
20
|
+
end
|
14
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
|
data/test/schema.rb
CHANGED
@@ -21,12 +21,18 @@ ActiveRecord::Schema.define version: 0 do
|
|
21
21
|
t.column "created_at", :datetime
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
create_table "users", :force => true do |t|
|
26
25
|
t.column "name", :string
|
27
26
|
t.column "language", :string
|
28
27
|
end
|
29
28
|
|
29
|
+
create_table "issue_relations", :force => true do |t|
|
30
|
+
t.column "issue_from_id", :integer
|
31
|
+
t.column "issue_to_id", :integer
|
32
|
+
t.column "relation_type", :string
|
33
|
+
t.column "delay", :integer
|
34
|
+
end
|
35
|
+
|
30
36
|
create_table "issues", :force => true do |t|
|
31
37
|
t.integer "project_id"
|
32
38
|
t.column "subject", :string
|
data/test/tags_helper_test.rb
CHANGED
@@ -3,10 +3,10 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
3
3
|
# module RedmineCrm
|
4
4
|
class TagsHelperTest < ActiveSupport::TestCase
|
5
5
|
include RedmineCrm::TagsHelper
|
6
|
-
|
6
|
+
|
7
7
|
def test_tag_cloud
|
8
8
|
cloud_elements = []
|
9
|
-
|
9
|
+
|
10
10
|
tag_cloud Issue.tag_counts, %w(css1 css2 css3 css4) do |tag, css_class|
|
11
11
|
cloud_elements << [tag, css_class]
|
12
12
|
end
|
@@ -16,7 +16,7 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
16
16
|
assert cloud_elements.include?([tags(:feature), "css2"])
|
17
17
|
assert_equal 4, cloud_elements.size
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# def test_tag_cloud_when_no_tags
|
21
21
|
# cloud_elements = []
|
22
22
|
# tag_cloud SpecialIssue.tag_counts, %w(css1) do |tag, css_class|
|
@@ -26,4 +26,4 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
26
26
|
# assert_equal 0, cloud_elements.size
|
27
27
|
# end
|
28
28
|
end
|
29
|
-
# end
|
29
|
+
# end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redmine_crm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.57
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RedmineUP
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -111,6 +111,8 @@ files:
|
|
111
111
|
- app/views/redmine_crm/settings.html.erb
|
112
112
|
- bitbucket-pipelines.yml
|
113
113
|
- config/currency_iso.json
|
114
|
+
- config/locales/cs.yml
|
115
|
+
- config/locales/de.yml
|
114
116
|
- config/locales/en.yml
|
115
117
|
- config/locales/ru.yml
|
116
118
|
- config/routes.rb
|
@@ -120,6 +122,7 @@ files:
|
|
120
122
|
- lib/redmine_crm/acts_as_draftable/draft.rb
|
121
123
|
- lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb
|
122
124
|
- lib/redmine_crm/acts_as_list/list.rb
|
125
|
+
- lib/redmine_crm/acts_as_priceable/rcrm_acts_as_priceable.rb
|
123
126
|
- lib/redmine_crm/acts_as_taggable/rcrm_acts_as_taggable.rb
|
124
127
|
- lib/redmine_crm/acts_as_taggable/tag.rb
|
125
128
|
- lib/redmine_crm/acts_as_taggable/tag_list.rb
|
@@ -143,6 +146,8 @@ files:
|
|
143
146
|
- lib/redmine_crm/helpers/tags_helper.rb
|
144
147
|
- lib/redmine_crm/helpers/vote_helper.rb
|
145
148
|
- lib/redmine_crm/hooks/views_layouts_hook.rb
|
149
|
+
- lib/redmine_crm/liquid/drops/attachment_drop.rb
|
150
|
+
- lib/redmine_crm/liquid/drops/issue_relations_drop.rb
|
146
151
|
- lib/redmine_crm/liquid/drops/issues_drop.rb
|
147
152
|
- lib/redmine_crm/liquid/drops/news_drop.rb
|
148
153
|
- lib/redmine_crm/liquid/drops/projects_drop.rb
|
@@ -152,6 +157,7 @@ files:
|
|
152
157
|
- lib/redmine_crm/liquid/filters/base.rb
|
153
158
|
- lib/redmine_crm/liquid/filters/colors.rb
|
154
159
|
- lib/redmine_crm/money_helper.rb
|
160
|
+
- lib/redmine_crm/patches/liquid_patch.rb
|
155
161
|
- lib/redmine_crm/settings.rb
|
156
162
|
- lib/redmine_crm/settings/money.rb
|
157
163
|
- lib/redmine_crm/version.rb
|
@@ -178,6 +184,7 @@ files:
|
|
178
184
|
- test/fixtures/votable_caches.yml
|
179
185
|
- test/fixtures/votables.yml
|
180
186
|
- test/fixtures/voters.yml
|
187
|
+
- test/liquid/drops/issue_relations_drop_test.rb
|
181
188
|
- test/liquid/drops/issues_drop_test.rb
|
182
189
|
- test/liquid/drops/news_drop_test.rb
|
183
190
|
- test/liquid/drops/projects_drop_test.rb
|
@@ -187,6 +194,7 @@ files:
|
|
187
194
|
- test/liquid/filters/colors_filter_test.rb
|
188
195
|
- test/liquid/liquid_helper.rb
|
189
196
|
- test/models/issue.rb
|
197
|
+
- test/models/issue_relation.rb
|
190
198
|
- test/models/news.rb
|
191
199
|
- test/models/project.rb
|
192
200
|
- test/models/user.rb
|
@@ -215,15 +223,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
223
|
requirements:
|
216
224
|
- - ">="
|
217
225
|
- !ruby/object:Gem::Version
|
218
|
-
version:
|
226
|
+
version: 2.0.0
|
219
227
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
228
|
requirements:
|
221
229
|
- - ">="
|
222
230
|
- !ruby/object:Gem::Version
|
223
231
|
version: '0'
|
224
232
|
requirements: []
|
225
|
-
|
226
|
-
rubygems_version: 2.6.11
|
233
|
+
rubygems_version: 3.1.2
|
227
234
|
signing_key:
|
228
235
|
specification_version: 4
|
229
236
|
summary: Common libraries for RedmineUP plugins for Redmine
|
@@ -250,6 +257,7 @@ test_files:
|
|
250
257
|
- test/fixtures/votable_caches.yml
|
251
258
|
- test/fixtures/votables.yml
|
252
259
|
- test/fixtures/voters.yml
|
260
|
+
- test/liquid/drops/issue_relations_drop_test.rb
|
253
261
|
- test/liquid/drops/issues_drop_test.rb
|
254
262
|
- test/liquid/drops/news_drop_test.rb
|
255
263
|
- test/liquid/drops/projects_drop_test.rb
|
@@ -259,6 +267,7 @@ test_files:
|
|
259
267
|
- test/liquid/filters/colors_filter_test.rb
|
260
268
|
- test/liquid/liquid_helper.rb
|
261
269
|
- test/models/issue.rb
|
270
|
+
- test/models/issue_relation.rb
|
262
271
|
- test/models/news.rb
|
263
272
|
- test/models/project.rb
|
264
273
|
- test/models/user.rb
|