test_redmine_vz 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/README.md +71 -0
- data/Rakefile +20 -0
- data/config/currency_iso.json +2532 -0
- data/doc/CHANGELOG +55 -0
- data/doc/LICENSE.txt +339 -0
- data/lib/redmine_crm.rb +67 -0
- data/lib/redmine_crm/currency.rb +439 -0
- data/lib/redmine_crm/currency/formatting.rb +227 -0
- data/lib/redmine_crm/currency/heuristics.rb +151 -0
- data/lib/redmine_crm/currency/loader.rb +24 -0
- data/lib/redmine_crm/helpers/tags_helper.rb +15 -0
- data/lib/redmine_crm/helpers/vote_helper.rb +38 -0
- data/lib/redmine_crm/liquid/drops/issues_drop.rb +61 -0
- data/lib/redmine_crm/liquid/drops/news_drop.rb +45 -0
- data/lib/redmine_crm/liquid/drops/projects_drop.rb +78 -0
- data/lib/redmine_crm/liquid/drops/users_drop.rb +59 -0
- data/lib/redmine_crm/liquid/filters.rb +85 -0
- data/lib/redmine_crm/money_helper.rb +67 -0
- data/lib/redmine_crm/rcrm_acts_as_taggable.rb +342 -0
- data/lib/redmine_crm/rcrm_acts_as_viewed.rb +287 -0
- data/lib/redmine_crm/rcrm_acts_as_votable.rb +79 -0
- data/lib/redmine_crm/rcrm_acts_as_voter.rb +27 -0
- data/lib/redmine_crm/tag.rb +81 -0
- data/lib/redmine_crm/tag_list.rb +112 -0
- data/lib/redmine_crm/tagging.rb +20 -0
- data/lib/redmine_crm/version.rb +3 -0
- data/lib/redmine_crm/votable.rb +334 -0
- data/lib/redmine_crm/vote.rb +30 -0
- data/lib/redmine_crm/voter.rb +136 -0
- data/redmine_crm.gemspec +22 -0
- data/test/acts_as_taggable_test.rb +384 -0
- data/test/currency_test.rb +292 -0
- data/test/database.yml +17 -0
- data/test/fixtures/issue.rb +14 -0
- data/test/fixtures/issues.yml +12 -0
- data/test/fixtures/taggings.yml +32 -0
- data/test/fixtures/tags.yml +11 -0
- data/test/fixtures/user.rb +7 -0
- data/test/fixtures/users.yml +5 -0
- data/test/fixtures/votable_caches.yml +2 -0
- data/test/fixtures/votables.yml +4 -0
- data/test/fixtures/vote_classes.rb +54 -0
- data/test/fixtures/voters.yml +6 -0
- data/test/liquid_test.rb +80 -0
- data/test/money_helper_test.rb +12 -0
- data/test/schema.rb +100 -0
- data/test/tag_test.rb +63 -0
- data/test/tagging_test.rb +14 -0
- data/test/tags_helper_test.rb +29 -0
- data/test/test_helper.rb +118 -0
- data/test/viewed_test.rb +45 -0
- data/test/votable_model_test.rb +478 -0
- data/test/votable_test.rb +17 -0
- data/test/vote_helper_test.rb +28 -0
- data/test/voter_model_test.rb +296 -0
- metadata +141 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'redmine_crm/helpers/vote_helper'
|
2
|
+
|
3
|
+
module RedmineCrm
|
4
|
+
module ActsAsVotable
|
5
|
+
class Vote < ActiveRecord::Base
|
6
|
+
|
7
|
+
include Helpers::Words
|
8
|
+
|
9
|
+
if defined?(ProtectedAttributes) || ::ActiveRecord::VERSION::MAJOR < 4
|
10
|
+
attr_accessible :votable_id, :votable_type,
|
11
|
+
:voter_id, :voter_type,
|
12
|
+
:votable, :voter,
|
13
|
+
:vote_flag, :vote_scope
|
14
|
+
end
|
15
|
+
|
16
|
+
belongs_to :votable, :polymorphic => true
|
17
|
+
belongs_to :voter, :polymorphic => true
|
18
|
+
|
19
|
+
scope :up, lambda{ where(:vote_flag => true) }
|
20
|
+
scope :down, lambda{ where(:vote_flag => false) }
|
21
|
+
scope :for_type, lambda{ |klass| where(:votable_type => klass) }
|
22
|
+
scope :by_type, lambda{ |klass| where(:voter_type => klass) }
|
23
|
+
|
24
|
+
validates_presence_of :votable_id
|
25
|
+
validates_presence_of :voter_id
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module RedmineCrm
|
2
|
+
module ActsAsVotable
|
3
|
+
module Voter
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
|
7
|
+
# allow user to define these
|
8
|
+
aliases = {
|
9
|
+
:vote_up_for => [:likes, :upvotes, :up_votes],
|
10
|
+
:vote_down_for => [:dislikes, :downvotes, :down_votes],
|
11
|
+
:unvote_for => [:unlike, :undislike],
|
12
|
+
:voted_on? => [:voted_for?],
|
13
|
+
:voted_up_on? => [:voted_up_for?, :liked?],
|
14
|
+
:voted_down_on? => [:voted_down_for?, :disliked?],
|
15
|
+
:voted_as_when_voting_on => [:voted_as_when_voted_on, :voted_as_when_voting_for, :voted_as_when_voted_for],
|
16
|
+
:find_up_voted_items => [:find_liked_items],
|
17
|
+
:find_down_voted_items => [:find_disliked_items]
|
18
|
+
}
|
19
|
+
|
20
|
+
base.class_eval do
|
21
|
+
|
22
|
+
has_many :votes, :class_name => 'RedmineCrm::ActsAsVotable::Vote', :as => :voter, :dependent => :destroy do
|
23
|
+
def votables
|
24
|
+
includes(:votable).map(&:votable)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
aliases.each do |method, links|
|
29
|
+
links.each do |new_method|
|
30
|
+
alias_method(new_method, method)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# voting
|
39
|
+
def vote args
|
40
|
+
args[:votable].vote_by args.merge({:voter => self})
|
41
|
+
end
|
42
|
+
|
43
|
+
def vote_up_for model=nil, args={}
|
44
|
+
vote :votable => model, :vote_scope => args[:vote_scope], :vote => true
|
45
|
+
end
|
46
|
+
|
47
|
+
def vote_down_for model=nil, args={}
|
48
|
+
vote :votable => model, :vote_scope => args[:vote_scope], :vote => false
|
49
|
+
end
|
50
|
+
|
51
|
+
def unvote_for model, args={}
|
52
|
+
model.unvote :voter => self, :vote_scope => args[:vote_scope]
|
53
|
+
end
|
54
|
+
|
55
|
+
# results
|
56
|
+
def voted_on? votable, args={}
|
57
|
+
votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
|
58
|
+
:vote_scope => args[:vote_scope])
|
59
|
+
votes.size > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
def voted_up_on? votable, args={}
|
63
|
+
votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
|
64
|
+
:vote_scope => args[:vote_scope], :vote_flag => true)
|
65
|
+
votes.size > 0
|
66
|
+
end
|
67
|
+
|
68
|
+
def voted_down_on? votable, args={}
|
69
|
+
votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
|
70
|
+
:vote_scope => args[:vote_scope], :vote_flag => false)
|
71
|
+
votes.size > 0
|
72
|
+
end
|
73
|
+
|
74
|
+
def voted_as_when_voting_on votable, args={}
|
75
|
+
vote = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
|
76
|
+
:vote_scope => args[:vote_scope]).select(:vote_flag).last
|
77
|
+
return nil unless vote
|
78
|
+
return vote.vote_flag
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_votes extra_conditions = {}
|
82
|
+
votes.where(extra_conditions)
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_up_votes args={}
|
86
|
+
find_votes :vote_flag => true, :vote_scope => args[:vote_scope]
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_down_votes args={}
|
90
|
+
find_votes :vote_flag => false, :vote_scope => args[:vote_scope]
|
91
|
+
end
|
92
|
+
|
93
|
+
def find_votes_for_class klass, extra_conditions = {}
|
94
|
+
find_votes extra_conditions.merge({:votable_type => klass.name})
|
95
|
+
end
|
96
|
+
|
97
|
+
def find_up_votes_for_class klass, args={}
|
98
|
+
find_votes_for_class klass, :vote_flag => true, :vote_scope => args[:vote_scope]
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_down_votes_for_class klass, args={}
|
102
|
+
find_votes_for_class klass, :vote_flag => false, :vote_scope => args[:vote_scope]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Including polymporphic relations for eager loading
|
106
|
+
def include_objects
|
107
|
+
ActsAsVotable::Vote.includes(:votable)
|
108
|
+
end
|
109
|
+
|
110
|
+
def find_voted_items extra_conditions = {}
|
111
|
+
options = extra_conditions.merge :voter_id => id, :voter_type => self.class.base_class.name
|
112
|
+
include_objects.where(options).collect(&:votable)
|
113
|
+
end
|
114
|
+
|
115
|
+
def find_up_voted_items extra_conditions = {}
|
116
|
+
find_voted_items extra_conditions.merge(:vote_flag => true)
|
117
|
+
end
|
118
|
+
|
119
|
+
def find_down_voted_items extra_conditions = {}
|
120
|
+
find_voted_items extra_conditions.merge(:vote_flag => false)
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_voted klass, extra_conditions = {}
|
124
|
+
klass.joins(:votes_for).merge find_votes(extra_conditions)
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_up_voted klass
|
128
|
+
klass.joins(:votes_for).merge find_up_votes
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_down_voted klass
|
132
|
+
klass.joins(:votes_for).merge find_down_votes
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/redmine_crm.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
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 = "test_redmine_vz"
|
8
|
+
spec.version = RedmineCrm::VERSION
|
9
|
+
spec.authors = ["Redmine"]
|
10
|
+
spec.email = ["support@redminecrm.com"]
|
11
|
+
spec.summary = %q{Common libraries for RedmineCRM plugins for Redmine}
|
12
|
+
spec.description = %q{Common libraries for RedmineCRM plugins for Redmine. Requered Redmine from http://redmine.org}
|
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_runtime_dependency 'liquid', "<2.6.4"
|
22
|
+
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
|