Commit a49ad7f9df9506c398cfd8f44c36959fc8e7c255

Authored by Victor Costa
1 parent 6334307e

Dynamically define badges

db/migrate/20150330102818_create_badges.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class CreateBadges < ActiveRecord::Migration
  2 + def change
  3 + create_table :gamification_plugin_badges do |t|
  4 + t.string :name
  5 + t.integer :level
  6 + t.string :description
  7 + t.string :custom_fields
  8 + t.references :owner, :polymorphic => true
  9 + t.timestamps
  10 + end
  11 + end
  12 +end
lib/ext/environment.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +require_dependency 'environment'
  2 +
  3 +class Environment
  4 +
  5 + has_many :gamification_plugin_badges, :class_name => 'GamificationPlugin::Badge', :foreign_key => 'owner_id'
  6 +
  7 +end
lib/gamification_plugin.rb
@@ -37,27 +37,4 @@ class GamificationPlugin &lt; Noosfero::Plugin @@ -37,27 +37,4 @@ class GamificationPlugin &lt; Noosfero::Plugin
37 37
38 require 'merit_ext' 38 require 'merit_ext'
39 39
40 - Merit::Badge.create!(  
41 - id: 1,  
42 - name: "comment_author",  
43 - description: "Commenter"  
44 - )  
45 - Merit::Badge.create!(  
46 - id: 2,  
47 - name: "relevant_commenter",  
48 - description: "Relevant Commenter"  
49 - )  
50 - Merit::Badge.create!(  
51 - id: 3,  
52 - name: "article_author",  
53 - description: "Article Creator",  
54 - level: 1  
55 - )  
56 - Merit::Badge.create!(  
57 - id: 4,  
58 - name: "article_author",  
59 - description: "Article Creator",  
60 - level: 2  
61 - )  
62 -  
63 end 40 end
lib/gamification_plugin/badge.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class GamificationPlugin::Badge < Noosfero::Plugin::ActiveRecord
  2 +
  3 + belongs_to :owner, :polymorphic => true
  4 +
  5 + attr_accessible :owner, :name, :description, :level, :custom_fields
  6 +
  7 + serialize :custom_fields
  8 +
  9 +end
lib/merit/badge_rules.rb
@@ -41,22 +41,19 @@ module Merit @@ -41,22 +41,19 @@ module Merit
41 def initialize(environment=nil) 41 def initialize(environment=nil)
42 return if environment.nil? 42 return if environment.nil?
43 @environment = environment 43 @environment = environment
  44 + # FIXME avoid this
  45 + Merit::Badge.all.each { |badge| badge.destroy }
  46 +
  47 + GamificationPlugin::Badge.all.each do |badge|
  48 + # FIXME avoid this
  49 + Merit::Badge.create!(:name => badge.name, :id => badge.id, :level => badge.level) # FIXME conflict with multitenancy?
44 50
45 - Merit::Badge.all.each do |badge|  
46 setting = AVAILABLE_RULES[badge.name.to_sym] 51 setting = AVAILABLE_RULES[badge.name.to_sym]
47 - grant_on setting[:action], :badge => badge.name do |source|  
48 - setting[:value].call(source) >= setting[:default_threshold] 52 + grant_on setting[:action], :badge => badge.name, :level => badge.level do |source|
  53 + setting[:value].call(source) >= (badge.custom_fields || {}).fetch(:threshold, setting[:default_threshold])
49 end 54 end
50 end 55 end
51 56
52 - grant_on 'article#create', badge: 'article_author', level: 1 do |article|  
53 - article.author.present? && article.author.articles.count >= 5  
54 - end  
55 -  
56 - grant_on 'article#create', badge: 'article_author', level: 2 do |article|  
57 - article.author.present? && article.author.articles.count >= 10  
58 - end  
59 -  
60 grant_on 'vote_plugin_profile#vote', badge: 'relevant-commenter', model_name: 'comment', to: 'author' do |voteable| 57 grant_on 'vote_plugin_profile#vote', badge: 'relevant-commenter', model_name: 'comment', to: 'author' do |voteable|
61 return false if voteable.nil? || !voteable.kind_of?(Comment) 58 return false if voteable.nil? || !voteable.kind_of?(Comment)
62 voteable.votes.count >= 2 59 voteable.votes.count >= 2
test/functional/gamification_plugin_profile_controller_test.rb
@@ -5,10 +5,11 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase @@ -5,10 +5,11 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase
5 def setup 5 def setup
6 @profile = fast_create(Profile) 6 @profile = fast_create(Profile)
7 @person = create_user('person').person 7 @person = create_user('person').person
  8 + @environment = Environment.default
