purgatory 2.0.0 → 2.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 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