purgatory 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDk0ZTBiMmNiNjlmMWUyODRjNTc0OWZjNjE5YTAxZDE0YTI1YjExYQ==
4
+ ZDk2M2Q4ODkzMTE1NDM4YzRjNGFjZTVmNDg3ZDI0MTE2YzI5NjkzOA==
5
5
  data.tar.gz: !binary |-
6
- MWZjODBlNzQ0MDNmYWI2NmE1MTEyZWQwNjBlYzEwYTcwMzgxNTljZg==
7
- SHA512:
6
+ MjgzNTkxZWM0NzJiNDQyYzY3YzI4NmQ3NmEzNWMwMzZhYjhjNDk5ZQ==
7
+ !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OGFhNDljZmM4YjU0YWZiNTllNjgwZDcyMjhlMGUwZWIzZDRkYzMzMjk1ZWM5
10
- YTkwOWVkNjg4MjViNzFhZGE0MzM0ODdhNGQ4YTEwYmQwMDgxNWRlMmMzMGQ2
11
- YzllMzlhYmQ1MTAzMmNjY2M0NTkyMjg0NjNhZGVjNWVhZTI1YmI=
9
+ MTJlOTU1NDRiNjgzZjM5ODgzZWY1NjExZTg1YzAxMWVkZTI1OTdkZTA2NGQ5
10
+ NmQ2NmIwYjMyZDI2OWFlNDM0ZDcwODI5OWU0ZTMxMThhYTkwYjFiM2U2NzIy
11
+ NDEzZTNmMWQ0MTliZDVhMzk2OTJlYmUyNDY0ZDUxNjVhZWE1ODc=
12
12
  data.tar.gz: !binary |-
13
- ZGJmNDZhNjNhMWQ2ZTdmMGYwMzAyNDMyZjQ3NjFiY2U1MThhYzNiNzYzM2Vl
14
- MzdjYThkZGUyNGVjN2JlYmQ0M2M3MzU0MGJmNDMxYTVmYzQ0YjFiYmQyMWNk
15
- MjY2MzBjYjNhZWZkNTk3ZTlkNzc2MGY1NTg3YzI3ZTY0MjBiMjI=
13
+ MTJlMmE3ZWEwNjM0NDQyNGYxNjNmYjE5NzVmOTE3ZGFmNDI1ZTFhZjgwYzdh
14
+ YzFhMjkwZDlkZmYyN2JjMThhNmIzNjIzYmZjYTFjNzFjMjAzZjhiZDFjOGFj
15
+ ZGQxN2E3Mjc5NDJjMmJjNWJmZTA0OTE0ZDJkZmQ2NmE2Yjg0Mjk=
data/Gemfile CHANGED
@@ -11,3 +11,9 @@ group :development do
11
11
  gem "bundler", "~> 1.0"
12
12
  gem "jeweler", "~> 1.8.7"
13
13
  end
14
+
15
+ group :test do
16
+ gem "activerecord"
17
+ gem "rspec"
18
+ gem "sqlite3"
19
+ end
data/Gemfile.lock CHANGED
@@ -1,6 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ activerecord (1.6.0)
4
5
  activesupport (4.0.1)
5
6
  i18n (~> 0.6, >= 0.6.4)
6
7
  minitest (~> 4.2)
@@ -10,6 +11,7 @@ GEM
10
11
  addressable (2.3.5)
11
12
  atomic (1.1.14)
12
13
  builder (3.2.2)
14
+ diff-lcs (1.1.3)
13
15
  faraday (0.8.8)
14
16
  multipart-post (~> 1.2.0)
15
17
  git (1.2.6)
@@ -52,12 +54,21 @@ GEM
52
54
  rake (10.1.0)
53
55
  rdoc (3.12.2)
54
56
  json (~> 1.4)
57
+ rspec (2.11.0)
58
+ rspec-core (~> 2.11.0)
59
+ rspec-expectations (~> 2.11.0)
60
+ rspec-mocks (~> 2.11.0)
61
+ rspec-core (2.11.1)
62
+ rspec-expectations (2.11.3)
63
+ diff-lcs (~> 1.1.3)
64
+ rspec-mocks (2.11.3)
55
65
  shoulda (3.5.0)
