Commit 7cc2f467770c1614829549d8b405e4583c2e3221

Authored by Victor Costa
1 parent 00a9e2a0

Manage rank rules

controllers/gamification_plugin_admin_controller.rb
@@ -11,6 +11,14 @@ class GamificationPluginAdminController < PluginAdminController @@ -11,6 +11,14 @@ class GamificationPluginAdminController < PluginAdminController
11 end 11 end
12 end 12 end
13 13
  14 + def levels
  15 + if save_settings
  16 + render :file => 'gamification_plugin_admin/index'
  17 + else
  18 + render :file => 'gamification_plugin_admin/levels'
  19 + end
  20 + end
  21 +
14 protected 22 protected
15 23
16 def save_settings 24 def save_settings
lib/ext/profile.rb
@@ -4,4 +4,14 @@ class Profile @@ -4,4 +4,14 @@ class Profile
4 4
5 has_merit 5 has_merit
6 6
  7 + def gamification_plugin_calculate_level
  8 + settings = GamificationPlugin.settings(environment)
  9 + last_level = 0
  10 + (settings.get_setting(:rank_rules) || []).sort_by {|r| r[:points] }.each do |rule|
  11 + return last_level if points < rule[:points]
  12 + last_level = rule[:level]
  13 + end
  14 + last_level
  15 + end
  16 +
7 end 17 end
lib/gamification_plugin.rb
@@ -8,6 +8,10 @@ class GamificationPlugin &lt; Noosfero::Plugin @@ -8,6 +8,10 @@ class GamificationPlugin &lt; Noosfero::Plugin
8 _("Gamification Plugin") 8 _("Gamification Plugin")
9 end 9 end
10 10
  11 + def self.settings(environment)
  12 + Noosfero::Plugin::Settings.new(environment, GamificationPlugin)
  13 + end
  14 +
11 def user_data_extras 15 def user_data_extras
12 proc do 16 proc do
13 current_person.present? ? {:gamification_plugin => {:points => current_person.points, :badges => current_person.badges, :level => current_person.level}} : {} 17 current_person.present? ? {:gamification_plugin => {:points => current_person.points, :badges => current_person.badges, :level => current_person.level}} : {}
@@ -54,6 +58,7 @@ class GamificationPlugin &lt; Noosfero::Plugin @@ -54,6 +58,7 @@ class GamificationPlugin &lt; Noosfero::Plugin
54 config.checks_on_each_request = false 58 config.checks_on_each_request = false
55 config.user_model_name = 'Profile' 59 config.user_model_name = 'Profile'
56 config.current_user_method = 'current_person' 60 config.current_user_method = 'current_person'
  61 + config.add_observer 'Merit::RankObserver'
57 end 62 end
58 63
59 require_dependency 'merit_ext' 64 require_dependency 'merit_ext'
lib/merit/rank_observer.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +module Merit
  2 +
  3 + class RankObserver
  4 + def update(changed_data)
  5 + merit = changed_data[:merit_object]
  6 + if merit.kind_of?(Merit::Score::Point)
  7 + profile = merit.score.sash.profile
  8 + profile.update_attribute(:level, profile.gamification_plugin_calculate_level) if profile.present?
  9 + end
  10 + end
  11 + end
  12 +
  13 +end
lib/merit/rank_rules.rb
@@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
1 -# Be sure to restart your server when you modify this file.  
2 -#  
3 -# 5 stars is a common ranking use case. They are not given at specified  
4 -# actions like badges, you should define a cron job to test if ranks are to be  
5 -# granted.  
6 -#  
7 -# +set_rank+ accepts:  
8 -# * :+level+ ranking level (greater is better)  
9 -# * :+to+ model or scope to check if new rankings apply  
10 -# * :+level_name+ attribute name (default is empty and results in 'level'  
11 -# attribute, if set it's appended like 'level_#{level_name}')  
12 -  
13 -module Merit  
14 - class RankRules  
15 - include Merit::RankRulesMethods  
16 -  
17 - def initialize  
18 - # set_rank :level => 1, :to => Commiter.active do |commiter|  
19 - # commiter.repositories.count > 1 && commiter.followers >= 10  
20 - # end  
21 - #  
22 - # set_rank :level => 2, :to => Commiter.active do |commiter|  
23 - # commiter.branches.count > 1 && commiter.followers >= 10  
24 - # end  
25 - #  
26 - # set_rank :level => 3, :to => Commiter.active do |commiter|  
27 - # commiter.branches.count > 2 && commiter.followers >= 20  
28 - # end  
29 - end  
30 - end  
31 -end  
lib/merit/sash.rb
@@ -3,6 +3,12 @@ module Merit @@ -3,6 +3,12 @@ module Merit
3 class Sash 3 class Sash
4 has_many :gamification_plugin_badges, :through => :badges_sashes, :source => :gamification_plugin_badge 4 has_many :gamification_plugin_badges, :through => :badges_sashes, :source => :gamification_plugin_badge
5 alias :badges :gamification_plugin_badges 5 alias :badges :gamification_plugin_badges
  6 + has_one :profile, :foreign_key => :sash_id, :class_name => 'Profile'
  7 + has_one :article, :foreign_key => :sash_id, :class_name => 'Article'
  8 +
  9 + def target
  10 + profile || article
  11 + end
6 end 12 end
7 13
8 def notify_all_badges_from_user 14 def notify_all_badges_from_user
public/admin.css 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +.gamification-plugin-rank-rules .template-level {
  2 + display: none !important;
  3 +}
public/admin.js 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +var gamificationPluginAdmin = {
  2 +
  3 + addNewLevelRule: function() {
  4 + var template = $('.gamification-plugin-rank-rules .template-level > div').clone();
  5 + template.find('.level-value').text($('.gamification-plugin-rank-rules .rank-rules .items .level').length + 1);
  6 + $('.gamification-plugin-rank-rules .rank-rules .items').append(template);
  7 + }
  8 +}
test/functional/gamification_plugin_admin_controller_test.rb
@@ -31,5 +31,20 @@ class GamificationPluginAdminControllerTest &lt; ActionController::TestCase @@ -31,5 +31,20 @@ class GamificationPluginAdminControllerTest &lt; ActionController::TestCase
31 assert_select 'input[name=?][value=?]', "settings[point_rules][comment_author[weight]]", 500 31 assert_select 'input[name=?][value=?]', "settings[point_rules][comment_author[weight]]", 500
32 end 32 end
33 33
  34 + should 'save rank rules' do
  35 + post :levels, :settings => {:rank_rules => [{:level => 1, :points => 10}]}
  36 + @settings = Noosfero::Plugin::Settings.new(environment.reload, GamificationPlugin)
  37 + assert_equal({:rank_rules => [{'level' => '1', 'points' => '10'}]}, @settings.settings)
  38 + end
  39 +
  40 + should 'load saved levels' do
  41 + settings = Noosfero::Plugin::Settings.new(environment, GamificationPlugin, {})
  42 + settings.set_setting(:rank_rules, [{'level' => '1', 'points' => '10'}, {'level' => '2', 'points' => '20'}])
  43 + settings.save!
  44 + get :levels
  45 + assert_select 'input[name=?][value=?]', "settings[rank_rules][][points]", 10
  46 + assert_select 'input[name=?][value=?]', "settings[rank_rules][][points]", 20
  47 + end
  48 +
