merit 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +7 -4
- data/Rakefile +4 -7
- data/UPGRADING.md +14 -0
- data/app/models/merit/badge.rb +1 -1
- data/lib/generators/active_record/templates/add_target_data_to_merit_actions.rb +5 -0
- data/lib/generators/active_record/templates/create_merit_actions.rb +1 -0
- data/lib/generators/active_record/upgrade_generator.rb +36 -0
- data/lib/generators/merit/upgrade_generator.rb +7 -0
- data/lib/merit.rb +7 -2
- data/lib/merit/base_target_finder.rb +19 -3
- data/lib/merit/controller_extensions.rb +16 -3
- data/lib/merit/model_additions.rb +1 -1
- data/lib/merit/models/active_record/merit/action.rb +1 -1
- data/lib/merit/models/base/badges_sash.rb +1 -1
- data/lib/merit/models/mongoid/merit/action.rb +1 -0
- data/lib/merit/rule.rb +1 -1
- data/lib/merit/rules_rank_methods.rb +11 -2
- data/lib/merit/sash_finder.rb +4 -0
- data/lib/merit/target_finder.rb +2 -3
- data/merit.gemspec +2 -3
- data/test/dummy/app/models/merit/point_rules.rb +4 -0
- data/test/dummy/app/models/user.rb +1 -1
- data/test/dummy/app/views/layouts/application.html.erb +0 -1
- data/test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb +5 -0
- data/test/dummy/db/migrate/20140906225844_create_players.rb +8 -0
- data/test/dummy/db/schema.rb +36 -30
- data/test/integration/navigation_test.rb +39 -32
- data/test/orm_models/active_record.rb +0 -4
- data/test/orm_models/mongoid.rb +0 -5
- data/test/support/integration_case.rb +1 -1
- data/test/test_helper.rb +8 -13
- data/test/unit/action_test.rb +12 -0
- data/test/unit/base_target_finder_test.rb +39 -4
- data/test/unit/merit_unit_test.rb +12 -10
- data/test/unit/sash_finder_test.rb +2 -2
- data/test/unit/score_test.rb +3 -3
- data/test/unit/target_finder_test.rb +11 -10
- metadata +11 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bceef6c4f4123e4b5aa45f35c90f51779803eccb
|
4
|
+
data.tar.gz: f64bea2e08e184c8b413e5410c02424f51b44c35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22924df6b8915eb8dde70a0360141d2551eaf42d21cc8c45fbd8375354ff5897bd8e68433963cf426265be38eac3adfe4487c7c95376739b43f93d7d297bc075
|
7
|
+
data.tar.gz: 9d1324c2c32759030bb54e7aa9b37face51cf7e82da3ab53462b818a200e1efbb9d05d83fb896345cb112dfab21047c38bcd1c348e7175de72337df67b6f4007
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.2.0
|
4
|
+
|
5
|
+
- [#181] Rescue `ActiveRecord` only if constant is defined (doesn't trigger
|
6
|
+
errors in other ORMs).
|
7
|
+
- [#184] Namespaces `Badge` calls inside of `Merit::`. Prevents errors if the
|
8
|
+
app using merit has a model named Badge
|
9
|
+
- [#189] Fixes issue when objects needed to grant reputation are already deleted
|
10
|
+
from the database. Before, merit was either failing with exceptions or
|
11
|
+
ignoring reputation changes; now it works as expected.
|
12
|
+
|
3
13
|
## 2.1.2
|
4
14
|
|
5
15
|
- Improves observer API.
|
data/Gemfile
CHANGED
@@ -2,15 +2,17 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
version = ENV['RAILS_VERSION'] || '
|
5
|
+
version = ENV['RAILS_VERSION'] || '4.1'
|
6
6
|
rails = case version
|
7
7
|
when 'master'
|
8
8
|
{ github: 'rails/rails' }
|
9
9
|
when '4.0-protected-attributes'
|
10
10
|
gem 'protected_attributes'
|
11
|
+
"~> 4.0.0"
|
12
|
+
when /4\.0|4\.1/
|
11
13
|
"~> #{version}.0"
|
12
|
-
when
|
13
|
-
"~> #{version}.0"
|
14
|
+
when /4\.2/
|
15
|
+
"~> #{version}.0.beta1"
|
14
16
|
when '3.2'
|
15
17
|
gem 'strong_parameters'
|
16
18
|
"~> #{version}.0"
|
@@ -22,7 +24,7 @@ case ENV['ORM']
|
|
22
24
|
when 'active_record'
|
23
25
|
gem 'activerecord'
|
24
26
|
when 'mongoid'
|
25
|
-
gem 'mongoid'
|
27
|
+
gem 'mongoid'
|
26
28
|
end
|
27
29
|
|
28
30
|
group :development, :test do
|
@@ -32,6 +34,7 @@ end
|
|
32
34
|
|
33
35
|
platforms :rbx do
|
34
36
|
gem 'rubysl', '~> 2.0'
|
37
|
+
gem 'psych'
|
35
38
|
gem 'racc'
|
36
39
|
gem 'minitest'
|
37
40
|
gem 'rubinius-developer_tools'
|
data/Rakefile
CHANGED
@@ -1,27 +1,24 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
require 'rubygems'
|
3
2
|
begin
|
4
3
|
require 'bundler/setup'
|
5
4
|
rescue LoadError
|
6
5
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
6
|
end
|
8
7
|
|
9
|
-
require 'rake'
|
10
|
-
|
11
8
|
require 'rake/testtask'
|
12
9
|
|
10
|
+
desc 'Default: run tests for all ORMs.'
|
11
|
+
task default: :test
|
12
|
+
|
13
13
|
Rake::TestTask.new(:test) do |t|
|
14
14
|
t.libs << 'lib'
|
15
15
|
t.libs << 'test'
|
16
16
|
t.pattern = 'test/**/*_test.rb'
|
17
|
-
t.verbose =
|
17
|
+
t.verbose = true
|
18
18
|
end
|
19
19
|
|
20
|
-
task :default => :test
|
21
|
-
|
22
20
|
begin
|
23
21
|
require 'rdoc/task'
|
24
|
-
|
25
22
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
26
23
|
rdoc.rdoc_dir = 'rdoc'
|
27
24
|
rdoc.title = 'Merit'
|
data/UPGRADING.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Main Changes / Upgrading Notes
|
2
2
|
|
3
|
+
## 2.1.0
|
4
|
+
|
5
|
+
Adds serialisation of destroyed target models so that reputation can be awarded
|
6
|
+
when the item is already deleted from the DB. For this to work you need a new
|
7
|
+
column, to add it you can run:
|
8
|
+
|
9
|
+
```
|
10
|
+
rails generate merit:upgrade
|
11
|
+
rake db:migrate
|
12
|
+
```
|
13
|
+
|
14
|
+
This is a backwards compatible addition, so if you don't add the column but
|
15
|
+
upgrade, your application should continue to work well, without the new feature.
|
16
|
+
|
3
17
|
## 2.0.0
|
4
18
|
|
5
19
|
* Removes deprecated methods: `Merit::Badge.last_granted` and
|
data/app/models/merit/badge.rb
CHANGED
@@ -36,7 +36,7 @@ module Merit
|
|
36
36
|
|
37
37
|
class << self
|
38
38
|
def find_by_name_and_level(name, level)
|
39
|
-
badges = Badge.by_name(name)
|
39
|
+
badges = Merit::Badge.by_name(name)
|
40
40
|
badges = badges.by_level(level) unless level.nil?
|
41
41
|
if (badge = badges.first).nil?
|
42
42
|
str = "No badge '#{name}' found. Define it in initializers/merit.rb"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Generators
|
5
|
+
class UpgradeGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
desc 'Makes Active Record migrations to handle upgrades between versions'
|
10
|
+
|
11
|
+
def self.next_migration_number(path)
|
12
|
+
ActiveRecord::Generators::Base.next_migration_number(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_migrations_and_model
|
16
|
+
if merit_actions_exists? && target_data_column_doesnt_exist?
|
17
|
+
migration_template 'add_target_data_to_merit_actions.rb',
|
18
|
+
'db/migrate/add_target_data_to_merit_actions.rb'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def target_data_column_doesnt_exist?
|
25
|
+
!ActiveRecord::Base.connection.column_exists?(:merit_actions,
|
26
|
+
:target_data)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Might be foolishly running this before install. Ugly error if we don't
|
30
|
+
# check.
|
31
|
+
def merit_actions_exists?
|
32
|
+
ActiveRecord::Base.connection.table_exists? :merit_actions
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/merit.rb
CHANGED
@@ -49,6 +49,11 @@ module Merit
|
|
49
49
|
@config.add_observer(class_name)
|
50
50
|
end
|
51
51
|
|
52
|
+
def self.upgrade_target_data_warning
|
53
|
+
Rails.logger.warn '[merit] Missing column: target_data. Run `rails ' \
|
54
|
+
'generate merit:upgrade` and `rake db:migrate` to add it.'
|
55
|
+
end
|
56
|
+
|
52
57
|
class Configuration
|
53
58
|
attr_accessor :checks_on_each_request, :orm, :user_model_name, :observers,
|
54
59
|
:current_user_method
|
@@ -68,8 +73,8 @@ module Merit
|
|
68
73
|
setup
|
69
74
|
add_observer('Merit::ReputationChangeObserver')
|
70
75
|
|
71
|
-
class BadgeNotFound <
|
72
|
-
class RankAttributeNotDefined <
|
76
|
+
class BadgeNotFound < StandardError; end
|
77
|
+
class RankAttributeNotDefined < StandardError; end
|
73
78
|
|
74
79
|
class Engine < Rails::Engine
|
75
80
|
config.app_generators.orm Merit.orm
|
@@ -10,11 +10,27 @@ module Merit
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def find
|
13
|
-
|
14
|
-
klass = klass_name.camelize.constantize
|
15
|
-
klass.find_by_id @action.target_id
|
13
|
+
get_target_from_database || reanimate_target_from_action
|
16
14
|
rescue => e
|
17
15
|
Rails.logger.warn "[merit] no target found: #{e}. #{caller.first}"
|
18
16
|
end
|
17
|
+
|
18
|
+
def get_target_from_database
|
19
|
+
model_class.find_by_id(@action.target_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def model_class
|
23
|
+
klass_name = (@rule.model_name || @action.target_model).singularize
|
24
|
+
klass_name.camelize.constantize
|
25
|
+
end
|
26
|
+
|
27
|
+
def reanimate_target_from_action
|
28
|
+
if @action.respond_to? :target_data
|
29
|
+
YAML.load(@action.target_data)
|
30
|
+
else
|
31
|
+
Merit.upgrade_target_data_warning
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
19
35
|
end
|
20
36
|
end
|
@@ -15,14 +15,27 @@ module Merit
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def log_merit_action
|
18
|
-
Merit::Action.create(
|
18
|
+
Merit::Action.create(merit_action_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def merit_action_hash
|
22
|
+
{
|
19
23
|
user_id: send(Merit.current_user_method).try(:id),
|
20
24
|
action_method: action_name,
|
21
25
|
action_value: params[:value],
|
22
26
|
had_errors: had_errors?,
|
23
27
|
target_model: controller_path,
|
24
|
-
target_id: target_id
|
25
|
-
)
|
28
|
+
target_id: target_id,
|
29
|
+
}.merge(target_data_hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
def target_data_hash
|
33
|
+
if Merit::Action.new.respond_to? :target_data
|
34
|
+
{ target_data: target_object.to_yaml }
|
35
|
+
else
|
36
|
+
Merit.upgrade_target_data_warning
|
37
|
+
{}
|
38
|
+
end
|
26
39
|
end
|
27
40
|
|
28
41
|
def rules_defined?
|
@@ -35,7 +35,7 @@ module Merit
|
|
35
35
|
|
36
36
|
def _merit_define_badge_related_entries_method
|
37
37
|
meritable_class_name = name.demodulize
|
38
|
-
Badge._define_related_entries_method(meritable_class_name)
|
38
|
+
Merit::Badge._define_related_entries_method(meritable_class_name)
|
39
39
|
end
|
40
40
|
|
41
41
|
def show_attr_accessible?
|
data/lib/merit/rule.rb
CHANGED
@@ -48,11 +48,20 @@ module Merit
|
|
48
48
|
next unless rule.applies?(object)
|
49
49
|
object.update_attribute rule.level_name, level
|
50
50
|
end
|
51
|
-
rescue
|
52
|
-
str = "
|
51
|
+
rescue rank_exception
|
52
|
+
str = "Error while granting rankings. Probably you need to add
|
53
|
+
#{rule.level_name} column to #{scoped_model.class.name}."
|
53
54
|
raise RankAttributeNotDefined, str
|
54
55
|
end
|
55
56
|
|
57
|
+
def rank_exception
|
58
|
+
if defined? ActiveRecord
|
59
|
+
ActiveRecord::StatementInvalid
|
60
|
+
else
|
61
|
+
Exception
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
56
65
|
def scope_to_promote(scope, level_name, level)
|
57
66
|
if Merit.orm == :mongoid
|
58
67
|
scope.where(:"#{level_name}".lt => level)
|
data/lib/merit/sash_finder.rb
CHANGED
@@ -2,6 +2,10 @@ module Merit
|
|
2
2
|
class SashFinder
|
3
3
|
def self.find(rule, action)
|
4
4
|
targets(rule, action).map(&:_sash)
|
5
|
+
rescue NoMethodError
|
6
|
+
Rails.logger.warn "[merit] Couldn't find model to grant reputation to. " \
|
7
|
+
"Refer to https://github.com/tute/merit/issues/171#issuecomment-44185696."
|
8
|
+
[]
|
5
9
|
end
|
6
10
|
|
7
11
|
def self.targets(rule, action)
|
data/lib/merit/target_finder.rb
CHANGED
@@ -35,9 +35,8 @@ module Merit
|
|
35
35
|
def other_target
|
36
36
|
base_target.send rule.to
|
37
37
|
rescue NoMethodError
|
38
|
-
str =
|
39
|
-
|
40
|
-
str << ' (called from Merit::TargetFinder#other_target)'
|
38
|
+
str = "[merit] NoMethodError on `#{base_target.class.name}##{rule.to}`" \
|
39
|
+
' (called from Merit::TargetFinder#other_target)'
|
41
40
|
Rails.logger.warn str
|
42
41
|
end
|
43
42
|
end
|
data/merit.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.homepage = "http://github.com/tute/merit"
|
6
6
|
s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
|
7
7
|
s.license = 'MIT'
|
8
|
-
s.version = '2.
|
8
|
+
s.version = '2.2.0'
|
9
9
|
s.authors = ["Tute Costa"]
|
10
10
|
s.email = 'tutecosta@gmail.com'
|
11
11
|
|
@@ -13,10 +13,9 @@ Gem::Specification.new do |s|
|
|
13
13
|
|
14
14
|
s.add_dependency 'ambry', '~> 0.3.0'
|
15
15
|
s.add_development_dependency 'rails', '>= 3.2.0'
|
16
|
-
s.add_development_dependency 'jquery-rails', '~> 2.1'
|
17
16
|
s.add_development_dependency 'capybara'
|
18
17
|
s.add_development_dependency 'simplecov'
|
19
18
|
s.add_development_dependency 'rubocop'
|
20
19
|
s.add_development_dependency 'minitest-rails'
|
21
|
-
s.add_development_dependency 'mocha', '0
|
20
|
+
s.add_development_dependency 'mocha', '1.1.0'
|
22
21
|
end
|
data/test/dummy/db/schema.rb
CHANGED
@@ -9,49 +9,50 @@
|
|
9
9
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
10
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
11
|
#
|
12
|
-
# It's strongly recommended
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:
|
14
|
+
ActiveRecord::Schema.define(version: 20140906225844) do
|
15
15
|
|
16
|
-
create_table "addresses", :
|
16
|
+
create_table "addresses", force: true do |t|
|
17
17
|
t.integer "user_id"
|
18
18
|
end
|
19
19
|
|
20
|
-
create_table "badges_sashes", :
|
20
|
+
create_table "badges_sashes", force: true do |t|
|
21
21
|
t.integer "badge_id"
|
22
22
|
t.integer "sash_id"
|
23
|
-
t.boolean "notified_user", :
|
23
|
+
t.boolean "notified_user", default: false
|
24
24
|
t.datetime "created_at"
|
25
25
|
end
|
26
26
|
|
27
|
-
add_index "badges_sashes", ["badge_id", "sash_id"], :
|
28
|
-
add_index "badges_sashes", ["badge_id"], :
|
29
|
-
add_index "badges_sashes", ["sash_id"], :
|
27
|
+
add_index "badges_sashes", ["badge_id", "sash_id"], name: "index_badges_sashes_on_badge_id_and_sash_id"
|
28
|
+
add_index "badges_sashes", ["badge_id"], name: "index_badges_sashes_on_badge_id"
|
29
|
+
add_index "badges_sashes", ["sash_id"], name: "index_badges_sashes_on_sash_id"
|
30
30
|
|
31
|
-
create_table "comments", :
|
31
|
+
create_table "comments", force: true do |t|
|
32
32
|
t.string "name"
|
33
33
|
t.text "comment"
|
34
34
|
t.integer "user_id"
|
35
|
-
t.integer "votes", :
|
36
|
-
t.datetime "created_at",
|
37
|
-
t.datetime "updated_at",
|
35
|
+
t.integer "votes", default: 0
|
36
|
+
t.datetime "created_at", null: false
|
37
|
+
t.datetime "updated_at", null: false
|
38
38
|
t.integer "sash_id"
|
39
|
-
t.integer "level", :
|
39
|
+
t.integer "level", default: 0
|
40
40
|
end
|
41
41
|
|
42
|
-
create_table "merit_actions", :
|
42
|
+
create_table "merit_actions", force: true do |t|
|
43
43
|
t.integer "user_id"
|
44
44
|
t.string "action_method"
|
45
45
|
t.integer "action_value"
|
46
|
-
t.boolean "had_errors", :
|
46
|
+
t.boolean "had_errors", default: false
|
47
47
|
t.string "target_model"
|
48
48
|
t.integer "target_id"
|
49
|
-
t.boolean "processed", :
|
50
|
-
t.datetime "created_at",
|
51
|
-
t.datetime "updated_at",
|
49
|
+
t.boolean "processed", default: false
|
50
|
+
t.datetime "created_at", null: false
|
51
|
+
t.datetime "updated_at", null: false
|
52
|
+
t.text "target_data"
|
52
53
|
end
|
53
54
|
|
54
|
-
create_table "merit_activity_logs", :
|
55
|
+
create_table "merit_activity_logs", force: true do |t|
|
55
56
|
t.integer "action_id"
|
56
57
|
t.string "related_change_type"
|
57
58
|
t.integer "related_change_id"
|
@@ -59,29 +60,34 @@ ActiveRecord::Schema.define(:version => 20140211144001) do
|
|
59
60
|
t.datetime "created_at"
|
60
61
|
end
|
61
62
|
|
62
|
-
create_table "merit_score_points", :
|
63
|
+
create_table "merit_score_points", force: true do |t|
|
63
64
|
t.integer "score_id"
|
64
|
-
t.integer "num_points", :
|
65
|
+
t.integer "num_points", default: 0
|
65
66
|
t.string "log"
|
66
67
|
t.datetime "created_at"
|
67
68
|
end
|
68
69
|
|
69
|
-
create_table "merit_scores", :
|
70
|
+
create_table "merit_scores", force: true do |t|
|
70
71
|
t.integer "sash_id"
|
71
|
-
t.string "category", :
|
72
|
+
t.string "category", default: "default"
|
72
73
|
end
|
73
74
|
|
74
|
-
create_table "
|
75
|
-
t.
|
76
|
-
t.
|
75
|
+
create_table "players", force: true do |t|
|
76
|
+
t.integer "sash_id"
|
77
|
+
t.integer "level", default: 0
|
78
|
+
end
|
79
|
+
|
80
|
+
create_table "sashes", force: true do |t|
|
81
|
+
t.datetime "created_at", null: false
|
82
|
+
t.datetime "updated_at", null: false
|
77
83
|
end
|
78
84
|
|
79
|
-
create_table "users", :
|
85
|
+
create_table "users", force: true do |t|
|
80
86
|
t.string "name"
|
81
|
-
t.datetime "created_at",
|
82
|
-
t.datetime "updated_at",
|
87
|
+
t.datetime "created_at", null: false
|
88
|
+
t.datetime "updated_at", null: false
|
83
89
|
t.integer "sash_id"
|
84
|
-
t.integer "level", :
|
90
|
+
t.integer "level", default: 0
|
85
91
|
end
|
86
92
|
|
87
93
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class NavigationTest <
|
4
|
-
def
|
3
|
+
class NavigationTest < ActionDispatch::IntegrationTest
|
4
|
+
def teardown
|
5
5
|
DummyObserver.unstub(:update)
|
6
6
|
end
|
7
7
|
|
8
8
|
test 'user sign up should grant badge to itself' do
|
9
9
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
hash[:description] == 'granted just-registered badge' &&
|
11
|
+
hash[:sash_id] == user('Jack').sash_id &&
|
12
|
+
hash[:granted_at].to_date == Time.now.utc.to_date
|
13
|
+
end
|
14
14
|
|
15
15
|
visit '/users/new'
|
16
16
|
fill_in 'Name', with: 'Jack'
|
@@ -48,18 +48,16 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
48
48
|
|
49
49
|
test 'users#index should grant badge multiple times' do
|
50
50
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
hash[:description] == 'granted visited_admin badge' &&
|
52
|
+
hash[:sash_id] == user.sash_id
|
53
|
+
end
|
54
54
|
DummyObserver.any_instance.expects(:update).times(5).with do |hash|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
8.
|
59
|
-
|
60
|
-
|
61
|
-
hash[:sash_id] == user.sash_id
|
62
|
-
end
|
55
|
+
hash[:description] == 'granted gossip badge' &&
|
56
|
+
hash[:sash_id] == user.sash_id
|
57
|
+
end
|
58
|
+
DummyObserver.any_instance.expects(:update).times(8).with do |hash|
|
59
|
+
hash[:description] == 'granted wildcard_badge badge' &&
|
60
|
+
hash[:sash_id] == user.sash_id
|
63
61
|
end
|
64
62
|
|
65
63
|
# Multiple rule
|
@@ -221,6 +219,15 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
221
219
|
user = User.where(name: 'a').first
|
222
220
|
assert_equal 51, user.points, 'Commenting should grant the integer in
|
223
221
|
comment points if comment is an integer'
|
222
|
+
|
223
|
+
# Destroying a comment should remove points from the comment creator.
|
224
|
+
comment_to_destroy = user.comments.last
|
225
|
+
visit '/comments'
|
226
|
+
assert_difference lambda { user.reload.points }, -5 do
|
227
|
+
within("tr#c_#{comment_to_destroy.id}") do
|
228
|
+
click_link 'Destroy'
|
229
|
+
end
|
230
|
+
end
|
224
231
|
end
|
225
232
|
|
226
233
|
test 'user workflow should grant levels at some times' do
|
@@ -262,21 +269,21 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
262
269
|
|
263
270
|
test 'assigning points to a group of records' do
|
264
271
|
DummyObserver.any_instance.expects(:update).times(2).with do |hash|
|
265
|
-
|
266
|
-
|
267
|
-
|
272
|
+
hash[:description] == 'granted 1 points' &&
|
273
|
+
hash[:sash_id] == user('commenter').sash_id
|
274
|
+
end
|
268
275
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
269
|
-
|
270
|
-
|
271
|
-
|
276
|
+
hash[:description] == 'granted 2 points' &&
|
277
|
+
hash[:sash_id] == user('commenter').comments.first.sash_id
|
278
|
+
end
|
272
279
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
273
|
-
|
274
|
-
|
275
|
-
|
280
|
+
hash[:description] == 'granted 2 points' &&
|
281
|
+
hash[:sash_id] == user('commenter').comments.last.sash_id
|
282
|
+
end
|
276
283
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
277
|
-
|
278
|
-
|
279
|
-
|
284
|
+
hash[:description] == 'granted 5 points' &&
|
285
|
+
hash[:sash_id] == user('commenter').sash_id
|
286
|
+
end
|
280
287
|
|
281
288
|
comment_1 = user('commenter').comments.create(name: 'a', comment: 'a')
|
282
289
|
comment_2 = user('commenter').comments.create(name: 'b', comment: 'b')
|
@@ -296,9 +303,9 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
296
303
|
|
297
304
|
test 'api/comments#show should grant 1 point to user' do
|
298
305
|
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
299
|
-
|
300
|
-
|
301
|
-
|
306
|
+
hash[:description] == 'granted 1 points' &&
|
307
|
+
hash[:sash_id] == user.sash_id
|
308
|
+
end
|
302
309
|
|
303
310
|
assert_equal 0, user.points
|
304
311
|
comment = user.comments.create!(name: 'test-comment', comment: 'comment body')
|
data/test/orm_models/mongoid.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
ENV['RAILS_ENV'] = 'test'
|
3
3
|
RUBYOPT="-w $RUBYOPT"
|
4
4
|
|
5
|
-
require 'coveralls'
|
6
|
-
Coveralls.wear!('rails')
|
7
|
-
|
8
5
|
if ENV["COVERAGE"]
|
6
|
+
require 'coveralls'
|
9
7
|
require 'simplecov'
|
8
|
+
|
9
|
+
Coveralls.wear!('rails')
|
10
|
+
|
10
11
|
SimpleCov.adapters.define 'rubygem' do
|
11
12
|
# Add app to Merit group
|
12
13
|
# https://github.com/colszowka/simplecov/pull/104
|
@@ -17,10 +18,10 @@ if ENV["COVERAGE"]
|
|
17
18
|
SimpleCov.start 'rubygem'
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
21
|
require File.expand_path('../dummy/config/environment.rb', __FILE__)
|
22
22
|
require 'rails/test_help'
|
23
23
|
require 'minitest/rails'
|
24
|
+
require "orm/#{Merit.orm}"
|
24
25
|
|
25
26
|
Rails.backtrace_cleaner.remove_silencers!
|
26
27
|
|
@@ -29,17 +30,11 @@ require 'capybara/rails'
|
|
29
30
|
Capybara.default_driver = :rack_test
|
30
31
|
Capybara.default_selector = :css
|
31
32
|
|
33
|
+
# Load support files
|
34
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
35
|
+
|
32
36
|
Merit.orm = :active_record if Merit.orm.nil?
|
33
37
|
|
34
38
|
def active_record_orm?
|
35
39
|
Merit.orm == :active_record
|
36
40
|
end
|
37
|
-
|
38
|
-
def mongoid_orm?
|
39
|
-
Merit.orm == :mongoid
|
40
|
-
end
|
41
|
-
|
42
|
-
require "orm/#{Merit.orm}"
|
43
|
-
|
44
|
-
# Load support files
|
45
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Merit::Action do
|
4
|
+
it 'saves correctly with a serialised model' do
|
5
|
+
comment = Comment.new(name: 'the comment name')
|
6
|
+
action = Merit::Action.create(target_model: 'comment',
|
7
|
+
target_id: 2,
|
8
|
+
target_data: comment.to_yaml)
|
9
|
+
comment_yaml = Merit::Action.find(action.id).target_data
|
10
|
+
assert_equal comment.name, YAML::load(comment_yaml).name
|
11
|
+
end
|
12
|
+
end
|
@@ -22,17 +22,17 @@ describe Merit::BaseTargetFinder do
|
|
22
22
|
it 'should fall back to the action#target_model' do
|
23
23
|
rule = Merit::Rule.new
|
24
24
|
rule.to = :itself
|
25
|
-
action = Merit::Action.new(target_model: '
|
26
|
-
user =
|
25
|
+
action = Merit::Action.new(target_model: 'players', target_id: 3)
|
26
|
+
user = Player.new(id: 3)
|
27
27
|
|
28
|
-
|
28
|
+
Player.stubs(:find_by_id).with(3).returns(user)
|
29
29
|
|
30
30
|
finder = Merit::BaseTargetFinder.new(rule, action)
|
31
31
|
finder.find.must_be :==, user
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
describe 'when the
|
35
|
+
describe 'when the targeted class is not meritable' do
|
36
36
|
it 'should warn and return' do
|
37
37
|
rule = Merit::Rule.new
|
38
38
|
rule.to = :itself
|
@@ -44,5 +44,40 @@ describe Merit::BaseTargetFinder do
|
|
44
44
|
finder.find.must_be_nil
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
describe 'target was destroyed' do
|
49
|
+
it 'gets the object from the JSON data in the merit_actions table' do
|
50
|
+
comment = Comment.new(name: 'the comment name')
|
51
|
+
|
52
|
+
rule = Merit::Rule.new
|
53
|
+
rule.to = :itself
|
54
|
+
rule.model_name = 'comment'
|
55
|
+
action = Merit::Action.new(target_model: 'comment',
|
56
|
+
target_id: 2,
|
57
|
+
target_data: comment.to_yaml)
|
58
|
+
|
59
|
+
finder = Merit::BaseTargetFinder.new(rule, action)
|
60
|
+
finder.find.name.must_be :==, 'the comment name'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'warns when the target_data column has not been created' do
|
65
|
+
it 'sends a message to the logger' do
|
66
|
+
comment = Comment.new(name: 'the comment name')
|
67
|
+
|
68
|
+
rule = Merit::Rule.new
|
69
|
+
rule.to = :itself
|
70
|
+
rule.model_name = 'comment'
|
71
|
+
action = Merit::Action.new(target_model: 'comment',
|
72
|
+
target_id: 2,
|
73
|
+
target_data: comment.to_yaml)
|
74
|
+
action.stubs(:respond_to?).with(:target_data).returns(false)
|
75
|
+
|
76
|
+
Rails.logger.expects(:warn)
|
77
|
+
|
78
|
+
finder = Merit::BaseTargetFinder.new(rule, action)
|
79
|
+
finder.reanimate_target_from_action
|
80
|
+
end
|
81
|
+
end
|
47
82
|
end
|
48
83
|
end
|
@@ -5,7 +5,7 @@ class MeritUnitTest < ActiveSupport::TestCase
|
|
5
5
|
require "orm_models/#{Merit.orm}"
|
6
6
|
|
7
7
|
test 'extends only meritable models' do
|
8
|
-
assert
|
8
|
+
assert Player.method_defined?(:points), 'has_merit adds methods'
|
9
9
|
assert !Fruit.method_defined?(:points), 'other models aren\'t extended'
|
10
10
|
end
|
11
11
|
|
@@ -14,17 +14,19 @@ class MeritUnitTest < ActiveSupport::TestCase
|
|
14
14
|
assert Merit::Badge.method_defined?(:players), 'Badge#players should be defined'
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
if active_record_orm?
|
18
|
+
test 'unknown ranking raises exception' do
|
19
|
+
class WeirdRankRules
|
20
|
+
include Merit::RankRulesMethods
|
21
|
+
def initialize
|
22
|
+
set_rank level: 1, to: Player, level_name: :clown
|
23
|
+
end
|
24
|
+
end
|
25
|
+
assert_raises Merit::RankAttributeNotDefined do
|
26
|
+
WeirdRankRules.new.check_rank_rules
|
22
27
|
end
|
23
28
|
end
|
24
|
-
|
25
|
-
WeirdRankRules.new.check_rank_rules
|
26
|
-
end
|
27
|
-
end if active_record_orm?
|
29
|
+
end
|
28
30
|
|
29
31
|
test 'Badge#custom_fields_hash saves correctly' do
|
30
32
|
Merit::Badge.create(id: 99,
|
@@ -3,11 +3,11 @@ require 'test_helper'
|
|
3
3
|
describe Merit::SashFinder do
|
4
4
|
it 'should return an array of sashes of the target objects' do
|
5
5
|
sash_1 = Merit::Sash.new
|
6
|
-
user_1 =
|
6
|
+
user_1 = Player.new
|
7
7
|
user_1.stubs(:_sash).returns(sash_1)
|
8
8
|
|
9
9
|
sash_2 = Merit::Sash.new
|
10
|
-
user_2 =
|
10
|
+
user_2 = Player.new
|
11
11
|
user_2.stubs(:_sash).returns(sash_2)
|
12
12
|
|
13
13
|
# TODO: With stub we are not exercising compact
|
data/test/unit/score_test.rb
CHANGED
@@ -2,11 +2,11 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe Merit::Score do
|
4
4
|
it 'Point#sash_id delegates to Score' do
|
5
|
-
score =
|
6
|
-
score.
|
5
|
+
score = Merit::Score.new
|
6
|
+
score.sash_id = 33
|
7
7
|
|
8
8
|
point = Merit::Score::Point.new
|
9
|
-
point.
|
9
|
+
point.score = score
|
10
10
|
|
11
11
|
point.sash_id.must_be :==, score.sash_id
|
12
12
|
end
|
@@ -23,16 +23,20 @@ describe Merit::TargetFinder do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe 'rule#to is :action_user' do
|
26
|
+
before do
|
27
|
+
Merit.setup { |config| config.user_model_name = 'Player' }
|
28
|
+
end
|
29
|
+
after do
|
30
|
+
Merit.setup { |config| config.user_model_name = 'User' }
|
31
|
+
end
|
32
|
+
|
26
33
|
it 'should return an array including user that executed the action' do
|
27
|
-
Merit.setup do |config|
|
28
|
-
config.user_model_name = 'User'
|
29
|
-
end
|
30
34
|
rule = Merit::Rule.new
|
31
35
|
rule.to = :action_user
|
32
36
|
action = Merit::Action.new(user_id: 22)
|
33
|
-
user =
|
37
|
+
user = Player.new
|
34
38
|
|
35
|
-
|
39
|
+
Player.stubs(:find_by_id).with(22).returns(user)
|
36
40
|
|
37
41
|
finder = Merit::TargetFinder.new(rule, action)
|
38
42
|
collection = finder.find
|
@@ -42,14 +46,11 @@ describe Merit::TargetFinder do
|
|
42
46
|
|
43
47
|
describe 'when user does not exist' do
|
44
48
|
it 'should return warn and return an empty array' do
|
45
|
-
Merit.setup do |config|
|
46
|
-
config.user_model_name = 'User'
|
47
|
-
end
|
48
49
|
rule = Merit::Rule.new
|
49
50
|
rule.to = :action_user
|
50
51
|
action = Merit::Action.new(user_id: 22)
|
51
52
|
|
52
|
-
Rails.logger.expects(:warn).with('[merit] no
|
53
|
+
Rails.logger.expects(:warn).with('[merit] no Player found with id 22')
|
53
54
|
finder = Merit::TargetFinder.new(rule, action)
|
54
55
|
finder.find.must_be_empty
|
55
56
|
end
|
@@ -63,7 +64,7 @@ describe Merit::TargetFinder do
|
|
63
64
|
rule.model_name = 'comments'
|
64
65
|
action = Merit::Action.new(target_id: 40)
|
65
66
|
|
66
|
-
user =
|
67
|
+
user = Player.new
|
67
68
|
comment = Comment.new
|
68
69
|
comment.stubs(:user).returns(user)
|
69
70
|
Comment.stubs(:find_by_id).with(40).returns(comment)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: merit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tute Costa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ambry
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.2.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: jquery-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2.1'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '2.1'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: capybara
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +100,14 @@ dependencies:
|
|
114
100
|
requirements:
|
115
101
|
- - '='
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
103
|
+
version: 1.1.0
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
108
|
- - '='
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
110
|
+
version: 1.1.0
|
125
111
|
description: Manage badges, points and rankings (reputation) of resources in a Rails
|
126
112
|
application.
|
127
113
|
email: tutecosta@gmail.com
|
@@ -142,6 +128,7 @@ files:
|
|
142
128
|
- lib/generators/active_record/merit_generator.rb
|
143
129
|
- lib/generators/active_record/remove_generator.rb
|
144
130
|
- lib/generators/active_record/templates/add_fields_to_model.rb
|
131
|
+
- lib/generators/active_record/templates/add_target_data_to_merit_actions.rb
|
145
132
|
- lib/generators/active_record/templates/create_badges_sashes.rb
|
146
133
|
- lib/generators/active_record/templates/create_merit_actions.rb
|
147
134
|
- lib/generators/active_record/templates/create_merit_activity_logs.rb
|
@@ -149,6 +136,7 @@ files:
|
|
149
136
|
- lib/generators/active_record/templates/create_scores_and_points.rb
|
150
137
|
- lib/generators/active_record/templates/remove_fields_from_model.rb
|
151
138
|
- lib/generators/active_record/templates/remove_merit_tables.rb
|
139
|
+
- lib/generators/active_record/upgrade_generator.rb
|
152
140
|
- lib/generators/merit/install_generator.rb
|
153
141
|
- lib/generators/merit/merit_generator.rb
|
154
142
|
- lib/generators/merit/remove_generator.rb
|
@@ -156,6 +144,7 @@ files:
|
|
156
144
|
- lib/generators/merit/templates/merit_badge_rules.rb
|
157
145
|
- lib/generators/merit/templates/merit_point_rules.rb
|
158
146
|
- lib/generators/merit/templates/merit_rank_rules.rb
|
147
|
+
- lib/generators/merit/upgrade_generator.rb
|
159
148
|
- lib/merit.rb
|
160
149
|
- lib/merit/base_target_finder.rb
|
161
150
|
- lib/merit/controller_extensions.rb
|
@@ -237,6 +226,8 @@ files:
|
|
237
226
|
- test/dummy/db/migrate/20130329224409_create_badges_sashes.rb
|
238
227
|
- test/dummy/db/migrate/20130329224410_create_scores_and_points.rb
|
239
228
|
- test/dummy/db/migrate/20140211144001_create_addresses.rb
|
229
|
+
- test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb
|
230
|
+
- test/dummy/db/migrate/20140906225844_create_players.rb
|
240
231
|
- test/dummy/db/schema.rb
|
241
232
|
- test/dummy/db/seeds.rb
|
242
233
|
- test/dummy/public/404.html
|
@@ -260,6 +251,7 @@ files:
|
|
260
251
|
- test/orm_models/mongoid.rb
|
261
252
|
- test/support/integration_case.rb
|
262
253
|
- test/test_helper.rb
|
254
|
+
- test/unit/action_test.rb
|
263
255
|
- test/unit/base_target_finder_test.rb
|
264
256
|
- test/unit/merit_unit_test.rb
|
265
257
|
- test/unit/rule_unit_test.rb
|
@@ -288,9 +280,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
280
|
version: '0'
|
289
281
|
requirements: []
|
290
282
|
rubyforge_project:
|
291
|
-
rubygems_version: 2.
|
283
|
+
rubygems_version: 2.4.1
|
292
284
|
signing_key:
|
293
285
|
specification_version: 4
|
294
286
|
summary: General reputation Rails engine.
|
295
287
|
test_files: []
|
296
|
-
has_rdoc:
|