redmine_crm 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,82 @@
1
+ module RedmineCrm
2
+ class Tag < ActiveRecord::Base
3
+ has_many :taggings, :dependent => :destroy
4
+
5
+ validates_presence_of :name
6
+ # validates_uniqueness_of :name
7
+ validates :name, :uniqueness => true
8
+ validates :name, :presence => true
9
+ cattr_accessor :destroy_unused
10
+ self.destroy_unused = false
11
+
12
+ attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity)
13
+
14
+ # LIKE is used for cross-database case-insensitivity
15
+ def self.find_or_create_with_like_by_name(name)
16
+ # find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
17
+ where("name LIKE LOWER(?)", name.downcase).first || create(:name => name)
18
+ end
19
+
20
+ def ==(object)
21
+ super || (object.is_a?(Tag) && name == object.name)
22
+ end
23
+
24
+ def to_s
25
+ name
26
+ end
27
+
28
+ def count
29
+ read_attribute(:count).to_i
30
+ end
31
+
32
+ class << self
33
+ # Calculate the tag counts for all tags.
34
+ # :start_at - Restrict the tags to those created after a certain time
35
+ # :end_at - Restrict the tags to those created before a certain time
36
+ # :conditions - A piece of SQL conditions to add to the query
37
+ # :limit - The maximum number of tags to return
38
+ # :order - A piece of SQL to order by. Eg 'count desc' or 'taggings.created_at desc'
39
+ # :at_least - Exclude tags with a frequency less than the given value
40
+ # :at_most - Exclude tags with a frequency greater than the given value
41
+ def counts(options = {})
42
+ # find(:all, options_for_counts(options))
43
+ opt = options_for_counts(options)
44
+ # byebug
45
+ select(opt[:select]).where(opt[:conditions]).joins(opt[:joins]).group(opt[:group])
46
+ end
47
+
48
+ def options_for_counts(options = {})
49
+ options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :joins
50
+ options = options.dup
51
+
52
+ start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
53
+ end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
54
+
55
+ conditions = [
56
+ (sanitize_sql(options.delete(:conditions)) if options[:conditions]),
57
+ start_at,
58
+ end_at
59
+ ].compact
60
+
61
+ conditions = conditions.join(' AND ') if conditions.any?
62
+
63
+ joins = ["INNER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
64
+ joins << options.delete(:joins) if options[:joins]
65
+
66
+ at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
67
+ at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
68
+ having = "COUNT(*) > 0"
69
+ having = [having, at_least, at_most].compact.join(' AND ')
70
+ group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name"
71
+ # group_by << " AND #{having}" unless having.blank?
72
+
73
+ { :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count",
74
+ :joins => joins.join(" "),
75
+ :conditions => conditions,
76
+ :group => group_by,
77
+ :having => having
78
+ }.update(options)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,112 @@
1
+ module RedmineCrm
2
+ class TagList < Array
3
+ cattr_accessor :delimiter
4
+ self.delimiter = ','
5
+
6
+ def initialize(*args)
7
+ add(*args)
8
+ end
9
+
10
+ # Add tags to the tag_list. Duplicate or blank tags will be ignored.
11
+ #
12
+ # tag_list.add("Fun", "Happy")
13
+ #
14
+ # Use the <tt>:parse</tt> option to add an unparsed tag string.
15
+ #
16
+ # tag_list.add("Fun, Happy", :parse => true)
17
+ def add(*names)
18
+ extract_and_apply_options!(names)
19
+ concat(names)
20
+ clean!
21
+ self
22
+ end
23
+
24
+ # Remove specific tags from the tag_list.
25
+ #
26
+ # tag_list.remove("Sad", "Lonely")
27
+ #
28
+ # Like #add, the <tt>:parse</tt> option can be used to remove multiple tags in a string.
29
+ #
30
+ # tag_list.remove("Sad, Lonely", :parse => true)
31
+ def remove(*names)
32
+ extract_and_apply_options!(names)
33
+ delete_if { |name| names.include?(name) }
34
+ self
35
+ end
36
+
37
+ # Toggle the presence of the given tags.
38
+ # If a tag is already in the list it is removed, otherwise it is added.
39
+ def toggle(*names)
40
+ extract_and_apply_options!(names)
41
+
42
+ names.each do |name|
43
+ include?(name) ? delete(name) : push(name)
44
+ end
45
+
46
+ clean!
47
+ self
48
+ end
49
+
50
+ # Transform the tag_list into a tag string suitable for edting in a form.
51
+ # The tags are joined with <tt>TagList.delimiter</tt> and quoted if necessary.
52
+ #
53
+ # tag_list = TagList.new("Round", "Square,Cube")
54
+ # tag_list.to_s # 'Round, "Square,Cube"'
55
+ def to_s
56
+ clean!
57
+
58
+ map do |name|
59
+ name.include?(delimiter) ? "\"#{name}\"" : name
60
+ end.join(delimiter.ends_with?(" ") ? delimiter : "#{delimiter} ")
61
+ end
62
+
63
+ private
64
+ # Remove whitespace, duplicates, and blanks.
65
+ def clean!
66
+ reject!(&:blank?)
67
+ map!(&:strip)
68
+ uniq!
69
+ end
70
+
71
+ def extract_and_apply_options!(args)
72
+ options = args.last.is_a?(Hash) ? args.pop : {}
73
+ options.assert_valid_keys :parse
74
+
75
+ if options[:parse]
76
+ args.map! { |a| self.class.from(a) }
77
+ end
78
+
79
+ args.flatten!
80
+ end
81
+
82
+ class << self
83
+ # Returns a new TagList using the given tag string.
84
+ #
85
+ # tag_list = TagList.from("One , Two, Three")
86
+ # tag_list # ["One", "Two", "Three"]
87
+ def from(source)
88
+ tag_list = new
89
+
90
+ case source
91
+ when Array
92
+ tag_list.add(source)
93
+ else
94
+ string = source.to_s.dup
95
+
96
+ # Parse the quoted tags
97
+ [
98
+ /\s*#{delimiter}\s*(['"])(.*?)\1\s*/,
99
+ /^\s*(['"])(.*?)\1\s*#{delimiter}?/
100
+ ].each do |re|
101
+ string.gsub!(re) { tag_list << $2; "" }
102
+ end
103
+
104
+ tag_list.add(string.split(delimiter))
105
+ end
106
+
107
+ tag_list
108
+ end
109
+ end
110
+ end
111
+
112
+ end
@@ -0,0 +1,20 @@
1
+ module RedmineCrm
2
+
3
+ class Tagging < ActiveRecord::Base #:nodoc:
4
+ belongs_to :tag
5
+ belongs_to :taggable, :polymorphic => true
6
+
7
+ after_destroy :destroy_tag_if_unused
8
+
9
+ private
10
+
11
+ def destroy_tag_if_unused
12
+ if Tag.destroy_unused
13
+ if tag.taggings.count.zero?
14
+ tag.destroy
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,15 @@
1
+ module RedmineCrm
2
+ module TagsHelper
3
+ # See the README for an example using tag_cloud.
4
+ def tag_cloud(tags, classes)
5
+ return if tags.empty?
6
+
7
+ max_count = tags.sort_by(&:count).last.count.to_f
8
+
9
+ tags.each do |tag|
10
+ index = ((tag.count / max_count) * (classes.size - 1)).round
11
+ yield tag, classes[index]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module RedmineCrm
2
+ VERSION = "0.0.4"
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'redmine_crm/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "redmine_crm"
8
+ spec.version = RedmineCrm::VERSION
9
+ spec.authors = ["RedmineCRM"]
10
+ spec.email = ["support@redminecrm.com"]
11
+ spec.summary = %q{plugins for remine}
12
+ spec.description = %q{plugins for Redmine}
13
+ spec.homepage = ""
14
+ spec.license = "GPL2"
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
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "activerecord"
25
+ spec.add_development_dependency "actionpack"
26
+ spec.add_development_dependency "sqlite3"
27
+ spec.add_development_dependency "mysql2"
28
+ spec.add_development_dependency "activerecord-mysql-adapter"
29
+ spec.add_development_dependency "pg"
30
+ end
@@ -0,0 +1,384 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ActsAsTaggableTest < ActiveSupport::TestCase
4
+ def test_find_related_tags_with
5
+ assert_equivalent [tags(:feature), tags(:bug), tags(:question)], Issue.find_related_tags("error")
6
+ assert_equivalent [tags(:feature), tags(:error), tags(:question)], Issue.find_related_tags(tags(:bug))
7
+ assert_equivalent [tags(:error), tags(:question)], Issue.find_related_tags(["New feature", "bug"])
8
+ assert_equivalent [tags(:feature), tags(:bug)], Issue.find_related_tags([tags(:error), tags(:question)])
9
+ end
10
+
11
+ def test_find_tagged_with_include_and_order
12
+ assert_equal issues(:third_issue, :first_issue, :second_issue), Issue.find_tagged_with("question", :order => "issues.description DESC", :include => :user).to_a
13
+ end
14
+
15
+ def test_find_related_tags_with_non_existent_tags
16
+ assert_equal [], Issue.find_related_tags("ABCDEFG")
17
+ assert_equal [], Issue.find_related_tags(['HIJKLM'])
18
+ end
19
+
20
+ def test_find_related_tags_with_nothing
21
+ assert_equal [], Issue.find_related_tags("")
22
+ assert_equal [], Issue.find_related_tags([])
23
+ end
24
+
25
+ def test_find_tagged_with
26
+ assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)], Issue.find_tagged_with('"error"')
27
+ assert_equal Issue.find_tagged_with('"error"'), Issue.find_tagged_with(['error'])
28
+ assert_equal Issue.find_tagged_with('"error"'), Issue.find_tagged_with([tags(:error)])
29
+
30
+ assert_equivalent [issues(:second_issue),], Issue.find_tagged_with('New feature')
31
+ assert_equal Issue.find_tagged_with('New feature'), Issue.find_tagged_with(['New feature'])
32
+ assert_equal Issue.find_tagged_with('New feature'), Issue.find_tagged_with([tags(:feature)])
33
+
34
+ # assert_equivalent [issues(:jonathan_bad_cat), issues(:jonathan_dog), issues(:second_issue)], Issue.find_tagged_with('"Crazy animal" Bad')
35
+ # assert_equal Issue.find_tagged_with('"Crazy animal" Bad'), Issue.find_tagged_with(['Crazy animal', 'Bad'])
36
+ # assert_equal Issue.find_tagged_with('"Crazy animal" Bad'), Issue.find_tagged_with([tags(:animal), tags(:bad)])
37
+ end
38
+
39
+ def test_find_tagged_with_nothing
40
+ assert_equal [], Issue.find_tagged_with("")
41
+ assert_equal [], Issue.find_tagged_with([])
42
+ end
43
+
44
+ def test_find_tagged_with_nonexistant_tags
45
+ assert_equal [], Issue.find_tagged_with('ABCDEFG')
46
+ assert_equal [], Issue.find_tagged_with(['HIJKLM'])
47
+ assert_equal [], Issue.find_tagged_with([RedmineCrm::Tag.new(:name => 'unsaved tag')])
48
+ end
49
+
50
+ def test_find_tagged_with_match_all
51
+ assert_equivalent [issues(:second_issue)],
52
+ Issue.find_tagged_with('error, "bug", "New feature", "question"', :match_all => true)
53
+ end
54
+
55
+ def test_find_tagged_with_match_all_and_include
56
+ assert_equivalent [issues(:first_issue), issues(:second_issue), issues(:third_issue)], Issue.find_tagged_with(['error', 'question'], :match_all => true, :include => :tags)
57
+ end
58
+
59
+ def test_find_tagged_with_conditions
60
+ assert_equal [], Issue.find_tagged_with('"error", bug', :conditions => '1=0')
61
+ end
62
+
63
+ def test_find_tagged_with_duplicates_options_hash
64
+ options = { :conditions => '1=1' }.freeze
65
+ assert_nothing_raised { Issue.find_tagged_with("error", options) }
66
+ end
67
+
68
+ def test_find_tagged_with_exclusions
69
+ assert_equivalent [issues(:first_issue), issues(:third_issue)], Issue.find_tagged_with("bug", :exclude => true)
70
+ assert_equivalent [issues(:first_issue), issues(:third_issue)], Issue.find_tagged_with("'bug', feature", :exclude => true)
71
+ end
72
+
73
+ def test_find_options_for_find_tagged_with_no_tags_returns_empty_hash
74
+ assert_equal Hash.new, Issue.find_options_for_find_tagged_with("")
75
+ assert_equal Hash.new, Issue.find_options_for_find_tagged_with([nil])
76
+ end
77
+
78
+ def test_find_options_for_find_tagged_with_leaves_arguments_unchanged
79
+ original_tags = issues(:second_issue).tags.dup
80
+ Issue.find_options_for_find_tagged_with(issues(:second_issue).tags)
81
+ assert_equal original_tags, issues(:second_issue).tags
82
+ end
83
+
84
+ def test_find_options_for_find_tagged_with_respects_custom_table_name
85
+ RedmineCrm::Tagging.table_name = "categorisations"
86
+ RedmineCrm::Tag.table_name = "categories"
87
+
88
+ options = Issue.find_options_for_find_tagged_with("Hello")
89
+
90
+ assert_no_match(/ taggings /, options[:joins])
91
+ assert_no_match(/ tags /, options[:joins])
92
+
93
+ assert_match(/ categorisations /, options[:joins])
94
+ assert_match(/ categories /, options[:joins])
95
+ ensure
96
+ RedmineCrm::Tagging.table_name = "taggings"
97
+ RedmineCrm::Tag.table_name = "tags"
98
+ end
99
+
100
+ def test_include_tags_on_find_tagged_with
101
+ assert_nothing_raised do
102
+ Issue.find_tagged_with('error', :include => :tags)
103
+ Issue.find_tagged_with("error", :include => { :taggings => :tag })
104
+ end
105
+ end
106
+
107
+ def test_basic_tag_counts_on_class
108
+ assert_tag_counts Issue.tag_counts, :error => 3, :feature => 1, :question => 3, :bug => 1
109
+ # assert_tag_counts Issue.tag_counts, :good => 1, :question => 3, :question => 1, :bad => 1, :animal => 3
110
+ end
111
+
112
+ def test_tag_counts_on_class_with_date_conditions
113
+ assert_tag_counts Issue.tag_counts(:start_at => Date.new(2015, 1, 1)), :error => 2, :feature => 1, :question => 3, :bug => 1
114
+ assert_tag_counts Issue.tag_counts(:end_at => Date.new(2014, 12, 31)), :error => 1
115
+ assert_tag_counts Issue.tag_counts(:start_at => Date.new(2015, 1, 31), :end_at => Date.new(2015, 3, 1)), :question => 1
116
+
117
+ # assert_tag_counts Issue.tag_counts(:start_at => Date.new(2006, 8, 12), :end_at => Date.new(2006, 8, 19)), :good => 1, :question => 2, :bad => 1, :question => 1, :animal => 3
118
+ end
119
+
120
+ def test_tag_counts_on_class_with_frequencies
121
+ assert_tag_counts Issue.tag_counts(:at_least => 2), :question => 3, :error => 3
122
+ assert_tag_counts Issue.tag_counts(:at_most => 2), :bug => 1, :feature => 1
123
+ end
124
+
125
+ def test_tag_counts_on_class_with_frequencies_and_conditions
126
+ assert_tag_counts Issue.tag_counts(:at_least => 2, :conditions => '1=1'), :question => 3, :error => 3
127
+ end
128
+
129
+ def test_tag_counts_duplicates_options_hash
130
+ options = { :at_least => 2, :conditions => '1=1' }.freeze
131
+ assert_nothing_raised { Issue.tag_counts(options) }
132
+ end
133
+
134
+ def test_tag_counts_with_limit
135
+ assert_equal 2, Issue.tag_counts(:limit => 2).to_a.size
136
+ assert_equal 2, Issue.tag_counts(:at_least => 3, :limit => 2).to_a.size
137
+ end
138
+
139
+ def test_tag_counts_with_limit_and_order
140
+ assert_equivalent RedmineCrm::Tag.where(:id => [tags(:error), tags(:question)]), Issue.tag_counts(:order => 'count desc', :limit => 2)
141
+ end
142
+
143
+ def test_tag_counts_on_association
144
+ assert_tag_counts users(:jonathan).issues.tag_counts, :error => 2, :bug => 1, :question => 2, :feature => 1
145
+ assert_tag_counts users(:sam).issues.tag_counts, :error => 1, :question => 1
146
+
147
+ # assert_tag_counts users(:jonathan).issues.tag_counts, :animal => 3, :question => 1, :question => 1, :bad => 1
148
+ # assert_tag_counts users(:sam).issues.tag_counts, :question => 2, :good => 1
149
+ end
150
+
151
+ def test_tag_counts_on_association_with_options
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,
154
+ :feature => 1, :error => 2, :question => 2
155
+ end
156
+
157
+ # def test_tag_counts_on_has_many_through
158
+ # assert_tag_counts users(:jonathan).magazines.tag_counts, :good => 1
159
+ # end
160
+
161
+ def test_tag_counts_on_model_instance
162
+ assert_tag_counts issues(:third_issue).tag_counts, :error => 3, :question => 3
163
+ end
164
+
165
+ def test_tag_counts_on_model_instance_merges_conditions
166
+ assert_tag_counts issues(:first_issue).tag_counts(:conditions => "tags.name = 'error'"), :error => 3
167
+ end
168
+
169
+ def test_tag_counts_on_model_instance_with_no_tags
170
+ issue = Issue.create!(:description => "desc")
171
+
172
+ assert_tag_counts issue.tag_counts, {}
173
+ end
174
+
175
+ def test_tag_counts_should_sanitize_scope_conditions
176
+ Issue.send :where, { "tags.id = ?" => tags(:error).id } do
177
+ assert_tag_counts Issue.tag_counts, :error => 3
178
+ end
179
+ end
180
+
181
+ def test_tag_counts_respects_custom_table_names
182
+ RedmineCrm::Tagging.table_name = "categorisations"
183
+ RedmineCrm::Tag.table_name = "categories"
184
+
185
+ options = Issue.find_options_for_tag_counts(:start_at => 2.weeks.ago, :end_at => Date.today)
186
+ sql = options.values.join(' ')
187
+
188
+ assert_no_match /taggings/, sql
189
+ assert_no_match /tags/, sql
190
+
191
+ assert_match /categorisations/, sql
192
+ assert_match /categories/, sql
193
+ ensure
194
+ RedmineCrm::Tagging.table_name = "taggings"
195
+ RedmineCrm::Tag.table_name = "tags"
196
+ end
197
+
198
+ def test_tag_list_reader
199
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
200
+ assert_equivalent ["error", "New feature", "bug", "question"], issues(:second_issue).tag_list
201
+ end
202
+
203
+ def test_reassign_tag_list
204
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
205
+ issues(:first_issue).taggings.reload
206
+
207
+ # Only an update of the issues table should be executed, the other two queries are for savepoints
208
+ # assert_queries 3 do
209
+ # issues(:first_issue).update_attributes!(:description => "new name", :tag_list => issues(:first_issue).tag_list.to_s)
210
+ # end
211
+
212
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
213
+ end
214
+
215
+ def test_new_tags
216
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
217
+ issues(:first_issue).update_attributes!(:tag_list => "#{issues(:first_issue).tag_list}, One, Two")
218
+ assert_equivalent ["error", "question", "One", "Two"], issues(:first_issue).tag_list
219
+ end
220
+
221
+ def test_remove_tag
222
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
223
+ issues(:first_issue).update_attributes!(:tag_list => "error")
224
+ assert_equivalent ["error"], issues(:first_issue).tag_list
225
+ end
226
+
227
+ # def test_change_case_of_tags
228
+ # original_tag_names = issues(:second_issue).tag_list
229
+ # issues(:second_issue).update_attributes!(:tag_list => issues(:second_issue).tag_list.to_s.upcase)
230
+
231
+ # # The new tag list is not uppercase becuase the AR finders are not case-sensitive
232
+ # # and find the old tags when re-tagging with the uppercase tags.
233
+ # assert_equivalent original_tag_names, issues(:second_issue).reload.tag_list
234
+ # end
235
+
236
+ def test_remove_and_add_tag
237
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
238
+ issues(:first_issue).update_attributes!(:tag_list => "question, Beautiful")
239
+ assert_equivalent ["question", "Beautiful"], issues(:first_issue).tag_list
240
+ end
241
+
242
+ def test_tags_not_saved_if_validation_fails
243
+ assert_equivalent ["error", "question"], issues(:first_issue).tag_list
244
+ assert !issues(:first_issue).update_attributes(:tag_list => "One, Two", :description => "")
245
+ assert_equivalent ["error", "question"], Issue.find(issues(:first_issue).id).tag_list
246
+ end
247
+
248
+ def test_tag_list_accessors_on_new_record
249
+ p = Issue.new(:description => 'Test')
250
+
251
+ assert p.tag_list.blank?
252
+ p.tag_list = "One, Two"
253
+ assert_equal "One, Two", p.tag_list.to_s
254
+ end
255
+
256
+ def test_clear_tag_list_with_nil
257
+ p = issues(:second_issue)
258
+
259
+ assert !p.tag_list.blank?
260
+ assert p.update_attributes(:tag_list => nil)
261
+ assert p.tag_list.blank?
262
+
263
+ assert p.reload.tag_list.blank?
264
+ end
265
+
266
+ def test_clear_tag_list_with_string
267
+ p = issues(:second_issue)
268
+
269
+ assert !p.tag_list.blank?
270
+ assert p.update_attributes(:tag_list => ' ')
271
+ assert p.tag_list.blank?
272
+
273
+ assert p.reload.tag_list.blank?
274
+ end
275
+
276
+ def test_tag_list_reset_on_reload
277
+ p = issues(:second_issue)
278
+ assert !p.tag_list.blank?
279
+ p.tag_list = nil
280
+ assert p.tag_list.blank?
281
+ assert !p.reload.tag_list.blank?
282
+ end
283
+
284
+ def test_instance_tag_counts
285
+ assert_tag_counts issues(:first_issue).tag_counts, :error => 3, :question => 3
286
+ end
287
+
288
+ def test_tag_list_populated_when_cache_nil
289
+ assert_nil issues(:first_issue).cached_tag_list
290
+ issues(:first_issue).save!
291
+ assert_equal issues(:first_issue).tag_list.to_s, issues(:first_issue).cached_tag_list
292
+ end
293
+
294
+ # def test_cached_tag_list_used
295
+ # issues(:first_issue).save!
296
+ # issues(:first_issue).reload
297
+
298
+ # assert_no_queries do
299
+ # assert_equivalent ["error", "question"], issues(:first_issue).tag_list
300
+ # end
301
+ # end
302
+
303
+ def test_cached_tag_list_not_used
304
+ # Load fixture and column information
305
+ issues(:first_issue).taggings(:reload)
306
+
307
+ # assert_queries 1 do
308
+ # # Tags association will be loaded
309
+ # issues(:first_issue).tag_list
310
+ # end
311
+ end
312
+
313
+ def test_cached_tag_list_updated
314
+ assert_nil issues(:first_issue).cached_tag_list
315
+ issues(:first_issue).save!
316
+ assert_equivalent ["question", "error"], RedmineCrm::TagList.from(issues(:first_issue).cached_tag_list)
317
+ issues(:first_issue).update_attributes!(:tag_list => "None")
318
+
319
+ assert_equal 'None', issues(:first_issue).cached_tag_list
320
+ assert_equal 'None', issues(:first_issue).reload.cached_tag_list
321
+ end
322
+
323
+ def test_clearing_cached_tag_list
324
+ # Generate the cached tag list
325
+ issues(:first_issue).save!
326
+
327
+ issues(:first_issue).update_attributes!(:tag_list => "")
328
+ assert_equal "", issues(:first_issue).cached_tag_list
329
+ end
330
+
331
+ def test_find_tagged_with_using_sti
332
+ special_Issue = SpecialIssue.create!(:description => "Test", :tag_list => "Random")
333
+
334
+ assert_equal [special_Issue], SpecialIssue.find_tagged_with("Random")
335
+ assert SpecialIssue.find_tagged_with("Random").include?(special_Issue)
336
+ end
337
+
338
+ # def test_tag_counts_using_sti
339
+ # SpecialIssue.create!(:description => "Test", :tag_list => "question")
340
+ # assert_tag_counts SpecialIssue.tag_counts, :question => 1
341
+ # end
342
+
343
+ def test_case_insensitivity
344
+ assert_difference "RedmineCrm::Tag.count", 1 do
345
+ Issue.create!(:description => "Test", :tag_list => "one")
346
+ Issue.create!(:description => "Test", :tag_list => "One")
347
+ end
348
+ assert_equal Issue.find_tagged_with("question"), Issue.find_tagged_with("question")
349
+ end
350
+
351
+ def test_tag_not_destroyed_when_unused
352
+ issues(:first_issue).tag_list.add("Random")
353
+ issues(:first_issue).save!
354
+
355
+ assert_no_difference 'RedmineCrm::Tag.count' do
356
+ issues(:first_issue).tag_list.remove("Random")
357
+ issues(:first_issue).save!
358
+ end
359
+ end
360
+
361
+ def test_tag_destroyed_when_unused
362
+ RedmineCrm::Tag.destroy_unused = true
363
+
364
+ issues(:first_issue).tag_list.add("Random")
365
+ issues(:first_issue).save!
366
+
367
+ assert_difference 'RedmineCrm::Tag.count', -1 do
368
+ issues(:first_issue).tag_list.remove("Random")
369
+ issues(:first_issue).save!
370
+ end
371
+ ensure
372
+ RedmineCrm::Tag.destroy_unused = false
373
+ end
374
+ end
375
+
376
+ # class ActsAsTaggableOnSteroidsFormTest < ActiveSupport::TestCase
377
+ # include ActionView::Helpers::FormHelper
378
+
379
+ # def test_tag_list_contents
380
+ # fields_for :Issue, issues(:first_issue) do |f|
381
+ # assert_match issues(:first_issue).tag_list.to_s, f.text_field(:tag_list)
382
+ # end
383
+ # end
384
+ # end