-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Utility Methods to Aws::Record Model Interface #82
Changes from 1 commit
582fb49
911118c
9bfd913
ee13827
fd5c694
a7119e8
0a4f1fc
927c728
1e7bd5c
122330d
5262302
d36551d
d6391c1
f89c95d
bfe72a6
61c66c2
ad6a46c
32337e6
c95a62e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,24 @@ def save(opts = {}) | |
end | ||
end | ||
|
||
|
||
# Performs mass assignment of model attributes | ||
def assign_attributes(opts) | ||
opts.each do |field, new_value| | ||
if !respond_to?("#{field}=") | ||
raise ArgumentError.new "Invalid field: #{field} for model" | ||
end | ||
@data.set_attribute field, new_value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style point in this repo, we explicitly use @data.set_attribute(field, new_value) |
||
end | ||
end | ||
|
||
# Updates model attributes and then performs a conditional save | ||
def update(opts) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also add an |
||
self.assign_attributes opts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||
|
||
self.save | ||
end | ||
|
||
# Deletes the item instance that matches the key values of this item | ||
# instance in Amazon DynamoDB. Uses the | ||
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_item-instance_method Aws::DynamoDB::Client#delete_item} | ||
|
@@ -90,7 +108,7 @@ def delete! | |
table_name: self.class.table_name, | ||
key: key_values | ||
) | ||
true | ||
self.instance_variable_get("@data").destroyed = true | ||
end | ||
|
||
private | ||
|
@@ -151,6 +169,10 @@ def _perform_save(opts) | |
) | ||
end | ||
end | ||
data = self.instance_variable_get("@data") | ||
data.destroyed = false if data.destroyed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the "if" condition here? It looks like the end condition is always going to be false or false-equivalent. |
||
data.new_record = false if data.new_record | ||
true | ||
end | ||
|
||
def _build_item_for_save | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,6 +188,30 @@ | |
|
||
end | ||
|
||
describe "persisted?" do | ||
before(:each) do | ||
klass.configure_client(client: stub_client) | ||
end | ||
|
||
it "appropriately determines whether an item is persisted" do | ||
item = klass.new | ||
item.mykey = SecureRandom.uuid | ||
item.body = SecureRandom.uuid | ||
|
||
# Test all combinations of new_recorded and destroyed | ||
expect(item.persisted?).to be false | ||
item.save | ||
expect(item.persisted?).to be true | ||
item.delete! | ||
expect(item.persisted?).to be false | ||
item = klass.new | ||
item.mykey = SecureRandom.uuid | ||
item.body = SecureRandom.uuid | ||
item.delete! | ||
expect(item.persisted?).to be false | ||
end | ||
end | ||
|
||
describe '#rollback_[attribute]!' do | ||
|
||
it "should restore the attribute to its last known clean value" do | ||
|
@@ -236,6 +260,39 @@ | |
|
||
end | ||
|
||
describe "#update" do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It also looks like we never actually test-call the |
||
|
||
before(:each) do | ||
klass.configure_client(client: stub_client) | ||
end | ||
|
||
it 'should perform a hash based attribute assignment without persisting changes' do | ||
item = klass.new | ||
item.mykey = SecureRandom.uuid | ||
item.body = SecureRandom.uuid | ||
item.save | ||
|
||
new_key = SecureRandom.uuid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd strongly encourage that we use explicit values in these tests. Why do we need randomness? |
||
new_body = SecureRandom.uuid | ||
item.assign_attributes :mykey => new_key, :body => new_body | ||
expect(item.mykey).to eq new_key | ||
expect(item.body).to eq new_body | ||
expect(item.dirty?).to be true | ||
end | ||
|
||
it 'should throw an argument error when you try to update an invalid attribute' do | ||
item = klass.new | ||
item.mykey = SecureRandom.uuid | ||
item.body = SecureRandom.uuid | ||
item.save | ||
|
||
expect { | ||
item.assign_attributes :mykey_key => SecureRandom.uuid | ||
}.to raise_error(ArgumentError) | ||
end | ||
|
||
end | ||
|
||
describe "#save" do | ||
|
||
before(:each) do | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,23 @@ module Record | |
end | ||
end | ||
|
||
describe "#new_record" do | ||
it 'marks records fetched from a client call as not being new' do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should go ahead and add the "obvious" test that something created by hand is marked as a new record. Part of the test coverage notion is to avoid surprise regressions later. |
||
stub_client.stub_responses(:scan, non_truncated_resp) | ||
c = ItemCollection.new( | ||
:scan, | ||
{ table_name: "TestTable" }, | ||
model, | ||
stub_client | ||
) | ||
|
||
c.each do |record| | ||
expect(record.new_record?).to eq false | ||
expect(record.destroyed?).to be false | ||
end | ||
end | ||
end | ||
|
||
describe "#last_evaluated_key" do | ||
it "points you to the client response pagination value if present" do | ||
stub_client.stub_responses(:scan, truncated_resp) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we document why this is the separator? It's very possible and valid for these key values to contain the ":" character. Depending on what the API contract is, we may need to do more here.