Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resend #53

Merged
merged 5 commits into from
Dec 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,166 changes: 1,166 additions & 0 deletions .rubocop.yml

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ class UsersController < ApplicationController
end
end

def resend_confirmation_instructions

# if you have a 'resend instructions?' flow you can generate a new token and send instructions again in one step
user.resend_confirm_instructions! do
# Sending the email is up to you, by passing a block here:
UserMailer.send_confirm(user) # or some other logic
end
end

end
```

Expand Down Expand Up @@ -176,13 +185,14 @@ include TokenMaster::Model
```
This adds the `token_master` class method we used above, and you can make the same calls we described in the `confirm` example above.

2. When you call the `token_master` class method, for each *tokenable action* you provide, five methods are added to the class for each *tokenable action*, and named accordingly.
2. When you call the `token_master` class method, for each *tokenable action* you provide, a handful of methods are added to the class for each *tokenable action*, and named accordingly.

Assuming the *tokenable action* below is `confirm`, the methods would look like this:

Instance methods
* `set_confirm_token!`
* `send_confirm_instructions!`
* `resend_confirm_instructions!`
* `confirm_status`
* `force_confirm!`

Expand Down
14 changes: 14 additions & 0 deletions lib/token_master/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ def send_instructions!(model, key)
model.save(validate: false)
end

# Calls set_token! and send_instructions! to generate a new token and send instructions again (accepts a block, such as a mailer method, for sending instructions).<br />Note, any previously generated token for the user will be invalid.
# @example Resend Reset Instructions
# user.resend_reset_instruction! { user.send_email } =>
# <User id: 205, name: "John Smith", email: "[email protected]", reset_token: "4ZcHkSJ8kXrV4wl", reset_created_at: 2017-04-25 16:21:54", reset_sent_at: "2017-04-25 16:22:42", reset_completed_at: nil>
# @param [Object] model the tokenable model instance
# @param [String, Symbol] key the tokenable action
# @param [Integer] token_length the length of the generated token, method will use configuration token_length if not provided otherwise
# @raise [NotTokenableError] if the provided Class does not have the correct tokenable column
# @return [Object] tokenable model instance
def resend_instructions!(model, key, token_length = nil)
set_token!(model, key, token_length)
send_instructions!(model, key)
end

# Provides the status of the tokenable action, whether the action has been completed, the token has been sent, the token is expired, or the token has only been created
# @param [Object] model the tokenable model instance
# @param [String, Symbol] key the tokenable action
Expand Down
7 changes: 6 additions & 1 deletion lib/token_master/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ def token_master(*tokenables)
TokenMaster::Core.send_instructions!(self, tokenable, &email)
end

# Defines a method on the tokenable model instance to generate a new token and send tokenable action instructions again, e.g., `user.resend_confim_instructions!`. Accepts a block with app logic to send instructions.
define_method("resend_#{tokenable}_instructions!") do |&email|
TokenMaster::Core.resend_instructions!(self, tokenable, &email)
end

# Defines a method on the tokenable model instance to retrieve the status of a tokenable action, e.g., `user.confim_status`
define_method("#{tokenable}_status") do
TokenMaster::Core.status(self, tokenable)
Expand All @@ -35,7 +40,7 @@ def token_master(*tokenables)
end
# class methods

# Defines a method on the tokenable model class to completed a tokenable action given a token, e.g., `User.confim_by_token!`. Takes the token and accepts any keyword arguments for `required_params`.
# Defines a method on the tokenable model class to complete a tokenable action given a token, e.g., `User.confim_by_token!`. Takes the token and accepts any keyword arguments for `required_params`.
define_singleton_method("#{tokenable}_by_token!") do |token, **params|
TokenMaster::Core.do_by_token!(self, tokenable, token, **params)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/token_master/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module TokenMaster
# Current version of TokenMaster
VERSION = '1.0.1'.freeze
VERSION = '1.1.0'.freeze
end
12 changes: 5 additions & 7 deletions test/dummy/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@ git_source(:github) do |repo_name|
"https://github.com/#{repo_name}.git"
end

gem 'rails', '~> 5.0.2'
gem 'bcrypt', '~> 3.1.7'
gem 'factory_bot_rails'
gem 'faker'
gem 'pg', '~> 0.18'
# gem 'puma', '~> 3.0'
gem 'bcrypt', '~> 3.1.7'
gem 'rails', '~> 5.0.2'
gem 'token_master', path: './../..'
gem 'faker'
gem 'pry'
gem 'factory_girl_rails'

group :development, :test do
gem 'byebug', platform: :mri
gem 'pry'
gem 'rspec-rails'
end

group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen'
# gem 'spring'
# gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
Expand Down
12 changes: 6 additions & 6 deletions test/dummy/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ../..
specs:
token_master (0.1.3)
token_master (1.0.1)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -52,10 +52,10 @@ GEM
debug_inspector (0.0.2)
diff-lcs (1.3)
erubis (2.7.0)
factory_girl (4.8.0)
factory_bot (4.8.2)
activesupport (>= 3.0.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
factory_bot_rails (4.8.2)
factory_bot (~> 4.8.2)
railties (>= 3.0.0)
faker (1.7.2)
i18n (~> 0.5)
Expand Down Expand Up @@ -162,7 +162,7 @@ PLATFORMS
DEPENDENCIES
bcrypt (~> 3.1.7)
byebug
factory_girl_rails
factory_bot_rails
faker
listen
pg (~> 0.18)
Expand All @@ -175,4 +175,4 @@ DEPENDENCIES
web-console (>= 3.3.0)

BUNDLED WITH
1.14.5
1.15.1
6 changes: 3 additions & 3 deletions test/dummy/spec/factories/users.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FactoryGirl.define do
FactoryBot.define do
factory :user do
sequence(:email) { |n| "user_#{n}@example.com"}
password "password"
password_confirmation "password"
password 'password'
password_confirmation 'password'
name { Faker::Name.name }
end
end
2 changes: 2 additions & 0 deletions test/dummy/spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
config.include Shoulda::Matchers
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"

Expand Down
3 changes: 3 additions & 0 deletions test/dummy/spec/support/factory_bot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
3 changes: 0 additions & 3 deletions test/dummy/spec/support/factory_girl.rb

This file was deleted.

33 changes: 33 additions & 0 deletions test/test_core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,39 @@ def present?
end
end

describe '#resend_instructions!' do
describe 'when not manageable' do
it 'raises' do
assert_raises TokenMaster::Errors::NotTokenable do
TM.resend_instructions!(MockActiveRecord.new, 'confirm')
end
end
end

describe 'when manageable' do
before do
@model = MockTokenMaster.new
TM.set_token! @model, 'confirm'
TM.send_instructions! @model, 'confirm'
@old_token = @model.confirm_token
@old_sent_at = @model.confirm_sent_at
TM.resend_instructions! @model, 'confirm'
end

describe 'generates new token' do
it 'sets new token' do
refute_equal @model.confirm_token, @old_token
end
end

describe 'sends new instructions' do
it 'resets sent_at time' do
refute_equal @model.confirm_sent_at, @old_sent_at
end
end
end
end

describe '#force_tokenable!' do
describe 'when not manageable' do
it 'raises' do
Expand Down
6 changes: 6 additions & 0 deletions test/test_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
end
end

it '#resend_instructions!' do
TokenMaster::Core.stub :resend_instructions!, :foo do
assert_equal @tokenable_model.resend_confirm_instructions! {'foo'}, :foo
end
end

it '#status' do
TokenMaster::Core.stub :status, :foo do
assert_equal @tokenable_model.confirm_status, :foo
Expand Down