Commit 4fa3b9844fa825008461f2759896cb77a2e30cbf

Authored by Victor Costa
1 parent 0fc833ce

Add badges with an organization as owner

lib/ext/environment.rb
... ... @@ -3,5 +3,6 @@ require_dependency 'environment'
3 3 class Environment
4 4  
5 5 has_many :gamification_plugin_badges, :class_name => 'GamificationPlugin::Badge', :foreign_key => 'owner_id', :source => :owner
  6 + has_many :gamification_plugin_organization_badges, :through => :organizations
6 7  
7 8 end
... ...
lib/ext/organization.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +require_dependency 'organization'
  2 +
  3 +class Organization
  4 +
  5 + has_many :gamification_plugin_organization_badges, :class_name => 'GamificationPlugin::Badge', :foreign_key => 'owner_id', :source => :owner
  6 +
  7 +end
... ...
lib/merit/badge_rules.rb
... ... @@ -14,6 +14,7 @@ module Merit
14 14 action: 'comment#create',
15 15 default_threshold: 5,
16 16 to: :author,
  17 + target_profile: lambda {|comment| comment.profile },
17 18 value: lambda { |comment, author| author.present? ? author.comments.count : 0 }
18 19 }
19 20 ],
... ... @@ -22,6 +23,7 @@ module Merit
22 23 action: 'comment#create',
23 24 default_threshold: 5,
24 25 to: lambda {|comment| comment.source.author},
  26 + target_profile: lambda {|comment| comment.profile },
25 27 value: lambda { |comment, author| author.present? ? Comment.where(source_id: Article.where(author_id: author.id)).count : 0 }
26 28 }
27 29 ],
... ... @@ -30,6 +32,7 @@ module Merit
30 32 action: 'article#create',
31 33 default_threshold: 5,
32 34 to: :author,
  35 + target_profile: lambda {|article| article.profile },
33 36 value: lambda { |article, author| author.present? ? TextArticle.where(author_id: author.id).count : 0 }
34 37 },
35 38 ],
... ... @@ -38,6 +41,7 @@ module Merit
38 41 action: 'vote#create',
39 42 default_threshold: 5,
40 43 to: lambda {|vote| vote.voteable.author},
  44 + target_profile: lambda {|vote| vote.voteable.profile },
41 45 value: lambda { |vote, author| vote.voteable ? Vote.for_voteable(vote.voteable).where('vote > 0').count : 0}
42 46 }
43 47 ],
... ... @@ -46,6 +50,7 @@ module Merit
46 50 action: 'vote#create',
47 51 default_threshold: 5,
48 52 to: lambda {|vote| vote.voteable.author},
  53 + target_profile: lambda {|vote| vote.voteable.profile },
49 54 value: lambda { |vote, author| Vote.for_voteable(vote.voteable).where('vote < 0').count }
50 55 }
51 56 ],
... ... @@ -54,6 +59,7 @@ module Merit
54 59 action: 'vote#create',
55 60 default_threshold: 5,
56 61 to: lambda {|vote| vote.voter},
  62 + target_profile: lambda {|vote| vote.voteable.profile },
57 63 value: lambda { |vote, voter| voter ? Vote.for_voter(voter).count : 0 }
58 64 }
59 65 ],
... ... @@ -72,12 +78,14 @@ module Merit
72 78 action: 'comment#create',
73 79 default_threshold: 5,
74 80 to: :author,
  81 + target_profile: lambda {|comment| comment.profile },
75 82 value: lambda { |comment, author| author.present? ? author.comments.count : 0 }
76 83 },
77 84 {
78 85 action: 'article#create',
79 86 default_threshold: 5,
80 87 to: :author,
  88 + target_profile: lambda {|article| article.profile },
81 89 value: lambda { |article, author| author.present? ? author.articles.count : 0 }
82 90 },
83 91 ],
... ... @@ -86,6 +94,7 @@ module Merit
86 94 action: 'articlefollower#create',
87 95 default_threshold: 5,
88 96 to: lambda {|article| article.person },
  97 + target_profile: lambda {|article_follower| article_follower.article.profile },
89 98 model: 'ArticleFollower',
90 99 value: lambda { |article, person| person.present? ? person.article_followers.count : 0 }
91 100 }
... ... @@ -95,12 +104,14 @@ module Merit
95 104 action: 'Vote#create',
96 105 default_threshold: 5,
97 106 to: lambda { |vote| vote.voter },
  107 + target_profile: lambda {|vote| vote.voteable.profile },
98 108 value: lambda { |vote, voter| Vote.for_voter(voter).count }
99 109 },
100 110 {
101 111 action: 'Event#create',
102 112 default_threshold: 5,
103 113 to: lambda { |article| article.author },
  114 + target_profile: lambda {|article| article.profile },
104 115 value: lambda { |event, author| author.events.count }
105 116 },
106 117 ],
... ... @@ -109,12 +120,14 @@ module Merit
109 120 action: 'vote#create',
110 121 default_threshold: 5,
111 122 to: lambda {|vote| vote.voter},
  123 + target_profile: lambda {|vote| vote.voteable.profile },
112 124 value: lambda { |vote, voter| voter ? voter.votes.where('vote > 0').count : 0 }
113 125 },
114 126 {
115 127 action: 'comment#create',
116 128 default_threshold: 5,
117 129 to: :author,
  130 + target_profile: lambda {|comment| comment.profile },
118 131 value: lambda { |comment, author| author.present? ? author.comments.count : 0 }
119 132 }
120 133 ],
... ... @@ -123,6 +136,7 @@ module Merit
123 136 action: 'articlefollower#create',
124 137 default_threshold: 5,
125 138 to: :person,
  139 + target_profile: lambda {|article_follower| article_follower.article.profile },
126 140 model: 'ArticleFollower',
127 141 value: lambda { |article_follower, person| person.present? ? person.article_followers.count : 0 }
128 142 },
... ... @@ -130,11 +144,28 @@ module Merit
130 144 action: 'comment#create',
131 145 default_threshold: 5,
132 146 to: :author,
  147 + target_profile: lambda {|comment| comment.profile },
133 148 value: lambda { |comment, author| author.present? ? author.comments.count : 0 }
134 149 },
135 150 ]
136 151 }
137 152  
  153 + def target_author(source, setting)
  154 + if setting[:to].is_a? Symbol
  155 + source.send(setting[:to])
  156 + else
  157 + setting[:to].call(source) rescue nil
  158 + end
  159 + end
  160 +
  161 + def target_profile(source, setting)
  162 + setting[:target_profile].present? ? setting[:target_profile].call(source) : nil
  163 + end
  164 +
  165 + def check_organization_badge(badge, source, setting)
  166 + !badge.owner.kind_of?(Organization) || badge.owner == target_profile(source, setting)
  167 + end
  168 +
138 169 def initialize(environment=nil)
139 170 return if environment.nil?
140 171 @environment = environment
... ... @@ -142,7 +173,8 @@ module Merit
142 173 rules = AVAILABLE_RULES
143 174 rules.merge! CONFERENCE_RULES if defined? CONFERENCE_RULES
144 175  
145   - environment.gamification_plugin_badges.all.each do |badge|
  176 + gamification_plugin_badges = environment.gamification_plugin_badges + environment.gamification_plugin_organization_badges
  177 + gamification_plugin_badges.each do |badge|
146 178 next if rules[badge.name.to_sym].nil?
147 179 rules[badge.name.to_sym].each do |setting|
148 180 options = {badge: badge.name, level: badge.level, to: setting[:to]}
... ... @@ -150,18 +182,11 @@ module Merit
150 182 grant_on setting[:action], options do |source|
151 183 can_be_granted = true
152 184 rules[badge.name.to_sym].each do |s|
153   - if setting[:to].is_a? Symbol
154   - to = source.send(setting[:to])
155   - else
156   - begin
157   - to = setting[:to].call(source)
158   - rescue
159   - to = nil
160   - end
161   - end
162   - # pass source and to for different situations
  185 + to = target_author(source, setting)
  186 + # pass source and to for different situations