8 login_as(@person.identifier) 9 login_as(@person.identifier)
9 end 10 end
10 11
11 - attr_accessor :profile, :person 12 + attr_accessor :profile, :person, :environment
12 13
13 should 'display points in gamification info page' do 14 should 'display points in gamification info page' do
14 person.add_points(20, :category => :comment_author) 15 person.add_points(20, :category => :comment_author)
@@ -26,8 +27,12 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase @@ -26,8 +27,12 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase
26 end 27 end
27 28
28 should 'display person badges' do 29 should 'display person badges' do
29 - person.add_badge(1)  
30 - person.add_badge(2) 30 + badge1 = GamificationPlugin::Badge.create!(:owner => environment, :name => 'article_author', :level => 1)
  31 + badge2 = GamificationPlugin::Badge.create!(:owner => environment, :name => 'article_author', :level => 2, :custom_fields => {:threshold => 10})
  32 + GamificationPlugin.gamification_set_rules(environment)
  33 +
  34 + person.add_badge(badge1.id)
  35 + person.add_badge(badge2.id)
31 get :info, :profile => profile.identifier 36 get :info, :profile => profile.identifier
32 assert_select '.badges .badge-list .badge', 2 37 assert_select '.badges .badge-list .badge', 2
33 end 38 end
test/unit/article_test.rb
@@ -4,10 +4,11 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -4,10 +4,11 @@ class ArticleTest &lt; ActiveSupport::TestCase
4 4
5 def setup 5 def setup
6 @person = create_user('testuser').person 6 @person = create_user('testuser').person
7 - GamificationPlugin.gamification_set_rules(Environment.default) 7 + @environment = Environment.default
  8 + GamificationPlugin.gamification_set_rules(@environment)
8 end 9 end
9 10
10 - attr_accessor :person 11 + attr_accessor :person, :environment
11 12
12 should 'add merit points to author when create a new article' do 13 should 'add merit points to author when create a new article' do
13 create(Article, :profile_id => person.id, :author => person) 14 create(Article, :profile_id => person.id, :author => person)
@@ -23,12 +24,19 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -23,12 +24,19 @@ class ArticleTest &lt; ActiveSupport::TestCase
23 end 24 end
24 25
25 should 'add merit badge to author when create 5 new articles' do 26 should 'add merit badge to author when create 5 new articles' do
  27 + GamificationPlugin::Badge.create!(:owner => environment, :name => 'article_author', :level => 1)
  28 + GamificationPlugin.gamification_set_rules(environment)
  29 +
26 5.times { create(Article, :profile_id => person.id, :author => person) } 30 5.times { create(Article, :profile_id => person.id, :author => person) }
27 assert_equal 'article_author', person.badges.first.name 31 assert_equal 'article_author', person.badges.first.name
28 assert_equal 1, person.badges.first.level 32 assert_equal 1, person.badges.first.level
29 end 33 end
30 34
31 should 'add merit badge level 2 to author when create 10 new articles' do 35 should 'add merit badge level 2 to author when create 10 new articles' do
  36 + GamificationPlugin::Badge.create!(:owner => environment, :name => 'article_author', :level => 1)
  37 + GamificationPlugin::Badge.create!(:owner => environment, :name => 'article_author', :level => 2, :custom_fields => {:threshold => 10})
  38 + GamificationPlugin.gamification_set_rules(environment)
  39 +
32 10.times { create(Article, :profile_id => person.id, :author => person) } 40 10.times { create(Article, :profile_id => person.id, :author => person) }
33 assert_equal ['article_author'], person.badges.map(&:name).uniq 41 assert_equal ['article_author'], person.badges.map(&:name).uniq
34 assert_equal [1, 2], person.badges.map(&:level) 42 assert_equal [1, 2], person.badges.map(&:level)
test/unit/comment_test.rb
@@ -5,9 +5,10 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -5,9 +5,10 @@ class CommentTest &lt; ActiveSupport::TestCase
5 def setup 5 def setup
6 @person = create_user('testuser').person 6 @person = create_user('testuser').person
7 @article = create(TextileArticle, :profile_id => person.id) 7 @article = create(TextileArticle, :profile_id => person.id)
8 - GamificationPlugin.gamification_set_rules(Environment.default) 8 + @environment = Environment.default
  9 + GamificationPlugin.gamification_set_rules(@environment)
9 end 10 end
10 - attr_accessor :person, :article 11 + attr_accessor :person, :article, :environment
11 12
12 should 'add merit points to author when create a new comment' do 13 should 'add merit points to author when create a new comment' do
13 create(Comment, :source => article, :author_id => person.id) 14 create(Comment, :source => article, :author_id => person.id)
@@ -23,6 +24,9 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -23,6 +24,9 @@ class CommentTest &lt; ActiveSupport::TestCase
23 end 24 end
24 25
25 should 'add merit badge to author when create 5 new comments' do 26 should 'add merit badge to author when create 5 new comments' do
  27 + GamificationPlugin::Badge.create!(:owner => environment, :name => 'comment_author')
  28 + GamificationPlugin.gamification_set_rules(environment)
  29 +
26 5.times { create(Comment, :source => article, :author_id => person.id) } 30 5.times { create(Comment, :source => article, :author_id => person.id) }
27 assert_equal 'comment_author', person.badges.first.name 31 assert_equal 'comment_author', person.badges.first.name
28 end 32 end