devise-async 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ test/support/app/log/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in devise_background.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Marcelo Silveira
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Devise Async
2
+
3
+ Devise Async provides an easy way to configure Devise to send its emails asynchronously using your preferred queuing backend.
4
+
5
+ Supported backends:
6
+
7
+ * Resque
8
+ * Sidekiq
9
+ * Delayed::Job
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'devise-async'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install devise-async
24
+
25
+ ## Usage
26
+
27
+ Set `DeviseAsync::Proxy` as Devise's mailer in `config/initializers/devise.rb`:
28
+
29
+ # Configure the class responsible to send e-mails.
30
+ config.mailer = "DeviseAsync::Proxy"
31
+
32
+ Set your queuing backend by creating `config/initializers/devise_async.rb`:
33
+
34
+ # Supported options: :resque, :sidekiq, :delayed_job
35
+ DeviseAsync.backend = :resque
36
+
37
+ Tip: it defaults to Resque. You don't need to create the initializer if using it.
38
+
39
+ ## Contributing
40
+
41
+ 1. Fork it
42
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
43
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
44
+ 4. Push to the branch (`git push origin my-new-feature`)
45
+ 5. Create new Pull Request
46
+
47
+ ## License
48
+
49
+ Released under the MIT License. See the [LICENSE][license] file for further details.
50
+
51
+ [license]: https://github.com/mhfs/devise-async/blob/master/LICENSE
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new do |t|
9
+ t.libs << "lib"
10
+ t.libs << "test"
11
+ t.test_files = FileList["test/**/*_test.rb"]
12
+ t.verbose = true
13
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/devise_async/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Marcelo Silveira"]
6
+ gem.email = ["marcelo@mhfs.com.br"]
7
+ gem.description = %q{Send Devise's emails in background. Supports Resque, Sidekiq and Delayed::Job.}
8
+ gem.summary = %q{Devise Async provides an easy way to configure Devise to send its emails asynchronously using your preferred queuing backend. It supports Resque, Sidekiq and Delayed::Job.}
9
+ gem.homepage = "https://github.com/mhfs/devise-async/"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "devise-async"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = DeviseAsync::VERSION
17
+
18
+ gem.add_dependency "devise"
19
+
20
+ gem.add_development_dependency "activerecord", "~> 3.2"
21
+ gem.add_development_dependency "actionpack", "~> 3.2"
22
+ gem.add_development_dependency "actionmailer", "~> 3.2"
23
+ gem.add_development_dependency "mysql2", "~> 0.3"
24
+ gem.add_development_dependency "resque", "~> 1.20"
25
+ gem.add_development_dependency "sidekiq", "~> 1.2"
26
+ gem.add_development_dependency "delayed_job_active_record", "~> 0.3"
27
+ gem.add_development_dependency "mocha", "~> 0.11"
28
+ gem.add_development_dependency "minitest", "~> 3.0"
29
+ end
@@ -0,0 +1 @@
1
+ require "devise_async"
@@ -0,0 +1,18 @@
1
+ require "active_support/dependencies"
2
+ require "devise_async/version"
3
+
4
+ module DeviseAsync
5
+ autoload :Proxy, "devise_async/proxy"
6
+ autoload :Worker, "devise_async/worker"
7
+ autoload :Backend, "devise_async/backend"
8
+
9
+ module Backend
10
+ autoload :Resque, "devise_async/backend/resque"
11
+ autoload :Sidekiq, "devise_async/backend/sidekiq"
12
+ autoload :DelayedJob, "devise_async/backend/delayed_job"
13
+ end
14
+
15
+ # Defines the queue backend to be used. Resque by default.
16
+ mattr_accessor :backend
17
+ @@backend = :resque
18
+ end
@@ -0,0 +1,9 @@
1
+ module DeviseAsync
2
+ module Backend
3
+ def self.for(backend)
4
+ const_get(backend.to_s.camelize)
5
+ rescue NameError
6
+ raise ArgumentError, "unsupported backend for devise-async."
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module DeviseAsync
2
+ module Backend
3
+ class DelayedJob
4
+ def self.enqueue(*args)
5
+ new.delay.perform(*args)
6
+ end
7
+
8
+ def perform(method, resource_class, resource_id)
9
+ resource = resource_class.constantize.find(resource_id)
10
+ Devise::Mailer.send(method, resource).deliver
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module DeviseAsync
2
+ module Backend
3
+ class Resque
4
+ @queue = :mailer
5
+
6
+ def self.enqueue(*args)
7
+ args.unshift(self)
8
+ ::Resque.enqueue(*args)
9
+ end
10
+
11
+ def self.perform(method, resource_class, resource_id)
12
+ resource = resource_class.constantize.find(resource_id)
13
+ Devise::Mailer.send(method, resource).deliver
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module DeviseAsync
2
+ module Backend
3
+ class Sidekiq
4
+ include ::Sidekiq::Worker
5
+
6
+ sidekiq_options :queue => :mailer
7
+
8
+ def self.enqueue(*args)
9
+ perform_async(*args)
10
+ end
11
+
12
+ def perform(method, resource_class, resource_id)
13
+ resource = resource_class.constantize.find(resource_id)
14
+ Devise::Mailer.send(method, resource).deliver
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module DeviseAsync
2
+ class Proxy
3
+ # catches all devise emails
4
+ def self.method_missing(method, *args, &block)
5
+ new(method, args.first)
6
+ end
7
+
8
+ def initialize(method, resource)
9
+ @method, @resource = method, resource
10
+ end
11
+
12
+ def deliver
13
+ Worker.enqueue(@method, @resource.class.name, @resource.id)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module DeviseAsync
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,13 @@
1
+ module DeviseAsync
2
+ class Worker
3
+ def self.enqueue(method, resource_class, resource_id)
4
+ backend_class.enqueue(method, resource_class, resource_id)
5
+ end
6
+
7
+ private
8
+
9
+ def self.backend_class
10
+ Backend.for(DeviseAsync.backend)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ module Backend
5
+ describe "DelayedJob" do
6
+ it "enqueues job" do
7
+ delayed_instance = mock()
8
+ delayed_instance.expects(:perform).once.with(:mailer_method, "User", 123)
9
+ DelayedJob.any_instance.expects(:delay).once.returns(delayed_instance)
10
+
11
+ DelayedJob.enqueue(:mailer_method, "User", 123)
12
+ end
13
+
14
+ it "delegates to devise mailer when delivering" do
15
+ user = create_user
16
+ ActionMailer::Base.deliveries = []
17
+ Backend::DelayedJob.new.perform(:confirmation_instructions, "User", user.id)
18
+ ActionMailer::Base.deliveries.size.must_equal 1
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ module Backend
5
+ describe "Resque" do
6
+ it "enqueues job" do
7
+ ::Resque.expects(:enqueue).with(Resque, :mailer_method, "User", 123)
8
+ Resque.enqueue(:mailer_method, "User", 123)
9
+ end
10
+
11
+ it "delegates to devise mailer when delivering" do
12
+ user = create_user
13
+ ActionMailer::Base.deliveries = []
14
+ Backend::Resque.perform(:confirmation_instructions, "User", user.id)
15
+ ActionMailer::Base.deliveries.size.must_equal 1
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ module Backend
5
+ describe "Sidekiq" do
6
+ it "enqueues job" do
7
+ Sidekiq.expects(:perform_async).with(:mailer_method, "User", 123)
8
+ Sidekiq.enqueue(:mailer_method, "User", 123)
9
+ end
10
+
11
+ it "delegates to devise mailer when delivering" do
12
+ user = create_user
13
+ ActionMailer::Base.deliveries = []
14
+ Backend::Sidekiq.new.perform(:confirmation_instructions, "User", user.id)
15
+ ActionMailer::Base.deliveries.size.must_equal 1
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ describe "Backend" do
5
+ it "gives resque as the backend" do
6
+ Backend.for(:resque).must_equal Backend::Resque
7
+ end
8
+
9
+ it "gives sidekiq as the backend" do
10
+ Backend.for(:sidekiq).must_equal Backend::Sidekiq
11
+ end
12
+
13
+ it "gives delayed job as the backend" do
14
+ Backend.for(:delayed_job).must_equal Backend::DelayedJob
15
+ end
16
+
17
+ it "alerts about unsupported backend" do
18
+ assert_raises ArgumentError do
19
+ Backend.for(:unsupported_backend)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ describe "Proxy" do
5
+ it "gets called by devise operations and proxy to worker" do
6
+ user = create_user
7
+ Worker.expects(:enqueue).with(:confirmation_instructions, "User", user.id)
8
+ user.send_confirmation_instructions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class User < ActiveRecord::Base
2
+ devise :database_authenticatable, :confirmable, :lockable, :recoverable,
3
+ :registerable, :rememberable, :timeoutable, :token_authenticatable,
4
+ :trackable, :validatable
5
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ adapter: mysql2
3
+ database: test
4
+ username: root
5
+ password: 123mudar
6
+ host: localhost
@@ -0,0 +1,219 @@
1
+ # Use this hook to configure devise mailer, warden hooks and so forth.
2
+ # Many of these configuration options can be set straight in your model.
3
+ Devise.setup do |config|
4
+ # ==> Mailer Configuration
5
+ # Configure the e-mail address which will be shown in Devise::Mailer,
6
+ # note that it will be overwritten if you use your own mailer class with default "from" parameter.
7
+ config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
8
+
9
+ # Configure the class responsible to send e-mails.
10
+ config.mailer = "DeviseAsync::Proxy"
11
+
12
+ # ==> ORM configuration
13
+ # Load and configure the ORM. Supports :active_record (default) and
14
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
15
+ # available as additional gems.
16
+ require 'devise/orm/active_record'
17
+
18
+ # ==> Configuration for any authentication mechanism
19
+ # Configure which keys are used when authenticating a user. The default is
20
+ # just :email. You can configure it to use [:username, :subdomain], so for
21
+ # authenticating a user, both parameters are required. Remember that those
22
+ # parameters are used only when authenticating and not when retrieving from
23
+ # session. If you need permissions, you should implement that in a before filter.
24
+ # You can also supply a hash where the value is a boolean determining whether
25
+ # or not authentication should be aborted when the value is not present.
26
+ # config.authentication_keys = [ :email ]
27
+
28
+ # Configure parameters from the request object used for authentication. Each entry
29
+ # given should be a request method and it will automatically be passed to the
30
+ # find_for_authentication method and considered in your model lookup. For instance,
31
+ # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
32
+ # The same considerations mentioned for authentication_keys also apply to request_keys.
33
+ # config.request_keys = []
34
+
35
+ # Configure which authentication keys should be case-insensitive.
36
+ # These keys will be downcased upon creating or modifying a user and when used
37
+ # to authenticate or find a user. Default is :email.
38
+ config.case_insensitive_keys = [ :email ]
39
+
40
+ # Configure which authentication keys should have whitespace stripped.
41
+ # These keys will have whitespace before and after removed upon creating or
42
+ # modifying a user and when used to authenticate or find a user. Default is :email.
43
+ config.strip_whitespace_keys = [ :email ]
44
+
45
+ # Tell if authentication through request.params is enabled. True by default.
46
+ # It can be set to an array that will enable params authentication only for the
47
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
48
+ # enable it only for database (email + password) authentication.
49
+ # config.params_authenticatable = true
50
+
51
+ # Tell if authentication through HTTP Basic Auth is enabled. False by default.
52
+ # It can be set to an array that will enable http authentication only for the
53
+ # given strategies, for example, `config.http_authenticatable = [:token]` will
54
+ # enable it only for token authentication.
55
+ # config.http_authenticatable = false
56
+
57
+ # If http headers should be returned for AJAX requests. True by default.
58
+ # config.http_authenticatable_on_xhr = true
59
+
60
+ # The realm used in Http Basic Authentication. "Application" by default.
61
+ # config.http_authentication_realm = "Application"
62
+
63
+ # It will change confirmation, password recovery and other workflows
64
+ # to behave the same regardless if the e-mail provided was right or wrong.
65
+ # Does not affect registerable.
66
+ # config.paranoid = true
67
+
68
+ # By default Devise will store the user in session. You can skip storage for
69
+ # :http_auth and :token_auth by adding those symbols to the array below.
70
+ # Notice that if you are skipping storage for all authentication paths, you
71
+ # may want to disable generating routes to Devise's sessions controller by
72
+ # passing :skip => :sessions to `devise_for` in your config/routes.rb
73
+ config.skip_session_storage = [:http_auth]
74
+
75
+ # ==> Configuration for :database_authenticatable
76
+ # For bcrypt, this is the cost for hashing the password and defaults to 10. If
77
+ # using other encryptors, it sets how many times you want the password re-encrypted.
78
+ #
79
+ # Limiting the stretches to just one in testing will increase the performance of
80
+ # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
81
+ # a value less than 10 in other environments.
82
+ config.stretches = Rails.env.test? ? 1 : 10
83
+
84
+ # Setup a pepper to generate the encrypted password.
85
+ config.pepper = "e6b692498a53202d3be57ac3517afa2252d7b6eec044e8ff1e0f2f1119afc92d03305e6cb1715da01009c2ae8dbcdb0176612b2d1390bfadf55527a78f247f7b"
86
+
87
+ # ==> Configuration for :confirmable
88
+ # A period that the user is allowed to access the website even without
89
+ # confirming his account. For instance, if set to 2.days, the user will be
90
+ # able to access the website for two days without confirming his account,
91
+ # access will be blocked just in the third day. Default is 0.days, meaning
92
+ # the user cannot access the website without confirming his account.
93
+ # config.allow_unconfirmed_access_for = 2.days
94
+
95
+ # If true, requires any email changes to be confirmed (exactly the same way as
96
+ # initial account confirmation) to be applied. Requires additional unconfirmed_email
97
+ # db field (see migrations). Until confirmed new email is stored in
98
+ # unconfirmed email column, and copied to email column on successful confirmation.
99
+ config.reconfirmable = true
100
+
101
+ # Defines which key will be used when confirming an account
102
+ # config.confirmation_keys = [ :email ]
103
+
104
+ # ==> Configuration for :rememberable
105
+ # The time the user will be remembered without asking for credentials again.
106
+ # config.remember_for = 2.weeks
107
+
108
+ # If true, extends the user's remember period when remembered via cookie.
109
+ # config.extend_remember_period = false
110
+
111
+ # Options to be passed to the created cookie. For instance, you can set
112
+ # :secure => true in order to force SSL only cookies.
113
+ # config.rememberable_options = {}
114
+
115
+ # ==> Configuration for :validatable
116
+ # Range for password length. Default is 6..128.
117
+ # config.password_length = 6..128
118
+
119
+ # Email regex used to validate email formats. It simply asserts that
120
+ # an one (and only one) @ exists in the given string. This is mainly
121
+ # to give user feedback and not to assert the e-mail validity.
122
+ # config.email_regexp = /\A[^@]+@[^@]+\z/
123
+
124
+ # ==> Configuration for :timeoutable
125
+ # The time you want to timeout the user session without activity. After this
126
+ # time the user will be asked for credentials again. Default is 30 minutes.
127
+ # config.timeout_in = 30.minutes
128
+
129
+ # ==> Configuration for :lockable
130
+ # Defines which strategy will be used to lock an account.
131
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
132
+ # :none = No lock strategy. You should handle locking by yourself.
133
+ # config.lock_strategy = :failed_attempts
134
+
135
+ # Defines which key will be used when locking and unlocking an account
136
+ # config.unlock_keys = [ :email ]
137
+
138
+ # Defines which strategy will be used to unlock an account.
139
+ # :email = Sends an unlock link to the user email
140
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
141
+ # :both = Enables both strategies
142
+ # :none = No unlock strategy. You should handle unlocking by yourself.
143
+ # config.unlock_strategy = :both
144
+
145
+ # Number of authentication tries before locking an account if lock_strategy
146
+ # is failed attempts.
147
+ # config.maximum_attempts = 20
148
+
149
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
150
+ # config.unlock_in = 1.hour
151
+
152
+ # ==> Configuration for :recoverable
153
+ #
154
+ # Defines which key will be used when recovering the password for an account
155
+ # config.reset_password_keys = [ :email ]
156
+
157
+ # Time interval you can reset your password with a reset password key.
158
+ # Don't put a too small interval or your users won't have the time to
159
+ # change their passwords.
160
+ config.reset_password_within = 6.hours
161
+
162
+ # ==> Configuration for :encryptable
163
+ # Allow you to use another encryption algorithm besides bcrypt (default). You can use
164
+ # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
165
+ # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
166
+ # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
167
+ # REST_AUTH_SITE_KEY to pepper)
168
+ # config.encryptor = :sha512
169
+
170
+ # ==> Configuration for :token_authenticatable
171
+ # Defines name of the authentication token params key
172
+ # config.token_authentication_key = :auth_token
173
+
174
+ # ==> Scopes configuration
175
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
176
+ # "users/sessions/new". It's turned off by default because it's slower if you
177
+ # are using only default views.
178
+ # config.scoped_views = false
179
+
180
+ # Configure the default scope given to Warden. By default it's the first
181
+ # devise role declared in your routes (usually :user).
182
+ # config.default_scope = :user
183
+
184
+ # Configure sign_out behavior.
185
+ # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
186
+ # The default is true, which means any logout action will sign out all active scopes.
187
+ # config.sign_out_all_scopes = true
188
+
189
+ # ==> Navigation configuration
190
+ # Lists the formats that should be treated as navigational. Formats like
191
+ # :html, should redirect to the sign in page when the user does not have
192
+ # access, but formats like :xml or :json, should return 401.
193
+ #
194
+ # If you have any extra navigational formats, like :iphone or :mobile, you
195
+ # should add them to the navigational formats lists.
196
+ #
197
+ # The "*/*" below is required to match Internet Explorer requests.
198
+ # config.navigational_formats = ["*/*", :html]
199
+
200
+ # The default HTTP method used to sign out a resource. Default is :delete.
201
+ config.sign_out_via = :delete
202
+
203
+ # ==> OmniAuth
204
+ # Add a new OmniAuth provider. Check the wiki for more information on setting
205
+ # up on your models and hooks.
206
+ # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
207
+
208
+ # ==> Warden configuration
209
+ # If you want to use other strategies, that are not supported by Devise, or
210
+ # change the failure app, you can configure them inside the config.warden block.
211
+ #
212
+ # config.warden do |manager|
213
+ # manager.intercept_401 = false
214
+ # manager.default_strategies(:scope => :user).unshift :some_external_strategy
215
+ # end
216
+
217
+ # FIXME remove as soon as deprecation stops
218
+ config.use_salt_as_remember_token = true
219
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ devise_for :users
3
+ end
@@ -0,0 +1,44 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+ begin
3
+ drop_table :users
4
+ drop_rable :delayed_jobs
5
+ rescue Exception => e
6
+ end
7
+
8
+ create_table "users", :force => true do |t|
9
+ t.string "username"
10
+ t.string "facebook_token"
11
+ t.string "email", :default => "", :null => false
12
+ t.string "unconfirmed_email", :default => ""
13
+ t.string "encrypted_password", :limit => 128, :default => "", :null => false
14
+ t.string "confirmation_token"
15
+ t.datetime "confirmed_at"
16
+ t.datetime "confirmation_sent_at"
17
+ t.string "reset_password_token"
18
+ t.datetime "remember_created_at"
19
+ t.integer "sign_in_count", :default => 0
20
+ t.datetime "current_sign_in_at"
21
+ t.datetime "last_sign_in_at"
22
+ t.string "current_sign_in_ip"
23
+ t.string "last_sign_in_ip"
24
+ t.integer "failed_attempts", :default => 0
25
+ t.string "unlock_token"
26
+ t.datetime "locked_at"
27
+ t.string "authentication_token"
28
+ t.datetime "created_at"
29
+ t.datetime "updated_at"
30
+ end
31
+
32
+ create_table :delayed_jobs, :force => true do |table|
33
+ table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
34
+ table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
35
+ table.text :handler # YAML-encoded string of the object that will do work
36
+ table.text :last_error # reason for last failure (See Note below)
37
+ table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
38
+ table.datetime :locked_at # Set when a client is working on this object
39
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
40
+ table.string :locked_by # Who is working on this object (if locked)
41
+ table.string :queue # The name of the queue this job is in
42
+ table.timestamps
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ def valid_attributes(attributes={})
2
+ { :username => "usertest",
3
+ :email => generate_unique_email,
4
+ :password => '123456',
5
+ :password_confirmation => '123456' }.update(attributes)
6
+ end
7
+
8
+ def generate_unique_email
9
+ @@email_count ||= 0
10
+ @@email_count += 1
11
+ "test#{@@email_count}@example.com"
12
+ end
13
+
14
+ def new_user(attributes={})
15
+ User.new(valid_attributes(attributes))
16
+ end
17
+
18
+ def create_user(attributes={})
19
+ User.create!(valid_attributes(attributes))
20
+ end
@@ -0,0 +1,29 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require "minitest/autorun"
4
+ require "minitest/spec"
5
+ require "minitest/mock"
6
+ require "mocha"
7
+
8
+ require "devise_async"
9
+ require "rails/all"
10
+ require "devise"
11
+ require "resque"
12
+ require "sidekiq"
13
+ require "delayed_job_active_record"
14
+
15
+ require "support/helpers"
16
+
17
+ Devise.mailer = "DeviseAsync::Proxy"
18
+
19
+ module DeviseAsync
20
+ class RailsApp < ::Rails::Application
21
+ config.root = File.dirname(__FILE__) + "/support/app"
22
+ config.active_support.deprecation = :log
23
+ config.action_mailer.default_url_options = { :host => "localhost:3000" }
24
+ config.action_mailer.delivery_method = :test
25
+ end
26
+ end
27
+
28
+ DeviseAsync::RailsApp.initialize!
29
+ load File.dirname(__FILE__) + "/support/app/db/schema.rb"
@@ -0,0 +1,26 @@
1
+ require "test_helper"
2
+
3
+ module DeviseAsync
4
+ describe "Worker" do
5
+ it "enqueues job using the resque backend" do
6
+ DeviseAsync.backend = :resque
7
+
8
+ Backend::Resque.expects(:enqueue).with(:mailer_method, "User", 123)
9
+ Worker.enqueue(:mailer_method, "User", 123)
10
+ end
11
+
12
+ it "enqueues job using the sidekiq backend" do
13
+ DeviseAsync.backend = :sidekiq
14
+
15
+ Backend::Sidekiq.expects(:enqueue).with(:mailer_method, "User", 123)
16
+ Worker.enqueue(:mailer_method, "User", 123)
17
+ end
18
+
19
+ it "enqueues job using the delayed job backend" do
20
+ DeviseAsync.backend = :delayed_job
21
+
22
+ Backend::DelayedJob.expects(:enqueue).with(:mailer_method, "User", 123)
23
+ Worker.enqueue(:mailer_method, "User", 123)
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,256 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise-async
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marcelo Silveira
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: devise
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.2'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.2'
46
+ - !ruby/object:Gem::Dependency
47
+ name: actionpack
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '3.2'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ - !ruby/object:Gem::Dependency
63
+ name: actionmailer
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '3.2'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.2'
78
+ - !ruby/object:Gem::Dependency
79
+ name: mysql2
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.3'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.3'
94
+ - !ruby/object:Gem::Dependency
95
+ name: resque
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '1.20'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '1.20'
110
+ - !ruby/object:Gem::Dependency
111
+ name: sidekiq
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.2'
126
+ - !ruby/object:Gem::Dependency
127
+ name: delayed_job_active_record
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '0.3'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '0.3'
142
+ - !ruby/object:Gem::Dependency
143
+ name: mocha
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '0.11'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '0.11'
158
+ - !ruby/object:Gem::Dependency
159
+ name: minitest
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: '3.0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: '3.0'
174
+ description: Send Devise's emails in background. Supports Resque, Sidekiq and Delayed::Job.
175
+ email:
176
+ - marcelo@mhfs.com.br
177
+ executables: []
178
+ extensions: []
179
+ extra_rdoc_files: []
180
+ files:
181
+ - .gitignore
182
+ - Gemfile
183
+ - LICENSE
184
+ - README.md
185
+ - Rakefile
186
+ - devise-async.gemspec
187
+ - lib/devise-async.rb
188
+ - lib/devise_async.rb
189
+ - lib/devise_async/backend.rb
190
+ - lib/devise_async/backend/delayed_job.rb
191
+ - lib/devise_async/backend/resque.rb
192
+ - lib/devise_async/backend/sidekiq.rb
193
+ - lib/devise_async/proxy.rb
194
+ - lib/devise_async/version.rb
195
+ - lib/devise_async/worker.rb
196
+ - test/backend/delayed_job_test.rb
197
+ - test/backend/resque_test.rb
198
+ - test/backend/sidekiq_test.rb
199
+ - test/backend_test.rb
200
+ - test/proxy_test.rb
201
+ - test/support/app/app/models/user.rb
202
+ - test/support/app/config/database.yml
203
+ - test/support/app/config/initializers/devise.rb
204
+ - test/support/app/config/routes.rb
205
+ - test/support/app/db/schema.rb
206
+ - test/support/app/log/development.log
207
+ - test/support/helpers.rb
208
+ - test/test_helper.rb
209
+ - test/worker_test.rb
210
+ homepage: https://github.com/mhfs/devise-async/
211
+ licenses: []
212
+ post_install_message:
213
+ rdoc_options: []
214
+ require_paths:
215
+ - lib
216
+ required_ruby_version: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ segments:
223
+ - 0
224
+ hash: 375512970430548018
225
+ required_rubygems_version: !ruby/object:Gem::Requirement
226
+ none: false
227
+ requirements:
228
+ - - ! '>='
229
+ - !ruby/object:Gem::Version
230
+ version: '0'
231
+ segments:
232
+ - 0
233
+ hash: 375512970430548018
234
+ requirements: []
235
+ rubyforge_project:
236
+ rubygems_version: 1.8.23
237
+ signing_key:
238
+ specification_version: 3
239
+ summary: Devise Async provides an easy way to configure Devise to send its emails
240
+ asynchronously using your preferred queuing backend. It supports Resque, Sidekiq
241
+ and Delayed::Job.
242
+ test_files:
243
+ - test/backend/delayed_job_test.rb
244
+ - test/backend/resque_test.rb
245
+ - test/backend/sidekiq_test.rb
246
+ - test/backend_test.rb
247
+ - test/proxy_test.rb
248
+ - test/support/app/app/models/user.rb
249
+ - test/support/app/config/database.yml
250
+ - test/support/app/config/initializers/devise.rb
251
+ - test/support/app/config/routes.rb
252
+ - test/support/app/db/schema.rb
253
+ - test/support/app/log/development.log
254
+ - test/support/helpers.rb
255
+ - test/test_helper.rb
256
+ - test/worker_test.rb