Commit 7cc2f467770c1614829549d8b405e4583c2e3221
1 parent
00a9e2a0
Exists in
master
and in
1 other branch
Manage rank rules
Showing
13 changed files
with
154 additions
and
41 deletions
Show diff stats
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 < Noosfero::Plugin | @@ -8,6 +8,10 @@ class GamificationPlugin < 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 < Noosfero::Plugin | @@ -54,6 +58,7 @@ class GamificationPlugin < 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' |
@@ -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 |
@@ -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 < ActionController::TestCase | @@ -31,5 +31,20 @@ class GamificationPluginAdminControllerTest < 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 |
@@ -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/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> |
@@ -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> |