public_activity 1.4.0 → 1.4.1

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: 86fca5f56a3715cdc7aa50a5429478d3da652e2a
4
- data.tar.gz: 6873ddaac083d14044c4e9eb7f4137b257d7bfec
3
+ metadata.gz: dc33d068df00d2d1ab1df8449bfd3c403b94ff02
4
+ data.tar.gz: ac6cd95c756f4509ec2b6543d9e39c11dd08d8b4
5
5
  SHA512:
6
- metadata.gz: 8b432bcada38def3820e0a72b49d233e14bd1c87ceb6fdca7263e5b442a1c4d888cf88cc106a3df66febf6b5a6785b1a92a15b148c5410a72b8608596732a540
7
- data.tar.gz: 8ace1656f39368a932ff0e5883d710a59a546ce269f25608bfaa9e08e6fde99881681e8eade10461f0d8142e3a72751545016a0a9eda3aae5f3c319332cb731c
6
+ metadata.gz: 0cde8051ae540c65efe52fe188161b2e811c261bfe561d152f1e3459878d8944e5ec8245864aaf21c916df2047a3cd3dd8094a5c5d4bb4c01aaacff90acaecfd
7
+ data.tar.gz: 7183678eb58a29ae1009a4d96c01c362998ac3e86f9e2b821e94660ec6d406a44648ac14847f23574f0affb34e7300f70a59b2fc049a76e48dea22c005e5f7af
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
- # PublicActivity [![Build Status](https://secure.travis-ci.org/pokonski/public_activity.png)](http://travis-ci.org/pokonski/public_activity) [![Dependency Status](https://gemnasium.com/pokonski/public_activity.png)](https://gemnasium.com/pokonski/public_activity)
1
+ # PublicActivity [![Build Status](https://secure.travis-ci.org/pokonski/public_activity.png)](http://travis-ci.org/pokonski/public_activity) [![Dependency Status](https://gemnasium.com/pokonski/public_activity.png)](https://gemnasium.com/pokonski/public_activity) [![Code Climate](https://codeclimate.com/github/pokonski/public_activity.png)](https://codeclimate.com/github/pokonski/public_activity) [![Gem Version](https://badge.fury.io/rb/public_activity.png)](http://badge.fury.io/rb/public_activity)
2
2
 
3
- _public_activity_ provides easy activity tracking for your **ActiveRecord**, **Mongoid 3** and **MongoMapper** models
3
+ `public_activity` provides easy activity tracking for your **ActiveRecord**, **Mongoid 3** and **MongoMapper** models
4
4
  in Rails 3. Simply put: it records what has been changed or created and gives you the ability to present those
5
5
  recorded activities to users - in a similar way to how GitHub does it.
6
6
 
7
+ ## Rails 4
8
+
9
+ **As of 1.4.0 version, public_activity now supports both Rails 3.X and 4.0.**
10
+
11
+
7
12
  ## Table of contents
8
13
 