56
66
  shoulda-context (~> 1.0, >= 1.0.1)
57
67
  shoulda-matchers (>= 1.4.1, < 3.0)
58
- shoulda-context (1.1.5)
68
+ shoulda-context (1.1.6)
59
69
  shoulda-matchers (2.4.0)
60
70
  activesupport (>= 3.0.0)
71
+ sqlite3 (1.3.7)
61
72
  thread_safe (0.1.3)
62
73
  atomic
63
74
  tzinfo (0.3.38)
@@ -66,7 +77,10 @@ PLATFORMS
66
77
  ruby
67
78
 
68
79
  DEPENDENCIES
80
+ activerecord
69
81
  bundler (~> 1.0)
70
82
  jeweler (~> 1.8.7)
71
83
  rdoc (~> 3.12)
84
+ rspec
72
85
  shoulda
86
+ sqlite3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.1.0
@@ -1,6 +1,4 @@
1
1
  class Purgatory < ActiveRecord::Base
2
- attr_accessible :requester, :soul
3
-
4
2
  belongs_to :soul, polymorphic: true, autosave: false
5
3
  belongs_to :requester, class_name: 'User'
6
4
  belongs_to :approver, class_name: 'User'
@@ -8,8 +6,13 @@ class Purgatory < ActiveRecord::Base
8
6
 
9
7
  validates :soul_type, presence: true
10
8
 
11
- scope :pending, conditions: { approved_at: nil }
12
- scope :approved, conditions: ["approved_at IS NOT NULL"]
9
+ def self.pending
10
+ where(approved_at: nil)
11
+ end
12
+
13
+ def self.approved
14
+ where ["approved_at IS NOT NULL"]
15
+ end
13
16
 
14
17
  def approved?
15
18
  approved_at.present?
@@ -24,14 +27,13 @@ class Purgatory < ActiveRecord::Base
24
27
  end
25
28
 
26
29
  def soul
27
- super || soul_type.constantize.new
30
+ @soul ||= (super || soul_type.constantize.new)
28
31
  end
29
32
 
30
33
  def approve!(approver = nil)
31
34
  return false if approved?
32
- changes = changes_hash
33
-
34
- if soul.update_attributes(changes.update(changes){|k,v| v.last}, without_protection: true)
35
+ changes_hash.each{|k,v| soul.send "#{k}=", v[1]}
36
+ if soul.save
35
37
  self.approver = approver
36
38
  self.approved_at = Time.now
37
39
  save
data/purgatory.gemspec CHANGED
@@ -2,15 +2,14 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: purgatory 2.0.0 ruby lib
6
5
 
7
6
  Gem::Specification.new do |s|
8
7
  s.name = "purgatory"
9
- s.version = "2.0.0"
8
+ s.version = "2.1.0"
10
9
 
11
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
11
  s.authors = ["Elan Dubrofsky"]
13
- s.date = "2013-11-22"
12
+ s.date = "2013-11-24"
14
13
  s.description = "Put your model changes in purgatory and allow them to remain lost souls until they are approved"
15
14
  s.email = "elan.dubrofsky@gmail.com"
16
15
  s.extra_rdoc_files = [
@@ -32,13 +31,15 @@ Gem::Specification.new do |s|
32
31
  "lib/purgatory/purgatory.rb",
33
32
  "lib/purgatory/purgatory_module.rb",
34
33
  "purgatory.gemspec",
35
- "test/helper.rb",
36
- "test/test_purgatory.rb"
34
+ "spec/purgatory_spec.rb",
35
+ "spec/support/active_record.rb",
36
+ "spec/support/user.rb",
37
+ "spec/support/widget.rb"
37
38
  ]
38
39
  s.homepage = "http://github.com/financeit/purgatory"
39
40
  s.licenses = ["MIT"]
40
41
  s.require_paths = ["lib"]
41
- s.rubygems_version = "2.1.10"
42
+ s.rubygems_version = "2.0.3"
42
43
  s.summary = "Allow changes to a model to be put in purgatory until they are approved"
