public_activity 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
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: