has_token_on 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/MIT-LICENSE +20 -0
- data/README.md +125 -0
- data/Rakefile +20 -0
- data/has_token_on.gemspec +33 -0
- data/lib/generators/has_token_on/USAGE +2 -0
- data/lib/generators/has_token_on/config_generator.rb +36 -0
- data/lib/generators/has_token_on/templates/create_token.rb.erb +15 -0
- data/lib/has_token_on.rb +1 -0
- data/lib/has_token_on/models/active_record.rb +151 -0
- data/lib/has_token_on/rails.rb +16 -0
- data/lib/has_token_on/version.rb +3 -0
- data/rails/init.rb +1 -0
- data/spec/has_token_on/has_token_on_spec.rb +243 -0
- data/spec/spec_helper.rb +18 -0
- metadata +195 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Saulius Grigaliunas
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# HasTokenOn
|
2
|
+
|
3
|
+
Simple yet customizable token generator for Rails 3
|
4
|
+
|
5
|
+
# Features
|
6
|
+
|
7
|
+
* Any number of tokens per model
|
8
|
+
* Customizable length of each token
|
9
|
+
* Prepending/Appending to token
|
10
|
+
* Condition checking when setting the token
|
11
|
+
* Setting token on various callbacks namely initialization, creation, updating
|
12
|
+
* Customizable seed to generate token from
|
13
|
+
|
14
|
+
# Examples
|
15
|
+
|
16
|
+
## Initialization
|
17
|
+
|
18
|
+
* Single token
|
19
|
+
|
20
|
+
has_token_on :slug, :length => 3
|
21
|
+
|
22
|
+
* Multiple tokens, same configuration
|
23
|
+
|
24
|
+
has_token_on [:slug, :permalink], :length => 3
|
25
|
+
|
26
|
+
* Multiple tokens with individual configuration
|
27
|
+
|
28
|
+
has_token_on :slug, :length => 3
|
29
|
+
has_token_on :permalink, :length => 5
|
30
|
+
|
31
|
+
* .. or using single hash
|
32
|
+
|
33
|
+
has_token_on :slug => { :length => 3 }, :permalink => { :length => 5 }
|
34
|
+
|
35
|
+
## Options
|
36
|
+
|
37
|
+
Options are as follows:
|
38
|
+
|
39
|
+
* :length - token length. Default - 16.
|
40
|
+
|
41
|
+
has_token_on :slug, length => 3
|
42
|
+
|
43
|
+
* :prepend - prepend something to the beginning of the token. Default - none.
|
44
|
+
|
45
|
+
has_token_on :slug, :prepend => "private"
|
46
|
+
|
47
|
+
* :append - append something to the back of the token. Default - none.
|
48
|
+
|
49
|
+
has_token_on :slug, :append => "ending"
|
50
|
+
|
51
|
+
* :unique - ensure that tokens is unique (checking is performed in the app logic). Default - false.
|
52
|
+
|
53
|
+
has_token_on :slug, :unique => true
|
54
|
+
|
55
|
+
* :if - generate token only if provided condition is met. Default - none.
|
56
|
+
|
57
|
+
has_token_on :slug, :if => lambda { |record| record.private? }
|
58
|
+
|
59
|
+
* :on - generates token on certain time: :initialize, :create (default), :update.
|
60
|
+
|
61
|
+
has_token_on :slug, :on => :initialize
|
62
|
+
|
63
|
+
* :seed - elements or functions that are used to generate hash. Options:
|
64
|
+
* :securerandom - uses ActiveSupport::SecureRandom.hex (default)
|
65
|
+
|
66
|
+
has_token_on :slug, :seed => :securerandom
|
67
|
+
|
68
|
+
* :guid - uses simple_uuid gem. You should add it to your Gemfile. 36 characters long GUID. Length param is ignored.
|
69
|
+
|
70
|
+
has_token_on :slug, :seed => :guid
|
71
|
+
|
72
|
+
* ('a'..'z') - a Range. Mixes the range elements up to specified length.
|
73
|
+
|
74
|
+
has_token_on :slug, :seed => ('a'..'z')
|
75
|
+
|
76
|
+
* lambda { 2 * 2 } - a Proc. Executes proc. Length param is ignored.
|
77
|
+
|
78
|
+
has_token_on :slug, :seed => lambda { 2 * 2 }
|
79
|
+
|
80
|
+
## Generator
|
81
|
+
|
82
|
+
has_token_on comes with a generator that generates a migration for token.
|
83
|
+
|
84
|
+
Usage:
|
85
|
+
rails generate has_token_on:config MODEL NAME [options]
|
86
|
+
|
87
|
+
Options:
|
88
|
+
[--length=N] # Token length
|
89
|
+
[--create-on=CREATE_ON] # Create on: initialize, create, update
|
90
|
+
[--with-index] # Index the token field (default: es)
|
91
|
+
# Default: true
|
92
|
+
[--unique] # Is token unique?
|
93
|
+
# Default: true
|
94
|
+
|
95
|
+
Runtime options:
|
96
|
+
-f, [--force] # Overwrite files that already exist
|
97
|
+
-p, [--pretend] # Run but do not make any changes
|
98
|
+
-q, [--quiet] # Supress status output
|
99
|
+
-s, [--skip] # Skip files that already exist
|
100
|
+
|
101
|
+
Description:
|
102
|
+
Generates a migration that adds token field a model. Modifies model code.
|
103
|
+
|
104
|
+
Example:
|
105
|
+
rails g has_token_on:config paste token
|
106
|
+
|
107
|
+
# Testing
|
108
|
+
|
109
|
+
Tested on Mac OS X with Ruby 1.9.2 p180.
|
110
|
+
|
111
|
+
* Enter gem directory
|
112
|
+
* Execute
|
113
|
+
|
114
|
+
bundle
|
115
|
+
rake
|
116
|
+
|
117
|
+
You may use [guard](https://github.com/guard) for continuous testing
|
118
|
+
|
119
|
+
bundle exec guard
|
120
|
+
|
121
|
+
**NB** it will try to install some OSX specific gems like 'rb-fsevent'.
|
122
|
+
|
123
|
+
# License
|
124
|
+
|
125
|
+
Copyright (c) 2011 Saulius Grigaliunas, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :spec
|
13
|
+
|
14
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = 'HasTokenOn'
|
17
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
18
|
+
rdoc.rdoc_files.include('README')
|
19
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "has_token_on/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'has_token_on'
|
6
|
+
s.version = HasTokenOn::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Saulius Grigaliunas']
|
9
|
+
s.email = ['saulius@ninja.lt']
|
10
|
+
s.homepage = 'https://github.com/sauliusg/has_token_on'
|
11
|
+
s.summary = 'A token generator plugin for Rails 3'
|
12
|
+
s.description = 'Simple yet customizable token generator for Rails 3'
|
13
|
+
s.licenses = ['MIT']
|
14
|
+
s.rubyforge_project = 'has_token_on'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
18
|
+
s.extra_rdoc_files = ['README.md']
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
|
22
|
+
s.add_dependency 'rails', ['>= 3.0.0']
|
23
|
+
s.add_dependency 'simple_uuid'
|
24
|
+
s.add_development_dependency 'sqlite3', ['>= 0']
|
25
|
+
s.add_development_dependency 'rspec', ['>= 2.0.0']
|
26
|
+
s.add_development_dependency 'mocha', ['>= 0.9.8']
|
27
|
+
s.add_development_dependency 'with_model', ['>= 0.1.4']
|
28
|
+
s.add_development_dependency 'guard', ['>= 0.3.4']
|
29
|
+
s.add_development_dependency 'guard-rspec', ['>= 0']
|
30
|
+
s.add_development_dependency 'growl', ['>= 0']
|
31
|
+
s.add_development_dependency 'rb-fsevent', ['>= 0']
|
32
|
+
s.add_development_dependency 'ruby-debug19', ['>= 0']
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
require 'rails/generators/active_record/migration'
|
4
|
+
|
5
|
+
module HasTokenOn
|
6
|
+
class ConfigGenerator < ::Rails::Generators::Base
|
7
|
+
include ::Rails::Generators::Migration
|
8
|
+
extend ::ActiveRecord::Generators::Migration
|
9
|
+
|
10
|
+
source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
11
|
+
|
12
|
+
argument :model, :type => :string, :required => true, :desc => "Model to put token on to"
|
13
|
+
argument :name, :type => :string, :required => true, :desc => "Token name"
|
14
|
+
|
15
|
+
class_option :length, :type => :numeric, :desc => "Token length"
|
16
|
+
class_option :create_on, :type => :string, :desc => "Create on: initialize, create, update"
|
17
|
+
class_option :with_index, :type => :boolean, :default => true, :desc => "Index the token field (default: es)"
|
18
|
+
class_option :unique, :type => :boolean, :default => true, :desc => "Is token unique?"
|
19
|
+
|
20
|
+
desc <<DESC
|
21
|
+
Description:
|
22
|
+
Generates a migration that adds token field a model. Modifies model code.
|
23
|
+
|
24
|
+
Example:
|
25
|
+
rails g has_token_on:config paste token
|
26
|
+
DESC
|
27
|
+
|
28
|
+
def create_migration_file
|
29
|
+
migration_template "create_token.rb.erb",
|
30
|
+
"db/migrate/create_#{self.model}_#{self.name}.rb",
|
31
|
+
:assigns => { :model => self.model, :name => self.name }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Create<%=model.capitalize%><%=name.capitalize%> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :<%= model.pluralize %>, :<%= name %>, :string
|
4
|
+
<%- if options.with_index -%>
|
5
|
+
add_index :<%= model.pluralize %>, ["<%= name %>"], :name => "index_<%=model.pluralize%>_on_<%=name%>", :unique => <% if options.unique %>true<% else %>false<% end %>
|
6
|
+
<%- end -%>
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
<%- if options.with_index -%>
|
11
|
+
remove_index :<%= model.pluralize %>, ["<%= name %>"]
|
12
|
+
<%- end -%>
|
13
|
+
remove_column :<%= model.pluralize %>, :<%= name %>
|
14
|
+
end
|
15
|
+
end
|
data/lib/has_token_on.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "has_token_on/rails" if defined?(Rails)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
begin; require 'simple_uuid'; rescue LoadError; end
|
2
|
+
|
3
|
+
module HasTokenOn
|
4
|
+
|
5
|
+
class LibraryNotPresent < StandardError #:nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
module ActiveRecord
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
after_initialize { |record| create_tokens(record, :initialize) }
|
13
|
+
before_create { |record| create_tokens(record, :create) }
|
14
|
+
before_update { |record| create_tokens(record, :update) }
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
# = has_token_on
|
19
|
+
#
|
20
|
+
# Simple yet customizable token generator
|
21
|
+
#
|
22
|
+
# == Declaration
|
23
|
+
#
|
24
|
+
# Declare this in your model to generate token on specified attributes. Declaration can either be:
|
25
|
+
#
|
26
|
+
# For single token with configuration:
|
27
|
+
#
|
28
|
+
# has_token_on :slug, :length => 3
|
29
|
+
#
|
30
|
+
# For multiple tokens with same configuration:
|
31
|
+
#
|
32
|
+
# has_token_on [:slug, :permalink], :length => 3
|
33
|
+
#
|
34
|
+
# For multiple tokens with individual configurations:
|
35
|
+
#
|
36
|
+
# has_token_on :slug, :length => 3
|
37
|
+
# has_token_on :permalink, :length => 5
|
38
|
+
#
|
39
|
+
# Or using single hash:
|
40
|
+
#
|
41
|
+
# has_token_on :slug => { :length => 3 }, :permalink => { :length => 5 }
|
42
|
+
#
|
43
|
+
# == Options
|
44
|
+
#
|
45
|
+
# * :length - length of the token to generate
|
46
|
+
# * :prepend - prepend something to the token string
|
47
|
+
# * :append - append something to the token string
|
48
|
+
# * :unique - should the token be unique among other record's tokens
|
49
|
+
# * :if - sets the token only if Proc passed to this option returns true
|
50
|
+
# * :on - specify when to set the token, possible options are: :initialize, :create, :update
|
51
|
+
# * :seed - elements or functions used to generate hash. Possible options:
|
52
|
+
# * :securerandom (default) uses ActiveSupport::SecureRandom.hex
|
53
|
+
# * :guid uses simple_uuid gem (add it to your Gemfile!).
|
54
|
+
# Length is ignored in this case. GUIDs are 36 characters long.
|
55
|
+
# * ('a'..'z') a Range. Mixes the range elements up to specified length.
|
56
|
+
# * lambda { 2 * 2 } a Proc. Executes proc, length param is ignored in this case.
|
57
|
+
#
|
58
|
+
def has_token_on(*args)
|
59
|
+
@tokens ||= {}
|
60
|
+
|
61
|
+
case args.first
|
62
|
+
when String, Symbol
|
63
|
+
@tokens[args.first] = args.last
|
64
|
+
when Hash
|
65
|
+
args.first.each { |token, config|
|
66
|
+
@tokens[token] = config
|
67
|
+
}
|
68
|
+
when Array
|
69
|
+
args.first.each { |token|
|
70
|
+
@tokens[token] = args.last
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns Hash of tokens that are configured for specific class
|
76
|
+
def tokens
|
77
|
+
@tokens
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
module InstanceMethods
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def create_tokens(record, callback)
|
87
|
+
return unless any_tokens?
|
88
|
+
|
89
|
+
tokens_to_build_on(callback).each do |token, config|
|
90
|
+
if !config.has_key?(:if) or (config.has_key?(:if) and config[:if].call(record))
|
91
|
+
begin
|
92
|
+
self[token] = build_token(config)
|
93
|
+
end while (config.has_key?(:unique) and config[:unique]) and self.class.exists?(token => self[token])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def build_token(config)
|
99
|
+
defaults = { :length => 16, :prepend => "", :append => "", :seed => :securerandom }
|
100
|
+
config = defaults.merge(config)
|
101
|
+
|
102
|
+
return [config[:prepend],
|
103
|
+
build_from_seed(config),
|
104
|
+
config[:append]
|
105
|
+
].join
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_from_seed(config)
|
109
|
+
case config[:seed]
|
110
|
+
when Symbol
|
111
|
+
if config[:seed] == :securerandom
|
112
|
+
ActiveSupport::SecureRandom.hex(config[:length]).first(config[:length])
|
113
|
+
elsif config[:seed] == :guid
|
114
|
+
if simple_uuid_present?
|
115
|
+
::SimpleUUID::UUID.new.to_guid
|
116
|
+
else
|
117
|
+
raise LibraryNotPresent, "Supporting library SimpleUUID is not present. Add it to your Gemfile?"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
when Range
|
121
|
+
chars = config[:seed].to_a
|
122
|
+
(0...config[:length]).collect { chars[Kernel.rand(chars.length)] }.join
|
123
|
+
when Proc
|
124
|
+
config[:seed].call.to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def any_tokens?
|
129
|
+
self.class.tokens && self.class.tokens.any?
|
130
|
+
end
|
131
|
+
|
132
|
+
def tokens_to_build_on(callback)
|
133
|
+
self.class.tokens.select{ |token, config|
|
134
|
+
if config.has_key?(:on)
|
135
|
+
config[:on].include?(callback)
|
136
|
+
else
|
137
|
+
# if user didn't specify :on we set token before record create
|
138
|
+
callback == :create
|
139
|
+
end
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
def simple_uuid_present?
|
144
|
+
defined? ::SimpleUUID
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
::ActiveRecord::Base.send :include, HasTokenOn::ActiveRecord
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module HasTokenOn
|
4
|
+
class Engine < ::Rails::Engine #:nodoc:
|
5
|
+
|
6
|
+
generators do
|
7
|
+
require "generators/has_token_on/config_generator"
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer :load_models do
|
11
|
+
::ActiveSupport.on_load(:active_record) do
|
12
|
+
require File.join(File.dirname(__FILE__), 'models/active_record')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'has_token_on'
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
|
+
require 'pp'
|
3
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
4
|
+
|
5
|
+
describe HasTokenOn::ActiveRecord, "instantiation" do
|
6
|
+
subject { Post }
|
7
|
+
|
8
|
+
with_model :post do
|
9
|
+
table do |t|
|
10
|
+
t.string "permalink"
|
11
|
+
end
|
12
|
+
|
13
|
+
model do
|
14
|
+
has_token_on :permalink, { :length => 3 }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
its('tokens.size') { should == 1 }
|
19
|
+
its('tokens') { should include(:permalink) }
|
20
|
+
|
21
|
+
it "should provide access to set tokens" do
|
22
|
+
subject.tokens.size.should == 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return set tokens" do
|
26
|
+
subject.tokens.first.should == [ :permalink, { :length => 3 } ]
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when instantiating" do
|
30
|
+
|
31
|
+
it "should allow to set multiple tokens when multiple calls" do
|
32
|
+
subject.class_eval do
|
33
|
+
has_token_on :tkn
|
34
|
+
end
|
35
|
+
|
36
|
+
subject.tokens.size.should == 2
|
37
|
+
subject.tokens.keys == [:permalink, :tkn]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should allow to set multiple tokens with hash syntax" do
|
41
|
+
subject.class_eval do
|
42
|
+
has_token_on :tkn1 => { :length => 3 }, :tkn2 => { :length => 4 }
|
43
|
+
end
|
44
|
+
|
45
|
+
subject.tokens.size.should == 4
|
46
|
+
subject.tokens.keys.should == [:permalink, :tkn, :tkn1, :tkn2]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should allow to set multiple tokens with array syntax (same configuration for all)" do
|
50
|
+
subject.class_eval do
|
51
|
+
has_token_on [:tkn3, :tkn4], { :length => 10 }
|
52
|
+
end
|
53
|
+
|
54
|
+
subject.tokens.size.should == 6
|
55
|
+
subject.tokens.keys.should include(:tkn3, :tkn4)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe HasTokenOn::ActiveRecord, "callbacks" do
|
62
|
+
subject { Post.new }
|
63
|
+
|
64
|
+
with_model :post do
|
65
|
+
table do |t|
|
66
|
+
t.string "permalink_init"
|
67
|
+
t.string "permalink_create"
|
68
|
+
t.string "permalink_update"
|
69
|
+
t.string "permalink_none"
|
70
|
+
end
|
71
|
+
|
72
|
+
model do
|
73
|
+
has_token_on :permalink_init, { :length => 3, :on => [:initialize] }
|
74
|
+
has_token_on :permalink_create, { :length => 3, :on => [:create] }
|
75
|
+
has_token_on :permalink_update, { :length => 3, :on => [:update] }
|
76
|
+
has_token_on :permalink_none, { :length => 3 }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should set token on initialize if specified" do
|
81
|
+
subject.permalink_init.should_not be_nil
|
82
|
+
subject.permalink_create.should be_nil
|
83
|
+
subject.permalink_update.should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set token on create if specified" do
|
87
|
+
subject.save
|
88
|
+
subject.permalink_init.should_not be_nil
|
89
|
+
subject.permalink_create.should_not be_nil
|
90
|
+
subject.permalink_update.should be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should set token on update if specified" do
|
94
|
+
subject.save
|
95
|
+
subject.update_attribute(:permalink_init, "sup yo")
|
96
|
+
subject.permalink_init.should_not be_nil
|
97
|
+
subject.permalink_create.should_not be_nil
|
98
|
+
subject.permalink_update.should_not be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should generate token before create if configuration doesnt specify :on scope" do
|
102
|
+
subject.save
|
103
|
+
subject.update_attribute(:permalink_init, "sup yo")
|
104
|
+
subject.permalink_none.should_not be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe HasTokenOn::ActiveRecord do
|
109
|
+
subject { Post.new }
|
110
|
+
|
111
|
+
with_model :post do
|
112
|
+
table do |t|
|
113
|
+
t.string "permalink"
|
114
|
+
t.string "test"
|
115
|
+
t.string "str"
|
116
|
+
t.string "sixteen"
|
117
|
+
t.string "proc_seed"
|
118
|
+
t.string "range_seed"
|
119
|
+
t.string "guid_seed"
|
120
|
+
t.boolean :check, :default => true
|
121
|
+
end
|
122
|
+
|
123
|
+
model do
|
124
|
+
has_token_on :permalink => {
|
125
|
+
:length => 4,
|
126
|
+
:if => lambda {|r| r.check },
|
127
|
+
:prepend => "foo",
|
128
|
+
:append => "bar",
|
129
|
+
:on => [:initialize]
|
130
|
+
},
|
131
|
+
:test => {
|
132
|
+
:length => 4,
|
133
|
+
:prepend => "foo",
|
134
|
+
:seed => :simplerandom,
|
135
|
+
:append => "bar",
|
136
|
+
:on => [:initialize]
|
137
|
+
},
|
138
|
+
:str => {
|
139
|
+
:length => 4,
|
140
|
+
:seed => ('a'..'z'),
|
141
|
+
:if => lambda {|r| !r.check },
|
142
|
+
:on => [:initialize]
|
143
|
+
},
|
144
|
+
:sixteen => {
|
145
|
+
:on => [:initialize]
|
146
|
+
},
|
147
|
+
:proc_seed => {
|
148
|
+
:seed => lambda { 2 * 2 },
|
149
|
+
:on => [:initialize]
|
150
|
+
},
|
151
|
+
:range_seed => {
|
152
|
+
:seed => ('a'..'z'),
|
153
|
+
:on => [:initialize]
|
154
|
+
},
|
155
|
+
:guid_seed => {
|
156
|
+
:seed => :guid,
|
157
|
+
:on => [:create]
|
158
|
+
}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when setting the token" do
|
163
|
+
|
164
|
+
it "should not be nil if :if executes succcessfully" do
|
165
|
+
subject.permalink.should_not be_nil
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should be nil if :if executes with false return" do
|
169
|
+
subject.str.should be_nil
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should be of given length (with prepended and appended parts)" do
|
173
|
+
subject.permalink.size.should == 10 # foo****bar
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should default length to 16 symbols if not provided" do
|
177
|
+
subject.sixteen.length.should == 16
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should prepend string if asked" do
|
181
|
+
subject.permalink.should =~ /^foo/
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should append string if asked" do
|
185
|
+
subject.permalink.should =~ /bar$/
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should generate GUID using SimpleUUID if it is available" do
|
189
|
+
subject.save
|
190
|
+
subject.guid_seed.should =~ /[a-z0-9]/
|
191
|
+
subject.guid_seed.size.should == 36
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should raise an error if SimpleUUID is not available" do
|
195
|
+
p = Post.new
|
196
|
+
p.stubs(:simple_uuid_present?).returns(false)
|
197
|
+
lambda { p.save }.should raise_error
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should allow :seed to be described as proc" do
|
201
|
+
subject.proc_seed.should == "4"
|
202
|
+
subject.proc_seed.size.should == 1
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should allow :seed to be described as range" do
|
206
|
+
subject.range_seed.should =~ /[a-z]/
|
207
|
+
subject.range_seed.size.should == 16
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
describe HasTokenOn::ActiveRecord do
|
215
|
+
subject { Post.new }
|
216
|
+
|
217
|
+
with_model :post do
|
218
|
+
table do |t|
|
219
|
+
t.string "permalink"
|
220
|
+
end
|
221
|
+
|
222
|
+
model do
|
223
|
+
has_token_on :permalink, {
|
224
|
+
:length => 5,
|
225
|
+
:unique => true,
|
226
|
+
:prepend => "foo",
|
227
|
+
:append => "bar",
|
228
|
+
:on => [:create]
|
229
|
+
}
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should generate unique token if requested" do
|
234
|
+
somepost = Post.new
|
235
|
+
somepost.stubs(:build_token).returns('hi')
|
236
|
+
somepost.save
|
237
|
+
subject.expects(:build_token).times(3).returns('hi').then.returns('unique')
|
238
|
+
Post.expects(:exists?).twice # on first time we'll find unique
|
239
|
+
subject.save
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'active_support/all'
|
6
|
+
require 'active_record'
|
7
|
+
require 'with_model'
|
8
|
+
require 'mocha'
|
9
|
+
|
10
|
+
require 'has_token_on'
|
11
|
+
require 'has_token_on/models/active_record'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.filter_run :focus => true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.extend WithModel
|
17
|
+
end
|
18
|
+
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_token_on
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Saulius Grigaliunas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-21 00:00:00 +03:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rails
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.0.0
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: simple_uuid
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: sqlite3
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 2.0.0
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mocha
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.8
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: with_model
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.1.4
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: guard
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.3.4
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: guard-rspec
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id008
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: growl
|
106
|
+
prerelease: false
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "0"
|
113
|
+
type: :development
|
114
|
+
version_requirements: *id009
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: rb-fsevent
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: "0"
|
124
|
+
type: :development
|
125
|
+
version_requirements: *id010
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: ruby-debug19
|
128
|
+
prerelease: false
|
129
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: "0"
|
135
|
+
type: :development
|
136
|
+
version_requirements: *id011
|
137
|
+
description: Simple yet customizable token generator for Rails 3
|
138
|
+
email:
|
139
|
+
- saulius@ninja.lt
|
140
|
+
executables: []
|
141
|
+
|
142
|
+
extensions: []
|
143
|
+
|
144
|
+
extra_rdoc_files:
|
145
|
+
- README.md
|
146
|
+
files:
|
147
|
+
- .gitignore
|
148
|
+
- .rspec
|
149
|
+
- .rvmrc
|
150
|
+
- Gemfile
|
151
|
+
- Guardfile
|
152
|
+
- MIT-LICENSE
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- has_token_on.gemspec
|
156
|
+
- lib/generators/has_token_on/USAGE
|
157
|
+
- lib/generators/has_token_on/config_generator.rb
|
158
|
+
- lib/generators/has_token_on/templates/create_token.rb.erb
|
159
|
+
- lib/has_token_on.rb
|
160
|
+
- lib/has_token_on/models/active_record.rb
|
161
|
+
- lib/has_token_on/rails.rb
|
162
|
+
- lib/has_token_on/version.rb
|
163
|
+
- rails/init.rb
|
164
|
+
- spec/has_token_on/has_token_on_spec.rb
|
165
|
+
- spec/spec_helper.rb
|
166
|
+
has_rdoc: true
|
167
|
+
homepage: https://github.com/sauliusg/has_token_on
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
post_install_message:
|
171
|
+
rdoc_options: []
|
172
|
+
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: "0"
|
181
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: "0"
|
187
|
+
requirements: []
|
188
|
+
|
189
|
+
rubyforge_project: has_token_on
|
190
|
+
rubygems_version: 1.6.1
|
191
|
+
signing_key:
|
192
|
+
specification_version: 3
|
193
|
+
summary: A token generator plugin for Rails 3
|
194
|
+
test_files: []
|
195
|
+
|