34 end 49 end
35 50
test/unit/profile_test.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class ProfileTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @profile = fast_create(Profile)
  8 + @settings = GamificationPlugin.settings(environment)
  9 + @settings.set_setting(:rank_rules, [
  10 + {:level => 1, :points => 10},
  11 + {:level => 2, :points => 20},
  12 + {:level => 3, :points => 30}
  13 + ])
  14 + @settings.save!
  15 + end
  16 +
  17 + attr_accessor :profile, :environment
  18 +
  19 + should 'calculate profile level' do
  20 + profile.stubs(:points).returns(25)
  21 + assert_equal 2, profile.gamification_plugin_calculate_level
  22 + end
  23 +
  24 + should 'calculate profile last level' do
  25 + profile.stubs(:points).returns(35)
  26 + assert_equal 3, profile.gamification_plugin_calculate_level
  27 + end
  28 +
  29 + should 'calculate profile first level' do
  30 + profile.stubs(:points).returns(10)
  31 + assert_equal 1, profile.gamification_plugin_calculate_level
  32 + end
  33 +
  34 + should 'update profile level when the score changes' do
  35 + GamificationPlugin.gamification_set_rules(environment)
  36 + person = create_user('testuser').person
  37 + assert_equal 0, person.level
  38 + create(Article, :profile_id => profile.id, :author => person)
  39 + assert_equal 3, person.reload.level
  40 + end
  41 +
  42 +end
views/gamification_plugin_admin/_level.html.erb 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +<div class="level">
  2 + <span class="label"><%= _('Level') %></span> <span class="level-value"><%= level_counter + 1 %></span>
  3 + <span><%= text_field_tag("settings[rank_rules][][points]", level['points']) %></span>
  4 +</div>
views/gamification_plugin_admin/index.html.erb
1 <h1><%= _('Gamification Settings')%></h1> 1 <h1><%= _('Gamification Settings')%></h1>
2 2
3 -<div>  
4 - <%= link_to _('Manage Point Rules'), :controller => 'gamification_plugin_admin', :action => :points %>  
5 -</div> 3 +<ul>
  4 + <li>
  5 + <%= link_to _('Manage Point Rules'), :controller => 'gamification_plugin_admin', :action => :points %>
  6 + </li>
6 7
7 -<div>  
8 - <%= link_to _('Manage Badges'), :controller => 'gamification_plugin_badges' %>  
9 -</div> 8 + <li>
  9 + <%= link_to _('Manage Badges'), :controller => 'gamification_plugin_badges' %>
  10 + </li>
10 11
11 -<div>  
12 - <%#= link_to _('Manage Levels'), :controller => 'gamification_plugin_admin', :action => :levels %>  
13 -</div> 12 + <li>
  13 + <%= link_to _('Manage Levels'), :controller => 'gamification_plugin_admin', :action => :levels %>
  14 + </li>
  15 +</ul>
14 16
15 -<%= button :cancel, _('Cancel'), :controller => :plugins, :action => :index %> 17 +<div class="actions">
  18 + <%= button :cancel, _('Cancel'), :controller => :plugins, :action => :index %>
  19 +</div>
views/gamification_plugin_admin/levels.html.erb 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +<%= javascript_include_tag 'plugins/gamification/admin.js' %>
  2 +<%= stylesheet_link_tag 'plugins/gamification/admin.css' %>
  3 +
  4 +<div class="gamification-plugin-rank-rules">
  5 +<h1><%= _('Gamification Settings: Rank Rules')%></h1>
  6 +
  7 +<%= form_for(:settings) do |f| %>
  8 + <div class="rank-rules">
  9 + <h3><%= _('Rank Rules') %></h3>
  10 + <div class="items">
  11 + <%= render :partial => 'gamification_plugin_admin/level', :collection => @settings.rank_rules %>
  12 + </div>
  13 + </div>
  14 +
  15 + <% button_bar do %>
  16 + <%= link_to_function(_('New Level'), 'gamificationPluginAdmin.addNewLevelRule();', :class => 'button icon-add with-text') %>
  17 + <%= submit_button(:save, c_('Save'), :cancel => {:action => 'index'}) %>
  18 + <% end %>
  19 +
  20 +<% end %>
  21 +
  22 +<div class="template-level">
  23 + <%= render :partial => 'gamification_plugin_admin/level', :collection => [{}] %>
  24 +</div>
  25 +
  26 +</div>