Commit 7fd77a7eb0747bc580694f7c668dcb401af8736b
1 parent
7b2d77fa
Exists in
master
and in
1 other branch
Categorize points
Showing
9 changed files
with
95 additions
and
26 deletions
Show diff stats
lib/gamification_plugin.rb
@@ -8,6 +8,12 @@ class GamificationPlugin < Noosfero::Plugin | @@ -8,6 +8,12 @@ class GamificationPlugin < Noosfero::Plugin | ||
8 | _("Gamification Plugin") | 8 | _("Gamification Plugin") |
9 | end | 9 | end |
10 | 10 | ||
11 | + def user_data_extras | ||
12 | + proc do | ||
13 | + {:points => current_person.points} | ||
14 | + end | ||
15 | + end | ||
16 | + | ||
11 | Merit.setup do |config| | 17 | Merit.setup do |config| |
12 | config.checks_on_each_request = false | 18 | config.checks_on_each_request = false |
13 | config.user_model_name = 'Profile' | 19 | config.user_model_name = 'Profile' |
lib/merit/badge_rules.rb
@@ -23,20 +23,20 @@ module Merit | @@ -23,20 +23,20 @@ module Merit | ||
23 | def initialize | 23 | def initialize |
24 | 24 | ||
25 | grant_on 'comment#create', badge: 'commenter' do |comment| | 25 | grant_on 'comment#create', badge: 'commenter' do |comment| |
26 | - comment.author.present? && comment.author.comments.count == 5 | 26 | + comment.author.present? && comment.author.comments.count >= 5 |
27 | end | 27 | end |
28 | 28 | ||
29 | grant_on 'article#create', badge: 'article-creator', level: 1 do |article| | 29 | grant_on 'article#create', badge: 'article-creator', level: 1 do |article| |
30 | - article.author.present? && article.author.articles.count == 5 | 30 | + article.author.present? && article.author.articles.count >= 5 |
31 | end | 31 | end |
32 | 32 | ||
33 | grant_on 'article#create', badge: 'article-creator', level: 2 do |article| | 33 | grant_on 'article#create', badge: 'article-creator', level: 2 do |article| |
34 | - article.author.present? && article.author.articles.count == 10 | 34 | + article.author.present? && article.author.articles.count >= 10 |
35 | end | 35 | end |
36 | 36 | ||
37 | grant_on 'vote_plugin_profile#vote', badge: 'relevant-commenter', model_name: 'comment', to: 'author' do |voteable| | 37 | grant_on 'vote_plugin_profile#vote', badge: 'relevant-commenter', model_name: 'comment', to: 'author' do |voteable| |
38 | return false if voteable.nil? || !voteable.kind_of?(Comment) | 38 | return false if voteable.nil? || !voteable.kind_of?(Comment) |
39 | - voteable.votes.count == 2 | 39 | + voteable.votes.count >= 2 |
40 | end | 40 | end |
41 | 41 | ||
42 | end | 42 | end |
lib/merit/point_rules.rb
@@ -42,8 +42,8 @@ module Merit | @@ -42,8 +42,8 @@ module Merit | ||
42 | } | 42 | } |
43 | 43 | ||
44 | # FIXME get value from environment | 44 | # FIXME get value from environment |
45 | - def weight(action) | ||
46 | - case action | 45 | + def weight(category) |
46 | + case category | ||
47 | when :comment_author | 47 | when :comment_author |
48 | 10 | 48 | 10 |
49 | when :article_author | 49 | when :article_author |
@@ -55,28 +55,18 @@ module Merit | @@ -55,28 +55,18 @@ module Merit | ||
55 | end | 55 | end |
56 | end | 56 | end |
57 | 57 | ||
58 | - def calculate_score(target, action, value) | 58 | + def calculate_score(target, category, value) |
59 | value = value.call(target) if value.respond_to?(:call) | 59 | value = value.call(target) if value.respond_to?(:call) |
60 | - weight(action) * value | 60 | + weight(category) * value |
61 | end | 61 | end |
62 | 62 | ||
63 | def initialize | 63 | def initialize |
64 | - AVAILABLE_RULES.each do |key, setting| | ||
65 | - score lambda {|target| calculate_score(target, key, setting[:value])}, :on => setting[:action], :to => setting[:to] | ||
66 | - if setting[:undo_action].present? | ||
67 | - score lambda {|target| -calculate_score(target, key, setting[:value])}, :on => setting[:undo_action], :to => setting[:to] | 64 | + AVAILABLE_RULES.each do |category, setting| |
65 | + [setting[:action], setting[:undo_action]].compact.zip([1, -1]).each do |action, signal| | ||
66 | + score lambda {|target| signal * calculate_score(target, category, setting[:value])}, :on => action, :to => setting[:to], :category => category | ||
68 | end | 67 | end |
69 | end | 68 | end |
70 | - | ||
71 | - #score lambda {|target| calculate_score(target, :comment_create, 1)}, :on => 'comment#create' | ||
72 | - #score lambda {|target| calculate_score(target, :comment_create, -1)}, :on => 'comment#destroy' | ||
73 | - | ||
74 | - #score lambda {|target| calculate_score(target, :article_create, 1)}, :on => 'article#create' | ||
75 | - #score lambda {|target| calculate_score(target, :article_create, -1)}, :on => 'article#destroy' | ||
76 | - | ||
77 | - #score lambda {|target| calculate_score(target, :vote_create, target.vote)}, :on => 'vote#create', :to => lambda {|vote| vote.voteable.author} | ||
78 | - #score lambda {|target| calculate_score(target, :vote_create, target.vote)}, :on => 'vote#create', :to => lambda {|vote| vote.voteable} | ||
79 | - #score lambda {|target| calculate_score(target, :vote_create, -target.vote)}, :on => 'vote#destroy', :to => lambda {|vote| vote.voteable.author} | ||
80 | end | 69 | end |
70 | + | ||
81 | end | 71 | end |
82 | end | 72 | end |
test/functional/gamification_plugin_profile_controller_test.rb
0 → 100644
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +require_relative '../test_helper' | ||
2 | + | ||
3 | +class GamificationPluginProfileControllerTest < ActionController::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @profile = fast_create(Profile) | ||
7 | + @person = create_user('person').person | ||
8 | + login_as(@person.identifier) | ||
9 | + end | ||
10 | + | ||
11 | + attr_accessor :profile, :person | ||
12 | + | ||
13 | + should 'display points in gamification info page' do | ||
14 | + Profile.any_instance.expects(:points).returns(125) | ||
15 | + get :info, :profile => profile.identifier | ||
16 | + assert_tag :div, :attributes => {:class => 'score'}, :child => {:tag => 'span', :attributes => {:class => 'value'}, :content => '125'} | ||
17 | + end | ||
18 | + | ||
19 | + should 'display level in gamification info page' do | ||
20 | + person.update_attribute(:level, 12) | ||
21 | + get :info, :profile => profile.identifier | ||
22 | + assert_tag :div, :attributes => {:class => 'level'}, :child => {:tag => 'span', :attributes => {:class => 'value'}, :content => '12'} | ||
23 | + end | ||
24 | + | ||
25 | +end |
test/unit/article_test.rb
@@ -36,7 +36,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -36,7 +36,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
36 | should 'add merit points to article owner when an user like it' do | 36 | should 'add merit points to article owner when an user like it' do |
37 | article = create(Article, :name => 'Test', :profile => person, :author => person) | 37 | article = create(Article, :name => 'Test', :profile => person, :author => person) |
38 | 38 | ||
39 | - assert_difference 'article.author.points', 5 do | 39 | + assert_difference 'article.author.points(:category => :vote_voteable_author)', 5 do |
40 | Vote.create!(:voter => person, :voteable => article, :vote => 1) | 40 | Vote.create!(:voter => person, :voteable => article, :vote => 1) |
41 | end | 41 | end |
42 | end | 42 | end |
@@ -45,7 +45,7 @@ class ArticleTest < ActiveSupport::TestCase | @@ -45,7 +45,7 @@ class ArticleTest < ActiveSupport::TestCase | ||
45 | article = create(Article, :name => 'Test', :profile => person, :author => person) | 45 | article = create(Article, :name => 'Test', :profile => person, :author => person) |
46 | article = article.reload | 46 | article = article.reload |
47 | 47 | ||
48 | - assert_difference 'article.points', 5 do | 48 | + assert_difference 'article.points(:category => :vote_voteable)', 5 do |
49 | Vote.create!(:voter => person, :voteable => article, :vote => 1) | 49 | Vote.create!(:voter => person, :voteable => article, :vote => 1) |
50 | end | 50 | end |
51 | end | 51 | end |
test/unit/comment_test.rb
@@ -29,7 +29,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -29,7 +29,7 @@ class CommentTest < ActiveSupport::TestCase | ||
29 | should 'add merit points to comment owner when an user like his comment' do | 29 | should 'add merit points to comment owner when an user like his comment' do |
30 | comment = create(Comment, :source => article, :author_id => person.id) | 30 | comment = create(Comment, :source => article, :author_id => person.id) |
31 | 31 | ||
32 | - assert_difference 'comment.author.points', 5 do | 32 | + assert_difference 'comment.author.points(:category => :vote_voteable_author)', 5 do |
33 | Vote.create!(:voter => person, :voteable => comment, :vote => 1) | 33 | Vote.create!(:voter => person, :voteable => comment, :vote => 1) |
34 | end | 34 | end |
35 | end | 35 | end |
@@ -46,7 +46,7 @@ class CommentTest < ActiveSupport::TestCase | @@ -46,7 +46,7 @@ class CommentTest < ActiveSupport::TestCase | ||
46 | should 'subtract merit points from comment owner when an user dislike his comment' do | 46 | should 'subtract merit points from comment owner when an user dislike his comment' do |
47 | comment = create(Comment, :source => article, :author_id => person.id) | 47 | comment = create(Comment, :source => article, :author_id => person.id) |
48 | 48 | ||
49 | - assert_difference 'comment.author.points', -5 do | 49 | + assert_difference 'comment.author.points(:category => :vote_voteable_author)', -5 do |
50 | Vote.create!(:voter => person, :voteable => comment, :vote => -1) | 50 | Vote.create!(:voter => person, :voteable => comment, :vote => -1) |
51 | end | 51 | end |
52 | end | 52 | end |
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +require_relative '../../../../test/test_helper' | ||
2 | + | ||
3 | +class GamificationPluginTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @plugin = GamificationPlugin.new | ||
7 | + @current_person = create_user('person').person | ||
8 | + end | ||
9 | + | ||
10 | + attr_accessor :plugin, :current_person | ||
11 | + | ||
12 | + should 'return user points in user_data_extras' do | ||
13 | + assert_equal({:points => 0}, instance_eval(&plugin.user_data_extras)) | ||
14 | + end | ||
15 | + | ||
16 | +end |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<div class="gamification"> | ||
2 | + <h1><%= _('Gamification Info for %s' % @target.identifier) %></h1> | ||
3 | + <div class="score"> | ||
4 | + <span class="label"><%= _('Score: ') %></span> | ||
5 | + <span class="value"><%= @target.points %></span> | ||
6 | + </div> | ||
7 | + <div class="level"> | ||
8 | + <span class="label"><%= _('Level: ') %></span> | ||
9 | + <span class="value"><%= @target.level %></span> | ||
10 | + </div> | ||
11 | + <div class="badges"> | ||
12 | + <h3><%= _('Badges') %></h3> | ||
13 | + <ul> | ||
14 | + <% @target.badges.each do |badge| %> | ||
15 | + <li class="badge <%= badge.name %>"> | ||
16 | + <span class="description"><%= badge.description %></span> | ||
17 | + <% if badge.level.present? %> | ||
18 | + <span class="label"><%= _('Level') %></span> <span class="level"><%= badge.level %></span> | ||
19 | + <% end %> | ||
20 | + </li> | ||
21 | + <% end %> | ||
22 | + </ul> | ||
23 | + </div> | ||
24 | +</div> |