163 187 action = (badge.custom_fields || {}).fetch(s[:action], {})
164 188 can_be_granted &= s[:value].call(source, to) >= action.fetch(:threshold, s[:default_threshold]).to_i
  189 + can_be_granted &= check_organization_badge(badge, source, setting)
165 190 end
166 191 can_be_granted
167 192 end
... ...
test/unit/badge_rules_test.rb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class BadgeRulesTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + end
  8 +
  9 + attr_accessor :environment
  10 +
  11 + should "define badge rules for environment's badges" do
  12 + badge = GamificationPlugin::Badge.create!(:owner => environment, :name => :comment_author)
  13 + badge_rules = Merit::BadgeRules.new(environment)
  14 + assert_equal [Merit::BadgeRules::AVAILABLE_RULES[badge.name].first[:action]], badge_rules.defined_rules.keys
  15 + end
  16 +
  17 + should "define badge rules for organization's badges" do
  18 + organization = fast_create(Organization)
  19 + badge = GamificationPlugin::Badge.create!(:owner => organization, :name => :comment_author)
  20 + badge_rules = Merit::BadgeRules.new(environment)
  21 + assert_equal [Merit::BadgeRules::AVAILABLE_RULES[badge.name].first[:action]], badge_rules.defined_rules.keys
  22 + end
  23 +
  24 + should 'check organization returns true when badge belongs to the environment' do
  25 + badge = GamificationPlugin::Badge.create!(:owner => environment, :name => :comment_author)
  26 + badge_rules = Merit::BadgeRules.new(environment)
  27 + comment = fast_create(Comment)
  28 + assert badge_rules.check_organization_badge(badge, comment, Merit::BadgeRules::AVAILABLE_RULES[badge.name].first)
  29 + end
  30 +
  31 + should 'check organization returns true when the comment belongs to the organization' do
  32 + organization = fast_create(Organization)
  33 + badge = GamificationPlugin::Badge.create!(:owner => organization, :name => :comment_author)
  34 + badge_rules = Merit::BadgeRules.new(environment)
  35 + article = fast_create(Article,:profile_id => organization.id)
  36 + comment = fast_create(Comment, :source_id => article.id)
  37 + assert badge_rules.check_organization_badge(badge, comment, Merit::BadgeRules::AVAILABLE_RULES[badge.name].first)
  38 + end
  39 +
  40 + should 'check organization returns false when the comment does not belongs to the organization' do
  41 + organization = fast_create(Organization)
  42 + badge = GamificationPlugin::Badge.create!(:owner => organization, :name => :comment_author)
  43 + badge_rules = Merit::BadgeRules.new(environment)
  44 + comment = fast_create(Comment)
  45 + assert !badge_rules.check_organization_badge(badge, comment, Merit::BadgeRules::AVAILABLE_RULES[badge.name].first)
  46 + end
  47 +
  48 +end
... ...
test/unit/badge_test.rb
... ... @@ -5,9 +5,10 @@ class BadgeTest &lt; ActiveSupport::TestCase
5 5 def setup
6 6 @person = create_user('testuser').person
7 7 @environment = Environment.default
  8 + @organization = fast_create(Organization)
8 9 end
9 10  
10   - attr_accessor :person, :environment
  11 + attr_accessor :person, :environment, :organization
11 12  
12 13 should 'add badge to person' do
13 14 badge = GamificationPlugin::Badge.create!(:owner => environment)
... ... @@ -37,4 +38,10 @@ class BadgeTest &lt; ActiveSupport::TestCase
37 38 assert_equal [badge2], person.badges.notification_pending
38 39 end
39 40  
  41 + should 'add badge to person with organization as the badge owner' do
  42 + badge = GamificationPlugin::Badge.create(:owner => organization)
  43 + person.add_badge(badge.id)
  44 + assert_equal [badge], person.badges
  45 + end
  46 +
40 47 end
... ...