merit 2.1.1 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/README.md +18 -31
- data/lib/merit/judge.rb +10 -7
- data/lib/merit/models/active_record/merit/sash.rb +1 -1
- data/merit.gemspec +2 -2
- data/test/integration/navigation_test.rb +52 -18
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1c7ff1372bb3ca30c5c71a235ebfbaa285be9a6
|
4
|
+
data.tar.gz: 93f9531439ccb6efd93c8a3092e46016d328283e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66770fcab721991a7c18ecc53d6e0bbb7190775404db8ceddd39605d32e300c1d6b1c61fa16d07a9075718777f3d093dbd72a4b1873901c367a1111fdab8713c
|
7
|
+
data.tar.gz: 7f4b0660da679fb7551208aa268121c9f41bd91967fed1963a2972081f8dee27941bcf6b20d97c6c37776e81f84a7ac30af33d9a5de18f3fcaaaac7c85f3cdf3
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -35,8 +35,8 @@ Status](https://coveralls.io/repos/tute/merit/badge.png?branch=master)](https://
|
|
35
35
|
# Installation
|
36
36
|
|
37
37
|
1. Add `gem 'merit'` to your `Gemfile`
|
38
|
-
2. Run `rails g merit:install
|
39
|
-
3. Run `rails g merit MODEL_NAME` (e.g. `user`)
|
38
|
+
2. Run `rails g merit:install`. This creates several migrations.
|
39
|
+
3. Run `rails g merit MODEL_NAME` (e.g. `user`). This creates a migration and adds `has_merit` to MODEL_NAME.
|
40
40
|
4. Run `rake db:migrate`
|
41
41
|
5. Define badges in `config/initializers/merit.rb`. You can also define ORM:
|
42
42
|
`:active_record` (default) or `:mongoid`.
|
@@ -50,7 +50,7 @@ Status](https://coveralls.io/repos/tute/merit/badge.png?branch=master)](https://
|
|
50
50
|
Create badges in `config/initializers/merit.rb`
|
51
51
|
|
52
52
|
`Merit::Badge.create!` takes a hash describing the badge:
|
53
|
-
* `:id` integer (
|
53
|
+
* `:id` integer (required)
|
54
54
|
* `:name` this is how you reference the badge (required)
|
55
55
|
* `:level` (optional)
|
56
56
|
* `:description` (optional)
|
@@ -61,7 +61,7 @@ Create badges in `config/initializers/merit.rb`
|
|
61
61
|
```ruby
|
62
62
|
Merit::Badge.create!(
|
63
63
|
id: 1,
|
64
|
-
name: "
|
64
|
+
name: "year-member",
|
65
65
|
description: "Active member for a year",
|
66
66
|
custom_fields: { difficulty: :silver }
|
67
67
|
)
|
@@ -265,37 +265,27 @@ end
|
|
265
265
|
You can get observers notified any time merit changes reputation in your
|
266
266
|
application.
|
267
267
|
|
268
|
-
|
268
|
+
It needs to implement the `update` method, which receives as parameter the
|
269
|
+
following hash:
|
270
|
+
|
271
|
+
* `description`, describes what happened. For example: "granted 5 points",
|
272
|
+
"granted just-registered badge", "removed autobiographer badge".
|
273
|
+
* `sash_id`, who saw it's reputation changed.
|
274
|
+
* `granted_at`, date and time when the reputation change took effect.
|
275
|
+
|
276
|
+
Example code (add your observer to `app/models` or `app/observers`):
|
269
277
|
|
270
278
|
```ruby
|
271
279
|
# reputation_change_observer.rb
|
272
280
|
class ReputationChangeObserver
|
273
281
|
def update(changed_data)
|
274
|
-
# description will be something like:
|
275
|
-
# granted 5 points
|
276
|
-
# granted just-registered badge
|
277
|
-
# removed autobiographer badge
|
278
282
|
description = changed_data[:description]
|
279
283
|
|
280
|
-
# If user is your meritable model, you can
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
# To know where and when it happened:
|
287
|
-
merit_action = Merit::Action.find changed_data[:merit_action_id]
|
288
|
-
controller = merit_action.target_model
|
289
|
-
action = merit_action.action_method
|
290
|
-
when = merit_action.created_at
|
291
|
-
|
292
|
-
# From here on, you can create a new Notification assuming that's an
|
293
|
-
# ActiveRecord Model in your app, send an email, etc. For example:
|
294
|
-
Notification.create(
|
295
|
-
user: user,
|
296
|
-
what: description,
|
297
|
-
where: "#{controller}##{action}",
|
298
|
-
when: when)
|
284
|
+
# If user is your meritable model, you can query for it doing:
|
285
|
+
user = User.where(sash_id: changed_data[:sash_id]).first
|
286
|
+
|
287
|
+
# When did it happened:
|
288
|
+
datetime = changed_data[:granted_at]
|
299
289
|
end
|
300
290
|
end
|
301
291
|
```
|
@@ -304,9 +294,6 @@ end
|
|
304
294
|
config.add_observer 'ReputationChangeObserver'
|
305
295
|
```
|
306
296
|
|
307
|
-
TODO: Improve API sending in `changed_data` concrete data instead of merit
|
308
|
-
objects.
|
309
|
-
|
310
297
|
|
311
298
|
# Uninstalling Merit
|
312
299
|
|
data/lib/merit/judge.rb
CHANGED
@@ -29,7 +29,7 @@ module Merit
|
|
29
29
|
notify_observers(
|
30
30
|
description: "granted #{points} points",
|
31
31
|
merit_object: point,
|
32
|
-
|
32
|
+
sash_id: point.sash_id
|
33
33
|
)
|
34
34
|
end
|
35
35
|
end
|
@@ -43,18 +43,17 @@ module Merit
|
|
43
43
|
notify_observers(
|
44
44
|
description: "granted #{badge.name} badge",
|
45
45
|
merit_object: badge_sash,
|
46
|
-
|
46
|
+
sash_id: badge_sash.sash_id
|
47
47
|
)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
def remove_badges
|
52
52
|
sashes.each do |sash|
|
53
|
-
|
53
|
+
sash.rm_badge badge.id
|
54
54
|
notify_observers(
|
55
55
|
description: "removed #{badge.name} badge",
|
56
|
-
|
57
|
-
merit_action_id: @action.id
|
56
|
+
sash_id: sash.id
|
58
57
|
)
|
59
58
|
end
|
60
59
|
end
|
@@ -91,9 +90,13 @@ module Merit
|
|
91
90
|
@rule.badge
|
92
91
|
end
|
93
92
|
|
94
|
-
def notify_observers(changed_data)
|
93
|
+
def notify_observers(changed_data = {})
|
95
94
|
changed
|
96
|
-
|
95
|
+
hash = {
|
96
|
+
granted_at: @action.created_at,
|
97
|
+
merit_action_id: @action.id
|
98
|
+
}.merge(changed_data)
|
99
|
+
super(hash)
|
97
100
|
end
|
98
101
|
end
|
99
102
|
end
|
@@ -18,7 +18,7 @@ module Merit
|
|
18
18
|
# @return [ActiveRecord::Relation] containing the points
|
19
19
|
def score_points(options = {})
|
20
20
|
scope = Merit::Score::Point
|
21
|
-
.
|
21
|
+
.joins(:score)
|
22
22
|
.where('merit_scores.sash_id = ?', id)
|
23
23
|
if (category = options[:category])
|
24
24
|
scope = scope.where('merit_scores.category = ?', category)
|
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.1.
|
8
|
+
s.version = '2.1.2'
|
9
9
|
s.authors = ["Tute Costa"]
|
10
10
|
s.email = 'tutecosta@gmail.com'
|
11
11
|
|
@@ -18,5 +18,5 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_development_dependency 'simplecov'
|
19
19
|
s.add_development_dependency 'rubocop'
|
20
20
|
s.add_development_dependency 'minitest-rails'
|
21
|
-
s.add_development_dependency 'mocha', '0.
|
21
|
+
s.add_development_dependency 'mocha', '0.14'
|
22
22
|
end
|
@@ -1,21 +1,25 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class NavigationTest < ActiveSupport::IntegrationCase
|
4
|
-
|
5
4
|
def tear_down
|
6
5
|
DummyObserver.unstub(:update)
|
7
6
|
end
|
8
7
|
|
9
8
|
test 'user sign up should grant badge to itself' do
|
10
|
-
DummyObserver.any_instance.expects(:update).times
|
9
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
10
|
+
hash[:description] == 'granted just-registered badge' &&
|
11
|
+
hash[:sash_id] == user('Jack').sash_id &&
|
12
|
+
hash[:granted_at].to_date == Date.today
|
13
|
+
end
|
14
|
+
|
11
15
|
visit '/users/new'
|
12
16
|
fill_in 'Name', with: 'Jack'
|
13
17
|
assert_difference('Merit::ActivityLog.count') do
|
14
18
|
click_button('Create User')
|
15
19
|
end
|
16
20
|
|
17
|
-
|
18
|
-
assert_equal [
|
21
|
+
just_registered = Merit::Badge.by_name('just-registered').first
|
22
|
+
assert_equal [just_registered], user('Jack').badges
|
19
23
|
end
|
20
24
|
|
21
25
|
test 'User#add_badge should add one badge, #rm_badge should delete one' do
|
@@ -43,8 +47,20 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
43
47
|
end
|
44
48
|
|
45
49
|
test 'users#index should grant badge multiple times' do
|
46
|
-
DummyObserver.any_instance.expects(:update).times
|
47
|
-
|
50
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
51
|
+
hash[:description] == 'granted visited_admin badge' &&
|
52
|
+
hash[:sash_id] == user.sash_id
|
53
|
+
end
|
54
|
+
DummyObserver.any_instance.expects(:update).times(5).with do |hash|
|
55
|
+
hash[:description] == 'granted gossip badge' &&
|
56
|
+
hash[:sash_id] == user.sash_id
|
57
|
+
end
|
58
|
+
8.times do |merit_action_id|
|
59
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
60
|
+
hash[:description] == 'granted wildcard_badge badge' &&
|
61
|
+
hash[:sash_id] == user.sash_id
|
62
|
+
end
|
63
|
+
end
|
48
64
|
|
49
65
|
# Multiple rule
|
50
66
|
assert_difference 'badges_by_name(user, "gossip").count', 3 do
|
@@ -70,7 +86,7 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
70
86
|
test 'user workflow should grant some badges at some times' do
|
71
87
|
DummyObserver.any_instance.expects(:update).at_least_once
|
72
88
|
# Commented 9 times, no badges yet
|
73
|
-
user
|
89
|
+
user # creates user
|
74
90
|
# Create needed friend user object
|
75
91
|
friend = User.create(name: 'friend')
|
76
92
|
|
@@ -121,14 +137,10 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
121
137
|
end
|
122
138
|
|
123
139
|
relevant_badge = Merit::Badge.by_name('relevant-commenter').first
|
124
|
-
|
125
|
-
assert user_badges.include?(relevant_badge), "User badges: #{user.badges.collect(&:name).inspect} should contain relevant-commenter badge."
|
140
|
+
assert user.badges.include?(relevant_badge), "User badges: #{user.badges.collect(&:name).inspect} should contain relevant-commenter badge."
|
126
141
|
|
127
142
|
# Edit user's name by long name
|
128
143
|
# tests ruby code in grant_on is being executed, and gives badge
|
129
|
-
user = User.where(name: 'test-user').first
|
130
|
-
user_badges = user.badges
|
131
|
-
|
132
144
|
visit "/users/#{user.id}/edit"
|
133
145
|
fill_in 'Name', with: 'long_name!'
|
134
146
|
click_button('Update User')
|
@@ -249,10 +261,25 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
249
261
|
end
|
250
262
|
|
251
263
|
test 'assigning points to a group of records' do
|
252
|
-
DummyObserver.any_instance.expects(:update).times
|
253
|
-
|
254
|
-
|
255
|
-
|
264
|
+
DummyObserver.any_instance.expects(:update).times(2).with do |hash|
|
265
|
+
hash[:description] == 'granted 1 points' &&
|
266
|
+
hash[:sash_id] == user('commenter').sash_id
|
267
|
+
end
|
268
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
269
|
+
hash[:description] == 'granted 2 points' &&
|
270
|
+
hash[:sash_id] == user('commenter').comments.first.sash_id
|
271
|
+
end
|
272
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
273
|
+
hash[:description] == 'granted 2 points' &&
|
274
|
+
hash[:sash_id] == user('commenter').comments.last.sash_id
|
275
|
+
end
|
276
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
277
|
+
hash[:description] == 'granted 5 points' &&
|
278
|
+
hash[:sash_id] == user('commenter').sash_id
|
279
|
+
end
|
280
|
+
|
281
|
+
comment_1 = user('commenter').comments.create(name: 'a', comment: 'a')
|
282
|
+
comment_2 = user('commenter').comments.create(name: 'b', comment: 'b')
|
256
283
|
|
257
284
|
visit comments_path
|
258
285
|
# Thanks for voting point, to voted user and it's comments
|
@@ -268,8 +295,11 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
268
295
|
end
|
269
296
|
|
270
297
|
test 'api/comments#show should grant 1 point to user' do
|
271
|
-
DummyObserver.any_instance.expects(:update).times
|
272
|
-
|
298
|
+
DummyObserver.any_instance.expects(:update).times(1).with do |hash|
|
299
|
+
hash[:description] == 'granted 1 points' &&
|
300
|
+
hash[:sash_id] == user.sash_id
|
301
|
+
end
|
302
|
+
|
273
303
|
assert_equal 0, user.points
|
274
304
|
comment = user.comments.create!(name: 'test-comment', comment: 'comment body')
|
275
305
|
|
@@ -277,6 +307,10 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
277
307
|
assert_equal 1, user.points
|
278
308
|
end
|
279
309
|
|
310
|
+
def user(name = 'test-user')
|
311
|
+
User.where(name: name).first || User.create(name: name)
|
312
|
+
end
|
313
|
+
|
280
314
|
def badges_by_name(user, name)
|
281
315
|
user.reload.badges.select{|b| b.name == name }
|
282
316
|
end
|
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.1.
|
4
|
+
version: 2.1.2
|
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-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ambry
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
117
|
+
version: '0.14'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
124
|
+
version: '0.14'
|
125
125
|
description: Manage badges, points and rankings (reputation) of resources in a Rails
|
126
126
|
application.
|
127
127
|
email: tutecosta@gmail.com
|
@@ -293,3 +293,4 @@ signing_key:
|
|
293
293
|
specification_version: 4
|
294
294
|
summary: General reputation Rails engine.
|
295
295
|
test_files: []
|
296
|
+
has_rdoc:
|