Commit a49ad7f9df9506c398cfd8f44c36959fc8e7c255

Authored by Victor Costa
1 parent 6334307e

Dynamically define badges

db/migrate/20150330102818_create_badges.rb 0 → 100644
... ... @@ -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 @@
  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 37  
38 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 40 end
... ...
lib/gamification_plugin/badge.rb 0 → 100644
... ... @@ -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 41 def initialize(environment=nil)
42 42 return if environment.nil?
43 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 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 54 end
50 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 57 grant_on 'vote_plugin_profile#vote', badge: 'relevant-commenter', model_name: 'comment', to: 'author' do |voteable|
61 58 return false if voteable.nil? || !voteable.kind_of?(Comment)
62 59 voteable.votes.count >= 2
... ...
test/functional/gamification_plugin_profile_controller_test.rb
... ... @@ -5,10 +5,11 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase
5 5 def setup
6 6 @profile = fast_create(Profile)
7 7 @person = create_user('person').person
  8 + @environment = Environment.default
8 9 login_as(@person.identifier)
9 10 end
10 11  
11   - attr_accessor :profile, :person
  12 + attr_accessor :profile, :person, :environment
12 13  
13 14 should 'display points in gamification info page' do
14 15 person.add_points(20, :category => :comment_author)
... ... @@ -26,8 +27,12 @@ class GamificationPluginProfileControllerTest &lt; ActionController::TestCase
26 27 end
27 28  
28 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 36 get :info, :profile => profile.identifier
32 37 assert_select '.badges .badge-list .badge', 2
33 38 end
... ...
test/unit/article_test.rb
... ... @@ -4,10 +4,11 @@ class ArticleTest &lt; ActiveSupport::TestCase
4 4  
5 5 def setup
6 6 @person = create_user('testuser').person
7   - GamificationPlugin.gamification_set_rules(Environment.default)
  7 + @environment = Environment.default
  8 + GamificationPlugin.gamification_set_rules(@environment)
8 9 end
9 10  
10   - attr_accessor :person
  11 + attr_accessor :person, :environment
11 12  
12 13 should 'add merit points to author when create a new article' do
13 14 create(Article, :profile_id => person.id, :author => person)
... ... @@ -23,12 +24,19 @@ class ArticleTest &lt; ActiveSupport::TestCase
23 24 end
24 25  
25 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 30 5.times { create(Article, :profile_id => person.id, :author => person) }
27 31 assert_equal 'article_author', person.badges.first.name
28 32 assert_equal 1, person.badges.first.level
29 33 end
30 34  
31 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 40 10.times { create(Article, :profile_id => person.id, :author => person) }
33 41 assert_equal ['article_author'], person.badges.map(&:name).uniq
34 42 assert_equal [1, 2], person.badges.map(&:level)
... ...
test/unit/comment_test.rb
... ... @@ -5,9 +5,10 @@ class CommentTest &lt; ActiveSupport::TestCase
5 5 def setup
6 6 @person = create_user('testuser').person
7 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 10 end
10   - attr_accessor :person, :article
  11 + attr_accessor :person, :article, :environment
11 12  
12 13 should 'add merit points to author when create a new comment' do
13 14 create(Comment, :source => article, :author_id => person.id)
... ... @@ -23,6 +24,9 @@ class CommentTest &lt; ActiveSupport::TestCase
23 24 end
24 25  
25 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 30 5.times { create(Comment, :source => article, :author_id => person.id) }
27 31 assert_equal 'comment_author', person.badges.first.name
28 32 end
... ...