riaction 1.3.5 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/README.md +20 -1
- data/lib/generators/riaction/{USAGE → install/USAGE} +1 -1
- data/lib/generators/riaction/install/install_generator.rb +23 -0
- data/lib/generators/riaction/{templates → install/templates}/i_actionable.yml +0 -0
- data/lib/generators/riaction/install/templates/riaction.rb +21 -0
- data/lib/generators/riaction_generator.rb +11 -0
- data/lib/riaction/api_failure.rb +21 -0
- data/lib/riaction/event_performer.rb +41 -41
- data/lib/riaction/profile_creator.rb +32 -18
- data/lib/riaction/railtie.rb +0 -4
- data/lib/riaction/riaction.rb +1 -0
- data/lib/riaction/version.rb +1 -1
- data/spec/event_performer_spec.rb +47 -35
- data/spec/profile_creation_spec.rb +46 -4
- metadata +28 -26
- data/lib/generators/riaction/riaction_generator.rb +0 -17
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# CHANGELOG #
|
2
2
|
|
3
|
+
## 1.4.0 ##
|
4
|
+
|
5
|
+
* Since IActionable creates non-existent profiles named in an event logging, the event logger no longer tries to confirm profile existence as a pre-condition.
|
6
|
+
* Adding support to provide custom behavior when the API returns a 500 on creating a profile or logging an event.
|
7
|
+
|
3
8
|
## 1.3.4 ##
|
4
9
|
|
5
10
|
* background logging of events will first check if the profile exists, and re-enqueue the job if it doesn't, up to a max number of retries, at which point it will log the event regardless.
|
data/README.md
CHANGED
@@ -16,7 +16,9 @@ Riaction uses [Resque](https://github.com/defunkt/resque) to schedule and perfor
|
|
16
16
|
|
17
17
|
Riaction comes with a generator for creating a YAML file to contain your credentials for each environment of your application. The YAML file is necessary for riaction to run correctly in your rails app.
|
18
18
|
|
19
|
-
rails g riaction development:12345:abcde production:54321:edcba
|
19
|
+
rails g riaction:install development:12345:abcde production:54321:edcba
|
20
|
+
|
21
|
+
This generator will also create an initializer in config/initializers/riaction.rb, where you can provide custom error handling if you wish (see below in *Custom API Error Handling*).
|
20
22
|
|
21
23
|
### Declaring A Model As A Profile ###
|
22
24
|
|
@@ -177,6 +179,23 @@ If you want to avoid the automatic creation of a profile, or the automatic loggi
|
|
177
179
|
Review.riactionless{ @user_instance.reviews.create(:text => "loved it!") } # won't fire the 'write_a_review' event
|
178
180
|
Review.riactionless{ @review_instance.trigger_thumbs_up! } # won't fire the 'receive_thumbs_up' event
|
179
181
|
|
182
|
+
#### Custom API Error Handling ####
|
183
|
+
|
184
|
+
When the API returns a status code 500 on internal error the [Ruby-IActionable gem](https://github.com/zortnac/Ruby-IActionable) will raise an exception of class IActionable::Error::Internal. The default behavior in riaction is to re-raise the error. You can create custom behavior to log the error through a third party service (like Airbrake), have riaction re-schedule the task to try again, save the information to have it be re-attempted later through your own means, or any combination of the above:
|
185
|
+
|
186
|
+
::Riaction::EventPerformer.handle_api_failure_with do |exception, event_name, class_name, id|
|
187
|
+
# log the error through a third party service and then re-attempt
|
188
|
+
Airbrake.notify(exception)
|
189
|
+
true
|
190
|
+
end
|
191
|
+
|
192
|
+
::Riaction::ProfileCreator.handle_api_failure_with do |exception, class_name, id|
|
193
|
+
# log the error through a third party service, punish the user for their failure, and do not re-attempt
|
194
|
+
Airbrake.notify(exception)
|
195
|
+
class_name.constantize.find_by_id(id).flog(:lashes => 100)
|
196
|
+
false
|
197
|
+
end
|
198
|
+
|
180
199
|
### Rails Rake Tasks ###
|
181
200
|
|
182
201
|
There are 3 rake tasks included for summarizing all of your models' declarations as well as a way to initialize profiles on IActionable. To see a report of all the events declared across your application, run the following:
|
@@ -2,7 +2,7 @@ Description:
|
|
2
2
|
Generate a Yaml file in your config directory to contain your IActionable credentials.
|
3
3
|
|
4
4
|
Example:
|
5
|
-
rails generate riaction ENVIRONMENT:APP_KEY:API_KEY ENVIRONMENT:APP_KEY:API_KEY
|
5
|
+
rails generate riaction:install ENVIRONMENT:APP_KEY:API_KEY ENVIRONMENT:APP_KEY:API_KEY
|
6
6
|
|
7
7
|
This will create:
|
8
8
|
config/i_actionable.yml
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'generators/riaction_generator'
|
2
|
+
|
3
|
+
module Riaction
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Base
|
6
|
+
argument :credentials, :type => :array, :required => true, :banner => "environment:app_key:api_key environment:app_key:api_key"
|
7
|
+
|
8
|
+
def create_credentials_file
|
9
|
+
credentials.map!{|credential| { :env => credential[credential_regexp,1],
|
10
|
+
:app_key => credential[credential_regexp,2],
|
11
|
+
:api_key => credential[credential_regexp,3] } }
|
12
|
+
template "i_actionable.yml", "config/i_actionable.yml"
|
13
|
+
template "riaction.rb", "config/initializers/riaction.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def credential_regexp
|
19
|
+
/^(\w+):(\w+):(\w+)$/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# When the IActionable API returns a 500 for logging an event or creating a profile, a custom handler can be defined below,
|
2
|
+
# useful for making calls to external exception notifier services (airbrake, etc), or handling the failure in some specific way
|
3
|
+
# useful to the application.
|
4
|
+
#
|
5
|
+
# ::Riaction::EventPerformer.handle_api_failure_with do |exception, event_name, class_name, id|
|
6
|
+
# # re-raise the exception
|
7
|
+
# raise exception
|
8
|
+
# # return true to have the event rescheduled
|
9
|
+
# true
|
10
|
+
# # return false to not have the event rescheduled
|
11
|
+
# false
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# ::Riaction::ProfileCreator.handle_api_failure_with do |exception, class_name, id|
|
15
|
+
# # re-raise the exception
|
16
|
+
# raise exception
|
17
|
+
# # return true to have the event rescheduled
|
18
|
+
# true
|
19
|
+
# # return false to not have the event rescheduled
|
20
|
+
# false
|
21
|
+
# end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
|
3
|
+
module Riaction
|
4
|
+
module Generators
|
5
|
+
class Base < Rails::Generators::Base
|
6
|
+
def self.source_root
|
7
|
+
@_riaction_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'riaction', generator_name, 'templates'))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Riaction
|
2
|
+
module ApiFailure
|
3
|
+
def handle_api_failure(exception)
|
4
|
+
if @api_failure_handler_block
|
5
|
+
@api_failure_handler_block.call(exception)
|
6
|
+
else
|
7
|
+
default_behavior(exception)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle_api_failure_with(&block)
|
12
|
+
if block_given?
|
13
|
+
@api_failure_handler_block = block
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_behavior(exception)
|
18
|
+
raise exception
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,56 +3,56 @@ require "resque"
|
|
3
3
|
|
4
4
|
module Riaction
|
5
5
|
class EventPerformer
|
6
|
+
extend ::Riaction::ApiFailure
|
7
|
+
|
6
8
|
@queue = :riaction_event_logger
|
7
9
|
|
8
10
|
# Sends an event to IActionable based on the name of a riaction class and the ID used to locate the instance
|
9
11
|
def self.perform(event_name, klass_name, id, attempt=0)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
12
|
+
check_class_requirements!(event_name, klass_name)
|
13
|
+
begin
|
14
|
+
log_event(event_name, klass_name, id)
|
15
|
+
rescue IActionable::Error::BadRequest => e
|
16
|
+
# Log event should never throw this as of IActionable API v3
|
17
|
+
rescue Faraday::Error::TimeoutError, Timeout::Error => e
|
18
|
+
Resque.enqueue(self, event_name, klass_name, id, attempt+1)
|
19
|
+
rescue IActionable::Error::Internal => e
|
20
|
+
# handle_api_failure(event_name, klass_name, id, attempt)
|
21
|
+
handle_api_failure(e, event_name, klass_name, id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.check_class_requirements!(event_name, klass_name)
|
26
|
+
unless klass_name.constantize.riactionary? &&
|
27
|
+
klass_name.constantize.riaction_events? &&
|
28
|
+
klass_name.constantize.riaction_defines_event?(event_name.to_sym)
|
29
|
+
raise ::Riaction::ConfigurationError.new("#{klass_name} does not define event #{event_name}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.log_event(event_name, klass_name, id)
|
34
|
+
iactionable_api = IActionable::Api.new
|
35
|
+
if event_object = klass_name.constantize.find_by_id(id)
|
36
|
+
event_params = event_object.riaction_event_params
|
37
|
+
if event_params.has_key?(event_name.to_sym)
|
38
|
+
iactionable_api.log_event( event_params[event_name.to_sym][:profile][:type],
|
39
|
+
event_params[event_name.to_sym][:profile][:id_type],
|
40
|
+
event_params[event_name.to_sym][:profile][:id],
|
41
|
+
event_name.to_sym,
|
42
|
+
event_params[event_name.to_sym][:params])
|
39
43
|
else
|
40
44
|
raise ::Riaction::ConfigurationError.new("Instance of #{klass_name} with ID #{id} could not construct event parameters for event #{event_name}. Is the profile a valid one?")
|
41
45
|
end
|
42
|
-
else
|
43
|
-
raise ::Riaction::ConfigurationError.new("#{klass_name} does not define event #{event_name}")
|
44
46
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if attempt < ::Riaction::Constants.retry_attempts_for_internal_error
|
53
|
-
Resque.enqueue(self, event_name, klass_name, id, attempt+1)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.handle_api_failure(exception, event_name, klass_name, id)
|
50
|
+
if @api_failure_handler_block
|
51
|
+
if @api_failure_handler_block.call(exception, event_name, klass_name, id)
|
52
|
+
Resque.enqueue(self, event_name, klass_name, id)
|
53
|
+
end
|
54
54
|
else
|
55
|
-
|
55
|
+
default_behavior(exception)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -3,14 +3,33 @@ require "resque"
|
|
3
3
|
|
4
4
|
module Riaction
|
5
5
|
class ProfileCreator
|
6
|
+
extend ::Riaction::ApiFailure
|
7
|
+
|
6
8
|
@queue = :riaction_profile_creator
|
7
9
|
|
8
10
|
def self.perform(klass_name, id, attempt=0)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
check_class_requirements!(klass_name)
|
12
|
+
create_profile(klass_name, id)
|
13
|
+
rescue IActionable::Error::BadRequest => e
|
14
|
+
# This should only be thrown if the profile type names specified in the model don't match what's on IActionable's dashboard
|
15
|
+
raise e
|
16
|
+
rescue Faraday::Error::TimeoutError, Timeout::Error => e
|
17
|
+
Resque.enqueue(self, klass_name, id, attempt+1)
|
18
|
+
rescue IActionable::Error::Internal => e
|
19
|
+
handle_api_failure(e, klass_name, id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.check_class_requirements!(klass_name)
|
23
|
+
unless klass_name.constantize.riactionary? &&
|
24
|
+
klass_name.constantize.riaction_profile? &&
|
25
|
+
klass_name.constantize.riaction_profile_types_defined > 0
|
26
|
+
raise ::Riaction::RuntimeError.new("#{klass_name} does not define any riaction profiles")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create_profile(klass_name, id)
|
31
|
+
iactionable_api = IActionable::Api.new
|
32
|
+
if record = klass_name.constantize.find_by_id(id)
|
14
33
|
record.riaction_profile_keys.each_pair do |profile_type, ids|
|
15
34
|
identifiers = ids.to_a
|
16
35
|
first_defined = identifiers.shift
|
@@ -19,21 +38,16 @@ module Riaction
|
|
19
38
|
iactionable_api.add_profile_identifier(profile_type.to_s, first_defined.first.to_s, first_defined.last.to_s, identifier.first.to_s, identifier.last.to_s)
|
20
39
|
end
|
21
40
|
end
|
22
|
-
else
|
23
|
-
raise ::Riaction::RuntimeError.new("#{klass_name} does not define any riaction profiles")
|
24
41
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# after the max number of attempts, re-raise
|
33
|
-
if attempt < ::Riaction::Constants.retry_attempts_for_internal_error
|
34
|
-
Resque.enqueue(self, klass_name, id, attempt+1)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.handle_api_failure(exception, klass_name, id)
|
45
|
+
if @api_failure_handler_block
|
46
|
+
if @api_failure_handler_block.call(exception, klass_name, id)
|
47
|
+
Resque.enqueue(self, klass_name, id)
|
48
|
+
end
|
35
49
|
else
|
36
|
-
|
50
|
+
default_behavior(exception)
|
37
51
|
end
|
38
52
|
end
|
39
53
|
end
|
data/lib/riaction/railtie.rb
CHANGED
@@ -6,10 +6,6 @@ module Riaction
|
|
6
6
|
load "tasks/riaction.rake"
|
7
7
|
end
|
8
8
|
|
9
|
-
generators do
|
10
|
-
require "generators/riaction/riaction_generator"
|
11
|
-
end
|
12
|
-
|
13
9
|
initializer "riaction_railtie.configure_i_actionable_creds" do |app|
|
14
10
|
begin
|
15
11
|
IActionable::Api.init_settings(YAML.load_file("#{::Rails.root}/config/i_actionable.yml")[::Rails.env].symbolize_keys!)
|
data/lib/riaction/riaction.rb
CHANGED
data/lib/riaction/version.rb
CHANGED
@@ -93,36 +93,6 @@ describe "sending an event to IActionable from the name of a riaction class and
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
describe "when the profile attached to the event does not exist on IActionable" do
|
97
|
-
before do
|
98
|
-
Comment.class_eval do
|
99
|
-
riaction :event, :name => :make_a_comment, :trigger => :create, :profile => :user, :profile_type => :player
|
100
|
-
end
|
101
|
-
|
102
|
-
@comment = Comment.riactionless{ Comment.create(:user_id => @user.id, :content => 'this is a comment') }
|
103
|
-
|
104
|
-
@api.stub!(:get_profile_summary).and_raise(IActionable::Error::BadRequest.new(nil))
|
105
|
-
end
|
106
|
-
|
107
|
-
it "should not log the event, but reschedule the job with an incremented attempt count" do
|
108
|
-
@api.should_not_receive(:log_event)
|
109
|
-
Resque.should_receive(:enqueue).once.with(Riaction::EventPerformer, :make_a_comment, 'Comment', @comment.id, 1)
|
110
|
-
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)
|
111
|
-
end
|
112
|
-
|
113
|
-
describe "and the number of attempts has reached the max" do
|
114
|
-
it "should log the event, and not re-enqueue" do
|
115
|
-
@api.should_receive(:log_event).once.with(@comment.riaction_event_params[:make_a_comment][:profile][:type],
|
116
|
-
@comment.riaction_event_params[:make_a_comment][:profile][:id_type],
|
117
|
-
@comment.riaction_event_params[:make_a_comment][:profile][:id],
|
118
|
-
:make_a_comment,
|
119
|
-
{})
|
120
|
-
Resque.should_not_receive(:enqueue)
|
121
|
-
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id, Riaction::Constants.retry_attempts_for_missing_profile)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
96
|
describe "when fetching the event params raises a" do
|
127
97
|
before do
|
128
98
|
Comment.class_eval do
|
@@ -135,7 +105,7 @@ describe "sending an event to IActionable from the name of a riaction class and
|
|
135
105
|
describe "RuntimeError" do
|
136
106
|
before do
|
137
107
|
@comment.stub!(:riaction_event_params).and_raise(::Riaction::RuntimeError)
|
138
|
-
Comment.stub!(:find_by_id
|
108
|
+
Comment.stub!(:find_by_id).and_return(@comment)
|
139
109
|
end
|
140
110
|
|
141
111
|
it "should not try to create the event" do
|
@@ -154,7 +124,7 @@ describe "sending an event to IActionable from the name of a riaction class and
|
|
154
124
|
describe "ConfigurationError" do
|
155
125
|
before do
|
156
126
|
@comment.stub!(:riaction_event_params).and_raise(::Riaction::ConfigurationError)
|
157
|
-
Comment.stub!(:find_by_id
|
127
|
+
Comment.stub!(:find_by_id).and_return(@comment)
|
158
128
|
end
|
159
129
|
|
160
130
|
it "should not try to create the event" do
|
@@ -266,17 +236,59 @@ describe "sending an event to IActionable from the name of a riaction class and
|
|
266
236
|
|
267
237
|
describe "when the call to IActionable, through API wrapper, fails" do
|
268
238
|
before do
|
269
|
-
@
|
239
|
+
@exception = IActionable::Error::Internal.new("")
|
240
|
+
@api.stub!(:log_event).and_raise(@exception)
|
270
241
|
Comment.class_eval do
|
271
242
|
riaction :event, :name => :make_a_comment, :trigger => :create, :profile => :user, :profile_type => :npc, :params => {:foo => 'bar'}
|
272
243
|
end
|
273
244
|
@comment = Comment.riactionless{ Comment.create(:user_id => @user.id, :content => 'this is a comment') }
|
274
245
|
end
|
275
246
|
|
276
|
-
it "should
|
277
|
-
|
247
|
+
it "should handle the failure passing the exception, event name, class name, and model id" do
|
248
|
+
::Riaction::EventPerformer.should_receive(:handle_api_failure).once.with(@exception, :make_a_comment, 'Comment', @comment.id)
|
278
249
|
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)
|
279
250
|
end
|
251
|
+
|
252
|
+
describe "and the default behavior of the failure handler is in place" do
|
253
|
+
it "should re-raise the exception" do
|
254
|
+
lambda{::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)}.should raise_error(@exception)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "and custom behavior of the failure handler is in place" do
|
259
|
+
before do
|
260
|
+
::Riaction::EventPerformer.handle_api_failure_with do |exception, event_name, class_name, id|
|
261
|
+
5.times do
|
262
|
+
exception.inspect
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should perform the custom behavior" do
|
268
|
+
@exception.should_receive(:inspect).exactly(5).times
|
269
|
+
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)
|
270
|
+
end
|
271
|
+
|
272
|
+
describe "and that custom behavior evaluates to true" do
|
273
|
+
it "should reschedule the event" do
|
274
|
+
Resque.should_receive(:enqueue).once.with(Riaction::EventPerformer, :make_a_comment, 'Comment', @comment.id)
|
275
|
+
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe "and that custom behavior evaluates to false" do
|
280
|
+
before do
|
281
|
+
::Riaction::EventPerformer.handle_api_failure_with do |exception, event_name, class_name, id|
|
282
|
+
false
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should not reschedule the event" do
|
287
|
+
Resque.should_not_receive(:enqueue)
|
288
|
+
::Riaction::EventPerformer.perform(:make_a_comment, 'Comment', @comment.id)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
280
292
|
end
|
281
293
|
|
282
294
|
describe "when the call to IActionable, through API wrapper, times out" do
|
@@ -114,16 +114,58 @@ describe "automatic profile creation from riaction definitions:" do
|
|
114
114
|
|
115
115
|
describe "when the call to IActionable, through API wrapper, fails" do
|
116
116
|
before do
|
117
|
-
@
|
117
|
+
@exception = IActionable::Error::Internal.new("")
|
118
|
+
@api.stub!(:create_profile).and_raise(@exception)
|
118
119
|
User.class_eval do
|
119
120
|
riaction :profile, :type => :player, :custom => :id, :username => :name
|
120
121
|
end
|
121
122
|
@user = User.riactionless{ User.create(:name => 'zortnac') }
|
122
123
|
end
|
123
124
|
|
124
|
-
it "should
|
125
|
-
|
126
|
-
::Riaction::ProfileCreator.perform('User', @user.id
|
125
|
+
it "should handle the failure passing the exception, class name, and model id" do
|
126
|
+
::Riaction::ProfileCreator.should_receive(:handle_api_failure).once.with(@exception, 'User', @user.id)
|
127
|
+
::Riaction::ProfileCreator.perform('User', @user.id)
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "and the default behavior of the failure handler is in place" do
|
131
|
+
it "should re-raise the exception" do
|
132
|
+
lambda{::Riaction::ProfileCreator.perform('User', @user.id)}.should raise_error(@exception)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "and custom behavior of the failure handler is in place" do
|
137
|
+
before do
|
138
|
+
::Riaction::ProfileCreator.handle_api_failure_with do |exception, class_name, id|
|
139
|
+
3.times do
|
140
|
+
exception.inspect
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should perform the custom behavior" do
|
146
|
+
@exception.should_receive(:inspect).exactly(3).times
|
147
|
+
::Riaction::ProfileCreator.perform('User', @user.id)
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "and that custom behavior evaluates to true" do
|
151
|
+
it "should reschedule the event" do
|
152
|
+
Resque.should_receive(:enqueue).once.with(Riaction::ProfileCreator, "User", @user.id)
|
153
|
+
::Riaction::ProfileCreator.perform('User', @user.id)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "and that custom behavior evaluates to false" do
|
158
|
+
before do
|
159
|
+
::Riaction::ProfileCreator.handle_api_failure_with do |exception, class_name, id|
|
160
|
+
false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should not reschedule the event" do
|
165
|
+
Resque.should_not_receive(:enqueue)
|
166
|
+
::Riaction::ProfileCreator.perform('User', @user.id)
|
167
|
+
end
|
168
|
+
end
|
127
169
|
end
|
128
170
|
end
|
129
171
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riaction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-06-27 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rspec
|
18
|
-
requirement: &
|
18
|
+
requirement: &2164272500 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ! '>='
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '2.8'
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *2164272500
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sqlite3
|
29
|
-
requirement: &
|
29
|
+
requirement: &2164271940 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ! '>='
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *2164271940
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: ruby-debug19
|
40
|
-
requirement: &
|
40
|
+
requirement: &2164271140 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *2164271140
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: yard
|
51
|
-
requirement: &
|
51
|
+
requirement: &2164270380 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ! '>='
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *2164270380
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: redcarpet
|
62
|
-
requirement: &
|
62
|
+
requirement: &2164268920 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ! '>='
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *2164268920
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rake
|
73
|
-
requirement: &
|
73
|
+
requirement: &2164268200 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *2164268200
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: activerecord
|
84
|
-
requirement: &
|
84
|
+
requirement: &2164267400 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ! '>='
|
@@ -89,10 +89,10 @@ dependencies:
|
|
89
89
|
version: 3.0.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *2164267400
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: activesupport
|
95
|
-
requirement: &
|
95
|
+
requirement: &2164266480 !ruby/object:Gem::Requirement
|
96
96
|
none: false
|
97
97
|
requirements:
|
98
98
|
- - ! '>='
|
@@ -100,10 +100,10 @@ dependencies:
|
|
100
100
|
version: 3.0.0
|
101
101
|
type: :runtime
|
102
102
|
prerelease: false
|
103
|
-
version_requirements: *
|
103
|
+
version_requirements: *2164266480
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
105
|
name: resque
|
106
|
-
requirement: &
|
106
|
+
requirement: &2164265680 !ruby/object:Gem::Requirement
|
107
107
|
none: false
|
108
108
|
requirements:
|
109
109
|
- - ! '>='
|
@@ -111,10 +111,10 @@ dependencies:
|
|
111
111
|
version: '0'
|
112
112
|
type: :runtime
|
113
113
|
prerelease: false
|
114
|
-
version_requirements: *
|
114
|
+
version_requirements: *2164265680
|
115
115
|
- !ruby/object:Gem::Dependency
|
116
116
|
name: ruby-iactionable
|
117
|
-
requirement: &
|
117
|
+
requirement: &2164264420 !ruby/object:Gem::Requirement
|
118
118
|
none: false
|
119
119
|
requirements:
|
120
120
|
- - ! '>='
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
version: 0.1.2
|
123
123
|
type: :runtime
|
124
124
|
prerelease: false
|
125
|
-
version_requirements: *
|
125
|
+
version_requirements: *2164264420
|
126
126
|
description: Wrapper for IActionable's restful API and an "acts-as" style interface
|
127
127
|
for models to behave as profiles and drive game events.
|
128
128
|
email:
|
@@ -175,10 +175,13 @@ files:
|
|
175
175
|
- doc/js/jquery.js
|
176
176
|
- doc/method_list.html
|
177
177
|
- doc/top-level-namespace.html
|
178
|
-
- lib/generators/riaction/USAGE
|
179
|
-
- lib/generators/riaction/
|
180
|
-
- lib/generators/riaction/templates/i_actionable.yml
|
178
|
+
- lib/generators/riaction/install/USAGE
|
179
|
+
- lib/generators/riaction/install/install_generator.rb
|
180
|
+
- lib/generators/riaction/install/templates/i_actionable.yml
|
181
|
+
- lib/generators/riaction/install/templates/riaction.rb
|
182
|
+
- lib/generators/riaction_generator.rb
|
181
183
|
- lib/riaction.rb
|
184
|
+
- lib/riaction/api_failure.rb
|
182
185
|
- lib/riaction/constants.rb
|
183
186
|
- lib/riaction/crud_event_callback.rb
|
184
187
|
- lib/riaction/event_performer.rb
|
@@ -189,7 +192,6 @@ files:
|
|
189
192
|
- lib/riaction/version.rb
|
190
193
|
- lib/rspec/matchers/riaction.rb
|
191
194
|
- lib/tasks/riaction.rake
|
192
|
-
- riaction-1.3.5.gem
|
193
195
|
- riaction.gemspec
|
194
196
|
- spec/custom_matchers_spec.rb
|
195
197
|
- spec/event_performer_spec.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class RiactionGenerator < Rails::Generators::Base
|
2
|
-
source_root File.expand_path("../templates", __FILE__)
|
3
|
-
argument :credentials, :type => :array, :required => true, :banner => "environment:app_key:api_key environment:app_key:api_key"
|
4
|
-
|
5
|
-
def create_credentials_file
|
6
|
-
credentials.map!{|credential| { :env => credential[credential_regexp,1],
|
7
|
-
:app_key => credential[credential_regexp,2],
|
8
|
-
:api_key => credential[credential_regexp,3] } }
|
9
|
-
template "i_actionable.yml", "config/i_actionable.yml"
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def credential_regexp
|
15
|
-
/^(\w+):(\w+):(\w+)$/
|
16
|
-
end
|
17
|
-
end
|