-
Notifications
You must be signed in to change notification settings - Fork 5
Use read_attribute_for_database when generating cached INSERTs #64
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
Changes from all commits
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 |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class BinaryBlob < ActiveRecord::Base | ||
| has_many :children, class_name: "BinaryBlobChild" | ||
| encrypts :secret_note | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class BinaryBlobChild < ActiveRecord::Base | ||
| belongs_to :binary_blob | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,6 +115,71 @@ def upsert_all_options(model) | |
| end | ||
| end | ||
|
|
||
| describe "binary column encoding" do | ||
| let(:raw_bytes) { (240..255).map(&:chr).join.force_encoding(Encoding::ASCII_8BIT) } | ||
|
|
||
| it "preserves exact bytes when fixtures are mounted from cache" do | ||
| result = coder.generate { BinaryBlob.create!(payload: raw_bytes, label: "first") } | ||
|
|
||
| coder.mount(result) | ||
|
|
||
| replayed = BinaryBlob.find_by!(label: "first") | ||
| expect(replayed.payload.b).to eq(raw_bytes) | ||
| end | ||
|
|
||
| it "round-trips multiple rows with different payloads" do | ||
| other_bytes = (128..143).map(&:chr).join.force_encoding(Encoding::ASCII_8BIT) | ||
| result = coder.generate do | ||
| BinaryBlob.create!(payload: raw_bytes, label: "first") | ||
| BinaryBlob.create!(payload: other_bytes, label: "second") | ||
| end | ||
|
|
||
| coder.mount(result) | ||
|
|
||
| expect(BinaryBlob.find_by!(label: "first").payload.b).to eq(raw_bytes) | ||
| expect(BinaryBlob.find_by!(label: "second").payload.b).to eq(other_bytes) | ||
| end | ||
|
|
||
| it "round-trips a JSON column alongside binary data" do | ||
| metadata = {"version" => 2, "tags" => ["alpha", "beta"]} | ||
| result = coder.generate do | ||
| BinaryBlob.create!(payload: raw_bytes, label: "with-json", metadata: metadata) | ||
| end | ||
|
|
||
| coder.mount(result) | ||
|
|
||
| replayed = BinaryBlob.find_by!(label: "with-json") | ||
| expect(replayed.payload.b).to eq(raw_bytes) | ||
| expect(replayed.metadata).to eq(metadata) | ||
| end | ||
|
|
||
| it "stores ciphertext, not cleartext, for encrypts attributes" do | ||
| cleartext = "shhh-this-is-private-#{SecureRandom.hex(4)}" | ||
| result = coder.generate { BinaryBlob.create!(payload: raw_bytes, label: "encrypted", secret_note: cleartext) } | ||
|
|
||
| sql = result[BinaryBlob] | ||
| expect(sql).not_to include(cleartext) | ||
|
|
||
| coder.mount(result) | ||
|
|
||
| replayed = BinaryBlob.find_by!(label: "encrypted") | ||
| expect(replayed.secret_note).to eq(cleartext) | ||
| end | ||
|
|
||
| it "replays a foreign key relationship without integrity errors" do | ||
| result = coder.generate do | ||
| parent = BinaryBlob.create!(payload: raw_bytes, label: "parent") | ||
| BinaryBlobChild.create!(binary_blob: parent, payload: raw_bytes) | ||
| end | ||
|
|
||
| coder.mount(result) | ||
|
|
||
| parent = BinaryBlob.find_by!(label: "parent") | ||
| expect(parent.children.count).to eq(1) | ||
| expect(parent.children.first.payload.b).to eq(raw_bytes) | ||
| end | ||
| end | ||
|
Comment on lines
+118
to
+181
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. 🟡 Minor | PR description claims a test exists for custom Attribute API types ('UuidBlob#external_id modeled on mysql-binuuid-rails serializes UUID-string -> bytes correctly through the cache') but no UuidBlob model or test case is present in the codebase. This is a claimed-but-missing test for a serialization path the PR explicitly calls out as previously broken. 🙏🏽 Please 👍🏽 👎🏽 if you found this useful. Generated by Fresh Eyes Reviewer. Get help in #ai-code-reviews |
||
|
|
||
| describe "#mount" do | ||
| it "documents that connection execute_batch is currently private" do | ||
| connection = User.connection | ||
|
|
||
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.
🟡 Minor |
[fresh_eyes]: test-coveragePR description calls out encrypted attributes as a security concern (cleartext was emitted before this fix), but no test verifies that
encrypts :colnow round-trips ciphertext correctly through generate/mount. A dedicated test would guard against regression on the security-sensitive path.🙏🏽 Please 👍🏽 👎🏽 if you found this useful. Generated by Fresh Eyes Reviewer. Get help in #ai-code-reviews
💡 Tip: You can create custom checks for your project — see repository checks.
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.
Addressed in e012bcf