merit 2.1.1 → 2.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fffa4a71100476ce7342d95ec21d9841dcdba506
4
- data.tar.gz: 366af39f2fe07ec2eb644a5e7e2710a6fb95abcf
3
+ metadata.gz: d1c7ff1372bb3ca30c5c71a235ebfbaa285be9a6
4
+ data.tar.gz: 93f9531439ccb6efd93c8a3092e46016d328283e
5
5
  SHA512:
6
- metadata.gz: 766d06b7c33496656d497f3b06a522e9e29f3d4322e500168cfbfcb0deae4ec0502e1ac754108e6545e61c2e16d7f4538cae24d29e65b8bc1fd4789ffae6e646
7
- data.tar.gz: 09a1a3dbdc6d61b0acdebb4458fbc043eebcb487f95455bdc913120b97420bee7a4301ae8d34632045b9eb754377ee514fb720cd8a1022b9e6c829bcf7c1fb1d
6
+ metadata.gz: 66770fcab721991a7c18ecc53d6e0bbb7190775404db8ceddd39605d32e300c1d6b1c61fa16d07a9075718777f3d093dbd72a4b1873901c367a1111fdab8713c
7
+ data.tar.gz: 7f4b0660da679fb7551208aa268121c9f41bd91967fed1963a2972081f8dee27941bcf6b20d97c6c37776e81f84a7ac30af33d9a5de18f3fcaaaac7c85f3cdf3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.2
4
+
5
+ - Improves observer API.
6
+
3
7
  ## 2.1.1
4
8
 
5
9
  - [#158] Migrations bug fix.
data/Gemfile CHANGED
@@ -33,7 +33,7 @@ end
33
33
  platforms :rbx do
34
34
  gem 'rubysl', '~> 2.0'
35
35
  gem 'racc'
36
- gem 'rubysl-test-unit'
36
+ gem 'minitest'
37
37
  gem 'rubinius-developer_tools'
38
38
  end
39
39
 
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 (reqired)
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: "Yearling",
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
- To do so, add your observer (to `app/models` or `app/observers`, for example):
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 grab it like:
281
- if changed_data[:merit_object]
282
- sash_id = changed_data[:merit_object].sash_id
283
- user = User.where(sash_id: sash_id).first
284
- end
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
- merit_action_id: @action.id
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
- merit_action_id: @action.id
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
- badge_sash = sash.rm_badge badge.id
53
+ sash.rm_badge badge.id
54
54
  notify_observers(
55
55
  description: "removed #{badge.name} badge",
56
- merit_object: badge_sash,
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
- super
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
- .includes(:score)
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.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.13.3'
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 1
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
- user = User.where(name: 'Jack').first
18
- assert_equal [Merit::Badge.by_name('just-registered').first], user.badges
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 14
47
- user = User.create(name: 'test-user')
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 = User.create(name: 'test-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
- user_badges = User.where(name: 'test-user').first.badges
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 5
253
- commenter = User.create(name: 'commenter')
254
- comment_1 = commenter.comments.create(name: 'comment_1', comment: 'a')
255
- comment_2 = commenter.comments.create(name: 'comment_2', comment: 'b')
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 1
272
- user = User.create(name: 'test-user')
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.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-04-12 00:00:00.000000000 Z
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.13.3
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.13.3
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: