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 11 end
12 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 22 protected
15 23  
16 24 def save_settings
... ...
lib/ext/profile.rb
... ... @@ -4,4 +4,14 @@ class Profile
4 4  
5 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 17 end
... ...
lib/gamification_plugin.rb
... ... @@ -8,6 +8,10 @@ class GamificationPlugin &lt; Noosfero::Plugin
8 8 _("Gamification Plugin")
9 9 end
10 10  
  11 + def self.settings(environment)
  12 + Noosfero::Plugin::Settings.new(environment, GamificationPlugin)
  13 + end
  14 +
11 15 def user_data_extras
12 16 proc do
13 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 58 config.checks_on_each_request = false
55 59 config.user_model_name = 'Profile'
56 60 config.current_user_method = 'current_person'
  61 + config.add_observer 'Merit::RankObserver'
57 62 end
58 63  
59 64 require_dependency 'merit_ext'
... ...
lib/merit/rank_observer.rb 0 → 100644
... ... @@ -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   -# 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 3 class Sash
4 4 has_many :gamification_plugin_badges, :through => :badges_sashes, :source => :gamification_plugin_badge
5 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 12 end
7 13  
8 14 def notify_all_badges_from_user
... ...
public/admin.css 0 → 100644
... ... @@ -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 @@
  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 31 assert_select 'input[name=?][value=?]', "settings[point_rules][comment_author[weight]]", 500
32 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 49 end
35 50  
... ...
test/unit/profile_test.rb 0 → 100644
... ... @@ -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 @@
  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 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 @@
  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>
... ...