9
14
  1. [Example](#example)
@@ -18,9 +23,10 @@ recorded activities to users - in a similar way to how GitHub does it.
18
23
  5. [Displaying activities](#displaying-activities)
19
24
  1. [Activity views](#activity-views)
20
25
  2. [i18n](#i18n)
21
- 3. [Documentation](#documentation)
22
- 4. **[Help](#help)**
23
- 5. [Upgrading](https://github.com/pokonski/public_activity/wiki/Upgrading-from-pre-0.4.0-versions)
26
+ 3. [Testing](#testing)
27
+ 4. [Documentation](#documentation)
28
+ 5. **[Help](#help)**
29
+ 6. [Upgrading](https://github.com/pokonski/public_activity/wiki/Upgrading-from-pre-0.4.0-versions)
24
30
 
25
31
  ## Example
26
32
 
@@ -202,6 +208,32 @@ activity:
202
208
 
203
209
  This structure is valid for activities with keys `"activity.article.create"` or `"article.create"`. As mentioned before, `"activity."` part of the key is optional.
204
210
 
211
+ ## Testing
212
+
213
+ For RSpec you can first disable `public_activity` and add the `test_helper` in
214
+ the `spec_helper.rb` with
215
+
216
+ ```ruby
217
+ #spec_helper.rb
218
+ require 'public_activity/testing'
219
+
220
+ PublicActivity.enabled = false
221
+ ```
222
+
223
+ In your specs you can then blockwise decide wether to turn `public_activity` on
224
+ or off.
225
+
226
+ ```ruby
227
+ # file_spec.rb
228
+ PublicActivity.with_tracking do
229
+ # your test code goes here
230
+ end
231
+
232
+ PublicActivity.without_tracking do
233
+ # your test code goes here
234
+ end
235
+ ```
236
+
205
237
  ## Documentation
206
238
 
207
239
  For more documentation go [here](http://rubydoc.info/gems/public_activity/index)
@@ -3,7 +3,7 @@ require 'rails/generators/named_base'
3
3
  module PublicActivity
4
4
  # A generator module with Activity table schema.
5
5
  module Generators
6
- # A base module
6
+ # A base module
7
7
  module Base
8
8
  # Get path for migration template
9
9
  def source_root
@@ -65,4 +65,4 @@ module PublicActivity
65
65
  end
66
66
 
67
67
  require 'public_activity/utility/store_controller'
68
- require 'public_activity/utility/view_helpers'
68
+ require 'public_activity/utility/view_helpers'
@@ -6,10 +6,12 @@ module PublicActivity
6
6
  included do
7
7
  after_create :activity_on_create
8
8
  end
9
+
9
10
  private
10
- # Creates activity upon creation of the tracked model
11
- def activity_on_create
12
- create_activity(:create)
13
- end
11
+
12
+ # Creates activity upon creation of the tracked model
13
+ def activity_on_create
14
+ create_activity(:create)
15
+ end
14
16
  end
15
17
  end
@@ -6,10 +6,12 @@ module PublicActivity
6
6
  included do
7
7
  before_destroy :activity_on_destroy
8
8
  end
9
+
9
10
  private
10
- # Records an activity upon destruction of the tracked model
11
- def activity_on_destroy
12
- create_activity(:destroy)
13
- end
11
+
12
+ # Records an activity upon destruction of the tracked model
13
+ def activity_on_destroy
14
+ create_activity(:destroy)
15
+ end
14
16
  end
15
17
  end
@@ -6,10 +6,12 @@ module PublicActivity
6
6
  included do
7
7
  after_update :activity_on_update
8
8
  end
9
+
9
10
  private
10
- # Creates activity upon modification of the tracked model
11
- def activity_on_update
12
- create_activity(:update)
13
- end
11
+
12
+ # Creates activity upon modification of the tracked model
13
+ def activity_on_update
14
+ create_activity(:update)
15
+ end
14
16
  end
15
17
  end
@@ -269,60 +269,65 @@ module PublicActivity
269
269
  # @overload prepare_settings(options = {})
270
270
  # @see #create_activity
271
271
  def prepare_settings(*args)
272
- # key
273
- all_options = args.extract_options!
274
- options = {
275
- key: all_options.delete(:key),
276
- action: all_options.delete(:action),
277
- parameters: all_options.delete(:parameters) || all_options.delete(:params)
278
- }
279
- action = (args.first || options[:action]).try(:to_s)
272
+ raw_options = args.extract_options!
273
+ action = [args.first, raw_options.delete(:action)].compact.first
274
+ key = prepare_key(action, raw_options)
280
275
 
281
- options[:key] = extract_key(action, options)
276
+ raise NoKeyProvided, "No key provided for #{self.class.name}" unless key
282
277
 
283
- raise NoKeyProvided, "No key provided for #{self.class.name}" unless options[:key]
284
-
285
- options.delete(:action)
286
-
287
- # user responsible for the activity
288
- options[:owner] = PublicActivity.resolve_value(self,
289
- (all_options.has_key?(:owner) ? all_options[:owner] : (
290
- self.activity_owner || self.class.activity_owner_global
291
- )
292
- )
278
+ prepare_custom_fields(raw_options.except(:params)).merge(
279
+ {
280
+ key: key,
281
+ owner: prepare_relation(:owner, raw_options),
282
+ recipient: prepare_relation(:recipient, raw_options),
283
+ parameters: prepare_parameters(raw_options),
284
+ }
293
285
  )
286
+ end
294
287
 
295
- # recipient of the activity
296
- options[:recipient] = PublicActivity.resolve_value(self,
297
- (all_options.has_key?(:recipient) ? all_options[:recipient] : (
298
- self.activity_recipient || self.class.activity_recipient_global
299
- )
300
- )
301
- )
288
+ # Prepares and resolves custom fields
289
+ # users can pass to `tracked` method
290
+ # @private
291
+ def prepare_custom_fields(options)
292
+ customs = self.class.activity_custom_fields_global.clone
293
+ customs.merge!(self.activity_custom_fields) if self.activity_custom_fields
294
+ customs.merge!(options)
295
+ customs.each do |k, v|
296
+ customs[k] = PublicActivity.resolve_value(self, v)
297
+ end
298
+ end
302
299
 
303
- #customizable parameters
300
+ # Prepares i18n parameters that will
301
+ # be serialized into the Activity#parameters column
302
+ # @private
303
+ def prepare_parameters(options)
304
304
  params = {}
305
305
  params.merge!(self.class.activity_params_global)
306
306
  params.merge!(self.activity_params) if self.activity_params
307
- params.merge!(options[:params] || options[:parameters] || {})
307
+ params.merge!([options.delete(:parameters), options.delete(:params), {}].compact.first)
308
308
  params.each { |k, v| params[k] = PublicActivity.resolve_value(self, v) }
309
- options[:parameters] = params
310
- options.delete(:params)
309
+ end
311
310
 
312
- customs = self.class.activity_custom_fields_global.clone
313
- customs.merge!(self.activity_custom_fields) if self.activity_custom_fields
314
- customs.merge!(all_options)
315
- customs.each do |k, v|
316
- customs[k] = PublicActivity.resolve_value(self, v)
317
- end.merge options
311
+ # Prepares relation to be saved
312
+ # to Activity. Can be :recipient or :owner
313
+ # @private
314
+ def prepare_relation(name, options)
315
+ PublicActivity.resolve_value(self,
316
+ (options.has_key?(name) ? options[name] : (
317
+ self.send("activity_#{name}") || self.class.send("activity_#{name}_global")
318
+ )
319
+ )
320
+ )
318
321
  end
319
322
 
320
323
  # Helper method to serialize class name into relevant key
321
324
  # @return [String] the resulted key
322
325
  # @param [Symbol] or [String] the name of the operation to be done on class
323
326
  # @param [Hash] options to be used on key generation, defaults to {}
324
- def extract_key(action, options = {})
325
- (options[:key] || self.activity_key ||
327
+ def prepare_key(action, options = {})
328
+ (
329
+ options[:key] ||
330
+ self.activity_key ||
326
331
  ((self.class.name.underscore.gsub('/', '_') + "." + action.to_s) if action)
327
332
  ).try(:to_s)
328
333
  end
@@ -4,13 +4,14 @@ module PublicActivity
4
4
  # Class used to initialize configuration object.
5
5
  class Config
6
6
  include ::Singleton
7
- attr_accessor :enabled
7
+ attr_accessor :enabled, :table_name
8
8
 
9
9
  @@orm = :active_record
10
10
 
11
11
  def initialize
12
12
  # Indicates whether PublicActivity is enabled globally
13
- @enabled = true
13
+ @enabled = true
14
+ @table_name = "activities"
14
15
  end
15
16
 
16
17
  # Evaluates given block to provide DSL configuration.
@@ -18,15 +19,14 @@ module PublicActivity
18
19
  # PublicActivity::Config.set do
19
20
  # orm :mongo_mapper
20
21
  # enabled false
22
+ # table_name "activities"
21
23
  # end
22
24
  def self.set &block
23
25
  b = Block.new
24
26
  b.instance_eval &block
25
- orm = b.instance_variable_get(:@orm)
26
- @@orm = orm unless orm.nil?
27
- enabled = b.instance_variable_get(:@en)
27
+ @@orm = b.orm unless b.orm.nil?
28
28
  instance
29
- instance.instance_variable_set(:@enabled, enabled) unless enabled.nil?
29
+ instance.instance_variable_set(:@enabled, b.enabled) unless b.enabled.nil?
30
30
  end
31
31
 
32
32
  # Set the ORM for use by PublicActivity.
@@ -48,6 +48,7 @@ module PublicActivity
48
48
 
49
49
  # Provides simple DSL for the config block.
50
50
  class Block
51
+ attr_reader :orm, :enabled, :table_name
51
52
  # @see Config#orm
52
53
  def orm(orm = nil)
53
54
  @orm = (orm ? orm.to_sym : false) || @orm
@@ -56,7 +57,13 @@ module PublicActivity
56
57
  # Decides whether to enable PublicActivity.
57
58
  # @param en [Boolean] Enabled?
58
59
  def enabled(en = nil)
59
- @en = (en.nil? ? @en : en)
60
+ @enabled = (en.nil? ? @enabled : en)
61
+ end
62
+
63
+ # Sets the table_name
64
+ # for the model
65
+ def table_name(name = nil)
66
+ PublicActivity.config.table_name = name
60
67
  end
61
68
  end
62
69
  end
@@ -3,44 +3,29 @@ module PublicActivity
3
3
  module ActiveRecord
4
4
  # Module extending classes that serve as owners
5
5
  module Activist
6
- extend ActiveSupport::Concern
7
-
8
- # Loads the {ClassMethods#activist} method for declaring the class
9
- # as an activist.
10
- def self.extended(base)
11
- base.extend(ClassMethods)
12
- end
13
-
14
-
15
- # Module extending classes that serve as owners
16
- module ClassMethods
17
- # Adds ActiveRecord associations to model to simplify fetching
18
- # so you can list activities performed by the owner.
19
- # It is completely optional. Any model can be an owner to an activity
20
- # even without being an explicit activist.
21
- #
22
- # == Usage:
23
- # In model:
24
- #
25
- # class User < ActiveRecord::Base
26
- # include PublicActivity::Model
27
- # activist
28
- # end
29
- #
30
- # In controller:
31
- # User.first.activities
32
- #
33
- def activist
34
- # Association of activities as their owner.
35
- # @!method activities_as_owner
36
- # @return [Array<Activity>] Activities which self is the owner of.
37
- has_many :activities_as_owner, :class_name => "::PublicActivity::Activity", :as => :owner
38
-
39
- # Association of activities as their recipient.
40
- # @!method activities_as_recipient
41
- # @return [Array<Activity>] Activities which self is the recipient of.
42
- has_many :activities_as_recipient, :class_name => "::PublicActivity::Activity", :as => :recipient
43
- end
6
+ # Adds ActiveRecord associations to model to simplify fetching
7
+ # so you can list activities performed by the owner.
8
+ # It is completely optional. Any model can be an owner to an activity
9
+ # even without being an explicit activist.
10
+ #
11
+ # == Usage:
12
+ # In model:
13
+ #
14
+ # class User < ActiveRecord::Base
15
+ # include PublicActivity::Model
16
+ # activist
17
+ # end
18
+ #
19
+ # In controller:
20
+ # User.first.activities
21
+ #
22
+ def activist
23
+ has_many :activities_as_owner,
24
+ :class_name => "::PublicActivity::Activity",
25
+ :as => :owner
26
+ has_many :activities_as_recipient,
27
+ :class_name => "::PublicActivity::Activity",
28
+ :as => :recipient
44
29
  end
45
30
  end
46
31
  end
@@ -5,6 +5,7 @@ module PublicActivity
5
5
  # details about recorded activity.
6
6
  class Activity < ::ActiveRecord::Base
7
7
  include Renderable
8
+ self.table_name = PublicActivity.config.table_name
8
9
 
9
10
  # Define polymorphic association to the parent
10
11
  belongs_to :trackable, :polymorphic => true
@@ -15,10 +16,10 @@ module PublicActivity
15
16
  # Serialize parameters Hash
16
17
  serialize :parameters, Hash
17
18
 
18
- if ::ActiveRecord::VERSION::MAJOR < 4
19
+ if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(ProtectedAttributes)
19
20
  attr_accessible :key, :owner, :parameters, :recipient, :trackable
20
21
  end
21
22
  end
22
23
  end
23
24
  end
24
- end
25
+ end
@@ -3,42 +3,30 @@ module PublicActivity
3
3
  module MongoMapper
4
4
  # Module extending classes that serve as owners
5
5
  module Activist
6
- extend ActiveSupport::Concern
7
-
8
- def self.extended(base)
9
- base.extend(ClassMethods)
10
- end
11
- # Association of activities as their owner.
12
- # @!method activities
13
- # @return [Array<Activity>] Activities which self is the owner of.
14
-
15
- # Association of activities as their recipient.
16
- # @!method private_activities
17
- # @return [Array<Activity>] Activities which self is the recipient of.
18
-
19
- # Module extending classes that serve as owners
20
- module ClassMethods
21
- # Adds MongoMapper associations to model to simplify fetching
22
- # so you can list activities performed by the owner.
23
- # It is completely optional. Any model can be an owner to an activity
24
- # even without being an explicit activist.
25
- #
26
- # == Usage:
27
- # In model:
28
- #
29
- # class User
30
- # include MongoMapper::Document
31
- # include PublicActivity::Model
32
- # activist
33
- # end
34
- #
35
- # In controller:
36
- # User.first.activities
37
- #
38
- def activist
39
- many :activities_as_owner, :class_name => "::PublicActivity::Activity", :as => :owner
40
- many :activities_as_recipient, :class_name => "::PublicActivity::Activity", :as => :recipient
41
- end
6
+ # Adds MongoMapper associations to model to simplify fetching
7
+ # so you can list activities performed by the owner.
8
+ # It is completely optional. Any model can be an owner to an activity
9
+ # even without being an explicit activist.
10
+ #
11
+ # == Usage:
12
+ # In model:
13
+ #
14
+ # class User
15
+ # include MongoMapper::Document
16
+ # include PublicActivity::Model
17
+ # activist
18
+ # end
19
+ #
20
+ # In controller:
21
+ # User.first.activities
22
+ #
23
+ def activist
24
+ many :activities_as_owner,
25
+ :class_name => "::PublicActivity::Activity",
26
+ :as => :owner
27
+ many :activities_as_recipient,
28
+ :class_name => "::PublicActivity::Activity",
29
+ :as => :recipient
42
30
  end
43
31
  end
44
32
  end
@@ -3,41 +3,30 @@ module PublicActivity
3
3
  module Mongoid
4
4
  # Module extending classes that serve as owners
5
5
  module Activist
6
- extend ActiveSupport::Concern
6
+ # Adds ActiveRecord associations to model to simplify fetching
7
+ # so you can list activities performed by the owner.
8
+ # It is completely optional. Any model can be an owner to an activity
9
+ # even without being an explicit activist.
10
+ #
11
+ # == Usage:
12
+ # In model:
13
+ #
14
+ # class User < ActiveRecord::Base
15
+ # include PublicActivity::Model
16
+ # activist
17
+ # end
18
+ #
19
+ # In controller:
20
+ # User.first.activities
21
+ #
22
+ def activist
23
+ has_many :activities_as_owner,
24
+ :class_name => "::PublicActivity::Activity",
25
+ :inverse_of => :owner
7
26
 
8
- def self.extended(base)
9
- base.extend(ClassMethods)
10
- end
11
- # Association of activities as their owner.
12
- # @!method activities
13
- # @return [Array<Activity>] Activities which self is the owner of.
14
-
15
- # Association of activities as their recipient.
16
- # @!method private_activities
17
- # @return [Array<Activity>] Activities which self is the recipient of.
18
-
19
- # Module extending classes that serve as owners
20
- module ClassMethods
21
- # Adds ActiveRecord associations to model to simplify fetching
22
- # so you can list activities performed by the owner.
23
- # It is completely optional. Any model can be an owner to an activity
24
- # even without being an explicit activist.
25
- #
26
- # == Usage:
27
- # In model:
28
- #
29
- # class User < ActiveRecord::Base
30
- # include PublicActivity::Model
31
- # activist
32
- # end
33
- #
34
- # In controller:
35
- # User.first.activities
36
- #
37
- def activist
38
- has_many :activities_as_owner, :class_name => "::PublicActivity::Activity", :inverse_of => :owner
39
- has_many :activities_as_recipient, :class_name => "::PublicActivity::Activity", :inverse_of => :recipient
40
- end
27
+ has_many :activities_as_recipient,
28
+ :class_name => "::PublicActivity::Activity",
29
+ :inverse_of => :recipient
41
30
  end
42
31
  end
43
32
  end
@@ -53,6 +53,17 @@ module PublicActivity
53
53
  # <p><%= a.created_at %></p>
54
54
  # <%= yield %>
55
55
  #
56
+ # == Custom Layout Location
57
+ # You can customize the layout directory by supplying :layout_root
58
+ # or by using an absolute path.
59
+ #
60
+ # @example Declare custom layout location
61
+ #
62
+ # # Both examples look for a layout in "app/views/custom/_layout.erb"
63
+ #
64
+ # render_activity @activity, :layout_root => "custom"
65
+ # render_activity @activity, :layout => "/custom/layout"
66
+ #
56
67
  # = Creating a template
57
68
  # To use templates for formatting how the activity should render,
58
69
  # create a template based on activity key, for example:
@@ -64,6 +75,13 @@ module PublicActivity
64
75
  # directory structure will have to be deeper, for example:
65
76
  # activity.article.comments.destroy => app/views/public_activity/articles/comments/_destroy.html.erb
66
77
  #
78
+ # == Custom Directory
79
+ # You can override the default `public_directory` template root with the :root parameter
80
+ #
81
+ # @example Custom template root
82
+ # # look for templates inside of /app/views/custom instead of /app/views/public_directory
83
+ # render_activity @activity, :root => "custom"
84
+ #
67
85
  # == Variables in templates
68
86
  # From within a template there are two variables at your disposal:
69
87
  # * activity (aliased as *a* for a shortcut)
@@ -76,42 +94,69 @@ module PublicActivity
76
94
  # <%= distance_of_time_in_words_to_now(a.created_at) %>
77
95
  # </p>
78
96
  def render(context, params = {})
79
- partial_path = nil
97
+ partial_root = params.delete(:root) || 'public_activity'
98
+ partial_path = nil
99
+ layout_root = params.delete(:layout_root) || 'layouts'
100
+
80
101
  if params.has_key? :display
81
- # if i18n has been requested, let it render and bail
82
- return context.render :text => self.text(params) if params[:display].to_sym == :"i18n"
83
- partial_path = 'public_activity/'+params[:display].to_s
102
+ if params[:display].to_sym == :"i18n"
103
+ return context.render :text => self.text(params)
104
+ else
105
+ partial_path = File.join(partial_root, params[:display].to_s)
106
+ end
84
107
  end
85
108
 
86
- controller = PublicActivity.get_controller
87
- if layout = params.delete(:layout)
88
- layout = layout.to_s
89
- layout = layout[0,8] == "layouts/" ? layout : "layouts/#{layout}"
90
- end
109
+ context.render(
110
+ params.merge({
111
+ :partial => prepare_partial(partial_root, partial_path),
112
+ :layout => prepare_layout(layout_root, params.delete(:layout)),
113
+ :locals => prepare_locals(params)
114
+ })
115
+ )
116
+ end
117
+
118
+ def prepare_partial(root, path)
119
+ path || self.template_path(self.key, root)
120
+ end
91
121
 
122
+ def prepare_locals(params)
92
123
  locals = params.delete(:locals) || Hash.new
93
124
 
94
- params_indifferent = self.parameters.with_indifferent_access
95
- params_indifferent.merge!(params)
125
+ controller = PublicActivity.get_controller
126
+ prepared_params = prepare_parameters(params)
127
+ locals.merge(
128
+ {
129
+ :a => self,
130
+ :activity => self,
131
+ :controller => controller,
132
+ :current_user => controller.respond_to?(:current_user) ? controller.current_user : nil,
133
+ :p => prepared_params,
134
+ :params => prepared_params
135
+ }
136
+ )
137
+ end
138
+
139
+ def prepare_layout(root, layout)
140
+ if layout
141
+ path = layout.to_s
142
+ unless path.starts_with?(root) || path.starts_with?("/")
143
+ return File.join(root, path)
144
+ end
145
+ end
146
+ layout
147
+ end
96
148
 
97
- context.render :partial => (partial_path || self.template_path(self.key)),
98
- :layout => layout,
99
- :locals => locals.merge(:a => self, :activity => self,
100
- :controller => controller,
101
- :current_user => controller.respond_to?(:current_user) ?
102
- controller.current_user : nil ,
103
- :p => params_indifferent, :params => params_indifferent)
149
+ def prepare_parameters(params)
150
+ @prepared_params ||= self.parameters.with_indifferent_access.merge(params)
104
151
  end
105
152
 
106
153
  protected
154
+
107
155
  # Builds the path to template based on activity key
108
- # TODO: verify that attribute `key` is splitted by commas
109
- # and that the word before first comma is equal to
110
- # "activity"
111
- def template_path(key)
156
+ def template_path(key, partial_root)
112
157
  path = key.split(".")
113
158
  path.delete_at(0) if path[0] == "activity"
114
- path.unshift "public_activity"
159
+ path.unshift partial_root
115
160
  path.join("/")
116
161
  end
117
162
  end
@@ -29,10 +29,10 @@ module PublicActivity
29
29
  # @return [nil]
30
30
  def activity(options = {})
31
31
  rest = options.clone
32
- self.activity_key = rest.delete(:key) if rest[:key]
33
- self.activity_owner = rest.delete(:owner) if rest[:owner]
34
- self.activity_params = rest.delete(:params) if rest[:params]
35
- self.activity_recipient = rest.delete(:recipient) if rest[:recipient]
32
+ self.activity_key = rest.delete(:key) if rest[:key]
33
+ self.activity_owner = rest.delete(:owner) if rest[:owner]
34
+ self.activity_params = rest.delete(:params) if rest[:params]
35
+ self.activity_recipient = rest.delete(:recipient) if rest[:recipient]
36
36
  self.activity_custom_fields = rest if rest.count > 0
37
37
  nil
38
38
  end
@@ -133,50 +133,61 @@ module PublicActivity
133
133
  def tracked(opts = {})
134
134
  options = opts.clone
135
135
 
136
- all_options = [:create, :update, :destroy]
136
+ include_default_actions(options)
137
137
 
138
- if !options.has_key?(:skip_defaults) && !options[:only] && !options[:except]
139
- include Creation
140
- include Destruction
141
- include Update
142
- end
143
- options.delete(:skip_defaults)
138
+ assign_globals options
139
+ assign_hooks options
140
+ assign_custom_fields options
144
141
 
145
- if options[:except]
146
- options[:only] = all_options - Array(options.delete(:except))
147
- end
142
+ nil
143
+ end
148
144
 
149
- if options[:only]
150
- Array(options[:only]).each do |opt|
151
- if opt.eql?(:create)
152
- include Creation
153
- elsif opt.eql?(:destroy)
154
- include Destruction
155
- elsif opt.eql?(:update)
156
- include Update
157
- end
158
- end
159
- options.delete(:only)
145
+ def include_default_actions(options)
146
+ defaults = {
147
+ create: Creation,
148
+ destroy: Destruction,
149
+ update: Update
150
+ }
151
+
152
+ if options[:skip_defaults] == true
153
+ return
160
154
  end
161
155
 
162
- if options[:owner]
163
- self.activity_owner_global = options.delete(:owner)
156
+ modules = if options[:except]
157
+ defaults.except(*options[:except])
158
+ elsif options[:only]
159
+ defaults.slice(*options[:only])
160
+ else
161
+ defaults
164
162
  end
165
- if options[:recipient]
166
- self.activity_recipient_global = options.delete(:recipient)
163
+
164
+ modules.each do |key, value|
165
+ include value
167
166
  end
168
- if options[:params]
169
- self.activity_params_global = options.delete(:params)
167
+ end
168
+
169
+ def available_options
170
+ [:skip_defaults, :only, :except, :on, :owner, :recipient, :params].freeze
171
+ end
172
+
173
+ def assign_globals(options)
174
+ [:owner, :recipient, :params].each do |key|
175
+ if options[key]
176
+ self.send("activity_#{key}_global=".to_sym, options.delete(key))
177
+ end
170
178
  end
171
- if options.has_key?(:on) and options[:on].is_a? Hash
172
- self.activity_hooks = options.delete(:on).select {|_, v| v.is_a? Proc}.symbolize_keys
179
+ end
180
+
181
+ def assign_hooks(options)
182
+ if options[:on].is_a?(Hash)
183
+ self.activity_hooks = options[:on].select {|_, v| v.is_a? Proc}.symbolize_keys
173
184
  end
185
+ end
174
186
 
175
- options.each do |k, v|
187
+ def assign_custom_fields(options)
188
+ options.except(*available_options).each do |k, v|
176
189
  self.activity_custom_fields_global[k] = v
177
190
  end
178
-
179
- nil
180
191
  end
181
192
  end
182
193
  end
@@ -0,0 +1,35 @@
1
+ # This file provides functionality for testing your code with public_activity
2
+ # activated or deactivated.
3
+ # This file should only be required in test/spec code!
4
+ #
5
+ # To enable PublicActivity testing capabilities do:
6
+ # require 'public_activity/testing'
7
+ module PublicActivity
8
+ # Execute the code block with PublicActiviy active
9
+ #
10
+ # Example usage:
11
+ # PublicActivity.with_tracking do
12
+ # # your test code here
13
+ # end
14
+ def self.with_tracking
15
+ current = PublicActivity.enabled?
16
+ PublicActivity.enabled = true
17
+ yield
18
+ ensure
19
+ PublicActivity.enabled = current
20
+ end
21
+
22
+ # Execute the code block with PublicActiviy deactive
23
+ #
24
+ # Example usage:
25
+ # PublicActivity.without_tracking do
26
+ # # your test code here
27
+ # end
28
+ def self.without_tracking
29
+ current = PublicActivity.enabled?
30
+ PublicActivity.enabled = false
31
+ yield
32
+ ensure
33
+ PublicActivity.enabled = current
34
+ end
35
+ end
@@ -1,4 +1,4 @@
1
1
  module PublicActivity
2
2
  # A constant with gem's version
3
- VERSION = '1.4.0'
3
+ VERSION = '1.4.1'
4
4
  end
@@ -52,6 +52,13 @@ describe 'PublicActivity::Activity Rendering' do
52
52
  rendered.must_equal '1 2'
53
53
  end
54
54
 
55
+ it "pass all params to view context" do
56
+ view_context = mock('ViewContext')
57
+ PublicActivity.set_controller(nil)
58
+ view_context.expects(:render).with() {|params| params[:formats] == ['json']}
59
+ subject.render(view_context, :formats => ['json'])
60
+ end
61
+
55
62
  it "uses specified layout" do
56
63
  PublicActivity.set_controller(nil)
57
64
  subject.render(self, :layout => "activity")
@@ -63,5 +70,18 @@ describe 'PublicActivity::Activity Rendering' do
63
70
  subject.render(self, :layout => :activity)
64
71
  rendered.must_include "Here be the layouts"
65
72
  end
73
+
74
+ it "accepts a custom layout root" do
75
+ subject.render(self, :layout => :layout, :layout_root => "custom")
76
+ rendered.must_include "Here be the custom layouts"
77
+ end
78
+ it "accepts an absolute layout path" do
79
+ subject.render(self, :layout => '/custom/layout')
80
+ rendered.must_include "Here be the custom layouts"
81
+ end
82
+ it "accepts a template root" do
83
+ subject.render(self, :root => "custom")
84
+ rendered.must_include "Custom Template Root"
85
+ end
66
86
  end
67
87
  end
@@ -94,7 +94,7 @@ describe PublicActivity::Common do
94
94
  activity.owner.must_equal @owner
95
95
  end
96
96
 
97
- describe '#extract_key' do
97
+ describe '#prepare_key' do
98
98
  describe 'for class#activity_key method' do
99
99
  before do
100
100
  @article = article(:owner => :user).new(:user => @owner)
@@ -103,17 +103,17 @@ describe PublicActivity::Common do
103
103
  it 'assigns key to value of activity_key if set' do
104
104
  def @article.activity_key; "my_custom_key" end
105
105
 
106
- @article.extract_key(:create, {}).must_equal "my_custom_key"
106
+ @article.prepare_key(:create, {}).must_equal "my_custom_key"
107
107
  end
108
108
 
109
109
  it 'assigns key based on class name as fallback' do
110
110
  def @article.activity_key; nil end
111
111
 
112
- @article.extract_key(:create).must_equal "article.create"
112
+ @article.prepare_key(:create).must_equal "article.create"
113
113
  end
114
114
 
115
115
  it 'assigns key value from options hash' do
116
- @article.extract_key(:create, :key => :my_custom_key).must_equal "my_custom_key"
116
+ @article.prepare_key(:create, :key => :my_custom_key).must_equal "my_custom_key"
117
117
  end
118
118
  end
119
119
 
@@ -126,7 +126,7 @@ describe PublicActivity::Common do
126
126
  end
127
127
 
128
128
  it 'assigns generates key from class name' do
129
- @camel_case.extract_key(:create, {}).must_equal "camel_case.create"
129
+ @camel_case.prepare_key(:create, {}).must_equal "camel_case.create"
130
130
  end
131
131
  end
132
132
 
@@ -141,7 +141,7 @@ describe PublicActivity::Common do
141
141
  end
142
142
 
143
143
  it 'assigns key value from options hash' do
144
- @namespaced_camel_case.extract_key(:create, {}).must_equal "my_namespace_camel_case.create"
144
+ @namespaced_camel_case.prepare_key(:create, {}).must_equal "my_namespace_camel_case.create"
145
145
  end
146
146
  end
147
147
  end
@@ -2,7 +2,7 @@ require "rubygems"
2
2
  require "bundler"
3
3
  Bundler.setup(:default, :test)
4
4
 
5
- unless ENV['NOCOV']
5
+ if ENV['COV']
6
6
  require 'simplecov'
7
7
  SimpleCov.start do
8
8
  add_filter "/test/"
@@ -11,8 +11,9 @@ end
11
11
  $:.unshift File.expand_path('../../lib/', __FILE__)
12
12
  require 'active_support/testing/setup_and_teardown'
13
13
  require 'public_activity'
14
+ require 'public_activity/testing'
15
+ require 'pry'
14
16
  require 'minitest/autorun'
15
- require 'minitest/pride' if ENV['WITH_PRIDE'] or ENV['PRIDE']
16
17
 
17
18
  PublicActivity::Config.orm = (ENV['PA_ORM'] || :active_record)
18
19
 
@@ -121,4 +122,4 @@ class ViewSpec < MiniTest::Spec
121
122
  include ActiveSupport::Testing::SetupAndTeardown
122
123
  include ActionView::TestCase::Behavior
123
124
  end
124
- MiniTest::Spec.register_spec_type(/Rendering$/, ViewSpec)
125
+ MiniTest::Spec.register_spec_type(/Rendering$/, ViewSpec)
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+ describe PublicActivity do
3
+
4
+ describe "self.with_tracking" do
5
+ it "enables tracking inside the block" do
6
+ PublicActivity.enabled = false
7
+
8
+ PublicActivity.with_tracking do
9
+ PublicActivity.enabled?.must_equal true
10
+ end
11
+ end
12
+
13
+ it "restores previous `enabled` state" do
14
+ PublicActivity.enabled = false
15
+ PublicActivity.with_tracking do
16
+ # something
17
+ end
18
+ PublicActivity.enabled?.must_equal false
19
+ end
20
+ end
21
+
22
+ describe "self.without_tracking" do
23
+ it "disables tracking inside the block" do
24
+ PublicActivity.enabled = true
25
+
26
+ PublicActivity.without_tracking do
27
+ PublicActivity.enabled?.must_equal false
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1 @@
1
+ <h2>Here be the custom layouts</h2><%= yield %>
@@ -0,0 +1 @@
1
+ Custom Template Root <%= activity.id %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: public_activity
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotrek Okoński
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-22 00:00:00.000000000 Z
12
+ date: 2013-12-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -151,6 +151,20 @@ dependencies:
151
151
  - - ~>
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0.8'
154
+ - !ruby/object:Gem::Dependency
155
+ name: pry
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
154
168
  description: Easy activity tracking for your ActiveRecord models. Provides Activity
155
169
  model with details about actions performed by your users, like adding comments,
156
170
  responding etc.
@@ -195,6 +209,7 @@ files:
195
209
  - lib/public_activity/renderable.rb
196
210
  - lib/public_activity/roles/deactivatable.rb
197
211
  - lib/public_activity/roles/tracked.rb
212
+ - lib/public_activity/testing.rb
198
213
  - lib/public_activity/utility/store_controller.rb
199
214
  - lib/public_activity/utility/view_helpers.rb
200
215
  - lib/public_activity/version.rb
@@ -214,8 +229,11 @@ files:
214
229
  - test/test_controller_integration.rb
215
230
  - test/test_generators.rb
216
231
  - test/test_helper.rb
232
+ - test/test_testing.rb
217
233
  - test/test_tracking.rb
218
234
  - test/test_view_helpers.rb
235
+ - test/views/custom/_layout.erb
236
+ - test/views/custom/_test.erb
219
237
  - test/views/layouts/_activity.erb
220
238
  - test/views/public_activity/_test.erb
221
239
  homepage: https://github.com/pokonski/public_activity
@@ -237,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
255
  version: '0'
238
256
  requirements: []
239
257
  rubyforge_project:
240
- rubygems_version: 2.0.7
258
+ rubygems_version: 2.1.11
241
259
  signing_key:
242
260
  specification_version: 4
243
261
  summary: Easy activity tracking for ActiveRecord models
@@ -254,8 +272,11 @@ test_files:
254
272
  - test/test_controller_integration.rb
255
273
  - test/test_generators.rb
256
274
  - test/test_helper.rb
275
+ - test/test_testing.rb
257
276
  - test/test_tracking.rb
258
277
  - test/test_view_helpers.rb
278
+ - test/views/custom/_layout.erb
279
+ - test/views/custom/_test.erb
259
280
  - test/views/layouts/_activity.erb
260
281
  - test/views/public_activity/_test.erb
261
282
  has_rdoc: