activable 0.1.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.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +102 -0
- data/Rakefile +1 -0
- data/activable.gemspec +22 -0
- data/lib/activable/active_record.rb +3 -0
- data/lib/activable/version.rb +3 -0
- data/lib/activable.rb +83 -0
- data/lib/generators/activable/activable_generator.rb +42 -0
- data/lib/generators/activable/install_generator.rb +13 -0
- data/lib/generators/templates/activable.rb +14 -0
- data/lib/generators/templates/migration.rb +8 -0
- data/spec/activable_spec.rb +12 -0
- data/spec/factories/categories.rb +5 -0
- data/spec/factories/users.rb +9 -0
- data/spec/generators/activable_generator_spec.rb +57 -0
- data/spec/generators/install_generator_spec.rb +16 -0
- data/spec/has_no_responsible_spec.rb +41 -0
- data/spec/has_responsible_spec.rb +54 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/test_app/.gitignore +2 -0
- data/spec/test_app/Rakefile +7 -0
- data/spec/test_app/app/controllers/application_controller.rb +3 -0
- data/spec/test_app/app/helpers/application_helper.rb +2 -0
- data/spec/test_app/app/models/.gitkeep +0 -0
- data/spec/test_app/app/models/category.rb +4 -0
- data/spec/test_app/app/models/product.rb +3 -0
- data/spec/test_app/app/models/user.rb +4 -0
- data/spec/test_app/app/views/layouts/application.html.erb +14 -0
- data/spec/test_app/config/application.rb +62 -0
- data/spec/test_app/config/boot.rb +6 -0
- data/spec/test_app/config/database.yml +19 -0
- data/spec/test_app/config/environment.rb +5 -0
- data/spec/test_app/config/environments/development.rb +37 -0
- data/spec/test_app/config/environments/production.rb +67 -0
- data/spec/test_app/config/environments/test.rb +37 -0
- data/spec/test_app/config/initializers/activable.rb +14 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/inflections.rb +15 -0
- data/spec/test_app/config/initializers/mime_types.rb +5 -0
- data/spec/test_app/config/initializers/secret_token.rb +7 -0
- data/spec/test_app/config/initializers/session_store.rb +8 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/routes.rb +58 -0
- data/spec/test_app/config.ru +4 -0
- data/spec/test_app/db/migrate/20130402122537_create_users.rb +9 -0
- data/spec/test_app/db/migrate/20130403123944_create_products.rb +9 -0
- data/spec/test_app/db/migrate/20130403135220_add_activable_to_users.rb +9 -0
- data/spec/test_app/db/migrate/20130403185451_create_categories.rb +9 -0
- data/spec/test_app/db/migrate/20130403190146_add_activable_to_categories.rb +8 -0
- data/spec/test_app/db/schema.rb +43 -0
- data/spec/test_app/db/seeds.rb +7 -0
- data/spec/test_app/lib/assets/.gitkeep +0 -0
- data/spec/test_app/lib/tasks/.gitkeep +0 -0
- data/spec/test_app/log/.gitkeep +0 -0
- data/spec/test_app/log/development.log +18 -0
- data/spec/test_app/log/test.log +1576 -0
- data/spec/test_app/public/404.html +26 -0
- data/spec/test_app/public/422.html +26 -0
- data/spec/test_app/public/500.html +25 -0
- data/spec/test_app/public/favicon.ico +0 -0
- data/spec/test_app/public/index.html +241 -0
- data/spec/test_app/public/robots.txt +5 -0
- data/spec/test_app/script/rails +6 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjEzNzhkOGE4NTU3ODVjMzY2ZDEyZTBkMzQ1ZmNiOTcxZjllYjhkMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjE2NDRhODIyODRiYjRmNDcwMzljYjQxZjg3NGI3ZjEyNDQ1ZjAzMA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDI2NmIzNDMwZTU4YzIwYzE3ZmRjMGFmMGIzYWRlZTFlMTdjNGFkNDQ5OTRl
|
10
|
+
MDcyM2FlZmQ1YWM2NjA5ODZiY2MxZGIxM2VjZGNiNjNhMjk0N2JhNzg1Y2Zi
|
11
|
+
OTZlZjU4MDhmZjZmNTBiM2YyNTIzOTQ1OTNhYjk3YmE2YmIyNzM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
N2VjZmExMjgxNWJlOTg1NDQxMjZmNWQwZWMwZjI0ZTBjMjdkMDk2ZGQyOTUy
|
14
|
+
YTU5ZDE5ZDZiNzEwYTdiYTliYjVmOTNhNDJjNTkzOTQ0NGYyYTY3MDE1ZDBi
|
15
|
+
YzBiYTE1ZTlkZjQ0ZTk1ZTY3ZDQ4ZDdkYTBhODFmNmY1NzYxYzc=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Diego Selzlein
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Activable
|
2
|
+
|
3
|
+
This gem allows a model to be activated or deactivated, saving informations like
|
4
|
+
'activated_at', 'deactivated_at', 'activated_by' and 'deactivated_by'.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'activable', git: 'git://github.com/nerde/activable.git'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Create the initializer file:
|
21
|
+
|
22
|
+
$ rails g activable:install
|
23
|
+
|
24
|
+
Configure the models you want to be "activable". They need to be created first:
|
25
|
+
|
26
|
+
$ rails g model product description
|
27
|
+
$ rails g activable product
|
28
|
+
$ rake db:migrate
|
29
|
+
|
30
|
+
Your models will look like this:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class Product < ActiveRecord::Base
|
34
|
+
is_activable
|
35
|
+
# ...
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Optionally, you can customize each model to have a differente configuration from
|
40
|
+
the on in the initializer file:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
class Product < ActiveRecord::Base
|
44
|
+
is_activable has_responsible: false
|
45
|
+
# ...
|
46
|
+
end
|
47
|
+
|
48
|
+
class Category < ActiveRecord::Base
|
49
|
+
is_activable responsible: "Admin"
|
50
|
+
# ...
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Working with it
|
55
|
+
|
56
|
+
By default, new objects of a "activable" model are active:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
p = Product.new
|
60
|
+
p.active? # => true
|
61
|
+
```
|
62
|
+
|
63
|
+
If your model has a responsible, you **must** provide it before saving your object:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
p = Product.new
|
67
|
+
p.save # will not work, it will say that activated_by_id is required
|
68
|
+
|
69
|
+
# You need to do something like this
|
70
|
+
p = Product.new
|
71
|
+
p.activate responsible: current_user
|
72
|
+
```
|
73
|
+
|
74
|
+
The same rule applies when deactivating an object:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
product.deactivate responsible: current_user
|
78
|
+
```
|
79
|
+
|
80
|
+
You can check whether it is active or not whenever you want by calling the method
|
81
|
+
`active?`. Another useful informations are stored and you can see them:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
product.activated_at
|
85
|
+
product.deactivated_at
|
86
|
+
|
87
|
+
# And if it has a responsible:
|
88
|
+
product.activated_by # if has responsible
|
89
|
+
product.deactivated_by # if has responsible
|
90
|
+
```
|
91
|
+
|
92
|
+
## Testing the gem
|
93
|
+
|
94
|
+
rspec spec
|
95
|
+
|
96
|
+
## Contributing
|
97
|
+
|
98
|
+
1. Fork it
|
99
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
100
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
101
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
102
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/activable.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'activable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "activable"
|
8
|
+
spec.version = Activable::VERSION
|
9
|
+
spec.authors = ["Diego Selzlein"]
|
10
|
+
spec.email = ["diegoselzlein@gmail.com"]
|
11
|
+
spec.description = %q{Allows a model to be activated and deactivated}
|
12
|
+
spec.summary = %q{Allows a model to be activated and deactivated}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
end
|
data/lib/activable.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require "activable/version"
|
3
|
+
require 'active_support/dependencies'
|
4
|
+
|
5
|
+
module Activable
|
6
|
+
mattr_accessor :configuration
|
7
|
+
@@configuration = {has_responsible: true, responsible: "User"}
|
8
|
+
|
9
|
+
def self.set(options={})
|
10
|
+
@@configuration.merge! options
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.setup
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
|
17
|
+
module Methods
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
def init_active
|
21
|
+
self.activated_at = Time.now
|
22
|
+
end
|
23
|
+
|
24
|
+
def active?
|
25
|
+
return true unless self.activated_at && self.deactivated_at
|
26
|
+
self.activated_at > self.deactivated_at
|
27
|
+
end
|
28
|
+
|
29
|
+
def activate(options={})
|
30
|
+
verify_responsible(options)
|
31
|
+
self.activated_at = Time.now
|
32
|
+
self.activated_by = options[:responsible] if self.activable_config[:has_responsible]
|
33
|
+
end
|
34
|
+
|
35
|
+
def deactivate(options={})
|
36
|
+
verify_responsible(options)
|
37
|
+
self.deactivated_at = Time.now
|
38
|
+
self.deactivated_by = options[:responsible] if self.activable_config[:has_responsible]
|
39
|
+
end
|
40
|
+
|
41
|
+
def activate!(options={})
|
42
|
+
activate(options)
|
43
|
+
save
|
44
|
+
end
|
45
|
+
|
46
|
+
def deactivate!(options={})
|
47
|
+
deactivate(options)
|
48
|
+
save
|
49
|
+
end
|
50
|
+
|
51
|
+
included do
|
52
|
+
after_initialize :init_active
|
53
|
+
validates_presence_of :activated_at
|
54
|
+
if self.activable_config[:has_responsible]
|
55
|
+
belongs_to :activated_by, :class_name => self.activable_config[:responsible]
|
56
|
+
belongs_to :deactivated_by, :class_name => self.activable_config[:responsible]
|
57
|
+
validates_presence_of :activated_by_id, if: :active?
|
58
|
+
validates_presence_of :deactivated_by_id, unless: :active?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
def verify_responsible(options)
|
65
|
+
if self.activable_config[:has_responsible]
|
66
|
+
resp = options && options[:responsible]
|
67
|
+
if !resp
|
68
|
+
raise "You must provide a responsible to activate a " + self.class.name
|
69
|
+
elsif resp.class.name != self.activable_config[:responsible]
|
70
|
+
raise "Object of type #{resp.class.name} is not a " + self.activable_config[:responsible]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module Models
|
77
|
+
def is_activable(options = {})
|
78
|
+
cattr_accessor :activable_config
|
79
|
+
self.activable_config = Activable.configuration.merge options
|
80
|
+
include Activable::Methods
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module Activable
|
4
|
+
module Generators
|
5
|
+
class ActivableGenerator < ActiveRecord::Generators::Base
|
6
|
+
source_root File.expand_path("../../templates", __FILE__)
|
7
|
+
|
8
|
+
desc "Creates a migration to add the activable fields."
|
9
|
+
def copy_migration
|
10
|
+
klass = model_class
|
11
|
+
raise "The model #{class_name.camelize} does not exists!" unless klass && klass.table_name
|
12
|
+
migration_template "migration.rb", "#{migration_path}/add_activable_to_#{table_name}.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Adds activable fields to an existing model."
|
16
|
+
def inject_activable_content
|
17
|
+
content = <<CONTENT
|
18
|
+
is_activable
|
19
|
+
CONTENT
|
20
|
+
inject_into_class(model_path, model_class, content) if model_exists?
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def model_exists?
|
26
|
+
File.exists?(File.join(destination_root, model_path))
|
27
|
+
end
|
28
|
+
|
29
|
+
def model_path
|
30
|
+
File.join("app", "models", "#{class_name.downcase.singularize}.rb")
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_class
|
34
|
+
Object::const_get(class_name.singularize.camelize)
|
35
|
+
end
|
36
|
+
|
37
|
+
def migration_path
|
38
|
+
File.join("db", "migrate")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Activable
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
desc "Creates an Activable initializer."
|
7
|
+
|
8
|
+
def copy_initializer
|
9
|
+
template "activable.rb", "config/initializers/activable.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Use this hook to configure Activable gem.
|
2
|
+
Activable.setup do |config|
|
3
|
+
|
4
|
+
# Load the methods for ActiveRecord
|
5
|
+
require 'activable/active_record'
|
6
|
+
|
7
|
+
# Set here if your models have a responsible when they are either activated or
|
8
|
+
# deactivated.
|
9
|
+
config.set(has_responsible: true)
|
10
|
+
|
11
|
+
# Configure here who is the responsible for activating or deactivating your
|
12
|
+
# models. It has to be a class that extends ActiveRecord::Base.
|
13
|
+
config.set(responsible: "User")
|
14
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class AddActivableTo<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
add_column :<%= table_name %>, :activated_at, :datetime
|
4
|
+
add_column :<%= table_name %>, :deactivated_at, :datetime
|
5
|
+
add_column :<%= table_name %>, :activated_by_id, :integer
|
6
|
+
add_column :<%= table_name %>, :deactivated_by_id, :integer
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Activable do
|
4
|
+
it "can be configured" do
|
5
|
+
Activable.setup do |config|
|
6
|
+
config.set has_responsible: false
|
7
|
+
config.set responsible: "Atest"
|
8
|
+
end
|
9
|
+
Activable.configuration[:has_responsible].should eql(false)
|
10
|
+
Activable.configuration[:responsible].should eql("Atest")
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'generators/activable/activable_generator'
|
3
|
+
|
4
|
+
describe Activable::Generators::ActivableGenerator do
|
5
|
+
include GeneratorSpec::TestCase
|
6
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
7
|
+
arguments %w(product)
|
8
|
+
|
9
|
+
before do
|
10
|
+
Activable.setup do |config|
|
11
|
+
config.set(has_responsible: true)
|
12
|
+
config.set(responsible: "Responsible")
|
13
|
+
end
|
14
|
+
prepare_destination
|
15
|
+
copy_model
|
16
|
+
run_generator
|
17
|
+
end
|
18
|
+
|
19
|
+
it "adds is_activable to the model" do
|
20
|
+
assert_file 'app/models/product.rb', model_content
|
21
|
+
end
|
22
|
+
|
23
|
+
it "creates a migration file" do
|
24
|
+
assert_migration "db/migrate/add_activable_to_products.rb", migration_content
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def copy_model
|
30
|
+
dest = File.join('tmp','app','models')
|
31
|
+
FileUtils.mkdir_p dest
|
32
|
+
FileUtils.cp(File.join('spec','test_app','app','models','product.rb'),
|
33
|
+
File.join(dest,'product.rb'))
|
34
|
+
end
|
35
|
+
|
36
|
+
def migration_content
|
37
|
+
<<RUBY
|
38
|
+
class AddActivableToProducts < ActiveRecord::Migration
|
39
|
+
def change
|
40
|
+
add_column :products, :activated_at, :datetime
|
41
|
+
add_column :products, :deactivated_at, :datetime
|
42
|
+
add_column :products, :activated_by_id, :integer
|
43
|
+
add_column :products, :deactivated_by_id, :integer
|
44
|
+
end
|
45
|
+
end
|
46
|
+
RUBY
|
47
|
+
end
|
48
|
+
|
49
|
+
def model_content
|
50
|
+
<<RUBY
|
51
|
+
class Product < ActiveRecord::Base
|
52
|
+
is_activable
|
53
|
+
attr_accessible :name
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'generators/activable/install_generator'
|
3
|
+
|
4
|
+
describe Activable::Generators::InstallGenerator do
|
5
|
+
include GeneratorSpec::TestCase
|
6
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
prepare_destination
|
10
|
+
run_generator
|
11
|
+
end
|
12
|
+
|
13
|
+
it "creates a default initializer" do
|
14
|
+
assert_file "config/initializers/activable.rb"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Category do
|
4
|
+
it 'should have activable fields' do
|
5
|
+
Category.methods.include?(:is_activable).should be_true
|
6
|
+
c = Category.new
|
7
|
+
c.attributes.include?("activated_at").should be_true
|
8
|
+
c.attributes.include?("deactivated_at").should be_true
|
9
|
+
c.methods.include?(:activated_by).should_not be_true
|
10
|
+
c.methods.include?(:deactivated_by).should_not be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can be saved with no responsible' do
|
14
|
+
u = FactoryGirl.build(:category)
|
15
|
+
u.save.should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can be activated with no responsible' do
|
19
|
+
c = FactoryGirl.build(:category)
|
20
|
+
|
21
|
+
c.activate
|
22
|
+
c.save.should be_true, "Activated category with no responsible should be saved. " +
|
23
|
+
c.errors.full_messages.to_s
|
24
|
+
c.active?.should be_true
|
25
|
+
c.activated_by_id.should be_nil
|
26
|
+
c.activated_at.should_not be_nil
|
27
|
+
c.deactivated_by_id.should be_nil
|
28
|
+
c.deactivated_at.should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can be deactivated with no responsible' do
|
32
|
+
c = FactoryGirl.build(:category)
|
33
|
+
|
34
|
+
c.deactivate
|
35
|
+
c.save.should be_true, "Deactivated category with no responsible should be saved. " +
|
36
|
+
c.errors.full_messages.to_s
|
37
|
+
c.active?.should_not be_true
|
38
|
+
c.deactivated_by_id.should be_nil
|
39
|
+
c.deactivated_at.should_not be_nil
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe User do
|
4
|
+
it 'should have activable fields' do
|
5
|
+
User.methods.include?(:is_activable).should be_true
|
6
|
+
u = User.new
|
7
|
+
u.attributes.include?("activated_at").should be_true
|
8
|
+
u.attributes.include?("deactivated_at").should be_true
|
9
|
+
u.activated_by.should be_nil
|
10
|
+
u.deactivated_by.should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'cannot be saved without a responsible' do
|
14
|
+
u = FactoryGirl.build(:user)
|
15
|
+
u.save.should_not be_true
|
16
|
+
u.errors[:activated_by_id].should_not be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is active by default' do
|
20
|
+
u = FactoryGirl.build(:user)
|
21
|
+
u.active?.should be_true
|
22
|
+
u.activated_at.should_not be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can be activated' do
|
26
|
+
admin = FactoryGirl.build(:user)
|
27
|
+
admin.save(validate: false)
|
28
|
+
|
29
|
+
u = FactoryGirl.build(:another_user)
|
30
|
+
|
31
|
+
u.activate(responsible: admin)
|
32
|
+
u.save.should be_true, "Activated user should be saved. " +
|
33
|
+
u.errors.full_messages.to_s
|
34
|
+
u.active?.should be_true
|
35
|
+
u.activated_by.should be_equal admin
|
36
|
+
u.activated_at.should_not be_nil
|
37
|
+
u.deactivated_by.should be_nil
|
38
|
+
u.deactivated_at.should be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can be deactivated' do
|
42
|
+
another_user = FactoryGirl.build(:another_user)
|
43
|
+
another_user.save(validate: false)
|
44
|
+
|
45
|
+
u = FactoryGirl.build(:another_user)
|
46
|
+
|
47
|
+
u.deactivate(responsible: another_user)
|
48
|
+
u.save.should be_true, "Deactivated user should be saved. " +
|
49
|
+
u.errors.full_messages.to_s
|
50
|
+
u.active?.should_not be_true
|
51
|
+
u.deactivated_by.should be_equal another_user
|
52
|
+
u.deactivated_at.should_not be_nil
|
53
|
+
end
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'active_record'
|
5
|
+
require 'activable'
|
6
|
+
require 'generator_spec/test_case'
|
7
|
+
require 'test_app/config/environment'
|
8
|
+
require 'rake'
|
9
|
+
require 'factory_girl'
|
10
|
+
|
11
|
+
Dir[Pathname.new(File.expand_path('../', __FILE__)).join('support/**/*.rb')].each {|f| require f}
|
12
|
+
|
13
|
+
Dir.chdir File.expand_path("../test_app", __FILE__) do
|
14
|
+
system 'rake db:create' unless File.exists?('db/test.sqlite3')
|
15
|
+
system 'rake db:migrate'
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
end
|
20
|
+
|
21
|
+
FactoryGirl.find_definitions
|
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
|
7
|
+
TestApp::Application.load_tasks
|
File without changes
|