Skip to content

Commit

Permalink
Resend (#53)
Browse files Browse the repository at this point in the history
* add resend_x_instructions! method

* make doc example different

* Bump to 1.0.2

* Bump to 1.1.0
  • Loading branch information
inveterateliterate authored Dec 18, 2017
1 parent a7b2206 commit 50efc15
Show file tree
Hide file tree
Showing 13 changed files with 1,256 additions and 22 deletions.
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

0 comments on commit 50efc15

Please sign in to comment.