43
44
 
44
45
  if s.respond_to? :specification_version then
@@ -0,0 +1,166 @@
1
+ require 'support/active_record'
2
+ require 'support/widget'
3
+ require 'support/user'
4
+ require 'purgatory'
5
+
6
+ describe Purgatory do
7
+ let(:user1) {User.create name: 'Elan'}
8
+ let(:user2) {User.create name: 'Reg'}
9
+ context :purgatory! do
10
+ context "putting object changes into purgatory" do
11
+ context "valid changes" do
12
+ before {create_object_change_purgatory}
13
+
14
+ it "should create and return pending Purgatory object" do
15
+ @purgatory.should be_present
16
+ @purgatory.should_not be_approved
17
+ @purgatory.should be_pending
18
+ Purgatory.pending.count.should == 1
19
+ Purgatory.pending.first.should == @purgatory
20
+ Purgatory.approved.count.should be_zero
21
+ end
22
+
23
+ it "should store the soul, requester and requested changes" do
24
+ @purgatory.soul.should == @widget
25
+ @purgatory.requester.should == user1
26
+ @purgatory.changes_hash['name'].first.should == 'foo'
27
+ @purgatory.changes_hash['name'].last.should == 'bar'
28
+ @purgatory.changes_hash['price'].first.should == 100
29
+ @purgatory.changes_hash['price'].last.should == 200
30
+ end
31
+
32
+ it "should not change the widget" do
33
+ @widget.name.should == 'foo'
34
+ @widget.price.should == 100
35
+ end
36
+
37
+ it "should allow the widget to access its purgatories" do
38
+ @widget.purgatories.count.should == 1
39
+ @widget.purgatories.first.should == @purgatory
40
+ end
41
+ end
42
+
43
+ it "should not allow invalid changes to be put into purgatory" do
44
+ widget = Widget.create name: 'foo'
45
+ widget.name = ''
46
+ widget.purgatory!(user1).should be_nil
47
+ widget.reload
48
+ widget.name.should == 'foo'
49
+ Purgatory.count.should be_zero
50
+ end
51
+ end
52
+
53
+ context "putting new object creation into purgatory" do
54
+ context "valid object" do
55
+ before {create_new_object_purgatory}
56
+
57
+ it "should create and return pending Purgatory object" do
58
+ @purgatory.should be_present
59
+ @purgatory.should_not be_approved
60
+ @purgatory.should be_pending
61
+ Purgatory.pending.count.should == 1
62
+ Purgatory.pending.first.should == @purgatory
63
+ Purgatory.approved.count.should be_zero
64
+ end
65
+
66
+ it "should return the soul as a new instance of the purgatoried class" do
67
+ widget = @purgatory.soul
68
+ widget.class.should == Widget
69
+ widget.should be_new_record
70
+ end
71
+
72
+ it "should store the requester and requested changes" do
73
+ @purgatory.requester.should == user1
74
+ @purgatory.changes_hash['name'].first.should == nil
75
+ @purgatory.changes_hash['name'].last.should == 'foo'
76
+ @purgatory.changes_hash['price'].first.should == nil
77
+ @purgatory.changes_hash['price'].last.should == 100
78
+ end
79
+
80
+ it "should not create a widget" do
81
+ Widget.count.should be_zero
82
+ end
83
+ end
84
+
85
+ it "should not allow invalid object creation to be put into purgatory" do
86
+ widget = Widget.new name: ''
87
+ widget.purgatory!(user1).should be_nil
88
+ Purgatory.count.should be_zero
89
+ Widget.count.should be_zero
90
+ end
91
+ end
92
+ end
93
+
94
+ context :approve! do
95
+ context "approving object change purgatory" do
96
+ before do
97
+ create_object_change_purgatory
98
+ @purgatory.approve!(user2).should be_true
99
+ @widget.reload
100
+ end
101
+
102
+ it "should apply the changes" do
103
+ @widget.name.should == 'bar'
104
+ @widget.price.should == 200
105
+ end
106
+
107
+ it "should mark purgatory as approved and store approver" do
108
+ @purgatory.approver.should == user2
109
+ @purgatory.should be_approved
110
+ @purgatory.should_not be_pending
111
+ Purgatory.pending.count.should be_zero
112
+ Purgatory.approved.count.should == 1
113
+ Purgatory.approved.first.should == @purgatory
114
+ end
115
+
116
+ it "should fail if you try to approve again" do
117
+ @purgatory.approve!(user2).should be_false
118
+ end
119
+ end
120
+
121
+ context "approving new object creation" do
122
+ before do
123
+ create_new_object_purgatory
124
+ @purgatory.approve!(user2).should be_true
125
+ end
126
+
127
+ it "should create the new object and apply any callbacks" do
128
+ Widget.count.should == 1
129
+ widget = Widget.first
130
+ widget.name.should == 'foo'
131
+ widget.price.should == 100
132
+ widget.original_name.should == 'foo'
133
+ end
134
+
135
+ it "should mark purgatory as approved and store approver" do
136
+ @purgatory.approver.should == user2
137
+ @purgatory.should be_approved
138
+ @purgatory.should_not be_pending
139
+ Purgatory.pending.count.should be_zero
140
+ Purgatory.approved.count.should == 1
141
+ Purgatory.approved.first.should == @purgatory
142
+ end
143
+
144
+ it "should fail if you try to approve again" do
145
+ @purgatory.approve!(user2).should be_false
146
+ end
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ def create_object_change_purgatory
153
+ @widget = Widget.create name: 'foo', price: 100
154
+ @widget.name = 'bar'
155
+ @widget.price = 200
156
+ @purgatory = @widget.purgatory! user1
157
+ @widget.reload
158
+ @purgatory.reload
159
+ end
160
+
161
+ def create_new_object_purgatory
162
+ widget = Widget.new name: 'foo', price: 100
163
+ @purgatory = widget.purgatory! user1
164
+ @purgatory.reload
165
+ end
166
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_record'
2
+ require 'generators/purgatory/templates/create_purgatories'
3
+
4
+ ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
5
+
6
+ ActiveRecord::Migration.create_table :widgets do |t|
7
+ t.string :name
8
+ t.integer :price
9
+ t.string :original_name
10
+ t.timestamps
11
+ end
12
+
13
+ ActiveRecord::Migration.create_table :users do |t|
14
+ t.string :name
15
+ t.timestamps
16
+ end
17
+
18
+ CreatePurgatories.new.migrate(:up)
19
+
20
+ RSpec.configure do |config|
21
+ config.around do |example|
22
+ ActiveRecord::Base.transaction do
23
+ example.run
24
+ raise ActiveRecord::Rollback
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,13 @@
1
+ require 'purgatory'
2
+
3
+ class Widget < ActiveRecord::Base
4
+ use_purgatory
5
+ validates :name, presence: true
6
+ before_create :set_original_name
7
+
8
+ private
9
+
10
+ def set_original_name
11
+ self.original_name = name
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: purgatory
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elan Dubrofsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-22 00:00:00.000000000 Z
11
+ date: 2013-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: shoulda
@@ -89,8 +89,10 @@ files:
89
89
  - lib/purgatory/purgatory.rb
90
90
  - lib/purgatory/purgatory_module.rb
91
91
  - purgatory.gemspec
92
- - test/helper.rb
93
- - test/test_purgatory.rb
92
+ - spec/purgatory_spec.rb
93
+ - spec/support/active_record.rb
94
+ - spec/support/user.rb
95
+ - spec/support/widget.rb
94
96
  homepage: http://github.com/financeit/purgatory
95
97
  licenses:
96
98
  - MIT
@@ -111,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
113
  version: '0'
112
114
  requirements: []
113
115
  rubyforge_project:
114
- rubygems_version: 2.1.10
116
+ rubygems_version: 2.0.3
115
117
  signing_key:
116
118
  specification_version: 4
117
119
  summary: Allow changes to a model to be put in purgatory until they are approved
data/test/helper.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
-
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
15
- require 'purgatory'
16
-
17
- class Test::Unit::TestCase
18
- end
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestPurgatory < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end