merit 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|