protected_record 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ca5f6df32648cad9acee2ed43774965181ef3b4
4
- data.tar.gz: c9f887c42afc82b5a793b3e9b689102dc1492df6
3
+ metadata.gz: f77ce95c22273bab1bf96d5c3955ec8c0866ea72
4
+ data.tar.gz: cc5c1b24cda6552940a9b86a7fa466f7a56519ee
5
5
  SHA512:
6
- metadata.gz: c9ff4028860f759cb5a5dd2d9212d2d873b4e6e3b400343199ff37a5f93c852b7510410aa843630fbc1dcfce50979e6826c3c66b9014af8d14ecbfa4027b4518
7
- data.tar.gz: 30c2e5c35108ef953ad05c1f5fa676f15f7f74e5fe11c5adeabc1cf5555a70f9a24e7257f422b9700581e84e03c7a7606b5ea7a02d94a26953c3e11d1c1ea1b2
6
+ metadata.gz: c65da5f7063befa647fbd49a7ee8d6e13d582d79dbb74d3d760f264e0ec96c8f4022988f0bfc5709a7ec985443454fcacdddfea1675cd739e2f1d9e10ddfc6dd
7
+ data.tar.gz: 0bc2f938d78f5a4cd364c07082ed77da4a1504f15d361161c4c104ced43e5d1a508949ca2c64b0876f46d68d5b1c61bfdb40ba3bdcc865b9d20e3c2f0894b98e
data/README.md CHANGED
@@ -5,17 +5,17 @@
5
5
  I've created an engine to provide the necessary migrations as well as a (very)
6
6
  basic interface for triaging `ProtectedRecord::ChangeRequest::Record` objects.
7
7
  You are free to use this gem without the engine, but you'll need to
8
- [grab these](//github.com/rthbound/protected_record_manager/tree/master/db/migrate).
8
+ [grab these](https://github.com/rthbound/protected_record_manager/tree/master/db/migrate).
9
9
 
10
10
  ### Your models
11
11
 
12
12
  Prepare your models.
13
13
  There's **two types** of models at play here:
14
14
 
15
- 1. User (for now I expect a `User` class and `current\_user` method
15
+ 1. User (for now I expect a `User` class and `current_user` method
16
16
  2. Your records .. these are the models you want to track
17
17
 
18
- So, in your models
18
+ So, in your models add `require "protected_record"`
19
19
 
20
20
  ```ruby
21
21
  # app/models/user.rb
@@ -30,6 +30,22 @@ include ProtectedRecord::ChangeRequest::Changeling
30
30
  include ProtectedRecord::ChangeLog::Changeling
31
31
  ```
32
32
 
33
+ #### Protected Keys
34
+
35
+ You have two options,
36
+
37
+ 1. Inject the `:protected_keys` option when you execute the update (this will always take precedence)
38
+ 2. Include in your record class `ProtectedRecord::DirtyModel` and define them there:
39
+
40
+ ```ruby
41
+ class SomeRecord < ActiveRecord::Base
42
+ include ProtectedRecord::DirtyModel
43
+ protected_keys :do_not_resuscitate, :organ_donor
44
+ end
45
+ ```
46
+
47
+ If you do not specify either option, ProtectedRecord will use an empty array.
48
+
33
49
  ## Usage
34
50
 
35
51
  1. protected_record will prevent changes to attributes you specify as protected.
@@ -0,0 +1,17 @@
1
+ module ProtectedRecord
2
+ module DirtyModel
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+
6
+ def protected_keys
7
+ self.class.send(:protected_keys)
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def protected_keys(*args)
13
+ @@protected_keys ||= args.to_a
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,7 +3,8 @@ module ProtectedRecord
3
3
  module ChangeFilter
4
4
  class Create < PayDirt::Base
5
5
  def initialize(options)
6
- load_options(:protected_keys, :protected_record, options)
6
+ load_options(:protected_record, options)
7
+ validate_state
7
8
  end
8
9
 
9
10
  def execute!
@@ -22,6 +23,17 @@ module ProtectedRecord
22
23
  end
23
24
  end
24
25
  end
26
+
27
+ protected
28
+ def validate_state
29
+ if !@protected_keys.kind_of?(Array)
30
+ if @protected_record.respond_to? :protected_keys
31
+ @protected_keys = @protected_record.protected_keys
32
+ else
33
+ @protected_keys = []
34
+ end
35
+ end
36
+ end
25
37
  end
26
38
  end
27
39
  end
@@ -7,7 +7,8 @@ module ProtectedRecord
7
7
  record_class: ::ProtectedRecord::ChangeRequest::Record
8
8
  }.merge!(options) if !options.has_key?(:record_class)
9
9
 
10
- load_options(:protected_keys, :record_class, :user, :protected_record, options)
10
+ load_options(:record_class, :user, :protected_record, options)
11
+ validate_state
11
12
  end
12
13
 
13
14
  def execute!
@@ -45,6 +46,17 @@ module ProtectedRecord
45
46
 
46
47
  raise if @protected_keys.any? { |key| @protected_record.send("#{key}_changed?") }
47
48
  end
49
+
50
+ protected
51
+ def validate_state
52
+ if !@protected_keys.kind_of?(Array)
53
+ if @protected_record.respond_to? :protected_keys
54
+ @protected_keys = @protected_record.protected_keys
55
+ else
56
+ @protected_keys = []
57
+ end
58
+ end
59
+ end
48
60
  end
49
61
  end
50
62
  end
@@ -9,7 +9,7 @@ module ProtectedRecord
9
9
  change_log: UseCase::ChangeLog::Create
10
10
  }.merge!(options)
11
11
 
12
- load_options(:params, :protected_record, :change_request, :change_log, :change_filter, :protected_keys, :user, options)
12
+ load_options(:params, :protected_record, :change_request, :change_log, :change_filter, :user, options)
13
13
  validate_state
14
14
  end
15
15
 
@@ -70,7 +70,11 @@ module ProtectedRecord
70
70
  def validate_state
71
71
  # We expect some keys
72
72
  if !@protected_keys.kind_of?(Array)
73
- raise TypeError.new(':protected_keys not kind of Array')
73
+ if @protected_record.respond_to? :protected_keys
74
+ @protected_keys = @protected_record.protected_keys
75
+ else
76
+ @protected_keys = []
77
+ end
74
78
  end
75
79
 
76
80
  # The keys should respond to to_s
@@ -1,3 +1,3 @@
1
1
  module ProtectedRecord
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -11,3 +11,90 @@ $: << File.dirname(__FILE__) + "/../lib"
11
11
  $: << File.dirname(__FILE__)
12
12
 
13
13
  require "protected_record"
14
+
15
+ class TestCase
16
+ include ActiveModel::Dirty
17
+ include ProtectedRecord::DirtyModel
18
+
19
+ protected_keys :knowledge, :power
20
+
21
+ define_attribute_methods [:knowledge, :power]
22
+
23
+ def knowledge
24
+ @knowledge
25
+ end
26
+
27
+ def attributes=(args)
28
+ end
29
+
30
+ def id_was
31
+ 1
32
+ end
33
+
34
+ def power
35
+ @power
36
+ end
37
+
38
+ def knowledge=(val)
39
+ knowledge_will_change! unless val == @knowledge
40
+ @knowledge = val
41
+ end
42
+
43
+ def power=(val)
44
+ power_will_change! unless val == @power
45
+ @power = val
46
+ end
47
+
48
+ def save
49
+ @previously_changed = changes
50
+ @changed_attributes.clear
51
+ end
52
+
53
+ def initialize(attributes = {})
54
+ attributes.each do |name, value|
55
+ send("#{name}=", value)
56
+ end
57
+ end
58
+ end
59
+
60
+ class UnprotectedTestCase
61
+ include ActiveModel::Dirty
62
+
63
+ define_attribute_methods [:knowledge, :power]
64
+
65
+ def knowledge
66
+ @knowledge
67
+ end
68
+
69
+ def attributes=(args)
70
+ end
71
+
72
+ def id_was
73
+ 1
74
+ end
75
+
76
+ def power
77
+ @power
78
+ end
79
+
80
+ def knowledge=(val)
81
+ knowledge_will_change! unless val == @knowledge
82
+ @knowledge = val
83
+ end
84
+
85
+ def power=(val)
86
+ power_will_change! unless val == @power
87
+ @power = val
88
+ end
89
+
90
+ def save
91
+ @previously_changed = changes
92
+ @changed_attributes.clear
93
+ end
94
+
95
+ def initialize(attributes = {})
96
+ attributes.each do |name, value|
97
+ send("#{name}=", value)
98
+ end
99
+ end
100
+ end
@@ -1,45 +1,8 @@
1
1
  require "minitest_helper"
2
- require "active_record"
3
2
 
4
3
  describe ProtectedRecord::UseCase::ChangeFilter::Create do
5
4
  describe "new" do
6
5
  before do
7
- class TestCase
8
- include ActiveModel::Dirty
9
-
10
- define_attribute_methods [:knowledge, :power]
11
-
12
- def knowledge
13
- @knowledge
14
- end
15
-
16
- def power
17
- @power
18
- end
19
-
20
- def knowledge=(val)
21
- knowledge_will_change! unless val == @knowledge
22
- @knowledge = val
23
- end
24
-
25
- def power=(val)
26
- power_will_change! unless val == @power
27
- @power = val
28
- end
29
-
30
- def save
31
- @previously_changed = changes
32
- @changed_attributes.clear
33
- end
34
-
35
- def initialize(attributes = {})
36
- attributes.each do |name, value|
37
- send("#{name}=", value)
38
- end
39
- end
40
- #####
41
- end
42
-
43
6
  @subject = ProtectedRecord::UseCase::ChangeFilter::Create
44
7
 
45
8
  @protected_record = TestCase.new(knowledge: "power", power: "money")
@@ -129,5 +92,36 @@ describe ProtectedRecord::UseCase::ChangeFilter::Create do
129
92
  ret_obj.knowledge.must_equal "growth"
130
93
  ret_obj.power.must_equal "money"
131
94
  end
95
+
96
+ it "it will read protected_keys from your model" do
97
+ @protected_record.knowledge="growth"
98
+ @protected_record.power="knowledge"
99
+
100
+ result = @subject.new({
101
+ protected_record: @protected_record,
102
+ }).execute!
103
+
104
+ ret_obj = result.data[:change_request_record]
105
+
106
+ ret_obj.knowledge.must_equal "power"
107
+ ret_obj.power.must_equal "money"
108
+ end
109
+
110
+ it "will allow any changes when no protected_keys are provided" do
111
+ @protected_record = UnprotectedTestCase.new(knowledge: "power", power: "money")
112
+ @protected_record.save
113
+
114
+ @protected_record.knowledge="growth"
115
+ @protected_record.power="knowledge"
116
+
117
+ result = @subject.new({
118
+ protected_record: @protected_record,
119
+ }).execute!
120
+
121
+ ret_obj = result.data[:change_request_record]
122
+
123
+ ret_obj.knowledge.must_equal "growth"
124
+ ret_obj.power.must_equal "knowledge"
125
+ end
132
126
  end
133
127
  end
@@ -1,82 +1,45 @@
1
1
  require "minitest_helper"
2
- require "active_record"
3
2
 
4
- describe ProtectedRecord::UseCase::ChangeFilter::Create do
3
+ describe ProtectedRecord::UseCase::ChangeLog::Create do
5
4
  describe "new" do
6
5
  before do
7
- class TestCase
8
- include ActiveModel::Dirty
9
-
10
- define_attribute_methods [:knowledge, :power]
11
-
12
- def knowledge
13
- @knowledge
14
- end
15
-
16
- def power
17
- @power
18
- end
19
-
20
- def knowledge=(val)
21
- knowledge_will_change! unless val == @knowledge
22
- @knowledge = val
23
- end
24
-
25
- def power=(val)
26
- power_will_change! unless val == @power
27
- @power = val
28
- end
29
-
30
- def save
31
- @previously_changed = changes
32
- @changed_attributes.clear
33
- end
34
-
35
- def initialize(attributes = {})
36
- attributes.each do |name, value|
37
- send("#{name}=", value)
38
- end
39
- end
40
- #####
41
- end
42
-
43
- @subject = ProtectedRecord::UseCase::ChangeLog::Create
44
-
45
- @protected_record = TestCase.new(knowledge: "power", power: "money")
46
- @protected_record.save
47
-
48
- @mock_change_log_record_class = MiniTest::Mock.new
49
- @mock_change_log_record = MiniTest::Mock.new
50
- @mock_user = MiniTest::Mock.new
51
- @changes = JSON.generate(@protected_record.previous_changes)
52
- @mock_change_log_record_class.expect(:new, @mock_change_log_record)
53
- @mock_change_log_record.expect(:user=, @mock_user, [@mock_user])
54
- @mock_change_log_record.expect(:recordable=, @protected_record, [@protected_record])
55
- @mock_change_log_record.expect(:observed_changes=, @changes, [@changes])
56
- @mock_change_log_record.expect(:save, true)
6
+ @subject = ProtectedRecord::UseCase::ChangeLog::Create
7
+ @test_case = TestCase.new({
8
+ knowledge: "power",
9
+ power: "money"
10
+ })
11
+ @test_case.save
12
+
13
+ @change_log_record_class = MiniTest::Mock.new
14
+ @change_log_record = MiniTest::Mock.new
15
+ @user = MiniTest::Mock.new
16
+ @changes = JSON.generate(@test_case.previous_changes)
17
+ @change_log_record_class.expect :new, @change_log_record
18
+ @change_log_record.expect :user=, @user, [@user]
19
+ @change_log_record.expect :recordable=, @test_case, [@test_case]
20
+ @change_log_record.expect :observed_changes=, @changes, [@changes]
21
+ @change_log_record.expect :save, true
57
22
 
58
23
  @dependencies = {
59
- record_class: @mock_change_log_record_class,
60
- user: @mock_user,
61
- changed_object: @protected_record
24
+ user: @user,
25
+ record_class: @change_log_record_class,
26
+ changed_object: @test_case
62
27
  }
63
28
  end
64
29
 
65
30
  it "initializes with required options" do
66
- subject = @subject.new(@dependencies)
67
-
31
+ subject = @subject.new @dependencies
68
32
  subject.must_be_instance_of @subject
69
33
  end
70
34
 
71
35
  it "initializes when options with defaults are omitted" do
72
- subject = @subject.new(@dependencies.reject { |k| k == :record_class })
73
-
36
+ subject = @subject.new @dependencies.reject { |k| k == :record_class }
74
37
  subject.must_be_instance_of @subject
75
38
  end
76
39
 
77
40
  it "fails to initialize without :user" do
78
41
  begin
79
- @subject.new(@dependencies.reject { |k| k == :user })
42
+ @subject.new @dependencies.reject { |k| k == :user }
80
43
  rescue => e
81
44
  e.must_be_kind_of RuntimeError
82
45
  end
@@ -84,7 +47,7 @@ describe ProtectedRecord::UseCase::ChangeFilter::Create do
84
47
 
85
48
  it "fails to initialize without :changed_object" do
86
49
  begin
87
- @subject.new(@dependencies.reject { |k| k == :changed_object })
50
+ @subject.new @dependencies.reject { |k| k == :changed_object }
88
51
  rescue => e
89
52
  e.must_be_kind_of RuntimeError
90
53
  end
@@ -93,7 +56,7 @@ describe ProtectedRecord::UseCase::ChangeFilter::Create do
93
56
  it "returns a result" do
94
57
  result = @subject.new(@dependencies).execute!
95
58
 
96
- @mock_change_log_record.verify
59
+ @change_log_record.verify
97
60
 
98
61
  result.must_be_kind_of(PayDirt::Result)
99
62
  end
@@ -101,18 +64,18 @@ describe ProtectedRecord::UseCase::ChangeFilter::Create do
101
64
  it "does the deed" do
102
65
  result = @subject.new(@dependencies).execute!
103
66
 
104
- @mock_change_log_record.verify
67
+ @change_log_record.verify
105
68
 
106
69
  result.successful?.must_equal true
107
70
  end
108
71
 
109
72
  it "it's not successful if #save fails" do
110
- @mock_change_log_record.save
111
- @mock_change_log_record.expect(:save, false)
73
+ @change_log_record.save
74
+ @change_log_record.expect(:save, false)
112
75
 
113
76
  result = @subject.new(@dependencies).execute!
114
77
 
115
- @mock_change_log_record.verify
78
+ @change_log_record.verify
116
79
 
117
80
  result.successful?.must_equal false
118
81
  end
@@ -1,2 +1,94 @@
1
1
  require "minitest_helper"
2
2
 
3
+ describe ProtectedRecord::UseCase::ChangeRequest::Create do
4
+ describe "new" do
5
+ before do
6
+ @subject = ProtectedRecord::UseCase::ChangeRequest::Create
7
+
8
+ @protected_record = TestCase.new(knowledge: "power", power: "money")
9
+ @protected_record.save
10
+
11
+ @mock_change_request_record_class = MiniTest::Mock.new
12
+ @mock_change_request_record = MiniTest::Mock.new
13
+ @mock_user = MiniTest::Mock.new
14
+ @mock_change_request_record_class.expect(:new, @mock_change_request_record)
15
+ @mock_change_request_record.expect(:user=, @mock_user, [@mock_user])
16
+ @mock_change_request_record.expect(:recordable=, @protected_record, [@protected_record])
17
+ @mock_change_request_record.expect(:save, true)
18
+
19
+ @protected_record.power= "trivial knowledge"
20
+ @changes = JSON.generate(@protected_record.changes)
21
+ @mock_change_request_record.expect(:requested_changes=, @changes, [@changes])
22
+
23
+ @dependencies = {
24
+ protected_keys: %w{ power },
25
+ protected_record: @protected_record,
26
+ record_class: @mock_change_request_record_class,
27
+ user: @mock_user
28
+ }
29
+ end
30
+
31
+ it "initializes with required options" do
32
+ subject = @subject.new(@dependencies)
33
+
34
+ subject.must_be_instance_of @subject
35
+ end
36
+
37
+ it "initializes when options with defaults are omitted" do
38
+ subject = @subject.new(@dependencies.reject { |k| k == :record_class })
39
+
40
+ subject.must_be_instance_of @subject
41
+ end
42
+
43
+ it "fails to initialize without :user" do
44
+ begin
45
+ @subject.new(@dependencies.reject { |k| k == :user })
46
+ rescue => e
47
+ e.must_be_kind_of RuntimeError
48
+ end
49
+ end
50
+
51
+ it "fails to initialize without :changed_object" do
52
+ begin
53
+ @subject.new(@dependencies.reject { |k| k == :protected_record })
54
+ rescue => e
55
+ e.must_be_kind_of RuntimeError
56
+ end
57
+ end
58
+
59
+ it "returns a result" do
60
+ result = @subject.new(@dependencies).execute!
61
+
62
+ result.must_be_kind_of(PayDirt::Result)
63
+ end
64
+ it "does the deed" do
65
+ result = @subject.new(@dependencies).execute!
66
+
67
+ @mock_change_request_record.verify
68
+
69
+ result.successful?.must_equal true
70
+ end
71
+
72
+ it "can read protected_keys from your model" do
73
+ so = @subject.new @dependencies.reject { |k| k.to_s == "protected_keys" }
74
+ result = so.execute!
75
+
76
+
77
+ @mock_change_request_record.verify
78
+
79
+ result.successful?.must_equal true
80
+ end
81
+
82
+ it "it's not successful if #save fails" do
83
+ @mock_change_request_record.save
84
+ @mock_change_request_record.expect(:save, false)
85
+
86
+ result = @subject.new(@dependencies).execute!
87
+
88
+ @mock_change_request_record.verify
89
+
90
+ result.successful?.must_equal false
91
+ end
92
+ end
93
+ end
94
+
@@ -1 +1,44 @@
1
1
  require "minitest_helper"
2
+
3
+ describe ProtectedRecord::UseCase::Update do
4
+ before do
5
+ @subject = ProtectedRecord::UseCase::Update
6
+
7
+ @params = { params: {
8
+ knowledge: "bad",
9
+ power: "money"
10
+ }}
11
+
12
+ @test_case = TestCase.new( knowledge: :power )
13
+
14
+ @dependencies = {
15
+ user: MiniTest::Mock.new,
16
+ protected_record: @test_case,
17
+ protected_keys: [:knowledge],
18
+ }
19
+ @dependencies.merge! @params
20
+ end
21
+
22
+ it "can be initialized" do
23
+ @subject.must_respond_to :new
24
+ end
25
+
26
+ it "fails without required dependencies" do
27
+ %w{ user params protected_record }.each do |dep|
28
+ begin
29
+ @subject.new @dependencies.reject { |k| k.to_s == dep }
30
+ rescue => e
31
+ e.must_be_kind_of RuntimeError
32
+ end
33
+ end
34
+ end
35
+
36
+ it "initializes without :protected_keys" do
37
+ so = @subject.new @dependencies.reject { |k| k.to_s == "protected_keys" }
38
+ so.must_respond_to :execute!
39
+ end
40
+
41
+ it "can be executed" do
42
+ @subject.new(@dependencies).must_respond_to :execute!
43
+ end
44
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protected_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tad Hosford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-25 00:00:00.000000000 Z
11
+ date: 2013-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pay_dirt
@@ -98,6 +98,7 @@ files:
98
98
  - lib/protected_record.rb
99
99
  - lib/protected_record/change_log.rb
100
100
  - lib/protected_record/change_request.rb
101
+ - lib/protected_record/dirty_model.rb
101
102
  - lib/protected_record/use_case.rb
102
103
  - lib/protected_record/use_case/change_filter/create.rb
103
104
  - lib/protected_record/use_case/change_log/create.rb